private addRemoteVideoTrack()

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);
  }