Skip to content

Commit

Permalink
fix: sfu migration issues
Browse files Browse the repository at this point in the history
- Duplicate tiles on migration
- Screenshare not getting removed
- add audio/video plugins on migration
  • Loading branch information
raviteja83 authored Aug 1, 2024
1 parent c58345b commit fea3737
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 41 deletions.
13 changes: 12 additions & 1 deletion examples/prebuilt-react-integration/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,16 @@ export default function App() {
return <Diagnostics />;
}

return <HMSPrebuilt roomCode={roomCode} />;
return (
<HMSPrebuilt
roomCode={roomCode}
options={{
endpoints: {
tokenByRoomCode: 'https://auth-nonprod.100ms.live/v2/token',
roomLayout: 'https://api-nonprod.100ms.live/v2/layouts/ui',
init: 'https://qa-in2-ipv6.100ms.live/init',
},
}}
/>
);
}
11 changes: 10 additions & 1 deletion packages/hms-video-store/src/media/tracks/HMSLocalAudioTrack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,23 @@ export class HMSLocalAudioTrack extends HMSAudioTrack {
}

clone(stream?: HMSLocalStream) {
return new HMSLocalAudioTrack(
const track = new HMSLocalAudioTrack(
stream || (this.stream as HMSLocalStream).clone(),
this.nativeTrack.clone(),
this.source!,
this.eventBus,
this.settings,
this.room,
);

if (this.pluginsManager.pluginsMap.size > 0) {
this.pluginsManager.pluginsMap.forEach(value => {
track
.addPlugin(value)
.catch((e: Error) => HMSLogger.e(this.TAG, 'Plugin add failed while migrating', value, e));
});
}
return track;
}

getManuallySelectedDeviceId() {
Expand Down
13 changes: 12 additions & 1 deletion packages/hms-video-store/src/media/tracks/HMSLocalVideoTrack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,25 @@ export class HMSLocalVideoTrack extends HMSVideoTrack {
}

clone(stream?: HMSLocalStream) {
return new HMSLocalVideoTrack(
const track = new HMSLocalVideoTrack(
stream || (this.stream as HMSLocalStream).clone(),
this.nativeTrack.clone(),
this.source!,
this.eventBus,
this.settings,
this.room,
);
if (this.pluginsManager.pluginsMap.size > 0) {
this.pluginsManager.pluginsMap.forEach(value => {
track
.addPlugin(value)
.catch((e: Error) => HMSLogger.e(this.TAG, 'Plugin add failed while migrating', value, e));
});
}
if (this.mediaStreamPluginsManager.plugins.size > 0) {
track.addStreamPlugins(Array.from(this.mediaStreamPluginsManager.plugins));
}
return track;
}

/** @internal */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,11 @@ export class TrackManager {
};

handleTrackRemovedPermanently = (notification: TrackStateNotification) => {
HMSLogger.d(this.TAG, `ONTRACKREMOVE`, notification);
HMSLogger.d(this.TAG, `ONTRACKREMOVE permanently`, notification);
const trackIds = Object.keys(notification.tracks);

trackIds.forEach(trackId => {
const trackStateEntry = this.store.getTrackState(trackId);

if (!trackStateEntry) {
return;
}
Expand Down Expand Up @@ -205,7 +204,6 @@ export class TrackManager {
track.type === HMSTrackType.AUDIO
? this.eventBus.audioTrackAdded.publish({ track: track as HMSRemoteAudioTrack, peer: hmsPeer as HMSRemotePeer })
: this.listener?.onTrackUpdate(HMSTrackUpdate.TRACK_ADDED, track, hmsPeer);
this.store.removeTrackState(track.trackId);
this.tracksToProcess.delete(track.trackId);
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class HMSAudioPluginsManager {
private readonly TAG = '[AudioPluginsManager]';
private readonly hmsTrack: HMSLocalAudioTrack;
// Map maintains the insertion order
private readonly pluginsMap: Map<string, HMSAudioPlugin>;
readonly pluginsMap: Map<string, HMSAudioPlugin>;
private audioContext?: AudioContext;

private sourceNode?: MediaStreamAudioSourceNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import HMSLogger from '../../utils/logger';
export class HMSMediaStreamPluginsManager {
private readonly TAG = '[MediaStreamPluginsManager]';
private analytics: VideoPluginsAnalytics;
private plugins: Set<HMSMediaStreamPlugin>;
readonly plugins: Set<HMSMediaStreamPlugin>;
private room?: Room;

constructor(eventBus: EventBus, room?: Room) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class HMSVideoPluginsManager {
private pluginsLoopRunning = false;
private pluginsLoopState: 'paused' | 'running' = 'paused';
private readonly hmsTrack: HMSLocalVideoTrack;
private readonly pluginsMap: Map<string, HMSVideoPlugin>; // plugin names to their instance mapping
readonly pluginsMap: Map<string, HMSVideoPlugin>; // plugin names to their instance mapping
private inputVideo?: HTMLVideoElement;
private inputCanvas?: CanvasElement;
private outputCanvas?: CanvasElement;
Expand Down
9 changes: 9 additions & 0 deletions packages/hms-video-store/src/sdk/store/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ class Store {
this.simulcastEnabled = enabled;
}

removeRemoteTracks() {
this.tracks.forEach(track => {
if (track instanceof HMSRemoteAudioTrack || track instanceof HMSRemoteVideoTrack) {
this.removeTrack(track);
delete this.peerTrackStates[track.trackId];
}
});
}

getEnv() {
return this.env;
}
Expand Down
51 changes: 19 additions & 32 deletions packages/hms-video-store/src/transport/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,36 +431,26 @@ export default class HMSTransport {
// eslint-disable-next-line complexity
async handleSFUMigration() {
HMSLogger.time('sfu migration');
this.clearPeerConnections();
const peers = this.store.getPeerMap();
this.store.removeRemoteTracks();
for (const peerId in peers) {
const peer = peers[peerId];
if (peer.isLocal) {
continue;
}
if (peer.audioTrack) {
this.store.removeTrack(peer.audioTrack);
peer.audioTrack = undefined;
}
if (peer.videoTrack) {
this.store.removeTrack(peer.videoTrack);
peer.videoTrack = undefined;
}
while (peer.auxiliaryTracks.length > 0) {
const track = peer.auxiliaryTracks.shift();
if (track) {
this.store.removeTrack(track);
}
}
peer.audioTrack = undefined;
peer.videoTrack = undefined;
peer.auxiliaryTracks = [];
}
this.clearPeerConnections();
this.createPeerConnections();
await this.negotiateOnFirstPublish();

const localPeer = this.store.getLocalPeer();
if (!localPeer) {
return;
}

let tracksToPublish = [];
this.createPeerConnections();
this.trackStates.clear();
await this.negotiateOnFirstPublish();
const streamMap = new Map<string, HMSLocalStream>();
if (localPeer.audioTrack) {
const stream = localPeer.audioTrack.stream as HMSLocalStream;
Expand All @@ -469,7 +459,8 @@ export default class HMSTransport {
}
const newTrack = localPeer.audioTrack.clone(streamMap.get(stream.id));
this.store.removeTrack(localPeer.audioTrack);
tracksToPublish.push(newTrack);
localPeer.audioTrack.cleanup();
await this.publishTrack(newTrack);
localPeer.audioTrack = newTrack;
}

Expand All @@ -480,7 +471,8 @@ export default class HMSTransport {
}
this.store.removeTrack(localPeer.videoTrack);
const newTrack = localPeer.videoTrack.clone(streamMap.get(stream.id));
tracksToPublish.push(newTrack);
localPeer.videoTrack.cleanup();
await this.publishTrack(newTrack);
localPeer.videoTrack = newTrack;
}

Expand All @@ -497,16 +489,13 @@ export default class HMSTransport {
if (newTrack.type === 'video' && newTrack.source === 'screen') {
newTrack.nativeTrack.addEventListener('ended', this.onScreenshareStop);
}
track.cleanup();
await this.publishTrack(newTrack);
auxTracks.push(newTrack);
}
}
localPeer.auxiliaryTracks = auxTracks;
tracksToPublish = tracksToPublish.concat(auxTracks);
streamMap.clear();
for (const track of tracksToPublish) {
await this.publishTrack(track);
// this.listener?.onTrackUpdate(HMSTrackUpdate.TRACK_ADDED, track, localPeer);
}
this.listener?.onSFUMigration?.();
HMSLogger.timeEnd('sfu migration');
}
Expand Down Expand Up @@ -573,7 +562,7 @@ export default class HMSTransport {
HMSLogger.d(TAG, `✅ publishTrack: trackId=${track.trackId}`, `${track}`, this.callbacks);
}

private async unpublishTrack(track: HMSLocalTrack, sfuMigration = false): Promise<void> {
private async unpublishTrack(track: HMSLocalTrack): Promise<void> {
HMSLogger.d(TAG, `⏳ unpublishTrack: trackId=${track.trackId}`, `${track}`);
if (track.publishedTrackId && this.trackStates.has(track.publishedTrackId)) {
this.trackStates.delete(track.publishedTrackId);
Expand All @@ -599,11 +588,9 @@ export default class HMSTransport {
const stream = track.stream as HMSLocalStream;
stream.removeSender(track);
await p;
if (!sfuMigration) {
await track.cleanup();
// remove track from store on unpublish
this.store.removeTrack(track);
}
await track.cleanup();
// remove track from store on unpublish
this.store.removeTrack(track);
HMSLogger.d(TAG, `✅ unpublishTrack: trackId=${track.trackId}`, this.callbacks);
}

Expand Down

0 comments on commit fea3737

Please sign in to comment.