Display active speaker in canvas

Hello,
I’m trying to display active speaker’s video in the canvas but I can’t get the expected results.
Here is what I tried :

this.zoomCli.on('active-speaker', async (payload) => {
   console.log(`active-speaker`, payload);
   if(!this.meCanvas){
     this.meCanvas = document.getElementById('me-canvas');
   }
   if(this.currentSpeaker){
     if(this.currentSpeaker != payload[0].userId){
       await this.mediaStream.stopRenderVideo(this.meCanvas, this.currentSpeaker)
       this.mediaStream.clearVideoCanvas(this.meCanvas)
       await this.mediaStream.renderVideo(
         this.meCanvas,
         payload[0].userId,
         1280 / 2,
         640 / 2,
         0,
         0,
         2,
       ); 
       this.currentSpeaker = payload[0].userId
     }
   }else{
      await this.mediaStream.renderVideo(
      this.meCanvas,
      payload[0].userId,
      1280 / 2,
      640 / 2,
      0,
      0,
      2,
    ); 
    this.currentSpeaker = payload[0].userId
  }
});

Any idea ?

Hey @ALanois

Thanks for your feedback.

The userId in active-speaker event depends on the audio volume of participants, not directly relating to videos. video-active-change event may be a better choice.

Thanks
Vic

Thanks for your answer.

I need to get the userId of users who are actually talking to display their video. Based on the description for video-active-change, I don’t think it will do what I’m looking for.

Hey @ALanois

You may need add an additional conditional judgment, && payload[0].bVideoOn===true, and the clearVideoCanvas is unnecessary.

Thanks
Vic

Hello,
It still doesn’t give the expected result.
What I’m looking for is to switch the displayed video based on the speaker’s userId.

Up
I still not found a solution :confused:

Up :pray:
I still not found a solution :cry:

Hey @ALanois

The video-active-change event may address your concerns, let me elaborate the usage:

The payload of video-active-change event has two properties, state and userId, who should be active is judged by the server(depends on the volume of audio), thus it meets your requirement of the active speaker, and the next step is how to render the video, following is some pseudocode:

let currentActiveSpeaker = undefined;

const handleActiveVideo = ({state,userId})=>{
  if(state===VideoActiveState.Active){
    // active speaker changed
    if(userId!==currentActiveSpeaker.userId){
      // stop the previous active speaker's video
      if(currentActiveSpeaker?.bVideoOn){
        stream.stopRenderVideo(canvas,currentActiveSpeaker.userId)
      }
      // switch to the current active speaker
      stream.renderVideo(canvas,userId,width,height,x,y,quality)
    }
  }else{
    // active speaker don't turn on the video,
    if(currentActiveSpeaker?.bVideoOn){
      stream.stopRenderVideo(canvas,currentActiveSpeaker.userId)
    }
    // use dom element to display the active speaker
    // allUserList can be obtained by client.getAllUser() 
    const activeUser = allUserList.find(user=>user.userId===userId);
    setDisplayName(overlayAvatarElement,activeUser?.displayName);
  }
  currentActiveSpeaker = allUserList.find(user=>user.userId===userId)
}

client.on('video-active-change',handleActiveVideo);

Hope this can help you.

Thanks
Vic

Hello,
Thanks for the reply.
I tried to apply the code in my situation but I can’t get the expected result. I probably didn’t quite understand the use of “video-active-change”.
Does this event is triggered when a participant is speaking or when a user activate ?

Hey @ALanois

Yes. That’s correct.