import adapter from "webrtc-adapter"; Janus.sessions = {}, Janus.isExtensionEnabled = function () { return !(!navigator.mediaDevices || !navigator.mediaDevices.getDisplayMedia) || (!window.navigator.userAgent.match("Chrome") || (e = parseInt(window.navigator.userAgent.match(/Chrome\/(.*) /)[1], 10), n = 33, window.navigator.userAgent.match("Linux") && (n = 35), 26 <= e && e <= n || Janus.extension.isInstalled())); var e, n }; var defaultExtension = { extensionId: "hapfgfdkleiggjjpfpenajgdnfckjpaj", isInstalled: function () { return null !== document.querySelector("#janus-extension-installed") }, getScreen: function (e) { var n = window.setTimeout(function () { return (error = new Error("NavigatorUserMediaError")).name = 'The required Chrome extension is not installed: click here to install it. (NOTE: this will need you to refresh the page)', e(error) }, 1e3); this.cache[n] = e, window.postMessage({ type: "janusGetScreen", id: n }, "*") }, init: function () { var a = {}; this.cache = a, window.addEventListener("message", function (e) { var n, r; e.origin == window.location.origin && ("janusGotScreen" == e.data.type && a[e.data.id] ? (n = a[e.data.id], delete a[e.data.id], "" === e.data.sourceId ? ((r = new Error("NavigatorUserMediaError")).name = "You cancelled the request for permission, giving up...", n(r)) : n(null, e.data.sourceId)) : "janusGetScreenPending" == e.data.type && (console.log("clearing ", e.data.id), window.clearTimeout(e.data.id))) }) } }; function Janus (u) { if (void 0 === Janus.initDone) return u.error("Library not initialized"), {}; if (!Janus.isWebrtcSupported()) return u.error("WebRTC not supported by this browser"), {}; if (Janus.log("Library initialized: " + Janus.initDone), (u = u || {}).success = "function" == typeof u.success ? u.success : Janus.noop, u.error = "function" == typeof u.error ? u.error : Janus.noop, u.destroyed = "function" == typeof u.destroyed ? u.destroyed : Janus.noop, null === u.server || void 0 === u.server) return u.error("Invalid server url"), {}; var c = !1, l = null, f = {}, v = null, o = null, t = 0, g = u.server, C = (Janus.isArray(g) ? (Janus.log("Multiple servers provided (" + g.length + "), will use the first that works"), g = null, o = u.server, Janus.debug(o)) : 0 === g.indexOf("ws") ? (c = !0, Janus.log("Using WebSockets to contact Janus: " + g)) : (c = !1, Janus.log("Using REST API to contact Janus: " + g)), u.iceServers), N = (null == C && (C = [{ urls: "stun:stun.l.google.com:19302" }]), u.iceTransportPolicy), F = u.bundlePolicy, R = u.ipv6, p = (null == R && (R = !1), !1), n = (void 0 !== u.withCredentials && null !== u.withCredentials && (p = !0 === u.withCredentials), 10), m = ((n = void 0 !== u.max_poll_events && null !== u.max_poll_events ? u.max_poll_events : n) < 1 && (n = 1), null), b = (void 0 !== u.token && null !== u.token && (m = u.token), null), s = (void 0 !== u.apisecret && null !== u.apisecret && (b = u.apisecret), this.destroyOnUnload = !0, void 0 !== u.destroyOnUnload && null !== u.destroyOnUnload && (this.destroyOnUnload = !0 === u.destroyOnUnload), 25e3), r = (void 0 !== u.keepAlivePeriod && null !== u.keepAlivePeriod && (s = u.keepAlivePeriod), isNaN(s) && (s = 25e3), 6e4), J = (void 0 !== u.longPollTimeout && null !== u.longPollTimeout && (r = u.longPollTimeout), isNaN(r) && (r = 6e4), !1), w = null, I = {}, i = this, U = 0, d = {}; function h () { var e; null != w && (Janus.debug("Long poll..."), J ? (e = g + "/" + w + "?rid=" + (new Date).getTime(), null != n && (e = e + "&maxev=" + n), null != m && (e = e + "&token=" + encodeURIComponent(m)), null != b && (e = e + "&apisecret=" + encodeURIComponent(b)), Janus.httpAPICall(e, { verb: "GET", withCredentials: p, success: S, timeout: r, error: function (e, n) { if (Janus.error(e + ":", n), 3 < ++U) return J = !1, void u.error("Lost connection to the server (is it down?)"); h() } })) : Janus.warn("Is the server down? (connected=false)")) } function S (e, n) { var r, a, o, t, s; if (U = 0, c || null == w || !0 === n || h(), !c && Janus.isArray(e)) for (var i = 0;i < e.length;i++)S(e[i], !0); else "keepalive" === e.janus ? Janus.vdebug("Got a keepalive on session " + w) : "ack" === e.janus ? (Janus.debug("Got an ack on session " + w), Janus.debug(e), null != (s = e.transaction) && (null != (t = d[s]) && t(e), delete d[s])) : "success" === e.janus ? (Janus.debug("Got a success on session " + w), Janus.debug(e), null != (s = e.transaction) && (null != (t = d[s]) && t(e), delete d[s])) : "trickle" === e.janus ? null == (r = e.sender) ? Janus.warn("Missing sender...") : null == (o = I[r]) ? Janus.debug("This handle is not attached to this session") : (n = e.candidate, Janus.debug("Got a trickled candidate on session " + w), Janus.debug(n), (a = o.webrtcStuff).pc && a.remoteSdp ? (Janus.debug("Adding remote candidate:", n), n && !0 !== n.completed ? a.pc.addIceCandidate(n) : a.pc.addIceCandidate()) : (Janus.debug("We didn't do setRemoteDescription (trickle got here before the offer?), caching candidate"), a.candidates || (a.candidates = []), a.candidates.push(n), Janus.debug(a.candidates))) : "webrtcup" === e.janus ? (Janus.debug("Got a webrtcup event on session " + w), Janus.debug(e), null == (r = e.sender) ? Janus.warn("Missing sender...") : null == (o = I[r]) ? Janus.debug("This handle is not attached to this session") : o.webrtcState(!0)) : "hangup" === e.janus ? (Janus.debug("Got a hangup event on session " + w), Janus.debug(e), null == (r = e.sender) ? Janus.warn("Missing sender...") : null == (o = I[r]) ? Janus.debug("This handle is not attached to this session") : (o.webrtcState(!1, e.reason), o.hangup())) : "detached" === e.janus ? (Janus.debug("Got a detached event on session " + w), Janus.debug(e), null == (r = e.sender) ? Janus.warn("Missing sender...") : null != (o = I[r]) && (o.detached = !0, o.ondetached(), o.detach())) : "media" === e.janus ? (Janus.debug("Got a media event on session " + w), Janus.debug(e), null == (r = e.sender) ? Janus.warn("Missing sender...") : null == (o = I[r]) ? Janus.debug("This handle is not attached to this session") : o.mediaState(e.type, e.receiving)) : "slowlink" === e.janus ? (Janus.debug("Got a slowlink event on session " + w), Janus.debug(e), null == (r = e.sender) ? Janus.warn("Missing sender...") : null == (o = I[r]) ? Janus.debug("This handle is not attached to this session") : o.slowLink(e.uplink, e.nacks)) : "error" === e.janus ? (Janus.error("Ooops: " + e.error.code + " " + e.error.reason), Janus.debug(e), null != (s = e.transaction) && (null != (t = d[s]) && t(e), delete d[s])) : "event" === e.janus ? (Janus.debug("Got a plugin event on session " + w), Janus.debug(e), null == (r = e.sender) ? Janus.warn("Missing sender...") : null == (n = e.plugindata) ? Janus.warn("Missing plugindata...") : (Janus.debug(" -- Event is coming from " + r + " (" + n.plugin + ")"), a = n.data, Janus.debug(a), null == (o = I[r]) ? Janus.warn("This handle is not attached to this session") : (null != (t = e.jsep) && (Janus.debug("Handling SDP as well..."), Janus.debug(t)), null != (s = o.onmessage) ? (Janus.debug("Notifying application..."), s(a, t)) : Janus.debug("No provided notification callback")))) : "timeout" === e.janus ? (Janus.error("Timeout on session " + w), Janus.debug(e), c && l.close(3504, "Gateway timeout")) : (Janus.warn("Unknown message/event '" + e.janus + "' on session " + w), Janus.debug(e)) } function W () { var e; null !== g && c && J && (v = setTimeout(W, s), e = { janus: "keepalive", session_id: w, transaction: Janus.randomString(12) }, null != m && (e.token = m), null != b && (e.apisecret = b), l.send(JSON.stringify(e))) } function y (r) { var e = Janus.randomString(12), n = { janus: "create", transaction: e }; if (r.reconnect && (J = !1, n.janus = "claim", n.session_id = w, l && (l.onopen = null, l.onerror = null, l.onclose = null, v && (clearTimeout(v), v = null))), null != m && (n.token = m), null != b && (n.apisecret = b), null === g && Janus.isArray(o) && (0 === (g = o[t]).indexOf("ws") ? (c = !0, Janus.log("Server #" + (t + 1) + ": trying WebSockets to contact success(" + g + ")")) : (c = !1, Janus.log("Server #" + (t + 1) + ": trying REST API to contact Janus (" + g + ")"))), c) for (var a in l = Janus.newWebSocket(g, "janus-protocol"), f = { error: function () { if (Janus.error("Error connecting to the Janus WebSockets server... " + g), Janus.isArray(o) && !r.reconnect) return ++t == o.length ? void r.error("Error connecting to any of the provided Janus servers: Is the server down?") : (g = null, void setTimeout(function () { y(r) }, 200)); r.error("Error connecting to the Janus WebSockets server: Is the server down?") }, open: function () { d[e] = function (e) { if (Janus.debug(e), "success" !== e.janus) return Janus.error("Ooops: " + e.error.code + " " + e.error.reason), void r.error(e.error.reason); v = setTimeout(W, s), J = !0, w = e.session_id || e.data.id, r.reconnect ? Janus.log("Claimed session: " + w) : Janus.log("Created session: " + w), Janus.sessions[w] = i, r.success() }, l.send(JSON.stringify(n)) }, message: function (e) { S(JSON.parse(e.data)) }, close: function () { null !== g && J && (J = !1, u.error("Lost connection to the server (is it down?)")) } }) l.addEventListener(a, f[a]); else Janus.httpAPICall(g, { verb: "POST", withCredentials: p, body: n, success: function (e) { if (Janus.debug(e), "success" !== e.janus) return Janus.error("Ooops: " + e.error.code + " " + e.error.reason), void r.error(e.error.reason); J = !0, w = e.session_id || e.data.id, r.reconnect ? Janus.log("Claimed session: " + w) : Janus.log("Created session: " + w), Janus.sessions[w] = i, h(), r.success() }, error: function (e, n) { if (Janus.error(e + ":", n), Janus.isArray(o) && !r.reconnect) return ++t == o.length ? void r.error("Error connecting to any of the provided Janus servers: Is the server down?") : (g = null, void setTimeout(function () { y(r) }, 200)); "" === n ? r.error(e + ": Is the server down?") : r.error(e + ": " + n) } }) } function q (e, r) { if ((r = r || {}).success = "function" == typeof r.success ? r.success : Janus.noop, r.error = "function" == typeof r.error ? r.error : Janus.noop, !J) return Janus.warn("Is the server down? (connected=false)"), void r.error("Is the server down? (connected=false)"); var n, a, o, t = I[e]; return null == t || null === t.webrtcStuff || void 0 === t.webrtcStuff ? (Janus.warn("Invalid handle"), void r.error("Invalid handle")) : (a = r.message, n = r.jsep, o = { janus: "message", body: a, transaction: a = Janus.randomString(12) }, null !== t.token && void 0 !== t.token && (o.token = t.token), null != b && (o.apisecret = b), null != n && (o.jsep = n), Janus.debug("Sending message to plugin (handle=" + e + "):"), Janus.debug(o), c ? (o.session_id = w, o.handle_id = e, d[a] = function (e) { if (Janus.debug("Message sent!"), Janus.debug(e), "success" === e.janus) { var n = e.plugindata; if (null == n) return Janus.warn("Request succeeded, but missing plugindata..."), void r.success(); Janus.log("Synchronous transaction successful (" + n.plugin + ")"); n = n.data; return Janus.debug(n), void r.success(n) } "ack" !== e.janus ? void 0 !== e.error && null !== e.error ? (Janus.error("Ooops: " + e.error.code + " " + e.error.reason), r.error(e.error.code + " " + e.error.reason)) : (Janus.error("Unknown error"), r.error("Unknown error")) : r.success() }, void l.send(JSON.stringify(o))) : void Janus.httpAPICall(g + "/" + w + "/" + e, { verb: "POST", withCredentials: p, body: o, success: function (e) { if (Janus.debug("Message sent!"), Janus.debug(e), "success" === e.janus) { var n = e.plugindata; if (null == n) return Janus.warn("Request succeeded, but missing plugindata..."), void r.success(); Janus.log("Synchronous transaction successful (" + n.plugin + ")"); n = n.data; return Janus.debug(n), void r.success(n) } "ack" !== e.janus ? void 0 !== e.error && null !== e.error ? (Janus.error("Ooops: " + e.error.code + " " + e.error.reason), r.error(e.error.code + " " + e.error.reason)) : (Janus.error("Unknown error"), r.error("Unknown error")) : r.success() }, error: function (e, n) { Janus.error(e + ":", n), r.error(e + ": " + n) } })) } function _ (e, n) { if (J) { var r = I[e]; if (null == r || null === r.webrtcStuff || void 0 === r.webrtcStuff) Janus.warn("Invalid handle"); else { n = { janus: "trickle", candidate: n, transaction: Janus.randomString(12) }; if (null !== r.token && void 0 !== r.token && (n.token = r.token), null != b && (n.apisecret = b), Janus.vdebug("Sending trickle candidate (handle=" + e + "):"), Janus.vdebug(n), c) return n.session_id = w, n.handle_id = e, void l.send(JSON.stringify(n)); Janus.httpAPICall(g + "/" + w + "/" + e, { verb: "POST", withCredentials: p, body: n, success: function (e) { Janus.vdebug("Candidate sent!"), Janus.vdebug(e), "ack" !== e.janus && Janus.error("Ooops: " + e.error.code + " " + e.error.reason) }, error: function (e, n) { Janus.error(e + ":", n) } }) } } else Janus.warn("Is the server down? (connected=false)") } function V (e, n, r, a) { var o, t = I[e]; null == t || null === t.webrtcStuff || void 0 === t.webrtcStuff ? Janus.warn("Invalid handle") : (e = function (e) { Janus.log("Received state change on data channel:", e); var n = e.target.label, e = o.dataChannel[n] ? o.dataChannel[n].readyState : "null"; if (Janus.log("State change on <" + n + "> data channel: " + e), "open" === e) { if (o.dataChannel[n].pending && 0 < o.dataChannel[n].pending.length) { for (var r in Janus.log("Sending pending messages on <' + label + '>:", o.dataChannel[n].pending.length), o.dataChannel[n].pending) { r = o.dataChannel[n].pending[r]; Janus.log("Sending string on data channel <" + n + ">: " + r), o.dataChannel[n].send(r) } o.dataChannel[n].pending = [] } t.ondataopen(n) } }, (o = t.webrtcStuff).dataChannel[n] = r || o.pc.createDataChannel(n, { ordered: !1 }), o.dataChannel[n].onmessage = function (e) { Janus.log("Received message on data channel:", e); var n = e.target.label; t.ondata(e.data, n) }, o.dataChannel[n].onopen = e, o.dataChannel[n].onclose = e, o.dataChannel[n].onerror = function (e) { Janus.error("Got error on data channel:", e) }, o.dataChannel[n].pending = [], a && o.dataChannel[n].pending.push(a)) } function G (e, n) { (n = n || {}).success = "function" == typeof n.success ? n.success : Janus.noop, n.error = "function" == typeof n.error ? n.error : Janus.noop; var r = I[e]; if (null == r || null === r.webrtcStuff || void 0 === r.webrtcStuff) return Janus.warn("Invalid handle"), void n.error("Invalid handle"); var a, r = r.webrtcStuff, o = n.text; return null == o ? (Janus.warn("Invalid text"), void n.error("Invalid text")) : (a = n.label || Janus.dataChanDefaultLabel, r.dataChannel[a] ? "open" !== r.dataChannel[a].readyState ? r.dataChannel[a].pending.push(o) : (Janus.log("Sending string on data channel <" + a + ">: " + o), r.dataChannel[a].send(o)) : V(e, a, !1, o), void n.success()) } function B (e, n) { (n = n || {}).success = "function" == typeof n.success ? n.success : Janus.noop, n.error = "function" == typeof n.error ? n.error : Janus.noop; e = I[e]; if (null == e || null === e.webrtcStuff || void 0 === e.webrtcStuff) return Janus.warn("Invalid handle"), void n.error("Invalid handle"); e = e.webrtcStuff; if (null === e.dtmfSender || void 0 === e.dtmfSender) { if (void 0 !== e.pc && null !== e.pc) { var r = e.pc.getSenders().find(function (e) { return e.track && "audio" === e.track.kind }); if (!r) return Janus.warn("Invalid DTMF configuration (no audio track)"), void n.error("Invalid DTMF configuration (no audio track)"); e.dtmfSender = r.dtmf, e.dtmfSender && (Janus.log("Created DTMF Sender"), e.dtmfSender.ontonechange = function (e) { Janus.debug("Sent DTMF tone: " + e.tone) }) } if (null === e.dtmfSender || void 0 === e.dtmfSender) return Janus.warn("Invalid DTMF configuration"), void n.error("Invalid DTMF configuration") } r = n.dtmf; if (null == r) return Janus.warn("Invalid DTMF parameters"), void n.error("Invalid DTMF parameters"); var a = r.tones; if (null == a) return Janus.warn("Invalid DTMF string"), void n.error("Invalid DTMF string"); var o = r.duration, r = r.gap; Janus.debug("Sending DTMF string " + a + " (duration " + (o = null == o ? 500 : o) + "ms, gap " + (r = null == r ? 50 : r) + "ms)"), e.dtmfSender.insertDTMF(a, o, r), n.success() } function k (r, a) { (a = a || {}).success = "function" == typeof a.success ? a.success : Janus.noop, a.error = "function" == typeof a.error ? a.error : Janus.noop; var e = !0, n = (void 0 !== a.asyncRequest && null !== a.asyncRequest && (e = !0 === a.asyncRequest), !0), o = (void 0 !== a.noRequest && null !== a.noRequest && (n = !0 === a.noRequest), Janus.log("Destroying handle " + r + " (async=" + e + ")"), M(r), I[r]); return null == o || o.detached || n ? (delete I[r], void a.success()) : J ? (n = { janus: "detach", transaction: Janus.randomString(12) }, null !== o.token && void 0 !== o.token && (n.token = o.token), null != b && (n.apisecret = b), c ? (n.session_id = w, n.handle_id = r, l.send(JSON.stringify(n)), delete I[r], void a.success()) : void Janus.httpAPICall(g + "/" + w + "/" + r, { verb: "POST", async: e, withCredentials: p, body: n, success: function (e) { Janus.log("Destroyed handle:"), Janus.debug(e), "success" !== e.janus && Janus.error("Ooops: " + e.error.code + " " + e.error.reason), delete I[r], a.success() }, error: function (e, n) { Janus.error(e + ":", n), delete I[r], a.success() } })) : (Janus.warn("Is the server down? (connected=false)"), void a.error("Is the server down? (connected=false)")) } function T (v, g, p, m, n) { var r = I[v]; if (null == r || null === r.webrtcStuff || void 0 === r.webrtcStuff) return Janus.warn("Invalid handle"), void m.error("Invalid handle"); var a, b = r.webrtcStuff, e = (Janus.debug("streamsDone:", n), n && (Janus.debug(" -- Audio tracks:", n.getAudioTracks()), Janus.debug(" -- Video tracks:", n.getVideoTracks())), !1); if (b.myStream && p.update && !b.streamExternal) { if ((!p.update && O(p) || p.update && (p.addAudio || p.replaceAudio)) && n.getAudioTracks() && n.getAudioTracks().length) if (b.myStream.addTrack(n.getAudioTracks()[0]), "firefox" === Janus.webRTCAdapter.browserDetails.browser && 59 <= Janus.webRTCAdapter.browserDetails.version || "safari" === Janus.webRTCAdapter.browserDetails.browser && window.RTCRtpSender.prototype.replaceTrack || "chrome" === Janus.webRTCAdapter.browserDetails.browser && 72 <= Janus.webRTCAdapter.browserDetails.version) { Janus.log((p.replaceAudio ? "Replacing" : "Adding") + " audio track:", n.getAudioTracks()[0]); var o = null; if ((s = b.pc.getTransceivers()) && 0 < s.length) for (var t in s) if ((i = s[t]).sender && i.sender.track && "audio" === i.sender.track.kind || i.receiver && i.receiver.track && "audio" === i.receiver.track.kind) { o = i; break } o && o.sender ? o.sender.replaceTrack(n.getAudioTracks()[0]) : b.pc.addTrack(n.getAudioTracks()[0], n) } else Janus.log((p.replaceAudio ? "Replacing" : "Adding") + " audio track:", n.getAudioTracks()[0]), b.pc.addTrack(n.getAudioTracks()[0], n); if ((!p.update && E(p) || p.update && (p.addVideo || p.replaceVideo)) && n.getVideoTracks() && n.getVideoTracks().length) if (b.myStream.addTrack(n.getVideoTracks()[0]), "firefox" === Janus.webRTCAdapter.browserDetails.browser && 59 <= Janus.webRTCAdapter.browserDetails.version || "safari" === Janus.webRTCAdapter.browserDetails.browser && window.RTCRtpSender.prototype.replaceTrack || "chrome" === Janus.webRTCAdapter.browserDetails.browser && 72 <= Janus.webRTCAdapter.browserDetails.version) { Janus.log((p.replaceVideo ? "Replacing" : "Adding") + " video track:", n.getVideoTracks()[0]); var s, i, d = null; if ((s = b.pc.getTransceivers()) && 0 < s.length) for (var t in s) if ((i = s[t]).sender && i.sender.track && "video" === i.sender.track.kind || i.receiver && i.receiver.track && "video" === i.receiver.track.kind) { d = i; break } d && d.sender ? d.sender.replaceTrack(n.getVideoTracks()[0]) : b.pc.addTrack(n.getVideoTracks()[0], n) } else Janus.log((p.replaceVideo ? "Replacing" : "Adding") + " video track:", n.getVideoTracks()[0]), b.pc.addTrack(n.getVideoTracks()[0], n) } else b.myStream = n, e = !0; if (!b.pc) { var u = { iceServers: C, iceTransportPolicy: N, bundlePolicy: F }, c = ("chrome" === Janus.webRTCAdapter.browserDetails.browser && (u.sdpSemantics = Janus.webRTCAdapter.browserDetails.version < 72 ? "plan-b" : "unified-plan"), { optional: [{ DtlsSrtpKeyAgreement: !0 }] }); if (!0 === R && c.optional.push({ googIPv6: !0 }), m.rtcConstraints && "object" == typeof m.rtcConstraints) for (var t in Janus.debug("Adding custom PeerConnection constraints:", m.rtcConstraints), m.rtcConstraints) c.optional.push(m.rtcConstraints[t]); "edge" === Janus.webRTCAdapter.browserDetails.browser && (u.bundlePolicy = "max-bundle"), Janus.log("Creating PeerConnection"), Janus.debug(c), b.pc = new RTCPeerConnection(u, c), Janus.debug(b.pc), b.pc.getStats && (b.volume = {}, b.bitrate.value = "0 kbits/sec"), Janus.log("Preparing local SDP and gathering candidates (trickle=" + b.trickle + ")"), b.pc.oniceconnectionstatechange = function (e) { b.pc && r.iceState(b.pc.iceConnectionState) }, b.pc.onicecandidate = function (e) { var n, r; null == e.candidate || "edge" === Janus.webRTCAdapter.browserDetails.browser && 0 < e.candidate.candidate.indexOf("endOfCandidates") ? (Janus.log("End of candidates."), (b.iceDone = !0) === b.trickle ? _(v, { completed: !0 }) : (n = v, (r = (r = m) || {}).success = "function" == typeof r.success ? r.success : Janus.noop, r.error = "function" == typeof r.error ? r.error : Janus.noop, null == (n = I[n]) || null === n.webrtcStuff || void 0 === n.webrtcStuff ? Janus.warn("Invalid handle, not sending anything") : (n = n.webrtcStuff, Janus.log("Sending offer/answer SDP..."), null === n.mySdp || void 0 === n.mySdp ? Janus.warn("Local SDP instance is invalid, not sending anything...") : (!(n.mySdp = { type: n.pc.localDescription.type, sdp: n.pc.localDescription.sdp }) === n.trickle && (n.mySdp.trickle = !1), Janus.debug(r), n.sdpSent = !0, r.success(n.mySdp))))) : (console.log("candidate", 111), r = { candidate: e.candidate.candidate, sdpMid: e.candidate.sdpMid, sdpMLineIndex: e.candidate.sdpMLineIndex }, !0 === b.trickle && _(v, r)) }, b.pc.ontrack = function (e) { Janus.log("Handling Remote Track"), Janus.debug(e), e.streams && (b.remoteStream = e.streams[0], r.onremotestream(b.remoteStream), e.track && !e.track.onended && (Janus.log("Adding onended callback to track:", e.track), e.track.onended = function (e) { Janus.log("Remote track removed:", e), b.remoteStream && (b.remoteStream.removeTrack(e.target), r.onremotestream(b.remoteStream)) })) } } if (e && null != n && (Janus.log("Adding local stream"), a = !0 === m.simulcast2, n.getTracks().forEach(function (e) { Janus.log("Adding local track:", e), !a || "audio" === e.kind ? b.pc.addTrack(e, n) : (Janus.log("Enabling rid-based simulcasting:", e), b.pc.addTransceiver(e, { direction: "sendrecv", streams: [n], sendEncodings: [{ rid: "h", active: !0, maxBitrate: 9e5 }, { rid: "m", active: !0, maxBitrate: 3e5, scaleResolutionDownBy: 2 }, { rid: "l", active: !0, maxBitrate: 1e5, scaleResolutionDownBy: 4 }] })) })), u = p, Janus.debug("isDataEnabled:", u), ("edge" != Janus.webRTCAdapter.browserDetails.browser ? null == u || !0 !== u.data : (Janus.warn("Edge doesn't support data channels yet"), 1)) || b.dataChannel[Janus.dataChanDefaultLabel] || (Janus.log("Creating data channel"), V(v, Janus.dataChanDefaultLabel, !1), b.pc.ondatachannel = function (e) { Janus.log("Data channel created by Janus:", e), V(v, e.channel.label, e.channel) }), b.myStream && r.onlocalstream(b.myStream), null == g) { var e = v, l = p, f = m; if ((f = f || {}).success = "function" == typeof f.success ? f.success : Janus.noop, f.error = "function" == typeof f.error ? f.error : Janus.noop, f.customizeSdp = "function" == typeof f.customizeSdp ? f.customizeSdp : Janus.noop, null == (e = I[e]) || null === e.webrtcStuff || void 0 === e.webrtcStuff) Janus.warn("Invalid handle"), f.error("Invalid handle"); else { var J = e.webrtcStuff, w = !0 === f.simulcast, h = (w ? Janus.log("Creating offer (iceDone=" + J.iceDone + ", simulcast=" + w + ")") : Janus.log("Creating offer (iceDone=" + J.iceDone + ")"), {}); if ("firefox" === Janus.webRTCAdapter.browserDetails.browser && 59 <= Janus.webRTCAdapter.browserDetails.version || "safari" === Janus.webRTCAdapter.browserDetails.browser && window.RTCRtpSender.prototype.replaceTrack || "chrome" === Janus.webRTCAdapter.browserDetails.browser && 72 <= Janus.webRTCAdapter.browserDetails.version) { var S = null, y = null, k = J.pc.getTransceivers(); if (k && 0 < k.length) for (var T in k) { T = k[T]; T.sender && T.sender.track && "audio" === T.sender.track.kind || T.receiver && T.receiver.track && "audio" === T.receiver.track.kind ? S = S || T : (T.sender && T.sender.track && "video" === T.sender.track.kind || T.receiver && T.receiver.track && "video" === T.receiver.track.kind) && (y = y || T) } var e = O(l), D = j(l), e = (e || D ? e && D ? S && (S.setDirection ? S.setDirection("sendrecv") : S.direction = "sendrecv", Janus.log("Setting audio transceiver to sendrecv:", S)) : e && !D ? S && (S.setDirection ? S.setDirection("sendonly") : S.direction = "sendonly", Janus.log("Setting audio transceiver to sendonly:", S)) : !e && D && (S ? (S.setDirection ? S.setDirection("recvonly") : S.direction = "recvonly", Janus.log("Setting audio transceiver to recvonly:", S)) : (S = J.pc.addTransceiver("audio", { direction: "recvonly" }), Janus.log("Adding recvonly audio transceiver:", S))) : l.removeAudio && S && (S.setDirection ? S.setDirection("inactive") : S.direction = "inactive", Janus.log("Setting audio transceiver to inactive:", S)), E(l)), D = L(l); e || D ? e && D ? y && (y.setDirection ? y.setDirection("sendrecv") : y.direction = "sendrecv", Janus.log("Setting video transceiver to sendrecv:", y)) : e && !D ? y && (y.setDirection ? y.setDirection("sendonly") : y.direction = "sendonly", Janus.log("Setting video transceiver to sendonly:", y)) : !e && D && (y ? (y.setDirection ? y.setDirection("recvonly") : y.direction = "recvonly", Janus.log("Setting video transceiver to recvonly:", y)) : (y = J.pc.addTransceiver("video", { direction: "recvonly" }), Janus.log("Adding recvonly video transceiver:", y))) : l.removeVideo && y && (y.setDirection ? y.setDirection("inactive") : y.direction = "inactive", Janus.log("Setting video transceiver to inactive:", y)) } else h.offerToReceiveAudio = j(l), h.offerToReceiveVideo = L(l); !0 === f.iceRestart && (h.iceRestart = !0), Janus.debug(h); var A = E(l); A && w && "firefox" === Janus.webRTCAdapter.browserDetails.browser && (Janus.log("Enabling Simulcasting for Firefox (RID)"), (e = J.pc.getSenders().find(function (e) { return "video" == e.track.kind })) && ((D = (D = e.getParameters()) || {}).encodings = [{ rid: "h", active: !0, maxBitrate: 9e5 }, { rid: "m", active: !0, maxBitrate: 3e5, scaleResolutionDownBy: 2 }, { rid: "l", active: !0, maxBitrate: 1e5, scaleResolutionDownBy: 4 }], e.setParameters(D))), J.pc.createOffer(h).then(function (e) { Janus.debug(e); var n = { type: e.type, sdp: e.sdp }; f.customizeSdp(n), e.sdp = n.sdp, Janus.log("Setting local description"), A && w && ("chrome" === Janus.webRTCAdapter.browserDetails.browser || "safari" === Janus.webRTCAdapter.browserDetails.browser ? (Janus.log("Enabling Simulcasting for Chrome (SDP munging)"), e.sdp = function (e) { for (var n = e.split("\r\n"), r = !1, a = [-1], o = [-1], t = null, s = null, i = null, d = null, u = -1, c = 0;c < n.length;c++) { var l = n[c].match(/m=(\w+) */); if (l) { if ("video" === l[1]) { if (!(a[0] < 0)) { u = c; break } r = !0 } else if (-1 < a[0]) { u = c; break } } else if (r) { var f = n[c].match(/a=ssrc-group:FID (\d+) (\d+)/); if (f) a[0] = f[1], o[0] = f[2], n.splice(c, 1), c--; else { if (a[0]) { if ((v = n[c].match("a=ssrc:" + a[0] + " cname:(.+)")) && (t = v[1]), (v = n[c].match("a=ssrc:" + a[0] + " msid:(.+)")) && (s = v[1]), (v = n[c].match("a=ssrc:" + a[0] + " mslabel:(.+)")) && (i = v[1]), (v = n[c].match("a=ssrc:" + a[0] + " label:(.+)")) && (d = v[1]), 0 === n[c].indexOf("a=ssrc:" + o[0])) { n.splice(c, 1), c--; continue } if (0 === n[c].indexOf("a=ssrc:" + a[0])) { n.splice(c, 1), c--; continue } } 0 == n[c].length && (n.splice(c, 1), c--) } } } if (a[0] < 0) { r = !(u = -1); for (c = 0;c < n.length;c++) { var v, l = n[c].match(/m=(\w+) */); if (l) { if ("video" === l[1]) { if (!(a[0] < 0)) { u = c; break } r = !0 } else if (-1 < a[0]) { u = c; break } } else if (r) { if (a[0] < 0) { var g = n[c].match(/a=ssrc:(\d+)/); if (g) { a[0] = g[1], n.splice(c, 1), c--; continue } } else { if ((v = n[c].match("a=ssrc:" + a[0] + " cname:(.+)")) && (t = v[1]), (v = n[c].match("a=ssrc:" + a[0] + " msid:(.+)")) && (s = v[1]), (v = n[c].match("a=ssrc:" + a[0] + " mslabel:(.+)")) && (i = v[1]), (v = n[c].match("a=ssrc:" + a[0] + " label:(.+)")) && (d = v[1]), 0 === n[c].indexOf("a=ssrc:" + o[0])) { n.splice(c, 1), c--; continue } if (0 === n[c].indexOf("a=ssrc:" + a[0])) { n.splice(c, 1), c--; continue } } 0 == n[c].length && (n.splice(c, 1), c--) } } } if (a[0] < 0) return Janus.warn("Couldn't find the video SSRC, simulcasting NOT enabled"), e; u < 0 && (u = n.length); a[1] = Math.floor(4294967295 * Math.random()), a[2] = Math.floor(4294967295 * Math.random()), o[1] = Math.floor(4294967295 * Math.random()), o[2] = Math.floor(4294967295 * Math.random()); for (c = 0;c < a.length;c++)t && (n.splice(u, 0, "a=ssrc:" + a[c] + " cname:" + t), u++), s && (n.splice(u, 0, "a=ssrc:" + a[c] + " msid:" + s), u++), i && (n.splice(u, 0, "a=ssrc:" + a[c] + " mslabel:" + i), u++), d && (n.splice(u, 0, "a=ssrc:" + a[c] + " label:" + d), u++), t && (n.splice(u, 0, "a=ssrc:" + o[c] + " cname:" + t), u++), s && (n.splice(u, 0, "a=ssrc:" + o[c] + " msid:" + s), u++), i && (n.splice(u, 0, "a=ssrc:" + o[c] + " mslabel:" + i), u++), d && (n.splice(u, 0, "a=ssrc:" + o[c] + " label:" + d), u++); n.splice(u, 0, "a=ssrc-group:FID " + a[2] + " " + o[2]), n.splice(u, 0, "a=ssrc-group:FID " + a[1] + " " + o[1]), n.splice(u, 0, "a=ssrc-group:FID " + a[0] + " " + o[0]), n.splice(u, 0, "a=ssrc-group:SIM " + a[0] + " " + a[1] + " " + a[2]), (e = n.join("\r\n")).endsWith("\r\n") || (e += "\r\n"); return e }(e.sdp)) : "firefox" !== Janus.webRTCAdapter.browserDetails.browser && Janus.warn("simulcast=true, but this is not Chrome nor Firefox, ignoring")), J.mySdp = e.sdp, J.pc.setLocalDescription(e).catch(f.error), J.mediaConstraints = h, J.iceDone || J.trickle ? (Janus.log("Offer ready"), Janus.debug(f), f.success(e)) : Janus.log("Waiting for all candidates...") }, f.error) } } else b.pc.setRemoteDescription(g).then(function () { if (Janus.log("Remote description accepted!"), b.remoteSdp = g.sdp, b.candidates && 0 < b.candidates.length) { for (var e in b.candidates) { e = b.candidates[e]; Janus.debug("Adding remote candidate:", e), e && !0 !== e.completed ? b.pc.addIceCandidate(e) : b.pc.addIceCandidate() } b.candidates = [] } var n = v, r = p, a = m; if ((a = a || {}).success = "function" == typeof a.success ? a.success : Janus.noop, a.error = "function" == typeof a.error ? a.error : Janus.noop, a.customizeSdp = "function" == typeof a.customizeSdp ? a.customizeSdp : Janus.noop, null == (n = I[n]) || null === n.webrtcStuff || void 0 === n.webrtcStuff) Janus.warn("Invalid handle"), a.error("Invalid handle"); else { var o = n.webrtcStuff, t = !0 === a.simulcast, s = (t ? Janus.log("Creating answer (iceDone=" + o.iceDone + ", simulcast=" + t + ")") : Janus.log("Creating answer (iceDone=" + o.iceDone + ")"), null); if ("firefox" === Janus.webRTCAdapter.browserDetails.browser && 59 <= Janus.webRTCAdapter.browserDetails.version || "safari" === Janus.webRTCAdapter.browserDetails.browser && window.RTCRtpSender.prototype.replaceTrack || "chrome" === Janus.webRTCAdapter.browserDetails.browser && 72 <= Janus.webRTCAdapter.browserDetails.version) { s = {}; var i = null, d = null, u = o.pc.getTransceivers(); if (u && 0 < u.length) for (var c in u) { c = u[c]; c.sender && c.sender.track && "audio" === c.sender.track.kind || c.receiver && c.receiver.track && "audio" === c.receiver.track.kind ? i = i || c : (c.sender && c.sender.track && "video" === c.sender.track.kind || c.receiver && c.receiver.track && "video" === c.receiver.track.kind) && (d = d || c) } var n = O(r), l = j(r), n = (n || l ? n && l ? i && (i.setDirection ? i.setDirection("sendrecv") : i.direction = "sendrecv", Janus.log("Setting audio transceiver to sendrecv:", i)) : n && !l ? i && (i.setDirection ? i.setDirection("sendonly") : i.direction = "sendonly", Janus.log("Setting audio transceiver to sendonly:", i)) : !n && l && (i ? (i.setDirection ? i.setDirection("recvonly") : i.direction = "recvonly", Janus.log("Setting audio transceiver to recvonly:", i)) : (i = o.pc.addTransceiver("audio", { direction: "recvonly" }), Janus.log("Adding recvonly audio transceiver:", i))) : r.removeAudio && i && (i.setDirection ? i.setDirection("inactive") : i.direction = "inactive", Janus.log("Setting audio transceiver to inactive:", i)), E(r)), l = L(r); n || l ? n && l ? d && (d.setDirection ? d.setDirection("sendrecv") : d.direction = "sendrecv", Janus.log("Setting video transceiver to sendrecv:", d)) : n && !l ? d && (d.setDirection ? d.setDirection("sendonly") : d.direction = "sendonly", Janus.log("Setting video transceiver to sendonly:", d)) : !n && l && (d ? (d.setDirection ? d.setDirection("recvonly") : d.direction = "recvonly", Janus.log("Setting video transceiver to recvonly:", d)) : (d = o.pc.addTransceiver("video", { direction: "recvonly" }), Janus.log("Adding recvonly video transceiver:", d))) : r.removeVideo && d && (d.setDirection ? d.setDirection("inactive") : d.direction = "inactive", Janus.log("Setting video transceiver to inactive:", d)) } else s = "firefox" == Janus.webRTCAdapter.browserDetails.browser || "edge" == Janus.webRTCAdapter.browserDetails.browser ? { offerToReceiveAudio: j(r), offerToReceiveVideo: L(r) } : { mandatory: { OfferToReceiveAudio: j(r), OfferToReceiveVideo: L(r) } }; Janus.debug(s); var f = E(r); f && t && "firefox" === Janus.webRTCAdapter.browserDetails.browser && (Janus.log("Enabling Simulcasting for Firefox (RID)"), n = o.pc.getSenders()[1], Janus.log(n), l = n.getParameters(), Janus.log(l), n.setParameters({ encodings: [{ rid: "high", active: !0, priority: "high", maxBitrate: 1e6 }, { rid: "medium", active: !0, priority: "medium", maxBitrate: 3e5 }, { rid: "low", active: !0, priority: "low", maxBitrate: 1e5 }] })), o.pc.createAnswer(s).then(function (e) { Janus.debug(e); var n = { type: e.type, sdp: e.sdp }; a.customizeSdp(n), e.sdp = n.sdp, Janus.log("Setting local description"), f && t && ("chrome" === Janus.webRTCAdapter.browserDetails.browser ? Janus.warn("simulcast=true, but this is an answer, and video breaks in Chrome if we enable it") : "firefox" !== Janus.webRTCAdapter.browserDetails.browser && Janus.warn("simulcast=true, but this is not Chrome nor Firefox, ignoring")), o.mySdp = e.sdp, o.pc.setLocalDescription(e).catch(a.error), o.mediaConstraints = s, o.iceDone || o.trickle ? a.success(e) : Janus.log("Waiting for all candidates...") }, a.error) } }, m.error) } function D (s, e, i) { (i = i || {}).success = "function" == typeof i.success ? i.success : Janus.noop, i.error = "function" == typeof i.error ? i.error : Q; var d = i.jsep; if (e && d) return Janus.error("Provided a JSEP to a createOffer"), void i.error("Provided a JSEP to a createOffer"); if (!(e || d && d.type && d.sdp)) return Janus.error("A valid JSEP is required for createAnswer"), void i.error("A valid JSEP is required for createAnswer"); i.media = i.media || { audio: !0, video: !0 }; var u = i.media, c = I[s]; if (null == c || null === c.webrtcStuff || void 0 === c.webrtcStuff) return Janus.warn("Invalid handle"), void i.error("Invalid handle"); var n = c.webrtcStuff; if (n.trickle = (e = i.trickle, Janus.debug("isTrickleEnabled:", e), null == e || !0 === e), void 0 === n.pc || null === n.pc) u.update = !1, u.keepAudio = !1, u.keepVideo = !1; else if (void 0 !== n.pc && null !== n.pc) { if (Janus.log("Updating existing media session"), u.update = !0, null !== i.stream && void 0 !== i.stream) i.stream !== n.myStream && Janus.log("Renegotiation involves a new external stream"); else { if (u.addAudio) { if (u.keepAudio = !1, u.replaceAudio = !1, u.removeAudio = !1, u.audioSend = !0, n.myStream && n.myStream.getAudioTracks() && n.myStream.getAudioTracks().length) return Janus.error("Can't add audio stream, there already is one"), void i.error("Can't add audio stream, there already is one") } else u.removeAudio ? (u.keepAudio = !1, u.replaceAudio = !1, u.addAudio = !1, u.audioSend = !1) : u.replaceAudio && (u.keepAudio = !1, u.addAudio = !1, u.removeAudio = !1, u.audioSend = !0); if (null === n.myStream || void 0 === n.myStream ? (u.replaceAudio && (u.keepAudio = !1, u.replaceAudio = !1, u.addAudio = !0, u.audioSend = !0), O(u) && (u.keepAudio = !1, u.addAudio = !0)) : null === n.myStream.getAudioTracks() || void 0 === n.myStream.getAudioTracks() || 0 === n.myStream.getAudioTracks().length ? (u.replaceAudio && (u.keepAudio = !1, u.replaceAudio = !1, u.addAudio = !0, u.audioSend = !0), O(u) && (u.keepVideo = !1, u.addAudio = !0)) : !O(u) || u.removeAudio || u.replaceAudio || (u.keepAudio = !0), u.addVideo) { if (u.keepVideo = !1, u.replaceVideo = !1, u.removeVideo = !1, u.videoSend = !0, n.myStream && n.myStream.getVideoTracks() && n.myStream.getVideoTracks().length) return Janus.error("Can't add video stream, there already is one"), void i.error("Can't add video stream, there already is one") } else u.removeVideo ? (u.keepVideo = !1, u.replaceVideo = !1, u.addVideo = !1, u.videoSend = !1) : u.replaceVideo && (u.keepVideo = !1, u.addVideo = !1, u.removeVideo = !1, u.videoSend = !0); null === n.myStream || void 0 === n.myStream || null === n.myStream.getVideoTracks() || void 0 === n.myStream.getVideoTracks() || 0 === n.myStream.getVideoTracks().length ? (u.replaceVideo && (u.keepVideo = !1, u.replaceVideo = !1, u.addVideo = !0, u.videoSend = !0), E(u) && (u.keepVideo = !1, u.addVideo = !0)) : !E(u) || u.removeVideo || u.replaceVideo || (u.keepVideo = !0), u.addData && (u.data = !0) } if (O(u) && u.keepAudio && E(u) && u.keepVideo) return c.consentDialog(!1), void T(s, d, u, i, n.myStream) } if (u.update && !n.streamExternal) { if (u.removeAudio || u.replaceAudio) { if (n.myStream && n.myStream.getAudioTracks() && n.myStream.getAudioTracks().length) { var r = n.myStream.getAudioTracks()[0]; Janus.log("Removing audio track:", r), n.myStream.removeTrack(r); try { r.stop() } catch (e) { } } if (n.pc.getSenders() && n.pc.getSenders().length) { e = !0; if (e = u.replaceAudio && ("firefox" === Janus.webRTCAdapter.browserDetails.browser || "chrome" === Janus.webRTCAdapter.browserDetails.browser && 72 <= Janus.webRTCAdapter.browserDetails.version) ? !1 : e) for (var a in n.pc.getSenders()) (r = n.pc.getSenders()[a]) && r.track && "audio" === r.track.kind && (Janus.log("Removing audio sender:", r), n.pc.removeTrack(r)) } } if (u.removeVideo || u.replaceVideo) { if (n.myStream && n.myStream.getVideoTracks() && n.myStream.getVideoTracks().length) { r = n.myStream.getVideoTracks()[0]; Janus.log("Removing video track:", r), n.myStream.removeTrack(r); try { r.stop() } catch (e) { } } if (n.pc.getSenders() && n.pc.getSenders().length) { e = !0; if (e = u.replaceVideo && ("firefox" === Janus.webRTCAdapter.browserDetails.browser || "chrome" === Janus.webRTCAdapter.browserDetails.browser && 72 <= Janus.webRTCAdapter.browserDetails.version) ? !1 : e) for (var a in n.pc.getSenders()) (r = n.pc.getSenders()[a]) && r.track && "video" === r.track.kind && (Janus.log("Removing video sender:", r), n.pc.removeTrack(r)) } } } if (null !== i.stream && void 0 !== i.stream) { var l = i.stream; if (Janus.log("MediaStream provided by the application"), Janus.debug(l), u.update && n.myStream && n.myStream !== i.stream && !n.streamExternal) { try { var o, t = n.myStream.getTracks(); for (o in t) { var f = t[o]; Janus.log(f), null != f && f.stop() } } catch (e) { } n.myStream = null } return n.streamExternal = !0, c.consentDialog(!1), void T(s, d, u, i, l) } if (O(u) || E(u)) if (Janus.isGetUserMediaAvailable()) { var v = { mandatory: {}, optional: [] }, g = (c.consentDialog(!0), O(u)), p = (!0 === g && null != u && null != u && "object" == typeof u.audio && (g = u.audio), E(u)); if (!0 === p && null != u && null != u) { var e = !0 === i.simulcast, m = !0 === i.simulcast2; if (!e && !m || d || void 0 !== u.video && !1 !== u.video || (u.video = "hires"), u.video && "screen" != u.video && "window" != u.video) "object" == typeof u.video ? p = u.video : (m = e = 0, e = "lowres" === u.video ? (m = 240, 320) : "lowres-16:9" === u.video ? (m = 180, 320) : "hires" === u.video || "hires-16:9" === u.video || "hdres" === u.video ? (m = 720, 1280) : "fhdres" === u.video ? (m = 1080, 1920) : "4kres" === u.video ? (m = 2160, 3840) : (m = "stdres" === u.video ? 480 : "stdres-16:9" === u.video ? 360 : (Janus.log("Default video setting is stdres 4:3"), 480), 640), Janus.log("Adding media constraint:", u.video), p = { height: m, width: e }, Janus.log("Adding video constraint:", p)); else if ("screen" === u.video || "window" === u.video) { if (u.screenshareFrameRate || (u.screenshareFrameRate = 3), navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) return void navigator.mediaDevices.getDisplayMedia({ video: !0 }).then(function (n) { c.consentDialog(!1), O(u) && !u.keepAudio ? navigator.mediaDevices.getUserMedia({ audio: !0, video: !1 }).then(function (e) { n.addTrack(e.getAudioTracks()[0]), T(s, d, u, i, n) }) : T(s, d, u, i, n) }, function (e) { c.consentDialog(!1), i.error(e) }); function b (e, n) { c.consentDialog(!1), e ? i.error(e) : T(s, d, u, i, n) } function J (e, r, a) { Janus.log("Adding media constraint (screen capture)"), Janus.debug(e), navigator.mediaDevices.getUserMedia(e).then(function (n) { a ? navigator.mediaDevices.getUserMedia({ audio: !0, video: !1 }).then(function (e) { n.addTrack(e.getAudioTracks()[0]), r(null, n) }) : r(null, n) }).catch(function (e) { c.consentDialog(!1), r(e) }) } if ("chrome" === Janus.webRTCAdapter.browserDetails.browser) { var m = Janus.webRTCAdapter.browserDetails.version, e = 33; window.navigator.userAgent.match("Linux") && (e = 35), 26 <= m && m <= e ? J(v = { video: { mandatory: { googLeakyBucket: !0, maxWidth: window.screen.width, maxHeight: window.screen.height, minFrameRate: u.screenshareFrameRate, maxFrameRate: u.screenshareFrameRate, chromeMediaSource: "screen" } }, audio: O(u) && !u.keepAudio }, b) : Janus.extension.getScreen(function (e, n) { if (e) return c.consentDialog(!1), i.error(e); (v = { audio: !1, video: { mandatory: { chromeMediaSource: "desktop", maxWidth: window.screen.width, maxHeight: window.screen.height, minFrameRate: u.screenshareFrameRate, maxFrameRate: u.screenshareFrameRate }, optional: [{ googLeakyBucket: !0 }, { googTemporalLayeredScreencast: !0 }] } }).video.mandatory.chromeMediaSourceId = n, J(v, b, O(u) && !u.keepAudio) }) } else if ("firefox" === Janus.webRTCAdapter.browserDetails.browser) { if (!(33 <= Janus.webRTCAdapter.browserDetails.version)) return (m = new Error("NavigatorUserMediaError")).name = "Your version of Firefox does not support screen sharing, please install Firefox 33 (or more recent versions)", c.consentDialog(!1), void i.error(m); J(v = { video: { mozMediaSource: u.video, mediaSource: u.video }, audio: O(u) && !u.keepAudio }, function (e, n) { var r, a; b(e, n), e || (r = n.currentTime, a = window.setInterval(function () { n || window.clearInterval(a), n.currentTime == r && (window.clearInterval(a), n.onended && n.onended()), r = n.currentTime }, 500)) }) } return } } null != u && "screen" === u.video || navigator.mediaDevices.enumerateDevices().then(function (e) { var n = e.some(function (e) { return "audioinput" === e.kind }), e = function (e) { if (Janus.debug("isScreenSendEnabled:", e), null == e) return !1; if ("object" != typeof e.video || "object" != typeof e.video.mandatory) return !1; e = e.video.mandatory; { if (e.chromeMediaSource) return "desktop" === e.chromeMediaSource || "screen" === e.chromeMediaSource; if (e.mozMediaSource) return "window" === e.mozMediaSource || "screen" === e.mozMediaSource; if (e.mediaSource) return "window" === e.mediaSource || "screen" === e.mediaSource } return !1 }(u) || e.some(function (e) { return "videoinput" === e.kind }), r = O(u), a = E(u), o = (o = u, Janus.debug("isAudioSendRequired:", o), null != o && (!1 !== o.audio && !1 !== o.audioSend && (void 0 !== o.failIfNoAudio && null !== o.failIfNoAudio && !0 === o.failIfNoAudio))), t = (t = u, Janus.debug("isVideoSendRequired:", t), null != t && (!1 !== t.video && !1 !== t.videoSend && (void 0 !== t.failIfNoVideo && null !== t.failIfNoVideo && !0 === t.failIfNoVideo))); if (r || a || o || t) { r = !!r && n, a = !!a && e; if (!r && !a) return c.consentDialog(!1), i.error("No capture device found"), !1; if (!r && o) return c.consentDialog(!1), i.error("Audio capture is required, but no capture device found"), !1; if (!a && t) return c.consentDialog(!1), i.error("Video capture is required, but no capture device found"), !1 } r = { audio: !(!n || u.keepAudio) && g, video: !(!e || u.keepVideo) && p }; Janus.debug("getUserMedia constraints", r), r.audio || r.video ? navigator.mediaDevices.getUserMedia(r).then(function (e) { c.consentDialog(!1), T(s, d, u, i, e) }).catch(function (e) { c.consentDialog(!1), i.error({ code: e.code, name: e.name, message: e.message }) }) : (c.consentDialog(!1), T(s, d, u, i, l)) }).catch(function (e) { c.consentDialog(!1), i.error("enumerateDevices error", e) }) } else i.error("getUserMedia not available"); else T(s, d, u, i) } function z (e, n) { (n = n || {}).success = "function" == typeof n.success ? n.success : Janus.noop, n.error = "function" == typeof n.error ? n.error : Q; var r = n.jsep, e = I[e]; if (null == e || null === e.webrtcStuff || void 0 === e.webrtcStuff) return Janus.warn("Invalid handle"), void n.error("Invalid handle"); var a = e.webrtcStuff; if (null != r) { if (null === a.pc) return Janus.warn("Wait, no PeerConnection?? if this is an answer, use createAnswer and not handleRemoteJsep"), void n.error("No PeerConnection: if this is an answer, use createAnswer and not handleRemoteJsep"); a.pc.setRemoteDescription(r).then(function () { if (Janus.log("Remote description accepted!"), a.remoteSdp = r.sdp, a.candidates && 0 < a.candidates.length) { for (var e in a.candidates) { e = a.candidates[e]; Janus.debug("Adding remote candidate:", e), e && !0 !== e.completed ? a.pc.addIceCandidate(e) : a.pc.addIceCandidate() } a.candidates = [] } n.success() }, n.error) } else n.error("Invalid JSEP") } function A (e, o) { e = I[e]; if (null == e || null === e.webrtcStuff || void 0 === e.webrtcStuff) return Janus.warn("Invalid handle"), 0; var t = o ? "remote" : "local", s = e.webrtcStuff; return s.volume[t] || (s.volume[t] = { value: 0 }), s.pc.getStats && "chrome" === Janus.webRTCAdapter.browserDetails.browser ? !o || null !== s.remoteStream && void 0 !== s.remoteStream ? o || null !== s.myStream && void 0 !== s.myStream ? null === s.volume[t].timer || void 0 === s.volume[t].timer ? (Janus.log("Starting " + t + " volume monitor"), s.volume[t].timer = setInterval(function () { s.pc.getStats(function (e) { for (var n = e.result(), r = 0;r < n.length;r++) { var a = n[r]; "ssrc" == a.type && (o && a.stat("audioOutputLevel") ? s.volume[t].value = parseInt(a.stat("audioOutputLevel")) : !o && a.stat("audioInputLevel") && (s.volume[t].value = parseInt(a.stat("audioInputLevel")))) } }) }, 200), 0) : s.volume[t].value : (Janus.warn("Local stream unavailable"), 0) : (Janus.warn("Remote stream unavailable"), 0) : (Janus.warn("Getting the " + t + " volume unsupported by browser"), 0) } function x (e, n) { e = I[e]; if (null == e || null === e.webrtcStuff || void 0 === e.webrtcStuff) return Janus.warn("Invalid handle"), !0; e = e.webrtcStuff; return null === e.pc || void 0 === e.pc ? (Janus.warn("Invalid PeerConnection"), !0) : void 0 === e.myStream || null === e.myStream ? (Janus.warn("Invalid local MediaStream"), !0) : n ? null === e.myStream.getVideoTracks() || void 0 === e.myStream.getVideoTracks() || 0 === e.myStream.getVideoTracks().length ? (Janus.warn("No video track"), !0) : !e.myStream.getVideoTracks()[0].enabled : null === e.myStream.getAudioTracks() || void 0 === e.myStream.getAudioTracks() || 0 === e.myStream.getAudioTracks().length ? (Janus.warn("No audio track"), !0) : !e.myStream.getAudioTracks()[0].enabled } function P (e, n, r) { e = I[e]; if (null == e || null === e.webrtcStuff || void 0 === e.webrtcStuff) return Janus.warn("Invalid handle"), !1; e = e.webrtcStuff; return null === e.pc || void 0 === e.pc ? (Janus.warn("Invalid PeerConnection"), !1) : void 0 === e.myStream || null === e.myStream ? (Janus.warn("Invalid local MediaStream"), !1) : n ? null === e.myStream.getVideoTracks() || void 0 === e.myStream.getVideoTracks() || 0 === e.myStream.getVideoTracks().length ? (Janus.warn("No video track"), !1) : (e.myStream.getVideoTracks()[0].enabled = !r, !0) : null === e.myStream.getAudioTracks() || void 0 === e.myStream.getAudioTracks() || 0 === e.myStream.getAudioTracks().length ? (Janus.warn("No audio track"), !1) : (e.myStream.getAudioTracks()[0].enabled = !r, !0) } function H (e) { e = I[e]; if (null == e || null === e.webrtcStuff || void 0 === e.webrtcStuff) return Janus.warn("Invalid handle"), "Invalid handle"; var r = e.webrtcStuff; return null === r.pc || void 0 === r.pc ? "Invalid PeerConnection" : r.pc.getStats ? null === r.bitrate.timer || void 0 === r.bitrate.timer ? (Janus.log("Starting bitrate timer (via getStats)"), r.bitrate.timer = setInterval(function () { r.pc.getStats().then(function (e) { e.forEach(function (e) { var n; e && (n = !1, (n = !(("video" === e.mediaType || -1 < e.id.toLowerCase().indexOf("video")) && "inbound-rtp" === e.type && e.id.indexOf("rtcp") < 0) && ("ssrc" != e.type || !e.bytesReceived || "VP8" !== e.googCodecName && "" !== e.googCodecName) ? n : !0) && (r.bitrate.bsnow = e.bytesReceived, r.bitrate.tsnow = e.timestamp, null !== r.bitrate.bsbefore && null !== r.bitrate.tsbefore && (n = r.bitrate.tsnow - r.bitrate.tsbefore, "safari" == Janus.webRTCAdapter.browserDetails.browser && (n /= 1e3), e = Math.round(8 * (r.bitrate.bsnow - r.bitrate.bsbefore) / n), "safari" === Janus.webRTCAdapter.browserDetails.browser && (e = parseInt(e / 1e3)), r.bitrate.value = e + " kbits/sec"), r.bitrate.bsbefore = r.bitrate.bsnow, r.bitrate.tsbefore = r.bitrate.tsnow)) }) }) }, 1e3), "0 kbits/sec") : r.bitrate.value : (Janus.warn("Getting the video bitrate unsupported by browser"), "Feature unsupported by browser") } function Q (e) { Janus.error("WebRTC error:", e) } function M (e, n) { Janus.log("Cleaning WebRTC stuff"); var r = I[e]; if (null != r) { var a = r.webrtcStuff; if (null != a) { !0 === n && (n = { janus: "hangup", transaction: Janus.randomString(12) }, null !== r.token && void 0 !== r.token && (n.token = r.token), null != b && (n.apisecret = b), Janus.debug("Sending hangup request (handle=" + e + "):"), Janus.debug(n), c ? (n.session_id = w, n.handle_id = e, l.send(JSON.stringify(n))) : Janus.httpAPICall(g + "/" + w + "/" + e, { verb: "POST", withCredentials: p, body: n })), a.remoteStream = null, a.volume && (a.volume.local && a.volume.local.timer && clearInterval(a.volume.local.timer), a.volume.remote && a.volume.remote.timer && clearInterval(a.volume.remote.timer)), a.volume = {}, a.bitrate.timer && clearInterval(a.bitrate.timer), a.bitrate.timer = null, a.bitrate.bsnow = null, a.bitrate.bsbefore = null, a.bitrate.tsnow = null, a.bitrate.tsbefore = null, a.bitrate.value = null; try { if (!a.streamExternal && null !== a.myStream && void 0 !== a.myStream) { Janus.log("Stopping local stream tracks"); var o, t = a.myStream.getTracks(); for (o in t) { var s = t[o]; Janus.log(s), null != s && s.stop() } } } catch (e) { } a.streamExternal = !1, a.myStream = null; try { a.pc.close() } catch (e) { } a.pc = null, a.candidates = null, a.mySdp = null, a.remoteSdp = null, a.iceDone = !1, a.dataChannel = {}, a.dtmfSender = null } r.oncleanup() } } function O (e) { return Janus.debug("isAudioSendEnabled:", e), null == e || !1 !== e.audio && (void 0 === e.audioSend || null === e.audioSend || !0 === e.audioSend) } function j (e) { return Janus.debug("isAudioRecvEnabled:", e), null == e || !1 !== e.audio && (void 0 === e.audioRecv || null === e.audioRecv || !0 === e.audioRecv) } function E (e) { return Janus.debug("isVideoSendEnabled:", e), null == e || !1 !== e.video && (void 0 === e.videoSend || null === e.videoSend || !0 === e.videoSend) } function L (e) { return Janus.debug("isVideoRecvEnabled:", e), null == e || !1 !== e.video && (void 0 === e.videoRecv || null === e.videoRecv || !0 === e.videoRecv) } y(u), this.getServer = function () { return g }, this.isConnected = function () { return J }, this.reconnect = function (e) { (e = e || {}).success = "function" == typeof e.success ? e.success : Janus.noop, e.error = "function" == typeof e.error ? e.error : Janus.noop, e.reconnect = !0, y(e) }, this.getSessionId = function () { return w }, this.destroy = function (e) { var r = e, e = ((r = r || {}).success = "function" == typeof r.success ? r.success : Janus.noop, !0), a = (void 0 !== r.asyncRequest && null !== r.asyncRequest && (e = !0 === r.asyncRequest), !0), n = (void 0 !== r.notifyDestroyed && null !== r.notifyDestroyed && (a = !0 === r.notifyDestroyed), !1); if (void 0 !== r.cleanupHandles && null !== r.cleanupHandles && (n = !0 === r.cleanupHandles), Janus.log("Destroying session " + w + " (async=" + e + ")"), J) if (null == w) Janus.warn("No session to destroy"), r.success(), a && u.destroyed(); else { if (n) for (var o in I) k(o, { noRequest: !0 }); var t, s, i, d = { janus: "destroy", transaction: Janus.randomString(12) }; null != m && (d.token = m), null != b && (d.apisecret = b), c ? (d.session_id = w, t = function () { for (var e in f) l.removeEventListener(e, f[e]); l.removeEventListener("message", s), l.removeEventListener("error", i), v && clearTimeout(v), l.close() }, s = function (e) { e = JSON.parse(e.data); e.session_id == d.session_id && e.transaction == d.transaction && (t(), r.success(), a && u.destroyed()) }, i = function (e) { t(), r.error("Failed to destroy the server: Is the server down?"), a && u.destroyed() }, l.addEventListener("message", s), l.addEventListener("error", i), l.send(JSON.stringify(d))) : Janus.httpAPICall(g + "/" + w, { verb: "POST", async: e, withCredentials: p, body: d, success: function (e) { Janus.log("Destroyed session:"), Janus.debug(e), w = null, J = !1, "success" !== e.janus && Janus.error("Ooops: " + e.error.code + " " + e.error.reason), r.success(), a && u.destroyed() }, error: function (e, n) { Janus.error(e + ":", n), w = null, J = !1, r.success(), a && u.destroyed() } }) } else Janus.warn("Is the server down? (connected=false)"), r.success() }, this.attach = function (e) { var r, a, o, n; (r = (r = e) || {}).success = "function" == typeof r.success ? r.success : Janus.noop, r.error = "function" == typeof r.error ? r.error : Janus.noop, r.consentDialog = "function" == typeof r.consentDialog ? r.consentDialog : Janus.noop, r.iceState = "function" == typeof r.iceState ? r.iceState : Janus.noop, r.mediaState = "function" == typeof r.mediaState ? r.mediaState : Janus.noop, r.webrtcState = "function" == typeof r.webrtcState ? r.webrtcState : Janus.noop, r.slowLink = "function" == typeof r.slowLink ? r.slowLink : Janus.noop, r.onmessage = "function" == typeof r.onmessage ? r.onmessage : Janus.noop, r.onlocalstream = "function" == typeof r.onlocalstream ? r.onlocalstream : Janus.noop, r.onremotestream = "function" == typeof r.onremotestream ? r.onremotestream : Janus.noop, r.ondata = "function" == typeof r.ondata ? r.ondata : Janus.noop, r.ondataopen = "function" == typeof r.ondataopen ? r.ondataopen : Janus.noop, r.oncleanup = "function" == typeof r.oncleanup ? r.oncleanup : Janus.noop, r.ondetached = "function" == typeof r.ondetached ? r.ondetached : Janus.noop, J ? null == (a = r.plugin) ? (Janus.error("Invalid plugin"), r.error("Invalid plugin")) : (e = r.opaqueId, o = r.token || m, n = Janus.randomString(12), e = { janus: "attach", plugin: a, opaque_id: e, transaction: n }, null != o && (e.token = o), null != b && (e.apisecret = b), c ? (d[n] = function (e) { if (Janus.debug(e), "success" !== e.janus) return Janus.error("Ooops: " + e.error.code + " " + e.error.reason), void r.error("Ooops: " + e.error.code + " " + e.error.reason); var n = e.data.id, e = (Janus.log("Created handle: " + n), { session: i, plugin: a, id: n, token: o, detached: !1, webrtcStuff: { started: !1, myStream: null, streamExternal: !1, remoteStream: null, mySdp: null, mediaConstraints: null, pc: null, dataChannel: {}, dtmfSender: null, trickle: !0, iceDone: !1, volume: { value: null, timer: null }, bitrate: { value: null, bsnow: null, bsbefore: null, tsnow: null, tsbefore: null, timer: null } }, getId: function () { return n }, getPlugin: function () { return a }, getVolume: function () { return A(n, !0) }, getRemoteVolume: function () { return A(n, !0) }, getLocalVolume: function () { return A(n, !1) }, isAudioMuted: function () { return x(n, !1) }, muteAudio: function () { return P(n, !1, !0) }, unmuteAudio: function () { return P(n, !1, !1) }, isVideoMuted: function () { return x(n, !0) }, muteVideo: function () { return P(n, !0, !0) }, unmuteVideo: function () { return P(n, !0, !1) }, getBitrate: function () { return H(n) }, send: function (e) { q(n, e) }, data: function (e) { G(n, e) }, dtmf: function (e) { B(n, e) }, consentDialog: r.consentDialog, iceState: r.iceState, mediaState: r.mediaState, webrtcState: r.webrtcState, slowLink: r.slowLink, onmessage: r.onmessage, createOffer: function (e) { D(n, !0, e) }, createAnswer: function (e) { D(n, !1, e) }, handleRemoteJsep: function (e) { z(n, e) }, onlocalstream: r.onlocalstream, onremotestream: r.onremotestream, ondata: r.ondata, ondataopen: r.ondataopen, oncleanup: r.oncleanup, ondetached: r.ondetached, hangup: function (e) { M(n, !0 === e) }, detach: function (e) { k(n, e) } }); I[n] = e, r.success(e) }, e.session_id = w, l.send(JSON.stringify(e))) : Janus.httpAPICall(g + "/" + w, { verb: "POST", withCredentials: p, body: e, success: function (e) { if (Janus.debug(e), "success" !== e.janus) return Janus.error("Ooops: " + e.error.code + " " + e.error.reason), void r.error("Ooops: " + e.error.code + " " + e.error.reason); var n = e.data.id, e = (Janus.log("Created handle: " + n), { session: i, plugin: a, id: n, token: o, detached: !1, webrtcStuff: { started: !1, myStream: null, streamExternal: !1, remoteStream: null, mySdp: null, mediaConstraints: null, pc: null, dataChannel: {}, dtmfSender: null, trickle: !0, iceDone: !1, volume: { value: null, timer: null }, bitrate: { value: null, bsnow: null, bsbefore: null, tsnow: null, tsbefore: null, timer: null } }, getId: function () { return n }, getPlugin: function () { return a }, getVolume: function () { return A(n, !0) }, getRemoteVolume: function () { return A(n, !0) }, getLocalVolume: function () { return A(n, !1) }, isAudioMuted: function () { return x(n, !1) }, muteAudio: function () { return P(n, !1, !0) }, unmuteAudio: function () { return P(n, !1, !1) }, isVideoMuted: function () { return x(n, !0) }, muteVideo: function () { return P(n, !0, !0) }, unmuteVideo: function () { return P(n, !0, !1) }, getBitrate: function () { return H(n) }, send: function (e) { q(n, e) }, data: function (e) { G(n, e) }, dtmf: function (e) { B(n, e) }, consentDialog: r.consentDialog, iceState: r.iceState, mediaState: r.mediaState, webrtcState: r.webrtcState, slowLink: r.slowLink, onmessage: r.onmessage, createOffer: function (e) { D(n, !0, e) }, createAnswer: function (e) { D(n, !1, e) }, handleRemoteJsep: function (e) { z(n, e) }, onlocalstream: r.onlocalstream, onremotestream: r.onremotestream, ondata: r.ondata, ondataopen: r.ondataopen, oncleanup: r.oncleanup, ondetached: r.ondetached, hangup: function (e) { M(n, !0 === e) }, detach: function (e) { k(n, e) } }); I[n] = e, r.success(e) }, error: function (e, n) { Janus.error(e + ":", n) } })) : (Janus.warn("Is the server down? (connected=false)"), r.error("Is the server down? (connected=false)")) } } Janus.useDefaultDependencies = function (e) { var r = e && e.fetch || fetch, o = e && e.Promise || Promise, a = e && e.WebSocket || WebSocket; return { newWebSocket: function (e, n) { return new a(e, n) }, extension: e && e.extension || defaultExtension, isArray: function (e) { return Array.isArray(e) }, webRTCAdapter: e && e.adapter || adapter, httpAPICall: function (e, a) { var n = { method: a.verb, headers: { Accept: "application/json, text/plain, */*" }, cache: "no-cache" }, e = ("POST" === a.verb && (n.headers["Content-Type"] = "application/json"), void 0 !== a.withCredentials && (n.credentials = !0 === a.withCredentials ? "include" : a.withCredentials || "omit"), void 0 !== a.body && (n.body = JSON.stringify(a.body)), r(e, n).catch(function (e) { return o.reject({ message: "Probably a network error, is the server down?", error: e }) })); return void 0 !== a.timeout && (n = new o(function (e, n) { var r = setTimeout(function () { return clearTimeout(r), n({ message: "Request timed out", timeout: a.timeout }) }, a.timeout) }), e = o.race([e, n])), e.then(function (n) { return n.ok ? typeof a.success == typeof Janus.noop ? n.json().then(function (e) { a.success(e) }).catch(function (e) { return o.reject({ message: "Failed to parse response body", error: e, response: n }) }) : void 0 : o.reject({ message: "API call failed", response: n }) }).catch(function (e) { typeof a.error == typeof Janus.noop && a.error(e.message || "<< internal error >>", e) }), e } } }, Janus.useOldDependencies = function (e) { var o = e && e.jQuery || jQuery, r = e && e.WebSocket || WebSocket; return { newWebSocket: function (e, n) { return new r(e, n) }, isArray: function (e) { return o.isArray(e) }, extension: e && e.extension || defaultExtension, webRTCAdapter: e && e.adapter || adapter, httpAPICall: function (e, a) { var n = void 0 !== a.body ? { contentType: "application/json", data: JSON.stringify(a.body) } : {}, r = void 0 !== a.withCredentials ? { xhrFields: { withCredentials: a.withCredentials } } : {}; return o.ajax(o.extend(n, r, { url: e, type: a.verb, cache: !1, dataType: "json", async: a.async, timeout: a.timeout, success: function (e) { typeof a.success == typeof Janus.noop && a.success(e) }, error: function (e, n, r) { typeof a.error == typeof Janus.noop && a.error(n, r) } })) } } }, Janus.noop = function () { }, Janus.dataChanDefaultLabel = "JanusDataChannel", Janus.init = function (e) { if ((e = e || {}).callback = "function" == typeof e.callback ? e.callback : Janus.noop, !0 === Janus.initDone) e.callback(); else { if ("undefined" != typeof console && void 0 !== console.log || (console = { log: function () { } }), Janus.trace = Janus.noop, Janus.debug = Janus.noop, Janus.vdebug = Janus.noop, Janus.log = Janus.noop, Janus.warn = Janus.noop, Janus.error = Janus.noop, !0 === e.debug || "all" === e.debug) Janus.trace = console.trace.bind(console), Janus.debug = console.debug.bind(console), Janus.vdebug = console.debug.bind(console), Janus.log = console.log.bind(console), Janus.warn = console.warn.bind(console), Janus.error = console.error.bind(console); else if (Array.isArray(e.debug)) for (var n in e.debug) { var r = e.debug[n]; switch (r) { case "trace": Janus.trace = console.trace.bind(console); break; case "debug": Janus.debug = console.debug.bind(console); break; case "vdebug": Janus.vdebug = console.debug.bind(console); break; case "log": Janus.log = console.log.bind(console); break; case "warn": Janus.warn = console.warn.bind(console); break; case "error": Janus.error = console.error.bind(console); break; default: console.error("Unknown debugging option '" + r + "' (supported: 'trace', 'debug', 'vdebug', 'log', warn', 'error')") } } Janus.log("Initializing library"); var a = e.dependencies || Janus.useDefaultDependencies(); Janus.isArray = a.isArray, Janus.webRTCAdapter = a.webRTCAdapter, Janus.httpAPICall = a.httpAPICall, Janus.newWebSocket = a.newWebSocket, Janus.extension = a.extension, Janus.extension.init(), Janus.listDevices = function (t, e) { t = "function" == typeof t ? t : Janus.noop, null == e && (e = { audio: !0, video: !0 }), Janus.isGetUserMediaAvailable() ? navigator.mediaDevices.getUserMedia(e).then(function (o) { navigator.mediaDevices.enumerateDevices().then(function (e) { Janus.debug(e), t(e); try { var n, r = o.getTracks(); for (n in r) { var a = r[n]; null != a && a.stop() } } catch (e) { } }) }).catch(function (e) { Janus.error(e), t([]) }) : (Janus.warn("navigator.mediaDevices unavailable"), t([])) }, Janus.attachMediaStream = function (e, n) { "chrome" !== Janus.webRTCAdapter.browserDetails.browser || 52 <= Janus.webRTCAdapter.browserDetails.version ? e.srcObject = n : void 0 !== e.src ? e.src = URL.createObjectURL(n) : Janus.error("Error attaching stream to element") }, Janus.reattachMediaStream = function (e, n) { "chrome" !== Janus.webRTCAdapter.browserDetails.browser || 52 <= Janus.webRTCAdapter.browserDetails.version ? e.srcObject = n.srcObject : void 0 !== e.src ? e.src = n.src : Janus.error("Error reattaching stream to element") }; var a = 0 <= ["iPad", "iPhone", "iPod"].indexOf(navigator.platform) ? "pagehide" : "beforeunload", o = window["on" + a]; if (window.addEventListener(a, function (e) { for (var n in Janus.log("Closing window"), Janus.sessions) null !== Janus.sessions[n] && void 0 !== Janus.sessions[n] && Janus.sessions[n].destroyOnUnload && (Janus.log("Destroying session " + n), Janus.sessions[n].destroy({ asyncRequest: !1, notifyDestroyed: !1 })); o && "function" == typeof o && o() }), Janus.safariVp8 = !1, "safari" === Janus.webRTCAdapter.browserDetails.browser && 605 <= Janus.webRTCAdapter.browserDetails.version) if (RTCRtpSender && RTCRtpSender.getCapabilities && RTCRtpSender.getCapabilities("video") && RTCRtpSender.getCapabilities("video").codecs && RTCRtpSender.getCapabilities("video").codecs.length) { for (var n in RTCRtpSender.getCapabilities("video").codecs) { var t = RTCRtpSender.getCapabilities("video").codecs[n]; if (t && t.mimeType && "video/vp8" === t.mimeType.toLowerCase()) { Janus.safariVp8 = !0; break } } Janus.safariVp8 ? Janus.log("This version of Safari supports VP8") : Janus.warn("This version of Safari does NOT support VP8: if you're using a Technology Preview, try enabling the 'WebRTC VP8 codec' setting in the 'Experimental Features' Develop menu") } else { var s = new RTCPeerConnection({}, {}); s.createOffer({ offerToReceiveVideo: !0 }).then(function (e) { Janus.safariVp8 = -1 !== e.sdp.indexOf("VP8"), Janus.safariVp8 ? Janus.log("This version of Safari supports VP8") : Janus.warn("This version of Safari does NOT support VP8: if you're using a Technology Preview, try enabling the 'WebRTC VP8 codec' setting in the 'Experimental Features' Develop menu"), s.close(), s = null }) } Janus.initDone = !0, e.callback() } }, Janus.isWebrtcSupported = function () { return void 0 !== window.RTCPeerConnection && null !== window.RTCPeerConnection }, Janus.isGetUserMediaAvailable = function () { return void 0 !== navigator.mediaDevices && null !== navigator.mediaDevices && void 0 !== navigator.mediaDevices.getUserMedia && null !== navigator.mediaDevices.getUserMedia }, Janus.randomString = function (e) { for (var n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", r = "", a = 0;a < e;a++) { var o = Math.floor(Math.random() * n.length); r += n.substring(o, o + 1) } return r }; export default Janus;