Created
October 4, 2016 15:49
-
-
Save igorpavlov-zz/4caaa8243e8ec6d6622bb52dde1b7a7d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! adapterjs - v0.14.0 - 2016-10-03 */ | |
var AdapterJS = AdapterJS || {}; | |
"undefined" != typeof exports && (module.exports = AdapterJS), AdapterJS.options = AdapterJS.options || {}, AdapterJS.VERSION = "0.14.0", AdapterJS.onwebrtcready = AdapterJS.onwebrtcready || function(isUsingPlugin) {}, AdapterJS._onwebrtcreadies = [], AdapterJS.webRTCReady = function(callback) { | |
if ("function" != typeof callback) throw new Error("Callback provided is not a function"); | |
!0 === AdapterJS.onwebrtcreadyDone ? callback(null !== AdapterJS.WebRTCPlugin.plugin) : AdapterJS._onwebrtcreadies.push(callback) | |
}, AdapterJS.WebRTCPlugin = AdapterJS.WebRTCPlugin || {}, AdapterJS.WebRTCPlugin.pluginInfo = AdapterJS.WebRTCPlugin.pluginInfo || { | |
prefix: "Tem", | |
plugName: "TemWebRTCPlugin", | |
pluginId: "plugin0", | |
type: "application/x-temwebrtcplugin", | |
onload: "__TemWebRTCReady0", | |
portalLink: "http://skylink.io/plugin/", | |
downloadLink: null, | |
companyName: "Temasys", | |
downloadLinks: { | |
mac: "http://bit.ly/webrtcpluginpkg", | |
win: "http://bit.ly/webrtcpluginmsi" | |
} | |
}, "undefined" != typeof AdapterJS.WebRTCPlugin.pluginInfo.downloadLinks && null !== AdapterJS.WebRTCPlugin.pluginInfo.downloadLinks && (navigator.platform.match(/^Mac/i) ? AdapterJS.WebRTCPlugin.pluginInfo.downloadLink = AdapterJS.WebRTCPlugin.pluginInfo.downloadLinks.mac : navigator.platform.match(/^Win/i) && (AdapterJS.WebRTCPlugin.pluginInfo.downloadLink = AdapterJS.WebRTCPlugin.pluginInfo.downloadLinks.win)), AdapterJS.WebRTCPlugin.TAGS = { | |
NONE: "none", | |
AUDIO: "audio", | |
VIDEO: "video" | |
}, AdapterJS.WebRTCPlugin.pageId = Math.random().toString(36).slice(2), AdapterJS.WebRTCPlugin.plugin = null, AdapterJS.WebRTCPlugin.setLogLevel = null, AdapterJS.WebRTCPlugin.defineWebRTCInterface = null, AdapterJS.WebRTCPlugin.isPluginInstalled = null, AdapterJS.WebRTCPlugin.pluginInjectionInterval = null, AdapterJS.WebRTCPlugin.injectPlugin = null, AdapterJS.WebRTCPlugin.PLUGIN_STATES = { | |
NONE: 0, | |
INITIALIZING: 1, | |
INJECTING: 2, | |
INJECTED: 3, | |
READY: 4 | |
}, AdapterJS.WebRTCPlugin.pluginState = AdapterJS.WebRTCPlugin.PLUGIN_STATES.NONE, AdapterJS.onwebrtcreadyDone = !1, AdapterJS.WebRTCPlugin.PLUGIN_LOG_LEVELS = { | |
NONE: "NONE", | |
ERROR: "ERROR", | |
WARNING: "WARNING", | |
INFO: "INFO", | |
VERBOSE: "VERBOSE", | |
SENSITIVE: "SENSITIVE" | |
}, AdapterJS.WebRTCPlugin.WaitForPluginReady = null, AdapterJS.WebRTCPlugin.callWhenPluginReady = null, __TemWebRTCReady0 = function() { | |
if ("complete" === document.readyState) AdapterJS.WebRTCPlugin.pluginState = AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY, AdapterJS.maybeThroughWebRTCReady(); | |
else var timer = setInterval(function() { | |
"complete" === document.readyState && (clearInterval(timer), AdapterJS.WebRTCPlugin.pluginState = AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY, AdapterJS.maybeThroughWebRTCReady()) | |
}, 100) | |
}, AdapterJS.maybeThroughWebRTCReady = function() { | |
AdapterJS.onwebrtcreadyDone || (AdapterJS.onwebrtcreadyDone = !0, AdapterJS._onwebrtcreadies.length ? AdapterJS._onwebrtcreadies.forEach(function(callback) { | |
"function" == typeof callback && callback(null !== AdapterJS.WebRTCPlugin.plugin) | |
}) : "function" == typeof AdapterJS.onwebrtcready && AdapterJS.onwebrtcready(null !== AdapterJS.WebRTCPlugin.plugin)) | |
}, AdapterJS.TEXT = { | |
PLUGIN: { | |
REQUIRE_INSTALLATION: "This website requires you to install a WebRTC-enabling plugin to work on this browser.", | |
NOT_SUPPORTED: "Your browser does not support WebRTC.", | |
BUTTON: "Install Now" | |
}, | |
REFRESH: { | |
REQUIRE_REFRESH: "Please refresh page", | |
BUTTON: "Refresh Page" | |
} | |
}, AdapterJS._iceConnectionStates = { | |
starting: "starting", | |
checking: "checking", | |
connected: "connected", | |
completed: "connected", | |
done: "completed", | |
disconnected: "disconnected", | |
failed: "failed", | |
closed: "closed" | |
}, AdapterJS._iceConnectionFiredStates = [], AdapterJS.isDefined = null, AdapterJS.parseWebrtcDetectedBrowser = function() { | |
var hasMatch = null; | |
if (window.opr && opr.addons || window.opera || navigator.userAgent.indexOf(" OPR/") >= 0) hasMatch = navigator.userAgent.match(/OPR\/(\d+)/i) || [], webrtcDetectedBrowser = "opera", webrtcDetectedVersion = parseInt(hasMatch[1] || "0", 10), webrtcMinimumVersion = 26, webrtcDetectedType = "webkit", webrtcDetectedDCSupport = "SCTP"; | |
else if (navigator.userAgent.match(/Bowser\/[0-9.]*/g)) { | |
hasMatch = navigator.userAgent.match(/Bowser\/[0-9.]*/g) || []; | |
var chromiumVersion = parseInt((navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./i) || [])[2] || "0", 10); | |
webrtcDetectedBrowser = "bowser", webrtcDetectedVersion = parseFloat((hasMatch[0] || "0/0").split("/")[1], 10), webrtcMinimumVersion = 0, webrtcDetectedType = "webkit", webrtcDetectedDCSupport = chromiumVersion > 30 ? "SCTP" : "RTP" | |
} else if (navigator.userAgent.indexOf("OPiOS") > 0) hasMatch = navigator.userAgent.match(/OPiOS\/([0-9]+)\./), webrtcDetectedBrowser = "opera", webrtcDetectedVersion = parseInt(hasMatch[1] || "0", 10), webrtcMinimumVersion = 0, webrtcDetectedType = null, webrtcDetectedDCSupport = null; | |
else if (navigator.userAgent.indexOf("CriOS") > 0) hasMatch = navigator.userAgent.match(/CriOS\/([0-9]+)\./) || [], webrtcDetectedBrowser = "chrome", webrtcDetectedVersion = parseInt(hasMatch[1] || "0", 10), webrtcMinimumVersion = 0, webrtcDetectedType = null, webrtcDetectedDCSupport = null; | |
else if (navigator.userAgent.indexOf("FxiOS") > 0) hasMatch = navigator.userAgent.match(/FxiOS\/([0-9]+)\./) || [], webrtcDetectedBrowser = "firefox", webrtcDetectedVersion = parseInt(hasMatch[1] || "0", 10), webrtcMinimumVersion = 0, webrtcDetectedType = null, webrtcDetectedDCSupport = null; | |
else if (document.documentMode) hasMatch = /\brv[ :]+(\d+)/g.exec(navigator.userAgent) || [], webrtcDetectedBrowser = "IE", webrtcDetectedVersion = parseInt(hasMatch[1], 10), webrtcMinimumVersion = 9, webrtcDetectedType = "plugin", webrtcDetectedDCSupport = "SCTP", webrtcDetectedVersion || (hasMatch = /\bMSIE[ :]+(\d+)/g.exec(navigator.userAgent) || [], webrtcDetectedVersion = parseInt(hasMatch[1] || "0", 10)); | |
else if (window.StyleMedia || navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)) hasMatch = navigator.userAgent.match(/Edge\/(\d+).(\d+)$/) || [], webrtcDetectedBrowser = "edge", webrtcDetectedVersion = parseFloat((hasMatch[0] || "0/0").split("/")[1], 10), webrtcMinimumVersion = 13.10547, webrtcDetectedType = "ms", webrtcDetectedDCSupport = null; | |
else if ("undefined" != typeof InstallTrigger || navigator.userAgent.indexOf("irefox") > 0) hasMatch = navigator.userAgent.match(/Firefox\/([0-9]+)\./) || [], webrtcDetectedBrowser = "firefox", webrtcDetectedVersion = parseInt(hasMatch[1] || "0", 10), webrtcMinimumVersion = 31, webrtcDetectedType = "moz", webrtcDetectedDCSupport = "SCTP"; | |
else if (window.chrome && window.chrome.webstore || navigator.userAgent.indexOf("Chrom") > 0) hasMatch = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./i) || [], webrtcDetectedBrowser = "chrome", webrtcDetectedVersion = parseInt(hasMatch[2] || "0", 10), webrtcMinimumVersion = 38, webrtcDetectedType = "webkit", webrtcDetectedDCSupport = webrtcDetectedVersion > 30 ? "SCTP" : "RTP"; | |
else if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { | |
hasMatch = navigator.userAgent.match(/version\/(\d+)/i) || []; | |
var isMobile = navigator.userAgent.match(/(iPhone|iPad)/gi) || []; | |
webrtcDetectedBrowser = "safari", webrtcDetectedVersion = parseInt(hasMatch[1] || "0", 10), webrtcMinimumVersion = 7, webrtcDetectedType = 0 === isMobile.length ? "plugin" : null, webrtcDetectedDCSupport = 0 === isMobile.length ? "SCTP" : null | |
} | |
window.webrtcDetectedBrowser = webrtcDetectedBrowser, window.webrtcDetectedVersion = webrtcDetectedVersion, window.webrtcMinimumVersion = webrtcMinimumVersion, window.webrtcDetectedType = webrtcDetectedType, window.webrtcDetectedDCSupport = webrtcDetectedDCSupport | |
}, AdapterJS.addEvent = function(elem, evnt, func) { | |
elem.addEventListener ? elem.addEventListener(evnt, func, !1) : elem.attachEvent ? elem.attachEvent("on" + evnt, func) : elem[evnt] = func | |
}, AdapterJS.renderNotificationBar = function(text, buttonText, buttonLink, openNewTab, displayRefreshBar) { | |
if ("complete" === document.readyState) { | |
var w = window, | |
i = document.createElement("iframe"); | |
i.name = "adapterjs-alert", i.style.position = "fixed", i.style.top = "-41px", i.style.left = 0, i.style.right = 0, i.style.width = "100%", i.style.height = "40px", i.style.backgroundColor = "#ffffe1", i.style.border = "none", i.style.borderBottom = "1px solid #888888", i.style.zIndex = "9999999", "string" == typeof i.style.webkitTransition ? i.style.webkitTransition = "all .5s ease-out" : "string" == typeof i.style.transition && (i.style.transition = "all .5s ease-out"), document.body.appendChild(i); | |
var c = i.contentWindow ? i.contentWindow : i.contentDocument.document ? i.contentDocument.document : i.contentDocument; | |
c.document.open(), c.document.write('<span style="display: inline-block; font-family: Helvetica, Arial,sans-serif; font-size: .9rem; padding: 4px; vertical-align: middle; cursor: default;">' + text + "</span>"), buttonText && buttonLink ? (c.document.write('<button id="okay">' + buttonText + '</button><button id="cancel">Cancel</button>'), c.document.close(), AdapterJS.addEvent(c.document.getElementById("okay"), "click", function(e) { | |
displayRefreshBar && AdapterJS.renderNotificationBar(AdapterJS.TEXT.EXTENSION ? AdapterJS.TEXT.EXTENSION.REQUIRE_REFRESH : AdapterJS.TEXT.REFRESH.REQUIRE_REFRESH, AdapterJS.TEXT.REFRESH.BUTTON, "javascript:location.reload()"), window.open(buttonLink, openNewTab ? "_blank" : "_top"), e.preventDefault(); | |
try { | |
e.cancelBubble = !0 | |
} catch (error) {} | |
var pluginInstallInterval = setInterval(function() { | |
isIE || navigator.plugins.refresh(!1), AdapterJS.WebRTCPlugin.isPluginInstalled(AdapterJS.WebRTCPlugin.pluginInfo.prefix, AdapterJS.WebRTCPlugin.pluginInfo.plugName, AdapterJS.WebRTCPlugin.pluginInfo.type, function() { | |
clearInterval(pluginInstallInterval), AdapterJS.WebRTCPlugin.defineWebRTCInterface() | |
}, function() {}) | |
}, 500) | |
}), AdapterJS.addEvent(c.document.getElementById("cancel"), "click", function(e) { | |
w.document.body.removeChild(i) | |
})) : c.document.close(), setTimeout(function() { | |
"string" == typeof i.style.webkitTransform ? i.style.webkitTransform = "translateY(40px)" : "string" == typeof i.style.transform ? i.style.transform = "translateY(40px)" : i.style.top = "0px" | |
}, 300) | |
} | |
}, webrtcDetectedType = null, checkMediaDataChannelSettings = function(peerBrowserAgent, peerBrowserVersion, callback, constraints) { | |
if ("function" == typeof callback) { | |
var beOfferer = !0, | |
isLocalFirefox = "firefox" === webrtcDetectedBrowser, | |
isLocalFirefoxInterop = "moz" === webrtcDetectedType && webrtcDetectedVersion > 30, | |
isPeerFirefox = "firefox" === peerBrowserAgent; | |
if (isLocalFirefox && isPeerFirefox || isLocalFirefoxInterop) try { | |
delete constraints.mandatory.MozDontOfferDataChannel | |
} catch (error) {} else isLocalFirefox && !isPeerFirefox && (constraints.mandatory.MozDontOfferDataChannel = !0); | |
if (!isLocalFirefox) | |
for (var prop in constraints.mandatory) constraints.mandatory.hasOwnProperty(prop) && prop.indexOf("Moz") !== -1 && delete constraints.mandatory[prop]; | |
!isLocalFirefox || isPeerFirefox || isLocalFirefoxInterop || (beOfferer = !1), callback(beOfferer, constraints) | |
} | |
}, checkIceConnectionState = function(peerId, iceConnectionState, callback) { | |
"function" == typeof callback && (peerId = peerId ? peerId : "peer", AdapterJS._iceConnectionFiredStates[peerId] && iceConnectionState !== AdapterJS._iceConnectionStates.disconnected && iceConnectionState !== AdapterJS._iceConnectionStates.failed && iceConnectionState !== AdapterJS._iceConnectionStates.closed || (AdapterJS._iceConnectionFiredStates[peerId] = []), iceConnectionState = AdapterJS._iceConnectionStates[iceConnectionState], AdapterJS._iceConnectionFiredStates[peerId].indexOf(iceConnectionState) < 0 && (AdapterJS._iceConnectionFiredStates[peerId].push(iceConnectionState), iceConnectionState === AdapterJS._iceConnectionStates.connected && setTimeout(function() { | |
AdapterJS._iceConnectionFiredStates[peerId].push(AdapterJS._iceConnectionStates.done), callback(AdapterJS._iceConnectionStates.done) | |
}, 1e3), callback(iceConnectionState))) | |
}, createIceServer = null, createIceServers = null, RTCPeerConnection = null, RTCSessionDescription = "function" == typeof RTCSessionDescription ? RTCSessionDescription : null, RTCIceCandidate = "function" == typeof RTCIceCandidate ? RTCIceCandidate : null, getUserMedia = null, attachMediaStream = null, reattachMediaStream = null, webrtcDetectedBrowser = null, webrtcDetectedVersion = null, webrtcMinimumVersion = null, !(navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.mediaDevices && navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)) || 0 === (navigator.userAgent.match(/android/gi) || []).length && 0 === (navigator.userAgent.match(/chrome/gi) || []).length && navigator.userAgent.indexOf("Safari/") > 0 ? ("object" == typeof console && "function" == typeof console.log || (console = {} || console, console.log = function(arg) {}, console.info = function(arg) {}, console.error = function(arg) {}, console.dir = function(arg) {}, console.exception = function(arg) {}, console.trace = function(arg) {}, console.warn = function(arg) {}, console.count = function(arg) {}, console.debug = function(arg) {}, console.count = function(arg) {}, console.time = function(arg) {}, console.timeEnd = function(arg) {}, console.group = function(arg) {}, console.groupCollapsed = function(arg) {}, console.groupEnd = function(arg) {}), AdapterJS.parseWebrtcDetectedBrowser(), isIE = "IE" === webrtcDetectedBrowser, AdapterJS.WebRTCPlugin.WaitForPluginReady = function() { | |
for (; AdapterJS.WebRTCPlugin.pluginState !== AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY;); | |
}, AdapterJS.WebRTCPlugin.callWhenPluginReady = function(callback) { | |
if (AdapterJS.WebRTCPlugin.pluginState === AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY) callback(); | |
else var checkPluginReadyState = setInterval(function() { | |
AdapterJS.WebRTCPlugin.pluginState === AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY && (clearInterval(checkPluginReadyState), callback()) | |
}, 100) | |
}, AdapterJS.WebRTCPlugin.setLogLevel = function(logLevel) { | |
AdapterJS.WebRTCPlugin.callWhenPluginReady(function() { | |
AdapterJS.WebRTCPlugin.plugin.setLogLevel(logLevel) | |
}) | |
}, AdapterJS.WebRTCPlugin.injectPlugin = function() { | |
if ("complete" === document.readyState && AdapterJS.WebRTCPlugin.pluginState === AdapterJS.WebRTCPlugin.PLUGIN_STATES.INITIALIZING) { | |
if (AdapterJS.WebRTCPlugin.pluginState = AdapterJS.WebRTCPlugin.PLUGIN_STATES.INJECTING, "IE" === webrtcDetectedBrowser && webrtcDetectedVersion <= 10) { | |
var frag = document.createDocumentFragment(); | |
for (AdapterJS.WebRTCPlugin.plugin = document.createElement("div"), AdapterJS.WebRTCPlugin.plugin.innerHTML = '<object id="' + AdapterJS.WebRTCPlugin.pluginInfo.pluginId + '" type="' + AdapterJS.WebRTCPlugin.pluginInfo.type + '" width="1" height="1"><param name="pluginId" value="' + AdapterJS.WebRTCPlugin.pluginInfo.pluginId + '" /> <param name="windowless" value="false" /> <param name="pageId" value="' + AdapterJS.WebRTCPlugin.pageId + '" /> <param name="onload" value="' + AdapterJS.WebRTCPlugin.pluginInfo.onload + '" /><param name="tag" value="' + AdapterJS.WebRTCPlugin.TAGS.NONE + '" />' + (AdapterJS.options.getAllCams ? '<param name="forceGetAllCams" value="True" />' : "") + "</object>"; AdapterJS.WebRTCPlugin.plugin.firstChild;) frag.appendChild(AdapterJS.WebRTCPlugin.plugin.firstChild); | |
document.body.appendChild(frag), AdapterJS.WebRTCPlugin.plugin = document.getElementById(AdapterJS.WebRTCPlugin.pluginInfo.pluginId) | |
} else AdapterJS.WebRTCPlugin.plugin = document.createElement("object"), AdapterJS.WebRTCPlugin.plugin.id = AdapterJS.WebRTCPlugin.pluginInfo.pluginId, isIE ? (AdapterJS.WebRTCPlugin.plugin.width = "1px", AdapterJS.WebRTCPlugin.plugin.height = "1px") : (AdapterJS.WebRTCPlugin.plugin.width = "0px", AdapterJS.WebRTCPlugin.plugin.height = "0px"), AdapterJS.WebRTCPlugin.plugin.type = AdapterJS.WebRTCPlugin.pluginInfo.type, AdapterJS.WebRTCPlugin.plugin.innerHTML = '<param name="onload" value="' + AdapterJS.WebRTCPlugin.pluginInfo.onload + '"><param name="pluginId" value="' + AdapterJS.WebRTCPlugin.pluginInfo.pluginId + '"><param name="windowless" value="false" /> ' + (AdapterJS.options.getAllCams ? '<param name="forceGetAllCams" value="True" />' : "") + '<param name="pageId" value="' + AdapterJS.WebRTCPlugin.pageId + '"><param name="tag" value="' + AdapterJS.WebRTCPlugin.TAGS.NONE + '" />', document.body.appendChild(AdapterJS.WebRTCPlugin.plugin); | |
AdapterJS.WebRTCPlugin.pluginState = AdapterJS.WebRTCPlugin.PLUGIN_STATES.INJECTED | |
} | |
}, AdapterJS.WebRTCPlugin.isPluginInstalled = function(comName, plugName, plugType, installedCb, notInstalledCb) { | |
if (isIE) { | |
try { | |
new ActiveXObject(comName + "." + plugName) | |
} catch (e) { | |
return void notInstalledCb() | |
} | |
installedCb() | |
} else { | |
for (var pluginArray = navigator.mimeTypes, i = 0; i < pluginArray.length; i++) | |
if (pluginArray[i].type.indexOf(plugType) >= 0) return void installedCb(); | |
notInstalledCb() | |
} | |
}, AdapterJS.WebRTCPlugin.defineWebRTCInterface = function() { | |
if (AdapterJS.WebRTCPlugin.pluginState !== AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY) { | |
AdapterJS.WebRTCPlugin.pluginState = AdapterJS.WebRTCPlugin.PLUGIN_STATES.INITIALIZING, AdapterJS.isDefined = function(variable) { | |
return null !== variable && void 0 !== variable | |
}, createIceServer = function(url, username, password) { | |
var iceServer = null, | |
urlParts = url.split(":"); | |
return 0 === urlParts[0].indexOf("stun") ? iceServer = { | |
url: url, | |
hasCredentials: !1 | |
} : 0 === urlParts[0].indexOf("turn") && (iceServer = { | |
url: url, | |
hasCredentials: !0, | |
credential: password, | |
username: username | |
}), iceServer | |
}, createIceServers = function(urls, username, password) { | |
for (var iceServers = [], i = 0; i < urls.length; ++i) iceServers.push(createIceServer(urls[i], username, password)); | |
return iceServers | |
}, RTCSessionDescription = function(info) { | |
return AdapterJS.WebRTCPlugin.WaitForPluginReady(), AdapterJS.WebRTCPlugin.plugin.ConstructSessionDescription(info.type, info.sdp) | |
}, RTCPeerConnection = function(servers, constraints) { | |
if (void 0 !== servers && null !== servers && !Array.isArray(servers.iceServers)) throw new Error("Failed to construct 'RTCPeerConnection': Malformed RTCConfiguration"); | |
if ("undefined" != typeof constraints && null !== constraints) { | |
var invalidConstraits = !1; | |
if (invalidConstraits |= "object" != typeof constraints, invalidConstraits |= constraints.hasOwnProperty("mandatory") && void 0 !== constraints.mandatory && null !== constraints.mandatory && constraints.mandatory.constructor !== Object, invalidConstraits |= constraints.hasOwnProperty("optional") && void 0 !== constraints.optional && null !== constraints.optional && !Array.isArray(constraints.optional)) throw new Error("Failed to construct 'RTCPeerConnection': Malformed constraints object") | |
} | |
AdapterJS.WebRTCPlugin.WaitForPluginReady(); | |
var iceServers = null; | |
if (servers && Array.isArray(servers.iceServers)) { | |
iceServers = servers.iceServers; | |
for (var i = 0; i < iceServers.length; i++) iceServers[i].urls && !iceServers[i].url && (iceServers[i].url = iceServers[i].urls), iceServers[i].hasCredentials = AdapterJS.isDefined(iceServers[i].username) && AdapterJS.isDefined(iceServers[i].credential) | |
} | |
if (AdapterJS.WebRTCPlugin.plugin.PEER_CONNECTION_VERSION && AdapterJS.WebRTCPlugin.plugin.PEER_CONNECTION_VERSION > 1) return iceServers && (servers.iceServers = iceServers), AdapterJS.WebRTCPlugin.plugin.PeerConnection(servers); | |
var mandatory = constraints && constraints.mandatory ? constraints.mandatory : null, | |
optional = constraints && constraints.optional ? constraints.optional : null; | |
return AdapterJS.WebRTCPlugin.plugin.PeerConnection(AdapterJS.WebRTCPlugin.pageId, iceServers, mandatory, optional) | |
}, MediaStreamTrack = function() {}, MediaStreamTrack.getSources = function(callback) { | |
AdapterJS.WebRTCPlugin.callWhenPluginReady(function() { | |
AdapterJS.WebRTCPlugin.plugin.GetSources(callback) | |
}) | |
}; | |
var constraintsToPlugin = function(c) { | |
if ("object" != typeof c || c.mandatory || c.optional) return c; | |
var cc = {}; | |
return Object.keys(c).forEach(function(key) { | |
if ("require" !== key && "advanced" !== key && "mediaSource" !== key) { | |
var r = "object" == typeof c[key] ? c[key] : { | |
ideal: c[key] | |
}; | |
void 0 !== r.exact && "number" == typeof r.exact && (r.min = r.max = r.exact); | |
var oldname = function(prefix, name) { | |
return prefix ? prefix + name.charAt(0).toUpperCase() + name.slice(1) : "deviceId" === name ? "sourceId" : name | |
}; | |
if (void 0 !== r.ideal) { | |
cc.optional = cc.optional || []; | |
var oc = {}; | |
"number" == typeof r.ideal ? (oc[oldname("min", key)] = r.ideal, cc.optional.push(oc), oc = {}, oc[oldname("max", key)] = r.ideal, cc.optional.push(oc)) : (oc[oldname("", key)] = r.ideal, cc.optional.push(oc)) | |
} | |
void 0 !== r.exact && "number" != typeof r.exact ? (cc.mandatory = cc.mandatory || {}, cc.mandatory[oldname("", key)] = r.exact) : ["min", "max"].forEach(function(mix) { | |
void 0 !== r[mix] && (cc.mandatory = cc.mandatory || {}, cc.mandatory[oldname(mix, key)] = r[mix]) | |
}) | |
} | |
}), c.advanced && (cc.optional = (cc.optional || []).concat(c.advanced)), cc | |
}; | |
getUserMedia = function(constraints, successCallback, failureCallback) { | |
var cc = {}; | |
cc.audio = !!constraints.audio && constraintsToPlugin(constraints.audio), cc.video = !!constraints.video && constraintsToPlugin(constraints.video), AdapterJS.WebRTCPlugin.callWhenPluginReady(function() { | |
AdapterJS.WebRTCPlugin.plugin.getUserMedia(cc, successCallback, failureCallback) | |
}) | |
}, window.navigator.getUserMedia = getUserMedia, navigator.mediaDevices || "undefined" == typeof Promise || (requestUserMedia = function(constraints) { | |
return new Promise(function(resolve, reject) { | |
getUserMedia(constraints, resolve, reject) | |
}) | |
}, navigator.mediaDevices = { | |
getUserMedia: requestUserMedia, | |
enumerateDevices: function() { | |
return new Promise(function(resolve) { | |
var kinds = { | |
audio: "audioinput", | |
video: "videoinput" | |
}; | |
return MediaStreamTrack.getSources(function(devices) { | |
resolve(devices.map(function(device) { | |
return { | |
label: device.label, | |
kind: kinds[device.kind], | |
id: device.id, | |
deviceId: device.id, | |
groupId: "" | |
} | |
})) | |
}) | |
}) | |
} | |
}), attachMediaStream = function(element, stream) { | |
if (element && element.parentNode) { | |
var streamId; | |
null === stream ? streamId = "" : ("undefined" != typeof stream.enableSoundTracks && stream.enableSoundTracks(!0), streamId = stream.id); | |
var elementId = 0 === element.id.length ? Math.random().toString(36).slice(2) : element.id, | |
nodeName = element.nodeName.toLowerCase(); | |
if ("object" !== nodeName) { | |
var tag; | |
switch (nodeName) { | |
case "audio": | |
tag = AdapterJS.WebRTCPlugin.TAGS.AUDIO; | |
break; | |
case "video": | |
tag = AdapterJS.WebRTCPlugin.TAGS.VIDEO; | |
break; | |
default: | |
tag = AdapterJS.WebRTCPlugin.TAGS.NONE | |
} | |
var frag = document.createDocumentFragment(), | |
temp = document.createElement("div"), | |
classHTML = ""; | |
for (element.className ? classHTML = 'class="' + element.className + '" ' : element.attributes && element.attributes.class && (classHTML = 'class="' + element.attributes.class.value + '" '), temp.innerHTML = '<object id="' + elementId + '" ' + classHTML + 'type="' + AdapterJS.WebRTCPlugin.pluginInfo.type + '"><param name="pluginId" value="' + elementId + '" /> <param name="pageId" value="' + AdapterJS.WebRTCPlugin.pageId + '" /> <param name="windowless" value="true" /> <param name="streamId" value="' + streamId + '" /> <param name="tag" value="' + tag + '" /> </object>'; temp.firstChild;) frag.appendChild(temp.firstChild); | |
var height = "", | |
width = ""; | |
element.clientWidth || element.clientHeight ? (width = element.clientWidth, height = element.clientHeight) : (element.width || element.height) && (width = element.width, height = element.height), element.parentNode.insertBefore(frag, element), frag = document.getElementById(elementId), frag.width = width, frag.height = height, element.parentNode.removeChild(element) | |
} else { | |
for (var children = element.children, i = 0; i !== children.length; ++i) | |
if ("streamId" === children[i].name) { | |
children[i].value = streamId; | |
break | |
} | |
element.setStreamId(streamId) | |
} | |
var newElement = document.getElementById(elementId); | |
return AdapterJS.forwardEventHandlers(newElement, element, Object.getPrototypeOf(element)), newElement | |
} | |
}, reattachMediaStream = function(to, from) { | |
for (var stream = null, children = from.children, i = 0; i !== children.length; ++i) | |
if ("streamId" === children[i].name) { | |
AdapterJS.WebRTCPlugin.WaitForPluginReady(), stream = AdapterJS.WebRTCPlugin.plugin.getStreamWithId(AdapterJS.WebRTCPlugin.pageId, children[i].value); | |
break | |
} | |
if (null !== stream) return attachMediaStream(to, stream) | |
}, window.attachMediaStream = attachMediaStream, window.reattachMediaStream = reattachMediaStream, window.getUserMedia = getUserMedia, AdapterJS.attachMediaStream = attachMediaStream, AdapterJS.reattachMediaStream = reattachMediaStream, AdapterJS.getUserMedia = getUserMedia, AdapterJS.forwardEventHandlers = function(destElem, srcElem, prototype) { | |
properties = Object.getOwnPropertyNames(prototype); | |
for (var prop in properties) prop && (propName = properties[prop], "function" == typeof propName.slice && "on" === propName.slice(0, 2) && "function" == typeof srcElem[propName] && AdapterJS.addEvent(destElem, propName.slice(2), srcElem[propName])); | |
var subPrototype = Object.getPrototypeOf(prototype); | |
subPrototype && AdapterJS.forwardEventHandlers(destElem, srcElem, subPrototype) | |
}, RTCIceCandidate = function(candidate) { | |
return candidate.sdpMid || (candidate.sdpMid = ""), AdapterJS.WebRTCPlugin.WaitForPluginReady(), AdapterJS.WebRTCPlugin.plugin.ConstructIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.candidate) | |
}, AdapterJS.addEvent(document, "readystatechange", AdapterJS.WebRTCPlugin.injectPlugin), AdapterJS.WebRTCPlugin.injectPlugin() | |
} | |
}, AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCb = AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCb || function() { | |
AdapterJS.addEvent(document, "readystatechange", AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCbPriv), AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCbPriv() | |
}, AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCbPriv = function() { | |
if (!AdapterJS.options.hidePluginInstallPrompt) { | |
var downloadLink = AdapterJS.WebRTCPlugin.pluginInfo.downloadLink; | |
if (downloadLink) { | |
var popupString; | |
popupString = AdapterJS.WebRTCPlugin.pluginInfo.portalLink ? 'This website requires you to install the <a href="' + AdapterJS.WebRTCPlugin.pluginInfo.portalLink + '" target="_blank">' + AdapterJS.WebRTCPlugin.pluginInfo.companyName + " WebRTC Plugin</a> to work on this browser." : AdapterJS.TEXT.PLUGIN.REQUIRE_INSTALLATION, AdapterJS.renderNotificationBar(popupString, AdapterJS.TEXT.PLUGIN.BUTTON, downloadLink) | |
} else AdapterJS.renderNotificationBar(AdapterJS.TEXT.PLUGIN.NOT_SUPPORTED) | |
} | |
}, AdapterJS.WebRTCPlugin.isPluginInstalled(AdapterJS.WebRTCPlugin.pluginInfo.prefix, AdapterJS.WebRTCPlugin.pluginInfo.plugName, AdapterJS.WebRTCPlugin.pluginInfo.type, AdapterJS.WebRTCPlugin.defineWebRTCInterface, AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCb)) : (! function(f) { | |
if ("object" == typeof exports && "undefined" != typeof module) module.exports = f(); | |
else if ("function" == typeof define && define.amd) define([], f); | |
else { | |
var g; | |
g = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this, g.adapter = f() | |
} | |
}(function() { | |
return function e(t, n, r) { | |
function s(o, u) { | |
if (!n[o]) { | |
if (!t[o]) { | |
var a = "function" == typeof require && require; | |
if (!u && a) return a(o, !0); | |
if (i) return i(o, !0); | |
var f = new Error("Cannot find module '" + o + "'"); | |
throw f.code = "MODULE_NOT_FOUND", f | |
} | |
var l = n[o] = { | |
exports: {} | |
}; | |
t[o][0].call(l.exports, function(e) { | |
var n = t[o][1][e]; | |
return s(n ? n : e) | |
}, l, l.exports, e, t, n, r) | |
} | |
return n[o].exports | |
} | |
for (var i = "function" == typeof require && require, o = 0; o < r.length; o++) s(r[o]); | |
return s | |
}({ | |
1: [function(require, module, exports) { | |
"use strict"; | |
var SDPUtils = {}; | |
SDPUtils.generateIdentifier = function() { | |
return Math.random().toString(36).substr(2, 10) | |
}, SDPUtils.localCName = SDPUtils.generateIdentifier(), SDPUtils.splitLines = function(blob) { | |
return blob.trim().split("\n").map(function(line) { | |
return line.trim() | |
}) | |
}, SDPUtils.splitSections = function(blob) { | |
var parts = blob.split("\nm="); | |
return parts.map(function(part, index) { | |
return (index > 0 ? "m=" + part : part).trim() + "\r\n" | |
}) | |
}, SDPUtils.matchPrefix = function(blob, prefix) { | |
return SDPUtils.splitLines(blob).filter(function(line) { | |
return 0 === line.indexOf(prefix) | |
}) | |
}, SDPUtils.parseCandidate = function(line) { | |
var parts; | |
parts = 0 === line.indexOf("a=candidate:") ? line.substring(12).split(" ") : line.substring(10).split(" "); | |
for (var candidate = { | |
foundation: parts[0], | |
component: parts[1], | |
protocol: parts[2].toLowerCase(), | |
priority: parseInt(parts[3], 10), | |
ip: parts[4], | |
port: parseInt(parts[5], 10), | |
type: parts[7] | |
}, i = 8; i < parts.length; i += 2) switch (parts[i]) { | |
case "raddr": | |
candidate.relatedAddress = parts[i + 1]; | |
break; | |
case "rport": | |
candidate.relatedPort = parseInt(parts[i + 1], 10); | |
break; | |
case "tcptype": | |
candidate.tcpType = parts[i + 1] | |
} | |
return candidate | |
}, SDPUtils.writeCandidate = function(candidate) { | |
var sdp = []; | |
sdp.push(candidate.foundation), sdp.push(candidate.component), sdp.push(candidate.protocol.toUpperCase()), sdp.push(candidate.priority), sdp.push(candidate.ip), sdp.push(candidate.port); | |
var type = candidate.type; | |
return sdp.push("typ"), sdp.push(type), "host" !== type && candidate.relatedAddress && candidate.relatedPort && (sdp.push("raddr"), sdp.push(candidate.relatedAddress), sdp.push("rport"), sdp.push(candidate.relatedPort)), candidate.tcpType && "tcp" === candidate.protocol.toLowerCase() && (sdp.push("tcptype"), sdp.push(candidate.tcpType)), "candidate:" + sdp.join(" ") | |
}, SDPUtils.parseRtpMap = function(line) { | |
var parts = line.substr(9).split(" "), | |
parsed = { | |
payloadType: parseInt(parts.shift(), 10) | |
}; | |
return parts = parts[0].split("/"), parsed.name = parts[0], parsed.clockRate = parseInt(parts[1], 10), parsed.numChannels = 3 === parts.length ? parseInt(parts[2], 10) : 1, parsed | |
}, SDPUtils.writeRtpMap = function(codec) { | |
var pt = codec.payloadType; | |
return void 0 !== codec.preferredPayloadType && (pt = codec.preferredPayloadType), "a=rtpmap:" + pt + " " + codec.name + "/" + codec.clockRate + (1 !== codec.numChannels ? "/" + codec.numChannels : "") + "\r\n" | |
}, SDPUtils.parseExtmap = function(line) { | |
var parts = line.substr(9).split(" "); | |
return { | |
id: parseInt(parts[0], 10), | |
uri: parts[1] | |
} | |
}, SDPUtils.writeExtmap = function(headerExtension) { | |
return "a=extmap:" + (headerExtension.id || headerExtension.preferredId) + " " + headerExtension.uri + "\r\n" | |
}, SDPUtils.parseFmtp = function(line) { | |
for (var kv, parsed = {}, parts = line.substr(line.indexOf(" ") + 1).split(";"), j = 0; j < parts.length; j++) kv = parts[j].trim().split("="), parsed[kv[0].trim()] = kv[1]; | |
return parsed | |
}, SDPUtils.writeFmtp = function(codec) { | |
var line = "", | |
pt = codec.payloadType; | |
if (void 0 !== codec.preferredPayloadType && (pt = codec.preferredPayloadType), codec.parameters && Object.keys(codec.parameters).length) { | |
var params = []; | |
Object.keys(codec.parameters).forEach(function(param) { | |
params.push(param + "=" + codec.parameters[param]) | |
}), line += "a=fmtp:" + pt + " " + params.join(";") + "\r\n" | |
} | |
return line | |
}, SDPUtils.parseRtcpFb = function(line) { | |
var parts = line.substr(line.indexOf(" ") + 1).split(" "); | |
return { | |
type: parts.shift(), | |
parameter: parts.join(" ") | |
} | |
}, SDPUtils.writeRtcpFb = function(codec) { | |
var lines = "", | |
pt = codec.payloadType; | |
return void 0 !== codec.preferredPayloadType && (pt = codec.preferredPayloadType), codec.rtcpFeedback && codec.rtcpFeedback.length && codec.rtcpFeedback.forEach(function(fb) { | |
lines += "a=rtcp-fb:" + pt + " " + fb.type + (fb.parameter && fb.parameter.length ? " " + fb.parameter : "") + "\r\n" | |
}), lines | |
}, SDPUtils.parseSsrcMedia = function(line) { | |
var sp = line.indexOf(" "), | |
parts = { | |
ssrc: parseInt(line.substr(7, sp - 7), 10) | |
}, | |
colon = line.indexOf(":", sp); | |
return colon > -1 ? (parts.attribute = line.substr(sp + 1, colon - sp - 1), parts.value = line.substr(colon + 1)) : parts.attribute = line.substr(sp + 1), parts | |
}, SDPUtils.getDtlsParameters = function(mediaSection, sessionpart) { | |
var lines = SDPUtils.splitLines(mediaSection); | |
lines = lines.concat(SDPUtils.splitLines(sessionpart)); | |
var fpLine = lines.filter(function(line) { | |
return 0 === line.indexOf("a=fingerprint:") | |
})[0].substr(14), | |
dtlsParameters = { | |
role: "auto", | |
fingerprints: [{ | |
algorithm: fpLine.split(" ")[0], | |
value: fpLine.split(" ")[1] | |
}] | |
}; | |
return dtlsParameters | |
}, SDPUtils.writeDtlsParameters = function(params, setupType) { | |
var sdp = "a=setup:" + setupType + "\r\n"; | |
return params.fingerprints.forEach(function(fp) { | |
sdp += "a=fingerprint:" + fp.algorithm + " " + fp.value + "\r\n" | |
}), sdp | |
}, SDPUtils.getIceParameters = function(mediaSection, sessionpart) { | |
var lines = SDPUtils.splitLines(mediaSection); | |
lines = lines.concat(SDPUtils.splitLines(sessionpart)); | |
var iceParameters = { | |
usernameFragment: lines.filter(function(line) { | |
return 0 === line.indexOf("a=ice-ufrag:") | |
})[0].substr(12), | |
password: lines.filter(function(line) { | |
return 0 === line.indexOf("a=ice-pwd:") | |
})[0].substr(10) | |
}; | |
return iceParameters | |
}, SDPUtils.writeIceParameters = function(params) { | |
return "a=ice-ufrag:" + params.usernameFragment + "\r\na=ice-pwd:" + params.password + "\r\n" | |
}, SDPUtils.parseRtpParameters = function(mediaSection) { | |
for (var description = { | |
codecs: [], | |
headerExtensions: [], | |
fecMechanisms: [], | |
rtcp: [] | |
}, lines = SDPUtils.splitLines(mediaSection), mline = lines[0].split(" "), i = 3; i < mline.length; i++) { | |
var pt = mline[i], | |
rtpmapline = SDPUtils.matchPrefix(mediaSection, "a=rtpmap:" + pt + " ")[0]; | |
if (rtpmapline) { | |
var codec = SDPUtils.parseRtpMap(rtpmapline), | |
fmtps = SDPUtils.matchPrefix(mediaSection, "a=fmtp:" + pt + " "); | |
switch (codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {}, codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, "a=rtcp-fb:" + pt + " ").map(SDPUtils.parseRtcpFb), description.codecs.push(codec), codec.name.toUpperCase()) { | |
case "RED": | |
case "ULPFEC": | |
description.fecMechanisms.push(codec.name.toUpperCase()) | |
} | |
} | |
} | |
return SDPUtils.matchPrefix(mediaSection, "a=extmap:").forEach(function(line) { | |
description.headerExtensions.push(SDPUtils.parseExtmap(line)) | |
}), description | |
}, SDPUtils.writeRtpDescription = function(kind, caps) { | |
var sdp = ""; | |
return sdp += "m=" + kind + " ", sdp += caps.codecs.length > 0 ? "9" : "0", sdp += " UDP/TLS/RTP/SAVPF ", sdp += caps.codecs.map(function(codec) { | |
return void 0 !== codec.preferredPayloadType ? codec.preferredPayloadType : codec.payloadType | |
}).join(" ") + "\r\n", sdp += "c=IN IP4 0.0.0.0\r\n", sdp += "a=rtcp:9 IN IP4 0.0.0.0\r\n", caps.codecs.forEach(function(codec) { | |
sdp += SDPUtils.writeRtpMap(codec), sdp += SDPUtils.writeFmtp(codec), sdp += SDPUtils.writeRtcpFb(codec) | |
}), sdp += "a=rtcp-mux\r\n" | |
}, SDPUtils.parseRtpEncodingParameters = function(mediaSection) { | |
var secondarySsrc, encodingParameters = [], | |
description = SDPUtils.parseRtpParameters(mediaSection), | |
hasRed = description.fecMechanisms.indexOf("RED") !== -1, | |
hasUlpfec = description.fecMechanisms.indexOf("ULPFEC") !== -1, | |
ssrcs = SDPUtils.matchPrefix(mediaSection, "a=ssrc:").map(function(line) { | |
return SDPUtils.parseSsrcMedia(line) | |
}).filter(function(parts) { | |
return "cname" === parts.attribute | |
}), | |
primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc, | |
flows = SDPUtils.matchPrefix(mediaSection, "a=ssrc-group:FID").map(function(line) { | |
var parts = line.split(" "); | |
return parts.shift(), parts.map(function(part) { | |
return parseInt(part, 10) | |
}) | |
}); | |
flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc && (secondarySsrc = flows[0][1]), description.codecs.forEach(function(codec) { | |
if ("RTX" === codec.name.toUpperCase() && codec.parameters.apt) { | |
var encParam = { | |
ssrc: primarySsrc, | |
codecPayloadType: parseInt(codec.parameters.apt, 10), | |
rtx: { | |
payloadType: codec.payloadType, | |
ssrc: secondarySsrc | |
} | |
}; | |
encodingParameters.push(encParam), hasRed && (encParam = JSON.parse(JSON.stringify(encParam)), encParam.fec = { | |
ssrc: secondarySsrc, | |
mechanism: hasUlpfec ? "red+ulpfec" : "red" | |
}, encodingParameters.push(encParam)) | |
} | |
}), 0 === encodingParameters.length && primarySsrc && encodingParameters.push({ | |
ssrc: primarySsrc | |
}); | |
var bandwidth = SDPUtils.matchPrefix(mediaSection, "b="); | |
return bandwidth.length && (0 === bandwidth[0].indexOf("b=TIAS:") ? bandwidth = parseInt(bandwidth[0].substr(7), 10) : 0 === bandwidth[0].indexOf("b=AS:") && (bandwidth = parseInt(bandwidth[0].substr(5), 10)), encodingParameters.forEach(function(params) { | |
params.maxBitrate = bandwidth | |
})), encodingParameters | |
}, SDPUtils.writeSessionBoilerplate = function() { | |
return "v=0\r\no=thisisadapterortc 8169639915646943137 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n" | |
}, SDPUtils.writeMediaSection = function(transceiver, caps, type, stream) { | |
var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps); | |
if (sdp += SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters()), sdp += SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(), "offer" === type ? "actpass" : "active"), sdp += "a=mid:" + transceiver.mid + "\r\n", sdp += transceiver.rtpSender && transceiver.rtpReceiver ? "a=sendrecv\r\n" : transceiver.rtpSender ? "a=sendonly\r\n" : transceiver.rtpReceiver ? "a=recvonly\r\n" : "a=inactive\r\n", transceiver.rtpSender) { | |
var msid = "msid:" + stream.id + " " + transceiver.rtpSender.track.id + "\r\n"; | |
sdp += "a=" + msid, sdp += "a=ssrc:" + transceiver.sendEncodingParameters[0].ssrc + " " + msid | |
} | |
return sdp += "a=ssrc:" + transceiver.sendEncodingParameters[0].ssrc + " cname:" + SDPUtils.localCName + "\r\n" | |
}, SDPUtils.getDirection = function(mediaSection, sessionpart) { | |
for (var lines = SDPUtils.splitLines(mediaSection), i = 0; i < lines.length; i++) switch (lines[i]) { | |
case "a=sendrecv": | |
case "a=sendonly": | |
case "a=recvonly": | |
case "a=inactive": | |
return lines[i].substr(2) | |
} | |
return sessionpart ? SDPUtils.getDirection(sessionpart) : "sendrecv" | |
}, module.exports = SDPUtils | |
}, {}], | |
2: [function(require, module, exports) { | |
"use strict"; | |
! function() { | |
var logging = require("./utils").log, | |
browserDetails = require("./utils").browserDetails; | |
module.exports.browserDetails = browserDetails, module.exports.extractVersion = require("./utils").extractVersion, module.exports.disableLog = require("./utils").disableLog; | |
var chromeShim = require("./chrome/chrome_shim") || null, | |
edgeShim = require("./edge/edge_shim") || null, | |
firefoxShim = require("./firefox/firefox_shim") || null, | |
safariShim = require("./safari/safari_shim") || null; | |
switch (browserDetails.browser) { | |
case "opera": | |
case "chrome": | |
if (!chromeShim || !chromeShim.shimPeerConnection) return void logging("Chrome shim is not included in this adapter release."); | |
logging("adapter.js shimming chrome."), module.exports.browserShim = chromeShim, chromeShim.shimGetUserMedia(), chromeShim.shimMediaStream(), chromeShim.shimSourceObject(), chromeShim.shimPeerConnection(), chromeShim.shimOnTrack(); | |
break; | |
case "firefox": | |
if (!firefoxShim || !firefoxShim.shimPeerConnection) return void logging("Firefox shim is not included in this adapter release."); | |
logging("adapter.js shimming firefox."), module.exports.browserShim = firefoxShim, firefoxShim.shimGetUserMedia(), firefoxShim.shimSourceObject(), firefoxShim.shimPeerConnection(), firefoxShim.shimOnTrack(); | |
break; | |
case "edge": | |
if (!edgeShim || !edgeShim.shimPeerConnection) return void logging("MS edge shim is not included in this adapter release."); | |
logging("adapter.js shimming edge."), module.exports.browserShim = edgeShim, edgeShim.shimGetUserMedia(), edgeShim.shimPeerConnection(); | |
break; | |
case "safari": | |
if (!safariShim) return void logging("Safari shim is not included in this adapter release."); | |
logging("adapter.js shimming safari."), module.exports.browserShim = safariShim, safariShim.shimGetUserMedia(); | |
break; | |
default: | |
logging("Unsupported browser!") | |
} | |
}() | |
}, { | |
"./chrome/chrome_shim": 3, | |
"./edge/edge_shim": 5, | |
"./firefox/firefox_shim": 7, | |
"./safari/safari_shim": 9, | |
"./utils": 10 | |
}], | |
3: [function(require, module, exports) { | |
"use strict"; | |
var logging = require("../utils.js").log, | |
browserDetails = require("../utils.js").browserDetails, | |
chromeShim = { | |
shimMediaStream: function() { | |
window.MediaStream = window.MediaStream || window.webkitMediaStream | |
}, | |
shimOnTrack: function() { | |
"object" != typeof window || !window.RTCPeerConnection || "ontrack" in window.RTCPeerConnection.prototype || Object.defineProperty(window.RTCPeerConnection.prototype, "ontrack", { | |
get: function() { | |
return this._ontrack | |
}, | |
set: function(f) { | |
var self = this; | |
this._ontrack && (this.removeEventListener("track", this._ontrack), this.removeEventListener("addstream", this._ontrackpoly)), this.addEventListener("track", this._ontrack = f), this.addEventListener("addstream", this._ontrackpoly = function(e) { | |
e.stream.addEventListener("addtrack", function(te) { | |
var event = new Event("track"); | |
event.track = te.track, event.receiver = { | |
track: te.track | |
}, event.streams = [e.stream], self.dispatchEvent(event) | |
}), e.stream.getTracks().forEach(function(track) { | |
var event = new Event("track"); | |
event.track = track, event.receiver = { | |
track: track | |
}, event.streams = [e.stream], this.dispatchEvent(event) | |
}.bind(this)) | |
}.bind(this)) | |
} | |
}) | |
}, | |
shimSourceObject: function() { | |
"object" == typeof window && (!window.HTMLMediaElement || "srcObject" in window.HTMLMediaElement.prototype || Object.defineProperty(window.HTMLMediaElement.prototype, "srcObject", { | |
get: function() { | |
return this._srcObject | |
}, | |
set: function(stream) { | |
var self = this; | |
return this._srcObject = stream, this.src && URL.revokeObjectURL(this.src), stream ? (this.src = URL.createObjectURL(stream), stream.addEventListener("addtrack", function() { | |
self.src && URL.revokeObjectURL(self.src), self.src = URL.createObjectURL(stream) | |
}), void stream.addEventListener("removetrack", function() { | |
self.src && URL.revokeObjectURL(self.src), self.src = URL.createObjectURL(stream) | |
})) : void(this.src = "") | |
} | |
})) | |
}, | |
shimPeerConnection: function() { | |
window.RTCPeerConnection = function(pcConfig, pcConstraints) { | |
logging("PeerConnection"), pcConfig && pcConfig.iceTransportPolicy && (pcConfig.iceTransports = pcConfig.iceTransportPolicy); | |
var pc = new webkitRTCPeerConnection(pcConfig, pcConstraints), | |
origGetStats = pc.getStats.bind(pc); | |
return pc.getStats = function(selector, successCallback, errorCallback) { | |
var self = this, | |
args = arguments; | |
if (arguments.length > 0 && "function" == typeof selector) return origGetStats(selector, successCallback); | |
var fixChromeStats_ = function(response) { | |
var standardReport = {}, | |
reports = response.result(); | |
return reports.forEach(function(report) { | |
var standardStats = { | |
id: report.id, | |
timestamp: report.timestamp, | |
type: report.type | |
}; | |
report.names().forEach(function(name) { | |
standardStats[name] = report.stat(name) | |
}), standardReport[standardStats.id] = standardStats | |
}), standardReport | |
}, | |
makeMapStats = function(stats, legacyStats) { | |
var map = new Map(Object.keys(stats).map(function(key) { | |
return [key, stats[key]] | |
})); | |
return legacyStats = legacyStats || stats, Object.keys(legacyStats).forEach(function(key) { | |
map[key] = legacyStats[key] | |
}), map | |
}; | |
if (arguments.length >= 2) { | |
var successCallbackWrapper_ = function(response) { | |
args[1](makeMapStats(fixChromeStats_(response))) | |
}; | |
return origGetStats.apply(this, [successCallbackWrapper_, arguments[0]]) | |
} | |
return new Promise(function(resolve, reject) { | |
1 === args.length && "object" == typeof selector ? origGetStats.apply(self, [function(response) { | |
resolve(makeMapStats(fixChromeStats_(response))) | |
}, reject]) : origGetStats.apply(self, [function(response) { | |
resolve(makeMapStats(fixChromeStats_(response), response.result())) | |
}, reject]) | |
}).then(successCallback, errorCallback) | |
}, pc | |
}, window.RTCPeerConnection.prototype = webkitRTCPeerConnection.prototype, webkitRTCPeerConnection.generateCertificate && Object.defineProperty(window.RTCPeerConnection, "generateCertificate", { | |
get: function() { | |
return webkitRTCPeerConnection.generateCertificate | |
} | |
}), ["createOffer", "createAnswer"].forEach(function(method) { | |
var nativeMethod = webkitRTCPeerConnection.prototype[method]; | |
webkitRTCPeerConnection.prototype[method] = function() { | |
var self = this; | |
if (arguments.length < 1 || 1 === arguments.length && "object" == typeof arguments[0]) { | |
var opts = 1 === arguments.length ? arguments[0] : void 0; | |
return new Promise(function(resolve, reject) { | |
nativeMethod.apply(self, [resolve, reject, opts]) | |
}) | |
} | |
return nativeMethod.apply(this, arguments) | |
} | |
}), browserDetails.version < 51 && ["setLocalDescription", "setRemoteDescription", "addIceCandidate"].forEach(function(method) { | |
var nativeMethod = webkitRTCPeerConnection.prototype[method]; | |
webkitRTCPeerConnection.prototype[method] = function() { | |
var args = arguments, | |
self = this, | |
promise = new Promise(function(resolve, reject) { | |
nativeMethod.apply(self, [args[0], resolve, reject]) | |
}); | |
return args.length < 2 ? promise : promise.then(function() { | |
args[1].apply(null, []) | |
}, function(err) { | |
args.length >= 3 && args[2].apply(null, [err]) | |
}) | |
} | |
}), ["setLocalDescription", "setRemoteDescription", "addIceCandidate"].forEach(function(method) { | |
var nativeMethod = webkitRTCPeerConnection.prototype[method]; | |
webkitRTCPeerConnection.prototype[method] = function() { | |
return arguments[0] = new("addIceCandidate" === method ? RTCIceCandidate : RTCSessionDescription)(arguments[0]), nativeMethod.apply(this, arguments) | |
} | |
}); | |
var nativeAddIceCandidate = RTCPeerConnection.prototype.addIceCandidate; | |
RTCPeerConnection.prototype.addIceCandidate = function() { | |
return null === arguments[0] ? Promise.resolve() : nativeAddIceCandidate.apply(this, arguments) | |
} | |
} | |
}; | |
module.exports = { | |
shimMediaStream: chromeShim.shimMediaStream, | |
shimOnTrack: chromeShim.shimOnTrack, | |
shimSourceObject: chromeShim.shimSourceObject, | |
shimPeerConnection: chromeShim.shimPeerConnection, | |
shimGetUserMedia: require("./getusermedia") | |
} | |
}, { | |
"../utils.js": 10, | |
"./getusermedia": 4 | |
}], | |
4: [function(require, module, exports) { | |
"use strict"; | |
var logging = require("../utils.js").log; | |
module.exports = function() { | |
var constraintsToChrome_ = function(c) { | |
if ("object" != typeof c || c.mandatory || c.optional) return c; | |
var cc = {}; | |
return Object.keys(c).forEach(function(key) { | |
if ("require" !== key && "advanced" !== key && "mediaSource" !== key) { | |
var r = "object" == typeof c[key] ? c[key] : { | |
ideal: c[key] | |
}; | |
void 0 !== r.exact && "number" == typeof r.exact && (r.min = r.max = r.exact); | |
var oldname_ = function(prefix, name) { | |
return prefix ? prefix + name.charAt(0).toUpperCase() + name.slice(1) : "deviceId" === name ? "sourceId" : name | |
}; | |
if (void 0 !== r.ideal) { | |
cc.optional = cc.optional || []; | |
var oc = {}; | |
"number" == typeof r.ideal ? (oc[oldname_("min", key)] = r.ideal, cc.optional.push(oc), oc = {}, oc[oldname_("max", key)] = r.ideal, cc.optional.push(oc)) : (oc[oldname_("", key)] = r.ideal, cc.optional.push(oc)) | |
} | |
void 0 !== r.exact && "number" != typeof r.exact ? (cc.mandatory = cc.mandatory || {}, cc.mandatory[oldname_("", key)] = r.exact) : ["min", "max"].forEach(function(mix) { | |
void 0 !== r[mix] && (cc.mandatory = cc.mandatory || {}, cc.mandatory[oldname_(mix, key)] = r[mix]) | |
}) | |
} | |
}), c.advanced && (cc.optional = (cc.optional || []).concat(c.advanced)), cc | |
}, | |
shimConstraints_ = function(constraints, func) { | |
if (constraints = JSON.parse(JSON.stringify(constraints)), constraints && constraints.audio && (constraints.audio = constraintsToChrome_(constraints.audio)), constraints && "object" == typeof constraints.video) { | |
var face = constraints.video.facingMode; | |
if (face = face && ("object" == typeof face ? face : { | |
ideal: face | |
}), face && ("user" === face.exact || "environment" === face.exact || "user" === face.ideal || "environment" === face.ideal) && (!navigator.mediaDevices.getSupportedConstraints || !navigator.mediaDevices.getSupportedConstraints().facingMode) && (delete constraints.video.facingMode, "environment" === face.exact || "environment" === face.ideal)) return navigator.mediaDevices.enumerateDevices().then(function(devices) { | |
devices = devices.filter(function(d) { | |
return "videoinput" === d.kind | |
}); | |
var back = devices.find(function(d) { | |
return d.label.toLowerCase().indexOf("back") !== -1 | |
}) || devices.length && devices[devices.length - 1]; | |
return back && (constraints.video.deviceId = face.exact ? { | |
exact: back.deviceId | |
} : { | |
ideal: back.deviceId | |
}), constraints.video = constraintsToChrome_(constraints.video), logging("chrome: " + JSON.stringify(constraints)), func(constraints) | |
}); | |
constraints.video = constraintsToChrome_(constraints.video) | |
} | |
return logging("chrome: " + JSON.stringify(constraints)), func(constraints) | |
}, | |
shimError_ = function(e) { | |
return { | |
name: { | |
PermissionDeniedError: "NotAllowedError", | |
ConstraintNotSatisfiedError: "OverconstrainedError" | |
}[e.name] || e.name, | |
message: e.message, | |
constraint: e.constraintName, | |
toString: function() { | |
return this.name + (this.message && ": ") + this.message | |
} | |
} | |
}, | |
getUserMedia_ = function(constraints, onSuccess, onError) { | |
shimConstraints_(constraints, function(c) { | |
navigator.webkitGetUserMedia(c, onSuccess, function(e) { | |
onError(shimError_(e)) | |
}) | |
}) | |
}; | |
navigator.getUserMedia = getUserMedia_; | |
var getUserMediaPromise_ = function(constraints) { | |
return new Promise(function(resolve, reject) { | |
navigator.getUserMedia(constraints, resolve, reject) | |
}) | |
}; | |
if (navigator.mediaDevices || (navigator.mediaDevices = { | |
getUserMedia: getUserMediaPromise_, | |
enumerateDevices: function() { | |
return new Promise(function(resolve) { | |
var kinds = { | |
audio: "audioinput", | |
video: "videoinput" | |
}; | |
return MediaStreamTrack.getSources(function(devices) { | |
resolve(devices.map(function(device) { | |
return { | |
label: device.label, | |
kind: kinds[device.kind], | |
deviceId: device.id, | |
groupId: "" | |
} | |
})) | |
}) | |
}) | |
} | |
}), navigator.mediaDevices.getUserMedia) { | |
var origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); | |
navigator.mediaDevices.getUserMedia = function(cs) { | |
return shimConstraints_(cs, function(c) { | |
return origGetUserMedia(c).catch(function(e) { | |
return Promise.reject(shimError_(e)) | |
}) | |
}) | |
} | |
} else navigator.mediaDevices.getUserMedia = function(constraints) { | |
return getUserMediaPromise_(constraints) | |
}; | |
"undefined" == typeof navigator.mediaDevices.addEventListener && (navigator.mediaDevices.addEventListener = function() { | |
logging("Dummy mediaDevices.addEventListener called.") | |
}), "undefined" == typeof navigator.mediaDevices.removeEventListener && (navigator.mediaDevices.removeEventListener = function() { | |
logging("Dummy mediaDevices.removeEventListener called.") | |
}) | |
} | |
}, { | |
"../utils.js": 10 | |
}], | |
5: [function(require, module, exports) { | |
"use strict"; | |
var SDPUtils = require("sdp"), | |
browserDetails = require("../utils").browserDetails, | |
edgeShim = { | |
shimPeerConnection: function() { | |
window.RTCIceGatherer && (window.RTCIceCandidate || (window.RTCIceCandidate = function(args) { | |
return args | |
}), window.RTCSessionDescription || (window.RTCSessionDescription = function(args) { | |
return args | |
})), window.RTCPeerConnection = function(config) { | |
var self = this, | |
_eventTarget = document.createDocumentFragment(); | |
if (["addEventListener", "removeEventListener", "dispatchEvent"].forEach(function(method) { | |
self[method] = _eventTarget[method].bind(_eventTarget) | |
}), this.onicecandidate = null, this.onaddstream = null, this.ontrack = null, this.onremovestream = null, this.onsignalingstatechange = null, this.oniceconnectionstatechange = null, this.onnegotiationneeded = null, this.ondatachannel = null, this.localStreams = [], this.remoteStreams = [], this.getLocalStreams = function() { | |
return self.localStreams | |
}, this.getRemoteStreams = function() { | |
return self.remoteStreams | |
}, this.localDescription = new RTCSessionDescription({ | |
type: "", | |
sdp: "" | |
}), this.remoteDescription = new RTCSessionDescription({ | |
type: "", | |
sdp: "" | |
}), this.signalingState = "stable", this.iceConnectionState = "new", this.iceGatheringState = "new", this.iceOptions = { | |
gatherPolicy: "all", | |
iceServers: [] | |
}, config && config.iceTransportPolicy) switch (config.iceTransportPolicy) { | |
case "all": | |
case "relay": | |
this.iceOptions.gatherPolicy = config.iceTransportPolicy; | |
break; | |
case "none": | |
throw new TypeError('iceTransportPolicy "none" not supported') | |
} | |
if (this.usingBundle = config && "max-bundle" === config.bundlePolicy, config && config.iceServers) { | |
var iceServers = JSON.parse(JSON.stringify(config.iceServers)); | |
this.iceOptions.iceServers = iceServers.filter(function(server) { | |
if (server && server.urls) { | |
var urls = server.urls; | |
return "string" == typeof urls && (urls = [urls]), urls = urls.filter(function(url) { | |
return 0 === url.indexOf("turn:") && url.indexOf("transport=udp") !== -1 && url.indexOf("turn:[") === -1 || 0 === url.indexOf("stun:") && browserDetails.version >= 14393 | |
})[0], !!urls | |
} | |
return !1 | |
}) | |
} | |
this.transceivers = [], this._localIceCandidatesBuffer = [] | |
}, window.RTCPeerConnection.prototype._emitBufferedCandidates = function() { | |
var self = this, | |
sections = SDPUtils.splitSections(self.localDescription.sdp); | |
this._localIceCandidatesBuffer.forEach(function(event) { | |
var end = !event.candidate || 0 === Object.keys(event.candidate).length; | |
if (end) | |
for (var j = 1; j < sections.length; j++) sections[j].indexOf("\r\na=end-of-candidates\r\n") === -1 && (sections[j] += "a=end-of-candidates\r\n"); | |
else event.candidate.candidate.indexOf("typ endOfCandidates") === -1 && (sections[event.candidate.sdpMLineIndex + 1] += "a=" + event.candidate.candidate + "\r\n"); | |
if (self.localDescription.sdp = sections.join(""), self.dispatchEvent(event), null !== self.onicecandidate && self.onicecandidate(event), !event.candidate && "complete" !== self.iceGatheringState) { | |
var complete = self.transceivers.every(function(transceiver) { | |
return transceiver.iceGatherer && "completed" === transceiver.iceGatherer.state | |
}); | |
complete && (self.iceGatheringState = "complete") | |
} | |
}), this._localIceCandidatesBuffer = [] | |
}, window.RTCPeerConnection.prototype.addStream = function(stream) { | |
this.localStreams.push(stream.clone()), this._maybeFireNegotiationNeeded() | |
}, window.RTCPeerConnection.prototype.removeStream = function(stream) { | |
var idx = this.localStreams.indexOf(stream); | |
idx > -1 && (this.localStreams.splice(idx, 1), this._maybeFireNegotiationNeeded()) | |
}, window.RTCPeerConnection.prototype.getSenders = function() { | |
return this.transceivers.filter(function(transceiver) { | |
return !!transceiver.rtpSender | |
}).map(function(transceiver) { | |
return transceiver.rtpSender | |
}) | |
}, window.RTCPeerConnection.prototype.getReceivers = function() { | |
return this.transceivers.filter(function(transceiver) { | |
return !!transceiver.rtpReceiver | |
}).map(function(transceiver) { | |
return transceiver.rtpReceiver | |
}) | |
}, window.RTCPeerConnection.prototype._getCommonCapabilities = function(localCapabilities, remoteCapabilities) { | |
var commonCapabilities = { | |
codecs: [], | |
headerExtensions: [], | |
fecMechanisms: [] | |
}; | |
return localCapabilities.codecs.forEach(function(lCodec) { | |
for (var i = 0; i < remoteCapabilities.codecs.length; i++) { | |
var rCodec = remoteCapabilities.codecs[i]; | |
if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() && lCodec.clockRate === rCodec.clockRate && lCodec.numChannels === rCodec.numChannels) { | |
commonCapabilities.codecs.push(rCodec), rCodec.rtcpFeedback = rCodec.rtcpFeedback.filter(function(fb) { | |
for (var j = 0; j < lCodec.rtcpFeedback.length; j++) | |
if (lCodec.rtcpFeedback[j].type === fb.type && lCodec.rtcpFeedback[j].parameter === fb.parameter) return !0; | |
return !1 | |
}); | |
break | |
} | |
} | |
}), localCapabilities.headerExtensions.forEach(function(lHeaderExtension) { | |
for (var i = 0; i < remoteCapabilities.headerExtensions.length; i++) { | |
var rHeaderExtension = remoteCapabilities.headerExtensions[i]; | |
if (lHeaderExtension.uri === rHeaderExtension.uri) { | |
commonCapabilities.headerExtensions.push(rHeaderExtension); | |
break | |
} | |
} | |
}), commonCapabilities | |
}, window.RTCPeerConnection.prototype._createIceAndDtlsTransports = function(mid, sdpMLineIndex) { | |
var self = this, | |
iceGatherer = new RTCIceGatherer(self.iceOptions), | |
iceTransport = new RTCIceTransport(iceGatherer); | |
iceGatherer.onlocalcandidate = function(evt) { | |
var event = new Event("icecandidate"); | |
event.candidate = { | |
sdpMid: mid, | |
sdpMLineIndex: sdpMLineIndex | |
}; | |
var cand = evt.candidate, | |
end = !cand || 0 === Object.keys(cand).length; | |
end ? (void 0 === iceGatherer.state && (iceGatherer.state = "completed"), event.candidate.candidate = "candidate:1 1 udp 1 0.0.0.0 9 typ endOfCandidates") : (cand.component = "RTCP" === iceTransport.component ? 2 : 1, event.candidate.candidate = SDPUtils.writeCandidate(cand)); | |
var sections = SDPUtils.splitSections(self.localDescription.sdp); | |
event.candidate.candidate.indexOf("typ endOfCandidates") === -1 ? sections[event.candidate.sdpMLineIndex + 1] += "a=" + event.candidate.candidate + "\r\n" : sections[event.candidate.sdpMLineIndex + 1] += "a=end-of-candidates\r\n", self.localDescription.sdp = sections.join(""); | |
var complete = self.transceivers.every(function(transceiver) { | |
return transceiver.iceGatherer && "completed" === transceiver.iceGatherer.state | |
}); | |
switch (self.iceGatheringState) { | |
case "new": | |
self._localIceCandidatesBuffer.push(event), end && complete && self._localIceCandidatesBuffer.push(new Event("icecandidate")); | |
break; | |
case "gathering": | |
self._emitBufferedCandidates(), self.dispatchEvent(event), null !== self.onicecandidate && self.onicecandidate(event), complete && (self.dispatchEvent(new Event("icecandidate")), null !== self.onicecandidate && self.onicecandidate(new Event("icecandidate")), self.iceGatheringState = "complete"); | |
break; | |
case "complete": | |
} | |
}, iceTransport.onicestatechange = function() { | |
self._updateConnectionState() | |
}; | |
var dtlsTransport = new RTCDtlsTransport(iceTransport); | |
return dtlsTransport.ondtlsstatechange = function() { | |
self._updateConnectionState() | |
}, dtlsTransport.onerror = function() { | |
dtlsTransport.state = "failed", self._updateConnectionState() | |
}, { | |
iceGatherer: iceGatherer, | |
iceTransport: iceTransport, | |
dtlsTransport: dtlsTransport | |
} | |
}, window.RTCPeerConnection.prototype._transceive = function(transceiver, send, recv) { | |
var params = this._getCommonCapabilities(transceiver.localCapabilities, transceiver.remoteCapabilities); | |
send && transceiver.rtpSender && (params.encodings = transceiver.sendEncodingParameters, params.rtcp = { | |
cname: SDPUtils.localCName | |
}, transceiver.recvEncodingParameters.length && (params.rtcp.ssrc = transceiver.recvEncodingParameters[0].ssrc), transceiver.rtpSender.send(params)), recv && transceiver.rtpReceiver && (params.encodings = transceiver.recvEncodingParameters, params.rtcp = { | |
cname: transceiver.cname | |
}, transceiver.sendEncodingParameters.length && (params.rtcp.ssrc = transceiver.sendEncodingParameters[0].ssrc), transceiver.rtpReceiver.receive(params)) | |
}, window.RTCPeerConnection.prototype.setLocalDescription = function(description) { | |
var sections, sessionpart, self = this; | |
if ("offer" === description.type) this._pendingOffer && (sections = SDPUtils.splitSections(description.sdp), sessionpart = sections.shift(), sections.forEach(function(mediaSection, sdpMLineIndex) { | |
var caps = SDPUtils.parseRtpParameters(mediaSection); | |
self._pendingOffer[sdpMLineIndex].localCapabilities = caps | |
}), this.transceivers = this._pendingOffer, delete this._pendingOffer); | |
else if ("answer" === description.type) { | |
sections = SDPUtils.splitSections(self.remoteDescription.sdp), sessionpart = sections.shift(); | |
var isIceLite = SDPUtils.matchPrefix(sessionpart, "a=ice-lite").length > 0; | |
sections.forEach(function(mediaSection, sdpMLineIndex) { | |
var transceiver = self.transceivers[sdpMLineIndex], | |
iceGatherer = transceiver.iceGatherer, | |
iceTransport = transceiver.iceTransport, | |
dtlsTransport = transceiver.dtlsTransport, | |
localCapabilities = transceiver.localCapabilities, | |
remoteCapabilities = transceiver.remoteCapabilities, | |
rejected = "0" === mediaSection.split("\n", 1)[0].split(" ", 2)[1]; | |
if (!rejected && !transceiver.isDatachannel) { | |
var remoteIceParameters = SDPUtils.getIceParameters(mediaSection, sessionpart); | |
if (isIceLite) { | |
var cands = SDPUtils.matchPrefix(mediaSection, "a=candidate:").map(function(cand) { | |
return SDPUtils.parseCandidate(cand) | |
}).filter(function(cand) { | |
return "1" === cand.component | |
}); | |
cands.length && iceTransport.setRemoteCandidates(cands) | |
} | |
var remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection, sessionpart); | |
isIceLite && (remoteDtlsParameters.role = "server"), self.usingBundle && 0 !== sdpMLineIndex || (iceTransport.start(iceGatherer, remoteIceParameters, isIceLite ? "controlling" : "controlled"), dtlsTransport.start(remoteDtlsParameters)); | |
var params = self._getCommonCapabilities(localCapabilities, remoteCapabilities); | |
self._transceive(transceiver, params.codecs.length > 0, !1) | |
} | |
}) | |
} | |
switch (this.localDescription = { | |
type: description.type, | |
sdp: description.sdp | |
}, description.type) { | |
case "offer": | |
this._updateSignalingState("have-local-offer"); | |
break; | |
case "answer": | |
this._updateSignalingState("stable"); | |
break; | |
default: | |
throw new TypeError('unsupported type "' + description.type + '"') | |
} | |
var hasCallback = arguments.length > 1 && "function" == typeof arguments[1]; | |
if (hasCallback) { | |
var cb = arguments[1]; | |
window.setTimeout(function() { | |
cb(), "new" === self.iceGatheringState && (self.iceGatheringState = "gathering"), self._emitBufferedCandidates() | |
}, 0) | |
} | |
var p = Promise.resolve(); | |
return p.then(function() { | |
hasCallback || ("new" === self.iceGatheringState && (self.iceGatheringState = "gathering"), window.setTimeout(self._emitBufferedCandidates.bind(self), 500)) | |
}), p | |
}, window.RTCPeerConnection.prototype.setRemoteDescription = function(description) { | |
var self = this, | |
stream = new MediaStream, | |
receiverList = [], | |
sections = SDPUtils.splitSections(description.sdp), | |
sessionpart = sections.shift(), | |
isIceLite = SDPUtils.matchPrefix(sessionpart, "a=ice-lite").length > 0; | |
switch (this.usingBundle = SDPUtils.matchPrefix(sessionpart, "a=group:BUNDLE ").length > 0, sections.forEach(function(mediaSection, sdpMLineIndex) { | |
var lines = SDPUtils.splitLines(mediaSection), | |
mline = lines[0].substr(2).split(" "), | |
kind = mline[0], | |
rejected = "0" === mline[1], | |
direction = SDPUtils.getDirection(mediaSection, sessionpart), | |
mid = SDPUtils.matchPrefix(mediaSection, "a=mid:"); | |
if (mid = mid.length ? mid[0].substr(6) : SDPUtils.generateIdentifier(), "application" === kind && "DTLS/SCTP" === mline[2]) return void(self.transceivers[sdpMLineIndex] = { | |
mid: mid, | |
isDatachannel: !0 | |
}); | |
var transceiver, iceGatherer, iceTransport, dtlsTransport, rtpSender, rtpReceiver, sendEncodingParameters, recvEncodingParameters, localCapabilities, track, remoteIceParameters, remoteDtlsParameters, remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection); | |
rejected || (remoteIceParameters = SDPUtils.getIceParameters(mediaSection, sessionpart), remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection, sessionpart), remoteDtlsParameters.role = "client"), recvEncodingParameters = SDPUtils.parseRtpEncodingParameters(mediaSection); | |
var cname, remoteSsrc = SDPUtils.matchPrefix(mediaSection, "a=ssrc:").map(function(line) { | |
return SDPUtils.parseSsrcMedia(line) | |
}).filter(function(obj) { | |
return "cname" === obj.attribute | |
})[0]; | |
remoteSsrc && (cname = remoteSsrc.value); | |
var isComplete = SDPUtils.matchPrefix(mediaSection, "a=end-of-candidates", sessionpart).length > 0, | |
cands = SDPUtils.matchPrefix(mediaSection, "a=candidate:").map(function(cand) { | |
return SDPUtils.parseCandidate(cand) | |
}).filter(function(cand) { | |
return "1" === cand.component | |
}); | |
if ("offer" !== description.type || rejected) "answer" !== description.type || rejected || (transceiver = self.transceivers[sdpMLineIndex], iceGatherer = transceiver.iceGatherer, iceTransport = transceiver.iceTransport, dtlsTransport = transceiver.dtlsTransport, rtpSender = transceiver.rtpSender, rtpReceiver = transceiver.rtpReceiver, sendEncodingParameters = transceiver.sendEncodingParameters, localCapabilities = transceiver.localCapabilities, self.transceivers[sdpMLineIndex].recvEncodingParameters = recvEncodingParameters, self.transceivers[sdpMLineIndex].remoteCapabilities = remoteCapabilities, self.transceivers[sdpMLineIndex].cname = cname, (isIceLite || isComplete) && cands.length && iceTransport.setRemoteCandidates(cands), self.usingBundle && 0 !== sdpMLineIndex || (iceTransport.start(iceGatherer, remoteIceParameters, "controlling"), dtlsTransport.start(remoteDtlsParameters)), self._transceive(transceiver, "sendrecv" === direction || "recvonly" === direction, "sendrecv" === direction || "sendonly" === direction), !rtpReceiver || "sendrecv" !== direction && "sendonly" !== direction ? delete transceiver.rtpReceiver : (track = rtpReceiver.track, receiverList.push([track, rtpReceiver]), stream.addTrack(track))); | |
else { | |
var transports = self.usingBundle && sdpMLineIndex > 0 ? { | |
iceGatherer: self.transceivers[0].iceGatherer, | |
iceTransport: self.transceivers[0].iceTransport, | |
dtlsTransport: self.transceivers[0].dtlsTransport | |
} : self._createIceAndDtlsTransports(mid, sdpMLineIndex); | |
if (isComplete && transports.iceTransport.setRemoteCandidates(cands), localCapabilities = RTCRtpReceiver.getCapabilities(kind), sendEncodingParameters = [{ | |
ssrc: 1001 * (2 * sdpMLineIndex + 2) | |
}], rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, kind), track = rtpReceiver.track, receiverList.push([track, rtpReceiver]), stream.addTrack(track), self.localStreams.length > 0 && self.localStreams[0].getTracks().length >= sdpMLineIndex) { | |
var localTrack; | |
"audio" === kind ? localTrack = self.localStreams[0].getAudioTracks()[0] : "video" === kind && (localTrack = self.localStreams[0].getVideoTracks()[0]), localTrack && (rtpSender = new RTCRtpSender(localTrack, transports.dtlsTransport)) | |
} | |
self.transceivers[sdpMLineIndex] = { | |
iceGatherer: transports.iceGatherer, | |
iceTransport: transports.iceTransport, | |
dtlsTransport: transports.dtlsTransport, | |
localCapabilities: localCapabilities, | |
remoteCapabilities: remoteCapabilities, | |
rtpSender: rtpSender, | |
rtpReceiver: rtpReceiver, | |
kind: kind, | |
mid: mid, | |
cname: cname, | |
sendEncodingParameters: sendEncodingParameters, | |
recvEncodingParameters: recvEncodingParameters | |
}, self._transceive(self.transceivers[sdpMLineIndex], !1, "sendrecv" === direction || "sendonly" === direction) | |
} | |
}), this.remoteDescription = { | |
type: description.type, | |
sdp: description.sdp | |
}, description.type) { | |
case "offer": | |
this._updateSignalingState("have-remote-offer"); | |
break; | |
case "answer": | |
this._updateSignalingState("stable"); | |
break; | |
default: | |
throw new TypeError('unsupported type "' + description.type + '"') | |
} | |
return stream.getTracks().length && (self.remoteStreams.push(stream), window.setTimeout(function() { | |
var event = new Event("addstream"); | |
event.stream = stream, self.dispatchEvent(event), null !== self.onaddstream && window.setTimeout(function() { | |
self.onaddstream(event) | |
}, 0), receiverList.forEach(function(item) { | |
var track = item[0], | |
receiver = item[1], | |
trackEvent = new Event("track"); | |
trackEvent.track = track, trackEvent.receiver = receiver, trackEvent.streams = [stream], self.dispatchEvent(event), null !== self.ontrack && window.setTimeout(function() { | |
self.ontrack(trackEvent) | |
}, 0) | |
}) | |
}, 0)), arguments.length > 1 && "function" == typeof arguments[1] && window.setTimeout(arguments[1], 0), Promise.resolve() | |
}, window.RTCPeerConnection.prototype.close = function() { | |
this.transceivers.forEach(function(transceiver) { | |
transceiver.iceTransport && transceiver.iceTransport.stop(), transceiver.dtlsTransport && transceiver.dtlsTransport.stop(), transceiver.rtpSender && transceiver.rtpSender.stop(), transceiver.rtpReceiver && transceiver.rtpReceiver.stop() | |
}), this._updateSignalingState("closed") | |
}, window.RTCPeerConnection.prototype._updateSignalingState = function(newState) { | |
this.signalingState = newState; | |
var event = new Event("signalingstatechange"); | |
this.dispatchEvent(event), null !== this.onsignalingstatechange && this.onsignalingstatechange(event) | |
}, window.RTCPeerConnection.prototype._maybeFireNegotiationNeeded = function() { | |
var event = new Event("negotiationneeded"); | |
this.dispatchEvent(event), null !== this.onnegotiationneeded && this.onnegotiationneeded(event) | |
}, window.RTCPeerConnection.prototype._updateConnectionState = function() { | |
var newState, self = this, | |
states = { | |
new: 0, | |
closed: 0, | |
connecting: 0, | |
checking: 0, | |
connected: 0, | |
completed: 0, | |
failed: 0 | |
}; | |
if (this.transceivers.forEach(function(transceiver) { | |
states[transceiver.iceTransport.state]++, states[transceiver.dtlsTransport.state]++ | |
}), states.connected += states.completed, newState = "new", states.failed > 0 ? newState = "failed" : states.connecting > 0 || states.checking > 0 ? newState = "connecting" : states.disconnected > 0 ? newState = "disconnected" : states.new > 0 ? newState = "new" : (states.connected > 0 || states.completed > 0) && (newState = "connected"), newState !== self.iceConnectionState) { | |
self.iceConnectionState = newState; | |
var event = new Event("iceconnectionstatechange"); | |
this.dispatchEvent(event), null !== this.oniceconnectionstatechange && this.oniceconnectionstatechange(event) | |
} | |
}, window.RTCPeerConnection.prototype.createOffer = function() { | |
var self = this; | |
if (this._pendingOffer) throw new Error("createOffer called while there is a pending offer."); | |
var offerOptions; | |
1 === arguments.length && "function" != typeof arguments[0] ? offerOptions = arguments[0] : 3 === arguments.length && (offerOptions = arguments[2]); | |
var tracks = [], | |
numAudioTracks = 0, | |
numVideoTracks = 0; | |
if (this.localStreams.length && (numAudioTracks = this.localStreams[0].getAudioTracks().length, numVideoTracks = this.localStreams[0].getVideoTracks().length), offerOptions) { | |
if (offerOptions.mandatory || offerOptions.optional) throw new TypeError("Legacy mandatory/optional constraints not supported."); | |
void 0 !== offerOptions.offerToReceiveAudio && (numAudioTracks = offerOptions.offerToReceiveAudio), | |
void 0 !== offerOptions.offerToReceiveVideo && (numVideoTracks = offerOptions.offerToReceiveVideo) | |
} | |
for (this.localStreams.length && this.localStreams[0].getTracks().forEach(function(track) { | |
tracks.push({ | |
kind: track.kind, | |
track: track, | |
wantReceive: "audio" === track.kind ? numAudioTracks > 0 : numVideoTracks > 0 | |
}), "audio" === track.kind ? numAudioTracks-- : "video" === track.kind && numVideoTracks-- | |
}); numAudioTracks > 0 || numVideoTracks > 0;) numAudioTracks > 0 && (tracks.push({ | |
kind: "audio", | |
wantReceive: !0 | |
}), numAudioTracks--), numVideoTracks > 0 && (tracks.push({ | |
kind: "video", | |
wantReceive: !0 | |
}), numVideoTracks--); | |
var sdp = SDPUtils.writeSessionBoilerplate(), | |
transceivers = []; | |
tracks.forEach(function(mline, sdpMLineIndex) { | |
var rtpSender, rtpReceiver, track = mline.track, | |
kind = mline.kind, | |
mid = SDPUtils.generateIdentifier(), | |
transports = self.usingBundle && sdpMLineIndex > 0 ? { | |
iceGatherer: transceivers[0].iceGatherer, | |
iceTransport: transceivers[0].iceTransport, | |
dtlsTransport: transceivers[0].dtlsTransport | |
} : self._createIceAndDtlsTransports(mid, sdpMLineIndex), | |
localCapabilities = RTCRtpSender.getCapabilities(kind), | |
sendEncodingParameters = [{ | |
ssrc: 1001 * (2 * sdpMLineIndex + 1) | |
}]; | |
track && (rtpSender = new RTCRtpSender(track, transports.dtlsTransport)), mline.wantReceive && (rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, kind)), transceivers[sdpMLineIndex] = { | |
iceGatherer: transports.iceGatherer, | |
iceTransport: transports.iceTransport, | |
dtlsTransport: transports.dtlsTransport, | |
localCapabilities: localCapabilities, | |
remoteCapabilities: null, | |
rtpSender: rtpSender, | |
rtpReceiver: rtpReceiver, | |
kind: kind, | |
mid: mid, | |
sendEncodingParameters: sendEncodingParameters, | |
recvEncodingParameters: null | |
} | |
}), this.usingBundle && (sdp += "a=group:BUNDLE " + transceivers.map(function(t) { | |
return t.mid | |
}).join(" ") + "\r\n"), tracks.forEach(function(mline, sdpMLineIndex) { | |
var transceiver = transceivers[sdpMLineIndex]; | |
sdp += SDPUtils.writeMediaSection(transceiver, transceiver.localCapabilities, "offer", self.localStreams[0]) | |
}), this._pendingOffer = transceivers; | |
var desc = new RTCSessionDescription({ | |
type: "offer", | |
sdp: sdp | |
}); | |
return arguments.length && "function" == typeof arguments[0] && window.setTimeout(arguments[0], 0, desc), Promise.resolve(desc) | |
}, window.RTCPeerConnection.prototype.createAnswer = function() { | |
var self = this, | |
sdp = SDPUtils.writeSessionBoilerplate(); | |
this.usingBundle && (sdp += "a=group:BUNDLE " + this.transceivers.map(function(t) { | |
return t.mid | |
}).join(" ") + "\r\n"), this.transceivers.forEach(function(transceiver) { | |
if (transceiver.isDatachannel) return void(sdp += "m=application 0 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=mid:" + transceiver.mid + "\r\n"); | |
var commonCapabilities = self._getCommonCapabilities(transceiver.localCapabilities, transceiver.remoteCapabilities); | |
sdp += SDPUtils.writeMediaSection(transceiver, commonCapabilities, "answer", self.localStreams[0]) | |
}); | |
var desc = new RTCSessionDescription({ | |
type: "answer", | |
sdp: sdp | |
}); | |
return arguments.length && "function" == typeof arguments[0] && window.setTimeout(arguments[0], 0, desc), Promise.resolve(desc) | |
}, window.RTCPeerConnection.prototype.addIceCandidate = function(candidate) { | |
if (null === candidate) this.transceivers.forEach(function(transceiver) { | |
transceiver.iceTransport.addRemoteCandidate({}) | |
}); | |
else { | |
var mLineIndex = candidate.sdpMLineIndex; | |
if (candidate.sdpMid) | |
for (var i = 0; i < this.transceivers.length; i++) | |
if (this.transceivers[i].mid === candidate.sdpMid) { | |
mLineIndex = i; | |
break | |
} | |
var transceiver = this.transceivers[mLineIndex]; | |
if (transceiver) { | |
var cand = Object.keys(candidate.candidate).length > 0 ? SDPUtils.parseCandidate(candidate.candidate) : {}; | |
if ("tcp" === cand.protocol && (0 === cand.port || 9 === cand.port)) return; | |
if ("1" !== cand.component) return; | |
"endOfCandidates" === cand.type && (cand = {}), transceiver.iceTransport.addRemoteCandidate(cand); | |
var sections = SDPUtils.splitSections(this.remoteDescription.sdp); | |
sections[mLineIndex + 1] += (cand.type ? candidate.candidate.trim() : "a=end-of-candidates") + "\r\n", this.remoteDescription.sdp = sections.join("") | |
} | |
} | |
return arguments.length > 1 && "function" == typeof arguments[1] && window.setTimeout(arguments[1], 0), Promise.resolve() | |
}, window.RTCPeerConnection.prototype.getStats = function() { | |
var promises = []; | |
this.transceivers.forEach(function(transceiver) { | |
["rtpSender", "rtpReceiver", "iceGatherer", "iceTransport", "dtlsTransport"].forEach(function(method) { | |
transceiver[method] && promises.push(transceiver[method].getStats()) | |
}) | |
}); | |
var cb = arguments.length > 1 && "function" == typeof arguments[1] && arguments[1]; | |
return new Promise(function(resolve) { | |
var results = new Map; | |
Promise.all(promises).then(function(res) { | |
res.forEach(function(result) { | |
Object.keys(result).forEach(function(id) { | |
results.set(id, result[id]), results[id] = result[id] | |
}) | |
}), cb && window.setTimeout(cb, 0, results), resolve(results) | |
}) | |
}) | |
} | |
} | |
}; | |
module.exports = { | |
shimPeerConnection: edgeShim.shimPeerConnection, | |
shimGetUserMedia: require("./getusermedia") | |
} | |
}, { | |
"../utils": 10, | |
"./getusermedia": 6, | |
sdp: 1 | |
}], | |
6: [function(require, module, exports) { | |
"use strict"; | |
module.exports = function() { | |
var shimError_ = function(e) { | |
return { | |
name: { | |
PermissionDeniedError: "NotAllowedError" | |
}[e.name] || e.name, | |
message: e.message, | |
constraint: e.constraint, | |
toString: function() { | |
return this.name | |
} | |
} | |
}, | |
origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); | |
navigator.mediaDevices.getUserMedia = function(c) { | |
return origGetUserMedia(c).catch(function(e) { | |
return Promise.reject(shimError_(e)) | |
}) | |
} | |
} | |
}, {}], | |
7: [function(require, module, exports) { | |
"use strict"; | |
var browserDetails = require("../utils").browserDetails, | |
firefoxShim = { | |
shimOnTrack: function() { | |
"object" != typeof window || !window.RTCPeerConnection || "ontrack" in window.RTCPeerConnection.prototype || Object.defineProperty(window.RTCPeerConnection.prototype, "ontrack", { | |
get: function() { | |
return this._ontrack | |
}, | |
set: function(f) { | |
this._ontrack && (this.removeEventListener("track", this._ontrack), this.removeEventListener("addstream", this._ontrackpoly)), this.addEventListener("track", this._ontrack = f), this.addEventListener("addstream", this._ontrackpoly = function(e) { | |
e.stream.getTracks().forEach(function(track) { | |
var event = new Event("track"); | |
event.track = track, event.receiver = { | |
track: track | |
}, event.streams = [e.stream], this.dispatchEvent(event) | |
}.bind(this)) | |
}.bind(this)) | |
} | |
}) | |
}, | |
shimSourceObject: function() { | |
"object" == typeof window && (!window.HTMLMediaElement || "srcObject" in window.HTMLMediaElement.prototype || Object.defineProperty(window.HTMLMediaElement.prototype, "srcObject", { | |
get: function() { | |
return this.mozSrcObject | |
}, | |
set: function(stream) { | |
this.mozSrcObject = stream | |
} | |
})) | |
}, | |
shimPeerConnection: function() { | |
if ("object" == typeof window && (window.RTCPeerConnection || window.mozRTCPeerConnection)) { | |
window.RTCPeerConnection || (window.RTCPeerConnection = function(pcConfig, pcConstraints) { | |
if (browserDetails.version < 38 && pcConfig && pcConfig.iceServers) { | |
for (var newIceServers = [], i = 0; i < pcConfig.iceServers.length; i++) { | |
var server = pcConfig.iceServers[i]; | |
if (server.hasOwnProperty("urls")) | |
for (var j = 0; j < server.urls.length; j++) { | |
var newServer = { | |
url: server.urls[j] | |
}; | |
0 === server.urls[j].indexOf("turn") && (newServer.username = server.username, newServer.credential = server.credential), newIceServers.push(newServer) | |
} else newIceServers.push(pcConfig.iceServers[i]) | |
} | |
pcConfig.iceServers = newIceServers | |
} | |
return new mozRTCPeerConnection(pcConfig, pcConstraints) | |
}, window.RTCPeerConnection.prototype = mozRTCPeerConnection.prototype, mozRTCPeerConnection.generateCertificate && Object.defineProperty(window.RTCPeerConnection, "generateCertificate", { | |
get: function() { | |
return mozRTCPeerConnection.generateCertificate | |
} | |
}), window.RTCSessionDescription = mozRTCSessionDescription, window.RTCIceCandidate = mozRTCIceCandidate), ["setLocalDescription", "setRemoteDescription", "addIceCandidate"].forEach(function(method) { | |
var nativeMethod = RTCPeerConnection.prototype[method]; | |
RTCPeerConnection.prototype[method] = function() { | |
return arguments[0] = new("addIceCandidate" === method ? RTCIceCandidate : RTCSessionDescription)(arguments[0]), nativeMethod.apply(this, arguments) | |
} | |
}); | |
var nativeAddIceCandidate = RTCPeerConnection.prototype.addIceCandidate; | |
RTCPeerConnection.prototype.addIceCandidate = function() { | |
return null === arguments[0] ? Promise.resolve() : nativeAddIceCandidate.apply(this, arguments) | |
}; | |
var makeMapStats = function(stats) { | |
var map = new Map; | |
return Object.keys(stats).forEach(function(key) { | |
map.set(key, stats[key]), map[key] = stats[key] | |
}), map | |
}, | |
nativeGetStats = RTCPeerConnection.prototype.getStats; | |
RTCPeerConnection.prototype.getStats = function(selector, onSucc, onErr) { | |
return nativeGetStats.apply(this, [selector || null]).then(function(stats) { | |
return makeMapStats(stats) | |
}).then(onSucc, onErr) | |
} | |
} | |
} | |
}; | |
module.exports = { | |
shimOnTrack: firefoxShim.shimOnTrack, | |
shimSourceObject: firefoxShim.shimSourceObject, | |
shimPeerConnection: firefoxShim.shimPeerConnection, | |
shimGetUserMedia: require("./getusermedia") | |
} | |
}, { | |
"../utils": 10, | |
"./getusermedia": 8 | |
}], | |
8: [function(require, module, exports) { | |
"use strict"; | |
var logging = require("../utils").log, | |
browserDetails = require("../utils").browserDetails; | |
module.exports = function() { | |
var shimError_ = function(e) { | |
return { | |
name: { | |
SecurityError: "NotAllowedError", | |
PermissionDeniedError: "NotAllowedError" | |
}[e.name] || e.name, | |
message: { | |
"The operation is insecure.": "The request is not allowed by the user agent or the platform in the current context." | |
}[e.message] || e.message, | |
constraint: e.constraint, | |
toString: function() { | |
return this.name + (this.message && ": ") + this.message | |
} | |
} | |
}, | |
getUserMedia_ = function(constraints, onSuccess, onError) { | |
var constraintsToFF37_ = function(c) { | |
if ("object" != typeof c || c.require) return c; | |
var require = []; | |
return Object.keys(c).forEach(function(key) { | |
if ("require" !== key && "advanced" !== key && "mediaSource" !== key) { | |
var r = c[key] = "object" == typeof c[key] ? c[key] : { | |
ideal: c[key] | |
}; | |
if (void 0 === r.min && void 0 === r.max && void 0 === r.exact || require.push(key), void 0 !== r.exact && ("number" == typeof r.exact ? r.min = r.max = r.exact : c[key] = r.exact, delete r.exact), void 0 !== r.ideal) { | |
c.advanced = c.advanced || []; | |
var oc = {}; | |
"number" == typeof r.ideal ? oc[key] = { | |
min: r.ideal, | |
max: r.ideal | |
} : oc[key] = r.ideal, c.advanced.push(oc), delete r.ideal, Object.keys(r).length || delete c[key] | |
} | |
} | |
}), require.length && (c.require = require), c | |
}; | |
return constraints = JSON.parse(JSON.stringify(constraints)), browserDetails.version < 38 && (logging("spec: " + JSON.stringify(constraints)), constraints.audio && (constraints.audio = constraintsToFF37_(constraints.audio)), constraints.video && (constraints.video = constraintsToFF37_(constraints.video)), logging("ff37: " + JSON.stringify(constraints))), navigator.mozGetUserMedia(constraints, onSuccess, function(e) { | |
onError(shimError_(e)) | |
}) | |
}, | |
getUserMediaPromise_ = function(constraints) { | |
return new Promise(function(resolve, reject) { | |
getUserMedia_(constraints, resolve, reject) | |
}) | |
}; | |
if (navigator.mediaDevices || (navigator.mediaDevices = { | |
getUserMedia: getUserMediaPromise_, | |
addEventListener: function() {}, | |
removeEventListener: function() {} | |
}), navigator.mediaDevices.enumerateDevices = navigator.mediaDevices.enumerateDevices || function() { | |
return new Promise(function(resolve) { | |
var infos = [{ | |
kind: "audioinput", | |
deviceId: "default", | |
label: "", | |
groupId: "" | |
}, { | |
kind: "videoinput", | |
deviceId: "default", | |
label: "", | |
groupId: "" | |
}]; | |
resolve(infos) | |
}) | |
}, browserDetails.version < 41) { | |
var orgEnumerateDevices = navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices); | |
navigator.mediaDevices.enumerateDevices = function() { | |
return orgEnumerateDevices().then(void 0, function(e) { | |
if ("NotFoundError" === e.name) return []; | |
throw e | |
}) | |
} | |
} | |
if (browserDetails.version < 49) { | |
var origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); | |
navigator.mediaDevices.getUserMedia = function(c) { | |
return origGetUserMedia(c).catch(function(e) { | |
return Promise.reject(shimError_(e)) | |
}) | |
} | |
} | |
navigator.getUserMedia = function(constraints, onSuccess, onError) { | |
return browserDetails.version < 44 ? getUserMedia_(constraints, onSuccess, onError) : void navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError) | |
} | |
} | |
}, { | |
"../utils": 10 | |
}], | |
9: [function(require, module, exports) { | |
"use strict"; | |
var safariShim = { | |
shimGetUserMedia: function() { | |
navigator.getUserMedia = navigator.webkitGetUserMedia | |
} | |
}; | |
module.exports = { | |
shimGetUserMedia: safariShim.shimGetUserMedia | |
} | |
}, {}], | |
10: [function(require, module, exports) { | |
"use strict"; | |
var logDisabled_ = !0, | |
utils = { | |
disableLog: function(bool) { | |
return "boolean" != typeof bool ? new Error("Argument type: " + typeof bool + ". Please use a boolean.") : (logDisabled_ = bool, bool ? "adapter.js logging disabled" : "adapter.js logging enabled") | |
}, | |
log: function() { | |
if ("object" == typeof window) { | |
if (logDisabled_) return; | |
"undefined" != typeof console && "function" == typeof console.log | |
} | |
}, | |
extractVersion: function(uastring, expr, pos) { | |
var match = uastring.match(expr); | |
return match && match.length >= pos && parseInt(match[pos], 10) | |
}, | |
detectBrowser: function() { | |
var result = {}; | |
if (result.browser = null, result.version = null, "undefined" == typeof window || !window.navigator) return result.browser = "Not a browser.", result; | |
if (navigator.mozGetUserMedia) result.browser = "firefox", result.version = this.extractVersion(navigator.userAgent, /Firefox\/([0-9]+)\./, 1); | |
else if (navigator.webkitGetUserMedia) | |
if (window.webkitRTCPeerConnection) result.browser = "chrome", result.version = this.extractVersion(navigator.userAgent, /Chrom(e|ium)\/([0-9]+)\./, 2); | |
else { | |
if (!navigator.userAgent.match(/Version\/(\d+).(\d+)/)) return result.browser = "Unsupported webkit-based browser with GUM support but no WebRTC support.", result; | |
result.browser = "safari", result.version = this.extractVersion(navigator.userAgent, /AppleWebKit\/([0-9]+)\./, 1) | |
} | |
else { | |
if (!navigator.mediaDevices || !navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)) return result.browser = "Not a supported browser.", result; | |
result.browser = "edge", result.version = this.extractVersion(navigator.userAgent, /Edge\/(\d+).(\d+)$/, 2) | |
} | |
return result | |
} | |
}; | |
module.exports = { | |
log: utils.log, | |
disableLog: utils.disableLog, | |
browserDetails: utils.detectBrowser(), | |
extractVersion: utils.extractVersion | |
} | |
}, {}] | |
}, {}, [2])(2) | |
}), AdapterJS.parseWebrtcDetectedBrowser(), navigator.mozGetUserMedia ? (MediaStreamTrack.getSources = function(successCb) { | |
setTimeout(function() { | |
var infos = [{ | |
kind: "audio", | |
id: "default", | |
label: "", | |
facing: "" | |
}, { | |
kind: "video", | |
id: "default", | |
label: "", | |
facing: "" | |
}]; | |
successCb(infos) | |
}, 0) | |
}, attachMediaStream = function(element, stream) { | |
return element.srcObject = stream, element | |
}, reattachMediaStream = function(to, from) { | |
return to.srcObject = from.srcObject, to | |
}, createIceServer = function(url, username, password) { | |
var iceServer = null, | |
urlParts = url.split(":"); | |
if (0 === urlParts[0].indexOf("stun")) iceServer = { | |
urls: [url] | |
}; | |
else if (0 === urlParts[0].indexOf("turn")) | |
if (webrtcDetectedVersion < 27) { | |
var turnUrlParts = url.split("?"); | |
1 !== turnUrlParts.length && 0 !== turnUrlParts[1].indexOf("transport=udp") || (iceServer = { | |
urls: [turnUrlParts[0]], | |
credential: password, | |
username: username | |
}) | |
} else iceServer = { | |
urls: [url], | |
credential: password, | |
username: username | |
}; | |
return iceServer | |
}, createIceServers = function(urls, username, password) { | |
var iceServers = []; | |
for (i = 0; i < urls.length; i++) { | |
var iceServer = createIceServer(urls[i], username, password); | |
null !== iceServer && iceServers.push(iceServer) | |
} | |
return iceServers | |
}) : navigator.webkitGetUserMedia ? (attachMediaStream = function(element, stream) { | |
return webrtcDetectedVersion >= 43 ? element.srcObject = stream : "undefined" != typeof element.src && (element.src = URL.createObjectURL(stream)), element | |
}, reattachMediaStream = function(to, from) { | |
return webrtcDetectedVersion >= 43 ? to.srcObject = from.srcObject : to.src = from.src, to | |
}, createIceServer = function(url, username, password) { | |
var iceServer = null, | |
urlParts = url.split(":"); | |
return 0 === urlParts[0].indexOf("stun") ? iceServer = { | |
url: url | |
} : 0 === urlParts[0].indexOf("turn") && (iceServer = { | |
url: url, | |
credential: password, | |
username: username | |
}), iceServer | |
}, createIceServers = function(urls, username, password) { | |
var iceServers = []; | |
if (webrtcDetectedVersion >= 34) iceServers = { | |
urls: urls, | |
credential: password, | |
username: username | |
}; | |
else | |
for (i = 0; i < urls.length; i++) { | |
var iceServer = createIceServer(urls[i], username, password); | |
null !== iceServer && iceServers.push(iceServer) | |
} | |
return iceServers | |
}) : navigator.mediaDevices && navigator.userAgent.match(/Edge\/(\d+).(\d+)$/) && (attachMediaStream = function(element, stream) { | |
return element.srcObject = stream, element | |
}, reattachMediaStream = function(to, from) { | |
return to.srcObject = from.srcObject, to | |
}), attachMediaStream_base = attachMediaStream, "opera" === webrtcDetectedBrowser && (attachMediaStream_base = function(element, stream) { | |
webrtcDetectedVersion > 38 ? element.srcObject = stream : "undefined" != typeof element.src && (element.src = URL.createObjectURL(stream)) | |
}), attachMediaStream = function(element, stream) { | |
return "chrome" !== webrtcDetectedBrowser && "opera" !== webrtcDetectedBrowser || stream ? attachMediaStream_base(element, stream) : element.src = "", element | |
}, reattachMediaStream_base = reattachMediaStream, reattachMediaStream = function(to, from) { | |
return reattachMediaStream_base(to, from), to | |
}, window.attachMediaStream = attachMediaStream, window.reattachMediaStream = reattachMediaStream, window.getUserMedia = function(constraints, onSuccess, onFailure) { | |
navigator.getUserMedia(constraints, onSuccess, onFailure) | |
}, AdapterJS.attachMediaStream = attachMediaStream, AdapterJS.reattachMediaStream = reattachMediaStream, AdapterJS.getUserMedia = getUserMedia, "undefined" == typeof Promise && (requestUserMedia = null), AdapterJS.maybeThroughWebRTCReady()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment