Unable to bind Amazon Chime VideoTile to <video> in Angular

497 Views Asked by At

I'm creating angular client using Chime JS SDK. I'm able to create meeting and add attendees to the meeting. However there is no clear documentation on how to bind video tiles to UI on Angular. I'm trying this on videoTileDidUpdate event:

    const videoContainer = this.renderer.createElement('div');
    // Set the id of the div
    this.renderer.setProperty(videoContainer, 'id', "video-" + tileState.tileId);
    this.renderer.setProperty(videoContainer, 'class', "p-col");
    const videoTile = this.renderer.createElement('video');
    this.renderer.setProperty(videoTile, 'id', "tile-" + tileState.tileId);
    this.renderer.setProperty(videoTile, 'autoplay', "1");
  
    this.renderer.appendChild(videoContainer, videoTile);
    this.renderer.appendChild(videoElement.nativeElement, videoContainer);        

    this.meetingSession.audioVideo.bindVideoElement(tileState.tileId, videoTile);

The event gets triggered infinitely and infinite video elements are created. However there is no video. How to get the video showing on the video tag.

1

There are 1 best solutions below

0
On

I figured it out on my own. Posting it if someone is looking for it.

Instead of creating dynamic video elements on the fly, we need to use a set of video tags and get reference and bind them.

Template:

<div id="tile-container" class="tile-container" #video>
            <div id="tile-area" class="v-grid">
                <div id="tile-0" class="video-tile">
                    <video id="video-0" class="video-tile-video"></video>
                    <div id="attendeeid-0" class="video-tile-attendeeid"></div>
                    <div id="nameplate-0" class="video-tile-nameplate"></div>
                    <!-- <button id="video-pause-0" class="video-tile-pause">Pause</button> -->
                </div>
             </div>
        </div>

Reference it on the code.

@ViewChild('video', { static: false }) videoElement: ElementRef | undefined;

And then in tilDidUpdate observer bind it to the element.

videoTileDidUpdate(tileState: any) {

    console.log(`video tile updated: ${JSON.stringify(tileState, null, '  ')}`);
    if (!tileState.boundAttendeeId) {
      return;
    }
    const tileIndex = tileState.localTile
      ? 17
      : this.tileOrganizer.acquireTileIndex(tileState.tileId);

    const tileElement = this.videoElement?.nativeElement.querySelector(`#tile-${tileIndex}`) as HTMLDivElement;
    const videoElement = this.videoElement?.nativeElement.querySelector(`#video-${tileIndex}`) as HTMLVideoElement;
    const nameplateElement = document.getElementById(`nameplate-${tileIndex}`) as HTMLDivElement;
    const attendeeIdElement = document.getElementById(`attendeeid-${tileIndex}`) as HTMLDivElement;

    console.log(`binding video tile ${tileState.tileId}`);

    this.chimeVideoService.meetingSession.audioVideo.bindVideoElement(tileState.tileId, videoElement);
    this.tileIndexToTileId[tileIndex] = tileState.tileId;
    this.tileIdToTileIndex[tileState.tileId] = tileIndex;

    try {
      this.renderer.setProperty(nameplateElement, 'innerText', tileState.boundExternalUserId.split('#')[0]);
      this.renderer.setProperty(attendeeIdElement, 'innerText', tileState.boundAttendeeId);
    }
    catch (errr) {
      console.log(errr);
    }
}