Selaa lähdekoodia

Fixes issues with starting the streams after the conference has been joined.

release-8443
hristoterezov 10 vuotta sitten
vanhempi
commit
86a2e4257a

+ 19
- 8
doc/example/example.js Näytä tiedosto

1
+//var options = {
2
+//    hosts: {
3
+//        domain: "prod-us-east-1-app-xmpp1.internal.meet.hipchat.ninja",
4
+//        focus: "focus.prod-us-east-1-app-xmpp1.internal.meet.hipchat.ninja",
5
+//        muc: "conference.prod-us-east-1-app-xmpp1.internal.meet.hipchat.ninja", // FIXME: use XEP-0030
6
+//    },
7
+//    bosh: "https://xmpp1-meet.hipchat.me/http-bind", // FIXME: use xep-0156 for that
8
+//    clientNode: "http://prod-us-east-1-app-xmpp1.internal.meet.hipchat.ninja/jitsimeet" // The name of client node advertised in XEP-0115 'c' stanza
9
+//};
10
+
1
 var options = {
11
 var options = {
2
     hosts: {
12
     hosts: {
3
         domain: 'hristo.jitsi.net',
13
         domain: 'hristo.jitsi.net',
5
         bridge: 'jitsi-videobridge.hristo.jitsi.net', // FIXME: use XEP-0030
15
         bridge: 'jitsi-videobridge.hristo.jitsi.net', // FIXME: use XEP-0030
6
     },
16
     },
7
     bosh: '//hristo.jitsi.net/http-bind', // FIXME: use xep-0156 for that
17
     bosh: '//hristo.jitsi.net/http-bind', // FIXME: use xep-0156 for that
8
-    clientNode: 'http://jitsi.org/jitsimeet' // The name of client node advertised in XEP-0115 'c' stanza
9
-};
18
+    clientNode: 'http://jitsi.org/jitsimeet', // The name of client node advertised in XEP-0115 'c' stanza
19
+}
10
 
20
 
11
 var confOptions = {
21
 var confOptions = {
12
     openSctp: true
22
     openSctp: true
22
     console.log(tracks);
32
     console.log(tracks);
23
     tracks[0].attach($("#localAudio"));
33
     tracks[0].attach($("#localAudio"));
24
     tracks[1].attach($("#localVideo"));
34
     tracks[1].attach($("#localVideo"));
35
+    for(var i = 0; i < localTracks.length; i++)
36
+    {
37
+        localTracks[i].start();
38
+    }
25
 }
39
 }
26
 
40
 
27
 /**
41
 /**
46
  * That function is executed when the conference is joined
60
  * That function is executed when the conference is joined
47
  */
61
  */
48
 function onConferenceJoined () {
62
 function onConferenceJoined () {
49
-    for(var i = 0; i < localTracks.length; i++)
50
-    {
51
-        localTracks[i].start();
52
-    }
63
+    console.log("conference joined!");
64
+    room.createLocalTracks().then(onLocalTracks);
53
 }
65
 }
54
 
66
 
55
 function onUserLeft(id) {
67
 function onUserLeft(id) {
64
  * That function is called when connection is established successfully
76
  * That function is called when connection is established successfully
65
  */
77
  */
66
 function onConnectionSuccess(){
78
 function onConnectionSuccess(){
67
-    room = connection.initJitsiConference("conference1", confOptions);
68
-    room.createLocalTracks().then(onLocalTracks);
79
+    room = connection.initJitsiConference("conference2", confOptions);
69
     room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
80
     room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
70
     room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, function () {
81
     room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, function () {
71
         console.debug("track removed!!!");
82
         console.debug("track removed!!!");

+ 1
- 1
doc/example/index.html Näytä tiedosto

12
 </head>
12
 </head>
13
 <body>
13
 <body>
14
     <video id="localVideo" autoplay="true"></video>
14
     <video id="localVideo" autoplay="true"></video>
15
-    <audio id="localAudio" autoplay="true"></audio>
15
+    <!--<audio id="localAudio" autoplay="true" muted="true"></audio>-->
16
 </body>
16
 </body>
17
 </html>
17
 </html>

+ 56
- 10
lib-jitsi-meet.js Näytä tiedosto

26
     this.rtc = new RTC(this.room, options);
26
     this.rtc = new RTC(this.room, options);
27
     setupListeners(this);
27
     setupListeners(this);
28
     this.participants = {};
28
     this.participants = {};
29
+    this.lastActiveSpeaker = null;
29
 }
30
 }
30
 
31
 
31
 /**
32
 /**
220
 //        conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
221
 //        conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
221
 //    });
222
 //    });
222
     conference.rtc.addListener(RTCEvents.DOMINANTSPEAKER_CHANGED, function (id) {
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
     conference.rtc.addListener(RTCEvents.LASTN_CHANGED, function (oldValue, newValue) {
231
     conference.rtc.addListener(RTCEvents.LASTN_CHANGED, function (oldValue, newValue) {
845
     this.videoType = videoType;
850
     this.videoType = videoType;
846
     this.isGUMStream = true;
851
     this.isGUMStream = true;
847
     this.dontFireRemoveEvent = false;
852
     this.dontFireRemoveEvent = false;
853
+    this.isStarted = false;
848
     var self = this;
854
     var self = this;
849
     if(isGUMStream === false)
855
     if(isGUMStream === false)
850
         this.isGUMStream = isGUMStream;
856
         this.isGUMStream = isGUMStream;
947
  * NOTE: Works for local tracks only.
953
  * NOTE: Works for local tracks only.
948
  */
954
  */
949
 JitsiLocalTrack.prototype.start = function() {
955
 JitsiLocalTrack.prototype.start = function() {
956
+    this.isStarted = true;
950
     this.rtc.room.addStream(this.stream, function () {});
957
     this.rtc.room.addStream(this.stream, function () {});
951
 }
958
 }
952
 
959
 
1220
 var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
1227
 var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
1221
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
1228
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
1222
 var RTCEvents = require("../../service/RTC/RTCEvents.js");
1229
 var RTCEvents = require("../../service/RTC/RTCEvents.js");
1223
-var XMPPEvents = require("../../service/xmpp/XMPPEvents");
1224
 var desktopsharing = require("../desktopsharing/desktopsharing");
1230
 var desktopsharing = require("../desktopsharing/desktopsharing");
1225
 
1231
 
1226
 function getMediaStreamUsage()
1232
 function getMediaStreamUsage()
1279
         if(self.remoteStreams[from])
1285
         if(self.remoteStreams[from])
1280
             self.remoteStreams[from][JitsiTrack.AUDIO].setMute(values.value == "true");
1286
             self.remoteStreams[from][JitsiTrack.AUDIO].setMute(values.value == "true");
1281
     });
1287
     });
1282
-
1283
 }
1288
 }
1284
 
1289
 
1285
 /**
1290
 /**
1298
 RTC.prototype.onIncommingCall = function(event) {
1303
 RTC.prototype.onIncommingCall = function(event) {
1299
     if(this.options.config.openSctp)
1304
     if(this.options.config.openSctp)
1300
         this.dataChannels = new DataChannels(event.peerconnection, this.eventEmitter);
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
 RTC.prototype.selectedEndpoint = function (id) {
1313
 RTC.prototype.selectedEndpoint = function (id) {
1565
 
1574
 
1566
 module.exports = RTC;
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
 var currentBrowser;
1579
 var currentBrowser;
1571
 
1580
 
4903
     this.removessrc = [];
4912
     this.removessrc = [];
4904
     this.pendingop = null;
4913
     this.pendingop = null;
4905
     this.switchstreams = false;
4914
     this.switchstreams = false;
4915
+    this.addingStreams = false;
4906
 
4916
 
4907
     this.wait = true;
4917
     this.wait = true;
4908
     this.localStreamsSSRC = null;
4918
     this.localStreamsSSRC = null;
4915
      * by the application logic.
4925
      * by the application logic.
4916
      */
4926
      */
4917
     this.videoMuteByUser = false;
4927
     this.videoMuteByUser = false;
4928
+
4918
     this.modifySourcesQueue = async.queue(this._modifySources.bind(this), 1);
4929
     this.modifySourcesQueue = async.queue(this._modifySources.bind(this), 1);
4919
     // We start with the queue paused. We resume it when the signaling state is
4930
     // We start with the queue paused. We resume it when the signaling state is
4920
     // stable and the ice connection state is connected.
4931
     // stable and the ice connection state is connected.
5024
     var self = this;
5035
     var self = this;
5025
 // add any local and relayed stream
5036
 // add any local and relayed stream
5026
     localStreams.forEach(function(stream) {
5037
     localStreams.forEach(function(stream) {
5038
+        if(!stream.isStarted())
5039
+            return;
5027
         self.peerconnection.addStream(stream.getOriginalStream());
5040
         self.peerconnection.addStream(stream.getOriginalStream());
5028
     });
5041
     });
5029
 }
5042
 }
5831
     var self = this;
5844
     var self = this;
5832
 
5845
 
5833
     if (this.peerconnection.signalingState == 'closed') return;
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
         // There is nothing to do since scheduled job might have been executed by another succeeding call
5849
         // There is nothing to do since scheduled job might have been executed by another succeeding call
5836
         this.setLocalDescription();
5850
         this.setLocalDescription();
5837
         if(successCallback){
5851
         if(successCallback){
5841
         return;
5855
         return;
5842
     }
5856
     }
5843
 
5857
 
5844
-    // Reset switch streams flag
5858
+    // Reset switch streams flags
5845
     this.switchstreams = false;
5859
     this.switchstreams = false;
5860
+    this.addingStreams = false;
5846
 
5861
 
5847
     var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
5862
     var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
5848
 
5863
 
5991
         return;
6006
         return;
5992
     }
6007
     }
5993
 
6008
 
6009
+    this.addingStreams = true;
5994
     this.modifySourcesQueue.push(function() {
6010
     this.modifySourcesQueue.push(function() {
5995
         console.log('modify sources done');
6011
         console.log('modify sources done');
5996
 
6012
 
6393
  */
6409
  */
6394
 var isEnabled = !RTCBrowserType.isFirefox();
6410
 var isEnabled = !RTCBrowserType.isFirefox();
6395
 
6411
 
6412
+
6396
 /**
6413
 /**
6397
  * Stored SSRC of local video stream.
6414
  * Stored SSRC of local video stream.
6398
  */
6415
  */
6403
  * This is in order to tell Chrome what SSRC should be used in RTCP requests
6420
  * This is in order to tell Chrome what SSRC should be used in RTCP requests
6404
  * instead of 1.
6421
  * instead of 1.
6405
  */
6422
  */
6406
-var localRecvOnlySSRC;
6423
+var localRecvOnlySSRC, localRecvOnlyMSID, localRecvOnlyMSLabel, localRecvOnlyLabel;
6407
 
6424
 
6408
 /**
6425
 /**
6409
  * cname for <tt>localRecvOnlySSRC</tt>
6426
  * cname for <tt>localRecvOnlySSRC</tt>
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
  * Generates new SSRC for local video recvonly stream.
6512
  * Generates new SSRC for local video recvonly stream.
6480
  * FIXME what about eventual SSRC collision ?
6513
  * FIXME what about eventual SSRC collision ?
6485
         Math.random().toString(10).substring(2, 11);
6518
         Math.random().toString(10).substring(2, 11);
6486
     localRecvOnlyCName =
6519
     localRecvOnlyCName =
6487
         Math.random().toString(36).substring(2);
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
         "Generated local recvonly SSRC: " + localRecvOnlySSRC +
6527
         "Generated local recvonly SSRC: " + localRecvOnlySSRC +
6490
         ", cname: " + localRecvOnlyCName);
6528
         ", cname: " + localRecvOnlyCName);
6491
 }
6529
 }
6556
                 if (!localRecvOnlySSRC) {
6594
                 if (!localRecvOnlySSRC) {
6557
                     generateRecvonlySSRC();
6595
                     generateRecvonlySSRC();
6558
                 }
6596
                 }
6597
+                localVideoSSRC = localRecvOnlySSRC;
6559
 
6598
 
6560
                 console.info('No SSRC in video recvonly stream' +
6599
                 console.info('No SSRC in video recvonly stream' +
6561
                              ' - adding SSRC: ' + localRecvOnlySSRC);
6600
                              ' - adding SSRC: ' + localRecvOnlySSRC);
6562
 
6601
 
6563
                 sdp.media[1] += 'a=ssrc:' + localRecvOnlySSRC +
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
                 localDescription.sdp = sdp.session + sdp.media.join('');
6611
                 localDescription.sdp = sdp.session + sdp.media.join('');
6567
             }
6612
             }
7799
 
7844
 
7800
     // override as desired
7845
     // override as desired
7801
     this.trace = function (what, info) {
7846
     this.trace = function (what, info) {
7847
+        console.debug(what + " - " + info);
7802
         /*console.warn('WTRACE', what, info);
7848
         /*console.warn('WTRACE', what, info);
7803
         if (info && RTCBrowserType.isIExplorer()) {
7849
         if (info && RTCBrowserType.isIExplorer()) {
7804
             if (info.length > 1024) {
7850
             if (info.length > 1024) {

+ 2
- 0
modules/RTC/JitsiLocalTrack.js Näytä tiedosto

14
     this.videoType = videoType;
14
     this.videoType = videoType;
15
     this.isGUMStream = true;
15
     this.isGUMStream = true;
16
     this.dontFireRemoveEvent = false;
16
     this.dontFireRemoveEvent = false;
17
+    this.isStarted = false;
17
     var self = this;
18
     var self = this;
18
     if(isGUMStream === false)
19
     if(isGUMStream === false)
19
         this.isGUMStream = isGUMStream;
20
         this.isGUMStream = isGUMStream;
116
  * NOTE: Works for local tracks only.
117
  * NOTE: Works for local tracks only.
117
  */
118
  */
118
 JitsiLocalTrack.prototype.start = function() {
119
 JitsiLocalTrack.prototype.start = function() {
120
+    this.isStarted = true;
119
     this.rtc.room.addStream(this.stream, function () {});
121
     this.rtc.room.addStream(this.stream, function () {});
120
 }
122
 }
121
 
123
 

+ 5
- 3
modules/RTC/RTC.js Näytä tiedosto

11
 var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
11
 var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
12
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
12
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
13
 var RTCEvents = require("../../service/RTC/RTCEvents.js");
13
 var RTCEvents = require("../../service/RTC/RTCEvents.js");
14
-var XMPPEvents = require("../../service/xmpp/XMPPEvents");
15
 var desktopsharing = require("../desktopsharing/desktopsharing");
14
 var desktopsharing = require("../desktopsharing/desktopsharing");
16
 
15
 
17
 function getMediaStreamUsage()
16
 function getMediaStreamUsage()
70
         if(self.remoteStreams[from])
69
         if(self.remoteStreams[from])
71
             self.remoteStreams[from][JitsiTrack.AUDIO].setMute(values.value == "true");
70
             self.remoteStreams[from][JitsiTrack.AUDIO].setMute(values.value == "true");
72
     });
71
     });
73
-
74
 }
72
 }
75
 
73
 
76
 /**
74
 /**
89
 RTC.prototype.onIncommingCall = function(event) {
87
 RTC.prototype.onIncommingCall = function(event) {
90
     if(this.options.config.openSctp)
88
     if(this.options.config.openSctp)
91
         this.dataChannels = new DataChannels(event.peerconnection, this.eventEmitter);
89
         this.dataChannels = new DataChannels(event.peerconnection, this.eventEmitter);
92
-    this.room.addLocalStreams(this.localStreams);
90
+    for(var i = 0; i < this.localStreams.length; i++)
91
+        if(this.localStreams[i].isStarted)
92
+        {
93
+            this.localStreams[i].start();
94
+        }
93
 }
95
 }
94
 
96
 
95
 RTC.prototype.selectedEndpoint = function (id) {
97
 RTC.prototype.selectedEndpoint = function (id) {

+ 9
- 2
modules/xmpp/JingleSessionPC.js Näytä tiedosto

37
     this.removessrc = [];
37
     this.removessrc = [];
38
     this.pendingop = null;
38
     this.pendingop = null;
39
     this.switchstreams = false;
39
     this.switchstreams = false;
40
+    this.addingStreams = false;
40
 
41
 
41
     this.wait = true;
42
     this.wait = true;
42
     this.localStreamsSSRC = null;
43
     this.localStreamsSSRC = null;
49
      * by the application logic.
50
      * by the application logic.
50
      */
51
      */
51
     this.videoMuteByUser = false;
52
     this.videoMuteByUser = false;
53
+
52
     this.modifySourcesQueue = async.queue(this._modifySources.bind(this), 1);
54
     this.modifySourcesQueue = async.queue(this._modifySources.bind(this), 1);
53
     // We start with the queue paused. We resume it when the signaling state is
55
     // We start with the queue paused. We resume it when the signaling state is
54
     // stable and the ice connection state is connected.
56
     // stable and the ice connection state is connected.
158
     var self = this;
160
     var self = this;
159
 // add any local and relayed stream
161
 // add any local and relayed stream
160
     localStreams.forEach(function(stream) {
162
     localStreams.forEach(function(stream) {
163
+        if(!stream.isStarted())
164
+            return;
161
         self.peerconnection.addStream(stream.getOriginalStream());
165
         self.peerconnection.addStream(stream.getOriginalStream());
162
     });
166
     });
163
 }
167
 }
965
     var self = this;
969
     var self = this;
966
 
970
 
967
     if (this.peerconnection.signalingState == 'closed') return;
971
     if (this.peerconnection.signalingState == 'closed') return;
968
-    if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null || this.switchstreams)){
972
+    if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null
973
+        || this.switchstreams || this.addingStreams)){
969
         // There is nothing to do since scheduled job might have been executed by another succeeding call
974
         // There is nothing to do since scheduled job might have been executed by another succeeding call
970
         this.setLocalDescription();
975
         this.setLocalDescription();
971
         if(successCallback){
976
         if(successCallback){
975
         return;
980
         return;
976
     }
981
     }
977
 
982
 
978
-    // Reset switch streams flag
983
+    // Reset switch streams flags
979
     this.switchstreams = false;
984
     this.switchstreams = false;
985
+    this.addingStreams = false;
980
 
986
 
981
     var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
987
     var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
982
 
988
 
1125
         return;
1131
         return;
1126
     }
1132
     }
1127
 
1133
 
1134
+    this.addingStreams = true;
1128
     this.modifySourcesQueue.push(function() {
1135
     this.modifySourcesQueue.push(function() {
1129
         console.log('modify sources done');
1136
         console.log('modify sources done');
1130
 
1137
 

+ 52
- 6
modules/xmpp/LocalSSRCReplacement.js Näytä tiedosto

41
  */
41
  */
42
 var isEnabled = !RTCBrowserType.isFirefox();
42
 var isEnabled = !RTCBrowserType.isFirefox();
43
 
43
 
44
+
44
 /**
45
 /**
45
  * Stored SSRC of local video stream.
46
  * Stored SSRC of local video stream.
46
  */
47
  */
47
 var localVideoSSRC;
48
 var localVideoSSRC;
48
 
49
 
49
 /**
50
 /**
50
- * SSRC used for recvonly video stream when we have no local camera.
51
+ * SSRC, msid, mslabel, label used for recvonly video stream when we have no local camera.
51
  * This is in order to tell Chrome what SSRC should be used in RTCP requests
52
  * This is in order to tell Chrome what SSRC should be used in RTCP requests
52
  * instead of 1.
53
  * instead of 1.
53
  */
54
  */
54
-var localRecvOnlySSRC;
55
+var localRecvOnlySSRC, localRecvOnlyMSID, localRecvOnlyMSLabel, localRecvOnlyLabel;
55
 
56
 
56
 /**
57
 /**
57
  * cname for <tt>localRecvOnlySSRC</tt>
58
  * cname for <tt>localRecvOnlySSRC</tt>
124
 };
125
 };
125
 
126
 
126
 /**
127
 /**
127
- * Generates new SSRC for local video recvonly stream.
128
+ * Generates random hex number within the range [min, max]
129
+ * @param max the maximum value for the generated number
130
+ * @param min the minimum value for the generated number
131
+ * @returns random hex number
132
+ */
133
+function rangeRandomHex(min, max)
134
+{
135
+    return Math.floor(Math.random() * (max - min) + min).toString(16);
136
+}
137
+
138
+/**
139
+ * Generates hex number with length 4
140
+ */
141
+var random4digitsHex = rangeRandomHex.bind(null, 4096, 65535);
142
+
143
+/**
144
+ * Generates hex number with length 8
145
+ */
146
+var random8digitsHex = rangeRandomHex.bind(null, 268435456, 4294967295);
147
+
148
+/**
149
+ * Generates hex number with length 12
150
+ */
151
+var random12digitsHex = rangeRandomHex.bind(null, 17592186044416, 281474976710655);
152
+
153
+/**
154
+ * Generates new label/mslabel attribute
155
+ * @returns {string} label/mslabel attribute
156
+ */
157
+function generateLabel() {
158
+    return random8digitsHex() + "-" + random4digitsHex() + "-" + random4digitsHex() + "-" + random4digitsHex() + "-" + random12digitsHex();
159
+}
160
+
161
+/**
162
+ * Generates new SSRC, CNAME, mslabel, label and msid for local video recvonly stream.
128
  * FIXME what about eventual SSRC collision ?
163
  * FIXME what about eventual SSRC collision ?
129
  */
164
  */
130
 function generateRecvonlySSRC() {
165
 function generateRecvonlySSRC() {
131
-    //
132
     localRecvOnlySSRC =
166
     localRecvOnlySSRC =
133
         Math.random().toString(10).substring(2, 11);
167
         Math.random().toString(10).substring(2, 11);
134
     localRecvOnlyCName =
168
     localRecvOnlyCName =
135
         Math.random().toString(36).substring(2);
169
         Math.random().toString(36).substring(2);
136
-    console.info(
170
+    localRecvOnlyMSLabel = generateLabel();
171
+    localRecvOnlyLabel = generateLabel();
172
+    localRecvOnlyMSID = localRecvOnlyMSLabel + " " + localRecvOnlyLabel;
173
+
174
+
175
+        console.info(
137
         "Generated local recvonly SSRC: " + localRecvOnlySSRC +
176
         "Generated local recvonly SSRC: " + localRecvOnlySSRC +
138
         ", cname: " + localRecvOnlyCName);
177
         ", cname: " + localRecvOnlyCName);
139
 }
178
 }
204
                 if (!localRecvOnlySSRC) {
243
                 if (!localRecvOnlySSRC) {
205
                     generateRecvonlySSRC();
244
                     generateRecvonlySSRC();
206
                 }
245
                 }
246
+                localVideoSSRC = localRecvOnlySSRC;
207
 
247
 
208
                 console.info('No SSRC in video recvonly stream' +
248
                 console.info('No SSRC in video recvonly stream' +
209
                              ' - adding SSRC: ' + localRecvOnlySSRC);
249
                              ' - adding SSRC: ' + localRecvOnlySSRC);
210
 
250
 
211
                 sdp.media[1] += 'a=ssrc:' + localRecvOnlySSRC +
251
                 sdp.media[1] += 'a=ssrc:' + localRecvOnlySSRC +
212
-                                ' cname:' + localRecvOnlyCName + '\r\n';
252
+                                ' cname:' + localRecvOnlyCName + '\r\n' +
253
+                                'a=ssrc:' + localRecvOnlySSRC +
254
+                                ' msid:' + localRecvOnlyMSID + '\r\n' +
255
+                                'a=ssrc:' + localRecvOnlySSRC +
256
+                                ' mslabel:' + localRecvOnlyMSLabel + '\r\n' +
257
+                                'a=ssrc:' + localRecvOnlySSRC +
258
+                                ' label:' + localRecvOnlyLabel + '\r\n';
213
 
259
 
214
                 localDescription.sdp = sdp.session + sdp.media.join('');
260
                 localDescription.sdp = sdp.session + sdp.media.join('');
215
             }
261
             }

Loading…
Peruuta
Tallenna