ソースを参照

Merge branch 'master' into reloads

dev1
hristoterezov 9年前
コミット
20db0e4051

+ 67
- 6
JitsiConference.js ファイルの表示

@@ -63,6 +63,7 @@ function JitsiConference(options) {
63 63
         video: undefined
64 64
     };
65 65
     this.isMutedByFocus = false;
66
+    this.reportedAudioSSRCs = {};
66 67
 }
67 68
 
68 69
 /**
@@ -151,6 +152,8 @@ JitsiConference.prototype._leaveRoomAndRemoveParticipants = function () {
151 152
     }
152 153
 
153 154
     this.room = null;
155
+
156
+    this.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
154 157
 }
155 158
 /**
156 159
  * Leaves the conference.
@@ -371,7 +374,8 @@ JitsiConference.prototype.setSubject = function (subject) {
371 374
  */
372 375
 JitsiConference.prototype.addTrack = function (track) {
373 376
     if (track.disposed) {
374
-        throw new JitsiTrackError(JitsiTrackErrors.TRACK_IS_DISPOSED);
377
+        return Promise.reject(
378
+            new JitsiTrackError(JitsiTrackErrors.TRACK_IS_DISPOSED));
375 379
     }
376 380
 
377 381
     if (track.isVideoTrack()) {
@@ -383,8 +387,8 @@ JitsiConference.prototype.addTrack = function (track) {
383 387
             if (track === localVideoTrack) {
384 388
                 return Promise.resolve(track);
385 389
             } else {
386
-                throw new Error(
387
-                        "cannot add second video track to the conference");
390
+                return Promise.reject(new Error(
391
+                    "cannot add second video track to the conference"));
388 392
             }
389 393
         }
390 394
     }
@@ -488,9 +492,9 @@ JitsiConference.prototype._fireMuteChangeEvent = function (track) {
488 492
  * @returns {Promise}
489 493
  */
490 494
 JitsiConference.prototype.removeTrack = function (track) {
491
-    if(track.disposed)
492
-    {
493
-        throw new Error(JitsiTrackErrors.TRACK_IS_DISPOSED);
495
+    if (track.disposed) {
496
+        return Promise.reject(
497
+            new JitsiTrackError(JitsiTrackErrors.TRACK_IS_DISPOSED));
494 498
     }
495 499
 
496 500
     if(!this.room){
@@ -1096,6 +1100,63 @@ JitsiConference.prototype._onTrackAttach = function(track, container) {
1096 1100
         ssrc, track.isLocal(), track.getUsageLabel(), container.id);
1097 1101
 }
1098 1102
 
1103
+/**
1104
+ * Reports detected audio problem with the media stream related to the passed
1105
+ * ssrc.
1106
+ * @param ssrc {string} the ssrc
1107
+ */
1108
+JitsiConference.prototype._reportAudioProblem = function (ssrc) {
1109
+    if(this.reportedAudioSSRCs[ssrc])
1110
+        return;
1111
+    var track = this.rtc.getRemoteTrackBySSRC(ssrc);
1112
+    if(!track || !track.isAudioTrack())
1113
+        return;
1114
+
1115
+    this.reportedAudioSSRCs[ssrc] = true;
1116
+    var errorContent = {
1117
+        errMsg: "The audio is received but not played",
1118
+        ssrc: ssrc
1119
+    };
1120
+
1121
+    var mstream = track.stream, mtrack = track.track;
1122
+    if(mstream) {
1123
+        errorContent.MediaStream = {
1124
+            active: mstream.active,
1125
+            id: mstream.id
1126
+        }
1127
+    }
1128
+
1129
+    if(mtrack) {
1130
+        errorContent.MediaStreamTrack = {
1131
+            enabled: mtrack.enabled,
1132
+            id: mtrack.id,
1133
+            label: mtrack.label,
1134
+            muted: mtrack.muted
1135
+        }
1136
+    }
1137
+
1138
+    if(track.containers) {
1139
+        errorContent.containers = [];
1140
+        track.containers.forEach(function (container) {
1141
+            errorContent.containers.push({
1142
+                autoplay: container.autoplay,
1143
+                muted: container.muted,
1144
+                src: container.src,
1145
+                volume: container.volume,
1146
+                id: container.id,
1147
+                ended: container.ended,
1148
+                paused: container.paused,
1149
+                readyState: container.readyState
1150
+            });
1151
+        });
1152
+    }
1153
+
1154
+    this.statistics.sendDetectedAudioProblem(
1155
+        new Error(JSON.stringify(errorContent)));
1156
+    logger.error("Audio problem detected. The audio is received but not played",
1157
+        errorContent);
1158
+}
1159
+
1099 1160
 /**
1100 1161
  * Setups the listeners needed for the conference.
1101 1162
  */

+ 19
- 12
modules/RTC/RTC.js ファイルの表示

@@ -415,19 +415,26 @@ RTC.prototype.getResourceBySSRC = function (ssrc) {
415 415
         return this.conference.myUserId();
416 416
     }
417 417
 
418
-    var self = this;
419
-    var resultResource = null;
420
-    Object.keys(this.remoteTracks).some(function (resource) {
421
-        var audioTrack = self.getRemoteAudioTrack(resource);
422
-        var videoTrack = self.getRemoteVideoTrack(resource);
423
-        if((audioTrack && audioTrack.getSSRC() == ssrc) ||
424
-            (videoTrack && videoTrack.getSSRC() == ssrc)) {
425
-            resultResource = resource;
426
-            return true;
427
-        }
428
-    });
418
+    var track = this.getRemoteTrackBySSRC(ssrc);
419
+    return track? track.getParticipantId() : null;
420
+};
429 421
 
430
-    return resultResource;
422
+/**
423
+ * Searches in remoteTracks for the ssrc and returns the corresponding track.
424
+ * @param ssrc the ssrc to check.
425
+ */
426
+RTC.prototype.getRemoteTrackBySSRC = function (ssrc) {
427
+    for (var resource in this.remoteTracks) {
428
+        var track = this.getRemoteAudioTrack(resource);
429
+        if(track && track.getSSRC() == ssrc) {
430
+            return track;
431
+        }
432
+        track = this.getRemoteVideoTrack(resource);
433
+        if(track && track.getSSRC() == ssrc) {
434
+            return track;
435
+        }
436
+    }
437
+    return null;
431 438
 };
432 439
 
433 440
 /**

+ 12
- 0
modules/statistics/CallStats.js ファイルの表示

@@ -330,6 +330,18 @@ CallStats.prototype.sendTerminateEvent = _try_catch(function () {
330 330
         callStats.fabricEvent.fabricTerminated, this.confID);
331 331
 });
332 332
 
333
+/**
334
+ * Notifies CallStats that audio problems are detected.
335
+ *
336
+ * @param {Error} e error to send
337
+ * @param {CallStats} cs callstats instance related to the error (optional)
338
+ */
339
+CallStats.prototype.sendDetectedAudioProblem = _try_catch(function (e) {
340
+    CallStats._reportError.call(this, wrtcFuncNames.signalingError, e,
341
+        this.peerconnection);
342
+});
343
+
344
+
333 345
 /**
334 346
  * Notifies CallStats for ice connection failed
335 347
  * @param {RTCPeerConnection} pc connection on which failure occured.

+ 5
- 0
modules/statistics/RTPStatsCollector.js ファイルの表示

@@ -639,6 +639,11 @@ StatsCollector.prototype.processStatsReport = function () {
639 639
             bytesSent = Math.round(((bytesSent * 8) / time) / 1000);
640 640
         }
641 641
 
642
+        //detect audio issues (receiving data but audioLevel == 0)
643
+        if(bytesReceived > 10 && ssrcStats.ssrc2AudioLevel === 0) {
644
+            this.eventEmitter.emit(StatisticsEvents.AUDIO_NOT_WORKING, ssrc);
645
+        }
646
+
642 647
         ssrcStats.setSsrcBitrate({
643 648
             "download": bytesReceived,
644 649
             "upload": bytesSent

+ 18
- 0
modules/statistics/statistics.js ファイルの表示

@@ -146,6 +146,14 @@ Statistics.prototype.addConnectionStatsListener = function (listener) {
146 146
     this.eventEmitter.on(StatisticsEvents.CONNECTION_STATS, listener);
147 147
 };
148 148
 
149
+/**
150
+ * Adds listener for detected audio problems.
151
+ * @param listener the listener.
152
+ */
153
+Statistics.prototype.addAudioProblemListener = function (listener) {
154
+    this.eventEmitter.on(StatisticsEvents.AUDIO_NOT_WORKING, listener);
155
+};
156
+
149 157
 Statistics.prototype.removeConnectionStatsListener = function (listener) {
150 158
     this.eventEmitter.removeListener(StatisticsEvents.CONNECTION_STATS, listener);
151 159
 };
@@ -388,6 +396,16 @@ Statistics.prototype.sendAddIceCandidateFailed = function (e, pc) {
388 396
         CallStats.sendAddIceCandidateFailed(e, pc, this.callstats);
389 397
 };
390 398
 
399
+/**
400
+ * Notifies CallStats that audio problems are detected.
401
+ *
402
+ * @param {Error} e error to send
403
+ */
404
+Statistics.prototype.sendDetectedAudioProblem = function (e) {
405
+    if(this.callstats)
406
+        this.callstats.sendDetectedAudioProblem(e);
407
+};
408
+
391 409
 /**
392 410
  * Adds to CallStats an application log.
393 411
  *

+ 4
- 0
service/statistics/Events.js ファイルの表示

@@ -7,4 +7,8 @@ module.exports = {
7 7
      * FIXME: needs documentation.
8 8
      */
9 9
     AUDIO_LEVEL: "statistics.audioLevel",
10
+    /**
11
+     * Notifies about audio problem with remote participant.
12
+     */
13
+    AUDIO_NOT_WORKING: "statistics.audio_not_working"
10 14
 };

読み込み中…
キャンセル
保存