|
|
@ -30,6 +30,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'use strict'; |
|
|
|
|
|
|
|
|
|
|
|
var getUserMedia = null; |
|
|
|
var getUserMedia = null; |
|
|
|
var attachMediaStream = null; |
|
|
|
var attachMediaStream = null; |
|
|
|
var reattachMediaStream = null; |
|
|
|
var reattachMediaStream = null; |
|
|
@ -39,24 +41,79 @@ var webrtcMinimumVersion = null; |
|
|
|
var webrtcUtils = { |
|
|
|
var webrtcUtils = { |
|
|
|
log: function() { |
|
|
|
log: function() { |
|
|
|
// suppress console.log output when being included as a module.
|
|
|
|
// suppress console.log output when being included as a module.
|
|
|
|
if (!(typeof module !== 'undefined' || |
|
|
|
if (typeof module !== 'undefined' || |
|
|
|
typeof require === 'function') && (typeof define === 'function')) { |
|
|
|
typeof require === 'function' && typeof define === 'function') { |
|
|
|
console.log.apply(console, arguments); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
console.log.apply(console, arguments); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
extractVersion: function(uastring, expr, pos) { |
|
|
|
|
|
|
|
var match = uastring.match(expr); |
|
|
|
|
|
|
|
return match && match.length >= pos && parseInt(match[pos], 10); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
function trace(text) { |
|
|
|
|
|
|
|
// This function is used for logging.
|
|
|
|
|
|
|
|
if (text[text.length - 1] === '\n') { |
|
|
|
|
|
|
|
text = text.substring(0, text.length - 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (window.performance) { |
|
|
|
|
|
|
|
var now = (window.performance.now() / 1000).toFixed(3); |
|
|
|
|
|
|
|
webrtcUtils.log(now + ': ' + text); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
webrtcUtils.log(text); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (typeof window === 'object') { |
|
|
|
|
|
|
|
if (window.HTMLMediaElement && |
|
|
|
|
|
|
|
!('srcObject' in window.HTMLMediaElement.prototype)) { |
|
|
|
|
|
|
|
// Shim the srcObject property, once, when HTMLMediaElement is found.
|
|
|
|
|
|
|
|
Object.defineProperty(window.HTMLMediaElement.prototype, 'srcObject', { |
|
|
|
|
|
|
|
get: function() { |
|
|
|
|
|
|
|
// If prefixed srcObject property exists, return it.
|
|
|
|
|
|
|
|
// Otherwise use the shimmed property, _srcObject
|
|
|
|
|
|
|
|
return 'mozSrcObject' in this ? this.mozSrcObject : this._srcObject; |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
set: function(stream) { |
|
|
|
|
|
|
|
if ('mozSrcObject' in this) { |
|
|
|
|
|
|
|
this.mozSrcObject = stream; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// Use _srcObject as a private property for this shim
|
|
|
|
|
|
|
|
this._srcObject = stream; |
|
|
|
|
|
|
|
// TODO: revokeObjectUrl(this.src) when !stream to release resources?
|
|
|
|
|
|
|
|
this.src = URL.createObjectURL(stream); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Proxy existing globals
|
|
|
|
|
|
|
|
getUserMedia = window.navigator && window.navigator.getUserMedia; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Attach a media stream to an element.
|
|
|
|
|
|
|
|
attachMediaStream = function(element, stream) { |
|
|
|
|
|
|
|
element.srcObject = stream; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reattachMediaStream = function(to, from) { |
|
|
|
|
|
|
|
to.srcObject = from.srcObject; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
webrtcUtils.log('This does not appear to be a browser'); |
|
|
|
webrtcUtils.log('This does not appear to be a browser'); |
|
|
|
webrtcDetectedBrowser = 'not a browser'; |
|
|
|
webrtcDetectedBrowser = 'not a browser'; |
|
|
|
} else if (navigator.mozGetUserMedia) { |
|
|
|
} else if (navigator.mozGetUserMedia && window.mozRTCPeerConnection) { |
|
|
|
webrtcUtils.log('This appears to be Firefox'); |
|
|
|
webrtcUtils.log('This appears to be Firefox'); |
|
|
|
|
|
|
|
|
|
|
|
webrtcDetectedBrowser = 'firefox'; |
|
|
|
webrtcDetectedBrowser = 'firefox'; |
|
|
|
|
|
|
|
|
|
|
|
// the detected firefox version.
|
|
|
|
// the detected firefox version.
|
|
|
|
webrtcDetectedVersion = |
|
|
|
webrtcDetectedVersion = webrtcUtils.extractVersion(navigator.userAgent, |
|
|
|
parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10); |
|
|
|
/Firefox\/([0-9]+)\./, 1); |
|
|
|
|
|
|
|
|
|
|
|
// the minimum firefox version still supported by adapter.
|
|
|
|
// the minimum firefox version still supported by adapter.
|
|
|
|
webrtcMinimumVersion = 31; |
|
|
|
webrtcMinimumVersion = 31; |
|
|
@ -88,14 +145,18 @@ if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
pcConfig.iceServers = newIceServers; |
|
|
|
pcConfig.iceServers = newIceServers; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return new mozRTCPeerConnection(pcConfig, pcConstraints); |
|
|
|
return new mozRTCPeerConnection(pcConfig, pcConstraints); // jscs:ignore requireCapitalizedConstructors
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// The RTCSessionDescription object.
|
|
|
|
// The RTCSessionDescription object.
|
|
|
|
window.RTCSessionDescription = mozRTCSessionDescription; |
|
|
|
if (!window.RTCSessionDescription) { |
|
|
|
|
|
|
|
window.RTCSessionDescription = mozRTCSessionDescription; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// The RTCIceCandidate object.
|
|
|
|
// The RTCIceCandidate object.
|
|
|
|
window.RTCIceCandidate = mozRTCIceCandidate; |
|
|
|
if (!window.RTCIceCandidate) { |
|
|
|
|
|
|
|
window.RTCIceCandidate = mozRTCIceCandidate; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// getUserMedia constraints shim.
|
|
|
|
// getUserMedia constraints shim.
|
|
|
|
getUserMedia = function(constraints, onSuccess, onError) { |
|
|
|
getUserMedia = function(constraints, onSuccess, onError) { |
|
|
@ -168,8 +229,8 @@ if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
navigator.mediaDevices.enumerateDevices || function() { |
|
|
|
navigator.mediaDevices.enumerateDevices || function() { |
|
|
|
return new Promise(function(resolve) { |
|
|
|
return new Promise(function(resolve) { |
|
|
|
var infos = [ |
|
|
|
var infos = [ |
|
|
|
{kind: 'audioinput', deviceId: 'default', label:'', groupId:''}, |
|
|
|
{kind: 'audioinput', deviceId: 'default', label: '', groupId: ''}, |
|
|
|
{kind: 'videoinput', deviceId: 'default', label:'', groupId:''} |
|
|
|
{kind: 'videoinput', deviceId: 'default', label: '', groupId: ''} |
|
|
|
]; |
|
|
|
]; |
|
|
|
resolve(infos); |
|
|
|
resolve(infos); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -180,7 +241,7 @@ if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
var orgEnumerateDevices = |
|
|
|
var orgEnumerateDevices = |
|
|
|
navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices); |
|
|
|
navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices); |
|
|
|
navigator.mediaDevices.enumerateDevices = function() { |
|
|
|
navigator.mediaDevices.enumerateDevices = function() { |
|
|
|
return orgEnumerateDevices().catch(function(e) { |
|
|
|
return orgEnumerateDevices().then(undefined, function(e) { |
|
|
|
if (e.name === 'NotFoundError') { |
|
|
|
if (e.name === 'NotFoundError') { |
|
|
|
return []; |
|
|
|
return []; |
|
|
|
} |
|
|
|
} |
|
|
@ -188,30 +249,27 @@ if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
// Attach a media stream to an element.
|
|
|
|
} else if (navigator.webkitGetUserMedia && window.webkitRTCPeerConnection) { |
|
|
|
attachMediaStream = function(element, stream) { |
|
|
|
|
|
|
|
element.mozSrcObject = stream; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reattachMediaStream = function(to, from) { |
|
|
|
|
|
|
|
to.mozSrcObject = from.mozSrcObject; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else if (navigator.webkitGetUserMedia) { |
|
|
|
|
|
|
|
webrtcUtils.log('This appears to be Chrome'); |
|
|
|
webrtcUtils.log('This appears to be Chrome'); |
|
|
|
|
|
|
|
|
|
|
|
webrtcDetectedBrowser = 'chrome'; |
|
|
|
webrtcDetectedBrowser = 'chrome'; |
|
|
|
|
|
|
|
|
|
|
|
// the detected chrome version.
|
|
|
|
// the detected chrome version.
|
|
|
|
webrtcDetectedVersion = |
|
|
|
webrtcDetectedVersion = webrtcUtils.extractVersion(navigator.userAgent, |
|
|
|
parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10); |
|
|
|
/Chrom(e|ium)\/([0-9]+)\./, 2); |
|
|
|
|
|
|
|
|
|
|
|
// the minimum chrome version still supported by adapter.
|
|
|
|
// the minimum chrome version still supported by adapter.
|
|
|
|
webrtcMinimumVersion = 38; |
|
|
|
webrtcMinimumVersion = 38; |
|
|
|
|
|
|
|
|
|
|
|
// The RTCPeerConnection object.
|
|
|
|
// The RTCPeerConnection object.
|
|
|
|
window.RTCPeerConnection = function(pcConfig, pcConstraints) { |
|
|
|
window.RTCPeerConnection = function(pcConfig, pcConstraints) { |
|
|
|
var pc = new webkitRTCPeerConnection(pcConfig, pcConstraints); |
|
|
|
// Translate iceTransportPolicy to iceTransports,
|
|
|
|
|
|
|
|
// see https://code.google.com/p/webrtc/issues/detail?id=4869
|
|
|
|
|
|
|
|
if (pcConfig && pcConfig.iceTransportPolicy) { |
|
|
|
|
|
|
|
pcConfig.iceTransports = pcConfig.iceTransportPolicy; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var pc = new webkitRTCPeerConnection(pcConfig, pcConstraints); // jscs:ignore requireCapitalizedConstructors
|
|
|
|
var origGetStats = pc.getStats.bind(pc); |
|
|
|
var origGetStats = pc.getStats.bind(pc); |
|
|
|
pc.getStats = function(selector, successCallback, errorCallback) { // jshint ignore: line
|
|
|
|
pc.getStats = function(selector, successCallback, errorCallback) { // jshint ignore: line
|
|
|
|
var self = this; |
|
|
|
var self = this; |
|
|
@ -251,7 +309,14 @@ if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
|
|
|
|
|
|
|
|
// promise-support
|
|
|
|
// promise-support
|
|
|
|
return new Promise(function(resolve, reject) { |
|
|
|
return new Promise(function(resolve, reject) { |
|
|
|
origGetStats.apply(self, [resolve, reject]); |
|
|
|
if (args.length === 1 && selector === null) { |
|
|
|
|
|
|
|
origGetStats.apply(self, [ |
|
|
|
|
|
|
|
function(response) { |
|
|
|
|
|
|
|
resolve.apply(null, [fixChromeStats(response)]); |
|
|
|
|
|
|
|
}, reject]); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
origGetStats.apply(self, [resolve, reject]); |
|
|
|
|
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -417,7 +482,7 @@ if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
|
|
|
|
|
|
|
|
// Attach a media stream to an element.
|
|
|
|
// Attach a media stream to an element.
|
|
|
|
attachMediaStream = function(element, stream) { |
|
|
|
attachMediaStream = function(element, stream) { |
|
|
|
if (typeof element.srcObject !== 'undefined') { |
|
|
|
if (webrtcDetectedVersion >= 43) { |
|
|
|
element.srcObject = stream; |
|
|
|
element.srcObject = stream; |
|
|
|
} else if (typeof element.src !== 'undefined') { |
|
|
|
} else if (typeof element.src !== 'undefined') { |
|
|
|
element.src = URL.createObjectURL(stream); |
|
|
|
element.src = URL.createObjectURL(stream); |
|
|
@ -425,9 +490,12 @@ if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
webrtcUtils.log('Error attaching stream to element.'); |
|
|
|
webrtcUtils.log('Error attaching stream to element.'); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
reattachMediaStream = function(to, from) { |
|
|
|
reattachMediaStream = function(to, from) { |
|
|
|
to.src = from.src; |
|
|
|
if (webrtcDetectedVersion >= 43) { |
|
|
|
|
|
|
|
to.srcObject = from.srcObject; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
to.src = from.src; |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
} else if (navigator.mediaDevices && navigator.userAgent.match( |
|
|
|
} else if (navigator.mediaDevices && navigator.userAgent.match( |
|
|
@ -435,20 +503,11 @@ if (typeof window === 'undefined' || !window.navigator) { |
|
|
|
webrtcUtils.log('This appears to be Edge'); |
|
|
|
webrtcUtils.log('This appears to be Edge'); |
|
|
|
webrtcDetectedBrowser = 'edge'; |
|
|
|
webrtcDetectedBrowser = 'edge'; |
|
|
|
|
|
|
|
|
|
|
|
webrtcDetectedVersion = |
|
|
|
webrtcDetectedVersion = webrtcUtils.extractVersion(navigator.userAgent, |
|
|
|
parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10); |
|
|
|
/Edge\/(\d+).(\d+)$/, 2); |
|
|
|
|
|
|
|
|
|
|
|
// the minimum version still supported by adapter.
|
|
|
|
// the minimum version still supported by adapter.
|
|
|
|
webrtcMinimumVersion = 12; |
|
|
|
webrtcMinimumVersion = 12; |
|
|
|
|
|
|
|
|
|
|
|
getUserMedia = navigator.getUserMedia; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
attachMediaStream = function(element, stream) { |
|
|
|
|
|
|
|
element.srcObject = stream; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
reattachMediaStream = function(to, from) { |
|
|
|
|
|
|
|
to.srcObject = from.srcObject; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
webrtcUtils.log('Browser does not appear to be WebRTC-capable'); |
|
|
|
webrtcUtils.log('Browser does not appear to be WebRTC-capable'); |
|
|
|
} |
|
|
|
} |
|
|
@ -461,26 +520,35 @@ function requestUserMedia(constraints) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var webrtcTesting = {}; |
|
|
|
var webrtcTesting = {}; |
|
|
|
Object.defineProperty(webrtcTesting, 'version', { |
|
|
|
try { |
|
|
|
set: function(version) { |
|
|
|
Object.defineProperty(webrtcTesting, 'version', { |
|
|
|
webrtcDetectedVersion = version; |
|
|
|
set: function(version) { |
|
|
|
} |
|
|
|
webrtcDetectedVersion = version; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} catch (e) {} |
|
|
|
|
|
|
|
|
|
|
|
if (typeof module !== 'undefined') { |
|
|
|
if (typeof module !== 'undefined') { |
|
|
|
var RTCPeerConnection; |
|
|
|
var RTCPeerConnection; |
|
|
|
|
|
|
|
var RTCIceCandidate; |
|
|
|
|
|
|
|
var RTCSessionDescription; |
|
|
|
if (typeof window !== 'undefined') { |
|
|
|
if (typeof window !== 'undefined') { |
|
|
|
RTCPeerConnection = window.RTCPeerConnection; |
|
|
|
RTCPeerConnection = window.RTCPeerConnection; |
|
|
|
|
|
|
|
RTCIceCandidate = window.RTCIceCandidate; |
|
|
|
|
|
|
|
RTCSessionDescription = window.RTCSessionDescription; |
|
|
|
} |
|
|
|
} |
|
|
|
module.exports = { |
|
|
|
module.exports = { |
|
|
|
RTCPeerConnection: RTCPeerConnection, |
|
|
|
RTCPeerConnection: RTCPeerConnection, |
|
|
|
|
|
|
|
RTCIceCandidate: RTCIceCandidate, |
|
|
|
|
|
|
|
RTCSessionDescription: RTCSessionDescription, |
|
|
|
getUserMedia: getUserMedia, |
|
|
|
getUserMedia: getUserMedia, |
|
|
|
attachMediaStream: attachMediaStream, |
|
|
|
attachMediaStream: attachMediaStream, |
|
|
|
reattachMediaStream: reattachMediaStream, |
|
|
|
reattachMediaStream: reattachMediaStream, |
|
|
|
webrtcDetectedBrowser: webrtcDetectedBrowser, |
|
|
|
webrtcDetectedBrowser: webrtcDetectedBrowser, |
|
|
|
webrtcDetectedVersion: webrtcDetectedVersion, |
|
|
|
webrtcDetectedVersion: webrtcDetectedVersion, |
|
|
|
webrtcMinimumVersion: webrtcMinimumVersion, |
|
|
|
webrtcMinimumVersion: webrtcMinimumVersion, |
|
|
|
webrtcTesting: webrtcTesting |
|
|
|
webrtcTesting: webrtcTesting, |
|
|
|
|
|
|
|
webrtcUtils: webrtcUtils |
|
|
|
//requestUserMedia: not exposed on purpose.
|
|
|
|
//requestUserMedia: not exposed on purpose.
|
|
|
|
//trace: not exposed on purpose.
|
|
|
|
//trace: not exposed on purpose.
|
|
|
|
}; |
|
|
|
}; |
|
|
@ -489,13 +557,16 @@ if (typeof module !== 'undefined') { |
|
|
|
define([], function() { |
|
|
|
define([], function() { |
|
|
|
return { |
|
|
|
return { |
|
|
|
RTCPeerConnection: window.RTCPeerConnection, |
|
|
|
RTCPeerConnection: window.RTCPeerConnection, |
|
|
|
|
|
|
|
RTCIceCandidate: window.RTCIceCandidate, |
|
|
|
|
|
|
|
RTCSessionDescription: window.RTCSessionDescription, |
|
|
|
getUserMedia: getUserMedia, |
|
|
|
getUserMedia: getUserMedia, |
|
|
|
attachMediaStream: attachMediaStream, |
|
|
|
attachMediaStream: attachMediaStream, |
|
|
|
reattachMediaStream: reattachMediaStream, |
|
|
|
reattachMediaStream: reattachMediaStream, |
|
|
|
webrtcDetectedBrowser: webrtcDetectedBrowser, |
|
|
|
webrtcDetectedBrowser: webrtcDetectedBrowser, |
|
|
|
webrtcDetectedVersion: webrtcDetectedVersion, |
|
|
|
webrtcDetectedVersion: webrtcDetectedVersion, |
|
|
|
webrtcMinimumVersion: webrtcMinimumVersion, |
|
|
|
webrtcMinimumVersion: webrtcMinimumVersion, |
|
|
|
webrtcTesting: webrtcTesting |
|
|
|
webrtcTesting: webrtcTesting, |
|
|
|
|
|
|
|
webrtcUtils: webrtcUtils |
|
|
|
//requestUserMedia: not exposed on purpose.
|
|
|
|
//requestUserMedia: not exposed on purpose.
|
|
|
|
//trace: not exposed on purpose.
|
|
|
|
//trace: not exposed on purpose.
|
|
|
|
}; |
|
|
|
}; |
|
|
|