From 2b5d893ec13ead130564ac102d97eee91c6a1635 Mon Sep 17 00:00:00 2001 From: hristoterezov Date: Tue, 1 Sep 2015 14:04:55 -0500 Subject: [PATCH] Changes the implementation of RTCUtils to be static. --- modules/RTC/LocalStream.js | 4 +- modules/RTC/RTC.js | 37 +- modules/RTC/RTCUtils.js | 760 ++++++++++++++++---------------- modules/xmpp/JingleSessionPC.js | 5 +- 4 files changed, 401 insertions(+), 405 deletions(-) diff --git a/modules/RTC/LocalStream.js b/modules/RTC/LocalStream.js index ede8d6745..3f2f9c25b 100644 --- a/modules/RTC/LocalStream.js +++ b/modules/RTC/LocalStream.js @@ -83,8 +83,8 @@ LocalStream.prototype.setMute = function (mute) this.eventEmitter.emit(eventType, true); } else { var self = this; - this.rtcUtils.obtainAudioAndVideoPermissions( - (this.isAudioStream() ? ["audio"] : ["video"])) + this.rtc.obtainAudioAndVideoPermissions( + {devices: (this.isAudioStream() ? ["audio"] : ["video"])}) .then(function (stream) { if (isAudio) { self.rtc.changeLocalAudio(stream, diff --git a/modules/RTC/RTC.js b/modules/RTC/RTC.js index 524e54af1..3843d5907 100644 --- a/modules/RTC/RTC.js +++ b/modules/RTC/RTC.js @@ -11,7 +11,6 @@ var MediaStreamType = require("../../service/RTC/MediaStreamTypes"); var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js"); var RTCEvents = require("../../service/RTC/RTCEvents.js"); var XMPPEvents = require("../../service/xmpp/XMPPEvents"); -var UIEvents = require("../../service/UI/UIEvents"); var desktopsharing = require("../desktopsharing/desktopsharing"); function getMediaStreamUsage() @@ -44,7 +43,6 @@ function getMediaStreamUsage() function RTC(options) { - this.rtcUtils = null; this.devices = { audio: true, video: true @@ -68,7 +66,7 @@ function RTC(options) self.eventEmitter.emit(RTCEvents.RTC_READY, true); }; - this.rtcUtils = new RTCUtils(this, onReady); + RTCUtils.init(onReady); // Call onReady() if Temasys plugin is not used if (!RTCBrowserType.isTemasysPluginUsed()) { @@ -77,8 +75,8 @@ function RTC(options) } RTC.prototype.obtainAudioAndVideoPermissions = function (options) { - return this.rtcUtils.obtainAudioAndVideoPermissions( - null, getMediaStreamUsage(), options.resolution); + return RTCUtils.obtainAudioAndVideoPermissions(this, + options.devices, getMediaStreamUsage(), options.resolution); } RTC.prototype.onIncommingCall = function(event) { @@ -154,32 +152,32 @@ RTC.prototype.createRemoteStream = function (data, sid, thessrc) { return remoteStream; }; -RTC.prototype.getPCConstraints = function () { - return this.rtcUtils.pc_constraints; +RTC.getPCConstraints = function () { + return RTCUtils.pc_constraints; }; RTC.prototype.getUserMediaWithConstraints = function(um, success_callback, failure_callback, resolution, bandwidth, fps, desktopStream) { - return this.rtcUtils.getUserMediaWithConstraints(um, success_callback, + return RTCUtils.getUserMediaWithConstraints(this, um, success_callback, failure_callback, resolution, bandwidth, fps, desktopStream); }; -RTC.prototype.attachMediaStream = function (elSelector, stream) { - this.rtcUtils.attachMediaStream(elSelector, stream); +RTC.attachMediaStream = function (elSelector, stream) { + RTCUtils.attachMediaStream(elSelector, stream); }; -RTC.prototype.getStreamID = function (stream) { - return this.rtcUtils.getStreamID(stream); +RTC.getStreamID = function (stream) { + return RTCUtils.getStreamID(stream); }; -RTC.prototype.getVideoSrc = function (element) { - return this.rtcUtils.getVideoSrc(element); +RTC.getVideoSrc = function (element) { + return RTCUtils.getVideoSrc(element); }; -RTC.prototype.setVideoSrc = function (element, src) { - this.rtcUtils.setVideoSrc(element, src); +RTC.setVideoSrc = function (element, src) { + RTCUtils.setVideoSrc(element, src); }; RTC.prototype.getVideoElementName = function () { @@ -187,9 +185,6 @@ RTC.prototype.getVideoElementName = function () { }; RTC.prototype.dispose = function() { - if (this.rtcUtils) { - this.rtcUtils = null; - } }; RTC.prototype.muteRemoteVideoStream = function (jid, value) { @@ -239,7 +234,7 @@ RTC.prototype.changeLocalVideo = function (stream, isUsingScreenStream, callback if (stream && stream.videoStream) { stream = stream.videoStream; } - var videoStream = this.rtcUtils.createStream(stream, true); + var videoStream = RTCUtils.createStream(stream, true); this.localVideo = this.createLocalStream(videoStream, "video", true, type); // Stop the stream to trigger onended event for old stream oldStream.stop(); @@ -251,7 +246,7 @@ RTC.prototype.changeLocalVideo = function (stream, isUsingScreenStream, callback RTC.prototype.changeLocalAudio = function (stream, callback) { var oldStream = this.localAudio.getOriginalStream(); - var newStream = this.rtcUtils.createStream(stream); + var newStream = RTCUtils.createStream(stream); this.localAudio = this.createLocalStream(newStream, "audio", true); // Stop the stream to trigger onended event for old stream oldStream.stop(); diff --git a/modules/RTC/RTCUtils.js b/modules/RTC/RTCUtils.js index aadd6b9df..0b2a83729 100644 --- a/modules/RTC/RTCUtils.js +++ b/modules/RTC/RTCUtils.js @@ -5,6 +5,13 @@ var AdapterJS = require("./adapter.screenshare"); var SDPUtil = require("../xmpp/SDPUtil"); var currentResolution = null; +function DummyMediaStream(id) { + this.id = id; + this.label = id; + this.stop = function() { }; + this.getAudioTracks = function() { return []; }; + this.getVideoTracks = function() { return []; }; +} function getPreviousResolution(resolution) { if(!Resolutions[resolution]) @@ -135,420 +142,413 @@ function getConstraints(um, resolution, bandwidth, fps, desktopStream, isAndroid } //Options parameter is to pass config options. Currently uses only "useIPv6". -function RTCUtils(RTCService, onTemasysPluginReady) -{ - var self = this; - this.service = RTCService; - if (RTCBrowserType.isFirefox()) { - var FFversion = RTCBrowserType.getFirefoxVersion(); - if (FFversion >= 40) { - this.peerconnection = mozRTCPeerConnection; - this.getUserMedia = navigator.mozGetUserMedia.bind(navigator); - this.pc_constraints = {}; - this.attachMediaStream = function (element, stream) { - // srcObject is being standardized and FF will eventually - // support that unprefixed. FF also supports the - // "element.src = URL.createObjectURL(...)" combo, but that - // will be deprecated in favour of srcObject. - // - // https://groups.google.com/forum/#!topic/mozilla.dev.media/pKOiioXonJg - // https://github.com/webrtc/samples/issues/302 - if(!element[0]) - return; - element[0].mozSrcObject = stream; - element[0].play(); - }; - this.getStreamID = function (stream) { - var id = stream.id; - if (!id) { - var tracks = stream.getVideoTracks(); - if (!tracks || tracks.length === 0) { - tracks = stream.getAudioTracks(); +var RTCUtils = { + init: function (onTemasysPluginReady) { + var self = this; + if (RTCBrowserType.isFirefox()) { + var FFversion = RTCBrowserType.getFirefoxVersion(); + if (FFversion >= 40) { + this.peerconnection = mozRTCPeerConnection; + this.getUserMedia = navigator.mozGetUserMedia.bind(navigator); + this.pc_constraints = {}; + this.attachMediaStream = function (element, stream) { + // srcObject is being standardized and FF will eventually + // support that unprefixed. FF also supports the + // "element.src = URL.createObjectURL(...)" combo, but that + // will be deprecated in favour of srcObject. + // + // https://groups.google.com/forum/#!topic/mozilla.dev.media/pKOiioXonJg + // https://github.com/webrtc/samples/issues/302 + if (!element[0]) + return; + element[0].mozSrcObject = stream; + element[0].play(); + }; + this.getStreamID = function (stream) { + var id = stream.id; + if (!id) { + var tracks = stream.getVideoTracks(); + if (!tracks || tracks.length === 0) { + tracks = stream.getAudioTracks(); + } + id = tracks[0].id; } - id = tracks[0].id; - } - return SDPUtil.filter_special_chars(id); + return SDPUtil.filter_special_chars(id); + }; + this.getVideoSrc = function (element) { + if (!element) + return null; + return element.mozSrcObject; + }; + this.setVideoSrc = function (element, src) { + if (element) + element.mozSrcObject = src; + }; + RTCSessionDescription = mozRTCSessionDescription; + RTCIceCandidate = mozRTCIceCandidate; + } else { + console.error( + "Firefox version too old: " + FFversion + ". Required >= 40."); + window.location.href = 'unsupported_browser.html'; + return; + } + + } else if (RTCBrowserType.isChrome() || RTCBrowserType.isOpera()) { + this.peerconnection = webkitRTCPeerConnection; + this.getUserMedia = navigator.webkitGetUserMedia.bind(navigator); + this.attachMediaStream = function (element, stream) { + element.attr('src', webkitURL.createObjectURL(stream)); + }; + this.getStreamID = function (stream) { + // streams from FF endpoints have the characters '{' and '}' + // that make jQuery choke. + return SDPUtil.filter_special_chars(stream.id); }; this.getVideoSrc = function (element) { - if(!element) + if (!element) return null; - return element.mozSrcObject; + return element.getAttribute("src"); }; this.setVideoSrc = function (element, src) { - if(element) - element.mozSrcObject = src; + if (element) + element.setAttribute("src", src); }; - RTCSessionDescription = mozRTCSessionDescription; - RTCIceCandidate = mozRTCIceCandidate; - } else { - console.error( - "Firefox version too old: " + FFversion + ". Required >= 40."); - window.location.href = 'unsupported_browser.html'; - return; + // DTLS should now be enabled by default but.. + this.pc_constraints = {'optional': [ + {'DtlsSrtpKeyAgreement': 'true'} + ]}; + if (this.service.options.useIPv6) { + // https://code.google.com/p/webrtc/issues/detail?id=2828 + this.pc_constraints.optional.push({googIPv6: true}); + } + if (navigator.userAgent.indexOf('Android') != -1) { + this.pc_constraints = {}; // disable DTLS on Android + } + if (!webkitMediaStream.prototype.getVideoTracks) { + webkitMediaStream.prototype.getVideoTracks = function () { + return this.videoTracks; + }; + } + if (!webkitMediaStream.prototype.getAudioTracks) { + webkitMediaStream.prototype.getAudioTracks = function () { + return this.audioTracks; + }; + } } + // Detect IE/Safari + else if (RTCBrowserType.isTemasysPluginUsed()) { - } else if (RTCBrowserType.isChrome() || RTCBrowserType.isOpera()) { - this.peerconnection = webkitRTCPeerConnection; - this.getUserMedia = navigator.webkitGetUserMedia.bind(navigator); - this.attachMediaStream = function (element, stream) { - element.attr('src', webkitURL.createObjectURL(stream)); - }; - this.getStreamID = function (stream) { - // streams from FF endpoints have the characters '{' and '}' - // that make jQuery choke. - return SDPUtil.filter_special_chars(stream.id); - }; - this.getVideoSrc = function (element) { - if(!element) - return null; - return element.getAttribute("src"); - }; - this.setVideoSrc = function (element, src) { - if(element) - element.setAttribute("src", src); - }; - // DTLS should now be enabled by default but.. - this.pc_constraints = {'optional': [{'DtlsSrtpKeyAgreement': 'true'}]}; - if (this.service.options.useIPv6) { - // https://code.google.com/p/webrtc/issues/detail?id=2828 - this.pc_constraints.optional.push({googIPv6: true}); - } - if (navigator.userAgent.indexOf('Android') != -1) { - this.pc_constraints = {}; // disable DTLS on Android - } - if (!webkitMediaStream.prototype.getVideoTracks) { - webkitMediaStream.prototype.getVideoTracks = function () { - return this.videoTracks; - }; - } - if (!webkitMediaStream.prototype.getAudioTracks) { - webkitMediaStream.prototype.getAudioTracks = function () { - return this.audioTracks; - }; - } - } - // Detect IE/Safari - else if (RTCBrowserType.isTemasysPluginUsed()) { + //AdapterJS.WebRTCPlugin.setLogLevel( + // AdapterJS.WebRTCPlugin.PLUGIN_LOG_LEVELS.VERBOSE); - //AdapterJS.WebRTCPlugin.setLogLevel( - // AdapterJS.WebRTCPlugin.PLUGIN_LOG_LEVELS.VERBOSE); + AdapterJS.webRTCReady(function (isPlugin) { - AdapterJS.webRTCReady(function (isPlugin) { + self.peerconnection = RTCPeerConnection; + self.getUserMedia = getUserMedia; + self.attachMediaStream = function (elSel, stream) { - self.peerconnection = RTCPeerConnection; - self.getUserMedia = getUserMedia; - self.attachMediaStream = function (elSel, stream) { + if (stream.id === "dummyAudio" || stream.id === "dummyVideo") { + return; + } - if (stream.id === "dummyAudio" || stream.id === "dummyVideo") { - return; - } - - attachMediaStream(elSel[0], stream); - }; - self.getStreamID = function (stream) { - var id = SDPUtil.filter_special_chars(stream.label); - return id; - }; - self.getVideoSrc = function (element) { - if (!element) { - console.warn("Attempt to get video SRC of null element"); + attachMediaStream(elSel[0], stream); + }; + self.getStreamID = function (stream) { + var id = SDPUtil.filter_special_chars(stream.label); + return id; + }; + self.getVideoSrc = function (element) { + if (!element) { + console.warn("Attempt to get video SRC of null element"); + return null; + } + var children = element.children; + for (var i = 0; i !== children.length; ++i) { + if (children[i].name === 'streamId') { + return children[i].value; + } + } + //console.info(element.id + " SRC: " + src); return null; - } - var children = element.children; - for (var i = 0; i !== children.length; ++i) { - if (children[i].name === 'streamId') { - return children[i].value; + }; + self.setVideoSrc = function (element, src) { + //console.info("Set video src: ", element, src); + if (!src) { + console.warn("Not attaching video stream, 'src' is null"); + return; } - } - //console.info(element.id + " SRC: " + src); - return null; - }; - self.setVideoSrc = function (element, src) { - //console.info("Set video src: ", element, src); - if (!src) { - console.warn("Not attaching video stream, 'src' is null"); - return; - } - AdapterJS.WebRTCPlugin.WaitForPluginReady(); - var stream = AdapterJS.WebRTCPlugin.plugin - .getStreamWithId(AdapterJS.WebRTCPlugin.pageId, src); - attachMediaStream(element, stream); - }; + AdapterJS.WebRTCPlugin.WaitForPluginReady(); + var stream = AdapterJS.WebRTCPlugin.plugin + .getStreamWithId(AdapterJS.WebRTCPlugin.pageId, src); + attachMediaStream(element, stream); + }; - onTemasysPluginReady(isPlugin); - }); - } else { - try { - console.log('Browser does not appear to be WebRTC-capable'); - } catch (e) { } - window.location.href = 'unsupported_browser.html'; - } - -} - - -RTCUtils.prototype.getUserMediaWithConstraints = function( - um, success_callback, failure_callback, resolution,bandwidth, fps, - desktopStream) { - currentResolution = resolution; - // Check if we are running on Android device - var isAndroid = navigator.userAgent.indexOf('Android') != -1; - - var constraints = getConstraints( - um, resolution, bandwidth, fps, desktopStream, isAndroid); - - console.info("Get media constraints", constraints); - - var self = this; - - try { - this.getUserMedia(constraints, - function (stream) { - console.log('onUserMediaSuccess'); - self.setAvailableDevices(um, true); - success_callback(stream); - }, - function (error) { - self.setAvailableDevices(um, false); - console.warn('Failed to get access to local media. Error ', - error, constraints); - if (failure_callback) { - failure_callback(error); - } + onTemasysPluginReady(isPlugin); }); - } catch (e) { - console.error('GUM failed: ', e); - if(failure_callback) { - failure_callback(e); - } - } -}; - -RTCUtils.prototype.setAvailableDevices = function (um, available) { - var devices = {}; - if(um.indexOf("video") != -1) { - devices.video = available; - } - if(um.indexOf("audio") != -1) { - devices.audio = available; - } - this.service.setDeviceAvailability(devices); -}; - -/** - * We ask for audio and video combined stream in order to get permissions and - * not to ask twice. - */ -RTCUtils.prototype.obtainAudioAndVideoPermissions = - function(devices, usageOptions, resolution) -{ - var self = this; - // Get AV - - return new Promise(function(resolve, reject) { - var successCallback = function (stream) { - resolve(self.successCallback(stream, usageOptions)); - }; - - if (!devices) - devices = ['audio', 'video']; - - var newDevices = []; - - - if (usageOptions) - for (var i = 0; i < devices.length; i++) { - var device = devices[i]; - if (usageOptions[device] === true) - newDevices.push(device); - } - else - newDevices = devices; - - if (newDevices.length === 0) { - successCallback(); - return; - } - - if (RTCBrowserType.isFirefox() || RTCBrowserType.isTemasysPluginUsed()) { - - // With FF/IE we can't split the stream into audio and video because FF - // doesn't support media stream constructors. So, we need to get the - // audio stream separately from the video stream using two distinct GUM - // calls. Not very user friendly :-( but we don't have many other - // options neither. - // - // Note that we pack those 2 streams in a single object and pass it to - // the successCallback method. - var obtainVideo = function (audioStream) { - self.getUserMediaWithConstraints( - ['video'], - function (videoStream) { - return successCallback({ - audioStream: audioStream, - videoStream: videoStream - }); - }, - function (error) { - console.error( - 'failed to obtain video stream - stop', error); - self.errorCallback(error, resolve); - }, - config.resolution || '360'); - }; - var obtainAudio = function () { - self.getUserMediaWithConstraints( - ['audio'], - function (audioStream) { - if (newDevices.indexOf('video') !== -1) - obtainVideo(audioStream); - }, - function (error) { - console.error( - 'failed to obtain audio stream - stop', error); - self.errorCallback(error, resolve); - } - ); - }; - if (newDevices.indexOf('audio') !== -1) { - obtainAudio(); - } else { - obtainVideo(null); - } } else { - this.getUserMediaWithConstraints( - newDevices, + try { + console.log('Browser does not appear to be WebRTC-capable'); + } catch (e) { + } + window.location.href = 'unsupported_browser.html'; + } + + }, + + + getUserMediaWithConstraints: function (RTC, um, success_callback, failure_callback, resolution, bandwidth, fps, desktopStream) { + // Check if we are running on Android device + var isAndroid = navigator.userAgent.indexOf('Android') != -1; + + var constraints = getConstraints( + um, resolution, bandwidth, fps, desktopStream, isAndroid); + + console.info("Get media constraints", constraints); + + var self = this; + + try { + this.getUserMedia(constraints, function (stream) { - successCallback(stream); + console.log('onUserMediaSuccess'); + self.setAvailableDevices(RTC, um, true); + success_callback(stream); }, function (error) { - self.errorCallback(error, resolve); + self.setAvailableDevices(RTC, um, false); + console.warn('Failed to get access to local media. Error ', + error, constraints); + if (failure_callback) { + failure_callback(error, resolution); + } + }); + } catch (e) { + console.error('GUM failed: ', e); + if (failure_callback) { + failure_callback(e); + } + } + }, + + setAvailableDevices: function (RTC, um, available) { + var devices = {}; + if (um.indexOf("video") != -1) { + devices.video = available; + } + if (um.indexOf("audio") != -1) { + devices.audio = available; + } + RTC.setDeviceAvailability(devices); + }, + + /** + * We ask for audio and video combined stream in order to get permissions and + * not to ask twice. + */ + obtainAudioAndVideoPermissions: function (RTC, devices, usageOptions, resolution) { + var self = this; + // Get AV + + return new Promise(function (resolve, reject) { + var successCallback = function (stream) { + resolve(self.successCallback(stream, usageOptions)); + }; + + if (!devices) + devices = ['audio', 'video']; + + var newDevices = []; + + + if (usageOptions) + for (var i = 0; i < devices.length; i++) { + var device = devices[i]; + if (usageOptions[device] === true) + newDevices.push(device); + } + else + newDevices = devices; + + if (newDevices.length === 0) { + successCallback(); + return; + } + + if (RTCBrowserType.isFirefox() || RTCBrowserType.isTemasysPluginUsed()) { + + // With FF/IE we can't split the stream into audio and video because FF + // doesn't support media stream constructors. So, we need to get the + // audio stream separately from the video stream using two distinct GUM + // calls. Not very user friendly :-( but we don't have many other + // options neither. + // + // Note that we pack those 2 streams in a single object and pass it to + // the successCallback method. + var obtainVideo = function (audioStream) { + self.getUserMediaWithConstraints( + RTC, + ['video'], + function (videoStream) { + return successCallback({ + audioStream: audioStream, + videoStream: videoStream + }); + }, + function (error, resolution) { + console.error( + 'failed to obtain video stream - stop', error); + self.errorCallback(error, resolve, RTC, resolution); + }, + config.resolution || '360'); + }; + var obtainAudio = function () { + self.getUserMediaWithConstraints( + RTC, + ['audio'], + function (audioStream) { + if (newDevices.indexOf('video') !== -1) + obtainVideo(audioStream); + }, + function (error) { + console.error( + 'failed to obtain audio stream - stop', error); + self.errorCallback(error, resolve, RTC); + } + ); + }; + if (newDevices.indexOf('audio') !== -1) { + obtainAudio(); + } else { + obtainVideo(null); + } + } else { + this.getUserMediaWithConstraints( + RTC, + newDevices, + function (stream) { + successCallback(stream); + }, + function (error, resolution) { + self.errorCallback(error, resolve, RTC, resolution); + }, + resolution || '360'); + } + }.bind(this)); + }, + + successCallback: function (stream, usageOptions) { + // If this is FF or IE, the stream parameter is *not* a MediaStream object, + // it's an object with two properties: audioStream, videoStream. + if (stream && stream.getAudioTracks && stream.getVideoTracks) + console.log('got', stream, stream.getAudioTracks().length, + stream.getVideoTracks().length); + return this.handleLocalStream(stream, usageOptions); + }, + + errorCallback: function (error, resolve, RTC, currentResolution) { + var self = this; + console.error('failed to obtain audio/video stream - trying audio only', error); + var resolution = getPreviousResolution(currentResolution); + if (typeof error == "object" && error.constraintName && error.name + && (error.name == "ConstraintNotSatisfiedError" || + error.name == "OverconstrainedError") && + (error.constraintName == "minWidth" || error.constraintName == "maxWidth" || + error.constraintName == "minHeight" || error.constraintName == "maxHeight") + && resolution != null) { + self.getUserMediaWithConstraints(RTC, ['audio', 'video'], + function (stream) { + resolve(self.successCallback(stream)); + }, function (error, resolution) { + return self.errorCallback(error, resolve, RTC, resolution); + }, resolution); + } + else { + self.getUserMediaWithConstraints( + RTC, + ['audio'], + function (stream) { + resolve(self.successCallback(stream)); }, - resolution || '360'); + function (error) { + console.error('failed to obtain audio/video stream - stop', + error); + resolve(self.successCallback(null)); + } + ); } - }.bind(this)); -}; + }, -RTCUtils.prototype.successCallback = function (stream, usageOptions) { - // If this is FF or IE, the stream parameter is *not* a MediaStream object, - // it's an object with two properties: audioStream, videoStream. - if (stream && stream.getAudioTracks && stream.getVideoTracks) - console.log('got', stream, stream.getAudioTracks().length, - stream.getVideoTracks().length); - return this.handleLocalStream(stream, usageOptions); -}; + handleLocalStream: function (stream, usageOptions) { + // If this is FF, the stream parameter is *not* a MediaStream object, it's + // an object with two properties: audioStream, videoStream. + if (window.webkitMediaStream) { + audioStream = new webkitMediaStream(); + videoStream = new webkitMediaStream(); + if (stream) { + var audioTracks = stream.getAudioTracks(); -RTCUtils.prototype.errorCallback = function (error, resolve) { - var self = this; - console.error('failed to obtain audio/video stream - trying audio only', error); - var resolution = getPreviousResolution(currentResolution); - if(typeof error == "object" && error.constraintName && error.name - && (error.name == "ConstraintNotSatisfiedError" || - error.name == "OverconstrainedError") && - (error.constraintName == "minWidth" || error.constraintName == "maxWidth" || - error.constraintName == "minHeight" || error.constraintName == "maxHeight") - && resolution != null) - { - self.getUserMediaWithConstraints(['audio', 'video'], - function (stream) { - resolve(self.successCallback(stream)); - }, function (error) { - return self.errorCallback(error); - }, resolution); - } - else { - self.getUserMediaWithConstraints( - ['audio'], - function (stream) { - resolve(self.successCallback(stream)); - }, - function (error) { - console.error('failed to obtain audio/video stream - stop', - error); - resolve(self.successCallback(null)); - } - ); - } -}; + for (var i = 0; i < audioTracks.length; i++) { + audioStream.addTrack(audioTracks[i]); + } -RTCUtils.prototype.handleLocalStream = function(stream, usageOptions) { - // If this is FF, the stream parameter is *not* a MediaStream object, it's - // an object with two properties: audioStream, videoStream. - if(window.webkitMediaStream) - { - audioStream = new webkitMediaStream(); - videoStream = new webkitMediaStream(); - if(stream) { - var audioTracks = stream.getAudioTracks(); + var videoTracks = stream.getVideoTracks(); - for (var i = 0; i < audioTracks.length; i++) { - audioStream.addTrack(audioTracks[i]); + for (i = 0; i < videoTracks.length; i++) { + videoStream.addTrack(videoTracks[i]); + } } - var videoTracks = stream.getVideoTracks(); + } + else if (RTCBrowserType.isFirefox() || RTCBrowserType.isTemasysPluginUsed()) { // Firefox and Temasys plugin + if (stream && stream.audioStream) + audioStream = stream.audioStream; + else + audioStream = new DummyMediaStream("dummyAudio"); - for (i = 0; i < videoTracks.length; i++) { - videoStream.addTrack(videoTracks[i]); + if (stream && stream.videoStream) + videoStream = stream.videoStream; + else + videoStream = new DummyMediaStream("dummyVideo"); + } + + var audioMuted = (usageOptions && usageOptions.audio === false), + videoMuted = (usageOptions && usageOptions.video === false); + + var audioGUM = (!usageOptions || usageOptions.audio !== false), + videoGUM = (!usageOptions || usageOptions.video !== false); + + return this.service.createLocalStreams( + [ + {stream: audioStream, type: "audio", isMuted: audioMuted, isGUMStream: audioGUM, videoType: null}, + {stream: videoStream, type: "video", isMuted: videoMuted, isGUMStream: videoGUM, videoType: "camera"} + ]); + }, + + createStream: function (stream, isVideo) { + var newStream = null; + if (window.webkitMediaStream) { + newStream = new webkitMediaStream(); + if (newStream) { + var tracks = (isVideo ? stream.getVideoTracks() : stream.getAudioTracks()); + + for (var i = 0; i < tracks.length; i++) { + newStream.addTrack(tracks[i]); + } + } + + } + else { + // FIXME: this is duplicated with 'handleLocalStream' !!! + if (stream) { + newStream = stream; + } else { + newStream = + new DummyMediaStream(isVideo ? "dummyVideo" : "dummyAudio"); } } + return newStream; } - else if (RTCBrowserType.isFirefox() || RTCBrowserType.isTemasysPluginUsed()) - { // Firefox and Temasys plugin - if (stream && stream.audioStream) - audioStream = stream.audioStream; - else - audioStream = new DummyMediaStream("dummyAudio"); - - if (stream && stream.videoStream) - videoStream = stream.videoStream; - else - videoStream = new DummyMediaStream("dummyVideo"); - } - - var audioMuted = (usageOptions && usageOptions.audio === false), - videoMuted = (usageOptions && usageOptions.video === false); - - var audioGUM = (!usageOptions || usageOptions.audio !== false), - videoGUM = (!usageOptions || usageOptions.video !== false); - - return this.service.createLocalStreams( - [{stream: audioStream, type: "audio", isMuted: audioMuted, isGUMStream: audioGUM, videoType: null}, - {stream: videoStream, type: "video", isMuted: videoMuted, isGUMStream: videoGUM, videoType: "camera"}]); -}; - -function DummyMediaStream(id) { - this.id = id; - this.label = id; - this.stop = function() { }; - this.getAudioTracks = function() { return []; }; - this.getVideoTracks = function() { return []; }; } -RTCUtils.prototype.createStream = function(stream, isVideo) { - var newStream = null; - if (window.webkitMediaStream) { - newStream = new webkitMediaStream(); - if (newStream) { - var tracks = (isVideo ? stream.getVideoTracks() : stream.getAudioTracks()); - - for (var i = 0; i < tracks.length; i++) { - newStream.addTrack(tracks[i]); - } - } - - } - else { - // FIXME: this is duplicated with 'handleLocalStream' !!! - if (stream) { - newStream = stream; - } else { - newStream = - new DummyMediaStream(isVideo ? "dummyVideo" : "dummyAudio"); - } - } - - return newStream; -}; - module.exports = RTCUtils; diff --git a/modules/xmpp/JingleSessionPC.js b/modules/xmpp/JingleSessionPC.js index 9890f19df..973b5ddb4 100644 --- a/modules/xmpp/JingleSessionPC.js +++ b/modules/xmpp/JingleSessionPC.js @@ -9,6 +9,7 @@ var transform = require("sdp-transform"); var XMPPEvents = require("../../service/xmpp/XMPPEvents"); var RTCBrowserType = require("../RTC/RTCBrowserType"); var SSRCReplacement = require("./LocalSSRCReplacement"); +var RTC = require("../RTC/RTC"); // Jingle stuff function JingleSessionPC(me, sid, connection, service, eventEmitter) { @@ -94,8 +95,8 @@ JingleSessionPC.prototype.doInitialize = function () { }; this.peerconnection.onaddstream = function (event) { if (event.stream.id !== 'default') { - console.log("REMOTE STREAM ADDED: ", event.stream , event.stream.id); - self.remoteStreamAdded(event); + console.log("REMOTE STREAM ADDED: ", event.stream , event.stream.id); + self.remoteStreamAdded(event); } else { // This is a recvonly stream. Clients that implement Unified Plan, // such as Firefox use recvonly "streams/channels/tracks" for