diff --git a/modules/RTC/LocalStream.js b/modules/RTC/LocalStream.js index bc1a2438b..bf30305f1 100644 --- a/modules/RTC/LocalStream.js +++ b/modules/RTC/LocalStream.js @@ -1,7 +1,8 @@ /* global APP */ -var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js"); +var MediaStreamType = require("../../service/RTC/MediaStreamTypes"); var RTCEvents = require("../../service/RTC/RTCEvents"); var RTCBrowserType = require("./RTCBrowserType"); +var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js"); /** * This implements 'onended' callback normally fired by WebRTC after the stream @@ -29,7 +30,7 @@ function LocalStream(stream, type, eventEmitter, videoType, isGUMStream) { if(isGUMStream === false) this.isGUMStream = isGUMStream; var self = this; - if(type == "audio") { + if (MediaStreamType.AUDIO_TYPE === type) { this.getTracks = function () { return self.stream.getAudioTracks(); }; @@ -60,7 +61,11 @@ LocalStream.prototype.getOriginalStream = function() }; LocalStream.prototype.isAudioStream = function () { - return this.type === "audio"; + return MediaStreamType.AUDIO_TYPE === this.type; +}; + +LocalStream.prototype.isVideoStream = function () { + return MediaStreamType.VIDEO_TYPE === this.type; }; LocalStream.prototype.setMute = function (mute) diff --git a/modules/RTC/MediaStream.js b/modules/RTC/MediaStream.js index c5e3ca7f1..fc500781e 100644 --- a/modules/RTC/MediaStream.js +++ b/modules/RTC/MediaStream.js @@ -11,7 +11,7 @@ var MediaStreamType = require("../../service/RTC/MediaStreamTypes"); * * @constructor */ -function MediaStream(data, ssrc, browser, eventEmitter, muted) { +function MediaStream(data, ssrc, browser, eventEmitter, muted, type) { // XXX(gp) to minimize headaches in the future, we should build our // abstractions around tracks and not streams. ORTC is track based API. @@ -23,18 +23,29 @@ function MediaStream(data, ssrc, browser, eventEmitter, muted) { // Also, we should be able to associate multiple SSRCs with a MediaTrack as // a track might have an associated RTX and FEC sources. + if (!type) { + console.log("Errrm...some code needs an update..."); + } + this.stream = data.stream; this.peerjid = data.peerjid; this.videoType = data.videoType; this.ssrc = ssrc; - this.type = (this.stream.getVideoTracks().length > 0)? - MediaStreamType.VIDEO_TYPE : MediaStreamType.AUDIO_TYPE; + this.type = type; this.muted = muted; this.eventEmitter = eventEmitter; } +// FIXME duplicated with LocalStream methods - extract base class +MediaStream.prototype.isAudioStream = function () { + return MediaStreamType.AUDIO_TYPE === this.type; +}; -MediaStream.prototype.getOriginalStream = function() { +MediaStream.prototype.isVideoStream = function () { + return MediaStreamType.VIDEO_TYPE === this.type; +}; + +MediaStream.prototype.getOriginalStream = function () { return this.stream; }; diff --git a/modules/RTC/RTC.js b/modules/RTC/RTC.js index 59e4e1e34..6274a6ed6 100644 --- a/modules/RTC/RTC.js +++ b/modules/RTC/RTC.js @@ -76,7 +76,7 @@ var RTC = { if(isMuted === true) localStream.setMute(true); - if(type == "audio") { + if (MediaStreamType.AUDIO_TYPE === type) { this.localAudio = localStream; } else { this.localVideo = localStream; @@ -98,16 +98,27 @@ var RTC = { muted = pres.videoMuted; } - var remoteStream = new MediaStream(data, ssrc, - RTCBrowserType.getBrowserType(), eventEmitter, muted); + var self = this; + [MediaStreamType.AUDIO_TYPE, MediaStreamType.VIDEO_TYPE].forEach( + function (type) { + var tracks = + type == MediaStreamType.AUDIO_TYPE + ? data.stream.getAudioTracks() : data.stream.getVideoTracks(); + if (!tracks || !Array.isArray(tracks) || !tracks.length) { + console.log("Not creating a(n) " + type + " stream: no tracks"); + return; + } - if(!this.remoteStreams[jid]) { - this.remoteStreams[jid] = {}; - } - this.remoteStreams[jid][remoteStream.type]= remoteStream; - eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED, - remoteStream); - return remoteStream; + var remoteStream = new MediaStream(data, ssrc, + RTCBrowserType.getBrowserType(), eventEmitter, muted, type); + + if (!self.remoteStreams[jid]) { + self.remoteStreams[jid] = {}; + } + self.remoteStreams[jid][type] = remoteStream; + eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED, + remoteStream); + }); }, getPCConstraints: function () { return this.rtcUtils.pc_constraints; @@ -218,7 +229,9 @@ var RTC = { changeLocalAudio: function (stream, callback) { var oldStream = this.localAudio.getOriginalStream(); var newStream = this.rtcUtils.createStream(stream); - this.localAudio = this.createLocalStream(newStream, "audio", true); + this.localAudio + = this.createLocalStream( + newStream, MediaStreamType.AUDIO_TYPE, true); // Stop the stream this.stopMediaStream(oldStream); APP.xmpp.switchStreams(newStream, oldStream, callback, true); diff --git a/modules/RTC/RTCUtils.js b/modules/RTC/RTCUtils.js index e8448ae7a..d316e3cb3 100644 --- a/modules/RTC/RTCUtils.js +++ b/modules/RTC/RTCUtils.js @@ -2,6 +2,7 @@ RTCPeerConnection, webkitMediaStream, webkitURL, webkitRTCPeerConnection, mozRTCIceCandidate, mozRTCSessionDescription, mozRTCPeerConnection */ /* jshint -W101 */ +var MediaStreamType = require("../../service/RTC/MediaStreamTypes"); var RTCBrowserType = require("./RTCBrowserType"); var Resolutions = require("../../service/RTC/Resolutions"); var AdapterJS = require("./adapter.screenshare"); @@ -523,10 +524,12 @@ RTCUtils.prototype.handleLocalStream = function(stream, usageOptions) { videoGUM = (!usageOptions || usageOptions.video !== false); - this.service.createLocalStream(audioStream, "audio", null, null, + this.service.createLocalStream( + audioStream, MediaStreamType.AUDIO_TYPE, null, null, audioMuted, audioGUM); - this.service.createLocalStream(videoStream, "video", null, 'camera', + this.service.createLocalStream( + videoStream, MediaStreamType.VIDEO_TYPE, null, 'camera', videoMuted, videoGUM); }; diff --git a/modules/UI/UI.js b/modules/UI/UI.js index 62bcd0a17..95e4870eb 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -26,6 +26,7 @@ var JitsiPopover = require("./util/JitsiPopover"); var CQEvents = require("../../service/connectionquality/CQEvents"); var DesktopSharingEventTypes = require("../../service/desktopsharing/DesktopSharingEventTypes"); +var MediaStreamType = require("../../service/RTC/MediaStreamTypes"); var RTCEvents = require("../../service/RTC/RTCEvents"); var RTCBrowserType = require("../RTC/RTCBrowserType"); var StreamEventTypes = require("../../service/RTC/StreamEventTypes"); @@ -111,14 +112,14 @@ function setupToolbars() { function streamHandler(stream, isMuted) { switch (stream.type) { - case "audio": + case MediaStreamType.AUDIO_TYPE: VideoLayout.changeLocalAudio(stream, isMuted); break; - case "video": + case MediaStreamType.VIDEO_TYPE: VideoLayout.changeLocalVideo(stream, isMuted); break; - case "stream": - VideoLayout.changeLocalStream(stream, isMuted); + default: + console.error("Unknown stream type: " + stream.type); break; } } diff --git a/modules/UI/videolayout/LargeVideo.js b/modules/UI/videolayout/LargeVideo.js index f3de0764a..20485c81a 100644 --- a/modules/UI/videolayout/LargeVideo.js +++ b/modules/UI/videolayout/LargeVideo.js @@ -302,7 +302,8 @@ function createLargeVideoHTML() '' + '' + '
' + - '' + + '' + '
' + ''; html += ''; diff --git a/modules/UI/videolayout/RemoteVideo.js b/modules/UI/videolayout/RemoteVideo.js index 5dc5ffaff..4812bc720 100644 --- a/modules/UI/videolayout/RemoteVideo.js +++ b/modules/UI/videolayout/RemoteVideo.js @@ -2,6 +2,7 @@ var ConnectionIndicator = require("./ConnectionIndicator"); var SmallVideo = require("./SmallVideo"); var AudioLevels = require("../audio_levels/AudioLevels"); +var MediaStreamType = require("../../../service/RTC/MediaStreamTypes"); var RTCBrowserType = require("../../RTC/RTCBrowserType"); var UIUtils = require("../util/UIUtil"); var XMPPEvents = require("../../../service/xmpp/XMPPEvents"); @@ -178,8 +179,9 @@ RemoteVideo.prototype.remove = function () { RemoteVideo.prototype.waitForPlayback = function (sel, stream) { - var isVideo = stream.getVideoTracks().length > 0; - if (!isVideo || stream.id === 'mixedmslabel') { + var webRtcStream = stream.getOriginalStream(); + var isVideo = stream.isVideoStream(); + if (!isVideo || webRtcStream.id === 'mixedmslabel') { return; } @@ -191,7 +193,7 @@ RemoteVideo.prototype.waitForPlayback = function (sel, stream) { var onPlayingHandler = function () { // FIXME: why do i have to do this for FF? if (RTCBrowserType.isFirefox()) { - APP.RTC.attachMediaStream(sel, stream); + APP.RTC.attachMediaStream(sel, webRtcStream); } if (RTCBrowserType.isTemasysPluginUsed()) { sel = self.selectVideoElement(); @@ -212,7 +214,8 @@ RemoteVideo.prototype.addRemoteStreamElement = function (stream) { return; var self = this; - var isVideo = stream.getVideoTracks().length > 0; + var webRtcStream = stream.getOriginalStream(); + var isVideo = stream.isVideoStream(); var streamElement = SmallVideo.createStreamElement(stream); var newElementId = streamElement.id; @@ -226,14 +229,14 @@ RemoteVideo.prototype.addRemoteStreamElement = function (stream) { if (!isVideo || (this.container.offsetParent !== null && isVideo)) { this.waitForPlayback(sel, stream); - APP.RTC.attachMediaStream(sel, stream); + APP.RTC.attachMediaStream(sel, webRtcStream); } APP.RTC.addMediaStreamInactiveHandler( - stream, function () { + webRtcStream, function () { console.log('stream ended', this); - self.removeRemoteStreamElement(stream, isVideo, newElementId); + self.removeRemoteStreamElement(webRtcStream, isVideo, newElementId); }); // Add click handler. diff --git a/modules/UI/videolayout/SmallVideo.js b/modules/UI/videolayout/SmallVideo.js index 0bce83fc3..3d5e7acd2 100644 --- a/modules/UI/videolayout/SmallVideo.js +++ b/modules/UI/videolayout/SmallVideo.js @@ -4,6 +4,7 @@ var Avatar = require("../avatar/Avatar"); var UIUtil = require("../util/UIUtil"); var LargeVideo = require("./LargeVideo"); var RTCBrowserType = require("../../RTC/RTCBrowserType"); +var MediaStreamType = require("../../../service/RTC/MediaStreamTypes"); function SmallVideo() { this.isMuted = false; @@ -105,19 +106,22 @@ SmallVideo.prototype.setPresenceStatus = function (statusMsg) { * Creates an audio or video element for a particular MediaStream. */ SmallVideo.createStreamElement = function (stream) { - var isVideo = stream.getVideoTracks().length > 0; + var isVideo = stream.isVideoStream(); var element = isVideo ? document.createElement('video') : document.createElement('audio'); + if (isVideo) { + element.setAttribute("muted", "true"); + } if (!RTCBrowserType.isIExplorer()) { element.autoplay = true; } element.id = (isVideo ? 'remoteVideo_' : 'remoteAudio_') + - APP.RTC.getStreamID(stream); + APP.RTC.getStreamID(stream.getOriginalStream()); - element.onplay = function() { + element.onplay = function () { console.log("(TIME) Render " + (isVideo ? 'video' : 'audio') + ":\t", window.performance.now()); }; diff --git a/modules/UI/videolayout/VideoLayout.js b/modules/UI/videolayout/VideoLayout.js index 1154bbd75..58c226b2c 100644 --- a/modules/UI/videolayout/VideoLayout.js +++ b/modules/UI/videolayout/VideoLayout.js @@ -55,10 +55,6 @@ var VideoLayout = (function (my) { lastNEndpointsCache.indexOf(resource) !== -1); }; - my.changeLocalStream = function (stream, isMuted) { - VideoLayout.changeLocalVideo(stream, isMuted); - }; - my.changeLocalAudio = function(stream, isMuted) { if (isMuted) APP.UI.setAudioMuted(true, true); @@ -187,8 +183,7 @@ var VideoLayout = (function (my) { VideoLayout.ensurePeerContainerExists(stream.peerjid); var resourceJid = Strophe.getResourceFromJid(stream.peerjid); - remoteVideos[resourceJid].addRemoteStreamElement( - stream.getOriginalStream()); + remoteVideos[resourceJid].addRemoteStreamElement(stream); } }; diff --git a/modules/xmpp/JingleSessionPC.js b/modules/xmpp/JingleSessionPC.js index b5beaeefd..8b150cf07 100644 --- a/modules/xmpp/JingleSessionPC.js +++ b/modules/xmpp/JingleSessionPC.js @@ -562,7 +562,6 @@ JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) { if (config.webrtcIceUdpDisable) { this.remoteSDP.removeUdpCandidates = true; } - this.remoteSDP.fromJingle(elem); this.readSsrcInfo($(elem).find(">content")); if (this.peerconnection.remoteDescription !== null) { diff --git a/modules/xmpp/strophe.jingle.js b/modules/xmpp/strophe.jingle.js index 42599caa8..7e4a581ef 100644 --- a/modules/xmpp/strophe.jingle.js +++ b/modules/xmpp/strophe.jingle.js @@ -96,7 +96,7 @@ module.exports = function(XMPP, eventEmitter) { switch (action) { case 'session-initiate': console.log("(TIME) received session-initiate:\t", - window.performance.now()); + window.performance.now(), iq); var startMuted = $(iq).find('jingle>startmuted'); if (startMuted && startMuted.length > 0) { var audioMuted = startMuted.attr("audio"); @@ -176,10 +176,12 @@ module.exports = function(XMPP, eventEmitter) { break; case 'addsource': // FIXME: proprietary, un-jingleish case 'source-add': // FIXME: proprietary + console.info("source-add", iq); sess.addSource($(iq).find('>jingle>content')); break; case 'removesource': // FIXME: proprietary, un-jingleish case 'source-remove': // FIXME: proprietary + console.info("source-remove", iq); sess.removeSource($(iq).find('>jingle>content')); break; default: diff --git a/service/RTC/MediaStreamTypes.js b/service/RTC/MediaStreamTypes.js index 39af76288..3cd41d17c 100644 --- a/service/RTC/MediaStreamTypes.js +++ b/service/RTC/MediaStreamTypes.js @@ -1,6 +1,6 @@ var MediaStreamType = { - VIDEO_TYPE: "Video", + VIDEO_TYPE: "video", - AUDIO_TYPE: "Audio" + AUDIO_TYPE: "audio" }; module.exports = MediaStreamType; \ No newline at end of file