Переглянути джерело

Resolve xmpp dependacies in RTC module

master
hristoterezov 9 роки тому
джерело
коміт
c3f9885df0

+ 155
- 58
JitsiConference.js Переглянути файл

17
 var Settings = require("./modules/settings/Settings");
17
 var Settings = require("./modules/settings/Settings");
18
 var ComponentsVersions = require("./modules/version/ComponentsVersions");
18
 var ComponentsVersions = require("./modules/version/ComponentsVersions");
19
 var GlobalOnErrorHandler = require("./modules/util/GlobalOnErrorHandler");
19
 var GlobalOnErrorHandler = require("./modules/util/GlobalOnErrorHandler");
20
+var MediaType = require("./service/RTC/MediaType");
20
 
21
 
21
 /**
22
 /**
22
  * Creates a JitsiConference object with the given name and properties.
23
  * Creates a JitsiConference object with the given name and properties.
35
         logger.error(errmsg);
36
         logger.error(errmsg);
36
         throw new Error(errmsg);
37
         throw new Error(errmsg);
37
     }
38
     }
38
-    this.options = options;
39
-    this.connection = this.options.connection;
40
-    this.xmpp = this.connection.xmpp;
41
     this.eventEmitter = new EventEmitter();
39
     this.eventEmitter = new EventEmitter();
42
-    var confID = this.options.name  + '@' + this.xmpp.options.hosts.muc;
43
     this.settings = new Settings();
40
     this.settings = new Settings();
44
-    this.room = this.xmpp.createRoom(this.options.name, this.options.config,
45
-        this.settings);
46
-    this.componentsVersions = new ComponentsVersions(this.room);
47
-    this.room.updateDeviceAvailability(RTC.getDeviceAvailability());
48
-    this.rtc = new RTC(this.room, options);
41
+    this._init(options);
42
+    this.rtc = new RTC(this, options);
49
     this.statistics = new Statistics(this.xmpp, {
43
     this.statistics = new Statistics(this.xmpp, {
50
         callStatsID: this.options.config.callStatsID,
44
         callStatsID: this.options.config.callStatsID,
51
         callStatsSecret: this.options.config.callStatsSecret,
45
         callStatsSecret: this.options.config.callStatsSecret,
70
     this.isMutedByFocus = false;
64
     this.isMutedByFocus = false;
71
 }
65
 }
72
 
66
 
67
+/**
68
+ * Initializes the conference object properties
69
+ * @param options overrides this.options
70
+ */
71
+JitsiConference.prototype._init = function (options) {
72
+    if(!options)
73
+        options = {};
74
+    if(!this.options) {
75
+        this.options = options;
76
+    } else {
77
+        // Override config options
78
+        var config = options.config || {};
79
+        for(var key in config)
80
+            this.options.config[key] = config[key] || this.options.config[key];
81
+    }
82
+
83
+    // Override connection and xmpp properties (Usefull if the connection
84
+    // reloaded)
85
+    this.connection = options.connection || this.connection;
86
+    this.xmpp = this.connection.xmpp;
87
+
88
+    this.room = this.xmpp.createRoom(this.options.name, this.options.config,
89
+        this.settings);
90
+    this.componentsVersions = new ComponentsVersions(this.room);
91
+    this.room.updateDeviceAvailability(RTC.getDeviceAvailability());
92
+
93
+}
94
+
95
+/**
96
+ * Reloads the conference
97
+ * @param options {object} options to be overriden
98
+ */
99
+JitsiConference.prototype.reload = function (options) {
100
+    this.leave().then(function(){
101
+        this._init(options || {});
102
+        this.join();
103
+    }.bind(this));
104
+}
105
+
73
 /**
106
 /**
74
  * Joins the conference.
107
  * Joins the conference.
75
  * @param password {string} the password
108
  * @param password {string} the password
343
                 });
376
                 });
344
             }
377
             }
345
             this.rtc.addLocalTrack(track);
378
             this.rtc.addLocalTrack(track);
379
+
346
             if (track.startMuted) {
380
             if (track.startMuted) {
347
                 track.mute();
381
                 track.mute();
348
             }
382
             }
360
                                    track.muteHandler);
394
                                    track.muteHandler);
361
             track.addEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
395
             track.addEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
362
                                    track.audioLevelHandler);
396
                                    track.audioLevelHandler);
363
-            //FIXME: This dependacy is not necessary. This is quick fix.
397
+
364
             track._setConference(this);
398
             track._setConference(this);
365
 
399
 
366
             // send event for starting screen sharing
400
             // send event for starting screen sharing
422
     return new Promise(function (resolve, reject) {
456
     return new Promise(function (resolve, reject) {
423
         this.room.removeStream(track.getOriginalStream(), function(){
457
         this.room.removeStream(track.getOriginalStream(), function(){
424
             track._setSSRC(null);
458
             track._setSSRC(null);
425
-            //FIXME: This dependacy is not necessary. This is quick fix.
426
-            track._setConference(this);
459
+            track._setConference(null);
427
             this.rtc.removeLocalTrack(track);
460
             this.rtc.removeLocalTrack(track);
428
             track.removeEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED,
461
             track.removeEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED,
429
                 track.muteHandler);
462
                 track.muteHandler);
669
     emitter.emit(JitsiConferenceEvents.TRACK_ADDED, track);
702
     emitter.emit(JitsiConferenceEvents.TRACK_ADDED, track);
670
 };
703
 };
671
 
704
 
705
+/**
706
+ * Handles incoming call event.
707
+ */
708
+JitsiConference.prototype.onIncomingCall =
709
+function (jingleSession, jingleOffer, now) {
710
+    if (!this.room.isFocus(jingleSession.peerjid)) {
711
+        // Error cause this should never happen unless something is wrong!
712
+        var errmsg = "Rejecting session-initiate from non-focus user: "
713
+                + jingleSession.peerjid;
714
+        GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));
715
+        logger.error(errmsg);
716
+        return;
717
+    }
718
+
719
+    // Accept incoming call
720
+    this.room.setJingleSession(jingleSession);
721
+    this.room.connectionTimes["session.initiate"] = now;
722
+    try{
723
+        jingleSession.initialize(false /* initiator */,this.room);
724
+    } catch (error) {
725
+        GlobalOnErrorHandler.callErrorHandler(error);
726
+    };
727
+
728
+    this.rtc.onIncommingCall(jingleSession);
729
+    // Add local Tracks to the ChatRoom
730
+    this.rtc.localTracks.forEach(function(localTrack) {
731
+        var ssrcInfo = null;
732
+        if(localTrack.isVideoTrack() && localTrack.isMuted()) {
733
+            /**
734
+             * Handles issues when the stream is added before the peerconnection
735
+             * is created. The peerconnection is created when second participant
736
+             * enters the call. In that use case the track doesn't have
737
+             * information about it's ssrcs and no jingle packets are sent. That
738
+             * can cause inconsistent behavior later.
739
+             *
740
+             * For example:
741
+             * If we mute the stream and than second participant enter it's
742
+             * remote SDP won't include that track. On unmute we are not sending
743
+             * any jingle packets which will brake the unmute.
744
+             *
745
+             * In order to solve issues like the above one here we have to
746
+             * generate the ssrc information for the track .
747
+             */
748
+            localTrack._setSSRC(
749
+                this.room.generateNewStreamSSRCInfo());
750
+            ssrcInfo = {
751
+                mtype: localTrack.getType(),
752
+                type: "addMuted",
753
+                ssrc: localTrack.ssrc,
754
+                msid: localTrack.initialMSID
755
+            };
756
+        }
757
+        try {
758
+            this.room.addStream(
759
+                localTrack.getOriginalStream(), function () {}, function () {},
760
+                ssrcInfo, true);
761
+        } catch(e) {
762
+            GlobalOnErrorHandler.callErrorHandler(e);
763
+            logger.error(e);
764
+        }
765
+    }.bind(this));
766
+
767
+    jingleSession.acceptOffer(jingleOffer, null,
768
+        function (error) {
769
+            GlobalOnErrorHandler.callErrorHandler(error);
770
+            logger.error(
771
+                "Failed to accept incoming Jingle session", error);
772
+        }
773
+    );
774
+
775
+    // Start callstats as soon as peerconnection is initialized,
776
+    // do not wait for XMPPEvents.PEERCONNECTION_READY, as it may never
777
+    // happen in case if user doesn't have or denied permission to
778
+    // both camera and microphone.
779
+    this.statistics.startCallStats(jingleSession, this.settings);
780
+    this.statistics.startRemoteStats(jingleSession.peerconnection);
781
+}
782
+
672
 JitsiConference.prototype.updateDTMFSupport = function () {
783
 JitsiConference.prototype.updateDTMFSupport = function () {
673
     var somebodySupportsDTMF = false;
784
     var somebodySupportsDTMF = false;
674
     var participants = this.getParticipants();
785
     var participants = this.getParticipants();
915
     return this.statistics.isCallstatsEnabled();
1026
     return this.statistics.isCallstatsEnabled();
916
 }
1027
 }
917
 
1028
 
1029
+
1030
+/**
1031
+ * Handles track attached to container (Calls associateStreamWithVideoTag method
1032
+ * from statistics module)
1033
+ * @param track the track
1034
+ * @param container the container
1035
+ */
1036
+JitsiConference.prototype._onTrackAttach = function(track, container) {
1037
+    var ssrc = track.getSSRC();
1038
+    if (!container.id || !ssrc) {
1039
+        return;
1040
+    }
1041
+    this.statistics.associateStreamWithVideoTag(
1042
+        ssrc, track.isLocal(), track.getUsageLabel(), container.id);
1043
+}
1044
+
918
 /**
1045
 /**
919
  * Setups the listeners needed for the conference.
1046
  * Setups the listeners needed for the conference.
920
  * @param conference the conference
1047
  * @param conference the conference
921
  */
1048
  */
922
 function setupListeners(conference) {
1049
 function setupListeners(conference) {
923
     conference.xmpp.addListener(
1050
     conference.xmpp.addListener(
924
-        XMPPEvents.CALL_INCOMING, function (jingleSession, jingleOffer, now) {
925
-
926
-        if (conference.room.isFocus(jingleSession.peerjid)) {
927
-            // Accept incoming call
928
-            conference.room.setJingleSession(jingleSession);
929
-            conference.room.connectionTimes["session.initiate"] = now;
930
-            try{
931
-                jingleSession.initialize(false /* initiator */,
932
-                    conference.room);
933
-            } catch (error) {
934
-                GlobalOnErrorHandler.callErrorHandler(error);
935
-            };
936
-            conference.rtc.onIncommingCall(jingleSession);
937
-            jingleSession.acceptOffer(jingleOffer, null,
938
-                function (error) {
939
-                    GlobalOnErrorHandler.callErrorHandler(error);
940
-                    logger.error(
941
-                        "Failed to accept incoming Jingle session", error);
942
-                }
943
-            );
944
-            // Start callstats as soon as peerconnection is initialized,
945
-            // do not wait for XMPPEvents.PEERCONNECTION_READY, as it may never
946
-            // happen in case if user doesn't have or denied permission to
947
-            // both camera and microphone.
948
-            conference.statistics.startCallStats(jingleSession, conference.settings);
949
-            conference.statistics.startRemoteStats(jingleSession.peerconnection);
950
-        } else {
951
-            // Error cause this should never happen unless something is wrong!
952
-            var errmsg
953
-                = "Rejecting session-initiate from non-focus user: "
954
-                    + jingleSession.peerjid;
955
-            GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));
956
-            logger.error(errmsg);
957
-        }
958
-    });
1051
+        XMPPEvents.CALL_INCOMING, conference.onIncomingCall.bind(conference));
959
 
1052
 
960
     conference.room.addListener(XMPPEvents.ICE_RESTARTING, function () {
1053
     conference.room.addListener(XMPPEvents.ICE_RESTARTING, function () {
961
         // All data channels have to be closed, before ICE restart
1054
         // All data channels have to be closed, before ICE restart
1206
     conference.rtc.addListener(RTCEvents.AVAILABLE_DEVICES_CHANGED, function (devices) {
1299
     conference.rtc.addListener(RTCEvents.AVAILABLE_DEVICES_CHANGED, function (devices) {
1207
         conference.room.updateDeviceAvailability(devices);
1300
         conference.room.updateDeviceAvailability(devices);
1208
     });
1301
     });
1302
+
1303
+    conference.room.addPresenceListener("videomuted", function (values, from) {
1304
+        conference.rtc.handleRemoteTrackMute(MediaType.VIDEO,
1305
+            values.value == "true", from);
1306
+    });
1307
+
1308
+    conference.room.addPresenceListener("audiomuted", function (values, from) {
1309
+        conference.rtc.handleRemoteTrackMute(MediaType.AUDIO,
1310
+            values.value == "true", from);
1311
+    });
1312
+
1313
+    conference.room.addPresenceListener("videoType", function(data, from) {
1314
+        conference.rtc.handleRemoteTrackVideoTypeChanged(data.value, from);
1315
+    });
1316
+
1209
     conference.room.addPresenceListener("devices", function (data, from) {
1317
     conference.room.addPresenceListener("devices", function (data, from) {
1210
         var isAudioAvailable = false;
1318
         var isAudioAvailable = false;
1211
         var isVideoAvailable = false;
1319
         var isVideoAvailable = false;
1305
                     new Error("ICE fail"));
1413
                     new Error("ICE fail"));
1306
             });
1414
             });
1307
 
1415
 
1308
-        conference.rtc.addListener(RTCEvents.TRACK_ATTACHED,
1309
-            function(track, container) {
1310
-                var ssrc = track.getSSRC();
1311
-                if (!container.id || !ssrc) {
1312
-                    return;
1313
-                }
1314
-                conference.statistics.associateStreamWithVideoTag(
1315
-                    ssrc, track.isLocal(), track.getUsageLabel(), container.id);
1316
-
1317
-            });
1318
-
1319
         conference.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED,
1416
         conference.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED,
1320
             function (track) {
1417
             function (track) {
1321
                 if(!track.isLocal())
1418
                 if(!track.isLocal())

+ 20
- 28
modules/RTC/JitsiLocalTrack.js Переглянути файл

38
     this.deviceId = deviceId;
38
     this.deviceId = deviceId;
39
     this.startMuted = false;
39
     this.startMuted = false;
40
     this.disposed = false;
40
     this.disposed = false;
41
-    //FIXME: This dependacy is not necessary.
42
-    this.conference = null;
43
     this.initialMSID = this.getMSID();
41
     this.initialMSID = this.getMSID();
44
     this.inMuteOrUnmuteProgress = false;
42
     this.inMuteOrUnmuteProgress = false;
45
 
43
 
170
         resolve();
168
         resolve();
171
         return;
169
         return;
172
     }
170
     }
173
-    if(!this.rtc) {
171
+    if(!this.conference) {
174
         this.startMuted = mute;
172
         this.startMuted = mute;
175
         resolve();
173
         resolve();
176
         return;
174
         return;
197
         if (this.track)
195
         if (this.track)
198
             this.track.enabled = !mute;
196
             this.track.enabled = !mute;
199
         if(isAudio)
197
         if(isAudio)
200
-            this.rtc.room.setAudioMute(mute, callbackFunction);
198
+            this.conference.room.setAudioMute(mute, callbackFunction);
201
         else
199
         else
202
-            this.rtc.room.setVideoMute(mute, callbackFunction);
200
+            this.conference.room.setVideoMute(mute, callbackFunction);
203
     } else {
201
     } else {
204
         if (mute) {
202
         if (mute) {
205
             this.dontFireRemoveEvent = true;
203
             this.dontFireRemoveEvent = true;
206
-            this.rtc.room.removeStream(this.stream, function () {
204
+            this.conference.room.removeStream(this.stream, function () {
207
                     RTCUtils.stopMediaStream(this.stream);
205
                     RTCUtils.stopMediaStream(this.stream);
208
                     setStreamToNull = true;
206
                     setStreamToNull = true;
209
                     if(isAudio)
207
                     if(isAudio)
210
-                        this.rtc.room.setAudioMute(mute, callbackFunction);
208
+                        this.conference.room.setAudioMute(mute,
209
+                            callbackFunction);
211
                     else
210
                     else
212
-                        this.rtc.room.setVideoMute(mute, callbackFunction);
211
+                        this.conference.room.setVideoMute(mute,
212
+                            callbackFunction);
213
                     //FIXME: Maybe here we should set the SRC for the containers to something
213
                     //FIXME: Maybe here we should set the SRC for the containers to something
214
                 }.bind(this),
214
                 }.bind(this),
215
                 function (error) {
215
                 function (error) {
262
                                     self.containers[i], self.stream);
262
                                     self.containers[i], self.stream);
263
                     }
263
                     }
264
 
264
 
265
-                    self.rtc.room.addStream(self.stream,
265
+                    self.conference.room.addStream(self.stream,
266
                         function () {
266
                         function () {
267
                             if(isAudio)
267
                             if(isAudio)
268
-                                self.rtc.room.setAudioMute(
268
+                                self.conference.room.setAudioMute(
269
                                     mute, callbackFunction);
269
                                     mute, callbackFunction);
270
                             else
270
                             else
271
-                                self.rtc.room.setVideoMute(
271
+                                self.conference.room.setVideoMute(
272
                                     mute, callbackFunction);
272
                                     mute, callbackFunction);
273
                         }, function (error) {
273
                         }, function (error) {
274
                             reject(error);
274
                             reject(error);
331
     }
331
     }
332
 };
332
 };
333
 
333
 
334
-/**
335
- * Private method. Updates rtc property of the track.
336
- * @param rtc the rtc instance.
337
- */
338
-JitsiLocalTrack.prototype._setRTC = function (rtc) {
339
-    this.rtc = rtc;
340
-    // We want to keep up with postponed events which should have been fired
341
-    // on "attach" call, but for local track we not always have the conference
342
-    // before attaching. However this may result in duplicated events if they
343
-    // have been triggered on "attach" already.
344
-    for(var i = 0; i < this.containers.length; i++)
345
-    {
346
-        this._maybeFireTrackAttached(this.containers[i]);
347
-    }
348
-};
349
-
350
 /**
334
 /**
351
  * Updates the SSRC associated with the MediaStream in JitsiLocalTrack object.
335
  * Updates the SSRC associated with the MediaStream in JitsiLocalTrack object.
352
  * @ssrc the new ssrc
336
  * @ssrc the new ssrc
356
 };
340
 };
357
 
341
 
358
 
342
 
359
-//FIXME: This dependacy is not necessary. This is quick fix.
360
 /**
343
 /**
361
  * Sets the JitsiConference object associated with the track. This is temp
344
  * Sets the JitsiConference object associated with the track. This is temp
362
  * solution.
345
  * solution.
364
  */
347
  */
365
 JitsiLocalTrack.prototype._setConference = function(conference) {
348
 JitsiLocalTrack.prototype._setConference = function(conference) {
366
     this.conference = conference;
349
     this.conference = conference;
350
+
351
+    // We want to keep up with postponed events which should have been fired
352
+    // on "attach" call, but for local track we not always have the conference
353
+    // before attaching. However this may result in duplicated events if they
354
+    // have been triggered on "attach" already.
355
+    for(var i = 0; i < this.containers.length; i++)
356
+    {
357
+        this._maybeFireTrackAttached(this.containers[i]);
358
+    }
367
 };
359
 };
368
 
360
 
369
 /**
361
 /**

+ 3
- 3
modules/RTC/JitsiRemoteTrack.js Переглянути файл

13
  * @param muted intial muted state of the JitsiRemoteTrack
13
  * @param muted intial muted state of the JitsiRemoteTrack
14
  * @constructor
14
  * @constructor
15
  */
15
  */
16
-function JitsiRemoteTrack(RTC, ownerJid, stream, track, mediaType, videoType,
16
+function JitsiRemoteTrack(conference, ownerJid, stream, track, mediaType, videoType,
17
                           ssrc, muted) {
17
                           ssrc, muted) {
18
     JitsiTrack.call(
18
     JitsiTrack.call(
19
-        this, RTC, stream, track, function () {}, mediaType, videoType, ssrc);
20
-    this.rtc = RTC;
19
+        this, conference, stream, track, function () {}, mediaType, videoType, ssrc);
20
+    this.conference = conference;
21
     this.peerjid = ownerJid;
21
     this.peerjid = ownerJid;
22
     this.muted = muted;
22
     this.muted = muted;
23
 }
23
 }

+ 4
- 4
modules/RTC/JitsiTrack.js Переглянути файл

54
  * @param videoType the VideoType for this track if any
54
  * @param videoType the VideoType for this track if any
55
  * @param ssrc the SSRC of this track if known
55
  * @param ssrc the SSRC of this track if known
56
  */
56
  */
57
-function JitsiTrack(rtc, stream, track, streamInactiveHandler, trackMediaType,
57
+function JitsiTrack(conference, stream, track, streamInactiveHandler, trackMediaType,
58
                     videoType, ssrc)
58
                     videoType, ssrc)
59
 {
59
 {
60
     /**
60
     /**
62
      * @type {Array}
62
      * @type {Array}
63
      */
63
      */
64
     this.containers = [];
64
     this.containers = [];
65
-    this.rtc = rtc;
65
+    this.conference = conference;
66
     this.stream = stream;
66
     this.stream = stream;
67
     this.ssrc = ssrc;
67
     this.ssrc = ssrc;
68
     this.eventEmitter = new EventEmitter();
68
     this.eventEmitter = new EventEmitter();
151
  * @private
151
  * @private
152
  */
152
  */
153
 JitsiTrack.prototype._maybeFireTrackAttached = function (container) {
153
 JitsiTrack.prototype._maybeFireTrackAttached = function (container) {
154
-    if (this.rtc && container) {
155
-        this.rtc.eventEmitter.emit(RTCEvents.TRACK_ATTACHED, this, container);
154
+    if (this.conference && container) {
155
+        this.conference._onTrackAttach(this, container);
156
     }
156
     }
157
 };
157
 };
158
 
158
 

+ 47
- 68
modules/RTC/RTC.js Переглянути файл

32
     return newTracks;
32
     return newTracks;
33
 }
33
 }
34
 
34
 
35
-function RTC(room, options) {
36
-    this.room = room;
35
+function RTC(conference, options) {
36
+    this.conference = conference;
37
     this.localTracks = [];
37
     this.localTracks = [];
38
     //FIXME: We should support multiple streams per jid.
38
     //FIXME: We should support multiple streams per jid.
39
     this.remoteTracks = {};
39
     this.remoteTracks = {};
42
     this.eventEmitter = new EventEmitter();
42
     this.eventEmitter = new EventEmitter();
43
     var self = this;
43
     var self = this;
44
     this.options = options || {};
44
     this.options = options || {};
45
-    room.addPresenceListener("videomuted", function (values, from) {
46
-        var videoTrack = self.getRemoteVideoTrack(from);
47
-        if (videoTrack) {
48
-            videoTrack.setMute(values.value == "true");
49
-        }
50
-    });
51
-    room.addPresenceListener("audiomuted", function (values, from) {
52
-        var audioTrack = self.getRemoteAudioTrack(from);
53
-        if (audioTrack) {
54
-            audioTrack.setMute(values.value == "true");
55
-        }
56
-    });
57
-    room.addPresenceListener("videoType", function(data, from) {
58
-        var videoTrack = self.getRemoteVideoTrack(from);
59
-        if (videoTrack) {
60
-            videoTrack._setVideoType(data.value);
61
-        }
62
-    });
63
 
45
 
64
     // Switch audio output device on all remote audio tracks. Local audio tracks
46
     // Switch audio output device on all remote audio tracks. Local audio tracks
65
     // handle this event by themselves.
47
     // handle this event by themselves.
102
     if(this.options.config.openSctp)
84
     if(this.options.config.openSctp)
103
         this.dataChannels = new DataChannels(event.peerconnection,
85
         this.dataChannels = new DataChannels(event.peerconnection,
104
             this.eventEmitter);
86
             this.eventEmitter);
105
-    // Add local Tracks to the ChatRoom
106
-    this.localTracks.forEach(function(localTrack) {
107
-        var ssrcInfo = null;
108
-        if(localTrack.isVideoTrack() && localTrack.isMuted()) {
109
-            /**
110
-             * Handles issues when the stream is added before the peerconnection
111
-             * is created. The peerconnection is created when second participant
112
-             * enters the call. In that use case the track doesn't have
113
-             * information about it's ssrcs and no jingle packets are sent. That
114
-             * can cause inconsistent behavior later.
115
-             *
116
-             * For example:
117
-             * If we mute the stream and than second participant enter it's
118
-             * remote SDP won't include that track. On unmute we are not sending
119
-             * any jingle packets which will brake the unmute.
120
-             *
121
-             * In order to solve issues like the above one here we have to
122
-             * generate the ssrc information for the track .
123
-             */
124
-            localTrack._setSSRC(
125
-                this.room.generateNewStreamSSRCInfo());
126
-            ssrcInfo = {
127
-                mtype: localTrack.getType(),
128
-                type: "addMuted",
129
-                ssrc: localTrack.ssrc,
130
-                msid: localTrack.initialMSID
131
-            };
132
-        }
133
-        try {
134
-            this.room.addStream(
135
-                localTrack.getOriginalStream(), function () {}, function () {},
136
-                ssrcInfo, true);
137
-        } catch(e) {
138
-            GlobalOnErrorHandler.callErrorHandler(e);
139
-            logger.error(e);
140
-        }
141
-    }.bind(this));
142
 };
87
 };
143
 
88
 
144
 RTC.prototype.selectedEndpoint = function (id) {
89
 RTC.prototype.selectedEndpoint = function (id) {
185
         throw new Error('track must not be null nor undefined');
130
         throw new Error('track must not be null nor undefined');
186
 
131
 
187
     this.localTracks.push(track);
132
     this.localTracks.push(track);
188
-    track._setRTC(this);
133
+
134
+    track.conference = this.conference;
189
 
135
 
190
     if (track.isAudioTrack()) {
136
     if (track.isAudioTrack()) {
191
         this.localAudio = track;
137
         this.localAudio = track;
203
 };
149
 };
204
 
150
 
205
 /**
151
 /**
206
- * Gets JitsiRemoteTrack for AUDIO MediaType associated with given MUC nickname
207
- * (resource part of the JID).
152
+ * Gets JitsiRemoteTrack for the passed MediaType associated with given MUC
153
+ * nickname (resource part of the JID).
154
+ * @param type audio or video.
208
  * @param resource the resource part of the MUC JID
155
  * @param resource the resource part of the MUC JID
209
  * @returns {JitsiRemoteTrack|null}
156
  * @returns {JitsiRemoteTrack|null}
210
  */
157
  */
211
-RTC.prototype.getRemoteAudioTrack = function (resource) {
158
+RTC.prototype.getRemoteTrackByType = function (type, resource) {
212
     if (this.remoteTracks[resource])
159
     if (this.remoteTracks[resource])
213
-        return this.remoteTracks[resource][MediaType.AUDIO];
160
+        return this.remoteTracks[resource][type];
214
     else
161
     else
215
         return null;
162
         return null;
216
 };
163
 };
217
 
164
 
165
+/**
166
+ * Gets JitsiRemoteTrack for AUDIO MediaType associated with given MUC nickname
167
+ * (resource part of the JID).
168
+ * @param resource the resource part of the MUC JID
169
+ * @returns {JitsiRemoteTrack|null}
170
+ */
171
+RTC.prototype.getRemoteAudioTrack = function (resource) {
172
+    return this.getRemoteTrackByType(MediaType.AUDIO, resource);
173
+};
174
+
218
 /**
175
 /**
219
  * Gets JitsiRemoteTrack for VIDEO MediaType associated with given MUC nickname
176
  * Gets JitsiRemoteTrack for VIDEO MediaType associated with given MUC nickname
220
  * (resource part of the JID).
177
  * (resource part of the JID).
222
  * @returns {JitsiRemoteTrack|null}
179
  * @returns {JitsiRemoteTrack|null}
223
  */
180
  */
224
 RTC.prototype.getRemoteVideoTrack = function (resource) {
181
 RTC.prototype.getRemoteVideoTrack = function (resource) {
225
-    if (this.remoteTracks[resource])
226
-        return this.remoteTracks[resource][MediaType.VIDEO];
227
-    else
228
-        return null;
182
+    return this.getRemoteTrackByType(MediaType.VIDEO, resource);
229
 };
183
 };
230
 
184
 
231
 /**
185
 /**
272
 RTC.prototype.createRemoteTrack = function (event) {
226
 RTC.prototype.createRemoteTrack = function (event) {
273
     var ownerJid = event.owner;
227
     var ownerJid = event.owner;
274
     var remoteTrack = new JitsiRemoteTrack(
228
     var remoteTrack = new JitsiRemoteTrack(
275
-        this,  ownerJid, event.stream,    event.track,
229
+        this.conference,  ownerJid, event.stream,    event.track,
276
         event.mediaType, event.videoType, event.ssrc, event.muted);
230
         event.mediaType, event.videoType, event.ssrc, event.muted);
277
     var resource = Strophe.getResourceFromJid(ownerJid);
231
     var resource = Strophe.getResourceFromJid(ownerJid);
278
     var remoteTracks
232
     var remoteTracks
444
 RTC.prototype.getResourceBySSRC = function (ssrc) {
398
 RTC.prototype.getResourceBySSRC = function (ssrc) {
445
     if((this.localVideo && ssrc == this.localVideo.getSSRC())
399
     if((this.localVideo && ssrc == this.localVideo.getSSRC())
446
         || (this.localAudio && ssrc == this.localAudio.getSSRC())) {
400
         || (this.localAudio && ssrc == this.localAudio.getSSRC())) {
447
-        return Strophe.getResourceFromJid(this.room.myroomjid);
401
+        return this.conference.myUserId();
448
     }
402
     }
449
 
403
 
450
     var self = this;
404
     var self = this;
462
     return resultResource;
416
     return resultResource;
463
 };
417
 };
464
 
418
 
419
+/**
420
+ * Handles remote track mute / unmute events.
421
+ * @param type {string} "audio" or "video"
422
+ * @param isMuted {boolean} the new mute state
423
+ * @param from {string} user id
424
+ */
425
+RTC.prototype.handleRemoteTrackMute = function (type, isMuted, from) {
426
+    var track = this.getRemoteTrackByType(type, from);
427
+    if (track) {
428
+        track.setMute(isMuted);
429
+    }
430
+}
431
+
432
+/**
433
+ * Handles remote track video type events
434
+ * @param value {string} the new video type
435
+ * @param from {string} user id
436
+ */
437
+RTC.prototype.handleRemoteTrackVideoTypeChanged = function (value, from) {
438
+    var videoTrack = this.getRemoteVideoTrack(from);
439
+    if (videoTrack) {
440
+        videoTrack._setVideoType(value);
441
+    }
442
+}
443
+
465
 module.exports = RTC;
444
 module.exports = RTC;

Завантаження…
Відмінити
Зберегти