onActiveSpeakerLoop method
void
onActiveSpeakerLoop()
Implementation
void onActiveSpeakerLoop() async {
String? nextActiveSpeaker;
// idc about screen sharing atm.
final userMediaStreamsCopyList = List.from(userMediaStreams);
for (final stream in userMediaStreamsCopyList) {
if (stream.userId == client.userID && stream.pc == null) {
continue;
}
final List<StatsReport> statsReport = await stream.pc!.getStats();
statsReport
.removeWhere((element) => !element.values.containsKey('audioLevel'));
// https://www.w3.org/TR/webrtc-stats/#summary
final otherPartyAudioLevel = statsReport
.singleWhereOrNull((element) =>
element.type == 'inbound-rtp' &&
element.values['kind'] == 'audio')
?.values['audioLevel'];
if (otherPartyAudioLevel != null) {
audioLevelsMap[stream.userId] = otherPartyAudioLevel;
}
// https://www.w3.org/TR/webrtc-stats/#dom-rtcstatstype-media-source
// firefox does not seem to have this though. Works on chrome and android
final ownAudioLevel = statsReport
.singleWhereOrNull((element) =>
element.type == 'media-source' &&
element.values['kind'] == 'audio')
?.values['audioLevel'];
if (ownAudioLevel != null &&
audioLevelsMap[client.userID] != ownAudioLevel) {
audioLevelsMap[client.userID!] = ownAudioLevel;
}
}
double maxAudioLevel = double.negativeInfinity;
// TODO: we probably want a threshold here?
audioLevelsMap.forEach((key, value) {
if (value > maxAudioLevel) {
nextActiveSpeaker = key;
maxAudioLevel = value;
}
});
if (nextActiveSpeaker != null && activeSpeaker != nextActiveSpeaker) {
activeSpeaker = nextActiveSpeaker;
onGroupCallEvent.add(GroupCallEvent.ActiveSpeakerChanged);
}
activeSpeakerLoopTimeout?.cancel();
activeSpeakerLoopTimeout =
Timer(activeSpeakerInterval, onActiveSpeakerLoop);
}