# Display active speaker in canvas

**URL:** <https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411>\
**Category:** Web\
**Created:** [November 18, 2021, 10:41am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411 "2021-11-18T10:41:02Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![ALanois](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alanois/32/33827_2.png) [@ALanois](https://devforum.zoom.us/u/ALanois)\
**Post date:** [November 18, 2021, 10:41am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/1 "2021-11-18T10:41:02Z")

</div>

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 :

```auto
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 ?

---

<div class="post-metadata">

**Author:** ![vic.yang](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/vic.yang/32/24656_2.png) [@vic.yang](https://devforum.zoom.us/u/vic.yang)\
**Post date:** [November 19, 2021, 7:09am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/2 "2021-11-19T07:09:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![ALanois](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alanois/32/33827_2.png) [@ALanois](https://devforum.zoom.us/u/ALanois)\
**Post date:** [November 19, 2021, 8:08am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/3 "2021-11-19T08:08:47Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![vic.yang](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/vic.yang/32/24656_2.png) [@vic.yang](https://devforum.zoom.us/u/vic.yang)\
**Post date:** [November 19, 2021, 9:15am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/4 "2021-11-19T09:15:55Z")

</div>

Hey @ALanois

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

Thanks  
Vic

---

<div class="post-metadata">

**Author:** ![ALanois](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alanois/32/33827_2.png) [@ALanois](https://devforum.zoom.us/u/ALanois)\
**Post date:** [November 23, 2021, 10:42am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/5 "2021-11-23T10:42:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ALanois](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alanois/32/33827_2.png) [@ALanois](https://devforum.zoom.us/u/ALanois)\
**Post date:** [November 25, 2021, 10:33am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/6 "2021-11-25T10:33:45Z")

</div>

Up  
I still not found a solution 😕

---

<div class="post-metadata">

**Author:** ![ALanois](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alanois/32/33827_2.png) [@ALanois](https://devforum.zoom.us/u/ALanois)\
**Post date:** [November 30, 2021, 8:15am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/7 "2021-11-30T08:15:35Z")

</div>

Up 🙏  
I still not found a solution 😢

---

<div class="post-metadata">

**Author:** ![vic.yang](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/vic.yang/32/24656_2.png) [@vic.yang](https://devforum.zoom.us/u/vic.yang)\
**Post date:** [November 30, 2021, 9:00am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/8 "2021-11-30T09:00:41Z")

</div>

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：

```auto
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

---

<div class="post-metadata">

**Author:** ![ALanois](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alanois/32/33827_2.png) [@ALanois](https://devforum.zoom.us/u/ALanois)\
**Post date:** [December 1, 2021, 9:58am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/10 "2021-12-01T09:58:05Z")

</div>

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 ?

---

<div class="post-metadata">

**Author:** ![vic.yang](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/vic.yang/32/24656_2.png) [@vic.yang](https://devforum.zoom.us/u/vic.yang)\
**Post date:** [December 1, 2021, 10:20am UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/11 "2021-12-01T10:20:10Z")

</div>

Hey @ALanois

Yes. That’s correct.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/6/1/614bdd549b610bbaa46ff934617683a02bdaa03c.png) [@system](https://devforum.zoom.us/u/system)\
**Post date:** [December 31, 2021, 8:20pm UTC](https://devforum.zoom.us/t/display-active-speaker-in-canvas/60411/12 "2021-12-31T20:20:26Z")

</div>

Closed on December 31, 2021, 8:20pm UTC

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
