Skip to content

Commit 8cf4c43

Browse files
authored
fix(flat-rtc): fix rtc avatar black-screened due to partial IAgoraRTCRemoteUser callback (#1582)
1 parent 5d81121 commit 8cf4c43

File tree

4 files changed

+98
-56
lines changed

4 files changed

+98
-56
lines changed

packages/flat-components/src/components/ClassroomPage/VideoAvatar/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ export const VideoAvatar: React.FC<VideoAvatarProps> = ({
3636
}) => {
3737
const isCameraCtrlDisable =
3838
avatarUser.userUUID !== userUUID && (!isCreator || !avatarUser.camera);
39-
console.log(avatarUser.userUUID, userUUID, isCreator, avatarUser.camera);
4039

4140
const isMicCtrlDisable = avatarUser.userUUID !== userUUID && (!isCreator || !avatarUser.mic);
4241

services/rtc/flat-rtc-agora-web/src/flat-rtc-agora-web.ts

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -326,28 +326,34 @@ export class FlatRTCAgoraWeb extends FlatRTC<FlatRTCAgoraWebUIDType> {
326326
mediaType: "audio" | "video",
327327
): Promise<void> => {
328328
const uid = user.uid as FlatRTCAgoraWebUIDType;
329-
if (this.shareScreenUID === uid && !this.shareScreen.shouldSubscribeRemoteTrack()) {
329+
if (this.shareScreenUID === uid) {
330+
if (mediaType === "video" && this.shareScreen.shouldSubscribeRemoteTrack()) {
331+
try {
332+
await client.subscribe(user, mediaType);
333+
this.shareScreen.setRemoteVideoTrack(user.videoTrack || null);
334+
} catch (e) {
335+
console.error(e);
336+
}
337+
}
330338
return;
331339
}
332340

333341
try {
334342
await client.subscribe(user, mediaType);
343+
let avatar = this._remoteAvatars.get(uid);
344+
if (avatar) {
345+
if (mediaType === "audio") {
346+
avatar.setAudioTrack(user.audioTrack);
347+
} else if (mediaType === "video") {
348+
avatar.setVideoTrack(user.videoTrack);
349+
}
350+
} else {
351+
avatar = new RTCRemoteAvatar({ rtcRemoteUser: user });
352+
this._remoteAvatars.set(uid, avatar);
353+
}
335354
} catch (e) {
336355
console.error(e);
337356
}
338-
339-
if (this.shareScreenUID === uid) {
340-
this.shareScreen.setRemoteUser(user);
341-
return;
342-
}
343-
344-
let avatar = this._remoteAvatars.get(uid);
345-
if (avatar) {
346-
avatar.updateUser(user);
347-
} else {
348-
avatar = new RTCRemoteAvatar({ rtcRemoteUser: user });
349-
this._remoteAvatars.set(uid, avatar);
350-
}
351357
};
352358

353359
client.on("user-published", handler);
@@ -359,19 +365,35 @@ export class FlatRTCAgoraWeb extends FlatRTC<FlatRTCAgoraWebUIDType> {
359365
user: IAgoraRTCRemoteUser,
360366
mediaType: "audio" | "video",
361367
): Promise<void> => {
368+
const uid = user.uid as FlatRTCAgoraWebUIDType;
369+
if (uid === this.shareScreenUID) {
370+
if (mediaType === "video") {
371+
try {
372+
await client.unsubscribe(user, mediaType);
373+
this.shareScreen.setRemoteVideoTrack(null);
374+
} catch (e) {
375+
console.error(e);
376+
}
377+
this.shareScreen.destroy();
378+
}
379+
return;
380+
}
381+
362382
try {
363383
await client.unsubscribe(user, mediaType);
384+
const avatar = this._remoteAvatars.get(uid);
385+
if (avatar) {
386+
if (mediaType === "audio") {
387+
avatar.setAudioTrack(undefined);
388+
} else if (mediaType === "video") {
389+
avatar.setVideoTrack(undefined);
390+
}
391+
}
364392
} catch (e) {
365393
console.error(e);
366394
}
367395

368396
if (!user.videoTrack && !user.audioTrack) {
369-
const uid = user.uid as FlatRTCAgoraWebUIDType;
370-
if (uid === this.shareScreenUID) {
371-
this.shareScreen.setRemoteUser(null);
372-
return;
373-
}
374-
375397
const avatar = this._remoteAvatars.get(uid);
376398
if (avatar) {
377399
avatar.destroy();

services/rtc/flat-rtc-agora-web/src/rtc-remote-avatar.ts

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ export class RTCRemoteAvatar implements FlatRTCAvatar {
3030
this._el$.setValue(el);
3131
}
3232

33-
public updateUser(rtcRemoteUser: IAgoraRTCRemoteUser): void {
34-
this._videoTrack$.setValue(rtcRemoteUser.videoTrack);
35-
this._audioTrack$.setValue(rtcRemoteUser.audioTrack);
33+
public setVideoTrack(videoTrack?: IRemoteVideoTrack): void {
34+
this._videoTrack$.setValue(videoTrack);
35+
}
36+
37+
public setAudioTrack(audioTrack?: IRemoteAudioTrack): void {
38+
this._audioTrack$.setValue(audioTrack);
3639
}
3740

3841
public getVolumeLevel(): number {
@@ -46,34 +49,54 @@ export class RTCRemoteAvatar implements FlatRTCAvatar {
4649

4750
this._sideEffect.addDisposer(
4851
combine([this._audioTrack$, this._shouldMic$]).subscribe(([audioTrack, shouldMic]) => {
49-
if (audioTrack) {
50-
try {
51-
if (shouldMic) {
52-
audioTrack.play();
53-
} else {
54-
audioTrack.stop();
52+
this._sideEffect.add(() => {
53+
let disposer = (): void => void 0;
54+
if (audioTrack) {
55+
try {
56+
if (shouldMic) {
57+
if (!audioTrack.isPlaying) {
58+
audioTrack.play();
59+
// dispose this track on next track update
60+
disposer = () => audioTrack.stop();
61+
}
62+
} else {
63+
if (audioTrack.isPlaying) {
64+
audioTrack.stop();
65+
}
66+
}
67+
} catch (e) {
68+
console.error(e);
5569
}
56-
} catch (e) {
57-
console.error(e);
5870
}
59-
}
71+
return disposer;
72+
}, "audio-track");
6073
}),
6174
);
6275

6376
this._sideEffect.addDisposer(
6477
combine([this._el$, this._videoTrack$, this._shouldCamera$]).subscribe(
6578
([el, videoTrack, shouldCamera]) => {
66-
if (el && videoTrack) {
67-
try {
68-
if (shouldCamera) {
69-
videoTrack.play(el);
70-
} else {
71-
videoTrack.stop();
79+
this._sideEffect.add(() => {
80+
let disposer = (): void => void 0;
81+
if (el && videoTrack) {
82+
try {
83+
if (shouldCamera) {
84+
if (!videoTrack.isPlaying) {
85+
videoTrack.play(el);
86+
// dispose this track on next track update
87+
disposer = () => videoTrack.stop();
88+
}
89+
} else {
90+
if (videoTrack.isPlaying) {
91+
videoTrack.stop();
92+
}
93+
}
94+
} catch (e) {
95+
console.error(e);
7296
}
73-
} catch (e) {
74-
console.error(e);
7597
}
76-
}
98+
return disposer;
99+
}, "video-track");
77100
},
78101
),
79102
);

services/rtc/flat-rtc-agora-web/src/rtc-share-screen.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import type {
2-
IAgoraRTCClient,
3-
IAgoraRTCRemoteUser,
4-
ILocalVideoTrack,
5-
IRemoteVideoTrack,
6-
} from "agora-rtc-sdk-ng";
1+
import type { IAgoraRTCClient, ILocalVideoTrack, IRemoteVideoTrack } from "agora-rtc-sdk-ng";
72
import { SideEffectManager } from "side-effect-manager";
83
import { Val } from "value-enhancer";
94
import { FlatRTCShareScreen, FlatRTCShareScreenParams } from "@netless/flat-rtc";
@@ -23,7 +18,7 @@ export class RTCShareScreen extends FlatRTCShareScreen {
2318
private readonly _params$ = new Val<RTCShareScreenParams | null>(null);
2419
private readonly _enabled$ = new Val(false);
2520

26-
private readonly _remoteUser$ = new Val<IAgoraRTCRemoteUser | null>(null);
21+
private readonly _remoteVideoTrack$ = new Val<IRemoteVideoTrack | null>(null);
2722
private readonly _el$: Val<HTMLElement | null>;
2823

2924
public readonly client: IAgoraRTCClient;
@@ -38,9 +33,12 @@ export class RTCShareScreen extends FlatRTCShareScreen {
3833
this._el$ = new Val(config.element ?? null);
3934

4035
this._sideEffect.addDisposer(
41-
this._remoteUser$.subscribe(user => {
42-
if (user && user.videoTrack) {
43-
this.remoteVideoTrack = user.videoTrack;
36+
this._remoteVideoTrack$.subscribe(remoteVideoTrack => {
37+
if (remoteVideoTrack) {
38+
if (this.remoteVideoTrack) {
39+
this.remoteVideoTrack.stop();
40+
}
41+
this.remoteVideoTrack = remoteVideoTrack;
4442
if (this._el$.value && !this.localVideoTrack) {
4543
this.remoteVideoTrack.play(this._el$.value);
4644
}
@@ -63,7 +61,7 @@ export class RTCShareScreen extends FlatRTCShareScreen {
6361

6462
this._sideEffect.addDisposer(
6563
this._enabled$.subscribe(async enabled => {
66-
if (enabled && this._remoteUser$.value) {
64+
if (enabled && this._remoteVideoTrack$.value) {
6765
this.events.emit(
6866
"err-enable",
6967
new Error("There already exists remote screen track."),
@@ -88,16 +86,16 @@ export class RTCShareScreen extends FlatRTCShareScreen {
8886
return !this._enabled$.value;
8987
}
9088

91-
public setRemoteUser(remoteUser: IAgoraRTCRemoteUser | null): void {
92-
this._remoteUser$.setValue(remoteUser);
89+
public setRemoteVideoTrack(remoteVideoTrack: IRemoteVideoTrack | null): void {
90+
this._remoteVideoTrack$.setValue(remoteVideoTrack);
9391
}
9492

9593
public setParams(params: RTCShareScreenParams | null): void {
9694
this._params$.setValue(params);
9795
}
9896

9997
public enable(enabled: boolean): void {
100-
if (enabled && this._remoteUser$.value) {
98+
if (enabled && this._remoteVideoTrack$.value) {
10199
throw new Error("There already exists remote screen track.");
102100
}
103101
this._enabled$.setValue(enabled);

0 commit comments

Comments
 (0)