ActiveSpeakerObserver will not work properly if I immediately add a fresh Producer.

Hi here,
I’m trying to understand why the “dominantspeaker” listener does not work if I add a fresh Producer to an ActiveSpeakerObserver (activeSpeakerObserver.addProducer()). To make it work I must give it some time by wrapping it with setTimeout.

Can someone explain why it works like? What can I do instead of using setTimeout?

Thanks :slight_smile:

Imagine this,

You send two messages to your producer server really fast, the server gets your producer request first but it’s stuck waiting for the completion, your other request gets there second but beats your first request.

The timeout would definitely work in your case but when the server is under load it would take a longer timeout just to be sure in those cases.


Media server should be queuing all tasks and be completing each one, one by one. This way order is kept and you don’t run into racing issues, which absolutely suck in production.

1 Like

@BronzedBroth Thanks for the heads up. Do you know why or experienced this problem before?

This code doesn’t work:

const producer = transport.produce(...)
activeSpeakerObserver.on('dominantspeaker', (dominantSpeaker) => {
   console.log('Called');
});
activeSpeakerObserver.addProducer({ producerId: producer.id  });

Result
-> "Called" is printed as soon as activeSpeakerObserver.addProducer({ producerId: producer.id }) but later it will never work

This code work:

const producer = transport.produce(...)
activeSpeakerObserver.on('dominantspeaker', (dominantSpeaker) => {
   console.log('Called');
});
setTimeout(() => {
 activeSpeakerObserver.addProducer({ producerId: producer.id  });
}, 3000);

Result

This work correctly
-> "Called"
-> "Called"
-> .... 

Please report it in mediasoup GitHub as a bug.

1 Like

@ibc Ok, I opened an issue on GitHub. ActiveSpeakerObserver: "dominantspeaker" listener does not work properly if I immediately add a fresh Producer. · Issue #901 · versatica/mediasoup · GitHub

Transport.produce(params).then((track)=>{
// Producer exists, we can call addProducer for our track at anytime now.
});

This is not a mediasoup problem.

The issue is that you’re not awaiting the callback of your produce function before calling addProducer. It’s no wonder that setTimeout solves yours issues because you’re waiting long enough produce should had resolved.

Change your code and you’ll be fine.


Seems like you may not had studied up at all on JS Async for some reason would be my guess because I only see you forcing synchronous for the most-part and that’s breaking everything on you.


Reading the GitHub seems you were told as well, you had seemed to use await in your code which is correct but if it’s not called asynchronously it’ll error out as your issue details.

By putting await I think the Producer should be ready for ActiveSpeakerObserver also the “dominantspeaker” listener got entered once before this stopped working so I think the activeSpeakerObserver.addProducer() is successful.

Other information:
I’m not just using ActiveSpeakerObserver but also AudioLevelObserver. The AudioLevelObserver is just working fine. In that case, If the producer is not ready the AudioLevelObserver will also have a problem but it’s not.

const producer = await transport.produce(...);
audioLevelObserver.addProducer({ producerId: producer.id  }); // this work fine
activeSpeakerObserver.addProducer({ producerId: producer.id  }); // the same producer but doesn't work properly.
1 Like

Looks indeed like a bug. Let’s handle this in the reported issue in GH.

Nice find.

Has it been resolved. Cause in my case also audioLevelObserver is working fine but activeSpeakerObserver’s dominantspeaker event callback is being called only once, immediately when producer is added to it for the first time.