Skip to content

Commit 8038d22

Browse files
committed
feat(DSI) Calculate dominant speakers locally when audio susbscription is enabled on client.
1 parent 8e4be76 commit 8038d22

File tree

12 files changed

+1129
-8
lines changed

12 files changed

+1129
-8
lines changed

JitsiConferenceEventManager.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Statistics from './modules/statistics/statistics';
99
import EventEmitterForwarder from './modules/util/EventEmitterForwarder';
1010
import { MediaType } from './service/RTC/MediaType';
1111
import RTCEvents from './service/RTC/RTCEvents';
12+
import { ReceiverAudioSubscription } from './service/RTC/ReceiverAudioSubscription';
1213
import AuthenticationEvents
1314
from './service/authentication/AuthenticationEvents';
1415
import {
@@ -466,8 +467,27 @@ export default class JitsiConferenceEventManager {
466467
RTCEvents.REMOTE_TRACK_REMOVED,
467468
conference.onRemoteTrackRemoved.bind(conference));
468469

470+
rtc.addListener(
471+
RTCEvents.AUDIO_SUBSCRIPTION_MODE_CHANGED,
472+
(mode, list) => {
473+
conference.eventEmitter.emit(
474+
JitsiConferenceEvents.AUDIO_SUBSCRIPTION_MODE_CHANGED, mode, list);
475+
476+
// We need to update the speaker list if audio subscription mode changes such that it triggers a
477+
// dominant speaker change based on the remote audio levels.
478+
if (conference.statistics && mode !== ReceiverAudioSubscription.ALL) {
479+
const remoteSpeakerIds = Array.isArray(list) ? list.map(source => source.split('-')[0]) : [];
480+
481+
conference.statistics.setSpeakerList(remoteSpeakerIds);
482+
}
483+
}
484+
);
485+
469486
rtc.addListener(RTCEvents.DOMINANT_SPEAKER_CHANGED,
470487
(dominant, previous, silence) => {
488+
if (conference.statistics.dominantSpeakerEnabled) {
489+
return;
490+
}
471491
if ((conference.lastDominantSpeaker !== dominant || conference.dominantSpeakerIsSilent !== silence)
472492
&& conference.room) {
473493
conference.lastDominantSpeaker = dominant;
@@ -658,14 +678,16 @@ export default class JitsiConferenceEventManager {
658678
conference.rtc.setAudioLevel(tpc, ssrc, level, isLocal);
659679
});
660680

661-
/* eslint-enable max-params */
662-
663681
// Forward the "before stats disposed" event
664682
conference.statistics.addBeforeDisposedListener(() => {
665683
conference.eventEmitter.emit(
666684
JitsiConferenceEvents.BEFORE_STATISTICS_DISPOSED);
667685
});
668686

687+
conference.statistics.addDominantSpeakerListener((tpc, dominant, previous) => {
688+
conference.eventEmitter.emit(JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED, dominant, previous);
689+
});
690+
669691
conference.statistics.addEncodeTimeStatsListener((tpc, stats) => {
670692
conference.eventEmitter.emit(
671693
JitsiConferenceEvents.ENCODE_TIME_STATS_RECEIVED, tpc, stats);

JitsiConferenceEvents.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as exported from "./JitsiConferenceEvents";
55
describe( "/JitsiConferenceEvents members", () => {
66
const {
77
AUDIO_INPUT_STATE_CHANGE,
8+
AUDIO_SUBSCRIPTION_MODE_CHANGED,
89
AUDIO_UNMUTE_PERMISSIONS_CHANGED,
910
AUTH_STATUS_CHANGED,
1011
BEFORE_STATISTICS_DISPOSED,
@@ -98,6 +99,7 @@ describe( "/JitsiConferenceEvents members", () => {
9899

99100
it( "known members", () => {
100101
expect( AUDIO_INPUT_STATE_CHANGE ).toBe( 'conference.audio_input_state_changed' );
102+
expect( AUDIO_SUBSCRIPTION_MODE_CHANGED ).toBe( 'conference.audio_subscription_mode_changed' );
101103
expect( AUDIO_UNMUTE_PERMISSIONS_CHANGED ).toBe( 'conference.audio_unmute_permissions_changed' );
102104
expect( AUTH_STATUS_CHANGED ).toBe( 'conference.auth_status_changed' );
103105
expect( BEFORE_STATISTICS_DISPOSED ).toBe( 'conference.beforeStatisticsDisposed' );
@@ -185,6 +187,7 @@ describe( "/JitsiConferenceEvents members", () => {
185187
expect( JitsiConferenceEvents ).toBeDefined();
186188

187189
expect( JitsiConferenceEvents.AUDIO_INPUT_STATE_CHANGE ).toBe( 'conference.audio_input_state_changed' );
190+
expect( JitsiConferenceEvents.AUDIO_SUBSCRIPTION_MODE_CHANGED ).toBe( 'conference.audio_subscription_mode_changed' );
188191
expect( JitsiConferenceEvents.AUDIO_UNMUTE_PERMISSIONS_CHANGED ).toBe( 'conference.audio_unmute_permissions_changed' );
189192
expect( JitsiConferenceEvents.AUTH_STATUS_CHANGED ).toBe( 'conference.auth_status_changed' );
190193
expect( JitsiConferenceEvents.BEFORE_STATISTICS_DISPOSED ).toBe( 'conference.beforeStatisticsDisposed' );

JitsiConferenceEvents.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ export enum JitsiConferenceEvents {
99
*/
1010
AUDIO_INPUT_STATE_CHANGE = 'conference.audio_input_state_changed',
1111

12+
/**
13+
* Event indicates that the audio subscription mode changed.
14+
*/
15+
AUDIO_SUBSCRIPTION_MODE_CHANGED = 'conference.audio_subscription_mode_changed',
1216
/**
1317
* Event indicates that the permission for unmuting audio has changed based on the number of audio senders in the
1418
* call and the audio sender limit configured in Jicofo.
@@ -534,6 +538,7 @@ export enum JitsiConferenceEvents {
534538
export const _MEDIA_SESSION_STARTED = JitsiConferenceEvents._MEDIA_SESSION_STARTED;
535539
export const _MEDIA_SESSION_ACTIVE_CHANGED = JitsiConferenceEvents._MEDIA_SESSION_ACTIVE_CHANGED;
536540
export const AUDIO_INPUT_STATE_CHANGE = JitsiConferenceEvents.AUDIO_INPUT_STATE_CHANGE;
541+
export const AUDIO_SUBSCRIPTION_MODE_CHANGED = JitsiConferenceEvents.AUDIO_SUBSCRIPTION_MODE_CHANGED;
537542
export const AUDIO_UNMUTE_PERMISSIONS_CHANGED = JitsiConferenceEvents.AUDIO_UNMUTE_PERMISSIONS_CHANGED;
538543
export const AUTH_STATUS_CHANGED = JitsiConferenceEvents.AUTH_STATUS_CHANGED;
539544
export const AV_MODERATION_APPROVED = JitsiConferenceEvents.AV_MODERATION_APPROVED;

modules/qualitycontrol/ReceiveAudioController.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { getLogger } from '@jitsi/logger';
33
import { isEqual } from 'lodash-es';
44

55
import JitsiConference from '../../JitsiConference';
6+
import { MediaType } from '../../service/RTC/MediaType';
7+
import RTCEvents from '../../service/RTC/RTCEvents';
68
import { IReceiverAudioSubscriptionMessage, ReceiverAudioSubscription } from '../../service/RTC/ReceiverAudioSubscription';
79
import RTC from '../RTC/RTC';
810

@@ -13,6 +15,11 @@ const logger = getLogger('modules/qualitycontrol/ReceiveAudioController');
1315
* based on different modes such as ALL, EXCLUDE, INCLUDE, and NONE.
1416
*/
1517
export class ReceiverAudioController {
18+
19+
/**
20+
* The JitsiConference instance associated with this controller.
21+
*/
22+
private _conference: JitsiConference;
1623
private _rtc: RTC;
1724

1825
/**
@@ -30,6 +37,7 @@ export class ReceiverAudioController {
3037
* Creates a new instance of the ReceiverAudioController.
3138
*/
3239
constructor(conference: JitsiConference) {
40+
this._conference = conference;
3341
this._rtc = conference.rtc;
3442
this._sourceList = [];
3543
this._subscriptionMode = ReceiverAudioSubscription.ALL;
@@ -70,6 +78,7 @@ export class ReceiverAudioController {
7078
return;
7179
}
7280
this._subscriptionMode = message.mode;
81+
7382
if (message.mode == ReceiverAudioSubscription.INCLUDE
7483
|| message.mode == ReceiverAudioSubscription.EXCLUDE) {
7584

@@ -92,5 +101,10 @@ export class ReceiverAudioController {
92101
list: this._sourceList,
93102
mode: this._subscriptionMode
94103
});
104+
105+
this._rtc.eventEmitter.emit(RTCEvents.AUDIO_SUBSCRIPTION_MODE_CHANGED, {
106+
list: this._sourceList,
107+
mode: this._subscriptionMode
108+
});
95109
}
96110
}

0 commit comments

Comments
 (0)