浏览代码

Resolve xmpp dependacies in RTC module

master
hristoterezov 9 年前
父节点
当前提交
c3f9885df0
共有 5 个文件被更改,包括 229 次插入161 次删除
  1. 155
    58
      JitsiConference.js
  2. 20
    28
      modules/RTC/JitsiLocalTrack.js
  3. 3
    3
      modules/RTC/JitsiRemoteTrack.js
  4. 4
    4
      modules/RTC/JitsiTrack.js
  5. 47
    68
      modules/RTC/RTC.js

+ 155
- 58
JitsiConference.js 查看文件

@@ -17,6 +17,7 @@ var JitsiTrackError = require("./JitsiTrackError");
17 17
 var Settings = require("./modules/settings/Settings");
18 18
 var ComponentsVersions = require("./modules/version/ComponentsVersions");
19 19
 var GlobalOnErrorHandler = require("./modules/util/GlobalOnErrorHandler");
20
+var MediaType = require("./service/RTC/MediaType");
20 21
 
21 22
 /**
22 23
  * Creates a JitsiConference object with the given name and properties.
@@ -35,17 +36,10 @@ function JitsiConference(options) {
35 36
         logger.error(errmsg);
36 37
         throw new Error(errmsg);
37 38
     }
38
-    this.options = options;
39
-    this.connection = this.options.connection;
40
-    this.xmpp = this.connection.xmpp;
41 39
     this.eventEmitter = new EventEmitter();
42
-    var confID = this.options.name  + '@' + this.xmpp.options.hosts.muc;
43 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 43
     this.statistics = new Statistics(this.xmpp, {
50 44
         callStatsID: this.options.config.callStatsID,
51 45
         callStatsSecret: this.options.config.callStatsSecret,
@@ -70,6 +64,45 @@ function JitsiConference(options) {
70 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 107
  * Joins the conference.
75 108
  * @param password {string} the password
@@ -343,6 +376,7 @@ JitsiConference.prototype.addTrack = function (track) {
343 376
                 });
344 377
             }
345 378
             this.rtc.addLocalTrack(track);
379
+
346 380
             if (track.startMuted) {
347 381
                 track.mute();
348 382
             }
@@ -360,7 +394,7 @@ JitsiConference.prototype.addTrack = function (track) {
360 394
                                    track.muteHandler);
361 395
             track.addEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
362 396
                                    track.audioLevelHandler);
363
-            //FIXME: This dependacy is not necessary. This is quick fix.
397
+
364 398
             track._setConference(this);
365 399
 
366 400
             // send event for starting screen sharing
@@ -422,8 +456,7 @@ JitsiConference.prototype.removeTrack = function (track) {
422 456
     return new Promise(function (resolve, reject) {
423 457
         this.room.removeStream(track.getOriginalStream(), function(){
424 458
             track._setSSRC(null);
425
-            //FIXME: This dependacy is not necessary. This is quick fix.
426
-            track._setConference(this);
459
+            track._setConference(null);
427 460
             this.rtc.removeLocalTrack(track);
428 461
             track.removeEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED,
429 462
                 track.muteHandler);
@@ -669,6 +702,84 @@ JitsiConference.prototype.onTrackAdded = function (track) {
669 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 783
 JitsiConference.prototype.updateDTMFSupport = function () {
673 784
     var somebodySupportsDTMF = false;
674 785
     var participants = this.getParticipants();
@@ -915,47 +1026,29 @@ JitsiConference.prototype.isCallstatsEnabled = function () {
915 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 1046
  * Setups the listeners needed for the conference.
920 1047
  * @param conference the conference
921 1048
  */
922 1049
 function setupListeners(conference) {
923 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 1053
     conference.room.addListener(XMPPEvents.ICE_RESTARTING, function () {
961 1054
         // All data channels have to be closed, before ICE restart
@@ -1206,6 +1299,21 @@ function setupListeners(conference) {
1206 1299
     conference.rtc.addListener(RTCEvents.AVAILABLE_DEVICES_CHANGED, function (devices) {
1207 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 1317
     conference.room.addPresenceListener("devices", function (data, from) {
1210 1318
         var isAudioAvailable = false;
1211 1319
         var isVideoAvailable = false;
@@ -1305,17 +1413,6 @@ function setupListeners(conference) {
1305 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 1416
         conference.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED,
1320 1417
             function (track) {
1321 1418
                 if(!track.isLocal())

+ 20
- 28
modules/RTC/JitsiLocalTrack.js 查看文件

@@ -38,8 +38,6 @@ function JitsiLocalTrack(stream, track, mediaType, videoType, resolution,
38 38
     this.deviceId = deviceId;
39 39
     this.startMuted = false;
40 40
     this.disposed = false;
41
-    //FIXME: This dependacy is not necessary.
42
-    this.conference = null;
43 41
     this.initialMSID = this.getMSID();
44 42
     this.inMuteOrUnmuteProgress = false;
45 43
 
@@ -170,7 +168,7 @@ JitsiLocalTrack.prototype._setMute = function (mute, resolve, reject) {
170 168
         resolve();
171 169
         return;
172 170
     }
173
-    if(!this.rtc) {
171
+    if(!this.conference) {
174 172
         this.startMuted = mute;
175 173
         resolve();
176 174
         return;
@@ -197,19 +195,21 @@ JitsiLocalTrack.prototype._setMute = function (mute, resolve, reject) {
197 195
         if (this.track)
198 196
             this.track.enabled = !mute;
199 197
         if(isAudio)
200
-            this.rtc.room.setAudioMute(mute, callbackFunction);
198
+            this.conference.room.setAudioMute(mute, callbackFunction);
201 199
         else
202
-            this.rtc.room.setVideoMute(mute, callbackFunction);
200
+            this.conference.room.setVideoMute(mute, callbackFunction);
203 201
     } else {
204 202
         if (mute) {
205 203
             this.dontFireRemoveEvent = true;
206
-            this.rtc.room.removeStream(this.stream, function () {
204
+            this.conference.room.removeStream(this.stream, function () {
207 205
                     RTCUtils.stopMediaStream(this.stream);
208 206
                     setStreamToNull = true;
209 207
                     if(isAudio)
210
-                        this.rtc.room.setAudioMute(mute, callbackFunction);
208
+                        this.conference.room.setAudioMute(mute,
209
+                            callbackFunction);
211 210
                     else
212
-                        this.rtc.room.setVideoMute(mute, callbackFunction);
211
+                        this.conference.room.setVideoMute(mute,
212
+                            callbackFunction);
213 213
                     //FIXME: Maybe here we should set the SRC for the containers to something
214 214
                 }.bind(this),
215 215
                 function (error) {
@@ -262,13 +262,13 @@ JitsiLocalTrack.prototype._setMute = function (mute, resolve, reject) {
262 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 266
                         function () {
267 267
                             if(isAudio)
268
-                                self.rtc.room.setAudioMute(
268
+                                self.conference.room.setAudioMute(
269 269
                                     mute, callbackFunction);
270 270
                             else
271
-                                self.rtc.room.setVideoMute(
271
+                                self.conference.room.setVideoMute(
272 272
                                     mute, callbackFunction);
273 273
                         }, function (error) {
274 274
                             reject(error);
@@ -331,22 +331,6 @@ JitsiLocalTrack.prototype.isMuted = function () {
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 335
  * Updates the SSRC associated with the MediaStream in JitsiLocalTrack object.
352 336
  * @ssrc the new ssrc
@@ -356,7 +340,6 @@ JitsiLocalTrack.prototype._setSSRC = function (ssrc) {
356 340
 };
357 341
 
358 342
 
359
-//FIXME: This dependacy is not necessary. This is quick fix.
360 343
 /**
361 344
  * Sets the JitsiConference object associated with the track. This is temp
362 345
  * solution.
@@ -364,6 +347,15 @@ JitsiLocalTrack.prototype._setSSRC = function (ssrc) {
364 347
  */
365 348
 JitsiLocalTrack.prototype._setConference = function(conference) {
366 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,11 +13,11 @@ var JitsiTrackEvents = require("../../JitsiTrackEvents");
13 13
  * @param muted intial muted state of the JitsiRemoteTrack
14 14
  * @constructor
15 15
  */
16
-function JitsiRemoteTrack(RTC, ownerJid, stream, track, mediaType, videoType,
16
+function JitsiRemoteTrack(conference, ownerJid, stream, track, mediaType, videoType,
17 17
                           ssrc, muted) {
18 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 21
     this.peerjid = ownerJid;
22 22
     this.muted = muted;
23 23
 }

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

@@ -54,7 +54,7 @@ function addMediaStreamInactiveHandler(mediaStream, handler) {
54 54
  * @param videoType the VideoType for this track if any
55 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 58
                     videoType, ssrc)
59 59
 {
60 60
     /**
@@ -62,7 +62,7 @@ function JitsiTrack(rtc, stream, track, streamInactiveHandler, trackMediaType,
62 62
      * @type {Array}
63 63
      */
64 64
     this.containers = [];
65
-    this.rtc = rtc;
65
+    this.conference = conference;
66 66
     this.stream = stream;
67 67
     this.ssrc = ssrc;
68 68
     this.eventEmitter = new EventEmitter();
@@ -151,8 +151,8 @@ JitsiTrack.prototype.getUsageLabel = function () {
151 151
  * @private
152 152
  */
153 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,8 +32,8 @@ function createLocalTracks(tracksInfo, options) {
32 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 37
     this.localTracks = [];
38 38
     //FIXME: We should support multiple streams per jid.
39 39
     this.remoteTracks = {};
@@ -42,24 +42,6 @@ function RTC(room, options) {
42 42
     this.eventEmitter = new EventEmitter();
43 43
     var self = this;
44 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 46
     // Switch audio output device on all remote audio tracks. Local audio tracks
65 47
     // handle this event by themselves.
@@ -102,43 +84,6 @@ RTC.prototype.onIncommingCall = function(event) {
102 84
     if(this.options.config.openSctp)
103 85
         this.dataChannels = new DataChannels(event.peerconnection,
104 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 89
 RTC.prototype.selectedEndpoint = function (id) {
@@ -185,7 +130,8 @@ RTC.prototype.addLocalTrack = function (track) {
185 130
         throw new Error('track must not be null nor undefined');
186 131
 
187 132
     this.localTracks.push(track);
188
-    track._setRTC(this);
133
+
134
+    track.conference = this.conference;
189 135
 
190 136
     if (track.isAudioTrack()) {
191 137
         this.localAudio = track;
@@ -203,18 +149,29 @@ RTC.prototype.getLocalVideoTrack = function () {
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 155
  * @param resource the resource part of the MUC JID
209 156
  * @returns {JitsiRemoteTrack|null}
210 157
  */
211
-RTC.prototype.getRemoteAudioTrack = function (resource) {
158
+RTC.prototype.getRemoteTrackByType = function (type, resource) {
212 159
     if (this.remoteTracks[resource])
213
-        return this.remoteTracks[resource][MediaType.AUDIO];
160
+        return this.remoteTracks[resource][type];
214 161
     else
215 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 176
  * Gets JitsiRemoteTrack for VIDEO MediaType associated with given MUC nickname
220 177
  * (resource part of the JID).
@@ -222,10 +179,7 @@ RTC.prototype.getRemoteAudioTrack = function (resource) {
222 179
  * @returns {JitsiRemoteTrack|null}
223 180
  */
224 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,7 +226,7 @@ RTC.prototype.removeLocalTrack = function (track) {
272 226
 RTC.prototype.createRemoteTrack = function (event) {
273 227
     var ownerJid = event.owner;
274 228
     var remoteTrack = new JitsiRemoteTrack(
275
-        this,  ownerJid, event.stream,    event.track,
229
+        this.conference,  ownerJid, event.stream,    event.track,
276 230
         event.mediaType, event.videoType, event.ssrc, event.muted);
277 231
     var resource = Strophe.getResourceFromJid(ownerJid);
278 232
     var remoteTracks
@@ -444,7 +398,7 @@ RTC.prototype.setAudioLevel = function (resource, audioLevel) {
444 398
 RTC.prototype.getResourceBySSRC = function (ssrc) {
445 399
     if((this.localVideo && ssrc == this.localVideo.getSSRC())
446 400
         || (this.localAudio && ssrc == this.localAudio.getSSRC())) {
447
-        return Strophe.getResourceFromJid(this.room.myroomjid);
401
+        return this.conference.myUserId();
448 402
     }
449 403
 
450 404
     var self = this;
@@ -462,4 +416,29 @@ RTC.prototype.getResourceBySSRC = function (ssrc) {
462 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 444
 module.exports = RTC;

正在加载...
取消
保存