Browse Source

feat: Handle dominant speaker silence.

dev1
Hristo Terezov 3 years ago
parent
commit
d96dad7205

+ 22
- 19
JitsiConferenceEventManager.js View File

@@ -513,29 +513,32 @@ JitsiConferenceEventManager.prototype.setupRTCListeners = function() {
513 513
         conference.onRemoteTrackRemoved.bind(conference));
514 514
 
515 515
     rtc.addListener(RTCEvents.DOMINANT_SPEAKER_CHANGED,
516
-        (dominant, previous) => {
517
-            if (conference.lastDominantSpeaker !== dominant && conference.room) {
516
+        (dominant, previous, silence) => {
517
+            if ((conference.lastDominantSpeaker !== dominant || conference.dominantSpeakerIsSilent !== silence)
518
+                    && conference.room) {
518 519
                 conference.lastDominantSpeaker = dominant;
520
+                conference.dominantSpeakerIsSilent = silence;
519 521
                 conference.eventEmitter.emit(
520
-                    JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED, dominant, previous);
521
-
522
-                if (previous && previous.length) {
523
-                    const speakerList = previous.slice(0);
524
-
525
-                    // Add the dominant speaker to the top of the list (exclude self).
526
-                    if (conference.myUserId !== dominant) {
527
-                        speakerList.splice(0, 0, dominant);
528
-                    }
529
-
530
-                    // Trim the list to the top 5 speakers only.
531
-                    if (speakerList.length > SPEAKERS_AUDIO_LEVELS) {
532
-                        speakerList.splice(SPEAKERS_AUDIO_LEVELS, speakerList.length - SPEAKERS_AUDIO_LEVELS);
533
-                    }
534
-                    conference.statistics && conference.statistics.setSpeakerList(speakerList);
535
-                }
522
+                    JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED, dominant, previous, silence);
536 523
                 if (conference.statistics && conference.myUserId() === dominant) {
537 524
                     // We are the new dominant speaker.
538
-                    conference.statistics.sendDominantSpeakerEvent(conference.room.roomjid);
525
+                    conference.statistics.sendDominantSpeakerEvent(conference.room.roomjid, silence);
526
+                }
527
+                if (conference.lastDominantSpeaker !== dominant) {
528
+                    if (previous && previous.length) {
529
+                        const speakerList = previous.slice(0);
530
+
531
+                        // Add the dominant speaker to the top of the list (exclude self).
532
+                        if (conference.myUserId !== dominant) {
533
+                            speakerList.splice(0, 0, dominant);
534
+                        }
535
+
536
+                        // Trim the list to the top 5 speakers only.
537
+                        if (speakerList.length > SPEAKERS_AUDIO_LEVELS) {
538
+                            speakerList.splice(SPEAKERS_AUDIO_LEVELS, speakerList.length - SPEAKERS_AUDIO_LEVELS);
539
+                        }
540
+                        conference.statistics && conference.statistics.setSpeakerList(speakerList);
541
+                    }
539 542
                 }
540 543
             }
541 544
         });

+ 2
- 2
modules/RTC/BridgeChannel.js View File

@@ -333,10 +333,10 @@ export default class BridgeChannel {
333 333
 
334 334
             switch (colibriClass) {
335 335
             case 'DominantSpeakerEndpointChangeEvent': {
336
-                const { dominantSpeakerEndpoint, previousSpeakers = [] } = obj;
336
+                const { dominantSpeakerEndpoint, previousSpeakers = [], silence } = obj;
337 337
 
338 338
                 logger.debug(`Dominant speaker: ${dominantSpeakerEndpoint}, previous speakers: ${previousSpeakers}`);
339
-                emitter.emit(RTCEvents.DOMINANT_SPEAKER_CHANGED, dominantSpeakerEndpoint, previousSpeakers);
339
+                emitter.emit(RTCEvents.DOMINANT_SPEAKER_CHANGED, dominantSpeakerEndpoint, previousSpeakers, silence);
340 340
                 break;
341 341
             }
342 342
             case 'EndpointConnectivityStatusChangeEvent': {

+ 28
- 10
modules/statistics/SpeakerStats.js View File

@@ -23,6 +23,8 @@ class SpeakerStats {
23 23
         this.setDominantSpeaker(false);
24 24
         this.totalDominantSpeakerTime = 0;
25 25
         this._dominantSpeakerStart = 0;
26
+        this._isDominantSpeaker = false;
27
+        this._isSilent = false;
26 28
         this._hasLeft = false;
27 29
         this._faceExpressions = {
28 30
             happy: 0,
@@ -78,7 +80,7 @@ class SpeakerStats {
78 80
      * @returns {boolean}
79 81
      */
80 82
     isDominantSpeaker() {
81
-        return this._dominantSpeakerStart > 0;
83
+        return this._isDominantSpeaker;
82 84
     }
83 85
 
84 86
     /**
@@ -87,18 +89,34 @@ class SpeakerStats {
87 89
      * @param {boolean} - If true, the user will being accumulating time
88 90
      * as dominant speaker. If false, the user will not accumulate time
89 91
      * and will record any time accumulated since starting as dominant speaker.
92
+     * @param {boolean} silence - Indecates whether the dominant speaker is silent or not.
90 93
      * @returns {void}
91 94
      */
92
-    setDominantSpeaker(isNowDominantSpeaker) {
93
-        if (!this.isDominantSpeaker() && isNowDominantSpeaker) {
95
+    setDominantSpeaker(isNowDominantSpeaker, silence) {
96
+        if (!this.isDominantSpeaker() && isNowDominantSpeaker && !silence) {
94 97
             this._dominantSpeakerStart = Date.now();
95
-        } else if (this.isDominantSpeaker() && !isNowDominantSpeaker) {
96
-            const now = Date.now();
97
-            const timeElapsed = now - this._dominantSpeakerStart;
98
-
99
-            this.totalDominantSpeakerTime += timeElapsed;
100
-            this._dominantSpeakerStart = 0;
98
+        } else if (this.isDominantSpeaker()) {
99
+            if (!isNowDominantSpeaker) {
100
+                if (!this._isSilent) {
101
+                    const now = Date.now();
102
+                    const timeElapsed = now - this._dominantSpeakerStart;
103
+
104
+                    this.totalDominantSpeakerTime += timeElapsed;
105
+                    this._dominantSpeakerStart = 0;
106
+                }
107
+            } else if (this._isSilent && !silence) {
108
+                this._dominantSpeakerStart = Date.now();
109
+            } else if (!this._isSilent && silence) {
110
+                const now = Date.now();
111
+                const timeElapsed = now - this._dominantSpeakerStart;
112
+
113
+                this.totalDominantSpeakerTime += timeElapsed;
114
+                this._dominantSpeakerStart = 0;
115
+            }
101 116
         }
117
+
118
+        this._isDominantSpeaker = isNowDominantSpeaker;
119
+        this._isSilent = silence;
102 120
     }
103 121
 
104 122
     /**
@@ -109,7 +127,7 @@ class SpeakerStats {
109 127
     getTotalDominantSpeakerTime() {
110 128
         let total = this.totalDominantSpeakerTime;
111 129
 
112
-        if (this.isDominantSpeaker()) {
130
+        if (this.isDominantSpeaker() && !this._isSilent) {
113 131
             total += Date.now() - this._dominantSpeakerStart;
114 132
         }
115 133
 

+ 5
- 4
modules/statistics/SpeakerStatsCollector.js View File

@@ -55,18 +55,19 @@ export default class SpeakerStatsCollector {
55 55
      * Reacts to dominant speaker change events by changing its speaker stats
56 56
      * models to reflect the current dominant speaker.
57 57
      *
58
-     * @param {string} dominantSpeakerId - The user id of the new
59
-     * dominant speaker.
58
+     * @param {string} dominantSpeakerId - The user id of the new dominant speaker.
59
+     * @param {Array[string]} previous - The array with previous speakers.
60
+     * @param {boolean} silence - Indecates whether the dominant speaker is silent or not.
60 61
      * @returns {void}
61 62
      * @private
62 63
      */
63
-    _onDominantSpeaker(dominantSpeakerId) {
64
+    _onDominantSpeaker(dominantSpeakerId, previous, silence) {
64 65
         const oldDominantSpeaker
65 66
             = this.stats.users[this.stats.dominantSpeakerId];
66 67
         const newDominantSpeaker = this.stats.users[dominantSpeakerId];
67 68
 
68 69
         oldDominantSpeaker && oldDominantSpeaker.setDominantSpeaker(false);
69
-        newDominantSpeaker && newDominantSpeaker.setDominantSpeaker(true);
70
+        newDominantSpeaker && newDominantSpeaker.setDominantSpeaker(true, silence);
70 71
         this.stats.dominantSpeakerId = dominantSpeakerId;
71 72
     }
72 73
 

+ 3
- 2
modules/statistics/statistics.js View File

@@ -614,14 +614,15 @@ Statistics.prototype.sendScreenSharingEvent
614 614
  * Notifies the statistics module that we are now the dominant speaker of the
615 615
  * conference.
616 616
  * @param {String} roomJid - The room jid where the speaker event occurred.
617
+ * @param {boolean} silence - Whether the dominant speaker is silent or not.
617 618
  */
618
-Statistics.prototype.sendDominantSpeakerEvent = function(roomJid) {
619
+Statistics.prototype.sendDominantSpeakerEvent = function(roomJid, silence) {
619 620
     for (const cs of this.callsStatsInstances.values()) {
620 621
         cs.sendDominantSpeakerEvent();
621 622
     }
622 623
 
623 624
     // xmpp send dominant speaker event
624
-    this.xmpp.sendDominantSpeakerEvent(roomJid);
625
+    this.xmpp.sendDominantSpeakerEvent(roomJid, silence);
625 626
 };
626 627
 
627 628
 /**

+ 4
- 2
modules/xmpp/xmpp.js View File

@@ -914,8 +914,9 @@ export default class XMPP extends Listenable {
914 914
      * Notifies speaker stats component if available that we are the new
915 915
      * dominant speaker in the conference.
916 916
      * @param {String} roomJid - The room jid where the speaker event occurred.
917
+     * @param {boolean} silence - Whether the dominant speaker is silent or not.
917 918
      */
918
-    sendDominantSpeakerEvent(roomJid) {
919
+    sendDominantSpeakerEvent(roomJid, silence) {
919 920
         // no speaker stats component advertised
920 921
         if (!this.speakerStatsComponentAddress || !roomJid) {
921 922
             return;
@@ -925,7 +926,8 @@ export default class XMPP extends Listenable {
925 926
 
926 927
         msg.c('speakerstats', {
927 928
             xmlns: 'http://jitsi.org/jitmeet',
928
-            room: roomJid })
929
+            room: roomJid,
930
+            silence })
929 931
             .up();
930 932
 
931 933
         this.connection.send(msg);

+ 4
- 1
types/auto/modules/statistics/SpeakerStats.d.ts View File

@@ -22,6 +22,8 @@ declare class SpeakerStats {
22 22
     _isLocalStats: boolean;
23 23
     totalDominantSpeakerTime: number;
24 24
     _dominantSpeakerStart: number;
25
+    _isDominantSpeaker: boolean;
26
+    _isSilent: boolean;
25 27
     _hasLeft: boolean;
26 28
     _faceExpressions: {
27 29
         happy: number;
@@ -70,9 +72,10 @@ declare class SpeakerStats {
70 72
      * @param {boolean} - If true, the user will being accumulating time
71 73
      * as dominant speaker. If false, the user will not accumulate time
72 74
      * and will record any time accumulated since starting as dominant speaker.
75
+     * @param {boolean} silence - Indecates whether the dominant speaker is silent or not.
73 76
      * @returns {void}
74 77
      */
75
-    setDominantSpeaker(isNowDominantSpeaker: any): void;
78
+    setDominantSpeaker(isNowDominantSpeaker: any, silence: boolean): void;
76 79
     /**
77 80
      * Get how long the tracked user has been dominant speaker.
78 81
      *

+ 3
- 2
types/auto/modules/statistics/SpeakerStatsCollector.d.ts View File

@@ -20,8 +20,9 @@ export default class SpeakerStatsCollector {
20 20
      * Reacts to dominant speaker change events by changing its speaker stats
21 21
      * models to reflect the current dominant speaker.
22 22
      *
23
-     * @param {string} dominantSpeakerId - The user id of the new
24
-     * dominant speaker.
23
+     * @param {string} dominantSpeakerId - The user id of the new dominant speaker.
24
+     * @param {Array[string]} previous - The array with previous speakers.
25
+     * @param {boolean} silence - Indecates whether the dominant speaker is silent or not.
25 26
      * @returns {void}
26 27
      * @private
27 28
      */

+ 2
- 1
types/auto/modules/statistics/statistics.d.ts View File

@@ -170,8 +170,9 @@ declare class Statistics {
170 170
      * Notifies the statistics module that we are now the dominant speaker of the
171 171
      * conference.
172 172
      * @param {String} roomJid - The room jid where the speaker event occurred.
173
+     * @param {boolean} silence - Whether the dominant speaker is silent or not.
173 174
      */
174
-    sendDominantSpeakerEvent(roomJid: string): void;
175
+    sendDominantSpeakerEvent(roomJid: string, silence: boolean): void;
175 176
     /**
176 177
      * Lets the underlying statistics module know where is given SSRC rendered by
177 178
      * providing renderer tag ID.

+ 2
- 1
types/auto/modules/xmpp/xmpp.d.ts View File

@@ -238,8 +238,9 @@ export default class XMPP extends Listenable {
238 238
      * Notifies speaker stats component if available that we are the new
239 239
      * dominant speaker in the conference.
240 240
      * @param {String} roomJid - The room jid where the speaker event occurred.
241
+     * @param {boolean} silence - Whether the dominant speaker is silent or not.
241 242
      */
242
-    sendDominantSpeakerEvent(roomJid: string): void;
243
+    sendDominantSpeakerEvent(roomJid: string, silence: boolean): void;
243 244
     /**
244 245
      * Sends face expressions to speaker stats component.
245 246
      * @param {String} roomJid - The room jid where the speaker event occurred.

Loading…
Cancel
Save