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)