瀏覽代碼

Fixes TRACK_REMOVED event.

dev1
hristoterezov 9 年之前
父節點
當前提交
ae85fc66e5
共有 7 個檔案被更改,包括 316 行新增147 行删除
  1. 17
    9
      JitsiConference.js
  2. 7
    6
      JitsiParticipant.js
  3. 3
    0
      doc/example/example.js
  4. 262
    111
      lib-jitsi-meet.js
  5. 0
    21
      modules/RTC/JitsiLocalTrack.js
  6. 6
    0
      modules/RTC/JitsiRemoteTrack.js
  7. 21
    0
      modules/RTC/JitsiTrack.js

+ 17
- 9
JitsiConference.js 查看文件

@@ -4,6 +4,7 @@ var StreamEventTypes = require("./service/RTC/StreamEventTypes");
4 4
 var RTCEvents = require("./service/RTC/RTCEvents");
5 5
 var EventEmitter = require("events");
6 6
 var JitsiConferenceEvents = require("./JitsiConferenceEvents");
7
+var JitsiParticipant = require("./JitsiParticipant");
7 8
 
8 9
 /**
9 10
  * Creates a JitsiConference object with the given name and properties.
@@ -23,6 +24,7 @@ function JitsiConference(options) {
23 24
     this.room = this.xmpp.createRoom(this.options.name, null, null, this.options.config);
24 25
     this.rtc = new RTC(this.room, options);
25 26
     setupListeners(this);
27
+    this.participants = {};
26 28
 }
27 29
 
28 30
 /**
@@ -171,7 +173,7 @@ JitsiConference.prototype.pinParticipant = function(participantId) {
171 173
  * @return Object a list of participant identifiers containing all conference participants.
172 174
  */
173 175
 JitsiConference.prototype.getParticipants = function() {
174
-
176
+    return this.participants;
175 177
 }
176 178
 
177 179
 /**
@@ -180,7 +182,12 @@ JitsiConference.prototype.getParticipants = function() {
180 182
  * @param id the id of the participant.
181 183
  */
182 184
 JitsiConference.prototype.getParticipantById = function(id) {
185
+    return this.participants[id];
186
+}
183 187
 
188
+JitsiConference.prototype.onMemberJoined = function (jid, email, nick) {
189
+    this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, Strophe.getResourceFromJid(jid));
190
+//    this.participants[jid] = new JitsiParticipant();
184 191
 }
185 192
 
186 193
 /**
@@ -195,15 +202,19 @@ function setupListeners(conference) {
195 202
     conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED, function (stream) {
196 203
         conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, stream);
197 204
     });
198
-    conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED, function (stream) {
205
+    conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_REMOTE_ENDED, function (stream) {
206
+        conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, stream);
207
+    });
208
+    conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_LOCAL_ENDED, function (stream) {
199 209
         conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, stream);
200 210
     })
201 211
     conference.room.addListener(XMPPEvents.MUC_JOINED, function () {
202 212
         conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_JOINED);
203 213
     });
204
-    conference.room.addListener(XMPPEvents.MUC_JOINED, function () {
205
-        conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
206
-    });
214
+//    FIXME
215
+//    conference.room.addListener(XMPPEvents.MUC_JOINED, function () {
216
+//        conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
217
+//    });
207 218
     conference.rtc.addListener(RTCEvents.DOMINANTSPEAKER_CHANGED, function (id) {
208 219
         conference.eventEmitter.emit(JitsiConferenceEvents.ACTIVE_SPEAKER_CHANGED, id);
209 220
     });
@@ -218,10 +229,7 @@ function setupListeners(conference) {
218 229
                 lastNEndpoints, endpointsEnteringLastN);
219 230
         });
220 231
 
221
-    conference.room.addListener(XMPPEvents.MUC_MEMBER_JOINED,
222
-        function (jid, email, nick) {
223
-            conference.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, Strophe.getResourceFromJid(jid));
224
-        });
232
+    conference.room.addListener(XMPPEvents.MUC_MEMBER_JOINED, conference.onMemberJoined.bind(conference));
225 233
     conference.room.addListener(XMPPEvents.MUC_MEMBER_LEFT,function (jid) {
226 234
         conference.eventEmitter.emit(JitsiConferenceEvents.USER_LEFT, Strophe.getResourceFromJid(jid));
227 235
     });

+ 7
- 6
JitsiParticipant.js 查看文件

@@ -1,15 +1,17 @@
1 1
 /**
2 2
  * Represents a participant in (a member of) a conference.
3 3
  */
4
-function JitsiParticipant(){
5
-
4
+function JitsiParticipant(id, conference, displayName){
5
+    this._id = id;
6
+    this._conference = conference;
7
+    this._displayName = displayName;
6 8
 }
7 9
 
8 10
 /**
9 11
  * @returns {JitsiConference} The conference that this participant belongs to.
10 12
  */
11 13
 JitsiParticipant.prototype.getConference = function() {
12
-
14
+    return this._conference;
13 15
 }
14 16
 
15 17
 /**
@@ -23,21 +25,20 @@ JitsiParticipant.prototype.getTracks = function() {
23 25
  * @returns {String} The ID (i.e. JID) of this participant.
24 26
  */
25 27
 JitsiParticipant.prototype.getId = function() {
26
-
28
+    return this._id;
27 29
 }
28 30
 
29 31
 /**
30 32
  * @returns {String} The human-readable display name of this participant.
31 33
  */
32 34
 JitsiParticipant.prototype.getDisplayName = function() {
33
-
35
+    return this._displayName;
34 36
 }
35 37
 
36 38
 /**
37 39
  * @returns {Boolean} Whether this participant is a moderator or not.
38 40
  */
39 41
 JitsiParticipant.prototype.isModerator = function() {
40
-
41 42
 }
42 43
 
43 44
 // Gets a link to an etherpad instance advertised by the participant?

+ 3
- 0
doc/example/example.js 查看文件

@@ -67,6 +67,9 @@ function onConnectionSuccess(){
67 67
     room = connection.initJitsiConference("conference1", confOptions);
68 68
     room.createLocalTracks().then(onLocalTracks);
69 69
     room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
70
+    room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, function () {
71
+        console.debug("track removed!!!");
72
+    });
70 73
     room.on(JitsiMeetJS.events.conference.CONFERENCE_JOINED, onConferenceJoined);
71 74
     room.on(JitsiMeetJS.events.conference.USER_JOINED, function(id){ remoteTracks[id] = [];});
72 75
     room.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);

+ 262
- 111
lib-jitsi-meet.js 查看文件

@@ -5,6 +5,7 @@ var StreamEventTypes = require("./service/RTC/StreamEventTypes");
5 5
 var RTCEvents = require("./service/RTC/RTCEvents");
6 6
 var EventEmitter = require("events");
7 7
 var JitsiConferenceEvents = require("./JitsiConferenceEvents");
8
+var JitsiParticipant = require("./JitsiParticipant");
8 9
 
9 10
 /**
10 11
  * Creates a JitsiConference object with the given name and properties.
@@ -24,6 +25,7 @@ function JitsiConference(options) {
24 25
     this.room = this.xmpp.createRoom(this.options.name, null, null, this.options.config);
25 26
     this.rtc = new RTC(this.room, options);
26 27
     setupListeners(this);
28
+    this.participants = {};
27 29
 }
28 30
 
29 31
 /**
@@ -172,7 +174,7 @@ JitsiConference.prototype.pinParticipant = function(participantId) {
172 174
  * @return Object a list of participant identifiers containing all conference participants.
173 175
  */
174 176
 JitsiConference.prototype.getParticipants = function() {
175
-
177
+    return this.participants;
176 178
 }
177 179
 
178 180
 /**
@@ -181,7 +183,12 @@ JitsiConference.prototype.getParticipants = function() {
181 183
  * @param id the id of the participant.
182 184
  */
183 185
 JitsiConference.prototype.getParticipantById = function(id) {
186
+    return this.participants[id];
187
+}
184 188
 
189
+JitsiConference.prototype.onMemberJoined = function (jid, email, nick) {
190
+    this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, Strophe.getResourceFromJid(jid));
191
+//    this.participants[jid] = new JitsiParticipant();
185 192
 }
186 193
 
187 194
 /**
@@ -196,15 +203,19 @@ function setupListeners(conference) {
196 203
     conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED, function (stream) {
197 204
         conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, stream);
198 205
     });
199
-    conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED, function (stream) {
206
+    conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_REMOTE_ENDED, function (stream) {
207
+        conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, stream);
208
+    });
209
+    conference.rtc.addListener(StreamEventTypes.EVENT_TYPE_LOCAL_ENDED, function (stream) {
200 210
         conference.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, stream);
201 211
     })
202 212
     conference.room.addListener(XMPPEvents.MUC_JOINED, function () {
203 213
         conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_JOINED);
204 214
     });
205
-    conference.room.addListener(XMPPEvents.MUC_JOINED, function () {
206
-        conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
207
-    });
215
+//    FIXME
216
+//    conference.room.addListener(XMPPEvents.MUC_JOINED, function () {
217
+//        conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
218
+//    });
208 219
     conference.rtc.addListener(RTCEvents.DOMINANTSPEAKER_CHANGED, function (id) {
209 220
         conference.eventEmitter.emit(JitsiConferenceEvents.ACTIVE_SPEAKER_CHANGED, id);
210 221
     });
@@ -219,10 +230,7 @@ function setupListeners(conference) {
219 230
                 lastNEndpoints, endpointsEnteringLastN);
220 231
         });
221 232
 
222
-    conference.room.addListener(XMPPEvents.MUC_MEMBER_JOINED,
223
-        function (jid, email, nick) {
224
-            conference.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, Strophe.getResourceFromJid(jid));
225
-        });
233
+    conference.room.addListener(XMPPEvents.MUC_MEMBER_JOINED, conference.onMemberJoined.bind(conference));
226 234
     conference.room.addListener(XMPPEvents.MUC_MEMBER_LEFT,function (jid) {
227 235
         conference.eventEmitter.emit(JitsiConferenceEvents.USER_LEFT, Strophe.getResourceFromJid(jid));
228 236
     });
@@ -231,7 +239,7 @@ function setupListeners(conference) {
231 239
 
232 240
 module.exports = JitsiConference;
233 241
 
234
-},{"./JitsiConferenceEvents":3,"./modules/RTC/RTC":12,"./service/RTC/RTCEvents":70,"./service/RTC/StreamEventTypes":72,"./service/xmpp/XMPPEvents":75,"events":76}],2:[function(require,module,exports){
242
+},{"./JitsiConferenceEvents":3,"./JitsiParticipant":8,"./modules/RTC/RTC":13,"./service/RTC/RTCEvents":71,"./service/RTC/StreamEventTypes":73,"./service/xmpp/XMPPEvents":76,"events":77}],2:[function(require,module,exports){
235 243
 /**
236 244
  * Enumeration with the errors for the conference.
237 245
  * @type {{string: string}}
@@ -415,7 +423,7 @@ JitsiConnection.prototype.removeEventListener = function (event, listener) {
415 423
 
416 424
 module.exports = JitsiConnection;
417 425
 
418
-},{"./JitsiConference":1,"./modules/xmpp/xmpp":32}],5:[function(require,module,exports){
426
+},{"./JitsiConference":1,"./modules/xmpp/xmpp":33}],5:[function(require,module,exports){
419 427
 /**
420 428
  * Enumeration with the errors for the connection.
421 429
  * @type {{string: string}}
@@ -496,7 +504,145 @@ window.Promise = window.Promise || require("es6-promise").polyfill();
496 504
 
497 505
 module.exports = LibJitsiMeet;
498 506
 
499
-},{"./JitsiConferenceErrors":2,"./JitsiConferenceEvents":3,"./JitsiConnection":4,"./JitsiConnectionErrors":5,"./JitsiConnectionEvents":6,"./modules/RTC/RTC":12,"es6-promise":34}],8:[function(require,module,exports){
507
+},{"./JitsiConferenceErrors":2,"./JitsiConferenceEvents":3,"./JitsiConnection":4,"./JitsiConnectionErrors":5,"./JitsiConnectionEvents":6,"./modules/RTC/RTC":13,"es6-promise":35}],8:[function(require,module,exports){
508
+/**
509
+ * Represents a participant in (a member of) a conference.
510
+ */
511
+function JitsiParticipant(id, conference, displayName){
512
+    this._id = id;
513
+    this._conference = conference;
514
+    this._displayName = displayName;
515
+}
516
+
517
+/**
518
+ * @returns {JitsiConference} The conference that this participant belongs to.
519
+ */
520
+JitsiParticipant.prototype.getConference = function() {
521
+    return this._conference;
522
+}
523
+
524
+/**
525
+ * @returns {Array.<JitsiTrack>} The list of media tracks for this participant.
526
+ */
527
+JitsiParticipant.prototype.getTracks = function() {
528
+
529
+}
530
+
531
+/**
532
+ * @returns {String} The ID (i.e. JID) of this participant.
533
+ */
534
+JitsiParticipant.prototype.getId = function() {
535
+    return this._id;
536
+}
537
+
538
+/**
539
+ * @returns {String} The human-readable display name of this participant.
540
+ */
541
+JitsiParticipant.prototype.getDisplayName = function() {
542
+    return this._displayName;
543
+}
544
+
545
+/**
546
+ * @returns {Boolean} Whether this participant is a moderator or not.
547
+ */
548
+JitsiParticipant.prototype.isModerator = function() {
549
+}
550
+
551
+// Gets a link to an etherpad instance advertised by the participant?
552
+//JitsiParticipant.prototype.getEtherpad = function() {
553
+//
554
+//}
555
+
556
+
557
+/*
558
+ * @returns {Boolean} Whether this participant has muted their audio.
559
+ */
560
+JitsiParticipant.prototype.isAudioMuted = function() {
561
+
562
+}
563
+
564
+/*
565
+ * @returns {Boolean} Whether this participant has muted their video.
566
+ */
567
+JitsiParticipant.prototype.isVideoMuted = function() {
568
+
569
+}
570
+
571
+/*
572
+ * @returns {???} The latest statistics reported by this participant (i.e. info used to populate the GSM bars)
573
+ * TODO: do we expose this or handle it internally?
574
+ */
575
+JitsiParticipant.prototype.getLatestStats = function() {
576
+
577
+}
578
+
579
+/**
580
+ * @returns {String} The role of this participant.
581
+ */
582
+JitsiParticipant.prototype.getRole = function() {
583
+
584
+}
585
+
586
+/*
587
+ * @returns {Boolean} Whether this participant is the conference focus (i.e. jicofo).
588
+ */
589
+JitsiParticipant.prototype.isFocus = function() {
590
+
591
+}
592
+
593
+/*
594
+ * @returns {Boolean} Whether this participant is a conference recorder (i.e. jirecon).
595
+ */
596
+JitsiParticipant.prototype.isRecorder = function() {
597
+
598
+}
599
+
600
+/*
601
+ * @returns {Boolean} Whether this participant is a SIP gateway (i.e. jigasi).
602
+ */
603
+JitsiParticipant.prototype.isSipGateway = function() {
604
+
605
+}
606
+
607
+/**
608
+ * @returns {String} The ID for this participant's avatar.
609
+ */
610
+JitsiParticipant.prototype.getAvatarId = function() {
611
+
612
+}
613
+
614
+/**
615
+ * @returns {Boolean} Whether this participant is currently sharing their screen.
616
+ */
617
+JitsiParticipant.prototype.isScreenSharing = function() {
618
+
619
+}
620
+
621
+/**
622
+ * @returns {String} The user agent of this participant (i.e. browser userAgent string).
623
+ */
624
+JitsiParticipant.prototype.getUserAgent = function() {
625
+
626
+}
627
+
628
+/**
629
+ * Kicks the participant from the conference (requires certain privileges).
630
+ */
631
+JitsiParticipant.prototype.kick = function() {
632
+
633
+}
634
+
635
+/**
636
+ * Asks this participant to mute themselves.
637
+ */
638
+JitsiParticipant.prototype.askToMute = function() {
639
+
640
+}
641
+
642
+
643
+module.exports = JitsiParticipant();
644
+
645
+},{}],9:[function(require,module,exports){
500 646
 /* global config, APP, Strophe */
501 647
 
502 648
 // cache datachannels to avoid garbage collection
@@ -683,28 +829,10 @@ DataChannels.prototype.handlePinnedEndpointEvent = function (userResource) {
683 829
 module.exports = DataChannels;
684 830
 
685 831
 
686
-},{"../../service/RTC/RTCEvents":70}],9:[function(require,module,exports){
832
+},{"../../service/RTC/RTCEvents":71}],10:[function(require,module,exports){
687 833
 var JitsiTrack = require("./JitsiTrack");
688 834
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
689 835
 var RTCEvents = require("../../service/RTC/RTCEvents");
690
-var RTCBrowserType = require("./RTCBrowserType");
691
-
692
-/**
693
- * This implements 'onended' callback normally fired by WebRTC after the stream
694
- * is stopped. There is no such behaviour yet in FF, so we have to add it.
695
- * @param stream original WebRTC stream object to which 'onended' handling
696
- *               will be added.
697
- */
698
-function implementOnEndedHandling(stream) {
699
-    var originalStop = stream.stop;
700
-    stream.stop = function () {
701
-        originalStop.apply(stream);
702
-        if (!stream.ended) {
703
-            stream.ended = true;
704
-            stream.onended();
705
-        }
706
-    };
707
-}
708 836
 
709 837
 /**
710 838
  * Represents a single media track (either audio or video).
@@ -721,9 +849,6 @@ function JitsiLocalTrack(RTC, stream, eventEmitter, videoType, isGUMStream)
721 849
     this.stream.onended = function () {
722 850
         this.eventEmitter.emit(StreamEventTypes.EVENT_TYPE_LOCAL_ENDED, this);
723 851
     }.bind(this);
724
-    if (RTCBrowserType.isFirefox()) {
725
-        implementOnEndedHandling(this.stream);
726
-    }
727 852
 }
728 853
 
729 854
 JitsiLocalTrack.prototype = Object.create(JitsiTrack.prototype);
@@ -804,8 +929,9 @@ JitsiLocalTrack.prototype.start = function() {
804 929
 
805 930
 module.exports = JitsiLocalTrack;
806 931
 
807
-},{"../../service/RTC/RTCEvents":70,"../../service/RTC/StreamEventTypes":72,"./JitsiTrack":11,"./RTCBrowserType":13}],10:[function(require,module,exports){
932
+},{"../../service/RTC/RTCEvents":71,"../../service/RTC/StreamEventTypes":73,"./JitsiTrack":12}],11:[function(require,module,exports){
808 933
 var JitsiTrack = require("./JitsiTrack");
934
+var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
809 935
 
810 936
 /**
811 937
  * Represents a single media track (either audio or video).
@@ -821,6 +947,11 @@ function JitsiRemoteTrack(RTC, data, sid, ssrc, browser, eventEmitter) {
821 947
     this.ssrc = ssrc;
822 948
     this.muted = false;
823 949
     this.eventEmitter = eventEmitter;
950
+    var self = this;
951
+    if(this.stream)
952
+        this.stream.onended = function () {
953
+            eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_ENDED, self);
954
+        }
824 955
 }
825 956
 
826 957
 JitsiRemoteTrack.prototype = Object.create(JitsiTrack.prototype);
@@ -844,8 +975,26 @@ delete JitsiRemoteTrack.prototype.start;
844 975
 
845 976
 module.exports = JitsiRemoteTrack;
846 977
 
847
-},{"./JitsiTrack":11}],11:[function(require,module,exports){
978
+},{"../../service/RTC/StreamEventTypes":73,"./JitsiTrack":12}],12:[function(require,module,exports){
848 979
 var RTC = require("./RTCUtils");
980
+var RTCBrowserType = require("./RTCBrowserType");
981
+
982
+/**
983
+ * This implements 'onended' callback normally fired by WebRTC after the stream
984
+ * is stopped. There is no such behaviour yet in FF, so we have to add it.
985
+ * @param stream original WebRTC stream object to which 'onended' handling
986
+ *               will be added.
987
+ */
988
+function implementOnEndedHandling(stream) {
989
+    var originalStop = stream.stop;
990
+    stream.stop = function () {
991
+        originalStop.apply(stream);
992
+        if (!stream.ended) {
993
+            stream.ended = true;
994
+            stream.onended();
995
+        }
996
+    };
997
+}
849 998
 
850 999
 /**
851 1000
  * Represents a single media track (either audio or video).
@@ -866,6 +1015,9 @@ function JitsiTrack(RTC, stream)
866 1015
             return this.stream.getVideoTracks();
867 1016
         }.bind(this);
868 1017
     }
1018
+    if (RTCBrowserType.isFirefox() && this.stream) {
1019
+        implementOnEndedHandling(this.stream);
1020
+    }
869 1021
 }
870 1022
 
871 1023
 /**
@@ -963,7 +1115,7 @@ JitsiTrack.prototype.getId = function () {
963 1115
 
964 1116
 module.exports = JitsiTrack;
965 1117
 
966
-},{"./RTCUtils":14}],12:[function(require,module,exports){
1118
+},{"./RTCBrowserType":14,"./RTCUtils":15}],13:[function(require,module,exports){
967 1119
 /* global APP */
968 1120
 var EventEmitter = require("events");
969 1121
 var RTCBrowserType = require("./RTCBrowserType");
@@ -1291,7 +1443,7 @@ RTC.prototype.setDeviceAvailability = function (devices) {
1291 1443
 
1292 1444
 module.exports = RTC;
1293 1445
 
1294
-},{"../../service/RTC/MediaStreamTypes":69,"../../service/RTC/RTCEvents.js":70,"../../service/RTC/StreamEventTypes.js":72,"../../service/desktopsharing/DesktopSharingEventTypes":74,"../../service/xmpp/XMPPEvents":75,"../desktopsharing/desktopsharing":16,"./DataChannels":8,"./JitsiLocalTrack.js":9,"./JitsiRemoteTrack.js":10,"./RTCBrowserType":13,"./RTCUtils.js":14,"events":76}],13:[function(require,module,exports){
1446
+},{"../../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,"./RTCBrowserType":14,"./RTCUtils.js":15,"events":77}],14:[function(require,module,exports){
1295 1447
 
1296 1448
 var currentBrowser;
1297 1449
 
@@ -1453,7 +1605,7 @@ function detectBrowser() {
1453 1605
 browserVersion = detectBrowser();
1454 1606
 
1455 1607
 module.exports = RTCBrowserType;
1456
-},{}],14:[function(require,module,exports){
1608
+},{}],15:[function(require,module,exports){
1457 1609
 /* global config, require, attachMediaStream, getUserMedia */
1458 1610
 var RTCBrowserType = require("./RTCBrowserType");
1459 1611
 var Resolutions = require("../../service/RTC/Resolutions");
@@ -2010,7 +2162,7 @@ var RTCUtils = {
2010 2162
 
2011 2163
 module.exports = RTCUtils;
2012 2164
 
2013
-},{"../../service/RTC/Resolutions":71,"../xmpp/SDPUtil":24,"./RTCBrowserType":13,"./adapter.screenshare":15,"events":76}],15:[function(require,module,exports){
2165
+},{"../../service/RTC/Resolutions":72,"../xmpp/SDPUtil":25,"./RTCBrowserType":14,"./adapter.screenshare":16,"events":77}],16:[function(require,module,exports){
2014 2166
 /*! adapterjs - custom version from - 2015-08-12 */
2015 2167
 
2016 2168
 // Adapter's interface.
@@ -3341,7 +3493,7 @@ if (navigator.mozGetUserMedia) {
3341 3493
     };
3342 3494
   }
3343 3495
 })();
3344
-},{}],16:[function(require,module,exports){
3496
+},{}],17:[function(require,module,exports){
3345 3497
 /* global $, alert, APP, changeLocalVideo, chrome, config, getConferenceHandler,
3346 3498
  getUserMediaWithConstraints */
3347 3499
 /**
@@ -3730,7 +3882,7 @@ module.exports = {
3730 3882
 };
3731 3883
 
3732 3884
 
3733
-},{"../../service/RTC/RTCEvents":70,"../../service/desktopsharing/DesktopSharingEventTypes":74,"../RTC/RTCBrowserType":13,"../RTC/adapter.screenshare":15,"events":76}],17:[function(require,module,exports){
3885
+},{"../../service/RTC/RTCEvents":71,"../../service/desktopsharing/DesktopSharingEventTypes":75,"../RTC/RTCBrowserType":14,"../RTC/adapter.screenshare":16,"events":77}],18:[function(require,module,exports){
3734 3886
 function supportsLocalStorage() {
3735 3887
     try {
3736 3888
         return 'localStorage' in window && window.localStorage !== null;
@@ -3812,7 +3964,7 @@ Settings.prototype.setLanguage = function (lang) {
3812 3964
 
3813 3965
 module.exports = Settings;
3814 3966
 
3815
-},{}],18:[function(require,module,exports){
3967
+},{}],19:[function(require,module,exports){
3816 3968
 var XMPPEvents = require("../../service/xmpp/XMPPEvents");
3817 3969
 var Moderator = require("./moderator");
3818 3970
 var EventEmitter = require("events");
@@ -4392,7 +4544,7 @@ ChatRoom.prototype.addLocalStreams = function (localStreams) {
4392 4544
 }
4393 4545
 
4394 4546
 module.exports = ChatRoom;
4395
-},{"../../service/xmpp/XMPPEvents":75,"./moderator":26,"events":76}],19:[function(require,module,exports){
4547
+},{"../../service/xmpp/XMPPEvents":76,"./moderator":27,"events":77}],20:[function(require,module,exports){
4396 4548
 /*
4397 4549
  * JingleSession provides an API to manage a single Jingle session. We will
4398 4550
  * have different implementations depending on the underlying interface used
@@ -4524,7 +4676,7 @@ JingleSession.prototype.setAnswer = function(jingle) {};
4524 4676
 
4525 4677
 module.exports = JingleSession;
4526 4678
 
4527
-},{}],20:[function(require,module,exports){
4679
+},{}],21:[function(require,module,exports){
4528 4680
 /* jshint -W117 */
4529 4681
 var JingleSession = require("./JingleSession");
4530 4682
 var TraceablePeerConnection = require("./TraceablePeerConnection");
@@ -4632,10 +4784,7 @@ JingleSessionPC.prototype.doInitialize = function () {
4632 4784
         }
4633 4785
     };
4634 4786
     this.peerconnection.onremovestream = function (event) {
4635
-        // Remove the stream from remoteStreams
4636
-        // FIXME: remotestreamremoved.jingle not defined anywhere(unused)
4637 4787
 
4638
-        $(document).trigger('remotestreamremoved.jingle', [event, self.sid]);
4639 4788
     };
4640 4789
     this.peerconnection.onsignalingstatechange = function (event) {
4641 4790
         if (!(self && self.peerconnection)) return;
@@ -5634,6 +5783,8 @@ JingleSessionPC.prototype.switchStreams = function (new_stream, oldStream, succe
5634 5783
  */
5635 5784
 JingleSessionPC.prototype.addStream = function (stream, callback) {
5636 5785
 
5786
+    var self = this;
5787
+
5637 5788
     // Remember SDP to figure out added/removed SSRCs
5638 5789
     var oldSdp = null;
5639 5790
     if(this.peerconnection) {
@@ -5650,14 +5801,14 @@ JingleSessionPC.prototype.addStream = function (stream, callback) {
5650 5801
         return;
5651 5802
     }
5652 5803
 
5653
-    self.modifySourcesQueue.push(function() {
5804
+    this.modifySourcesQueue.push(function() {
5654 5805
         console.log('modify sources done');
5655 5806
 
5656 5807
         callback();
5657 5808
 
5658
-        var newSdp = new SDP(this.peerconnection.localDescription.sdp);
5809
+        var newSdp = new SDP(self.peerconnection.localDescription.sdp);
5659 5810
         console.log("SDPs", oldSdp, newSdp);
5660
-        this.notifyMySSRCUpdate(oldSdp, newSdp);
5811
+        self.notifyMySSRCUpdate(oldSdp, newSdp);
5661 5812
     });
5662 5813
 }
5663 5814
 
@@ -6008,7 +6159,7 @@ JingleSessionPC.prototype.remoteStreamAdded = function (data, times) {
6008 6159
 
6009 6160
 module.exports = JingleSessionPC;
6010 6161
 
6011
-},{"../../service/xmpp/XMPPEvents":75,"../RTC/RTC":12,"../RTC/RTCBrowserType":13,"./JingleSession":19,"./LocalSSRCReplacement":21,"./SDP":22,"./SDPDiffer":23,"./SDPUtil":24,"./TraceablePeerConnection":25,"async":33,"sdp-transform":66}],21:[function(require,module,exports){
6162
+},{"../../service/xmpp/XMPPEvents":76,"../RTC/RTC":13,"../RTC/RTCBrowserType":14,"./JingleSession":20,"./LocalSSRCReplacement":22,"./SDP":23,"./SDPDiffer":24,"./SDPUtil":25,"./TraceablePeerConnection":26,"async":34,"sdp-transform":67}],22:[function(require,module,exports){
6012 6163
 /* global $ */
6013 6164
 
6014 6165
 /*
@@ -6278,7 +6429,7 @@ var LocalSSRCReplacement = {
6278 6429
 
6279 6430
 module.exports = LocalSSRCReplacement;
6280 6431
 
6281
-},{"../RTC/RTCBrowserType":13,"./SDP":22}],22:[function(require,module,exports){
6432
+},{"../RTC/RTCBrowserType":14,"./SDP":23}],23:[function(require,module,exports){
6282 6433
 /* jshint -W117 */
6283 6434
 var SDPUtil = require("./SDPUtil");
6284 6435
 
@@ -6904,7 +7055,7 @@ SDP.prototype.jingle2media = function (content) {
6904 7055
 module.exports = SDP;
6905 7056
 
6906 7057
 
6907
-},{"./SDPUtil":24}],23:[function(require,module,exports){
7058
+},{"./SDPUtil":25}],24:[function(require,module,exports){
6908 7059
 
6909 7060
 var SDPUtil = require("./SDPUtil");
6910 7061
 
@@ -7076,7 +7227,7 @@ SDPDiffer.prototype.toJingle = function(modify) {
7076 7227
 };
7077 7228
 
7078 7229
 module.exports = SDPDiffer;
7079
-},{"./SDPUtil":24}],24:[function(require,module,exports){
7230
+},{"./SDPUtil":25}],25:[function(require,module,exports){
7080 7231
 SDPUtil = {
7081 7232
     filter_special_chars: function (text) {
7082 7233
         return text.replace(/[\\\/\{,\}\+]/g, "");
@@ -7429,7 +7580,7 @@ SDPUtil = {
7429 7580
     }
7430 7581
 };
7431 7582
 module.exports = SDPUtil;
7432
-},{}],25:[function(require,module,exports){
7583
+},{}],26:[function(require,module,exports){
7433 7584
 var RTC = require('../RTC/RTC');
7434 7585
 var RTCBrowserType = require("../RTC/RTCBrowserType.js");
7435 7586
 var XMPPEvents = require("../../service/xmpp/XMPPEvents");
@@ -7885,7 +8036,7 @@ TraceablePeerConnection.prototype.getStats = function(callback, errback) {
7885 8036
 module.exports = TraceablePeerConnection;
7886 8037
 
7887 8038
 
7888
-},{"../../service/xmpp/XMPPEvents":75,"../RTC/RTC":12,"../RTC/RTCBrowserType.js":13,"./LocalSSRCReplacement":21,"sdp-interop":52,"sdp-simulcast":59,"sdp-transform":66}],26:[function(require,module,exports){
8039
+},{"../../service/xmpp/XMPPEvents":76,"../RTC/RTC":13,"../RTC/RTCBrowserType.js":14,"./LocalSSRCReplacement":22,"sdp-interop":53,"sdp-simulcast":60,"sdp-transform":67}],27:[function(require,module,exports){
7889 8040
 /* global $, $iq, APP, config, messageHandler,
7890 8041
  roomName, sessionTerminated, Strophe, Util */
7891 8042
 var XMPPEvents = require("../../service/xmpp/XMPPEvents");
@@ -8306,7 +8457,7 @@ module.exports = Moderator;
8306 8457
 
8307 8458
 
8308 8459
 
8309
-},{"../../service/authentication/AuthenticationEvents":73,"../../service/xmpp/XMPPEvents":75,"../settings/Settings":17}],27:[function(require,module,exports){
8460
+},{"../../service/authentication/AuthenticationEvents":74,"../../service/xmpp/XMPPEvents":76,"../settings/Settings":18}],28:[function(require,module,exports){
8310 8461
 /* jshint -W117 */
8311 8462
 /* a simple MUC connection plugin
8312 8463
  * can only handle a single MUC room
@@ -8399,7 +8550,7 @@ module.exports = function(XMPP) {
8399 8550
 };
8400 8551
 
8401 8552
 
8402
-},{"./ChatRoom":18}],28:[function(require,module,exports){
8553
+},{"./ChatRoom":19}],29:[function(require,module,exports){
8403 8554
 /* jshint -W117 */
8404 8555
 
8405 8556
 var JingleSession = require("./JingleSessionPC");
@@ -8690,7 +8841,7 @@ module.exports = function(XMPP, eventEmitter) {
8690 8841
 };
8691 8842
 
8692 8843
 
8693
-},{"../../service/xmpp/XMPPEvents":75,"../RTC/RTCBrowserType":13,"./JingleSessionPC":20}],29:[function(require,module,exports){
8844
+},{"../../service/xmpp/XMPPEvents":76,"../RTC/RTCBrowserType":14,"./JingleSessionPC":21}],30:[function(require,module,exports){
8694 8845
 /* global Strophe */
8695 8846
 module.exports = function () {
8696 8847
 
@@ -8711,7 +8862,7 @@ module.exports = function () {
8711 8862
         }
8712 8863
     });
8713 8864
 };
8714
-},{}],30:[function(require,module,exports){
8865
+},{}],31:[function(require,module,exports){
8715 8866
 /* jshint -W117 */
8716 8867
 module.exports = function() {
8717 8868
     Strophe.addConnectionPlugin('rayo',
@@ -8808,7 +8959,7 @@ module.exports = function() {
8808 8959
     );
8809 8960
 };
8810 8961
 
8811
-},{}],31:[function(require,module,exports){
8962
+},{}],32:[function(require,module,exports){
8812 8963
 /**
8813 8964
  * Strophe logger implementation. Logs from level WARN and above.
8814 8965
  */
@@ -8852,7 +9003,7 @@ module.exports = function () {
8852 9003
     };
8853 9004
 };
8854 9005
 
8855
-},{}],32:[function(require,module,exports){
9006
+},{}],33:[function(require,module,exports){
8856 9007
 /* global $, APP, config, Strophe*/
8857 9008
 var EventEmitter = require("events");
8858 9009
 var Pako = require("pako");
@@ -9148,7 +9299,7 @@ XMPP.prototype.disconnect = function () {
9148 9299
 
9149 9300
 module.exports = XMPP;
9150 9301
 
9151
-},{"../../JitsiConnectionErrors":5,"../../JitsiConnectionEvents":6,"../../service/RTC/RTCEvents":70,"../../service/RTC/StreamEventTypes":72,"../../service/xmpp/XMPPEvents":75,"../RTC/RTC":12,"./strophe.emuc":27,"./strophe.jingle":28,"./strophe.logger":29,"./strophe.rayo":30,"./strophe.util":31,"events":76,"pako":35}],33:[function(require,module,exports){
9302
+},{"../../JitsiConnectionErrors":5,"../../JitsiConnectionEvents":6,"../../service/RTC/RTCEvents":71,"../../service/RTC/StreamEventTypes":73,"../../service/xmpp/XMPPEvents":76,"../RTC/RTC":13,"./strophe.emuc":28,"./strophe.jingle":29,"./strophe.logger":30,"./strophe.rayo":31,"./strophe.util":32,"events":77,"pako":36}],34:[function(require,module,exports){
9152 9303
 (function (process){
9153 9304
 /*!
9154 9305
  * async
@@ -10275,7 +10426,7 @@ module.exports = XMPP;
10275 10426
 }());
10276 10427
 
10277 10428
 }).call(this,require('_process'))
10278
-},{"_process":77}],34:[function(require,module,exports){
10429
+},{"_process":78}],35:[function(require,module,exports){
10279 10430
 (function (process,global){
10280 10431
 /*!
10281 10432
  * @overview es6-promise - a tiny implementation of Promises/A+.
@@ -11246,7 +11397,7 @@ module.exports = XMPP;
11246 11397
 
11247 11398
 
11248 11399
 }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
11249
-},{"_process":77}],35:[function(require,module,exports){
11400
+},{"_process":78}],36:[function(require,module,exports){
11250 11401
 // Top level file is just a mixin of submodules & constants
11251 11402
 'use strict';
11252 11403
 
@@ -11262,7 +11413,7 @@ assign(pako, deflate, inflate, constants);
11262 11413
 
11263 11414
 module.exports = pako;
11264 11415
 
11265
-},{"./lib/deflate":36,"./lib/inflate":37,"./lib/utils/common":38,"./lib/zlib/constants":41}],36:[function(require,module,exports){
11416
+},{"./lib/deflate":37,"./lib/inflate":38,"./lib/utils/common":39,"./lib/zlib/constants":42}],37:[function(require,module,exports){
11266 11417
 'use strict';
11267 11418
 
11268 11419
 
@@ -11640,7 +11791,7 @@ exports.deflate = deflate;
11640 11791
 exports.deflateRaw = deflateRaw;
11641 11792
 exports.gzip = gzip;
11642 11793
 
11643
-},{"./utils/common":38,"./utils/strings":39,"./zlib/deflate.js":43,"./zlib/messages":48,"./zlib/zstream":50}],37:[function(require,module,exports){
11794
+},{"./utils/common":39,"./utils/strings":40,"./zlib/deflate.js":44,"./zlib/messages":49,"./zlib/zstream":51}],38:[function(require,module,exports){
11644 11795
 'use strict';
11645 11796
 
11646 11797
 
@@ -12021,7 +12172,7 @@ exports.inflate = inflate;
12021 12172
 exports.inflateRaw = inflateRaw;
12022 12173
 exports.ungzip  = inflate;
12023 12174
 
12024
-},{"./utils/common":38,"./utils/strings":39,"./zlib/constants":41,"./zlib/gzheader":44,"./zlib/inflate.js":46,"./zlib/messages":48,"./zlib/zstream":50}],38:[function(require,module,exports){
12175
+},{"./utils/common":39,"./utils/strings":40,"./zlib/constants":42,"./zlib/gzheader":45,"./zlib/inflate.js":47,"./zlib/messages":49,"./zlib/zstream":51}],39:[function(require,module,exports){
12025 12176
 'use strict';
12026 12177
 
12027 12178
 
@@ -12125,7 +12276,7 @@ exports.setTyped = function (on) {
12125 12276
 
12126 12277
 exports.setTyped(TYPED_OK);
12127 12278
 
12128
-},{}],39:[function(require,module,exports){
12279
+},{}],40:[function(require,module,exports){
12129 12280
 // String encode/decode helpers
12130 12281
 'use strict';
12131 12282
 
@@ -12312,7 +12463,7 @@ exports.utf8border = function(buf, max) {
12312 12463
   return (pos + _utf8len[buf[pos]] > max) ? pos : max;
12313 12464
 };
12314 12465
 
12315
-},{"./common":38}],40:[function(require,module,exports){
12466
+},{"./common":39}],41:[function(require,module,exports){
12316 12467
 'use strict';
12317 12468
 
12318 12469
 // Note: adler32 takes 12% for level 0 and 2% for level 6.
@@ -12346,7 +12497,7 @@ function adler32(adler, buf, len, pos) {
12346 12497
 
12347 12498
 module.exports = adler32;
12348 12499
 
12349
-},{}],41:[function(require,module,exports){
12500
+},{}],42:[function(require,module,exports){
12350 12501
 module.exports = {
12351 12502
 
12352 12503
   /* Allowed flush values; see deflate() and inflate() below for details */
@@ -12395,7 +12546,7 @@ module.exports = {
12395 12546
   //Z_NULL:                 null // Use -1 or null inline, depending on var type
12396 12547
 };
12397 12548
 
12398
-},{}],42:[function(require,module,exports){
12549
+},{}],43:[function(require,module,exports){
12399 12550
 'use strict';
12400 12551
 
12401 12552
 // Note: we can't get significant speed boost here.
@@ -12438,7 +12589,7 @@ function crc32(crc, buf, len, pos) {
12438 12589
 
12439 12590
 module.exports = crc32;
12440 12591
 
12441
-},{}],43:[function(require,module,exports){
12592
+},{}],44:[function(require,module,exports){
12442 12593
 'use strict';
12443 12594
 
12444 12595
 var utils   = require('../utils/common');
@@ -14205,7 +14356,7 @@ exports.deflatePrime = deflatePrime;
14205 14356
 exports.deflateTune = deflateTune;
14206 14357
 */
14207 14358
 
14208
-},{"../utils/common":38,"./adler32":40,"./crc32":42,"./messages":48,"./trees":49}],44:[function(require,module,exports){
14359
+},{"../utils/common":39,"./adler32":41,"./crc32":43,"./messages":49,"./trees":50}],45:[function(require,module,exports){
14209 14360
 'use strict';
14210 14361
 
14211 14362
 
@@ -14247,7 +14398,7 @@ function GZheader() {
14247 14398
 
14248 14399
 module.exports = GZheader;
14249 14400
 
14250
-},{}],45:[function(require,module,exports){
14401
+},{}],46:[function(require,module,exports){
14251 14402
 'use strict';
14252 14403
 
14253 14404
 // See state defs from inflate.js
@@ -14574,7 +14725,7 @@ module.exports = function inflate_fast(strm, start) {
14574 14725
   return;
14575 14726
 };
14576 14727
 
14577
-},{}],46:[function(require,module,exports){
14728
+},{}],47:[function(require,module,exports){
14578 14729
 'use strict';
14579 14730
 
14580 14731
 
@@ -16079,7 +16230,7 @@ exports.inflateSyncPoint = inflateSyncPoint;
16079 16230
 exports.inflateUndermine = inflateUndermine;
16080 16231
 */
16081 16232
 
16082
-},{"../utils/common":38,"./adler32":40,"./crc32":42,"./inffast":45,"./inftrees":47}],47:[function(require,module,exports){
16233
+},{"../utils/common":39,"./adler32":41,"./crc32":43,"./inffast":46,"./inftrees":48}],48:[function(require,module,exports){
16083 16234
 'use strict';
16084 16235
 
16085 16236
 
@@ -16408,7 +16559,7 @@ module.exports = function inflate_table(type, lens, lens_index, codes, table, ta
16408 16559
   return 0;
16409 16560
 };
16410 16561
 
16411
-},{"../utils/common":38}],48:[function(require,module,exports){
16562
+},{"../utils/common":39}],49:[function(require,module,exports){
16412 16563
 'use strict';
16413 16564
 
16414 16565
 module.exports = {
@@ -16423,7 +16574,7 @@ module.exports = {
16423 16574
   '-6':   'incompatible version' /* Z_VERSION_ERROR (-6) */
16424 16575
 };
16425 16576
 
16426
-},{}],49:[function(require,module,exports){
16577
+},{}],50:[function(require,module,exports){
16427 16578
 'use strict';
16428 16579
 
16429 16580
 
@@ -17624,7 +17775,7 @@ exports._tr_flush_block  = _tr_flush_block;
17624 17775
 exports._tr_tally = _tr_tally;
17625 17776
 exports._tr_align = _tr_align;
17626 17777
 
17627
-},{"../utils/common":38}],50:[function(require,module,exports){
17778
+},{"../utils/common":39}],51:[function(require,module,exports){
17628 17779
 'use strict';
17629 17780
 
17630 17781
 
@@ -17655,7 +17806,7 @@ function ZStream() {
17655 17806
 
17656 17807
 module.exports = ZStream;
17657 17808
 
17658
-},{}],51:[function(require,module,exports){
17809
+},{}],52:[function(require,module,exports){
17659 17810
 module.exports = function arrayEquals(array) {
17660 17811
     // if the other array is a falsy value, return
17661 17812
     if (!array)
@@ -17681,10 +17832,10 @@ module.exports = function arrayEquals(array) {
17681 17832
 }
17682 17833
 
17683 17834
 
17684
-},{}],52:[function(require,module,exports){
17835
+},{}],53:[function(require,module,exports){
17685 17836
 exports.Interop = require('./interop');
17686 17837
 
17687
-},{"./interop":53}],53:[function(require,module,exports){
17838
+},{"./interop":54}],54:[function(require,module,exports){
17688 17839
 "use strict";
17689 17840
 
17690 17841
 var transform = require('./transform');
@@ -18266,7 +18417,7 @@ Interop.prototype.toUnifiedPlan = function(desc) {
18266 18417
     //#endregion
18267 18418
 };
18268 18419
 
18269
-},{"./array-equals":51,"./transform":54}],54:[function(require,module,exports){
18420
+},{"./array-equals":52,"./transform":55}],55:[function(require,module,exports){
18270 18421
 var transform = require('sdp-transform');
18271 18422
 
18272 18423
 exports.write = function(session, opts) {
@@ -18365,7 +18516,7 @@ exports.parse = function(sdp) {
18365 18516
 };
18366 18517
 
18367 18518
 
18368
-},{"sdp-transform":56}],55:[function(require,module,exports){
18519
+},{"sdp-transform":57}],56:[function(require,module,exports){
18369 18520
 var grammar = module.exports = {
18370 18521
   v: [{
18371 18522
       name: 'version',
@@ -18614,7 +18765,7 @@ Object.keys(grammar).forEach(function (key) {
18614 18765
   });
18615 18766
 });
18616 18767
 
18617
-},{}],56:[function(require,module,exports){
18768
+},{}],57:[function(require,module,exports){
18618 18769
 var parser = require('./parser');
18619 18770
 var writer = require('./writer');
18620 18771
 
@@ -18624,7 +18775,7 @@ exports.parseFmtpConfig = parser.parseFmtpConfig;
18624 18775
 exports.parsePayloads = parser.parsePayloads;
18625 18776
 exports.parseRemoteCandidates = parser.parseRemoteCandidates;
18626 18777
 
18627
-},{"./parser":57,"./writer":58}],57:[function(require,module,exports){
18778
+},{"./parser":58,"./writer":59}],58:[function(require,module,exports){
18628 18779
 var toIntIfInt = function (v) {
18629 18780
   return String(Number(v)) === v ? Number(v) : v;
18630 18781
 };
@@ -18719,7 +18870,7 @@ exports.parseRemoteCandidates = function (str) {
18719 18870
   return candidates;
18720 18871
 };
18721 18872
 
18722
-},{"./grammar":55}],58:[function(require,module,exports){
18873
+},{"./grammar":56}],59:[function(require,module,exports){
18723 18874
 var grammar = require('./grammar');
18724 18875
 
18725 18876
 // customized util.format - discards excess arguments and can void middle ones
@@ -18835,7 +18986,7 @@ module.exports = function (session, opts) {
18835 18986
   return sdp.join('\r\n') + '\r\n';
18836 18987
 };
18837 18988
 
18838
-},{"./grammar":55}],59:[function(require,module,exports){
18989
+},{"./grammar":56}],60:[function(require,module,exports){
18839 18990
 var transform = require('sdp-transform');
18840 18991
 var transformUtils = require('./transform-utils');
18841 18992
 var parseSsrcs = transformUtils.parseSsrcs;
@@ -19237,7 +19388,7 @@ Simulcast.prototype.mungeLocalDescription = function (desc) {
19237 19388
 
19238 19389
 module.exports = Simulcast;
19239 19390
 
19240
-},{"./transform-utils":60,"sdp-transform":62}],60:[function(require,module,exports){
19391
+},{"./transform-utils":61,"sdp-transform":63}],61:[function(require,module,exports){
19241 19392
 exports.writeSsrcs = function(sources, order) {
19242 19393
   var ssrcs = [];
19243 19394
 
@@ -19288,15 +19439,15 @@ exports.parseSsrcs = function (mLine) {
19288 19439
 };
19289 19440
 
19290 19441
 
19291
-},{}],61:[function(require,module,exports){
19292
-arguments[4][55][0].apply(exports,arguments)
19293
-},{"dup":55}],62:[function(require,module,exports){
19442
+},{}],62:[function(require,module,exports){
19294 19443
 arguments[4][56][0].apply(exports,arguments)
19295
-},{"./parser":63,"./writer":64,"dup":56}],63:[function(require,module,exports){
19444
+},{"dup":56}],63:[function(require,module,exports){
19296 19445
 arguments[4][57][0].apply(exports,arguments)
19297
-},{"./grammar":61,"dup":57}],64:[function(require,module,exports){
19446
+},{"./parser":64,"./writer":65,"dup":57}],64:[function(require,module,exports){
19298 19447
 arguments[4][58][0].apply(exports,arguments)
19299
-},{"./grammar":61,"dup":58}],65:[function(require,module,exports){
19448
+},{"./grammar":62,"dup":58}],65:[function(require,module,exports){
19449
+arguments[4][59][0].apply(exports,arguments)
19450
+},{"./grammar":62,"dup":59}],66:[function(require,module,exports){
19300 19451
 var grammar = module.exports = {
19301 19452
   v: [{
19302 19453
       name: 'version',
@@ -19547,9 +19698,9 @@ Object.keys(grammar).forEach(function (key) {
19547 19698
   });
19548 19699
 });
19549 19700
 
19550
-},{}],66:[function(require,module,exports){
19551
-arguments[4][56][0].apply(exports,arguments)
19552
-},{"./parser":67,"./writer":68,"dup":56}],67:[function(require,module,exports){
19701
+},{}],67:[function(require,module,exports){
19702
+arguments[4][57][0].apply(exports,arguments)
19703
+},{"./parser":68,"./writer":69,"dup":57}],68:[function(require,module,exports){
19553 19704
 var toIntIfInt = function (v) {
19554 19705
   return String(Number(v)) === v ? Number(v) : v;
19555 19706
 };
@@ -19644,16 +19795,16 @@ exports.parseRemoteCandidates = function (str) {
19644 19795
   return candidates;
19645 19796
 };
19646 19797
 
19647
-},{"./grammar":65}],68:[function(require,module,exports){
19648
-arguments[4][58][0].apply(exports,arguments)
19649
-},{"./grammar":65,"dup":58}],69:[function(require,module,exports){
19798
+},{"./grammar":66}],69:[function(require,module,exports){
19799
+arguments[4][59][0].apply(exports,arguments)
19800
+},{"./grammar":66,"dup":59}],70:[function(require,module,exports){
19650 19801
 var MediaStreamType = {
19651 19802
     VIDEO_TYPE: "Video",
19652 19803
 
19653 19804
     AUDIO_TYPE: "Audio"
19654 19805
 };
19655 19806
 module.exports = MediaStreamType;
19656
-},{}],70:[function(require,module,exports){
19807
+},{}],71:[function(require,module,exports){
19657 19808
 var RTCEvents = {
19658 19809
     RTC_READY: "rtc.ready",
19659 19810
     DATA_CHANNEL_OPEN: "rtc.data_channel_open",
@@ -19666,7 +19817,7 @@ var RTCEvents = {
19666 19817
 };
19667 19818
 
19668 19819
 module.exports = RTCEvents;
19669
-},{}],71:[function(require,module,exports){
19820
+},{}],72:[function(require,module,exports){
19670 19821
 var Resolutions = {
19671 19822
     "1080": {
19672 19823
         width: 1920,
@@ -19720,7 +19871,7 @@ var Resolutions = {
19720 19871
     }
19721 19872
 };
19722 19873
 module.exports = Resolutions;
19723
-},{}],72:[function(require,module,exports){
19874
+},{}],73:[function(require,module,exports){
19724 19875
 var StreamEventTypes = {
19725 19876
     EVENT_TYPE_LOCAL_CREATED: "stream.local_created",
19726 19877
 
@@ -19734,7 +19885,7 @@ var StreamEventTypes = {
19734 19885
 };
19735 19886
 
19736 19887
 module.exports = StreamEventTypes;
19737
-},{}],73:[function(require,module,exports){
19888
+},{}],74:[function(require,module,exports){
19738 19889
 var AuthenticationEvents = {
19739 19890
     /**
19740 19891
      * Event callback arguments:
@@ -19748,7 +19899,7 @@ var AuthenticationEvents = {
19748 19899
 };
19749 19900
 module.exports = AuthenticationEvents;
19750 19901
 
19751
-},{}],74:[function(require,module,exports){
19902
+},{}],75:[function(require,module,exports){
19752 19903
 var DesktopSharingEventTypes = {
19753 19904
     INIT: "ds.init",
19754 19905
 
@@ -19758,7 +19909,7 @@ var DesktopSharingEventTypes = {
19758 19909
 };
19759 19910
 
19760 19911
 module.exports = DesktopSharingEventTypes;
19761
-},{}],75:[function(require,module,exports){
19912
+},{}],76:[function(require,module,exports){
19762 19913
 var XMPPEvents = {
19763 19914
     CONNECTION_FAILED: "xmpp.connection.failed",
19764 19915
     // Indicates an interrupted connection event.
@@ -19815,7 +19966,7 @@ var XMPPEvents = {
19815 19966
     REMOTE_STREAM_RECEIVED: "xmpp.remote_stream_received"
19816 19967
 };
19817 19968
 module.exports = XMPPEvents;
19818
-},{}],76:[function(require,module,exports){
19969
+},{}],77:[function(require,module,exports){
19819 19970
 // Copyright Joyent, Inc. and other Node contributors.
19820 19971
 //
19821 19972
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -20118,7 +20269,7 @@ function isUndefined(arg) {
20118 20269
   return arg === void 0;
20119 20270
 }
20120 20271
 
20121
-},{}],77:[function(require,module,exports){
20272
+},{}],78:[function(require,module,exports){
20122 20273
 // shim for using process in browser
20123 20274
 
20124 20275
 var process = module.exports = {};

+ 0
- 21
modules/RTC/JitsiLocalTrack.js 查看文件

@@ -1,24 +1,6 @@
1 1
 var JitsiTrack = require("./JitsiTrack");
2 2
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
3 3
 var RTCEvents = require("../../service/RTC/RTCEvents");
4
-var RTCBrowserType = require("./RTCBrowserType");
5
-
6
-/**
7
- * This implements 'onended' callback normally fired by WebRTC after the stream
8
- * is stopped. There is no such behaviour yet in FF, so we have to add it.
9
- * @param stream original WebRTC stream object to which 'onended' handling
10
- *               will be added.
11
- */
12
-function implementOnEndedHandling(stream) {
13
-    var originalStop = stream.stop;
14
-    stream.stop = function () {
15
-        originalStop.apply(stream);
16
-        if (!stream.ended) {
17
-            stream.ended = true;
18
-            stream.onended();
19
-        }
20
-    };
21
-}
22 4
 
23 5
 /**
24 6
  * Represents a single media track (either audio or video).
@@ -35,9 +17,6 @@ function JitsiLocalTrack(RTC, stream, eventEmitter, videoType, isGUMStream)
35 17
     this.stream.onended = function () {
36 18
         this.eventEmitter.emit(StreamEventTypes.EVENT_TYPE_LOCAL_ENDED, this);
37 19
     }.bind(this);
38
-    if (RTCBrowserType.isFirefox()) {
39
-        implementOnEndedHandling(this.stream);
40
-    }
41 20
 }
42 21
 
43 22
 JitsiLocalTrack.prototype = Object.create(JitsiTrack.prototype);

+ 6
- 0
modules/RTC/JitsiRemoteTrack.js 查看文件

@@ -1,4 +1,5 @@
1 1
 var JitsiTrack = require("./JitsiTrack");
2
+var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
2 3
 
3 4
 /**
4 5
  * Represents a single media track (either audio or video).
@@ -14,6 +15,11 @@ function JitsiRemoteTrack(RTC, data, sid, ssrc, browser, eventEmitter) {
14 15
     this.ssrc = ssrc;
15 16
     this.muted = false;
16 17
     this.eventEmitter = eventEmitter;
18
+    var self = this;
19
+    if(this.stream)
20
+        this.stream.onended = function () {
21
+            eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_ENDED, self);
22
+        }
17 23
 }
18 24
 
19 25
 JitsiRemoteTrack.prototype = Object.create(JitsiTrack.prototype);

+ 21
- 0
modules/RTC/JitsiTrack.js 查看文件

@@ -1,4 +1,22 @@
1 1
 var RTC = require("./RTCUtils");
2
+var RTCBrowserType = require("./RTCBrowserType");
3
+
4
+/**
5
+ * This implements 'onended' callback normally fired by WebRTC after the stream
6
+ * is stopped. There is no such behaviour yet in FF, so we have to add it.
7
+ * @param stream original WebRTC stream object to which 'onended' handling
8
+ *               will be added.
9
+ */
10
+function implementOnEndedHandling(stream) {
11
+    var originalStop = stream.stop;
12
+    stream.stop = function () {
13
+        originalStop.apply(stream);
14
+        if (!stream.ended) {
15
+            stream.ended = true;
16
+            stream.onended();
17
+        }
18
+    };
19
+}
2 20
 
3 21
 /**
4 22
  * Represents a single media track (either audio or video).
@@ -19,6 +37,9 @@ function JitsiTrack(RTC, stream)
19 37
             return this.stream.getVideoTracks();
20 38
         }.bind(this);
21 39
     }
40
+    if (RTCBrowserType.isFirefox() && this.stream) {
41
+        implementOnEndedHandling(this.stream);
42
+    }
22 43
 }
23 44
 
24 45
 /**

Loading…
取消
儲存