in src/task/CreatePeerConnectionTask.ts [139:232]
private addRemoteVideoTrack(track: MediaStreamTrack, stream: MediaStream): void {
const trackId = stream.id;
const attendeeId = this.context.videoStreamIndex.attendeeIdForTrack(trackId);
let skipAdding: boolean;
let tile: VideoTile;
if (this.context.videoTileController.getVideoTileForAttendeeId) {
tile = this.context.videoTileController.getVideoTileForAttendeeId(attendeeId);
skipAdding = !!tile?.state()?.boundVideoStream;
} else {
skipAdding = this.context.videoTileController.haveVideoTileForAttendeeId(attendeeId);
}
if (skipAdding) {
this.context.logger.info(
`Not adding remote track. Already have tile for attendeeId: ${attendeeId}`
);
return;
}
if (!tile) {
tile = this.context.videoTileController.addVideoTile();
this.logger.info(`Created video tile ${tile.id()}`);
}
let streamId: number | null = this.context.videoStreamIndex.streamIdForTrack(trackId);
if (typeof streamId === 'undefined') {
this.logger.warn(`stream not found for tile=${tile.id()} track=${trackId}`);
streamId = null;
}
let groupId = this.context.videoStreamIndex.groupIdForStreamId(streamId);
if (groupId === undefined) {
groupId = null;
}
for (let i = 0; i < this.trackEvents.length; i++) {
const trackEvent: string = this.trackEvents[i];
const videoTracks = stream.getVideoTracks();
if (videoTracks && videoTracks.length) {
const videoTrack: MediaStreamTrack = videoTracks[0];
const callback: EventListenerOrEventListenerObject = (): void => {
this.context.logger.info(
`received the ${trackEvent} event for tile=${tile.id()} id=${
track.id
} streamId=${streamId}`
);
if (trackEvent === 'ended') {
this.removeRemoteVideoTrack(track, tile.state());
}
};
videoTrack.addEventListener(trackEvent, callback);
if (!this.removeVideoTrackEventListeners[track.id]) {
this.removeVideoTrackEventListeners[track.id] = [];
}
this.removeVideoTrackEventListeners[track.id].push(() => {
videoTrack.removeEventListener(trackEvent, callback);
});
}
}
let width: number;
let height: number;
if (track.getSettings) {
const cap: MediaTrackSettings = track.getSettings();
width = cap.width as number;
height = cap.height as number;
} else {
const cap: MediaTrackCapabilities = track.getCapabilities();
width = cap.width as number;
height = cap.height as number;
}
const externalUserId = this.context.videoStreamIndex.externalUserIdForTrack(trackId);
tile.bindVideoStream(
attendeeId,
false,
stream,
width,
height,
streamId,
externalUserId,
groupId
);
this.logger.info(
`video track added, use tile=${tile.id()} track=${trackId} streamId=${streamId} groupId=${groupId}`
);
const endEvent = 'removetrack';
const target: MediaStream = stream;
const trackRemovedHandler = (): void => this.removeRemoteVideoTrack(track, tile.state());
this.removeTrackRemovedEventListeners[track.id] = () => {
target.removeEventListener(endEvent, trackRemovedHandler);
delete this.removeTrackRemovedEventListeners[track.id];
};
target.addEventListener(endEvent, trackRemovedHandler);
}