Преглед изворни кода

Merge branch 'talk-muted'

dev1
Lyubomir Marinov пре 9 година
родитељ
комит
15f6154cb0

+ 7
- 0
JitsiConference.js Прегледај датотеку

@@ -20,6 +20,7 @@ var VideoType = require('./service/RTC/VideoType');
20 20
 var Transcriber = require("./modules/transcription/transcriber");
21 21
 var ParticipantConnectionStatus
22 22
     = require("./modules/connectivity/ParticipantConnectionStatus");
23
+import TalkMutedDetection from "./modules/TalkMutedDetection";
23 24
 
24 25
 /**
25 26
  * Creates a JitsiConference object with the given name and properties.
@@ -116,6 +117,12 @@ JitsiConference.prototype._init = function (options) {
116 117
     // Always add listeners because on reload we are executing leave and the
117 118
     // listeners are removed from statistics module.
118 119
     this.eventManager.setupStatisticsListeners();
120
+
121
+    if (this.options.config.enableTalkWhileMuted) {
122
+        new TalkMutedDetection(this, () => {
123
+            this.eventEmitter.emit(JitsiConferenceEvents.TALK_WHILE_MUTED);
124
+        });
125
+    }
119 126
 }
120 127
 
121 128
 /**

+ 4
- 0
JitsiConferenceEvents.js Прегледај датотеку

@@ -118,6 +118,10 @@ export const STARTED_MUTED = "conference.started_muted";
118 118
  * Indicates that subject of the conference has changed.
119 119
  */
120 120
 export const SUBJECT_CHANGED = "conference.subjectChanged";
121
+/**
122
+ * Event indicates that local user is talking while he muted himself
123
+ */
124
+export const TALK_WHILE_MUTED = "conference.talk_while_muted";
121 125
 /**
122 126
  * A new media track was added to the conference. The event provides the
123 127
  * following parameters to its listeners:

+ 1
- 0
doc/API.md Прегледај датотеку

@@ -219,6 +219,7 @@ This objects represents the server connection. You can create new ```JitsiConnec
219 219
         3. jirecon
220 220
         4. callStatsID - callstats credentials
221 221
         5. callStatsSecret - callstats credentials
222
+        6. enableTalkWhileMuted - boolean property. Enables/disables talk while muted detection, by default the value is false/disabled.
222 223
         **NOTE: if 4 and 5 are set the library is going to send events to callstats. Otherwise the callstats integration will be disabled.**
223 224
 
224 225
 5. addEventListener(event, listener) - Subscribes the passed listener to the event.

+ 110
- 0
modules/TalkMutedDetection.js Прегледај датотеку

@@ -0,0 +1,110 @@
1
+import * as JitsiConferenceEvents from "../JitsiConferenceEvents";
2
+
3
+export default class TalkMutedDetection {
4
+    /**
5
+     * Creates TalkMutedDetection
6
+     * @param conference the JitsiConference instance that created us.
7
+     * @param callback the callback to call when detected that the local user is
8
+     * talking while her microphone is muted.
9
+     * @constructor
10
+     */
11
+    constructor(conference, callback) {
12
+        /**
13
+         * The callback to call when detected that the local user is talking
14
+         * while her microphone is muted.
15
+         *
16
+         * @private
17
+         */
18
+        this._callback = callback;
19
+
20
+        /**
21
+         * The indicator which determines whether <tt>callback</tt> has been
22
+         * invoked for the current local audio track of <tt>conference</tt> so
23
+         * that it is invoked once only.
24
+         *
25
+         * @private
26
+         */
27
+        this._eventFired = false;
28
+
29
+        // XXX I went back and forth on the subject of where to put the access
30
+        // to statistics. On the one had, (1) statistics is likely intended to
31
+        // be private to conference and (2) there is a desire to keep the
32
+        // dependencies of modules to the minimum (i.e. not have
33
+        // TalkMutedDetection depend on statistics). On the other hand, (1)
34
+        // statistics is technically not private because
35
+        // JitsiConferenceEventManager accesses it and (2) TalkMutedDetection
36
+        // works exactly because it knows that there are no audio levels for
37
+        // JitsiLocalTrack but there are audio levels for the local participant
38
+        // through statistics.
39
+        conference.statistics.addAudioLevelListener(
40
+            this._audioLevel.bind(this));
41
+
42
+        conference.on(
43
+            JitsiConferenceEvents.TRACK_MUTE_CHANGED,
44
+            this._trackMuteChanged.bind(this));
45
+        conference.on(
46
+            JitsiConferenceEvents.TRACK_ADDED,
47
+            this._trackAdded.bind(this));
48
+    }
49
+
50
+    /**
51
+     * Receives audio level events for all send and receive streams.
52
+     *
53
+     * @param ssrc - The synchronization source identifier (SSRC) of the
54
+     * endpoint/participant/stream being reported.
55
+     * @param {number} audioLevel - The audio level of <tt>ssrc</tt>.
56
+     * @param {boolean} isLocal - <tt>true</tt> if <tt>ssrc</tt> represents a
57
+     * local/send stream or <tt>false</tt> for a remote/receive stream.
58
+     */
59
+    _audioLevel(ssrc, audioLevel, isLocal) {
60
+        // We are interested in the local audio stream only and if event is not
61
+        // sent yet.
62
+        if (!isLocal || !this.audioTrack || this._eventFired)
63
+            return;
64
+
65
+        if (this.audioTrack.isMuted() && audioLevel > 0.6) {
66
+            this._eventFired = true;
67
+            this._callback();
68
+        }
69
+    }
70
+
71
+    /**
72
+     * Determines whether a specific {@link JitsiTrack} represents a local audio
73
+     * track.
74
+     *
75
+     * @param {JitsiTrack} track - The <tt>JitsiTrack</tt> to be checked whether
76
+     * it represents a local audio track.
77
+     * @private
78
+     * @return {boolean} - <tt>true</tt> if the specified <tt>track</tt>
79
+     * represents a local audio track; otherwise, <tt>false</tt>.
80
+     */
81
+    _isLocalAudioTrack(track) {
82
+        return track.isAudioTrack() && track.isLocal();
83
+    }
84
+
85
+    /**
86
+     * Notifies this <tt>TalkMutedDetection</tt> that a {@link JitsiTrack} was
87
+     * added to the associated {@link JitsiConference}. Looks for the local
88
+     * audio track only.
89
+     *
90
+     * @param {JitsiTrack} track - The added <tt>JitsiTrack</tt>.
91
+     * @private
92
+     */
93
+    _trackAdded(track) {
94
+        if (this._isLocalAudioTrack(track))
95
+            this.audioTrack = track;
96
+    }
97
+
98
+    /**
99
+     * Notifies this <tt>TalkMutedDetection</tt> that the mute state of a
100
+     * {@link JitsiTrack} has changed. Looks for the local audio track only.
101
+     *
102
+     * @param {JitsiTrack} track - The <tt>JitsiTrack</tt> whose mute state has
103
+     * changed.
104
+     * @private
105
+     */
106
+    _trackMuteChanged(track) {
107
+        if (this._isLocalAudioTrack(track) && track.isMuted())
108
+            this._eventFired = false;
109
+    }
110
+}

+ 9
- 9
modules/statistics/RTPStatsCollector.js Прегледај датотеку

@@ -1,10 +1,10 @@
1 1
 /* global require */
2 2
 /* jshint -W101 */
3 3
 
4
+var GlobalOnErrorHandler = require("../util/GlobalOnErrorHandler");
4 5
 var logger = require("jitsi-meet-logger").getLogger(__filename);
5 6
 var RTCBrowserType = require("../RTC/RTCBrowserType");
6
-var StatisticsEvents = require("../../service/statistics/Events");
7
-var GlobalOnErrorHandler = require("../util/GlobalOnErrorHandler");
7
+import * as StatisticsEvents from "../../service/statistics/Events";
8 8
 
9 9
 /* Whether we support the browser we are running into for logging statistics */
10 10
 var browserSupported = RTCBrowserType.isChrome() ||
@@ -731,9 +731,9 @@ StatsCollector.prototype.processStatsReport = function () {
731 731
             calculatePacketLoss(lostPackets.upload, totalPackets.upload)
732 732
     };
733 733
     this.eventEmitter.emit(StatisticsEvents.CONNECTION_STATS, {
734
+            "bandwidth": this.conferenceStats.bandwidth,
734 735
             "bitrate": this.conferenceStats.bitrate,
735 736
             "packetLoss": this.conferenceStats.packetLoss,
736
-            "bandwidth": this.conferenceStats.bandwidth,
737 737
             "resolution": resolutions,
738 738
             "transport": this.conferenceStats.transport
739 739
         });
@@ -753,10 +753,8 @@ StatsCollector.prototype.processAudioLevelReport = function () {
753 753
     for (var idx in this.currentAudioLevelsReport) {
754 754
         var now = this.currentAudioLevelsReport[idx];
755 755
 
756
-        //if we don't have "packetsReceived" this is local stream
757
-        if (now.type != 'ssrc' || !getStatValue(now, 'packetsReceived')) {
756
+        if (now.type != 'ssrc')
758 757
             continue;
759
-        }
760 758
 
761 759
         var before = this.baselineAudioLevelsReport[idx];
762 760
         var ssrc = getStatValue(now, 'ssrc');
@@ -788,12 +786,14 @@ StatsCollector.prototype.processAudioLevelReport = function () {
788 786
         }
789 787
 
790 788
         if (audioLevel) {
791
-            // TODO: can't find specs about what this value really is,
792
-            // but it seems to vary between 0 and around 32k.
789
+            const isLocal = !getStatValue(now, 'packetsReceived');
790
+
791
+            // TODO: Can't find specs about what this value really is, but it
792
+            // seems to vary between 0 and around 32k.
793 793
             audioLevel = audioLevel / 32767;
794 794
             ssrcStats.setSsrcAudioLevel(audioLevel);
795 795
             this.eventEmitter.emit(
796
-                StatisticsEvents.AUDIO_LEVEL, ssrc, audioLevel);
796
+                StatisticsEvents.AUDIO_LEVEL, ssrc, audioLevel, isLocal);
797 797
         }
798 798
     }
799 799
 };

+ 6
- 6
modules/statistics/statistics.js Прегледај датотеку

@@ -1,13 +1,13 @@
1 1
 /* global require */
2
-var LocalStats = require("./LocalStatsCollector.js");
3
-var logger = require("jitsi-meet-logger").getLogger(__filename);
4
-var RTPStats = require("./RTPStatsCollector.js");
5
-var EventEmitter = require("events");
6
-var StatisticsEvents = require("../../service/statistics/Events");
7 2
 var AnalyticsAdapter = require("./AnalyticsAdapter");
8 3
 var CallStats = require("./CallStats");
9
-var ScriptUtil = require('../util/ScriptUtil');
4
+var EventEmitter = require("events");
10 5
 import JitsiTrackError from "../../JitsiTrackError";
6
+var logger = require("jitsi-meet-logger").getLogger(__filename);
7
+var LocalStats = require("./LocalStatsCollector.js");
8
+var RTPStats = require("./RTPStatsCollector.js");
9
+var ScriptUtil = require('../util/ScriptUtil');
10
+import * as StatisticsEvents from "../../service/statistics/Events";
11 11
 
12 12
 /**
13 13
  * True if callstats API is loaded

+ 33
- 18
service/statistics/Events.js Прегледај датотеку

@@ -1,18 +1,33 @@
1
-module.exports = {
2
-    /**
3
-     * FIXME: needs documentation.
4
-     */
5
-    AUDIO_LEVEL: "statistics.audioLevel",
6
-    /**
7
-     * Notifies about audio problem with remote participant.
8
-     */
9
-    AUDIO_NOT_WORKING: "statistics.audio_not_working",
10
-    /**
11
-     * An event carrying connection statistics.
12
-     */
13
-    CONNECTION_STATS: "statistics.connectionstats",
14
-    /**
15
-     * An event carrying all statistics by ssrc.
16
-     */
17
-    BYTE_SENT_STATS: "statistics.byte_sent_stats"
18
-};
1
+/**
2
+ * Notifies about audio level in RTP statistics by SSRC.
3
+ *
4
+ * @param ssrc - The synchronization source identifier (SSRC) of the
5
+ * endpoint/participant whose audio level is being reported.
6
+ * @param {number} audioLevel - The audio level of <tt>ssrc</tt> according to
7
+ * RTP statistics.
8
+ * @param {boolean} isLocal - <tt>true</tt> if <tt>ssrc</tt> identifies the
9
+ * local endpoint/participant; otherwise, <tt>false</tt>.
10
+ */
11
+export const AUDIO_LEVEL = "statistics.audioLevel";
12
+
13
+/**
14
+ * Notifies about audio problem with remote participant.
15
+ *
16
+ * @param ssrc - The synchronization source identifier (SSRC) of the remote
17
+ * participant whose audio exhibits problems.
18
+ */
19
+export const AUDIO_NOT_WORKING = "statistics.audio_not_working";
20
+
21
+/**
22
+ * An event carrying all statistics by ssrc.
23
+ */
24
+export const BYTE_SENT_STATS = "statistics.byte_sent_stats";
25
+
26
+/**
27
+ * An event carrying connection statistics.
28
+ *
29
+ * @param {object} connectionStats - The connection statistics carried by the
30
+ * event such as <tt>bandwidth</tt>, <tt>bitrate</tt>, <tt>packetLoss</tt>,
31
+ * <tt>resolution</tt>, and <tt>transport</tt>.
32
+ */
33
+export const CONNECTION_STATS = "statistics.connectionstats";

Loading…
Откажи
Сачувај