浏览代码

Merge branch 'multiple-tracks'

j8
paweldomas 10 年前
父节点
当前提交
cfcf6fbc67

+ 8
- 3
modules/RTC/LocalStream.js 查看文件

@@ -1,7 +1,8 @@
1 1
 /* global APP */
2
-var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
2
+var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
3 3
 var RTCEvents = require("../../service/RTC/RTCEvents");
4 4
 var RTCBrowserType = require("./RTCBrowserType");
5
+var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
5 6
 
6 7
 /**
7 8
  * This implements 'onended' callback normally fired by WebRTC after the stream
@@ -29,7 +30,7 @@ function LocalStream(stream, type, eventEmitter, videoType, isGUMStream) {
29 30
     if(isGUMStream === false)
30 31
         this.isGUMStream = isGUMStream;
31 32
     var self = this;
32
-    if(type == "audio") {
33
+    if (MediaStreamType.AUDIO_TYPE === type) {
33 34
         this.getTracks = function () {
34 35
             return self.stream.getAudioTracks();
35 36
         };
@@ -60,7 +61,11 @@ LocalStream.prototype.getOriginalStream = function()
60 61
 };
61 62
 
62 63
 LocalStream.prototype.isAudioStream = function () {
63
-    return this.type === "audio";
64
+    return MediaStreamType.AUDIO_TYPE === this.type;
65
+};
66
+
67
+LocalStream.prototype.isVideoStream = function () {
68
+    return MediaStreamType.VIDEO_TYPE === this.type;
64 69
 };
65 70
 
66 71
 LocalStream.prototype.setMute = function (mute)

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

@@ -11,7 +11,7 @@ var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
11 11
  *
12 12
  * @constructor
13 13
  */
14
-function MediaStream(data, ssrc, browser, eventEmitter, muted) {
14
+function MediaStream(data, ssrc, browser, eventEmitter, muted, type) {
15 15
 
16 16
     // XXX(gp) to minimize headaches in the future, we should build our
17 17
     // abstractions around tracks and not streams. ORTC is track based API.
@@ -23,18 +23,29 @@ function MediaStream(data, ssrc, browser, eventEmitter, muted) {
23 23
     // Also, we should be able to associate multiple SSRCs with a MediaTrack as
24 24
     // a track might have an associated RTX and FEC sources.
25 25
 
26
+    if (!type) {
27
+        console.log("Errrm...some code needs an update...");
28
+    }
29
+
26 30
     this.stream = data.stream;
27 31
     this.peerjid = data.peerjid;
28 32
     this.videoType = data.videoType;
29 33
     this.ssrc = ssrc;
30
-    this.type = (this.stream.getVideoTracks().length > 0)?
31
-        MediaStreamType.VIDEO_TYPE : MediaStreamType.AUDIO_TYPE;
34
+    this.type = type;
32 35
     this.muted = muted;
33 36
     this.eventEmitter = eventEmitter;
34 37
 }
35 38
 
39
+// FIXME duplicated with LocalStream methods - extract base class
40
+MediaStream.prototype.isAudioStream = function () {
41
+    return MediaStreamType.AUDIO_TYPE === this.type;
42
+};
43
+
44
+MediaStream.prototype.isVideoStream = function () {
45
+    return MediaStreamType.VIDEO_TYPE === this.type;
46
+};
36 47
 
37
-MediaStream.prototype.getOriginalStream = function() {
48
+MediaStream.prototype.getOriginalStream = function () {
38 49
     return this.stream;
39 50
 };
40 51
 

+ 24
- 11
modules/RTC/RTC.js 查看文件

@@ -76,7 +76,7 @@ var RTC = {
76 76
         if(isMuted === true)
77 77
             localStream.setMute(true);
78 78
 
79
-        if(type == "audio") {
79
+        if (MediaStreamType.AUDIO_TYPE === type) {
80 80
             this.localAudio = localStream;
81 81
         } else {
82 82
             this.localVideo = localStream;
@@ -98,16 +98,27 @@ var RTC = {
98 98
             muted = pres.videoMuted;
99 99
         }
100 100
 
101
-        var remoteStream = new MediaStream(data, ssrc,
102
-            RTCBrowserType.getBrowserType(), eventEmitter, muted);
101
+        var self = this;
102
+        [MediaStreamType.AUDIO_TYPE, MediaStreamType.VIDEO_TYPE].forEach(
103
+            function (type) {
104
+            var tracks =
105
+                type == MediaStreamType.AUDIO_TYPE
106
+                ? data.stream.getAudioTracks() : data.stream.getVideoTracks();
107
+            if (!tracks || !Array.isArray(tracks) || !tracks.length) {
108
+                console.log("Not creating a(n) " + type + " stream: no tracks");
109
+                return;
110
+            }
103 111
 
104
-        if(!this.remoteStreams[jid]) {
105
-            this.remoteStreams[jid] = {};
106
-        }
107
-        this.remoteStreams[jid][remoteStream.type]= remoteStream;
108
-        eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED,
109
-                          remoteStream);
110
-        return remoteStream;
112
+            var remoteStream = new MediaStream(data, ssrc,
113
+                RTCBrowserType.getBrowserType(), eventEmitter, muted, type);
114
+
115
+            if (!self.remoteStreams[jid]) {
116
+                self.remoteStreams[jid] = {};
117
+            }
118
+            self.remoteStreams[jid][type] = remoteStream;
119
+            eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED,
120
+                remoteStream);
121
+        });
111 122
     },
112 123
     getPCConstraints: function () {
113 124
         return this.rtcUtils.pc_constraints;
@@ -218,7 +229,9 @@ var RTC = {
218 229
     changeLocalAudio: function (stream, callback) {
219 230
         var oldStream = this.localAudio.getOriginalStream();
220 231
         var newStream = this.rtcUtils.createStream(stream);
221
-        this.localAudio = this.createLocalStream(newStream, "audio", true);
232
+        this.localAudio
233
+            = this.createLocalStream(
234
+                    newStream, MediaStreamType.AUDIO_TYPE, true);
222 235
         // Stop the stream
223 236
         this.stopMediaStream(oldStream);
224 237
         APP.xmpp.switchStreams(newStream, oldStream, callback, true);

+ 5
- 2
modules/RTC/RTCUtils.js 查看文件

@@ -2,6 +2,7 @@
2 2
     RTCPeerConnection, webkitMediaStream, webkitURL, webkitRTCPeerConnection,
3 3
     mozRTCIceCandidate, mozRTCSessionDescription, mozRTCPeerConnection */
4 4
 /* jshint -W101 */
5
+var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
5 6
 var RTCBrowserType = require("./RTCBrowserType");
6 7
 var Resolutions = require("../../service/RTC/Resolutions");
7 8
 var AdapterJS = require("./adapter.screenshare");
@@ -523,10 +524,12 @@ RTCUtils.prototype.handleLocalStream = function(stream, usageOptions) {
523 524
         videoGUM = (!usageOptions || usageOptions.video !== false);
524 525
 
525 526
 
526
-    this.service.createLocalStream(audioStream, "audio", null, null,
527
+    this.service.createLocalStream(
528
+        audioStream, MediaStreamType.AUDIO_TYPE, null, null,
527 529
         audioMuted, audioGUM);
528 530
 
529
-    this.service.createLocalStream(videoStream, "video", null, 'camera',
531
+    this.service.createLocalStream(
532
+        videoStream, MediaStreamType.VIDEO_TYPE, null, 'camera',
530 533
         videoMuted, videoGUM);
531 534
 };
532 535
 

+ 5
- 4
modules/UI/UI.js 查看文件

@@ -26,6 +26,7 @@ var JitsiPopover = require("./util/JitsiPopover");
26 26
 var CQEvents = require("../../service/connectionquality/CQEvents");
27 27
 var DesktopSharingEventTypes
28 28
     = require("../../service/desktopsharing/DesktopSharingEventTypes");
29
+var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
29 30
 var RTCEvents = require("../../service/RTC/RTCEvents");
30 31
 var RTCBrowserType = require("../RTC/RTCBrowserType");
31 32
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
@@ -111,14 +112,14 @@ function setupToolbars() {
111 112
 
112 113
 function streamHandler(stream, isMuted) {
113 114
     switch (stream.type) {
114
-        case "audio":
115
+        case MediaStreamType.AUDIO_TYPE:
115 116
             VideoLayout.changeLocalAudio(stream, isMuted);
116 117
             break;
117
-        case "video":
118
+        case MediaStreamType.VIDEO_TYPE:
118 119
             VideoLayout.changeLocalVideo(stream, isMuted);
119 120
             break;
120
-        case "stream":
121
-            VideoLayout.changeLocalStream(stream, isMuted);
121
+        default:
122
+            console.error("Unknown stream type: " + stream.type);
122 123
             break;
123 124
     }
124 125
 }

+ 2
- 1
modules/UI/videolayout/LargeVideo.js 查看文件

@@ -302,7 +302,8 @@ function createLargeVideoHTML()
302 302
                 '<canvas id="activeSpeakerAudioLevel"></canvas>' +
303 303
             '</div>' +
304 304
             '<div id="largeVideoWrapper">' +
305
-                '<video id="largeVideo" autoplay oncontextmenu="return false;"></video>' +
305
+                '<video id="largeVideo" muted="true"' +
306
+                        'autoplay oncontextmenu="return false;"></video>' +
306 307
             '</div id="largeVideoWrapper">' +
307 308
             '<span id="videoConnectionMessage"></span>';
308 309
     html += '</div>';

+ 10
- 7
modules/UI/videolayout/RemoteVideo.js 查看文件

@@ -2,6 +2,7 @@
2 2
 var ConnectionIndicator = require("./ConnectionIndicator");
3 3
 var SmallVideo = require("./SmallVideo");
4 4
 var AudioLevels = require("../audio_levels/AudioLevels");
5
+var MediaStreamType = require("../../../service/RTC/MediaStreamTypes");
5 6
 var RTCBrowserType = require("../../RTC/RTCBrowserType");
6 7
 var UIUtils = require("../util/UIUtil");
7 8
 var XMPPEvents = require("../../../service/xmpp/XMPPEvents");
@@ -178,8 +179,9 @@ RemoteVideo.prototype.remove = function () {
178 179
 
179 180
 RemoteVideo.prototype.waitForPlayback = function (sel, stream) {
180 181
 
181
-    var isVideo = stream.getVideoTracks().length > 0;
182
-    if (!isVideo || stream.id === 'mixedmslabel') {
182
+    var webRtcStream = stream.getOriginalStream();
183
+    var isVideo = stream.isVideoStream();
184
+    if (!isVideo || webRtcStream.id === 'mixedmslabel') {
183 185
         return;
184 186
     }
185 187
 
@@ -191,7 +193,7 @@ RemoteVideo.prototype.waitForPlayback = function (sel, stream) {
191 193
     var onPlayingHandler = function () {
192 194
         // FIXME: why do i have to do this for FF?
193 195
         if (RTCBrowserType.isFirefox()) {
194
-            APP.RTC.attachMediaStream(sel, stream);
196
+            APP.RTC.attachMediaStream(sel, webRtcStream);
195 197
         }
196 198
         if (RTCBrowserType.isTemasysPluginUsed()) {
197 199
             sel = self.selectVideoElement();
@@ -212,7 +214,8 @@ RemoteVideo.prototype.addRemoteStreamElement = function (stream) {
212 214
         return;
213 215
 
214 216
     var self = this;
215
-    var isVideo = stream.getVideoTracks().length > 0;
217
+    var webRtcStream = stream.getOriginalStream();
218
+    var isVideo = stream.isVideoStream();
216 219
     var streamElement = SmallVideo.createStreamElement(stream);
217 220
     var newElementId = streamElement.id;
218 221
 
@@ -226,14 +229,14 @@ RemoteVideo.prototype.addRemoteStreamElement = function (stream) {
226 229
     if (!isVideo || (this.container.offsetParent !== null && isVideo)) {
227 230
         this.waitForPlayback(sel, stream);
228 231
 
229
-        APP.RTC.attachMediaStream(sel, stream);
232
+        APP.RTC.attachMediaStream(sel, webRtcStream);
230 233
     }
231 234
 
232 235
     APP.RTC.addMediaStreamInactiveHandler(
233
-        stream, function () {
236
+        webRtcStream, function () {
234 237
             console.log('stream ended', this);
235 238
 
236
-            self.removeRemoteStreamElement(stream, isVideo, newElementId);
239
+            self.removeRemoteStreamElement(webRtcStream, isVideo, newElementId);
237 240
     });
238 241
 
239 242
     // Add click handler.

+ 7
- 3
modules/UI/videolayout/SmallVideo.js 查看文件

@@ -4,6 +4,7 @@ var Avatar = require("../avatar/Avatar");
4 4
 var UIUtil = require("../util/UIUtil");
5 5
 var LargeVideo = require("./LargeVideo");
6 6
 var RTCBrowserType = require("../../RTC/RTCBrowserType");
7
+var MediaStreamType = require("../../../service/RTC/MediaStreamTypes");
7 8
 
8 9
 function SmallVideo() {
9 10
     this.isMuted = false;
@@ -105,19 +106,22 @@ SmallVideo.prototype.setPresenceStatus = function (statusMsg) {
105 106
  * Creates an audio or video element for a particular MediaStream.
106 107
  */
107 108
 SmallVideo.createStreamElement = function (stream) {
108
-    var isVideo = stream.getVideoTracks().length > 0;
109
+    var isVideo = stream.isVideoStream();
109 110
 
110 111
     var element = isVideo ? document.createElement('video')
111 112
         : document.createElement('audio');
113
+    if (isVideo) {
114
+        element.setAttribute("muted", "true");
115
+    }
112 116
 
113 117
     if (!RTCBrowserType.isIExplorer()) {
114 118
         element.autoplay = true;
115 119
     }
116 120
 
117 121
     element.id = (isVideo ? 'remoteVideo_' : 'remoteAudio_') +
118
-        APP.RTC.getStreamID(stream);
122
+        APP.RTC.getStreamID(stream.getOriginalStream());
119 123
 
120
-    element.onplay = function() {
124
+    element.onplay = function () {
121 125
         console.log("(TIME) Render " + (isVideo ? 'video' : 'audio') + ":\t",
122 126
                     window.performance.now());
123 127
     };

+ 1
- 6
modules/UI/videolayout/VideoLayout.js 查看文件

@@ -55,10 +55,6 @@ var VideoLayout = (function (my) {
55 55
                 lastNEndpointsCache.indexOf(resource) !== -1);
56 56
     };
57 57
 
58
-    my.changeLocalStream = function (stream, isMuted) {
59
-        VideoLayout.changeLocalVideo(stream, isMuted);
60
-    };
61
-
62 58
     my.changeLocalAudio = function(stream, isMuted) {
63 59
         if (isMuted)
64 60
             APP.UI.setAudioMuted(true, true);
@@ -187,8 +183,7 @@ var VideoLayout = (function (my) {
187 183
             VideoLayout.ensurePeerContainerExists(stream.peerjid);
188 184
 
189 185
             var resourceJid = Strophe.getResourceFromJid(stream.peerjid);
190
-            remoteVideos[resourceJid].addRemoteStreamElement(
191
-                stream.getOriginalStream());
186
+            remoteVideos[resourceJid].addRemoteStreamElement(stream);
192 187
         }
193 188
     };
194 189
 

+ 0
- 1
modules/xmpp/JingleSessionPC.js 查看文件

@@ -562,7 +562,6 @@ JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) {
562 562
     if (config.webrtcIceUdpDisable) {
563 563
         this.remoteSDP.removeUdpCandidates = true;
564 564
     }
565
-
566 565
     this.remoteSDP.fromJingle(elem);
567 566
     this.readSsrcInfo($(elem).find(">content"));
568 567
     if (this.peerconnection.remoteDescription !== null) {

+ 3
- 1
modules/xmpp/strophe.jingle.js 查看文件

@@ -96,7 +96,7 @@ module.exports = function(XMPP, eventEmitter) {
96 96
             switch (action) {
97 97
                 case 'session-initiate':
98 98
                     console.log("(TIME) received session-initiate:\t",
99
-                                window.performance.now());
99
+                                window.performance.now(), iq);
100 100
                     var startMuted = $(iq).find('jingle>startmuted');
101 101
                     if (startMuted && startMuted.length > 0) {
102 102
                         var audioMuted = startMuted.attr("audio");
@@ -176,10 +176,12 @@ module.exports = function(XMPP, eventEmitter) {
176 176
                     break;
177 177
                 case 'addsource': // FIXME: proprietary, un-jingleish
178 178
                 case 'source-add': // FIXME: proprietary
179
+                    console.info("source-add", iq);
179 180
                     sess.addSource($(iq).find('>jingle>content'));
180 181
                     break;
181 182
                 case 'removesource': // FIXME: proprietary, un-jingleish
182 183
                 case 'source-remove': // FIXME: proprietary
184
+                    console.info("source-remove", iq);
183 185
                     sess.removeSource($(iq).find('>jingle>content'));
184 186
                     break;
185 187
                 default:

+ 2
- 2
service/RTC/MediaStreamTypes.js 查看文件

@@ -1,6 +1,6 @@
1 1
 var MediaStreamType = {
2
-    VIDEO_TYPE: "Video",
2
+    VIDEO_TYPE: "video",
3 3
 
4
-    AUDIO_TYPE: "Audio"
4
+    AUDIO_TYPE: "audio"
5 5
 };
6 6
 module.exports = MediaStreamType;

正在加载...
取消
保存