Skip to content

Commit 852d8ab

Browse files
authored
Merge pull request #418 from lowcoder-org/agora-integrationn
Agora Video Meetings V0.5
2 parents accb05c + bcc1a3e commit 852d8ab

File tree

11 files changed

+2178
-26
lines changed

11 files changed

+2178
-26
lines changed

client/packages/lowcoder/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"@types/react-virtualized": "^9.21.21",
3939
"agora-access-token": "^2.0.4",
4040
"agora-rtc-sdk-ng": "^4.19.0",
41+
"agora-rtm-sdk": "^1.5.1",
4142
"ali-oss": "^6.17.1",
4243
"antd": "5.7.2",
4344
"antd-img-crop": "^4.12.2",

client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx

Lines changed: 147 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { useUserViewMode } from "util/hooks";
4141
import { isNumeric } from "util/stringUtils";
4242
import { NameConfig, withExposingConfigs } from "../../generators/withExposing";
4343

44+
import axios from "axios";
4445
import AgoraRTC, {
4546
ICameraVideoTrack,
4647
IMicrophoneAudioTrack,
@@ -52,6 +53,7 @@ import AgoraRTC, {
5253

5354
import { JSONValue } from "@lowcoder-ee/index.sdk";
5455
import { getData } from "../listViewComp/listViewUtils";
56+
import AgoraRTM, { RtmChannel, RtmClient, RtmMessage } from "agora-rtm-sdk";
5557

5658
const EventOptions = [closeEvent] as const;
5759

@@ -105,6 +107,17 @@ let audioTrack: IMicrophoneAudioTrack;
105107
let videoTrack: ICameraVideoTrack;
106108
let screenShareStream: ILocalVideoTrack;
107109
let userId: UID | null | undefined;
110+
let rtmChannelResponse: RtmChannel;
111+
let rtmClient: RtmClient;
112+
113+
const generateToken = async (
114+
appId: any,
115+
certificate: any,
116+
channelName: any
117+
) => {
118+
const agoraTokenUrl = `https://api.agora.io/v1/token?channelName=test&uid=${userId}&appID=${appId}&appCertificate=${certificate}`;
119+
await axios.post(agoraTokenUrl);
120+
};
108121

109122
const turnOnCamera = async (flag?: boolean) => {
110123
if (videoTrack) {
@@ -119,8 +132,6 @@ const turnOnMicrophone = async (flag?: boolean) => {
119132
return audioTrack.setEnabled(flag!);
120133
}
121134
audioTrack = await AgoraRTC.createMicrophoneAudioTrack();
122-
// audioTrack.play();
123-
124135
if (!flag) {
125136
await client.unpublish(audioTrack);
126137
} else {
@@ -141,7 +152,7 @@ const shareScreen = async (sharing: boolean) => {
141152
"disable"
142153
);
143154
await client.unpublish(videoTrack);
144-
screenShareStream.play(userId + "");
155+
screenShareStream.play("share-screen");
145156
await client.publish(screenShareStream);
146157
}
147158
} catch (error) {
@@ -158,15 +169,29 @@ const leaveChannel = async () => {
158169
await turnOnMicrophone(false);
159170
}
160171
await client.leave();
172+
await rtmChannelResponse.leave();
161173
};
162174

163175
const hostChanged = (users: any) => {};
164176

165-
const publishVideo = async (appId: any, channel: any, height: any) => {
177+
const publishVideo = async (
178+
appId: string,
179+
channel: any,
180+
height: any,
181+
certifiCateKey: string
182+
) => {
183+
// console.log(
184+
// "generateToken",
185+
// await generateToken(appId, certifiCateKey, channel)
186+
// );
187+
188+
// return;
166189
await turnOnCamera(true);
167190
await client.join(appId, channel, null, userId);
168191
await client.publish(videoTrack);
169192

193+
await rtmInit(appId, userId, channel);
194+
170195
const mediaStreamTrack = videoTrack.getMediaStreamTrack();
171196
if (mediaStreamTrack) {
172197
const videoSettings = mediaStreamTrack.getSettings();
@@ -177,6 +202,57 @@ const publishVideo = async (appId: any, channel: any, height: any) => {
177202
}
178203
};
179204

205+
const sendMessageRtm = (message: any) => {
206+
rtmChannelResponse
207+
.sendMessage({ text: JSON.stringify(message) })
208+
.then(() => {
209+
console.log("message sent " + JSON.stringify(message));
210+
})
211+
.catch((e: any) => {
212+
console.log("error", e);
213+
});
214+
};
215+
216+
const sendPeerMessageRtm = (message: any, toId: string) => {
217+
rtmClient
218+
.sendMessageToPeer({ text: JSON.stringify(message) }, toId)
219+
.then(() => {
220+
console.log("message sent " + JSON.stringify(message));
221+
})
222+
.catch((e: any) => {
223+
console.log("error", e);
224+
});
225+
};
226+
227+
const rtmInit = async (appId: any, uid: any, channel: any) => {
228+
rtmClient = AgoraRTM.createInstance(appId);
229+
let options = {
230+
uid: String(uid),
231+
};
232+
await rtmClient.login(options);
233+
234+
rtmClient.on("ConnectionStateChanged", function (state, reason) {
235+
console.log("State changed To: " + state + " Reason: " + reason);
236+
});
237+
238+
rtmChannelResponse = rtmClient.createChannel(channel);
239+
240+
await rtmChannelResponse.join().then(async () => {
241+
console.log(
242+
"You have successfully joined channel " + rtmChannelResponse.channelId
243+
);
244+
});
245+
246+
// Display channel member stats
247+
rtmChannelResponse.on("MemberJoined", function (memberId) {
248+
console.log(memberId + " joined the channel");
249+
});
250+
// Display channel member stats
251+
rtmChannelResponse.on("MemberLeft", function (memberId) {
252+
console.log(memberId + " left the channel");
253+
});
254+
};
255+
180256
export const meetingControllerChildren = {
181257
visible: booleanExposingStateControl("visible"),
182258
onEvent: eventHandlerControl(EventOptions),
@@ -199,6 +275,8 @@ export const meetingControllerChildren = {
199275
usersScreenShared: stateComp<JSONValue>([]),
200276
localUser: jsonObjectExposingStateControl(""),
201277
meetingName: stringExposingStateControl("meetingName"),
278+
certifiCateKey: stringExposingStateControl(""),
279+
messages: stateComp<JSONValue>([]),
202280
};
203281
let MTComp = (function () {
204282
return new ContainerCompBuilder(
@@ -222,6 +300,7 @@ let MTComp = (function () {
222300
[dispatch, isTopBom]
223301
);
224302
const [userIds, setUserIds] = useState<any>([]);
303+
const [rtmMessages, setRtmMessages] = useState<any>([]);
225304

226305
useEffect(() => {
227306
dispatch(
@@ -238,6 +317,32 @@ let MTComp = (function () {
238317
}
239318
}, [props.endCall.value]);
240319

320+
useEffect(() => {
321+
if (rtmMessages) {
322+
dispatch(
323+
changeChildAction("messages", getData(rtmMessages).data, false)
324+
);
325+
}
326+
}, [rtmMessages]);
327+
328+
useEffect(() => {
329+
if (rtmChannelResponse) {
330+
rtmClient.on("MessageFromPeer", function (message, peerId) {
331+
console.log(
332+
"Message from: " + peerId + " Message: " + message.text
333+
);
334+
setRtmMessages(message.text);
335+
});
336+
rtmChannelResponse.on("ChannelMessage", function (message, memberId) {
337+
console.log("Message received from: " + memberId, message.text);
338+
setRtmMessages(message.text);
339+
dispatch(
340+
changeChildAction("messages", getData(rtmMessages).data, false)
341+
);
342+
});
343+
}
344+
}, [rtmChannelResponse]);
345+
241346
useEffect(() => {
242347
client.on("user-joined", (user: IAgoraRTCRemoteUser) => {
243348
let userData = {
@@ -331,6 +436,10 @@ let MTComp = (function () {
331436
<>
332437
<Section name={sectionNames.basic}>
333438
{children.appId.propertyView({ label: trans("meeting.appid") })}
439+
{children.certifiCateKey.propertyView({
440+
label: trans("meeting.certifiCateKey"),
441+
})}
442+
334443
{children.meetingName.propertyView({
335444
label: trans("meeting.meetingName"),
336445
})}
@@ -429,7 +538,6 @@ MTComp = withMethodExposing(MTComp, [
429538
} else {
430539
await turnOnCamera(value);
431540
}
432-
433541
comp.children.videoControl.change(value);
434542
},
435543
},
@@ -450,10 +558,42 @@ MTComp = withMethodExposing(MTComp, [
450558
comp.children.meetingName.getView().value == ""
451559
? "_meetingId"
452560
: comp.children.meetingName.getView().value,
453-
comp.children
561+
comp.children,
562+
comp.children.certifiCateKey.getView().value
454563
);
455564
},
456565
},
566+
{
567+
method: {
568+
name: "broadCast",
569+
description: trans("meeting.broadCast"),
570+
params: [],
571+
},
572+
execute: async (comp, values) => {
573+
let otherData =
574+
values != undefined && values[1] !== undefined ? values[1] : "";
575+
let toUsers: any =
576+
values != undefined && values[0] !== undefined ? values[0] : "";
577+
578+
let message: any = {
579+
time: Date.now(),
580+
from: userId,
581+
};
582+
message["data"] = otherData;
583+
584+
console.log(toUsers);
585+
586+
if (toUsers.length > 0 && toUsers[0] !== undefined) {
587+
let peers = toUsers?.map((u: any) => u.user);
588+
console.log("peers", peers);
589+
peers.forEach((p: any) => {
590+
sendPeerMessageRtm(message, String(p));
591+
});
592+
} else {
593+
sendMessageRtm(message);
594+
}
595+
},
596+
},
457597
{
458598
method: {
459599
name: "endMeeting",
@@ -484,8 +624,5 @@ export const VideoMeetingControllerComp = withExposingConfigs(MTComp, [
484624
new NameConfig("localUser", trans("meeting.host")),
485625
new NameConfig("participants", trans("meeting.participants")),
486626
new NameConfig("meetingName", trans("meeting.meetingName")),
627+
new NameConfig("messages", trans("meeting.meetingName")),
487628
]);
488-
489-
export function agoraClient() {
490-
return client;
491-
}

client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ import { RefControl } from "comps/controls/refControl";
2828
import { useEffect, useRef, useState } from "react";
2929

3030
import { AutoHeightControl } from "comps/controls/autoHeightControl";
31-
import {
32-
client,
33-
} from "./videoMeetingControllerComp";
31+
import { client } from "./videoMeetingControllerComp";
3432

3533
import { IAgoraRTCRemoteUser } from "agora-rtc-sdk-ng";
3634

@@ -60,7 +58,7 @@ const Container = styled.div<{ $style: any }>`
6058
display: flex;
6159
align-items: center;
6260
justify-content: center;
63-
`;
61+
`;
6462
const VideoContainer = styled.video<{ $style: any }>`
6563
height: 100%;
6664
width: 100%;
@@ -154,6 +152,7 @@ const typeOptions = [
154152

155153
export const meetingStreamChildren = {
156154
autoHeight: withDefault(AutoHeightControl, "fixed"),
155+
shareScreen: withDefault(BoolCodeControl, false),
157156
type: dropdownControl(typeOptions, ""),
158157
onEvent: MeetingEventHandlerControl,
159158
disabled: BoolCodeControl,
@@ -246,8 +245,6 @@ let VideoCompBuilder = (function (props) {
246245
}
247246
}, [props.userId.value]);
248247

249-
250-
251248
return (
252249
<EditorContext.Consumer>
253250
{(editorState) => (
@@ -257,7 +254,7 @@ let VideoCompBuilder = (function (props) {
257254
onClick={() => props.onEvent("videoClicked")}
258255
ref={videoRef}
259256
$style={props.style}
260-
id={userId}
257+
id={props.shareScreen ? "share-screen" : userId}
261258
></VideoContainer>
262259
</Container>
263260
</ReactResizeDetector>
@@ -270,6 +267,9 @@ let VideoCompBuilder = (function (props) {
270267
<Section name={sectionNames.basic}>
271268
{children.userId.propertyView({ label: trans("meeting.videoId") })}
272269
{children.autoHeight.getPropertyView()}
270+
{children.shareScreen.propertyView({
271+
label: trans("meeting.shareScreen"),
272+
})}
273273
</Section>
274274
<Section name={sectionNames.interaction}>
275275
{children.onEvent.getPropertyView()}

client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,7 @@ export const en = {
14481448
top: "Top",
14491449
host: "Host",
14501450
participants: "Participants",
1451+
shareScreen: "Share Screen",
14511452
appid: "Application Id",
14521453
meetingName: "Meeting Name",
14531454
right: "Right",
@@ -1462,6 +1463,8 @@ export const en = {
14621463
width: "Drawer width",
14631464
height: "Drawer height",
14641465
actionBtnDesc: "Action Button",
1466+
broadCast: "BroadCast Messages",
1467+
certifiCateKey: "certifiCate Key",
14651468
title: "Meeting title",
14661469
meetingCompName: "Meeting Controller",
14671470
videoCompName: "Video Stream",

client/yarn.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4767,6 +4767,13 @@ __metadata:
47674767
languageName: node
47684768
linkType: hard
47694769

4770+
"agora-rtm-sdk@npm:^1.5.1":
4771+
version: 1.5.1
4772+
resolution: "agora-rtm-sdk@npm:1.5.1"
4773+
checksum: b7518664df7c63a8910d400c48660301da2536bccb2f2d55dc8daa074a8441ceb62c7987e97fd447fd76da5fb5285d44fff03f4c2e78bca78890fa3d62981947
4774+
languageName: node
4775+
linkType: hard
4776+
47704777
"ahooks-v3-count@npm:^1.0.0":
47714778
version: 1.0.0
47724779
resolution: "ahooks-v3-count@npm:1.0.0"
@@ -11858,6 +11865,7 @@ __metadata:
1185811865
"@vitejs/plugin-react": ^2.2.0
1185911866
agora-access-token: ^2.0.4
1186011867
agora-rtc-sdk-ng: ^4.19.0
11868+
agora-rtm-sdk: ^1.5.1
1186111869
ali-oss: ^6.17.1
1186211870
antd: 5.7.2
1186311871
antd-img-crop: ^4.12.2

node_modules/.package-lock.json

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy