瀏覽代碼

Adjustments to make lip-sync work. Stream merging is now done by Jicofo.

j8
paweldomas 10 年之前
父節點
當前提交
27fc4636b7

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

1
 /* global APP */
1
 /* global APP */
2
-var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
2
+var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
3
 var RTCEvents = require("../../service/RTC/RTCEvents");
3
 var RTCEvents = require("../../service/RTC/RTCEvents");
4
 var RTCBrowserType = require("./RTCBrowserType");
4
 var RTCBrowserType = require("./RTCBrowserType");
5
+var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
5
 
6
 
6
 /**
7
 /**
7
  * This implements 'onended' callback normally fired by WebRTC after the stream
8
  * This implements 'onended' callback normally fired by WebRTC after the stream
29
     if(isGUMStream === false)
30
     if(isGUMStream === false)
30
         this.isGUMStream = isGUMStream;
31
         this.isGUMStream = isGUMStream;
31
     var self = this;
32
     var self = this;
32
-    if(type == "audio") {
33
+    if (MediaStreamType.AUDIO_TYPE === type) {
33
         this.getTracks = function () {
34
         this.getTracks = function () {
34
             return self.stream.getAudioTracks();
35
             return self.stream.getAudioTracks();
35
         };
36
         };
60
 };
61
 };
61
 
62
 
62
 LocalStream.prototype.isAudioStream = function () {
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
 LocalStream.prototype.setMute = function (mute)
71
 LocalStream.prototype.setMute = function (mute)

+ 9
- 1
modules/RTC/MediaStream.js 查看文件

36
     this.eventEmitter = eventEmitter;
36
     this.eventEmitter = eventEmitter;
37
 }
37
 }
38
 
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
+};
39
 
47
 
40
-MediaStream.prototype.getOriginalStream = function() {
48
+MediaStream.prototype.getOriginalStream = function () {
41
     return this.stream;
49
     return this.stream;
42
 };
50
 };
43
 
51
 

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

76
         if(isMuted === true)
76
         if(isMuted === true)
77
             localStream.setMute(true);
77
             localStream.setMute(true);
78
 
78
 
79
-        if(type == "audio") {
79
+        if (MediaStreamType.AUDIO_TYPE === type) {
80
             this.localAudio = localStream;
80
             this.localAudio = localStream;
81
         } else {
81
         } else {
82
             this.localVideo = localStream;
82
             this.localVideo = localStream;
100
 
100
 
101
         var self = this;
101
         var self = this;
102
         [MediaStreamType.AUDIO_TYPE, MediaStreamType.VIDEO_TYPE].forEach(
102
         [MediaStreamType.AUDIO_TYPE, MediaStreamType.VIDEO_TYPE].forEach(
103
-            function(type) {
103
+            function (type) {
104
             var tracks =
104
             var tracks =
105
                 type == MediaStreamType.AUDIO_TYPE
105
                 type == MediaStreamType.AUDIO_TYPE
106
-                ? data.stream.getAudioTracks : data.stream.getVideoTracks();
106
+                ? data.stream.getAudioTracks() : data.stream.getVideoTracks();
107
             if (!tracks || !Array.isArray(tracks) || !tracks.length) {
107
             if (!tracks || !Array.isArray(tracks) || !tracks.length) {
108
-                console.log("Not creating a(n) "+type+" stream: no tracks");
108
+                console.log("Not creating a(n) " + type + " stream: no tracks");
109
                 return;
109
                 return;
110
             }
110
             }
111
 
111
 
229
     changeLocalAudio: function (stream, callback) {
229
     changeLocalAudio: function (stream, callback) {
230
         var oldStream = this.localAudio.getOriginalStream();
230
         var oldStream = this.localAudio.getOriginalStream();
231
         var newStream = this.rtcUtils.createStream(stream);
231
         var newStream = this.rtcUtils.createStream(stream);
232
-        this.localAudio = this.createLocalStream(newStream, "audio", true);
232
+        this.localAudio
233
+            = this.createLocalStream(
234
+                    newStream, MediaStreamType.AUDIO_TYPE, true);
233
         // Stop the stream
235
         // Stop the stream
234
         this.stopMediaStream(oldStream);
236
         this.stopMediaStream(oldStream);
235
         APP.xmpp.switchStreams(newStream, oldStream, callback, true);
237
         APP.xmpp.switchStreams(newStream, oldStream, callback, true);

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

2
     RTCPeerConnection, webkitMediaStream, webkitURL, webkitRTCPeerConnection,
2
     RTCPeerConnection, webkitMediaStream, webkitURL, webkitRTCPeerConnection,
3
     mozRTCIceCandidate, mozRTCSessionDescription, mozRTCPeerConnection */
3
     mozRTCIceCandidate, mozRTCSessionDescription, mozRTCPeerConnection */
4
 /* jshint -W101 */
4
 /* jshint -W101 */
5
+var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
5
 var RTCBrowserType = require("./RTCBrowserType");
6
 var RTCBrowserType = require("./RTCBrowserType");
6
 var Resolutions = require("../../service/RTC/Resolutions");
7
 var Resolutions = require("../../service/RTC/Resolutions");
7
 var AdapterJS = require("./adapter.screenshare");
8
 var AdapterJS = require("./adapter.screenshare");
523
         videoGUM = (!usageOptions || usageOptions.video !== false);
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
         audioMuted, audioGUM);
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
         videoMuted, videoGUM);
533
         videoMuted, videoGUM);
531
 };
534
 };
532
 
535
 

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

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

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

302
                 '<canvas id="activeSpeakerAudioLevel"></canvas>' +
302
                 '<canvas id="activeSpeakerAudioLevel"></canvas>' +
303
             '</div>' +
303
             '</div>' +
304
             '<div id="largeVideoWrapper">' +
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
             '</div id="largeVideoWrapper">' +
307
             '</div id="largeVideoWrapper">' +
307
             '<span id="videoConnectionMessage"></span>';
308
             '<span id="videoConnectionMessage"></span>';
308
     html += '</div>';
309
     html += '</div>';

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

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

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

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

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

55
                 lastNEndpointsCache.indexOf(resource) !== -1);
55
                 lastNEndpointsCache.indexOf(resource) !== -1);
56
     };
56
     };
57
 
57
 
58
-    my.changeLocalStream = function (stream, isMuted) {
59
-        VideoLayout.changeLocalVideo(stream, isMuted);
60
-    };
61
-
62
     my.changeLocalAudio = function(stream, isMuted) {
58
     my.changeLocalAudio = function(stream, isMuted) {
63
         if (isMuted)
59
         if (isMuted)
64
             APP.UI.setAudioMuted(true, true);
60
             APP.UI.setAudioMuted(true, true);
187
             VideoLayout.ensurePeerContainerExists(stream.peerjid);
183
             VideoLayout.ensurePeerContainerExists(stream.peerjid);
188
 
184
 
189
             var resourceJid = Strophe.getResourceFromJid(stream.peerjid);
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
- 52
modules/xmpp/JingleSessionPC.js 查看文件

554
     return this.ssrcOwners[ssrc];
554
     return this.ssrcOwners[ssrc];
555
 };
555
 };
556
 
556
 
557
-function copyParamAttr(dstElem, srcElem, name) {
558
-    var srcSelector = $(srcElem).find('parameter[name="' + name + '"]');
559
-    var dstSelector = $(dstElem).find('parameter[name="' + name + '"]');
560
-    if (srcSelector.length && dstSelector.length) {
561
-        dstSelector[0].setAttribute('value', srcSelector[0].getAttribute('value'));
562
-    } else {
563
-        console.error("did not copy " + name + " from|to ", srcElem, dstElem);
564
-    }
565
-}
566
-
567
-JingleSessionPC.prototype.mungeRemoteMsid = function (jingle) {
568
-
569
-    var videoContent = $(jingle).find(">content[name='video']");
570
-    console.info("Video contents", videoContent);
571
-    var audioContent = $(jingle).find(">content[name='audio']");
572
-    console.info("Audio contents", audioContent);
573
-
574
-    var videoSSRCInfos = videoContent.find('description>source>ssrc-info');
575
-    console.info("Video SSRC infos: ", videoSSRCInfos);
576
-    var videoSSRCs = {};
577
-    videoSSRCInfos.each(function (idx, ssrcInfo) {
578
-        var owner = ssrcInfo.getAttribute('owner');
579
-        if (owner !== 'jvb') {
580
-            console.info("Got video SSRC owner: " + owner + " of: ", ssrcInfo.parentNode);
581
-            videoSSRCs[owner] = ssrcInfo.parentNode;
582
-        }
583
-    });
584
-    Object.keys(videoSSRCs).forEach(function (owner) {
585
-        console.info("Looking for audio SSRC owned by: " + owner);
586
-        var audioSSRCInfo = audioContent.find('description>source>ssrc-info[owner="' + owner + '"]');
587
-        if (audioSSRCInfo.length) {
588
-            var audioSSRC = audioSSRCInfo[0].parentNode;
589
-            console.info("Found corresponding audio SSRC: ", audioSSRC);
590
-            var videoSSRC = videoSSRCs[owner];
591
-            console.info("Will copy fields from: ", videoSSRC);
592
-            copyParamAttr(audioSSRC, videoSSRC, 'msid');
593
-            copyParamAttr(audioSSRC, videoSSRC, 'mslabel');
594
-            copyParamAttr(audioSSRC, videoSSRC, 'label');
595
-        }
596
-    });
597
-
598
-    return jingle;
599
-};
600
-
601
 JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) {
557
 JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) {
602
     this.remoteSDP = new SDP('');
558
     this.remoteSDP = new SDP('');
603
     if (config.webrtcIceTcpDisable) {
559
     if (config.webrtcIceTcpDisable) {
606
     if (config.webrtcIceUdpDisable) {
562
     if (config.webrtcIceUdpDisable) {
607
         this.remoteSDP.removeUdpCandidates = true;
563
         this.remoteSDP.removeUdpCandidates = true;
608
     }
564
     }
609
-    elem = this.mungeRemoteMsid(elem);
610
-    console.info("Jingle after munge: ", elem[0]);
611
     this.remoteSDP.fromJingle(elem);
565
     this.remoteSDP.fromJingle(elem);
612
     this.readSsrcInfo($(elem).find(">content"));
566
     this.readSsrcInfo($(elem).find(">content"));
613
     if (this.peerconnection.remoteDescription !== null) {
567
     if (this.peerconnection.remoteDescription !== null) {
924
     console.log('addssrc', new Date().getTime());
878
     console.log('addssrc', new Date().getTime());
925
     console.log('ice', this.peerconnection.iceConnectionState);
879
     console.log('ice', this.peerconnection.iceConnectionState);
926
 
880
 
927
-    elem = this.mungeRemoteMsid(elem);
928
-    console.info("SSRC-ADD Jingle after munge: ", elem[0]);
929
-
930
-    elem = $(elem).find('>content');
931
-    console.info("ELEM: ", elem);
932
-
933
     this.readSsrcInfo(elem);
881
     this.readSsrcInfo(elem);
934
 
882
 
935
     var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
883
     var sdp = new SDP(this.peerconnection.remoteDescription.sdp);

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

177
                 case 'addsource': // FIXME: proprietary, un-jingleish
177
                 case 'addsource': // FIXME: proprietary, un-jingleish
178
                 case 'source-add': // FIXME: proprietary
178
                 case 'source-add': // FIXME: proprietary
179
                     console.info("source-add", iq);
179
                     console.info("source-add", iq);
180
-                    sess.addSource($(iq).find('>jingle'));
180
+                    sess.addSource($(iq).find('>jingle>content'));
181
                     break;
181
                     break;
182
                 case 'removesource': // FIXME: proprietary, un-jingleish
182
                 case 'removesource': // FIXME: proprietary, un-jingleish
183
                 case 'source-remove': // FIXME: proprietary
183
                 case 'source-remove': // FIXME: proprietary

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

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

Loading…
取消
儲存