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

Merge branch 'master' into reloads

dev1
hristoterezov пре 9 година
родитељ
комит
20db0e4051

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

63
         video: undefined
63
         video: undefined
64
     };
64
     };
65
     this.isMutedByFocus = false;
65
     this.isMutedByFocus = false;
66
+    this.reportedAudioSSRCs = {};
66
 }
67
 }
67
 
68
 
68
 /**
69
 /**
151
     }
152
     }
152
 
153
 
153
     this.room = null;
154
     this.room = null;
155
+
156
+    this.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
154
 }
157
 }
155
 /**
158
 /**
156
  * Leaves the conference.
159
  * Leaves the conference.
371
  */
374
  */
372
 JitsiConference.prototype.addTrack = function (track) {
375
 JitsiConference.prototype.addTrack = function (track) {
373
     if (track.disposed) {
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
     if (track.isVideoTrack()) {
381
     if (track.isVideoTrack()) {
383
             if (track === localVideoTrack) {
387
             if (track === localVideoTrack) {
384
                 return Promise.resolve(track);
388
                 return Promise.resolve(track);
385
             } else {
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
  * @returns {Promise}
492
  * @returns {Promise}
489
  */
493
  */
490
 JitsiConference.prototype.removeTrack = function (track) {
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
     if(!this.room){
500
     if(!this.room){
1096
         ssrc, track.isLocal(), track.getUsageLabel(), container.id);
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
  * Setups the listeners needed for the conference.
1161
  * Setups the listeners needed for the conference.
1101
  */
1162
  */

+ 19
- 12
modules/RTC/RTC.js Прегледај датотеку

415
         return this.conference.myUserId();
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
         callStats.fabricEvent.fabricTerminated, this.confID);
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
  * Notifies CallStats for ice connection failed
346
  * Notifies CallStats for ice connection failed
335
  * @param {RTCPeerConnection} pc connection on which failure occured.
347
  * @param {RTCPeerConnection} pc connection on which failure occured.

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

639
             bytesSent = Math.round(((bytesSent * 8) / time) / 1000);
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
         ssrcStats.setSsrcBitrate({
647
         ssrcStats.setSsrcBitrate({
643
             "download": bytesReceived,
648
             "download": bytesReceived,
644
             "upload": bytesSent
649
             "upload": bytesSent

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

146
     this.eventEmitter.on(StatisticsEvents.CONNECTION_STATS, listener);
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
 Statistics.prototype.removeConnectionStatsListener = function (listener) {
157
 Statistics.prototype.removeConnectionStatsListener = function (listener) {
150
     this.eventEmitter.removeListener(StatisticsEvents.CONNECTION_STATS, listener);
158
     this.eventEmitter.removeListener(StatisticsEvents.CONNECTION_STATS, listener);
151
 };
159
 };
388
         CallStats.sendAddIceCandidateFailed(e, pc, this.callstats);
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
  * Adds to CallStats an application log.
410
  * Adds to CallStats an application log.
393
  *
411
  *

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

7
      * FIXME: needs documentation.
7
      * FIXME: needs documentation.
8
      */
8
      */
9
     AUDIO_LEVEL: "statistics.audioLevel",
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
 };

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