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