Skip to content

Commit

Permalink
fix(flat-web): always play tracks on user published (#743)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyrious committed Jun 16, 2021
1 parent 0f7d0e0 commit 4fd0bcd
Showing 1 changed file with 41 additions and 51 deletions.
92 changes: 41 additions & 51 deletions web/flat-web/src/apiMiddleware/rtc/avatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import type {
IAgoraRTCClient,
IAgoraRTCRemoteUser,
ICameraVideoTrack,
ILocalTrack,
IMicrophoneAudioTrack,
IRemoteAudioTrack,
IRemoteVideoTrack,
ITrack,
} from "agora-rtc-sdk-ng";
import AgoraRTC from "agora-rtc-sdk-ng";
Expand Down Expand Up @@ -33,23 +32,12 @@ export class RtcAvatar {
public videoTrack?: ITrack;

private readonly isLocal: boolean;
private readonly remoteAudioTrack: Promise<IRemoteAudioTrack>;
private readonly remoteVideoTrack: Promise<IRemoteVideoTrack>;

private resolveRemoteAudioTrack?: (value: IRemoteAudioTrack) => void;
private resolveRemoteVideoTrack?: (value: IRemoteVideoTrack) => void;

constructor({ rtc, userUUID, avatarUser }: RtcAvatarParams) {
this.rtc = rtc;
this.userUUID = userUUID;
this.avatarUser = avatarUser;
this.isLocal = userUUID === avatarUser.userUUID;
this.remoteAudioTrack = new Promise<IRemoteAudioTrack>(resolve => {
this.resolveRemoteAudioTrack = resolve;
});
this.remoteVideoTrack = new Promise<IRemoteVideoTrack>(resolve => {
this.resolveRemoteVideoTrack = resolve;
});
if (!this.isLocal) {
this.setupExistingTracks();
this.client.on("user-published", this.onUserPublished);
Expand All @@ -65,48 +53,64 @@ export class RtcAvatar {
if (exist) {
if (exist.hasAudio) {
const audioTrack = await this.client.subscribe(exist, "audio");
this.resolveRemoteAudioTrack?.(audioTrack);
this.resolveRemoteAudioTrack = undefined;
audioTrack.play();
}
if (exist.hasVideo) {
const videoTrack = await this.client.subscribe(exist, "video");
this.resolveRemoteVideoTrack?.(videoTrack);
this.resolveRemoteVideoTrack = undefined;
this.element && videoTrack.play(this.element);
}
}
}

public destroy(): void {
public async destroy(): Promise<void> {
const { audioTrack, videoTrack } = this;
const tracks: ITrack[] = [];
if (audioTrack) {
this.audioTrack = undefined;
tracks.push(audioTrack);
}
if (videoTrack) {
this.videoTrack = undefined;
tracks.push(videoTrack);
}
if (this.isLocal) {
const { audioTrack, videoTrack } = this;
if (audioTrack) {
this.audioTrack = undefined;
(audioTrack as IMicrophoneAudioTrack).close();
if (tracks.length > 0) {
try {
await this.client.unpublish(tracks as ILocalTrack[]);
} catch (error) {
console.info("unpublish failed", error);
}
}
if (videoTrack) {
this.videoTrack = undefined;
(videoTrack as ICameraVideoTrack).close();
for (const track of tracks) {
(track as ILocalTrack).close();
}
}
if (!this.isLocal && this.client) {
} else {
this.client.off("user-published", this.onUserPublished);
}
this.resolveRemoteAudioTrack = undefined;
this.resolveRemoteVideoTrack = undefined;
}

private onUserPublished = async (
user: IAgoraRTCRemoteUser,
mediaType: "video" | "audio",
): Promise<void> => {
if (user.uid === this.avatarUser.rtcUID) {
if (mediaType === "audio") {
this.audioTrack?.stop();
} else {
this.videoTrack?.stop();
}
try {
await this.client.unsubscribe(user, mediaType);
} catch (error) {
console.info("unsubscribe failed", error);
}
const track = await this.client.subscribe(user, mediaType);
if (mediaType === "audio") {
this.resolveRemoteAudioTrack?.(track as IRemoteAudioTrack);
this.resolveRemoteAudioTrack = undefined;
this.audioTrack = track;
this.audioTrack.play();
} else {
this.resolveRemoteVideoTrack?.(track as IRemoteVideoTrack);
this.resolveRemoteVideoTrack = undefined;
this.videoTrack = track;
this.element && this.videoTrack.play(this.element);
}
}
};
Expand All @@ -116,20 +120,14 @@ export class RtcAvatar {
if (this.isLocal) {
const videoTrack = this.videoTrack as ICameraVideoTrack | undefined;
if (videoTrack) {
videoTrack.setEnabled(enable);
await videoTrack.setEnabled(enable);
} else if (enable) {
const videoTrack = await AgoraRTC.createCameraVideoTrack({
encoderConfig: { width: 288, height: 216 },
});
this.videoTrack = videoTrack;
this.element && videoTrack.play(this.element);
await this.client.publish([videoTrack]);
}
} else {
if (!this.videoTrack && enable) {
const videoTrack = await this.remoteVideoTrack;
this.videoTrack = videoTrack;
this.element && videoTrack.play(this.element);
await this.client.publish(videoTrack);
}
}
} catch (error) {
Expand All @@ -142,25 +140,17 @@ export class RtcAvatar {
if (this.isLocal) {
const audioTrack = this.audioTrack as IMicrophoneAudioTrack | undefined;
if (audioTrack) {
audioTrack.setEnabled(enable);
await audioTrack.setEnabled(enable);
} else if (enable) {
const audioTrack = await AgoraRTC.createMicrophoneAudioTrack();
this.audioTrack = audioTrack;
// NOTE: playing local audio track may cause echo
// NOTE: playing local audio track causes echo
// audioTrack.play();
await this.client.publish(audioTrack);
}
} else {
if (!this.audioTrack && enable) {
const audioTrack = await this.remoteAudioTrack;
this.audioTrack = audioTrack;
audioTrack.play();
}
}
} catch (error) {
console.info("setMic failed", error);
}
}
}

(window as any).RtcAvatar = RtcAvatar;

0 comments on commit 4fd0bcd

Please sign in to comment.