|
@@ -26,6 +26,7 @@ function JitsiConference(options) {
|
26
|
26
|
this.rtc = new RTC(this.room, options);
|
27
|
27
|
setupListeners(this);
|
28
|
28
|
this.participants = {};
|
|
29
|
+ this.lastActiveSpeaker = null;
|
29
|
30
|
}
|
30
|
31
|
|
31
|
32
|
/**
|
|
@@ -220,7 +221,11 @@ function setupListeners(conference) {
|
220
|
221
|
// conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
|
221
|
222
|
// });
|
222
|
223
|
conference.rtc.addListener(RTCEvents.DOMINANTSPEAKER_CHANGED, function (id) {
|
223
|
|
- conference.eventEmitter.emit(JitsiConferenceEvents.ACTIVE_SPEAKER_CHANGED, id);
|
|
224
|
+ if(conference.lastActiveSpeaker !== id && conference.room
|
|
225
|
+ && conference.room.myroomjid !== id) {
|
|
226
|
+ conference.lastActiveSpeaker = id;
|
|
227
|
+ conference.eventEmitter.emit(JitsiConferenceEvents.ACTIVE_SPEAKER_CHANGED, id);
|
|
228
|
+ }
|
224
|
229
|
});
|
225
|
230
|
|
226
|
231
|
conference.rtc.addListener(RTCEvents.LASTN_CHANGED, function (oldValue, newValue) {
|
|
@@ -845,6 +850,7 @@ function JitsiLocalTrack(RTC, stream, eventEmitter, videoType, isGUMStream)
|
845
|
850
|
this.videoType = videoType;
|
846
|
851
|
this.isGUMStream = true;
|
847
|
852
|
this.dontFireRemoveEvent = false;
|
|
853
|
+ this.isStarted = false;
|
848
|
854
|
var self = this;
|
849
|
855
|
if(isGUMStream === false)
|
850
|
856
|
this.isGUMStream = isGUMStream;
|
|
@@ -947,6 +953,7 @@ JitsiLocalTrack.prototype.stop = function () {
|
947
|
953
|
* NOTE: Works for local tracks only.
|
948
|
954
|
*/
|
949
|
955
|
JitsiLocalTrack.prototype.start = function() {
|
|
956
|
+ this.isStarted = true;
|
950
|
957
|
this.rtc.room.addStream(this.stream, function () {});
|
951
|
958
|
}
|
952
|
959
|
|
|
@@ -1220,7 +1227,6 @@ var DesktopSharingEventTypes
|
1220
|
1227
|
var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
|
1221
|
1228
|
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
|
1222
|
1229
|
var RTCEvents = require("../../service/RTC/RTCEvents.js");
|
1223
|
|
-var XMPPEvents = require("../../service/xmpp/XMPPEvents");
|
1224
|
1230
|
var desktopsharing = require("../desktopsharing/desktopsharing");
|
1225
|
1231
|
|
1226
|
1232
|
function getMediaStreamUsage()
|
|
@@ -1279,7 +1285,6 @@ function RTC(room, options) {
|
1279
|
1285
|
if(self.remoteStreams[from])
|
1280
|
1286
|
self.remoteStreams[from][JitsiTrack.AUDIO].setMute(values.value == "true");
|
1281
|
1287
|
});
|
1282
|
|
-
|
1283
|
1288
|
}
|
1284
|
1289
|
|
1285
|
1290
|
/**
|
|
@@ -1298,7 +1303,11 @@ RTC.prototype.obtainAudioAndVideoPermissions = function (options, dontCreateJits
|
1298
|
1303
|
RTC.prototype.onIncommingCall = function(event) {
|
1299
|
1304
|
if(this.options.config.openSctp)
|
1300
|
1305
|
this.dataChannels = new DataChannels(event.peerconnection, this.eventEmitter);
|
1301
|
|
- this.room.addLocalStreams(this.localStreams);
|
|
1306
|
+ for(var i = 0; i < this.localStreams.length; i++)
|
|
1307
|
+ if(this.localStreams[i].isStarted)
|
|
1308
|
+ {
|
|
1309
|
+ this.localStreams[i].start();
|
|
1310
|
+ }
|
1302
|
1311
|
}
|
1303
|
1312
|
|
1304
|
1313
|
RTC.prototype.selectedEndpoint = function (id) {
|
|
@@ -1565,7 +1574,7 @@ RTC.prototype.setDeviceAvailability = function (devices) {
|
1565
|
1574
|
|
1566
|
1575
|
module.exports = RTC;
|
1567
|
1576
|
|
1568
|
|
-},{"../../service/RTC/MediaStreamTypes":70,"../../service/RTC/RTCEvents.js":71,"../../service/RTC/StreamEventTypes.js":73,"../../service/desktopsharing/DesktopSharingEventTypes":75,"../../service/xmpp/XMPPEvents":76,"../desktopsharing/desktopsharing":17,"./DataChannels":9,"./JitsiLocalTrack.js":10,"./JitsiRemoteTrack.js":11,"./JitsiTrack":12,"./RTCBrowserType":14,"./RTCUtils.js":15,"events":77}],14:[function(require,module,exports){
|
|
1577
|
+},{"../../service/RTC/MediaStreamTypes":70,"../../service/RTC/RTCEvents.js":71,"../../service/RTC/StreamEventTypes.js":73,"../../service/desktopsharing/DesktopSharingEventTypes":75,"../desktopsharing/desktopsharing":17,"./DataChannels":9,"./JitsiLocalTrack.js":10,"./JitsiRemoteTrack.js":11,"./JitsiTrack":12,"./RTCBrowserType":14,"./RTCUtils.js":15,"events":77}],14:[function(require,module,exports){
|
1569
|
1578
|
|
1570
|
1579
|
var currentBrowser;
|
1571
|
1580
|
|
|
@@ -4903,6 +4912,7 @@ function JingleSessionPC(me, sid, connection, service) {
|
4903
|
4912
|
this.removessrc = [];
|
4904
|
4913
|
this.pendingop = null;
|
4905
|
4914
|
this.switchstreams = false;
|
|
4915
|
+ this.addingStreams = false;
|
4906
|
4916
|
|
4907
|
4917
|
this.wait = true;
|
4908
|
4918
|
this.localStreamsSSRC = null;
|
|
@@ -4915,6 +4925,7 @@ function JingleSessionPC(me, sid, connection, service) {
|
4915
|
4925
|
* by the application logic.
|
4916
|
4926
|
*/
|
4917
|
4927
|
this.videoMuteByUser = false;
|
|
4928
|
+
|
4918
|
4929
|
this.modifySourcesQueue = async.queue(this._modifySources.bind(this), 1);
|
4919
|
4930
|
// We start with the queue paused. We resume it when the signaling state is
|
4920
|
4931
|
// stable and the ice connection state is connected.
|
|
@@ -5024,6 +5035,8 @@ JingleSessionPC.prototype.addLocalStreams = function (localStreams) {
|
5024
|
5035
|
var self = this;
|
5025
|
5036
|
// add any local and relayed stream
|
5026
|
5037
|
localStreams.forEach(function(stream) {
|
|
5038
|
+ if(!stream.isStarted())
|
|
5039
|
+ return;
|
5027
|
5040
|
self.peerconnection.addStream(stream.getOriginalStream());
|
5028
|
5041
|
});
|
5029
|
5042
|
}
|
|
@@ -5831,7 +5844,8 @@ JingleSessionPC.prototype._modifySources = function (successCallback, queueCallb
|
5831
|
5844
|
var self = this;
|
5832
|
5845
|
|
5833
|
5846
|
if (this.peerconnection.signalingState == 'closed') return;
|
5834
|
|
- if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null || this.switchstreams)){
|
|
5847
|
+ if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null
|
|
5848
|
+ || this.switchstreams || this.addingStreams)){
|
5835
|
5849
|
// There is nothing to do since scheduled job might have been executed by another succeeding call
|
5836
|
5850
|
this.setLocalDescription();
|
5837
|
5851
|
if(successCallback){
|
|
@@ -5841,8 +5855,9 @@ JingleSessionPC.prototype._modifySources = function (successCallback, queueCallb
|
5841
|
5855
|
return;
|
5842
|
5856
|
}
|
5843
|
5857
|
|
5844
|
|
- // Reset switch streams flag
|
|
5858
|
+ // Reset switch streams flags
|
5845
|
5859
|
this.switchstreams = false;
|
|
5860
|
+ this.addingStreams = false;
|
5846
|
5861
|
|
5847
|
5862
|
var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
|
5848
|
5863
|
|
|
@@ -5991,6 +6006,7 @@ JingleSessionPC.prototype.addStream = function (stream, callback) {
|
5991
|
6006
|
return;
|
5992
|
6007
|
}
|
5993
|
6008
|
|
|
6009
|
+ this.addingStreams = true;
|
5994
|
6010
|
this.modifySourcesQueue.push(function() {
|
5995
|
6011
|
console.log('modify sources done');
|
5996
|
6012
|
|
|
@@ -6393,6 +6409,7 @@ var RTCBrowserType = require('../RTC/RTCBrowserType');
|
6393
|
6409
|
*/
|
6394
|
6410
|
var isEnabled = !RTCBrowserType.isFirefox();
|
6395
|
6411
|
|
|
6412
|
+
|
6396
|
6413
|
/**
|
6397
|
6414
|
* Stored SSRC of local video stream.
|
6398
|
6415
|
*/
|
|
@@ -6403,7 +6420,7 @@ var localVideoSSRC;
|
6403
|
6420
|
* This is in order to tell Chrome what SSRC should be used in RTCP requests
|
6404
|
6421
|
* instead of 1.
|
6405
|
6422
|
*/
|
6406
|
|
-var localRecvOnlySSRC;
|
|
6423
|
+var localRecvOnlySSRC, localRecvOnlyMSID, localRecvOnlyMSLabel, localRecvOnlyLabel;
|
6407
|
6424
|
|
6408
|
6425
|
/**
|
6409
|
6426
|
* cname for <tt>localRecvOnlySSRC</tt>
|
|
@@ -6475,6 +6492,22 @@ var storeLocalVideoSSRC = function (jingleIq) {
|
6475
|
6492
|
});
|
6476
|
6493
|
};
|
6477
|
6494
|
|
|
6495
|
+function rangeRandomHex(min, max)
|
|
6496
|
+{
|
|
6497
|
+ return Math.floor(Math.random() * (max - min) + min).toString(16);
|
|
6498
|
+}
|
|
6499
|
+
|
|
6500
|
+var random4digitsHex = rangeRandomHex.bind(null, 4096, 65535);
|
|
6501
|
+var random8digitsHex = rangeRandomHex.bind(null, 268435456, 4294967295);
|
|
6502
|
+var random12digitsHex = rangeRandomHex.bind(null, 17592186044416, 281474976710655);
|
|
6503
|
+
|
|
6504
|
+function generateLabel() {
|
|
6505
|
+ //4294967295 - ffffffff
|
|
6506
|
+ //65535 - ffff
|
|
6507
|
+ //281474976710655 - ffffffffffff
|
|
6508
|
+ return random8digitsHex() + "-" + random4digitsHex() + "-" + random4digitsHex() + "-" + random4digitsHex() + "-" + random12digitsHex();
|
|
6509
|
+}
|
|
6510
|
+
|
6478
|
6511
|
/**
|
6479
|
6512
|
* Generates new SSRC for local video recvonly stream.
|
6480
|
6513
|
* FIXME what about eventual SSRC collision ?
|
|
@@ -6485,7 +6518,12 @@ function generateRecvonlySSRC() {
|
6485
|
6518
|
Math.random().toString(10).substring(2, 11);
|
6486
|
6519
|
localRecvOnlyCName =
|
6487
|
6520
|
Math.random().toString(36).substring(2);
|
6488
|
|
- console.info(
|
|
6521
|
+ localRecvOnlyMSLabel = generateLabel();
|
|
6522
|
+ localRecvOnlyLabel = generateLabel();
|
|
6523
|
+ localRecvOnlyMSID = localRecvOnlyMSLabel + " " + localRecvOnlyLabel;
|
|
6524
|
+
|
|
6525
|
+
|
|
6526
|
+ console.info(
|
6489
|
6527
|
"Generated local recvonly SSRC: " + localRecvOnlySSRC +
|
6490
|
6528
|
", cname: " + localRecvOnlyCName);
|
6491
|
6529
|
}
|
|
@@ -6556,12 +6594,19 @@ var LocalSSRCReplacement = {
|
6556
|
6594
|
if (!localRecvOnlySSRC) {
|
6557
|
6595
|
generateRecvonlySSRC();
|
6558
|
6596
|
}
|
|
6597
|
+ localVideoSSRC = localRecvOnlySSRC;
|
6559
|
6598
|
|
6560
|
6599
|
console.info('No SSRC in video recvonly stream' +
|
6561
|
6600
|
' - adding SSRC: ' + localRecvOnlySSRC);
|
6562
|
6601
|
|
6563
|
6602
|
sdp.media[1] += 'a=ssrc:' + localRecvOnlySSRC +
|
6564
|
|
- ' cname:' + localRecvOnlyCName + '\r\n';
|
|
6603
|
+ ' cname:' + localRecvOnlyCName + '\r\n' +
|
|
6604
|
+ 'a=ssrc:' + localRecvOnlySSRC +
|
|
6605
|
+ ' msid:' + localRecvOnlyMSID + '\r\n' +
|
|
6606
|
+ 'a=ssrc:' + localRecvOnlySSRC +
|
|
6607
|
+ ' mslabel:' + localRecvOnlyMSLabel + '\r\n' +
|
|
6608
|
+ 'a=ssrc:' + localRecvOnlySSRC +
|
|
6609
|
+ ' label:' + localRecvOnlyLabel + '\r\n';
|
6565
|
6610
|
|
6566
|
6611
|
localDescription.sdp = sdp.session + sdp.media.join('');
|
6567
|
6612
|
}
|
|
@@ -7799,6 +7844,7 @@ function TraceablePeerConnection(ice_config, constraints, session) {
|
7799
|
7844
|
|
7800
|
7845
|
// override as desired
|
7801
|
7846
|
this.trace = function (what, info) {
|
|
7847
|
+ console.debug(what + " - " + info);
|
7802
|
7848
|
/*console.warn('WTRACE', what, info);
|
7803
|
7849
|
if (info && RTCBrowserType.isIExplorer()) {
|
7804
|
7850
|
if (info.length > 1024) {
|