Changes the implementation of RTCUtils to be static.

This commit is contained in:
hristoterezov 2015-09-01 14:04:55 -05:00
parent a241d4b9b4
commit 2b5d893ec1
4 changed files with 401 additions and 405 deletions

View File

@ -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,

View File

@ -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();

View File

@ -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;

View File

@ -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