From 2bbda7fa196f7ab8502a17ab67d294c0243aea29 Mon Sep 17 00:00:00 2001 From: Steve Seguin Date: Wed, 16 Jun 2021 18:54:49 -0400 Subject: [PATCH] adds custom user prompts/confirm boxes introduces lib.js as well, which is a split of main.js --- index.html | 48 +- lib.js | 14961 +++++++++++++++++++++++++++++++++++++ main.css | 18 +- main.js | 20485 +++++++-------------------------------------------- webrtc.js | 2 +- 5 files changed, 17828 insertions(+), 17686 deletions(-) create mode 100644 lib.js diff --git a/index.html b/index.html index 0081ed5..a7985c4 100644 --- a/index.html +++ b/index.html @@ -55,8 +55,9 @@ } - + + @@ -67,7 +68,7 @@ - +
"; + + controls.innerHTML += "
\ +
\ + " + soloLink + "\ + \ +

This is you, the director.
You are also a performer.

"; + + + controls.querySelectorAll('[data-action-type]').forEach((ele) => { // give action buttons some self-reference + ele.dataset.sid = session.streamID; + }); + + container.innerHTML = buttons; + container.appendChild(controls); + + Object.keys(session.sceneList).forEach((scene, index) => { + if (session.showDirector){ + if (document.getElementById("container_director")){ + if (!(getById("container_director").querySelectorAll('[data-scene="'+scene+'"]').length)){ + var newScene = document.createElement("div"); + newScene.innerHTML = ''; + getById("container_director").appendChild(newScene); + } + } + } + }); + + + var labelID = document.getElementById("label_director"); + + labelID.onclick = function(ee){ + var oldlabel = ee.target.innerText; + if (session.label===false){ + oldlabel = ""; + } + window.focus(); + var newlabel = prompt("Enter a new Display Name for this stream", oldlabel); + if (newlabel!==null){ + if (newlabel == ""){ + newlabel = false; + ee.target.innerText = "Add a label"; + } else { + ee.target.innerText = newlabel; + } + session.label = newlabel; + var data = {}; + data.changeLabel = true; + data.value = session.label; + session.sendMessage(data); + } + } + labelID.style.float = "left"; + labelID.style.top = "2px"; + labelID.style.marginLeft = "5px"; + labelID.style.position = "relative"; + labelID.style.cursor="pointer"; + if (session.label){ + labelID.innerText = session.label; + } +} + +function createControlBox(UUID, soloLink, streamID) { + if (document.getElementById("deleteme")) { + getById("deleteme").parentNode.removeChild(getById("deleteme")); + } + var controls = getById("controls_blank").cloneNode(true); + + var container = document.createElement("div"); + container.id = "container_" + UUID; // needed to delete on user disconnect + container.className = "vidcon directorMargins"; + controls.style.display = "block"; + controls.id = "controls_" + UUID; + getById("guestFeeds").appendChild(container); + + var buttons = "
ID: " + streamID + "\ + \ + \ +
"; + + if (!session.rpcs[UUID].voiceMeter) { + if (session.meterStyle==1){ + session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate2").cloneNode(true); + } else { + session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate").cloneNode(true); + session.rpcs[UUID].voiceMeter.classList.add("video-meter-director"); + session.rpcs[UUID].voiceMeter.style.opacity = 0; + } + session.rpcs[UUID].voiceMeter.id = "voiceMeter_" + UUID; + session.rpcs[UUID].voiceMeter.dataset.level = 0; + } + + session.rpcs[UUID].remoteMuteElement = getById("muteStateTemplate").cloneNode(true); + session.rpcs[UUID].remoteMuteElement.id = ""; + session.rpcs[UUID].remoteMuteElement.style.top = "5px"; + session.rpcs[UUID].remoteMuteElement.style.right = "7px"; + + session.rpcs[UUID].remoteVideoMuteElement = getById("videoMuteStateTemplate").cloneNode(true); + session.rpcs[UUID].remoteVideoMuteElement.id = ""; + session.rpcs[UUID].remoteVideoMuteElement.style.top = "5px"; + session.rpcs[UUID].remoteVideoMuteElement.style.right = "28px"; + + session.rpcs[UUID].remoteRaisedHandElement = getById("raisedHandTemplate").cloneNode(true); + session.rpcs[UUID].remoteRaisedHandElement.id = ""; + session.rpcs[UUID].remoteRaisedHandElement.style.top = "5px"; + session.rpcs[UUID].remoteRaisedHandElement.style.right = "49px"; + + + var videoContainer = document.createElement("div"); + videoContainer.id = "videoContainer_" + UUID; // needed to delete on user disconnect + videoContainer.style.margin = "0"; + videoContainer.style.position = "relative"; + + controls.innerHTML += "
"; + controls.innerHTML += "
"; + + var handsID = "hands_" + UUID; + + controls.innerHTML += "
\ +
\ + " + soloLink + "\ + \ +
\ + \ +
"; + + controls.querySelectorAll('[data-action-type]').forEach((ele) => { // give action buttons some self-reference + ele.dataset.UUID = UUID; + ele.dataset.sid = streamID; + }); + + container.innerHTML = buttons; + container.appendChild(videoContainer); + videoContainer.appendChild(session.rpcs[UUID].voiceMeter); + videoContainer.appendChild(session.rpcs[UUID].remoteMuteElement); + videoContainer.appendChild(session.rpcs[UUID].remoteVideoMuteElement); + videoContainer.appendChild(session.rpcs[UUID].remoteRaisedHandElement); + container.appendChild(controls); + initSceneList(UUID); +} + +function createDirectorCam(vid) { + + getById("press2talk").innerHTML = ""; + getById("press2talk").outerHTML = ""; + if (document.getElementById("videoContainer_director")){ + getById("videoContainer_director").appendChild(vid); + } else { + getById("miniPerformer").appendChild(vid); + } + vid.title = "This is the preview of the Director's audio and video output."; + getById("press2talk").dataset.value = 1; + session.muted = false; + toggleMute(true); + getById("screensharebutton").classList.remove("advanced"); + getById("hangupbutton2").classList.remove("advanced"); + setTimeout(function() { + toggleSettings(); + }, 200); + + if (urlParams.has('permaid')) { + updateURL("permaid=" + session.streamID); + } else { + updateURL("push=" + session.streamID); + } +} + +function press2talk(clean = false) { + var ele = getById("press2talk"); + ele.style.minWidth = "127px"; + ele.style.padding = "7px"; + getById("settingsbutton").classList.remove("advanced"); + + + if (!document.getElementById("controls_director") && session.showDirector){createDirectorOnlyBox();} + + + if (session.videoDevice || (session.audioDevice && session.audioDevice!==1)){ + if ((session.videoDevice === 1) && (session.audioDevice===false || session.audioDevice==1)){ + session.publishDirector(clean, true); + session.muted = false; + toggleMute(true); + return; + } else { + enumerateDevices().then(function(deviceInfos) { + var vdevice = false; + var adevice = true; + if (session.audioDevice==0){ + adevice=false; + } + if (session.videoDevice && (session.videoDevice!=1)){ + for (let i = 0; i !== deviceInfos.length; ++i) { + var deviceInfo = deviceInfos[i]; + if ((deviceInfo.kind === 'videoinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.videoDevice))) { + vdevice = {deviceId: {exact: deviceInfo.deviceId}}; + break; + } else if (deviceInfo.deviceId === session.videoDevice){ + vdevice = {deviceId: {exact: deviceInfo.deviceId}}; + break; + } + } + } + if (session.audioDevice && (session.audioDevice!=1)){ + for (let i = 0; i !== deviceInfos.length; ++i) { + var deviceInfo = deviceInfos[i]; + if ((deviceInfo.kind === 'audioinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.audioDevice))) { + adevice = {deviceId: {exact: deviceInfo.deviceId}}; + break; + } else if (deviceInfo.deviceId === session.audioDevice){ + adevice = {deviceId: {exact: deviceInfo.deviceId}}; + break; + } + } + } + session.publishDirector(clean, vdevice, adevice); + session.muted = false; + toggleMute(true); + }); + return; + } + } + + session.publishDirector(clean); + session.muted = false; + toggleMute(true); + +} + +function addToGoogleCalendar(){ + var title = "Live Stream"; + //var dates = "20180512T230000Z/20180513T030000Z"; + var linkout = getById("director_block_1").innerText; + var details = "Join the live stream as a performer at the following link:

===> "+linkout+"

To test your connection and camera ahead of time, please visit https://vdo.ninja/speedtest

Do not share the details of this invite with others, unless explicitly told to."; + details = details.split(' ').join('+'); + details = details.split('&').join('%26'); + var linkToOpen = "https://calendar.google.com/calendar/r/eventedit?text="+title+"&details="+details; + //https://calendar.google.com/calendar/r/eventedit?text=My+Custom+Event&dates=20180512T230000Z/20180513T030000Z&details=For+details,+link+here:+https://example.com/tickets-43251101208&location=Garage+Boston+-+20+Linden+Street+-+Allston,+MA+02134 + + window.open(linkToOpen); + +} + +function addToOutlookCalendar(){ + var title = "Live Stream"; + var linkout = getById("director_block_1").innerText; + var details = "Join the live stream as a performer at the following link:

===> "+linkout+"

To test your connection and camera ahead of time, please visit https://vdo.ninja/speedtest

Do not share the details of this invite with others, unless explicitly told to."; + details = details.split(' ').join('%20'); + details = details.split('&').join('%26'); + + + var linkToOpen = "https://outlook.live.com/owa/?path=%2Fcalendar%2Faction%2Fcompose&rru=addevent&subject="+title+"&body="+details; + //https://calendar.google.com/calendar/r/eventedit?text=My+Custom+Event&dates=20180512T230000Z/20180513T030000Z&details=For+details,+link+here:+https://example.com/tickets-43251101208&location=Garage+Boston+-+20+Linden+Street+-+Allston,+MA+02134 + + window.open(linkToOpen); +} + +function addToYahooCalendar(){ + var title = "Live Stream"; + var linkout = getById("director_block_1").innerText; + var details = "Join the live stream as a performer at the following link:

===> "+linkout+"

To test your connection and camera ahead of time, please visit https://vdo.ninja/speedtest

Do not share the details of this invite with others, unless explicitly told to."; + details = details.split(' ').join('%20'); + details = details.split('&').join('%26'); + var linkToOpen = "https://calendar.yahoo.com?v60&title="+title+"&desc="+details; + //https://calendar.google.com/calendar/r/eventedit?text=My+Custom+Event&dates=20180512T230000Z/20180513T030000Z&details=For+details,+link+here:+https://example.com/tickets-43251101208&location=Garage+Boston+-+20+Linden+Street+-+Allston,+MA+02134 + + window.open(linkToOpen); +} + +function toggle(ele, tog = false, inline = true) { + var x = ele; + if (x.style.display === "none") { + if (inline) { + x.style.display = "inline-block"; + } else { + x.style.display = "block"; + } + } else { + x.style.display = "none"; + } + if (tog) { + if (tog.dataset.saved) { + tog.innerHTML = tog.dataset.saved; + delete(tog.dataset.saved); + } else { + tog.dataset.saved = tog.innerHTML; + tog.innerHTML = "Hide This"; + } + } +} + +function toggleByDataset(filter) { + var elements = document.querySelectorAll('[data-cluster="'+filter+'"]'); // ie: .cluster1 + for (var i = 0; i < elements.length; i++) { + elements[i].classList.toggle('hidden'); + } +} + + +var SelectedAudioOutputDevices = []; // order matters. +var SelectedAudioInputDevices = []; // .. +var SelectedVideoInputDevices = []; // .. + +function enumerateDevices() { + + log("enumerated start"); + + if (typeof navigator.enumerateDevices === "function") { + log("enumerated failed 1"); + return navigator.enumerateDevices(); + } else if (typeof navigator.mediaDevices === "object" && typeof navigator.mediaDevices.enumerateDevices === "function") { + return navigator.mediaDevices.enumerateDevices(); + } else { + return new Promise((resolve, reject) => { + try { + if (window.MediaStreamTrack == null || window.MediaStreamTrack.getSources == null) { + throw new Error(); + } + window.MediaStreamTrack.getSources((devices) => { + resolve(devices + .filter(device => { + return device.kind.toLowerCase() === "video" || device.kind.toLowerCase() === "videoinput"; + }) + .map(device => { + return { + deviceId: device.deviceId != null ? device.deviceId : "" + , groupId: device.groupId + , kind: "videoinput" + , label: device.label + , toJSON: /* istanbul ignore next */ function() { + return this; + } + }; + })); + }); + } catch (e) { + errorlog(e); + } + }); + } +} + +function requestOutputAudioStream() { + try { + //warnlog("GET USER MEDIA"); + return navigator.mediaDevices.getUserMedia({ + audio: true + , video: false + }).then(function(stream1) { // Apple needs thi to happen before I can access EnumerateDevices. + log("get media sources; request audio stream"); + return enumerateDevices().then(function(deviceInfos) { + stream1.getTracks().forEach(function(track) { // We don't want to keep it without audio; so we are going to try to add audio now. + track.stop(); // I need to do this after the enumeration step, else it breaks firefox's labels + }); + const audioOutputSelect = getById('outputSourceScreenshare'); + audioOutputSelect.remove(0); + audioOutputSelect.removeAttribute("onclick"); + + for (let i = 0; i !== deviceInfos.length; ++i) { + const deviceInfo = deviceInfos[i]; + if (deviceInfo == null) { + continue; + } + const option = document.createElement('option'); + option.value = deviceInfo.deviceId; + if (deviceInfo.kind === 'audiooutput') { + const option = document.createElement('option'); + if (audioOutputSelect.length === 0) { + option.dataset.default = true; + } else { + option.dataset.default = false; + } + option.value = deviceInfo.deviceId || "default"; + if (option.value == session.sink) { + option.selected = true; + } + option.text = deviceInfo.label || `Speaker ${audioOutputSelect.length + 1}`; + audioOutputSelect.appendChild(option); + } else { + log('Some other kind of source/device: ', deviceInfo); + } + } + }); + }); + } catch (e) { + if (!(session.cleanOutput)) { + if (window.isSecureContext) { + warnUser("An error has occured when trying to access the default audio device. The reason is not known."); + } else if ((iOS) || (iPad)) { + warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported."); + } else { + warnUser("Error acessing the default audio device.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia"); + } + } + } +} + + +function requestAudioStream() { + try { + //warnlog("GET USER MEDIA"); + return navigator.mediaDevices.getUserMedia({ + audio: true + , video: false + }).then(function(stream1) { // Apple needs thi to happen before I can access EnumerateDevices. + log("get media sources; request audio stream"); + return enumerateDevices().then(function(deviceInfos) { + stream1.getTracks().forEach(function(track) { // We don't want to keep it without audio; so we are going to try to add audio now. + track.stop(); // I need to do this after the enumeration step, else it breaks firefox's labels + }); + log("updating audio"); + const audioInputSelect = getById('audioSourceScreenshare'); + audioInputSelect.remove(1); + audioInputSelect.removeAttribute("onchange"); + + + for (let i = 0; i !== deviceInfos.length; ++i) { + const deviceInfo = deviceInfos[i]; + if (deviceInfo == null) { + continue; + } + const option = document.createElement('option'); + option.value = deviceInfo.deviceId; + if (deviceInfo.kind === 'audioinput') { + option.text = deviceInfo.label || `Microphone ${audioInputSelect.length + 1}`; + audioInputSelect.appendChild(option); + } else { + log('Some other kind of source/device: ', deviceInfo); + } + } + audioInputSelect.style.minHeight = ((audioInputSelect.childElementCount + 1) * 1.15 * 16) + 'px'; + audioInputSelect.style.minWidth = "342px"; + }); + }); + } catch (e) { + if (!(session.cleanOutput)) { + if (window.isSecureContext) { + warnUser("An error has occured when trying to access the default audio device. The reason is not known."); + } else if ((iOS) || (iPad)) { + warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported."); + } else { + warnUser("Error acessing the default audio device.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia"); + } + } + } +} + + +function gotDevices(deviceInfos) { // https://github.com/webrtc/samples/blob/gh-pages/src/content/devices/input-output/js/main.js#L19 + + log("got devices!"); + log(deviceInfos); + try { + const audioInputSelect = getById('audioSource'); + + audioInputSelect.innerHTML = ""; + + var option = document.createElement('input'); + option.type = "checkbox"; + option.value = "ZZZ"; + option.name = "multiselect1"; + option.id = "multiselect1"; + option.style.display = "none"; + option.checked = true; + + + var label = document.createElement('label'); + label.for = option.name; + label.innerHTML = 'No Audio'; + + var listele = document.createElement('li'); + listele.appendChild(option); + listele.appendChild(label); + audioInputSelect.appendChild(listele); + + + option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected + if (!(getById("multiselect1").checked)) { + getById("multiselect1").checked = true; + + if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { + SelectedAudioInputDevices.push(event.currentTarget.value); + } + + log("CHECKED 1"); + } else { + + var list = document.querySelectorAll("#audioSource>li>input"); + for (var i = 0; i < list.length; i++) { + if (list[i].id !== "multiselect1") { + list[i].checked = false; + } + } + + while (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) { + SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(event.currentTarget.value), 1); + } + } + }; + + getById('multiselect-trigger').dataset.state = '0'; + getById('multiselect-trigger').classList.add('closed'); + getById('multiselect-trigger').classList.remove('open'); + getById('chevarrow1').classList.add('bottom'); + + const videoSelect = getById('videoSourceSelect'); + const audioOutputSelect = getById('outputSource'); + const selectors = [videoSelect]; + + const values = selectors.map(select => select.value); + selectors.forEach(select => { + while (select.firstChild) { + select.removeChild(select.firstChild); + } + }); + + + function comp(a, b) { + if (a.kind === 'audioinput') { + return 0; + } else if (a.kind === 'audiooutput') { + return 0; + } + const labelA = a.label.toUpperCase(); + const labelB = b.label.toUpperCase(); + if (labelA > labelB) { + return 1; + } else if (labelA < labelB) { + return -1; + } + return 0; + } + //deviceInfos.sort(comp); // I like this idea, but it messes with the defaults. I just don't know what it will do. + + // This is to hide NDI from default device. NDI Tools fucks up. + var tmp = []; + for (let i = 0; i !== deviceInfos.length; ++i) { + deviceInfo = deviceInfos[i]; + if (!((deviceInfo.kind === 'videoinput') && (deviceInfo.label.toLowerCase().startsWith("ndi") || deviceInfo.label.toLowerCase().startsWith("newtek")))) { + tmp.push(deviceInfo); + } + } + + for (let i = 0; i !== deviceInfos.length; ++i) { + deviceInfo = deviceInfos[i]; + if ((deviceInfo.kind === 'videoinput') && (deviceInfo.label.toLowerCase().startsWith("ndi") || deviceInfo.label.toLowerCase().startsWith("newtek"))) { + tmp.push(deviceInfo); + log("V DEVICE FOUND = " + deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase()); + } + } + deviceInfos = tmp; + log(deviceInfos); + + if ((session.audioDevice) && (session.audioDevice !== 1)) { // this sorts according to users's manual selection + var tmp = []; + for (let i = 0; i !== deviceInfos.length; ++i) { + deviceInfo = deviceInfos[i]; + if ((deviceInfo.kind === 'audioinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.audioDevice))) { + tmp.push(deviceInfo); + log("A DEVICE FOUND = " + deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase()); + } else if (deviceInfo.deviceId === session.audioDevice){ + tmp.push(deviceInfo); + log("EXACT A DEVICE FOUND"); + } + } + for (let i = 0; i !== deviceInfos.length; ++i) { + deviceInfo = deviceInfos[i]; + if (!((deviceInfo.kind === 'audioinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.audioDevice)))) { + if (deviceInfo.deviceId !== session.audioDevice){ + tmp.push(deviceInfo); + } + } + } + + deviceInfos = tmp; + log(session.audioDevice); + log(deviceInfos); + } + + + if ((session.videoDevice) && (session.videoDevice !== 1)) { // this sorts according to users's manual selection + var tmp = []; + for (let i = 0; i !== deviceInfos.length; ++i) { + deviceInfo = deviceInfos[i]; + if ((deviceInfo.kind === 'videoinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.videoDevice))) { + tmp.push(deviceInfo); + log("V DEVICE FOUND = " + deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase()); + } else if (deviceInfo.deviceId === session.videoDevice){ + tmp.push(deviceInfo); + log("EXACT V DEVICE FOUND"); + } + } + for (let i = 0; i !== deviceInfos.length; ++i) { + deviceInfo = deviceInfos[i]; + if (!((deviceInfo.kind === 'videoinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.videoDevice)))) { + if (deviceInfo.deviceId !== session.videoDevice){ + tmp.push(deviceInfo); + } + } + } + deviceInfos = tmp; + log("VDECICE:" + session.videoDevice); + log(deviceInfos); + } + + + var counter = 1; + for (let i = 0; i !== deviceInfos.length; ++i) { + const deviceInfo = deviceInfos[i]; + if (deviceInfo == null) { + continue; + } + + if (deviceInfo.kind === 'audioinput') { + option = document.createElement('input'); + option.type = "checkbox"; + counter++; + listele = document.createElement('li'); + if (counter == 2) { + option.checked = true; + listele.style.display = "block"; + option.style.display = "none"; + getById("multiselect1").checked = false; + try{ + getById("multiselect1").parentNode.style.display = "none"; + } catch(e){} + } else { + listele.style.display = "none"; + } + + + option.value = deviceInfo.deviceId || "default"; + option.name = "multiselect" + counter; + option.id = "multiselect" + counter; + label = document.createElement('label'); + label.for = option.name; + + label.innerHTML = " " + (deviceInfo.label || ("microphone " + ((audioInputSelect.length || 0) + 1))); + + listele.appendChild(option); + listele.appendChild(label); + audioInputSelect.appendChild(listele); + + option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected + getById("multiselect1").checked = false; + log("UNCHECKED"); + if (!(CtrlPressed)) { + document.querySelectorAll("#audioSource input[type='checkbox']").forEach(function(item) { + if (event.currentTarget.id !== item.id) { + item.checked = false; + + while (SelectedAudioInputDevices.indexOf(item.value) > -1) { + SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); + } + + } else { + item.checked = true; + if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { + SelectedAudioInputDevices.push(event.currentTarget.value); + } + } + }); + } + }; + + } else if (deviceInfo.kind === 'videoinput') { + option = document.createElement('option'); + option.value = deviceInfo.deviceId || "default"; + option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`; + videoSelect.appendChild(option); + } else if (deviceInfo.kind === 'audiooutput') { + option = document.createElement('option'); + if (audioOutputSelect.length === 0) { + option.dataset.default = true; + } else { + option.dataset.default = false; + } + option.value = deviceInfo.deviceId || "default"; + if (option.value == session.sink) { + option.selected = true; + } + option.text = deviceInfo.label || `Speaker ${audioOutputSelect.length + 1}`; + audioOutputSelect.appendChild(option); + } else { + log('Some other kind of source/device: ', deviceInfo); + } + } + + if (audioOutputSelect.childNodes.length == 0) { + option = document.createElement('option'); + option.value = "default"; + option.text = "System Default"; + audioOutputSelect.appendChild(option); + } + + option = document.createElement('option'); + option.text = "Disable Video"; + option.value = "ZZZ"; + videoSelect.appendChild(option); // NO AUDIO OPTION + + selectors.forEach((select, selectorIndex) => { + if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) { + select.value = values[selectorIndex]; + } + }); + + } catch (e) { + errorlog(e); + } +} + + +function getUserMediaVideoParams(resolutionFallbackLevel, isSafariBrowser) { + switch (resolutionFallbackLevel) { + case 0: + if (isSafariBrowser) { + return { + width: { + min: 360 + , ideal: 1920 + , max: 1920 + } + , height: { + min: 360 + , ideal: 1080 + , max: 1080 + } + }; + } else { + return { + width: { + min: 720 + , ideal: 1920 + , max: 1920 + } + , height: { + min: 720 + , ideal: 1080 + , max: 1920 + } + }; + } + case 1: + if (isSafariBrowser) { + return { + width: { + min: 360 + , ideal: 1280 + , max: 1280 + } + , height: { + min: 360 + , ideal: 720 + , max: 720 + } + }; + } else { + return { + width: { + min: 720 + , ideal: 1280 + , max: 1280 + } + , height: { + min: 720 + , ideal: 720 + , max: 1280 + } + }; + } + case 2: + if (isSafariBrowser) { + return { + width: { + min: 640 + } + , height: { + min: 360 + } + }; + } else { + return { + width: { + min: 240 + , ideal: 640 + , max: 1280 + } + , height: { + min: 240 + , ideal: 360 + , max: 1280 + } + }; + } + case 3: + if (isSafariBrowser) { + return { + width: { + min: 360 + , ideal: 1280 + , max: 1440 + } + }; + } else { + return { + width: { + min: 360 + , ideal: 1280 + , max: 1440 + } + }; + } + case 4: + if (isSafariBrowser) { + return { + height: { + min: 360 + , ideal: 720 + , max: 960 + } + }; + } else { + return { + height: { + ideal: 720 + , max: 960 + } + }; + } + case 5: + if (isSafariBrowser) { + return { + width: { + min: 360 + , ideal: 640 + , max: 1440 + } + , height: { + min: 360 + , ideal: 360 + , max: 720 + } + }; + } else { + return { + width: { + ideal: 640 + , max: 1920 + } + , height: { + ideal: 360 + , max: 1920 + } + }; // same as default, but I didn't want to mess with framerates until I gave it all a try first + } + case 6: + if (isSafariBrowser) { + return {}; // iphone users probably don't need to wait any longer, so let them just get to it + } else { + return { + width: { + min: 360 + , ideal: 640 + , max: 3840 + } + , height: { + min: 360 + , ideal: 360 + , max: 2160 + } + }; + + } + case 7: + return { // If the camera is recording in low-light, it may have a low framerate. It coudl also be recording at a very high resolution. + width: { + min: 360 + , ideal: 640 + } + , height: { + min: 360 + , ideal: 360 + } + , }; + + case 8: + return { + width: { + min: 360 + } + , height: { + min: 360 + } + , frameRate: 10 + }; // same as default, but I didn't want to mess with framerates until I gave it all a try first + case 9: + return { + frameRate: 0 + }; // Some Samsung Devices report they can only support a framerate of 0. + case 10: + return {} + default: + return {}; + } +} + +function addScreenDevices(device) { + if (device.kind == "audio") { + const audioInputSelect = getById('audioSource3'); + const listele = document.createElement('li'); + listele.style.display = "block"; + + const option = document.createElement('input'); + option.type = "checkbox"; + option.checked = true; + + if (getById('multiselect-trigger3').dataset.state == 0) { + option.style.display = "none"; + } + + option.value = device.id; + option.name = device.label; + option.dataset.type = "screen"; + option.label = device.label; + + const label = document.createElement('label'); + label.for = option.name; + label.innerHTML = " " + device.label; + listele.appendChild(option); + listele.appendChild(label); + + option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected + log("change 4644"); + if (!(CtrlPressed)) { + document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { + if (event.currentTarget.value !== item.value) { // this shoulnd't happen, but if it does. + + item.checked = false; + + if (item.dataset.type == "screen") { + item.parentElement.parentElement.removeChild(item.parentElement); + } + + while (SelectedAudioInputDevices.indexOf(item.value) > -1) { + SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); + } + + activatedPreview = false; + grabAudio("videosource", "#audioSource3"); // exclude item.id + + } else { + if (SelectedAudioInputDevices.indexOf(item.value) > -1) {} else { + SelectedAudioInputDevices.push(item.value); + } + + item.checked = true; + activatedPreview = false; + grabAudio("videosource", "#audioSource3", item.value); // exclude item.id. we will reconnect, even if already connected, as a way to 'reset' a device if it isn't working. + } + }); + } + event.stopPropagation(); + return false; + }; + audioInputSelect.appendChild(listele); + getById("audioSourceNoAudio2").checked = false; + + } else if (device.kind == "video") { + const videoSelect = getById('videoSource3'); + //const selectors = [ videoSelect]; + //const values = selectors.map(select => select.value); + const option = document.createElement('option'); + option.value = device.id; + option.text = device.label; + option.selected = true; + option.label = device.label; + videoSelect.appendChild(option); + } +} + +function gotDevices2(deviceInfos) { + log("got devices!"); + log(deviceInfos); + + getById("multiselect-trigger3").dataset.state = "0"; + getById("multiselect-trigger3").classList.add('closed'); + getById("multiselect-trigger3").classList.remove('open'); + getById("chevarrow2").classList.add('bottom'); + + var knownTrack = false; + + try { + const audioInputSelect = getById('audioSource3'); + const videoSelect = getById('videoSource3'); + const audioOutputSelect = getById('outputSource3'); + const selectors = [videoSelect]; + + + [audioInputSelect].forEach(select => { + while (select.firstChild) { + select.removeChild(select.firstChild); + } + }); + + const values = selectors.map(select => select.value); + selectors.forEach(select => { + while (select.firstChild) { + select.removeChild(select.firstChild); + } + }); + + [audioOutputSelect].forEach(select => { + while (select.firstChild) { + select.removeChild(select.firstChild); + } + }); + + var counter = 0; + for (let i = 0; i !== deviceInfos.length; ++i) { + const deviceInfo = deviceInfos[i]; + if (deviceInfo == null) { + continue; + } + + if (deviceInfo.kind === 'audioinput') { + const option = document.createElement('input'); + option.type = "checkbox"; + counter++; + const listele = document.createElement('li'); + listele.style.display = "none"; + + try { + session.streamSrc.getAudioTracks().forEach(function(track) { + if (deviceInfo.label == track.label) { + option.checked = true; + listele.style.display = "inherit"; + } + }); + } catch (e) { + errorlog(e); + } + + option.style.display = "none" + option.value = deviceInfo.deviceId || "default"; + option.name = "multiselecta" + counter; + option.id = "multiselecta" + counter; + option.dataset.label = deviceInfo.label || ("microphone " + ((audioInputSelect.length || 0) + 1)); + + const label = document.createElement('label'); + label.for = option.name; + + label.innerHTML = " " + (deviceInfo.label || ("microphone " + ((audioInputSelect.length || 0) + 1))); + + listele.appendChild(option); + listele.appendChild(label); + audioInputSelect.appendChild(listele); + + option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected + log("change 4768"); + if (!(CtrlPressed)) { + document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { + if (event.currentTarget.value !== item.value) { + item.checked = false; + if (item.dataset.type == "screen") { + item.parentElement.parentElement.removeChild(item.parentElement); + } + while (SelectedAudioInputDevices.indexOf(item.value) > -1) { + SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); + } + } else { + item.checked = true; + if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { + SelectedAudioInputDevices.push(event.currentTarget.value); + } + } + }); + } else { + + if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { + SelectedAudioInputDevices.push(event.currentTarget.value); + } + + getById("audioSourceNoAudio2").checked = false; + } + }; + + } else if (deviceInfo.kind === 'videoinput') { + const option = document.createElement('option'); + option.value = deviceInfo.deviceId || "default"; + option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`; + try { + if (!knownTrack){ + if (session.canvasSource){ + session.canvasSource.srcObject.getVideoTracks().forEach(function(track) { + if (option.text == track.label) { + option.selected = true; + knownTrack = true; + } + }); + } + } + if (!knownTrack){ + session.streamSrc.getVideoTracks().forEach(function(track) { + if (option.text == track.label) { + option.selected = true; + knownTrack = true; + } + }); + } + } catch (e) { + errorlog(e); + } + videoSelect.appendChild(option); + + } else if (deviceInfo.kind === 'audiooutput') { + const option = document.createElement('option'); + if (audioOutputSelect.length === 0) { + option.dataset.default = true; + } else { + option.dataset.default = false; + } + option.value = deviceInfo.deviceId || "default"; + if (option.value == session.sink) { + option.selected = true; + } + option.text = deviceInfo.label || `Speaker ${outputSelect.length + 1}`; + audioOutputSelect.appendChild(option); + + } else { + log('Some other kind of source/device: ', deviceInfo); + } + } + + if (audioOutputSelect.childNodes.length == 0) { + const option = document.createElement('option'); + option.value = "default"; + option.text = "System Default"; + audioOutputSelect.appendChild(option); + } + + //////////// + + session.streamSrc.getAudioTracks().forEach(function(track) { // add active ScreenShare audio tracks to the list + log("Checking for screenshare audio"); + var matched = false; + for (var i = 0; i !== deviceInfos.length; ++i) { + var deviceInfo = deviceInfos[i]; + if (deviceInfo == null) { + continue; + } + log("---"); + if (track.label == deviceInfo.label) { + matched = true; + continue; + } + } + if (matched == false) { // Not a gUM device + + var listele = document.createElement('li'); + listele.style.display = "block"; + var option = document.createElement('input'); + option.type = "checkbox"; + option.value = track.id; + option.checked = true; + option.style.display = "none"; + option.name = track.label; + option.label = track.label; + option.dataset.type = "screen"; + const label = document.createElement('label'); + label.for = option.name; + label.innerHTML = " " + track.label; + listele.appendChild(option); + listele.appendChild(label); + option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected + log("change 4873"); + var trackid = null; + if (!(CtrlPressed)) { + + document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { + if (event.currentTarget.value !== item.value) { // this shoulnd't happen, but if it does. + item.checked = false; + if (item.dataset.type == "screen") { + item.parentElement.parentElement.removeChild(item.parentElement); + } + } else { + event.currentTarget.checked = true; + trackid = item.value; + } + }); + } else { + //getById("audioSourceNoAudio2").checked=false; + if (event.currentTarget.dataset.type == "screen") { + event.currentTarget.parentElement.parentElement.removeChild(event.currentTarget.parentElement); + } + } + activatedPreview = false; + grabAudio("videosource", "#audioSource3", trackid); // exclude item.id. + event.stopPropagation(); + return false; + }; + audioInputSelect.appendChild(listele); + } + }); + /////////// no video option + var optionss = false; + if (screensharesupport) { + optionss = document.createElement('option'); + optionss.text = "New Screen Share"; + optionss.value = "XXX"; + optionss.previous = + videoSelect.appendChild(optionss); // NO AUDIO OPTION + } + + option = document.createElement('option'); // no video + option.text = "Disable Video"; + option.value = "ZZZ"; + videoSelect.appendChild(option); + if (session.streamSrc.getVideoTracks().length == 0) { + option.selected = true; + } else if (knownTrack == false) { + option = document.createElement('option'); // no video + option.text = session.streamSrc.getVideoTracks()[0].label; + option.value = "YYY"; + videoSelect.appendChild(option); + option.selected = true; + + } + + if (optionss) { + optionss.lastSelected = videoSelect.selectedIndex; + } + + ///////////// /// NO AUDIO appended option + + var option = document.createElement('input'); + option.type = "checkbox"; + option.value = "ZZZ"; + option.style.display = "none" + option.id = "audioSourceNoAudio2"; + + var label = document.createElement('label'); + label.for = option.name; + label.innerHTML = " No Audio"; + var listele = document.createElement('li'); + + if (session.streamSrc.getAudioTracks().length == 0) { + option.checked = true; + } else { + listele.style.display = "none"; + option.checked = false; + } + option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected + log("change 4938"); + if (!(CtrlPressed)) { + document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { + if (event.currentTarget.value !== item.value) { + item.checked = false; + if (item.dataset.type == "screen") { + item.parentElement.parentElement.removeChild(item.parentElement); + } + + while (SelectedAudioInputDevices.indexOf(item.value) > -1) { + SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); + } + } else { + item.checked = true; + if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) { + // + } else { + SelectedAudioInputDevices.push(event.currentTarget.value); + } + } + }); + } else { + document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { + if (event.currentTarget.value === item.value) { + event.currentTarget.checked = true; + if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { + SelectedAudioInputDevices.push(event.currentTarget.value); + } + } else { + item.checked = false; + if (item.dataset.type == "screen") { + item.parentElement.parentElement.removeChild(item.parentElement); + } + while (SelectedAudioInputDevices.indexOf(item.value) > -1) { + SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); + } + } + + }); + } + }; + listele.appendChild(option); + listele.appendChild(label); + audioInputSelect.appendChild(listele); + + //////////// + + + selectors.forEach((select, selectorIndex) => { + if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) { + select.value = values[selectorIndex]; + } + }); + + audioInputSelect.onchange = function() { + log("Audio OPTION HAS CHANGED? 2"); + activatedPreview = false; + setTimeout(function(){ + grabAudio("videosource", "#audioSource3"); + },10) + }; + videoSelect.onchange = function(event) { + try { + if (event.target.options[event.target.options.selectedIndex].value === "XXX") { + videoSelect.selectedIndex = event.target.options[event.target.options.selectedIndex].lastSelected; + if (session.screenShareState == false) { + toggleScreenShare(); + } else { + toggleScreenShare(true); + } + return; + } + } catch (e) {} + log("video source changed"); + activatedPreview = false; + grabVideo(session.quality, "videosource", "select#videoSource3"); + enumerateDevices().then(gotDevices2).then(function() { + session.screenShareState = false; + pokeIframeAPI("screen-share-ended"); + getById("screensharebutton").classList.add("float"); + getById("screensharebutton").classList.remove("float2"); + }); + }; + getById("refreshVideoButton").onclick = function() { + if (session.screenShareState) { + log("can't refresh a screenshare"); + return; + } + log("video source changed"); + activatedPreview = false; + grabVideo(session.quality, "videosource", "select#videoSource3"); + }; + + audioOutputSelect.onchange = function() { + + if ((iOS) || (iPad)) { + return; + } + + try { + var outputSelect = getById('outputSource3'); + session.sink = outputSelect.options[outputSelect.selectedIndex].value; + } catch (e) { + errorlog(e); + } + if (!session.sink){return;} + + try { + if (document.getElementById("videosource")){ + getById("videosource").setSinkId(session.sink).then(() => { + log("New Output Device:" + session.sink); + }).catch(error => { + errorlog(error); + }); + } + + for (UUID in session.rpcs) { + try{ + if (session.rpcs[UUID].videoElement){ + session.rpcs[UUID].videoElement.setSinkId(session.sink).then(() => { + log("New Output Device for: " + UUID); + }).catch(error => { + errorlog(error); + }); + } + } catch(e){warnlog(e);} + } + } catch (e) { + errorlog(e); + } + } + + } catch (e) { + errorlog(e); + } +} + +function gotDevicesRemote(deviceInfos, UUID) { + + try { + if (document.getElementById("remoteVideoSelect_"+UUID)){ + var videoSelect = document.getElementById("remoteVideoSelect_"+UUID); + var length = videoSelect.options.length; + for (i = length-1; i >= 0; i--) { + videoSelect.options[i] = null; + } + } else { + var videoSelect = document.createElement("select"); + videoSelect.id = "remoteVideoSelect_"+UUID; + videoSelect.style = "max-width:180px;font-size: 70% !important; margin: 5px 5px 5px 0; padding:2px;"; + var buttonGO = document.createElement("button"); + buttonGO.innerHTML = ' Apply'; + buttonGO.style = "padding: 5px;"; + buttonGO.title = "This will ask the remote guest for permission to change"; + buttonGO.onclick = function(){ + var data = {} + data.changeCamera = videoSelect.value; + data.UUID = UUID; + session.sendRequest(data, UUID); // Viewer is requesting the PUBLISHER + }; + + getById("advanced_video_director_" + UUID).appendChild(videoSelect); + getById("advanced_video_director_" + UUID).appendChild(buttonGO); + } + + if (document.getElementById("remoteAudioSelect_"+UUID)){ + var audioSelect = document.getElementById("remoteAudioSelect_"+UUID); + var length = audioSelect.options.length; + for (i = length-1; i >= 0; i--) { + audioSelect.options[i] = null; + } + } else { + var audioSelect = document.createElement("select"); + audioSelect.id = "remoteAudioSelect_"+UUID; + audioSelect.style = "max-width:180px;font-size: 70% !important; margin: 5px 5px 5px 0; padding:2px;"; + var buttonGO = document.createElement("button"); + buttonGO.innerHTML = ' Apply'; + buttonGO.style = "padding: 5px;"; + buttonGO.title = "This will ask the remote guest for permission to change"; + buttonGO.onclick = function(){ + var data = {} + data.changeMicrophone = audioSelect.value; + data.UUID = UUID; + session.sendRequest(data, UUID); // Viewer is requesting the PUBLISHER + } + var audioSelectDiv = document.createElement("div"); + getById("advanced_audio_director_" + UUID).appendChild(audioSelectDiv); + audioSelectDiv.appendChild(audioSelect); + audioSelectDiv.appendChild(buttonGO); + + } + + if (document.getElementById("remoteAudioOutputSelect_"+UUID)){ + var audioOutputSelect = document.getElementById("remoteAudioOutputSelect_"+UUID); + var length = audioOutputSelect.options.length; + for (i = length-1; i >= 0; i--) { + audioOutputSelect.options[i] = null; + } + } else { + var audioOutputSelect = document.createElement("select"); + audioOutputSelect.id = "remoteAudioOutputSelect_"+UUID; + audioOutputSelect.style = "max-width:180px;font-size: 70% !important; margin: 5px 5px 5px 0; padding:2px;"; + var buttonGO = document.createElement("button"); + buttonGO.innerHTML = ' Apply'; + buttonGO.style = "padding: 5px;"; + buttonGO.title = "This will ask the remote guest for permission to change"; + buttonGO.onclick = function(){ + var data = {} + data.changeSpeaker = audioOutputSelect.value; + data.UUID = UUID; + session.sendRequest(data, UUID); // Viewer is requesting the PUBLISHER + } + getById("advanced_audio_director_" + UUID).appendChild(audioOutputSelect); + getById("advanced_audio_director_" + UUID).appendChild(buttonGO); + getById("advanced_audio_director_" + UUID).appendChild(buttonGO); + } + + + for (let i = 0; i !== deviceInfos.length; ++i) { + const deviceInfo = deviceInfos[i]; + if (deviceInfo == null) { + continue; + } + if (deviceInfo.kind === 'videoinput'){ + const option = document.createElement('option'); + option.value = deviceInfo.deviceId || "default"; + option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`; + videoSelect.appendChild(option); + + } else if (deviceInfo.kind === 'audioinput'){ + const option = document.createElement('option'); + option.value = deviceInfo.deviceId || "default"; + option.text = deviceInfo.label || `microphone ${audioSelect.length + 1}`; + audioSelect.appendChild(option); + + } else if (deviceInfo.kind === 'audiooutput'){ + const option = document.createElement('option'); + option.value = deviceInfo.deviceId || "default"; + option.text = deviceInfo.label || `microphone ${audioOutputSelect.length + 1}`; + audioOutputSelect.appendChild(option); + } + } + + } catch(e){errorlog(e);} +} + +function playtone(screen = false) { + + if ((iOS) || (iPad)) { + // try{ + // session.audioContext.resume(); + // } catch(e){errorlog(e);} + var testtone = document.getElementById("testtone"); + if (testtone) { + testtone.mute + testtone.play(); + } + return; + } + + if (screen) { + try{ + var outputSelect = getById('outputSourceScreenshare'); + session.sink = outputSelect.options[outputSelect.selectedIndex].value; + } catch(e){errorlog(e);} + } + + var testtone = document.getElementById("testtone"); + if (testtone) { + if (session.sink) { + try { + testtone.setSinkId(session.sink).then(() => { // TODO: iOS doens't support sink. Needs to bypass if IOS + log("changing audio sink:" + session.sink); + testtone.play(); + }).catch(error => { + errolog("couldn't set sink"); + errorlog(error); + }); + } catch (e) { + warnlog(e); // firefox? + testtone.play(); + } + } else { + testtone.play(); + } + } +} + +async function getAudioOnly(selector, trackid = null, override = false) { + var audioSelect = document.querySelector(selector).querySelectorAll("input"); + var audioList = []; + var streams = []; + log("getAudioOnly()"); + for (var i = 0; i < audioSelect.length; i++) { + if (audioSelect[i].value == "ZZZ") { + continue; + } else if (trackid == audioSelect[i].value) { // skip already excluded + continue; + } else if ("screen" == audioSelect[i].dataset.type) { // skip already excluded ---------- !!!!!! DOES THIS MAKE SENSE? TODO: CHECK + continue; + } else if (audioSelect[i].checked) { + log(audioSelect[i]); + audioList.push(audioSelect[i]); + } + } + for (var i = 0; i < audioList.length; i++) { + + if ((session.echoCancellation !== false) && (session.autoGainControl !== false) && (session.noiseSuppression !== false)) { + var constraint = { + audio: { + deviceId: audioList[i].value + } + }; + } else { // Just trying to avoid problems with some systems that don't support these features + var constraint = { + audio: { + deviceId: { + exact: audioList[i].value + } + } + }; + if (session.echoCancellation === false) { + constraint.audio.echoCancellation = false; + } else { + constraint.audio.echoCancellation = true; + } + if (session.autoGainControl === false) { + constraint.audio.autoGainControl = false; + } else { + constraint.audio.autoGainControl = true; + } + if (session.noiseSuppression === false) { + constraint.audio.noiseSuppression = false; + } else { + constraint.audio.noiseSuppression = true; + } + } + constraint.video = false; + if (override !== false) { + try { + if (override.audio.deviceId == audioList[i].value) { + constraint = override; + } + } catch (e) {} + } + + if (session.audioInputChannels) { + if (constraint.audio === true) { + constraint.audio = {}; + constraint.audio.channelCount = session.audioInputChannels; + } else if (constraint.audio) { + constraint.audio.channelCount = session.audioInputChannels; + } + } + log("CONSTRAINT"); + log(constraint); + var stream = await navigator.mediaDevices.getUserMedia(constraint).then(function(stream2) { + return stream2; + }).catch(function(err) { + warnlog(err); + if (!(session.cleanOutput)) { + if (override !== false) { + if (err.name) { + if (err.constraint) { + warnUser(err['name'] + ": " + err['constraint']); + } + } + } + } + }); // More error reporting maybe? + if (stream) { + streams.push(stream); + } + } + + return streams; +} + +function applyMirror(mirror, eleName = 'previewWebcam') { // true unmirrors as its already mirrored + + var transFlip = ""; + var transNorm = ""; + if ((eleName == 'videosource') && (session.windowed)) { + transFlip = " translate(0, 50%)"; + transNorm = " translate(0, -50%)"; + } + + if (session.mirrored == 2) { + mirror = true; + } else if (session.mirrored === 0) { + mirror = true; + } + + + if (mirror) { + if (session.mirrored && session.flipped) { + getById(eleName).style.transform = " scaleX(-1) scaleY(-1)" + transFlip; + getById(eleName).classList.add("mirrorControl"); + } else if (session.mirrored) { + getById(eleName).style.transform = "scaleX(-1)" + transNorm; + getById(eleName).classList.add("mirrorControl"); + } else if (session.flipped) { + getById(eleName).style.transform = "scaleY(-1) scaleX(1)" + transFlip; + getById(eleName).classList.remove("mirrorControl"); + } else { + getById(eleName).style.transform = "scaleX(1)" + transNorm; + getById(eleName).classList.remove("mirrorControl"); + } + } else { + if (session.mirrored && session.flipped) { + getById(eleName).style.transform = " scaleX(1) scaleY(-1)" + transFlip; + getById(eleName).classList.remove("mirrorControl"); + } else if (session.mirrored) { + getById(eleName).style.transform = "scaleX(1)" + transNorm; + getById(eleName).classList.remove("mirrorControl"); + } else if (session.flipped) { + getById(eleName).style.transform = "scaleY(-1) scaleX(-1)" + transFlip; + getById(eleName).classList.add("mirrorControl"); + } else { + getById(eleName).style.transform = "scaleX(-1)" + transNorm; + getById(eleName).classList.add("mirrorControl"); + } + } +} + +function cleanupMediaTracks() { + try { + if (session.streamSrc) { + session.streamSrc.getTracks().forEach(function(track) { + session.streamSrc.removeTrack(track); + track.stop(); + log("stopping old track"); + }); + } + if (session.videoElement) { + session.videoElement.srcObject.getTracks().forEach(function(track) { + session.videoElement.srcObject.removeTrack(track); + track.stop(); + log("stopping old track"); + }); + } + activatedPreview = false; + } catch (e) { + errorlog(e); + } +} + +/// Detect system changes; handle change or use for debugging +var lastAudioDevice = null; +var lastVideoDevice = null; +var lastPlaybackDevice = null; + +var audioReconnectTimeout = null; +var videoReconnectTimeout = null; +var grabDevicesTimeout = null; +var playbackReconnectTimeout = null; + +function reconnectDevices(event) { /// TODO: Perhaps change this to only if there is a DISCONNECT; rather than ON NEW DEVICE? + if ((iOS) || (iPad)) { + // try{ + // session.audioContext.resume(); + // } catch(e){errorlog(e);} + // resetupAudioOut(); + return; + } + warnlog("A media device has changed"); + + if (document.getElementById("previewWebcam")) { + var outputSelect = document.getElementById("outputSource"); + if (!outputSelect) { + errorlog("resetup audio failed"); + return; + } + try { + session.sink = outputSelect.options[outputSelect.selectedIndex].value; + } catch (e) { + errorlog(e); + } + if (session.sink){ + try { + getById("previewWebcam").setSinkId(session.sink).then(() => {}).catch(error => { + warnlog(error); + }); + } catch(e){errorlog(e);} + } + return; + } + + + if (session.streamSrc === null) { + return; + } + if (document.getElementById("videosource") === null) { + return; + } + + try { + session.streamSrc.getTracks().forEach(function(track) { + + if (track.readyState == "ended") { + if (track.kind == "audio") { + lastAudioDevice = track.label; + } else if (track.kind == "video") { + lastVideoDevice = track.label; + } + session.streamSrc.removeTrack(track); + log("remove ended old track"); + } + }); + + session.videoElement.srcObject.getTracks().forEach(function(track) { + if (track.readyState == "ended") { + session.videoElement.srcObject.removeTrack(track); + log("remove ended old track"); + } + }); + + } catch (e) { + errorlog(e); + } + + clearTimeout(audioReconnectTimeout); + audioReconnectTimeout = null; + if (lastAudioDevice) { + audioReconnectTimeout = setTimeout(function() { // only reconnect same audio device. If reconnected, clear the disconnected flag. + enumerateDevices().then(gotDevices2).then(function() { + // TODO: check to see if any audio is connected? + var streamConnected = false; + var audioSelect = getById("audioSource3").querySelectorAll("input"); + for (var i = 0; i < audioSelect.length; i++) { + if (audioSelect[i].value == "ZZZ") { + continue; + } else if (audioSelect[i].checked) { + log("checked"); + streamConnected = true; + break; + } + } + + if (!streamConnected) { + for (var i = 0; i < audioSelect.length; i++) { + if (audioSelect[i].value == "ZZZ") { + continue; + } + //errorlog(lastAudioDevice + " : " + audioSelect[i].dataset.label); + if (lastAudioDevice == audioSelect[i].dataset.label) { // if the last disconnected device matches. + audioSelect[i].checked = true; + streamConnected = true; + lastAudioDevice = null; + warnlog("DISCONNECTED AUDIO DEVICE RECONNECTED"); + //for (var j=0; j check if session.sink still exists -> if not, select default default (track past last sink) -> if last disconnected devices comes back, reconnect it. + + // lastPlaybackDevice + //if (session.sink){ // Let Chrome handle the audio automatically, since not manually specified. + clearTimeout(playbackReconnectTimeout); + playbackReconnectTimeout = setTimeout(function() { + enumerateDevices().then(gotDevices2).then(function() { + resetupAudioOut(); + }); + }, 500); + +} + +function resetupAudioOut() { + if (iOS || iPad) { + for (var UUID in session.rpcs) { + if (session.rpcs[UUID].videoElement){ + try{ + log("10076"); + session.rpcs[UUID].videoElement.pause().then(() => { + setTimeout(function(uuid) { + log("win"); + try{ + session.rpcs[uuid].videoElement.play().then(() => { + log("toggle pause/play"); + }); + } catch(e){errorlog(e);} + }, 0, UUID); + }); + } catch(e){errorlog(e);} + } + } + return; + } + + var outputSelect = document.getElementById("outputSource3"); + if (!outputSelect) { + errorlog("resetup audio failed"); + return; + } + log("Resetting Audio Output"); + var sinkSet = false; + for (var i = 0; i < outputSelect.options.length; i++) { + if (outputSelect.options[i].value == session.sink) { + outputSelect.options[i].selected = true; + sinkSet = true; + } + } + if (sinkSet == false) { + if (outputSelect.options[0]) { + outputSelect.options[0].selected = true; + sinkSet = outputSelect.value; + } + } else { + sinkSet = session.sink; + } + if (sinkSet) { + if (session.videoElement){ + session.videoElement.setSinkId(sinkSet).then(() => {}).catch(error => { + errorlog(error); + }); + } + for (UUID in session.rpcs) { + try{ + if (session.rpcs[UUID].videoElement){ + session.rpcs[UUID].videoElement.setSinkId(sinkSet).then(() => { + log("New Output Device for: " + UUID); + }).catch(error => { + errorlog(error); + }); + } + } catch(e){warnlog(e);} + } + } +} + +function obfuscateURL(input) { + if (input.startsWith("https://obs.ninja/")) { + input = input.replace('https://obs.ninja/', ''); + } else if (input.startsWith("http://obs.ninja/")) { + input = input.replace('http://obs.ninja/', ''); + } else if (input.startsWith("obs.ninja/")) { + input = input.replace('obs.ninja/', ''); + } else if (input.startsWith("https://vdo.ninja/")) { + input = input.replace('https://vdo.ninja/', ''); + } else if (input.startsWith("http://vdo.ninja/")) { + input = input.replace('http://vdo.ninja/', ''); + } else if (input.startsWith("vdo.ninja/")) { + input = input.replace('vdo.ninja/', ''); + } + + input = input.replace('&view=', '&v='); + input = input.replace('&view&', '&v&'); + input = input.replace('?view&', '?v&'); + input = input.replace('?view=', '?v='); + + input = input.replace('&videobitrate=', '&vb='); + input = input.replace('?videobitrate=', '?vb='); + input = input.replace('&bitrate=', '&vb='); + input = input.replace('?bitrate=', '?vb='); + + input = input.replace('?audiodevice=', '?ad='); + input = input.replace('&audiodevice=', '&ad='); + + input = input.replace('?label=', '?l='); + input = input.replace('&label=', '&l='); + + input = input.replace('?stereo=', '?s='); + input = input.replace('&stereo=', '&s='); + input = input.replace('&stereo&', '&s&'); + input = input.replace('?stereo&', '?s&'); + + input = input.replace('?webcam&', '?wc&'); + input = input.replace('&webcam&', '&wc&'); + + input = input.replace('?remote=', '?rm='); + input = input.replace('&remote=', '&rm='); + + input = input.replace('?password=', '?p='); + input = input.replace('&password=', '&p='); + + input = input.replace('&maxvideobitrate=', '&mvb='); + input = input.replace('?maxvideobitrate=', '?mvb='); + + input = input.replace('&maxbitrate=', '&mvb='); + input = input.replace('?maxbitrate=', '?mvb='); + + input = input.replace('&height=', '&h='); + input = input.replace('?height=', '?h='); + + input = input.replace('&width=', '&w='); + input = input.replace('?width=', '?w='); + + input = input.replace('&quality=', '&q='); + input = input.replace('?quality=', '?q='); + + input = input.replace('&cleanoutput=', '&clean='); + input = input.replace('?cleanoutput=', '?clean='); + + input = input.replace('&maxviewers=', '&clean='); + input = input.replace('?maxviewers=', '?clean='); + + input = input.replace('&framerate=', '&fr='); + input = input.replace('?framerate=', '?fr='); + + input = input.replace('&fps=', '&fr='); + input = input.replace('?fps=', '?fr='); + + input = input.replace('&permaid=', '&push='); + input = input.replace('?permaid=', '?push='); + + input = input.replace('&roomid=', '&r='); + input = input.replace('?roomid=', '?r='); + + input = input.replace('&room=', '&r='); + input = input.replace('?room=', '?r='); + + log(input); + var key = "OBSNINJAFORLIFE"; + var encrypted = CryptoJS.AES.encrypt(input, key); + var output = "https://invite.cam/" + encrypted.toString(); + return output; +} + + +var beforeScreenShare = null; // video +var screenShareAudioTrack = null; +async function toggleScreenShare(reload = false) { //////////////////////////// + + if (reload) { + await grabScreen(quality = 0, audio = true, videoOnEnd = true).then(res => { + if (res != false) { + session.screenShareState = true; + getById("screensharebutton").classList.add("float2"); + getById("screensharebutton").classList.remove("float"); + enumerateDevices().then(gotDevices2).then(function() {}); + } + + }); + return; + } + + + if (session.screenShareState == false) { // adding a screen + + await grabScreen(quality = 0, audio = true, videoOnEnd = true).then(res => { + if (res != false) { + session.screenShareState = true; + getById("screensharebutton").classList.add("float2"); + getById("screensharebutton").classList.remove("float"); + enumerateDevices().then(gotDevices2).then(function() {}); + } + + }); + + } else { // removing a screen . session.screenShareState already true true ///////////////////////////////// + + + session.screenShareState = false; + pokeIframeAPI("screen-share-ended"); + + if (beforeScreenShare) { + + session.streamSrc.getAudioTracks().forEach(function(track) { // previous video track; saving it. Must remove the track at some point. + if (screenShareAudioTrack == track) { // since there are more than one audio track, lets see if we can remove JUST the audio track for the screen share. + session.streamSrc.removeTrack(track); + track.stop(); + } + }); + session.streamSrc.getVideoTracks().forEach(function(track) { + //errorlog(track); + session.streamSrc.removeTrack(track); + track.stop(); + }); + + session.videoElement.srcObject.getVideoTracks().forEach(function(track) { + //errorlog(track); + session.videoElement.srcObject.removeTrack(track); + track.stop(); + }); + + getById("screensharebutton").classList.add("float"); + getById("screensharebutton").classList.remove("float2"); + + session.streamSrc.addTrack(beforeScreenShare); // add back in the video track we had before we started screen sharing. It should be NULL if we changed the video track else where (such as via the settings). #TODO: + session.videoElement.srcObject.addTrack(beforeScreenShare); + + toggleVideoMute(true); + for (UUID in session.pcs) { + try { + if ((session.pcs[UUID].guest == true) && (session.roombitrate === 0)) { + log("room rate restriction detected. No videos will be published to other guests"); + } else if (session.pcs[UUID].allowVideo == true) { // allow + var senders = session.pcs[UUID].getSenders(); // for any connected peer, update the video they have if connected with a video already. + var added = false; + senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? + if (sender.track) { + if (sender.track && sender.track.kind == "video") { + sender.replaceTrack(beforeScreenShare); // replace may not be supported by all browsers. eek. + sender.track.enabled = true; + added = true; + } + } + }); + if (added == false) { + session.pcs[UUID].addTrack(beforeScreenShare, stream); + setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker + } + } + } catch (e) { + errorlog(e); + } + } + session.refreshScale(); + beforeScreenShare = null; + } + toggleSettings(forceShow = true); + //enumerateDevices().then(gotDevices2).then(function(){ + //grabVideo(); + //grabAudio(); + // toggleSettings(forceShow=true); + //}); + + + } +} + +var ElectronDesktopCapture = false; +if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { // this enables Screen Capture in Electron + try { + const { desktopCapturer} = require('electron'); // This is definitely Electron specific. Requires Node Integration to be on, which is a potential security hazzard + window.navigator.mediaDevices.getDisplayMedia = () => { + return new Promise(async (resolve, reject) => { + try { + + if (session.autostart){ + var sscid = 0 + if (typeof session.screenshare === "number"){ + sscid = session.screenshare-1; + if (sscid<0){sscid=0;} + } + const sources = await desktopCapturer.getSources({ types: ['screen'] }); + const stream = await window.navigator.mediaDevices.getUserMedia({ + audio: false, + video: { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: sources[sscid].id, + maxFrameRate: 60 + } + } + }); + resolve(stream) + } else { + const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] }); + const selectionElem = document.createElement('div'); + selectionElem.classList = 'desktop-capturer-selection'; + selectionElem.innerHTML = ` +
+
    + ${sources.map(({id, name, thumbnail, display_id, appIcon}) => ` +
  • + +
  • + `).join('')} + +
+
+ `; + + document.body.appendChild(selectionElem); + + document.getElementById('cancelscreenshare').addEventListener('click', async () => { + selectionElem.remove(); + reject(err); + }); + document.querySelectorAll('.desktop-capturer-selection__btn').forEach(button => { + button.addEventListener('click', async () => { + try { + const id = button.getAttribute('data-id'); + const source = sources.find(source => source.id === id); + if(!source) { + throw new Error(`Source with id ${id} does not exist`); + } + + const stream = await window.navigator.mediaDevices.getUserMedia({ + audio: false, + video: { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: source.id, + maxFrameRate: 60 + } + } + }); + resolve(stream); + + selectionElem.remove(); + } catch (err) { + errorlog('Error selecting desktop capture source:', err); + reject(err); + } + }) + }); + } + } catch (err) { + errorlog('Error displaying desktop capture sources:', err); + reject(err); + } + }) + } + ElectronDesktopCapture = true; + } catch(e){ + warnlog("couldn't load electron's screen capture; you might need to decrease security permissions a bit."); + } +} + +async function grabScreen(quality = 0, audio = true, videoOnEnd = false) { + if (!navigator.mediaDevices.getDisplayMedia) { + if (!(session.cleanOutput)) { + setTimeout(function() { + warnUser("Sorry, your browser is not supported. Please use the desktop versions of Firefox or Chrome instead"); + }, 1); + } + return false; + } + + if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { + if (!ElectronDesktopCapture){ + if (!(session.cleanOutput)) { + warnUser("Your Electron app does not support Screen Capture.

Update your Electron Capture app and then enable Elevated Privileges (right click) to access screen-sharing."); + } + return false; + } + } + + if (quality == 0) { // I'm going to go with default quality in most cases, as I assume Dynamic screenshare is going to want low-fps / high def. + var width = { + ideal: 1920 + }; + var height = { + ideal: 1080 + }; + } else if (quality == 1) { + var width = { + ideal: 1280 + }; + var height = { + ideal: 720 + }; + } else if (quality == 2) { + var width = { + ideal: 640 + }; + var height = { + ideal: 360 + }; + } else if (quality >= 3) { // lowest + var width = { + ideal: 320 + }; + var height = { + ideal: 180 + }; + } + + if (session.width) { + width = { + ideal: session.width + }; + } + if (session.height) { + height = { + ideal: session.height + }; + } + + var constraints = { // this part is a bit annoying. Do I use the same settings? I can add custom setting controls here later + audio: { + echoCancellation: false, // For screen sharing, we want it off by default. + autoGainControl: false + , noiseSuppression: false + } + , video: { + width: width + , height: height + } + //,cursor: {exact: "none"} + }; + + try { + let supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); + if (supportedConstraints.cursor) { + constraints.video.cursor = "never"; + } + } catch(e){ + warnlog("navigator.mediaDevices.getSupportedConstraints() not supported"); + } + + if (session.echoCancellation === true) { + constraints.audio.echoCancellation = true; + } + if (session.autoGainControl === true) { + constraints.audio.autoGainControl = true; + } + if (session.noiseSuppression === true) { + constraints.audio.noiseSuppression = true; + } + if (audio == false) { + constraints.audio = false; + } + + if (session.framerate) { + constraints.video.frameRate = session.framerate; + } else if (session.maxframerate !== false){ // not limiting screen share's fps with quality=2 due to gaming centric nature + constraints.video.frameRate = { + ideal: session.maxframerate, + max: session.maxframerate + }; + } + + return navigator.mediaDevices.getDisplayMedia(constraints).then(function(stream) { + log("adding video tracks 2245"); + + var eleName = "videosource"; + try { + if (session.streamSrc) { + session.streamSrc.getVideoTracks().forEach(function(track) { + //track.stop(); + beforeScreenShare = track; + session.streamSrc.removeTrack(track); + log("stopping video track"); + }); + session.videoElement.srcObject.getVideoTracks().forEach(function(track) { + //track.stop(); + session.videoElement.srcObject.removeTrack(track); + log("stopping video track 2"); + }); + } else { + session.streamSrc = new MediaStream(); + session.videoElement.srcObject = session.streamSrc; + log("CREATE NEW STREAM"); + } + } catch (e) { + warnlog(e); + } + //session.videoElement.srcObject = session.streamSrc; + + // Let's not pass the AUDIO thru the webaudio filter. It's screen share after all. + + try { + stream.getVideoTracks()[0].onended = function() { // if screen share stops, + + session.streamSrc.getVideoTracks().forEach(function(track) { + session.streamSrc.removeTrack(track); + track.stop(); + log("stopping video track 3"); + }); + session.videoElement.srcObject.getVideoTracks().forEach(function(track) { + session.videoElement.srcObject.removeTrack(track); + track.stop(); + log("stopping video track 4"); + }); + + session.screenShareState = false; + pokeIframeAPI("screen-share-ended"); + + getById("screensharebutton").classList.add("float"); + getById("screensharebutton").classList.remove("float2"); + + if (videoOnEnd == true) { + //activatedPreview = false; + + if (beforeScreenShare) { + session.streamSrc.addTrack(beforeScreenShare); + session.videoElement.srcObject.addTrack(beforeScreenShare); + if (beforeScreenShare.kind == "video") { + toggleVideoMute(true); + for (UUID in session.pcs) { + try { + if ((session.pcs[UUID].guest == true) && (session.roombitrate === 0)) { + log("room rate restriction detected. No videos will be published to other guests"); + } else if (session.pcs[UUID].allowVideo == true) { // allow + var senders = session.pcs[UUID].getSenders(); // for any connected peer, update the video they have if connected with a video already. + var added = false; + senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? + if (sender.track) { + if (sender.track && sender.track.kind == "video") { + sender.replaceTrack(beforeScreenShare); // replace may not be supported by all browsers. eek. + sender.track.enabled = true; + added = true; + } + } + }); + if (added == false) { + session.pcs[UUID].addTrack(beforeScreenShare, stream); + setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker + } + } + } catch (e) { + errorlog(e); + } + } + session.refreshScale(); + } + beforeScreenShare = null; + } + + toggleSettings(forceShow = true); + //grabVideo(eleName='videosource', selector="select#videoSource3"); + + + } else { + grabScreen(); + } + }; + } catch (e) { + log("No Video selected; screensharing?"); + } + + stream.getTracks().forEach(function(track) { + addScreenDevices(track); + + session.streamSrc.addTrack(track, stream); // Lets not add the audio to this preview; echo can be annoying + session.videoElement.srcObject.addTrack(track, stream); // I should probably add the remote control to his ; #TODO: + + if (track.kind == "video") { + toggleVideoMute(true); + for (UUID in session.pcs) { + try { + if ((session.pcs[UUID].guest == true) && (session.roombitrate === 0)) { + log("room rate restriction detected. No videos will be published to other guests"); + } else if (session.pcs[UUID].allowVideo == true) { // allow + var senders = session.pcs[UUID].getSenders(); // for any connected peer, update the video they have if connected with a video already. + var added = false; + senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? + if (sender.track) { + if (sender.track && sender.track.kind == "video") { + sender.replaceTrack(track); // replace may not be supported by all browsers. eek. + sender.track.enabled = true; + added = true; + } + } + }); + if (added == false) { + session.pcs[UUID].addTrack(track, stream); + setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker + } + } + } catch (e) { + errorlog(e); + } + } + session.refreshScale(); + } else { + toggleMute(true); // I might want to move this outside the loop, but whatever + for (UUID in session.pcs) { + try { + if (session.pcs[UUID].allowAudio == true) { + session.pcs[UUID].addTrack(track, stream); // If screen sharing, we will add audio; not replace. + } + } catch (e) { + errorlog(log); + } + } + screenShareAudioTrack = track; + } + }); + applyMirror(true, eleName); + return true; + }).catch(function(err) { + errorlog(err); + if ((err.name == "NotAllowedError") || (err.name == "PermissionDeniedError")) { + // User Stopped it. + } else { + if (audio == true) { + setTimeout(function() { + grabScreen(quality, false); + }, 1); + } + if (!(session.cleanOutput)) { + setTimeout(function(e) { + errorlog(e); + }, 1, err); // TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio capture is not supported + } + } + return false; + }); +} + +function toggleRoomSettings(){ + + toggle(getById('roomSettings')); + + + if (document.getElementById("modalBackdrop")){ + getById("modalBackdrop").innerHTML = ''; // Delete modal + getById("modalBackdrop").remove(); + } else { + zindex = 25; + getById('roomSettings').style.zIndex = 25; + var modalTemplate = `
`; + document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end + document.getElementById("modalBackdrop").addEventListener("click", toggleRoomSettings); + document.getElementById('trbSettingInput').value = session.totalRoomBitrate; + document.getElementById('trbSettingInputFeedback').innerHTML = session.totalRoomBitrate; + + } + +} + +function changeTRB(ele){ + session.totalRoomBitrate = parseInt(ele.value); + var msg = {}; + msg.directorSettings={}; + msg.directorSettings.totalRoomBitrate=session.totalRoomBitrate; + session.sendMessage(msg); +} + +function sendMediaDevices(UUID){ + enumerateDevices().then(function(deviceInfos){ + var data = {}; + data.UUID = UUID; + data.mediaDevices = deviceInfos; + session.sendMessage(data, data.UUID); + }); +} + +function changeVideoDevice(index, quality=0){ + enumerateDevices().then(gotDevices2).then(function() { + activatedPreview=false; + document.getElementById("videoSource3").selectedIndex = index+""; + grabVideo(quality, "videosource", "#videoSource3"); + }); +} + +function changeAudioDevice(index){ + enumerateDevices().then(gotDevices2).then(function() { + activatedPreview=false; + var audioSelect = document.getElementById("audioSource3").querySelectorAll("input"); + for (var i = 0; i < audioSelect.length; i++) { + audioSelect[i].checked = false; + } + audioSelect[index-1].checked = true; + grabAudio("videosource", "#audioSource3"); + }); +} + +function changeVideoDeviceById(deviceID, UUID){ + enumerateDevices().then(gotDevices2).then(function() { + var opts = document.getElementById("videoSource3").options; + var index = false + for (var opt, j = 0; opt = opts[j]; j++) { + if (opt.value == deviceID) { + index = j; + break; + } + } + if (index!==false){ + window.focus(); + confirmAlt("Allow the director to change your video device to:\n\n"+opts[index].text+" ?").then(res=>{ + if (res){ + document.getElementById("videoSource3").selectedIndex = j; + activatedPreview=false; + grabVideo(0, "videosource", "#videoSource3"); + setTimeout(function(uuid){ + var data = {}; + data.UUID = uuid; + data.videoOptions = listVideoSettingsPrep(); + sendMediaDevices(data.UUID); + session.sendMessage(data, data.UUID); + },1000, UUID); + } + + }); + } + }); +} + +function changeAudioDeviceById(deviceID, UUID){ + window.focus(); + confirmAlt("Allow the director to change your audio mic source").then(res=>{ + if (res){ + enumerateDevices().then(gotDevices2).then(function() { + var audioSelect = document.getElementById("audioSource3").querySelectorAll("input"); + for (var i = 0; i < audioSelect.length; i++) { + if (audioSelect[i].value == deviceID){ + audioSelect[i].checked=true; + } else { + audioSelect[i].checked = false; + } + } + activatedPreview=false; + grabAudio("videosource", "#audioSource3"); + setTimeout(function(uuid){ + var data = {}; + data.UUID = uuid; + data.audioOptions = listAudioSettingsPrep(); + sendMediaDevices(data.UUID); + session.sendMessage(data, data.UUID); + },1000, UUID); + }); + } + }); +} + +function changeAudioOutputDeviceById(deviceID, UUID){ + warnlog(deviceID); + enumerateDevices().then(gotDevices2).then(function() { + if (!document.getElementById("outputSource3")){return;} + var opts = document.getElementById("outputSource3").options; + var index = false + for (var opt, j = 0; opt = opts[j]; j++) { + if (opt.value == deviceID) { + index = j; + break; + } + } + if (index!==false){ + window.focus(); + confirmAlt("Allow the director to change your audio's speaker to:\n\n"+opts[index].text+" ?").then(res=>{ + if (res){ + document.getElementById("outputSource3").selectedIndex = j; + session.sink = document.getElementById("outputSource3").options[document.getElementById("outputSource3").selectedIndex].value; + resetupAudioOut(); + setTimeout(function(uuid){ + var data = {}; + data.UUID = uuid; + data.videoOptions = listVideoSettingsPrep(); + sendMediaDevices(data.UUID); + session.sendMessage(data, data.UUID); + },1000, UUID); + } + }); + } + }); +} + + + +var getUserMediaRequestID = 0; +var grabVideoUserMediaTimeout = null; +var grabVideoTimer = null; + +async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "select#videoSourceSelect") { + if (activatedPreview == true) { + log("activated preview return 2"); + return; + } + activatedPreview = true; + log("Grabbing video: " + quality); + if (grabVideoTimer) { + clearTimeout(grabVideoTimer); + } + log("element:" + eleName); + + var wasDisabled = true; + try { + if (session.streamSrc) { + + if (session.canvasSource){ + session.canvasSource.srcObject.getTracks().forEach(function(trk) { + session.canvasSource.srcObject.removeTrack(trk); + wasDisabled=false; + }); + } + + if (session.videoElement.srcObject) { + session.videoElement.srcObject.getVideoTracks().forEach(function(track) { + session.videoElement.srcObject.removeTrack(track); + session.videoElement.load(); + wasDisabled=false; + }); + } + session.streamSrc.getVideoTracks().forEach(function(track) { + session.streamSrc.removeTrack(track); + track.stop(); + log("track removed"); + wasDisabled=false; + }); + + } else { + //log(session.videoElement.srcObject.getTracks()); + session.streamSrc = new MediaStream(); + session.videoElement.srcObject = session.streamSrc; + log("CREATE NEW STREAM"); + } + } catch (e) { + errorlog(e); + } + + session.videoElement.controls = false; + + log("selector: " + selector); + var videoSelect = document.querySelector(selector); // document.querySelector("videoSource3").value == "ZZZ" + log(videoSelect); + var mirror = false; + + if (!videoSelect || videoSelect.value == "ZZZ") { // if there is no video, or if manually set to audio ready, then do this step. + warnlog("ZZZ SET - so no VIDEO"); + if ((eleName == "previewWebcam") && document.getElementById("previewWebcam")){ + if (session.autostart) { + publishWebcam(); // no need to mirror as there is no video... + return; + } else { + log("4462"); + updateStats(); + var gowebcam = getById("gowebcam"); + if (gowebcam) { + gowebcam.disabled = false; + gowebcam.dataset.ready = "true"; + gowebcam.innerHTML = "START"; + miniTranslate(gowebcam, "start"); + } + } + } else { // If they disabled the video but not in preview mode; but actualy live. We will want to remove the stream from the publishing + // we don't want to do this otherwise, as we are "replacing" the track in other cases. + // this does cause a problem, as previous bitrate settings & resolutions might not be applied if switched back.... must test + for (UUID in session.pcs) { + var senders = session.pcs[UUID].getSenders(); // for any connected peer, update the video they have if connected with a video already. + senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? + if (sender.track && sender.track.kind == "video") { + sender.track.enabled = false; + getById("mutevideobutton").classList.add("advanced"); // hide the mute button, so they can't unmute while no video. + //session.pcs[UUID].removeTrack(sender); // replace may not be supported by all browsers. eek. + errorlog("DELETED SENDER"); + } + }); + + } + var msg = {}; + msg.videoMuted = true; + session.sendMessage(msg); + } + // end + } else { + var sq = 0; + if (session.quality === false) { + sq = session.quality_wb; + } else if (session.quality > 2) { // 1080, 720, and 360p + sq = 2; // hacking my own code. TODO: ugly, so I need to revisit this. + } else { + sq = session.quality; + } + + if (session.director && (quality !== false)){ // URL-based quality won't matter if DIRECTOR; + // quality = quality; + } else if ((quality === false) || (quality < sq)) { + quality = sq; // override the user's setting + } + + + if ((iOS) || (iPad)) { // iOS will not work correctly at 1080p; likely a h264 codec issue. + if (quality == 0) { + quality = 1; + } + } + + var constraints = { + audio: false, + video: getUserMediaVideoParams(quality, iOS) + }; + + log("Quality selected:" + quality); + var _, sUsrAg = navigator.userAgent; + + + if ((iOS) || (iPad)) { + constraints.video.deviceId = { + exact: videoSelect.value + }; // iPhone 6s compatible ? Needs to be exact for iPhone 6s + + } else if (sUsrAg.indexOf("Firefox") > -1) { + constraints.video.deviceId = { + exact: videoSelect.value + }; // Firefox is a dick. Needs it to be exact. + + } else if (videoSelect.options[videoSelect.selectedIndex].text.includes("NDI Video")) { // NDI does not like "EXACT" + constraints.video.deviceId = videoSelect.value; + + } else { + constraints.video.deviceId = { + exact: videoSelect.value + }; // Default. Should work for Logitech, etc. + } + + if (session.width) { + constraints.video.width = { + exact: session.width + }; // manually specified - so must be exact + } + if (session.height) { + constraints.video.height = { + exact: session.height + }; + } + if (session.framerate) { + constraints.video.frameRate = { + exact: session.framerate + }; + } else if (session.maxframerate != false){ + constraints.video.frameRate = { + ideal: session.maxframerate, + max: session.maxframerate + }; + } + if (session.ptz){ + if (constraints.video && constraints.video!==true){ + if (getChromeVersion() && getChromeVersion()>80){ + constraints.video.pan=true; + constraints.video.tilt=true; + constraints.video.zoom=true; + } + } + } + var obscam = false; + log(videoSelect.options[videoSelect.selectedIndex].text); + if (videoSelect.options[videoSelect.selectedIndex].text.startsWith("OBS-Camera")) { // OBS Virtualcam + mirror = true; + obscam = true; + } else if (videoSelect.options[videoSelect.selectedIndex].text.startsWith("OBS Virtual Camera")) { // OBS Virtualcam + mirror = true; + obscam = true; + } else if (videoSelect.options[videoSelect.selectedIndex].text.includes(" back")) { // Android + mirror = true; + } else if (videoSelect.options[videoSelect.selectedIndex].text.includes(" rear")) { // Android + mirror = true; + } else if (videoSelect.options[videoSelect.selectedIndex].text.includes("NDI Video")) { // NDI Virtualcam + mirror = true; + } else if (videoSelect.options[videoSelect.selectedIndex].text.startsWith("Back Camera")) { // iPhone and iOS + mirror = true; + } else { + mirror = false; + } + session.mirrorExclude = mirror; + + log(constraints); + clearTimeout(grabVideoUserMediaTimeout); + getUserMediaRequestID += 1; + grabVideoUserMediaTimeout = setTimeout(function(gumID) { + navigator.mediaDevices.getUserMedia(constraints).then(function(stream) { + + if (getUserMediaRequestID !== gumID) { + errorlog("GET USER MEDIA CALL HAS EXPIRED"); + return; + } + log("adding video tracks 2412"); + stream.getVideoTracks().forEach(function(track) { + if (!session.streamSrc) { + session.streamSrc = new MediaStream(); + } + if (!session.videoElement) { + if (document.getElementById("previewWebcam")) { + session.videoElement = document.getElementById("previewWebcam"); + } else if (document.getElementById("videosource")) { + session.videoElement = document.getElementById("videosource"); + } + + } + + if (session.effects) { + track = applyEffects(track,stream); + } else { + log(session.videoElement); + session.streamSrc.addTrack(track, stream); // add video track to the preview video + session.videoElement.srcObject.addTrack(track, stream); // add video track to the preview video + } + + toggleVideoMute(true); + for (UUID in session.pcs) { + try { + if (((iOS) || (iPad)) && (session.pcs[UUID].guest == true)) { + warnlog("iOS and GUest detected"); + } else if ((session.pcs[UUID].guest == true) && (session.roombitrate === 0)) { + log("room rate restriction detected. No videos will be published to other guests"); + } else if (session.pcs[UUID].allowVideo == true) { // allow + + // for any connected peer, update the video they have if connected with a video already. + var added = false; + session.pcs[UUID].getSenders().forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? + + if (sender.track && sender.track.kind == "video") { + sender.replaceTrack(track); // replace may not be supported by all browsers. eek. + sender.track.enabled = true; + added = true; + } + + }); + if (added == false) { + session.pcs[UUID].addTrack(track, stream); // can't replace, so adding + setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker + } + } + + } catch (e) { + errorlog(e); + } + } + + if (wasDisabled && !session.videoMuted){ + var msg = {}; + msg.videoMuted = session.videoMuted; + session.sendMessage(msg); + } + + session.refreshScale(); + }); + + applyMirror(mirror, eleName); + + if ((eleName == "previewWebcam") && document.getElementById("previewWebcam")){ + if (session.autostart) { + publishWebcam(); + } else { + log("4620"); + if (document.getElementById("gear_webcam")) { + updateStats(obscam); + } + var gowebcam = getById("gowebcam"); + if (gowebcam) { + gowebcam.disabled = false; + gowebcam.dataset.ready = "true"; + gowebcam.innerHTML = "START"; + miniTranslate(gowebcam, "start"); + } + } + } else if (getById("gear_webcam3").style.display === "inline-block") { + updateStats(obscam); + } + + // Once crbug.com/711524 is fixed, we won't need to wait anymore. This is + // currently needed because capabilities can only be retrieved after the + // device starts streaming. This happens after and asynchronously w.r.t. + // getUserMedia() returns. + if (grabVideoTimer) { + clearTimeout(grabVideoTimer); + if ((eleName == "previewWebcam") && document.getElementById("previewWebcam")){ + session.videoElement.controls = true; + } + } + if (getById("popupSelector_constraints_video")) { + getById("popupSelector_constraints_video").innerHTML = ""; + } + if (getById("popupSelector_constraints_audio")) { + getById("popupSelector_constraints_audio").innerHTML = ""; + } + if (getById("popupSelector_constraints_loading")) { + getById("popupSelector_constraints_loading").style.display = ""; + } + + grabVideoTimer = setTimeout(function() { + if (getById("popupSelector_constraints_loading")) { + getById("popupSelector_constraints_loading").style.display = "none"; + } + if ((eleName == "previewWebcam") && document.getElementById("previewWebcam")){ + session.videoElement.controls = true; + } else { + updateConstraintSliders(); + } + + dragElement(session.videoElement); + }, 1000); // focus + + makeImages(true); + + log("DONE - found stream"); + }).catch(function(e) { + activatedPreview = false; + warnlog(e); + if (e.name === "OverconstrainedError") { + warnlog(e.message); + log("Resolution or framerate didn't work"); + } else if (e.name === "NotReadableError") { + if (quality <= 10) { + grabVideo(quality + 1, eleName, selector); + } else { + if (!(session.cleanOutput)) { + if (iOS) { + warnUser("An error occured. Closing existing tabs in Safari may solve this issue."); + } else { + warnUser("Error: Could not start video source.\n\nTypically this means the Camera is already be in use elsewhere. Most webcams can only be accessed by one program at a time.\n\nTry a different camera or perhaps try re-plugging in the device."); + } + } + activatedPreview = true; + if (getById('gowebcam')) { + getById('gowebcam').innerHTML = "Problem with Camera"; + } + + } + return; + } else if (e.name === "NavigatorUserMediaError") { + if (getById('gowebcam')) { + getById('gowebcam').innerHTML = "Problem with Camera"; + } + if (!(session.cleanOutput)) { + warnUser("Unknown error: 'NavigatorUserMediaError'"); + } + return; + } else if (e.name === "timedOut") { + activatedPreview = true; + if (getById('gowebcam')) { + getById('gowebcam').innerHTML = "Problem with Camera"; + } + if (!(session.cleanOutput)) { + warnUser(e.message); + } + return; + } else { + errorlog("An unknown camera error occured"); + } + + if (quality <= 10) { + grabVideo(quality + 1, eleName, selector); + } else { + errorlog("********Camera failed to work"); + activatedPreview = true; + if (getById('gowebcam')) { + getById('gowebcam').innerHTML = "Problem with Camera"; + } + if (!(session.cleanOutput)) { + if (session.width || session.height || session.framerate) { + warnUser(" Camera failed to load.\n\nPlease ensure your camera supports the resolution and framerate that has been manually specified. Perhaps use &quality=0 instead."); + } else { + warnUser(" Camera failed to load.\n\nPlease make sure it is not already in use by another application.\n\nPlease make sure you have accepted the camera permissions."); + } + } + } + }); + }, 100, getUserMediaRequestID); + } +} + + +async function grabAudio(eleName = "previewWebcam", selector = "#audioSource", trackid = null, override = false) { // trackid is the excluded track + if (activatedPreview == true) { + log("activated preview return 2"); + return; + } + activatedPreview = true; + warnlog("GRABBING AUDIO"); + log("TRACK EXCLUDED:" + trackid); + + + try { + if (session.videoElement.srcObject) { + var audioSelect = document.querySelector(selector).querySelectorAll("input"); + var audioExcludeList = []; + for (var i = 0; i < audioSelect.length; i++) { + try { + if ("screen" == audioSelect[i].dataset.type) { // skip already excluded ---------- !!!!!! DOES THIS MAKE SENSE? TODO: CHECK + if (audioSelect[i].checked) { + audioExcludeList.push(audioSelect[i]); + } + } + } catch (e) { + errorlog(e); + } + } + + session.videoElement.srcObject.getAudioTracks().forEach(function(track) { + for (var i = 0; i < audioExcludeList.length; i++) { + try { + if (audioExcludeList[i].label == track.label) { + warnlog("DONE"); + return; + } + } catch (e) {} + } + if (trackid && (track.id == trackid)) { + warnlog("SKIPPED EXCLUDED TRACK?"); + return; + } + session.videoElement.srcObject.removeTrack(track); + track.stop(); + }); + + session.streamSrc.getAudioTracks().forEach(function(track) { + for (var i = 0; i < audioExcludeList.length; i++) { + try { + if (audioExcludeList[i].label == track.label) { + warnlog("EXCLUDING TRACK; PROBABLY SCREEN SHARE"); + return; + } + } catch (e) {} + } + if (trackid && (track.id == trackid)) { + warnlog("SKIPPED EXCLUDED TRACK?"); + return; + } + session.streamSrc.removeTrack(track); + track.stop(); + }); + + + } else { // if no stream exists + session.streamSrc = new MediaStream(); + session.videoElement.srcObject = session.streamSrc; + log("CREATE NEW SOURCE FOR AUDIO"); + } + } catch (e) { + errorlog(e); + } + + var streams = await getAudioOnly(selector, trackid, override); // Get audio streams + warnlog(streams); + try { + for (var i = 0; i < streams.length; i++) { + streams[i].getAudioTracks().forEach(function(track) { + session.streamSrc.addTrack(track, streams[i]); // add video track to the preview video + }); + } + + session.videoElement.srcObject = outboundAudioPipeline(session.streamSrc); + + toggleMute(true); + if (session.videoElement.srcObject.getAudioTracks()) { + + for (UUID in session.pcs) { + if (session.pcs[UUID].allowAudio == true) { + var tracks = session.videoElement.srcObject.getAudioTracks(); + + session.pcs[UUID].getSenders().forEach((sender) => { + var good = false; + if (sender.track && sender.track.id && (sender.track.kind == "audio")) { + tracks.forEach(function(track) { + if (track.id == sender.track.id) { + good = true; + } + }); + } else { // video or something else; ignore it. + return; + } + if (good) { + return; + } + sender.track.enabled = false; + //session.pcs[UUID].removeTrack(sender); // Apparently removeTrack causes renogiation; also kills send/recv. + }); + + if (tracks.length) { + tracks.forEach(function(track) { + var matched = false; + session.pcs[UUID].getSenders().forEach((sender) => { + if (sender.track && sender.track.id && (sender.track.kind !== "video")) { + warnlog(sender.track.id + " " + track.id); + if (sender.track.id == track.id) { + warnlog("MATCHED 1"); + matched = true; + } + } + }); + if (matched) { + return; + } + var added = false; + session.pcs[UUID].getSenders().forEach((sender) => { + if (added) { + return; + } + if (sender.track && (sender.track.enabled == false)) { + sender.replaceTrack(track); + sender.track.enabled = true; + added = true; + warnlog("ADDED 2"); + } + }); + if (added) { + return; + } + var sender = session.pcs[UUID].addTrack(track, session.videoElement.srcObject); + }); + } else { + session.pcs[UUID].getSenders().forEach((sender) => { + if (sender.track && sender.track.kind == "audio") { + sender.track.enabled = false; // (trying this instead) + //session.pcs[UUID].removeTrack(sender); // Apparently removeTrack causes renogiation; also kills send/recv. + } + }); + } + + } + } + } + } catch (e) { + errorlog(e); + } + var gowebcam = getById("gowebcam"); + if (gowebcam) { + gowebcam.disabled = false; + gowebcam.dataset.ready = "true"; + gowebcam.innerHTML = "START"; + miniTranslate(gowebcam, "start"); + } +} + + +// WEBCAM +session.publishDirector = async function(clean, vdevice=false, adevice=true){ // stream is used to generated an SDP + log("DIRECTOR STREAM SETUP"); + + if (getById("press2talk").dataset.enabled){log("already enabled");return;} + getById("press2talk").dataset.enabled = 1; + + if (session.streamSrc){ + //if (!session.streamSrc){ + // session.streamSrc = new MediaStream(); + //} + if (document.getElementById("videosource")){ + var v = document.getElementById("videosource"); + v.muted = true; + v.autoplay = true; + v.controls = false; + v.setAttribute("playsinline",""); + session.videoElement = v; + } else if (session.videoElement){ + var v = session.videoElement; + v.muted = true; + v.autoplay = true; + v.controls = false; + v.setAttribute("playsinline",""); + getById("miniPerformer").appendChild(v); + } else { + var v = document.createElement("video"); + session.videoElement = v; + v.muted = true; + v.autoplay = true; + v.controls = false; + v.setAttribute("playsinline",""); + getById("miniPerformer").appendChild(v); + } + + if (session.streamID){ + session.videoElement.dataset.sid = session.streamID; + } + + v.title = "This is the mini-preview of the Director's audio and video output. The director cannot be muted by guest and does not show up in scenes."; + getById("press2talk").innerHTML = ""; + getById("press2talk").outerHTML = ""; + + session.muted = false; + toggleMute(true); + getById("screensharebutton").classList.remove("advanced"); + getById("hangupbutton2").classList.remove("advanced"); + + + v.muted = true; + v.autoplay = true; + v.controls = false; + v.setAttribute("playsinline",""); + v.srcObject = session.streamSrc; // blank, no worries. + + if (session.screenShareState) { + log("can't refresh a screenshare"); + getById("screensharebutton").classList.add("float2"); + getById("screensharebutton").classList.remove("float"); + session.screenShareState = false; + } + + + activatedPreview = false; + await grabAudio("videosource", "#audioSource3"); + + + enumerateDevices().then(gotDevices2).then(function() { + activatedPreview = false; + grabVideo(session.quality, "videosource", "select#videoSource3"); + }); + + toggleSettings(true); + + var msg = {}; + msg.videoMuted = session.videoMuted; + session.sendMessage(msg); + + return; + } + + + var title = "Director"; + var v = document.createElement("video"); + session.videoElement = v; + if (session.streamID){ + session.videoElement.dataset.sid = session.streamID; + } + v.id = "videosource"; // could be set to UUID in the future + v.muted = true; + v.autoplay = true; + v.controls = false; + v.setAttribute("playsinline",""); + + session.streamSrc = new MediaStream(); + v.srcObject = session.streamSrc; // blank, no worries. we dont need outbound. + + //createDirectorCam(v,clean); + + var quality = 1; + var framerate = 30; + + + if (session.quality!==false){ + quality = parseInt(session.quality) || 0; + if (quality>2){quality=2;} else if (quality<0){quality = 0;} + } + + if (session.showDirector){ + if (quality<2){ + framerate = 60; + } + } + + if (session.framerate!==false){ + framerate = parseInt(session.framerate) || 30; + } + + if (session.maxframerate){ + if (framerate > session.maxframerate){ + framerate = session.maxframerate || framerate; + } + } + + if (vdevice){ + if (vdevice===true){ + vdevice = {}; + } + if (quality===0){ + vdevice.width = {ideal:1920}; //{deviceId: {exact: deviceInfo.deviceId}}; + vdevice.height = {ideal:1080}; + vdevice.framerate = {ideal:framerate}; + } else if (quality===1){ + vdevice.width = {ideal:1280}; //{deviceId: {exact: deviceInfo.deviceId}}; + vdevice.height = {ideal:720}; + vdevice.framerate = {ideal:framerate}; + } else if (quality===2){ + vdevice.width = {ideal:640}; //{deviceId: {exact: deviceInfo.deviceId}}; + vdevice.height = {ideal:360}; + vdevice.framerate = {ideal:framerate}; + } + if (session.framerate){ + vdevice.framerate.ideal = parseInt(session.framerate) || 30; + } + if (session.maxframerate){ + vdevice.framerate.max = parseInt(session.maxframerate) || 60; + } + if (session.width){ + vdevice.width = {exact: session.width}; //{deviceId: {exact: deviceInfo.deviceId}}; + } + if (session.height){ + vdevice.height = {exact: session.height}; //{deviceId: {exact: deviceInfo.deviceId}}; + } + } + + var constraints = {audio: adevice, video: vdevice}; + + if (session.audioInputChannels){ + if (constraints.audio === true){ + constraints.audio = {}; + constraints.audio.channelCount = session.audioInputChannels; + } else if (constraints.audio){ + constraints.audio.channelCount = session.audioInputChannels; + } + } + + //if (session.echoCancellation===false){ + if (constraints.audio === true){ + constraints.audio = {}; + } + if (constraints.audio){ + if (session.echoCancellation===false || session.autoGainControl===false || session.noiseSuppression===false){ + if (session.echoCancellation===false){ + constraints.audio.echoCancellation=false; + } else { + constraints.audio.echoCancellation=true; + } + if (session.autoGainControl===false){ + constraints.audio.autoGainControl=false; + } else { + constraints.audio.autoGainControl=true; + } + if (session.noiseSuppression===false){ + constraints.audio.noiseSuppression=false; + } else { + constraints.audio.noiseSuppression=true; + } + } + } + + + try { + getById("webcamquality3").elements.namedItem("resolution").value = quality; + getById("gear_webcam3").style.display = "inline-block"; + getById("webcamquality3").onchange = function(event) { + if (parseInt(getById("webcamquality3").elements.namedItem("resolution").value) == 2) { + if (session.maxframerate===false){ + session.maxframerate = 30; + session.maxframerate_q2 = true; + } + } else if (session.maxframerate_q2){ + session.maxframerate = false; + session.maxframerate_q2 = false; + } + activatedPreview = false; + session.quality_wb = parseInt(getById("webcamquality3").elements.namedItem("resolution").value); + + grabVideo(session.quality_wb, "videosource", "select#videoSource3"); + }; + } catch (e) {} + + log("constraint"); + navigator.mediaDevices.getUserMedia(constraints).then(function(stream){ // very simple. + session.streamSrc = stream; + v.srcObject = outboundAudioPipeline(session.streamSrc); // not blank, so now we worry + + for (UUID in session.pcs){ + session.initialPublish(UUID); // Start publishing! + } + enumerateDevices().then(gotDevices2).then(function(){}); + createDirectorCam(v, clean); + }); + + + changeAudioOutputDevice(v); + + v.onpause = (event) => { // prevent things from pausing; human or other + if (!((event.ctrlKey) || (event.metaKey) )){ + log("Video paused; auto playing"); + event.currentTarget.play().then(_ => { + log("playing"); + }).catch(warnlog); + } + }; + + v.addEventListener('click', function(e) { // show stats of video if double clicked + log("click"); + try { + if ((e.ctrlKey)||(e.metaKey)){ + e.preventDefault(); + + //////////////////////// + + var [menu, innerMenu] = statsMenuCreator(); + + ////////////////////////////////// + + menu.interval = setInterval(printMyStats,3000, innerMenu); + printMyStats(innerMenu); + e.stopPropagation(); + + return false; + } + } catch(e){errorlog(e);} + }); + + if (session.directorEnabledPPT){ + return; + } + + if (session.videoMutedFlag){ + session.videoMuted = true; + toggleVideoMute(true); + } + + session.title=title; + session.directorEnabledPPT = true; + + + if (session.seeding){ + return; + } + + session.seeding=true; + session.seedStream(); + +}; + +function statsMenuCreator(){ + if (getById("menuStatsBox")){ + clearInterval(getById("menuStatsBox").interval); + getById("menuStatsBox").remove(); + } + + var menu = document.createElement("div"); + menu.id = "menuStatsBox"; + menu.className = "debugStats remotestats"; + getById('main').appendChild(menu); + + menu.style.left = parseInt(Math.random()*10)+15+"px" + menu.style.top = parseInt(Math.random()*10)+"px" + + menu.innerHTML="

Statistics

"; + var menuCloseBtn = document.createElement("button"); + menuCloseBtn.className="close"; + menuCloseBtn.innerHTML="ร—"; + menu.appendChild(menuCloseBtn); + + var innerMenu = document.createElement("div"); + menu.appendChild(innerMenu); + + menuCloseBtn.addEventListener('click', function(eve) { + clearInterval(menu.interval); + eve.currentTarget.parentNode.remove(); + }); + return [menu, innerMenu]; +} + + +// WEBCAM +session.publishStream = function(v, title="Stream Sharing Session"){ // stream is used to generated an SDP + log("STREAM SETUP"); + + try { + //session.streamSrc = v.srcObject; // this shoulnd't be needed + v.parentNode.removeChild(v); // remove the preview video element after we switch streams to avoid bug on iOS beta 14 + v.className = ""; + } catch (e){ + errorlog(e); + return; + } + + if (session.transcript){ + setTimeout(function(){setupClosedCaptions();},1000); + } + + toggleMute(true); // apply mute state + + if (!session.streamSrc){ + log("no stream selected"); + session.streamSrc = new MediaStream(); // this is just for backup. + } + + session.streamSrc.oninactive = function streamoninactive() { + errorlog('Stream inactive'); + if (session.videoElement.recording){ + session.videoElement.recorder.stop(); + } + }; + + if (session.streamSrc.getVideoTracks().length==0){ + warnlog("NO VIDEO TRACK INCLUDED"); + } + + if (session.streamSrc.getAudioTracks().length==0){ + warnlog("NO AUDIO TRACK INCLUDED"); + } + + + var container = document.createElement("div"); + container.id = "container"; + + if (session.cleanOutput){ + container.style.height = "100%"; + v.style.maxWidth = "100%"; + v.style.boxShadow = "none"; + } + + container.className = "vidcon"; + getById("gridlayout").appendChild(container); + + v.className = "tile"; + + v.muted = true; + v.autoplay = true; + v.controls = false; + v.setAttribute("playsinline",""); + v.id = "videosource"; // could be set to UUID in the future + v.oncanplay = null; + container.appendChild(v); + + if (session.nopreview){ + v.style.display="none"; + container.style.display="none"; + } + + changeAudioOutputDevice(v); + + if (session.mirrored && session.flipped){ + v.style.transform = "scaleX(1) scaleY(-1) "; + } else if (session.mirrored){ + v.style.transform = "scaleX(1) "; + } else if (session.flipped){ + v.style.transform = "scaleY(-1) scaleX(-1)"; + } else { + v.style.transform = "scaleX(-1) "; + } + + var bigPlayButton = document.getElementById("bigPlayButton"); + if (bigPlayButton){ + bigPlayButton.parentNode.removeChild(bigPlayButton); + } + + session.videoElement = v; + + if (session.streamID){ + session.videoElement.dataset.sid = session.streamID; + } + + if (session.director){ + // audio is not mucked with + } else if (session.scene!==false){ + setTimeout(function(){updateMixer();},1); + } else if (session.roomid!==false){ + if (session.roomid===""){ + if (!(session.view) || (session.view==="")){ + + + if (session.fullscreen){ + session.windowed = false; + } else { + v.className = "myVideo"; + session.windowed = true; + } + getById("mutespeakerbutton").classList.add("advanced"); + + applyMirror(session.mirrorExclude, 'videosource'); + + container.style.width="100%"; + //container.style.height="100%"; + + container.style.alignItems = "center"; + container.backgroundColor = "#666"; + + setTimeout(function (){dragElement(v);},1000); + play(); + } else { + session.windowed = false; + applyMirror(session.mirrorExclude, 'videosource'); + play(); + setTimeout(function(){updateMixer();},1); + } + } else { + //session.cbr=0; // we're just going to override it + if (session.stereo==5){ // not a scene or director, so we will assume its a guest. changing to stereo=3 + session.stereo=3; + } + session.windowed = false; + applyMirror(session.mirrorExclude, 'videosource'); + + setTimeout(function(){updateMixer();},1); + } + } else { + + + if (session.fullscreen){ + session.windowed = false; + } else { + v.className = "myVideo"; + session.windowed = true; + } + getById("mutespeakerbutton").classList.add("advanced"); + + applyMirror(session.mirrorExclude, 'videosource'); + + container.style.width="100%"; + //container.style.height="100%"; + //container.style.display = "flex"; + + container.style.alignItems = "center"; + container.backgroundColor = "#666"; + + setTimeout(function (){dragElement(v);},1000); + + } + + v.onpause = (event) => { // prevent things from pausing; human or other + if (!((event.ctrlKey) || (event.metaKey) )){ + log("Video paused; auto playing"); + event.currentTarget.play().then(_ => { + log("playing"); + }).catch(warnlog); + } + }; + + v.addEventListener('click', function(e) { + log("click"); + try { + if ((e.ctrlKey)||(e.metaKey)){ + e.preventDefault(); + + var [menu, innerMenu] = statsMenuCreator(); + + menu.interval = setInterval(printMyStats,3000, innerMenu); + + printMyStats(innerMenu); + e.stopPropagation(); + return false; + } + } catch(e){errorlog(e);} + }); + + v.touchTimeOut = null; + v.touchLastTap = 0; + v.touchCount = 0; + v.addEventListener('touchend', function(event) { + log("touched"); + + document.ontouchup = null; + document.onmouseup = null; + document.onmousemove = null; + document.ontouchmove = null; + + var currentTime = new Date().getTime(); + var tapLength = currentTime - v.touchLastTap; + clearTimeout(v.touchTimeOut); + if (tapLength < 500 && tapLength > 0) { + /// + log("double touched"); + v.touchCount+=1; + event.preventDefault(); + if (v.touchCount<5){ + v.touchLastTap = currentTime; + return false; + } + v.touchLastTap = 0; + v.touchCount=0; + + var [menu, innerMenu] = statsMenuCreator(); + + menu.interval = setInterval(printMyStats,3000, innerMenu); + + printMyStats(innerMenu); + event.stopPropagation(); + return false; + ////// + } else { + v.touchCount=1; + v.touchLastTap = currentTime; + + v.touchTimeOut = setTimeout(function(vv) { + clearTimeout(vv.touchTimeOut); + vv.touchLastTap = 0; + vv.touchCount=0; + }, 5000, v); + + } + + }); + + try{ + var m = getById("mainmenu"); + m.remove(); + } catch (e){} + + var added = ""; + if (session.defaultPassword===false){ + if (session.password){ + added="&pw="+session.password; + } + } + + var pie = ""; + if (session.pie){ + if (session.pie!==true){ + pie = "&pie="+session.pie; + } + } + + getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+added+pie; + getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+added+pie; + getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px'; + pokeIframeAPI('started-camera'); + + + + if (session.videoMutedFlag){ + session.videoMuted = true; + toggleVideoMute(true); + } + + clearInterval(session.updateLocalStatsInterval); + session.updateLocalStatsInterval = setInterval(function(){updateLocalStats();},3000); + + session.title=title; + session.seeding=true; + session.seedStream(); + + if (iOS || iPad) { + setTimeout(function(){ + try{ + enumerateDevices().then(gotDevices2); + } catch(e){} + },100); + } +}; + + +session.publishScreen = function(constraints, title="Screen Sharing Session", audioList=[], audio=true){ // webcam stream is used to generated an SDP + log("SCREEN SHARE SETUP"); + if (!navigator.mediaDevices.getDisplayMedia){ + setTimeout(function(){warnUser("Sorry, your browser is not supported. Please use the desktop versions of Firefox or Chrome instead");},1); + return false; + } + if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { + if (!ElectronDesktopCapture){ + if (!(session.cleanOutput && session.cleanish==false)){ + warnUser("Your Electron app does not support Screen Capture.

Update your Electron Capture app and then enable Elevated Privileges to access screen-sharing."); + } + return false; + } + } + + var streams = []; + for (var i=1; i{ + streams.push(stream); + }).catch(errorlog); + } + } + + if (session.audioDevice === 0 ){ + constraints.audio = false; + } + + log(constraints); + return navigator.mediaDevices.getDisplayMedia(constraints).then(function (stream){ + /// RETURN stream for preview? rather than jumping right in. + session.screenShareState=true; + try { + stream.getVideoTracks()[0].onended = function () { + session.screenShareState=false; + pokeIframeAPI("screen-share-ended"); + grabScreen(); + }; + } catch(e){log("No Video selected; screensharing?");} + + // OR, jump right in, and let user change from there + if (session.roomid!==false){ + if ((session.roomid==="") && ((!(session.view)) || (session.view===""))){ + + } else { + getById("head3").className = 'advanced'; + + log("ROOMID EANBLED"); + log("Update Mixer Event on REsize SET"); + window.addEventListener("resize", updateMixer); + window.addEventListener("orientationchange", updateMixer); + joinRoom(session.roomid); + } + + } else { + getById("head3").className = ''; + getById("logoname").style.display = 'none'; + } + + if (urlParams.has('permaid')){ + updateURL("permaid="+session.streamID); + } else { + updateURL("push="+session.streamID); + } + + log("adding tracks"); + for (var i=0; i{ + stream.addTrack(track); + }); + } + streams = null; + if (session.audioDevice !== 0){ + if (stream.getAudioTracks().length==0){ + if (!(session.cleanOutput)){ + if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1){ + // Electron has no audio. + } else { + setTimeout(function(){warnUser("No Audio Source was detected.\n\nIf you were wanting to capture an Application's Audio, please see:\nhttps://docs.vdo.ninja/help/guides-and-how-tos#audio for some guides.");},300); + } + } + } + } + + + + try { + session.streamSrc = stream; + } catch (e){errorlog(e);} + + toggleMute(true); + + var v = document.createElement("video"); + + session.videoElement = v; + + + if (session.streamID){ + session.videoElement.dataset.sid = session.streamID; + } + + + var container = document.createElement("div"); + container.id = "container"; + + if (session.cleanOutput){ + container.style.height = "100%"; + v.style.maxWidth = "100%"; + v.style.boxShadow = "none"; + } + + container.className = "vidcon"; + getById("gridlayout").appendChild(container); + + if (session.nopreview){ + v.style.display="none"; + container.style.display="none"; + } + + container.appendChild(v); + + + v.className = "tile"; + + changeAudioOutputDevice(v); + + if (session.director){ + } else if (session.scene!==false){ + setTimeout(function(){updateMixer();},1); + } else if (session.roomid!==false){ + if (session.roomid===""){ + if (!(session.view) || (session.view==="")){ + + getById("mutespeakerbutton").classList.add("advanced"); + + if (session.fullscreen){ + session.windowed = false; + if (session.mirrored && session.flipped){ + v.style.transform = " scaleX(-1) scaleY(-1)"; + v.classList.add("mirrorControl"); + } else if (session.mirrored){ + v.style.transform = "scaleX(-1)"; + v.classList.add("mirrorControl"); + } else if (session.flipped){ + v.style.transform = "scaleY(-1)"; + v.classList.remove("mirrorControl"); + } else { + v.style.transform = ""; + v.classList.remove("mirrorControl"); + } + } else { + v.className = "myVideo"; + session.windowed = true; + if (session.mirrored && session.flipped){ + v.style.transform = " scaleX(-1) scaleY(-1) translate(0, 50%)"; + v.classList.add("mirrorControl"); + } else if (session.mirrored){ + v.style.transform = "scaleX(-1) translate(0, -50%)"; + v.classList.add("mirrorControl"); + } else if (session.flipped){ + v.style.transform = "scaleY(-1) translate(0, 50%)"; + v.classList.remove("mirrorControl"); + } else { + v.style.transform = " translate(0, -50%)"; + v.classList.remove("mirrorControl"); + } + } + + container.style.width="100%"; + //container.style.height="100%"; + container.style.alignItems = "center"; + container.backgroundColor = "#666"; + + setTimeout(function (){dragElement(v);},1000); + play(); + } else { + play(); + setTimeout(function(){updateMixer();},1); + } + } else { + setTimeout(function(){updateMixer();},1); + } + } else { + + getById("mutespeakerbutton").classList.add("advanced"); + if (session.fullscreen){ + session.windowed = false; + if (session.mirrored && session.flipped){ + v.style.transform = " scaleX(-1) scaleY(-1)"; + v.classList.add("mirrorControl"); + } else if (session.mirrored){ + v.style.transform = "scaleX(-1)"; + v.classList.add("mirrorControl"); + } else if (session.flipped){ + v.style.transform = "scaleY(-1)"; + v.classList.remove("mirrorControl"); + } else { + v.style.transform = ""; + v.classList.remove("mirrorControl"); + } + } else { + v.className = "myVideo"; + session.windowed = true; + if (session.mirrored && session.flipped){ + v.style.transform = " scaleX(-1) scaleY(-1) translate(0, 50%)"; + v.classList.add("mirrorControl"); + } else if (session.mirrored){ + v.style.transform = "scaleX(-1) translate(0, -50%)"; + v.classList.add("mirrorControl"); + } else if (session.flipped){ + v.style.transform = "scaleY(-1) translate(0, 50%)"; + v.classList.remove("mirrorControl"); + } else { + v.style.transform = " translate(0, -50%)"; + v.classList.remove("mirrorControl"); + } + } + + + + + container.style.width="100%"; + //container.style.height="100%"; + container.style.alignItems = "center"; + container.backgroundColor = "#666"; + } + + v.autoplay = true; + v.controls = false; + v.setAttribute("playsinline",""); + v.muted = true; + v.id = "videosource"; + + //if (!v.srcObject || v.srcObject.id !== stream.id) { + // v.srcObject = stream; + v.srcObject = outboundAudioPipeline(session.streamSrc); + //} + + v.onpause = (event) => { // prevent things from pausing; human or other + if (!((event.ctrlKey) || (event.metaKey) )){ + log("Video paused; auto playing"); + event.currentTarget.play().then(_ => { + log("playing"); + }).catch(warnlog); + } + }; + + v.addEventListener('click', function(e) { // show stats of video if double clicked + log("click"); + try { + if ((e.ctrlKey)||(e.metaKey)){ + e.preventDefault(); + + var [menu, innerMenu] = statsMenuCreator(); + + menu.interval = setInterval(printMyStats,3000, innerMenu); + + printMyStats(innerMenu); + e.stopPropagation(); + return false; + } + } catch(e){errorlog(e);} + }); + + try{ + var m = getById("mainmenu"); + m.remove(); + } catch (e){} + + var pie = ""; + if (session.pie){ + if (session.pie!==true){ + pie = "&pie="+session.pie; + } + } + + getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+pie; + getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+pie; + getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px'; + + + if (session.videoMutedFlag){ + session.videoMuted = true; + toggleVideoMute(true); + } + + clearInterval(session.updateLocalStatsInterval); + session.updateLocalStatsInterval = setInterval(function(){updateLocalStats();},3000); + + session.title=title; + session.seeding=true; + session.seedStream(); + + pokeIframeAPI('started-screenshare'); + + return true; + }).catch(function(err){ + warnlog(err); /* handle the error */ + if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { + if (!ElectronDesktopCapture){ + if (!(session.cleanOutput)) { + warnUser("Your Electron app does not support Screen Capture.

Update your Electron Capture app and then enable Elevated Privileges to access screen-sharing."); + } + return false; + } + } + if ((err.name == "NotAllowedError") || (err.name == "PermissionDeniedError")){ + // User Stopped it. + session.screenShareState=false; + pokeIframeAPI("screen-share-ended"); + return false; + } else { + if (audio==true){ + constraints.audio=false; + if (!(session.cleanOutput)){ + setTimeout(function(){warnUser(err);},1); // TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio capture is not supported + } + return session.publishScreen(constraints, title, audioList, false); + } else { + if (!(session.cleanOutput)){ + setTimeout(function(){warnUser(err);},1); // TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio capture is not supported + } + return false; + } + + } + }); + +}; + +session.publishFile = function(ele, event, title="Video File Sharing Session"){ // webcam stream is used to generated an SDP + log("FILE SHARE SETUP"); + + if (session.transcript){ + setTimeout(function(){setupClosedCaptions();},1000); + } + + var files = []; + for (var i = 0; i < ele.files.length; i++){ // changing from a FileList to an Array. Arrays are easier to modify later on + files.push(ele.files[i]); + } + log(files); + //var type = file.type; + + var fileURL = URL.createObjectURL(files[0]); + var container = document.createElement("div"); + container.id = "container"; + + + + container.className = "vidcon"; + var v = document.createElement("video"); + + if (session.cleanOutput){ + container.style.height = "100%"; + v.style.maxWidth = "100%"; + v.style.boxShadow = "none"; + } + + if (session.streamID){ + v.dataset.sid = session.streamID; + } + + getById("gridlayout").appendChild(container); + + if (session.roomid!==false){ + if ((session.roomid==="") && ((!(session.view)) || (session.view===""))){ + + } else { + log("ROOMID EANBLED"); + log("Update Mixer Event on REsize SET"); + //window.addEventListener("resize", updateMixer);// TODO FIX + //window.addEventListener("orientationchange", updateMixer);// TODO FIX + getById("head3").className = 'advanced'; + joinRoom(session.roomid); + } + + } else { + getById("head3").className = ''; + getById("logoname").style.display = 'none'; + } + getById("head1").className = 'advanced'; + + if (urlParams.has('permaid')){ + updateURL("permaid="+session.streamID); + } else { + updateURL("push="+session.streamID); + } + + getById("head1").className = 'advanced'; + getById("head2").className = 'advanced'; + + if (!(session.cleanOutput)){ + getById("chatbutton").className="float"; + getById("hangupbutton").className="float"; + getById("controlButtons").style.display="flex"; + getById("helpbutton").style.display = "inherit"; + getById("reportbutton").style.display = ""; + } else { + getById("controlButtons").style.display="none"; + } + + var bigPlayButton = document.getElementById("bigPlayButton"); + if (bigPlayButton){ + bigPlayButton.parentNode.removeChild(bigPlayButton); + } + + v.autoplay = false; + v.controls = true; + v.muted = false; + + if (files.length ==1){ // we don't want to do the complex logic if there is just one video + v.loop = true; + } else { + v.loop = false; // triggers the complex track/rtc logic. + } + + v.setAttribute("playsinline",""); + v.src = fileURL; + + try { + session.streamSrc=v.captureStream(); + } catch (e){ + errorlog(e); + return; + } + + v.className = "tile clean fileshare"; + v.id = "videosource"; // could be set to UUID in the future + v.playlist = files; + + v.addEventListener('ended',myHandler,false); // only fires if the video doesn't loop. + + + function myHandler(e) { + log("MY HANDLER TRIGGERED"); + var vid = getById("videosource"); + log(vid.playlist); + vid.playlist.unshift(vid.playlist.pop()); + vid.src = URL.createObjectURL(vid.playlist[0]); + vid.onloadeddata = function(){ + session.streamSrc=vid.captureStream(); + + session.streamSrc.getTracks().forEach(function(track){ + for (UUID in session.pcs){ + var senders = session.pcs[UUID].getSenders(); + log(track); + if (track.kind == "video"){ + try { + if ((session.pcs[UUID].guest==true) && (session.roombitrate===0)) { + log("room rate restriction detected. No videos will be published to other guests"); + } else if (session.pcs[UUID].allowVideo==true){ // allow + // for any connected peer, update the video they have if connected with a video already. + var added=false; + senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? + + if (sender.track && sender.track.kind == "video"){ + sender.replaceTrack(track); // replace may not be supported by all browsers. eek. + added=true; + } + + }); + if (added==false){ + session.pcs[UUID].addTrack(track, session.streamSrc); + setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker + } + } + } catch (e){ + errorlog(e); + } + + } else { + session.pcs[UUID].addTrack(track, session.streamSrc); + } + } + }); + session.refreshScale(); + } + vid.load(); + log(session.streamSrc); + vid.play().then(_ => { + log("playing"); + }).catch(warnlog); + + } + + // no preview doesn't work, so just stop it from doing its thing. + + + container.appendChild(v); + changeAudioOutputDevice(v); + + if (session.mirrored && session.flipped){ + v.style.transform = "scaleX(1) scaleY(-1) "; + } else if (session.mirrored){ + v.style.transform = "scaleX(1) "; + } else if (session.flipped){ + v.style.transform = "scaleY(-1) scaleX(-1)"; + } else { + v.style.transform = "scaleX(-1) "; + } + + session.mirrorExclude=true; + + if (session.director){ + } else if (session.scene!==false){ + //setTimeout(function(){updateMixer();},1);// TODO FIX + } else if (session.roomid!==false){ + if (session.roomid===""){ + if (!(session.view) || (session.view==="")){ + + if (session.fullscreen){ + session.windowed = false; + } else { + v.className = "myVideo clean fileshare"; + session.windowed = true; + } + getById("mutespeakerbutton").classList.add("advanced"); + + applyMirror(session.mirrorExclude, 'videosource'); + + container.style.width="100%"; + //container.style.height="100%"; + + container.style.alignItems = "center"; + container.backgroundColor = "#666"; + + play(); + } else { + session.windowed = false; + applyMirror(session.mirrorExclude, 'videosource'); + play(); + //setTimeout(function(){updateMixer();},1);// TODO FIX + } + } else { + //session.cbr=0; // we're just going to override it + if (session.stereo==5){ + session.stereo=3; + } + session.windowed = false; + applyMirror(session.mirrorExclude, 'videosource'); + //setTimeout(function(){updateMixer();},1); // TODO FIX + } + } else { + + + if (session.fullscreen){ + session.windowed = false; + } else { + v.className = "myVideo clean fileshare"; + session.windowed = true; + } + getById("mutespeakerbutton").classList.add("advanced"); + + applyMirror(session.mirrorExclude, 'videosource'); + + container.style.width="100%"; + //container.style.height="100%"; + //container.style.display = "flex"; + + container.style.alignItems = "center"; + container.backgroundColor = "#666"; + + } + + + v.addEventListener('click', function(e){ + log("click"); + try { + if ((e.ctrlKey)||(e.metaKey)){ + e.preventDefault(); + + var [menu, innerMenu] = statsMenuCreator(); + + menu.interval = setInterval(printMyStats,3000, innerMenu); + + printMyStats(innerMenu); + e.stopPropagation(); + return false; + } + } catch(e){errorlog(e);} + }); + + + v.touchTimeOut = null; + v.touchLastTap = 0; + v.touchCount = 0; + v.addEventListener('touchend', function(event) { + log("touched"); + + document.ontouchup = null; + document.onmouseup = null; + document.onmousemove = null; + document.ontouchmove = null; + + var currentTime = new Date().getTime(); + var tapLength = currentTime - v.touchLastTap; + clearTimeout(v.touchTimeOut); + if (tapLength < 500 && tapLength > 0) { + /// + log("double touched"); + v.touchCount+=1; + event.preventDefault(); + if (v.touchCount<5){ + v.touchLastTap = currentTime; + return false; + } + v.touchLastTap = 0; + v.touchCount=0; + + var [menu, innerMenu] = statsMenuCreator(); + + menu.interval = setInterval(printMyStats,3000, innerMenu); + + printMyStats(innerMenu); + event.stopPropagation(); + return false; + ////// + } else { + v.touchCount=1; + v.touchTimeOut = setTimeout(function(vv) { + clearTimeout(vv.touchTimeOut); + vv.touchLastTap = 0; + vv.touchCount=0; + }, 5000, v); + v.touchLastTap = currentTime; + } + + }); + + try{ + var m = getById("mainmenu"); + m.remove(); + } catch (e){} + + var pie = ""; + if (session.pie){ + if (session.pie!==true){ + pie = "&pie="+session.pie; + } + } + + getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+pie; + getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+pie; + getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px'; + pokeIframeAPI('started-fileshare'); + + clearInterval(session.updateLocalStatsInterval); + session.updateLocalStatsInterval = setInterval(function(){updateLocalStats();},3000); + + session.title=title; + session.seeding=true; + + if (session.videoMutedFlag){ + session.videoMuted = true; + toggleVideoMute(true); + } + + session.seedStream(); +}; + + +function tryAgain(event) { // audio or video agnostic track reconnect ------------not actually in use,. maybe out of date + log("TRY AGAIN TRIGGERED"); + warnlog(event); +} + + +function enterPressedClick(event, ele) { + if (event.keyCode === 13) { + event.preventDefault(); + ele.click(); + } +} + +function enterPressed(event, callback) { + // Number 13 is the "Enter" key on the keyboard + if (event.keyCode === 13) { + event.preventDefault(); + callback(); + } +} + + +function dragElement(elmnt) { + var millis = Date.now(); + try { + var input = getById("zoomSlider"); + var stream = elmnt.srcObject; + try { + var track0 = stream.getVideoTracks(); + } catch (e) { + return; + } + + if (!(track0.length)) { + return; + } + + track0 = track0[0]; + if (track0.getCapabilities) { + var capabilities = track0.getCapabilities(); + var settings = track0.getSettings(); + + // Check whether zoom is supported or not. + if (!('zoom' in capabilities)) { + log('Zoom is not supported by ' + track0.label); + return; + } + + // Map zoom to a slider element. + input.min = capabilities.zoom.min; + input.max = capabilities.zoom.max; + input.step = capabilities.zoom.step; + input.value = settings.zoom; + } + } catch (e) { + errorlog(e); + return; + } + + log("drag on"); + elmnt.onmousedown = dragMouseDown; + elmnt.onclick = onvideoclick; + elmnt.ontouchstart = dragMouseDown; + + var pos0 = 1; + + function onvideoclick(e) { + log(e); + log("onvideoclick"); + e = e || window.event; + e.preventDefault(); + return false; + } + + function dragMouseDown(e) { + log(e); + log("dragMouseDown"); + + //closeDragElement(null); + + //elmnt.controls = false; + e = e || window.event; + e.preventDefault(); + + pos0 = input.value; + if (e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel') { + var touch = e.touches[0] || e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + pos3 = touch.clientX; + pos4 = touch.clientY; + } else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover' || e.type == 'mouseout' || e.type == 'mouseenter' || e.type == 'mouseleave') { + pos3 = e.clientX; + pos4 = e.clientY; + } + document.ontouchup = closeDragElement; + document.onmouseup = closeDragElement; + + document.ontouchmove = elementDrag; + document.onmousemove = elementDrag; + } + + function elementDrag(e) { + e = e || window.event; + e.preventDefault(); + // calculate the new cursor position: + + if (Date.now() - millis < 50) { + return; + } + millis = Date.now(); + + if (e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel') { + var touch = e.touches[0] || e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + pos1 = touch.clientX; + pos2 = touch.clientY; + } else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover' || e.type == 'mouseout' || e.type == 'mouseenter' || e.type == 'mouseleave') { + pos1 = e.clientX; + pos2 = e.clientY; + } + + var zoom = parseFloat((pos4 - pos2) * 2 / elmnt.offsetHeight); + + if (zoom > 1) { + zoom = 1.0; + } else if (zoom < -1) { + zoom = -1.0; + } + input.value = zoom * (input.max - input.min) + input.min; + if (input.value != pos0) { + track0.applyConstraints({ + advanced: [{ + zoom: input.value + }] + }); + } + } + + function closeDragElement(e) { + log(e); + log("closeDragElement"); + //if (e!==null){ + // elmnt.controls=true; + //} + /* stop moving when mouse button is released:*/ + document.ontouchup = null; + document.onmouseup = null; + document.onmousemove = null; + document.ontouchmove = null; + } +} + +function previewIframe(iframesrc) { // this is pretty important if you want to avoid camera permission popup problems. You can also call it automatically via: loadIframe();"> , but don't call it before the page loads. + + var iframe = document.createElement("iframe"); + iframe.allow = "autoplay;camera;microphone;fullscreen;transparency;picture-in-picture;"; + iframe.style.width = "100%"; + iframe.style.height = "100%"; + iframe.style.border = "10px dashed rgb(64 65 62)"; + + if (iframesrc == "") { + iframesrc = "./"; + } + + + if (iframesrc.startsWith("https://") || iframesrc.startsWith("http://")){ + var domain = (new URL(iframesrc)); + domain = domain.hostname; + log(domain); + if ((domain=="www.youtube.com") || (domain=="youtube.com")){ + var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; + var match = iframesrc.match(regExp); + var vidid = (match&&match[7].length==11)? match[7] : false; + + if(vidid){ + iframesrc = "https://www.youtube.com/embed/"+vidid+"?autoplay=1&modestbranding=1"; + log(iframesrc); + } + } else if (domain=="www.twitch.tv"){ + var vidid = iframesrc.split('/').pop().split('#')[0].split('?')[0]; + if (vidid){ + iframesrc = "https://player.twitch.tv/?channel="+vidid+"&parent="+location.hostname; + log(iframesrc); + } + } else if (domain=="twitch.tv"){ + var vidid = iframesrc.split('/').pop().split('#')[0].split('?')[0]; + if (vidid){ + iframesrc = "https://player.twitch.tv/?channel="+vidid+"&parent="+location.hostname; + log(iframesrc); + } + } + + } + + iframe.src = iframesrc; + getById("previewIframe").innerHTML = ""; + getById("previewIframe").style.width = "640px"; + getById("previewIframe").style.height = "360px"; + getById("previewIframe").style.margin = "auto"; + getById("previewIframe").appendChild(iframe); +} + +function loadIframe(iframesrc) { // this is pretty important if you want to avoid camera permission popup problems. You can also call it automatically via: loadIframe();"> , but don't call it before the page loads. + + var iframe = document.createElement("iframe"); + iframe.allow = "autoplay;camera;microphone;fullscreen;transparency;picture-in-picture;"; + iframe.style.width = "100%"; + iframe.style.height = "100%"; + iframe.style.border = "10px dashed rgb(64 65 62)"; + + if (iframesrc == "") { + iframesrc = "./"; + iframe.style.border = "0"; + } + + if (iframesrc.startsWith("https://vdo.ninja/")){ + iframe.style.border = "0"; + } else if (iframesrc.startsWith("https://youtube.com/")){ + iframe.style.border = "0"; + } else if (iframesrc.startsWith("https://www.youtube.com/")){ + iframe.style.border = "0"; + } else if (iframesrc.startsWith("https://youtube.com/")){ + iframe.style.border = "0"; + } else if (iframesrc.startsWith("https://player.twitch.tv/")){ + iframe.style.border = "0"; + } else if (iframesrc.startsWith("https://meshcast.io/")){ + iframe.style.border = "0"; + } + + if (document.getElementById("mainmenu")) { + var m = getById("mainmenu"); + m.remove(); + } + iframe.src = iframesrc; + return iframe +} + +function dropDownButtonAction(ele) { + var ele = getById("dropButton"); + if (ele) { + ele.parentNode.removeChild(ele); + getById('container-5').classList.remove('advanced'); + getById('container-8').classList.remove('advanced'); + getById('container-6').classList.remove('advanced'); + getById('container-7').classList.remove('advanced'); + } +} + +function updateConstraintSliders() { + log("updateConstraintSliders"); + if (session.roomid !== false && session.roomid !== "" && session.director !== true && session.forceMediaSettings == false) { + if (session.controlRoomBitrate !== false) { + listCameraSettings(); + } + if (session.effects!==false){ + if ((iOS) || (iPad)){ + } else { + getById("effectsDiv3").style.display = "block"; + getById("effectSelector3").value = (parseInt(session.effects) || 0) +""; + } + } + } else { + listAudioSettings(); + listCameraSettings(); + if ((iOS) || (iPad)){ + } else { + if (session.effects!==false){ + getById("effectsDiv3").style.display = "block"; + try{ + getById("effectSelector3").value = (parseInt(session.effects) || 0) +""; + } catch(E){} + } + } + } + //checkIfPIP(); // this doesn't actually work on iOS still, so whatever. +} + +function checkIfPIP() { + try { + if (session.videoElement && ((session.videoElement.webkitSupportsPresentationMode && typeof session.videoElement.webkitSetPresentationMode === "function") || (document.pictureInPictureEnabled || !videoElement.disablePictureInPicture))) { + // Toggle PiP when the user clicks the button. + + getById("pIpStartButton").addEventListener("click", function(event) { + // if ( (document.pictureInPictureEnabled || !videoElement.disablePictureInPicture)){ + //session.videoElement.requestPictureInPicture(); + // } else { + session.videoElement.webkitSetPresentationMode(session.videoElement.webkitPresentationMode === "picture-in-picture" ? "inline" : "picture-in-picture"); + // } + }); + getById("pIpStartButton").style.display = "inline-block"; + } + } catch (e) { + errorlog(e); + } +} + +function listAudioSettingsPrep() { + try { + var tracks = session.streamSrc.getAudioTracks(); + if (!tracks.length) { + warnlog("session.streamSrc contains no audio tracks"); + return; + } + } catch (e) { + warnlog(e); + return; + } + + var data = []; + + for (var i = 0; i < tracks.length; i += 1) { + track0 = tracks[i]; + var trackSet = {}; + + if (track0.getCapabilities) { + trackSet.audioConstraints = track0.getCapabilities(); + } + + if (track0.getSettings) { + trackSet.currentAudioConstraints = track0.getSettings(); + } + + trackSet.trackLabel = "unknown or none"; + if (track0.label) { + trackSet.trackLabel = track0.label; + } + + if (i == 0) { + trackSet.equalizer = session.equalizer; // only supporting the first track at the moment. + } else { + trackSet.equalizer = false; + } + + if (i == 0) { + trackSet.lowcut = session.lowcut; // only supporting the first track at the moment. + } else { + trackSet.lowcut = false; + } + + data.push(trackSet); + } + return data; +} + +function listVideoSettingsPrep() { + try { + var track0 = session.streamSrc.getVideoTracks(); + if (track0.length) { + track0 = track0[0]; + if (track0.getCapabilities) { + session.cameraConstraints = track0.getCapabilities(); + } + log(session.cameraConstraints); + } + } catch (e) { + warnlog(e); + return; + } + + try { + if (track0.getSettings) { + session.currentCameraConstraints = track0.getSettings(); + } + } catch (e) { + warnlog(e); + return; + } + var msg = {}; + msg.trackLabel = "unknown or none"; + if (track0.label) { + msg.trackLabel = track0.label; + } + msg.currentCameraConstraints = session.currentCameraConstraints; + msg.cameraConstraints = session.cameraConstraints; + return msg; +} + + +var Final_transcript = ""; +var Interim_transcript = ""; +var Recognition = null; + +if ("webkitSpeechRecognition" in window) { + var SpeechRecognition = webkitSpeechRecognition; +} else if ("SpeechRecognition" in window) { + var SpeechRecognition = window.SpeechRecognition; +} else { + var SpeechRecognition = false; +} + +var TranscriptionCounter = 0; +var retriesRecognition = 0; +var activeRecognition=false; +var timeoutRecognition = null; +function setupClosedCaptions() { + + if (activeRecognition){return;} + activeRecognition=true; + + log("CLOSED CAPTIONING SETUP"); + + if (SpeechRecognition) { + Recognition = new SpeechRecognition(); + + Recognition.lang = session.transcript; + + Recognition.continuous = true; + Recognition.interimResults = true; + Recognition.maxAlternatives = 0; + + Recognition.onstart = function() { + log("started transcription: "+Date.now()); + clearTimeout(timeoutRecognition); + timeoutRecognition = setTimeout(function(){ + retriesRecognition=0; + },10000); + }; + Recognition.onerror = function(event) { + errorlog(event); + }; + Recognition.onend = function(e) { + warnlog(e); + log("Stopped transcription "+Date.now()); + clearTimeout(timeoutRecognition); + timeoutRecognition = setTimeout(function() { + Recognition.start(); + }, parseInt(500*retriesRecognition*retriesRecognition)); // restart it if it fails. + retriesRecognition+=1; + }; + + Recognition.onresult = function(event) { + + Interim_transcript = ''; + if (typeof(event.results) == 'undefined') { + log(event); + return; + } + for (var i = event.resultIndex; i < event.results.length; ++i) { + if (event.results[i].isFinal) { + Final_transcript += event.results[i][0].transcript; + } else { + Interim_transcript += event.results[i][0].transcript; + } + } + + if (Final_transcript.length > 0) { + log("FINAL:" + Final_transcript); + try { + var data = {}; + data.isFinal = true; + data.transcript = Final_transcript; + data.counter = TranscriptionCounter; + session.sendMessage(data); + TranscriptionCounter += 1; + Final_transcript = ""; + Interim_transcript = ""; + } catch (e) { + errorlog(e); + } + + } else { + try { + var data = {}; + data.isFinal = false; + data.transcript = Interim_transcript; + data.counter = TranscriptionCounter; + session.sendMessage(data); + } catch (e) { + errorlog(e); + Interim_transcript = ""; + } + } + }; + + Recognition.start(); + } +} + + +function requestVideoRecord(ele) { + var UUID = ele.dataset.UUID + if (ele.classList.contains("pressed")) { + var msg = {}; + msg.requestVideoRecord = false; + msg.UUID = UUID; + session.sendRequest(msg, msg.UUID); + ele.classList.remove("pressed"); + } else { + var msg = {}; + msg.requestVideoRecord = true; + msg.UUID = UUID; + window.focus(); + var bitrate = prompt("What bitrate would you like to record at? (kbps)", 6000); + if (bitrate) { + msg.value = bitrate; + session.sendRequest(msg, msg.UUID); + ele.classList.add("pressed"); + } + } +} + +function changeOrderDirector(value) { + if (session.order==false){ + session.order=0; + } + session.order += parseInt(value) || 0; + + var elements = document.querySelectorAll('[data-action-type="order-value-director"]'); + //log(elements); + if (elements[0]){ + elements[0].innerText = parseInt(session.order) || 0; + } + + var data = {}; + data = {}; + data.order = session.order; + session.sendPeers(data); +} + + + +function changeOrder(value, UUID) { + var msg = {}; + msg.changeOrder = value; + msg.UUID = UUID; + session.sendRequest(msg, msg.UUID); +} + +function requestVideoHack(keyname, value, UUID) { + var msg = {}; + msg.requestVideoHack = true; + msg.keyname = keyname; + msg.value = value; + msg.UUID = UUID; + session.sendRequest(msg, msg.UUID); +} + +function requestAudioHack(keyname, value, UUID, track = 0) { // updateCameraConstraints + var msg = {}; + msg.requestAudioHack = true; + msg.keyname = keyname; + msg.value = value; + msg.UUID = UUID; + msg.track = track; + session.sendRequest(msg, msg.UUID); +} + +function requestChangeEQ(keyname, value, UUID, track = 0) { // updateCameraConstraints + var msg = {}; + msg.requestChangeEQ = true; + msg.keyname = keyname; + msg.value = value; + msg.UUID = UUID; + msg.track = track; + session.sendRequest(msg, msg.UUID); +} + +function requestChangeLowcut(value, UUID, track = 0) { // updateCameraConstraints + var msg = {}; + msg.requestChangeLowcut = true; + msg.value = value; + msg.UUID = UUID; + msg.track = track; + session.sendRequest(msg, msg.UUID); +} + +function toggleSystemPip(vid) { + if (vid.webkitSupportsPresentationMode && (typeof vid.webkitSetPresentationMode === "function")) { + vid.webkitSetPresentationMode( + vid.webkitPresentationMode === "picture-in-picture" + ? "inline" + : "picture-in-picture" + ); + } else { + if (document.pictureInPictureElemen) { + document.exitPictureInPicture(); + vid.requestPictureInPicture(); + } else { + vid.requestPictureInPicture(); + } + + } +} + +function updateDirectorsAudio(dataN, UUID) { + var audioEle = document.createElement("div"); + getById("advanced_audio_director_" + UUID).innerHTML = ""; + getById("advanced_audio_director_" + UUID).className = ""; + + //log(dataN); + if (!dataN.length) { + return; + } + + for (var n = 0; n < dataN.length; n += 1) { + var data = dataN[n]; + + if (data.trackLabel) { + var label = document.createElement("span"); + label.innerText = data.trackLabel; + label.style.marginBottom = "10px"; + label.style.display = "block"; + audioEle.appendChild(label); + } + if (n !== 0) { + //var label = document.createElement("span"); + //label.innerText = "Coming Soon"; + //audioEle.appendChild(label); + continue; // remove to more than one audio device (assuming other fixes are applied) + } + + + if (data.lowcut) { + var label = document.createElement("label"); + var i = "Low_Cut"; + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = "low cut:"; + + var input = document.createElement("input"); + input.min = 50; + input.max = 150; + + input.type = "range"; + input.dataset.keyname = i; + input.dataset.labelname = label.innerText; + input.dataset.track = n; + input.dataset.UUID = UUID; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + input.style.margin = "8px 0"; + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value; + requestChangeLowcut(parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track)); + }; + + audioEle.appendChild(label); + audioEle.appendChild(input); + } + + if (data.equalizer) { + var label = document.createElement("label"); + var i = "Low_EQ"; + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = "low EQ:"; + + var input = document.createElement("input"); + input.min = -50; + input.max = 50; + + input.type = "range"; + input.dataset.keyname = i; + input.dataset.labelname = label.innerText; + input.dataset.track = n; + input.dataset.UUID = UUID; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + input.style.margin = "8px 0"; + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value; + //changeLowEQ( e.target.value); + requestChangeEQ("low", parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track)); + }; + + audioEle.appendChild(label); + audioEle.appendChild(input); + + var label = document.createElement("label"); + var i = "Mid_EQ"; + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = "mid EQ:"; + + var input = document.createElement("input"); + input.min = -50; + input.max = 50; + + input.type = "range"; + input.dataset.keyname = i; + input.dataset.labelname = label.innerText; + input.dataset.track = n; + input.dataset.UUID = UUID; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + input.style.margin = "8px 0"; + + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value; + //changeMidEQ( e.target.value); + requestChangeEQ("mid", parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track)); + }; + + audioEle.appendChild(label); + audioEle.appendChild(input); + + + var label = document.createElement("label"); + var i = "High_EQ"; + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = "high EQ:"; + + var input = document.createElement("input"); + input.min = -50; + input.max = 50; + + input.type = "range"; + input.dataset.keyname = i; + input.dataset.labelname = label.innerText; + input.dataset.track = n; + input.dataset.UUID = UUID; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + input.style.margin = "8px 0"; + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value; + requestChangeEQ("high", parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track)); + }; + + audioEle.appendChild(label); + audioEle.appendChild(input); + } + for (var i in data.audioConstraints) { + try { + log(i); + log(data.audioConstraints[i]); + if ((typeof data.audioConstraints[i] === 'object') && (data.audioConstraints[i] !== null) && ("max" in data.audioConstraints[i]) && ("min" in data.audioConstraints[i])) { + if (i === "aspectRatio") { + continue; + } else if (i === "width") { + continue; + } else if (i === "height") { + continue; + } else if (i === "frameRate") { + continue; + } else if (i === "latency") { + continue; + } else if (i === "sampleRate") { + continue; + } else if (i === "channelCount") { + continue; + } + + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = i + ":"; + + var input = document.createElement("input"); + input.min = data.audioConstraints[i].min; + input.max = data.audioConstraints[i].max; + + if (parseFloat(input.min) == parseFloat(input.max)) { + continue; + } + + if (i in data.currentAudioConstraints) { + input.value = data.currentAudioConstraints[i]; + label.innerText = i + ": " + data.currentAudioConstraints[i]; + label.title = "Previously was: " + data.currentAudioConstraints[i]; + input.title = "Previously was: " + data.currentAudioConstraints[i]; + } else { + label.innerText = i; + } + if ("step" in data.audioConstraints[i]) { + input.step = data.audioConstraints[i].step; + } + input.type = "range"; + input.dataset.keyname = i; + input.dataset.track = n; + input.dataset.UUID = UUID; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.keyname + ": " + e.target.value; + //updateAudioConstraints(e.target.dataset.keyname, e.target.value); + requestAudioHack(e.target.dataset.keyname, e.target.value, e.target.dataset.UUID, e.target.dataset.track); + }; + + audioEle.appendChild(label); + audioEle.appendChild(input); + } else if ((typeof data.audioConstraints[i] === 'object') && (data.audioConstraints[i] !== null)) { + if (i == "resizeMode") { + continue; + } + + var div = document.createElement("div"); + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = i + ":"; + label.style = "display:inline-block; padding:0;margin: 5px 0px 9px;"; + label.dataset.keyname = i; + var input = document.createElement("select"); + var c = document.createElement("option"); + + if (data.audioConstraints[i].length > 1) { + for (var opts in data.audioConstraints[i]) { + log(opts); + var opt = new Option(data.audioConstraints[i][opts], data.audioConstraints[i][opts]); + input.options.add(opt); + if (i in data.currentAudioConstraints) { + if (data.audioConstraints[i][opts] == data.currentAudioConstraints[i]) { + opt.selected = true; + } + } + } + } else if (i.toLowerCase == "torch") { + var opt = new Option("Off", false); + input.options.add(opt); + opt = new Option("On", true); + input.options.add(opt); + } else { + continue; + } + + input.id = "constraints_" + i; + input.className = "constraintCameraInput"; + input.name = "constraints_" + i; + input.style = "display:inline; padding:2px; margin:0 10px;"; + input.dataset.keyname = i; + input.dataset.track = n; + input.dataset.UUID = UUID; + input.onchange = function(e) { + //getById("label_"+e.target.dataset.keyname).innerText =e.target.dataset.keyname+": "+e.target.value; + //updateAudioConstraints(e.target.dataset.keyname, e.target.value); + requestAudioHack(e.target.dataset.keyname, e.target.value, e.target.dataset.UUID, e.target.dataset.track); + log(e.target.dataset.keyname, e.target.value); + }; + audioEle.appendChild(div); + div.appendChild(label); + div.appendChild(input); + } else if (typeof data.audioConstraints[i] === 'boolean') { + + var div = document.createElement("div"); + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = i + ":"; + label.style = "display:inline-block; padding:0;margin: 5px 0px 9px;"; + label.dataset.keyname = i; + var input = document.createElement("select"); + var c = document.createElement("option"); + + var opt = new Option("Off", false); + input.options.add(opt); + opt = new Option("On", true); + input.options.add(opt); + + input.id = "constraints_" + i; + input.className = "constraintCameraInput"; + input.name = "constraints_" + i; + input.style = "display:inline; padding:2px; margin:0 10px;"; + input.dataset.keyname = i; + input.dataset.track = n; + input.dataset.UUID = UUID; + input.onchange = function(e) { + //getById("label_"+e.target.dataset.keyname).innerText =e.target.dataset.keyname+": "+e.target.value; + //updateAudioConstraints(e.target.dataset.keyname, e.target.value); + requestAudioHack(e.target.dataset.keyname, e.target.value, e.target.dataset.UUID, e.target.dataset.track); + log(e.target.dataset.keyname, e.target.value); + }; + audioEle.appendChild(div); + div.appendChild(label); + div.appendChild(input); + } + } catch (e) { + errorlog(e); + } + } + getById("advanced_audio_director_" + UUID).appendChild(audioEle); + } +} + +function updateDirectorsVideo(data, UUID) { + var videoEle = document.createElement("div"); + if (data.trackLabel) { + var label = document.createElement("span"); + label.innerText = data.trackLabel; + label.style.marginBottom = "10px"; + label.style.display = "block"; + videoEle.appendChild(label); + } + + + for (var i in data.cameraConstraints) { + try { + log(i); + log(data.cameraConstraints[i]); + if ((typeof data.cameraConstraints[i] === 'object') && (data.cameraConstraints[i] !== null) && ("max" in data.cameraConstraints[i]) && ("min" in data.cameraConstraints[i])) { + if (i === "aspectRatio") { + continue; + } else if (i === "width") { + continue; + } else if (i === "height") { + continue; + } else if (i === "frameRate") { + continue; + } else if (i === "latency") { + continue; + } else if (i === "sampleRate") { + continue; + } else if (i === "channelCount") { + continue; + } + + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = i + ":"; + + var input = document.createElement("input"); + input.min = data.cameraConstraints[i].min; + input.max = data.cameraConstraints[i].max; + + if (parseFloat(input.min) == parseFloat(input.max)) { + continue; + } + + + if (i in data.currentCameraConstraints) { + input.value = data.currentCameraConstraints[i]; + label.innerText = i + ": " + data.currentCameraConstraints[i]; + label.title = "Previously was: " + data.currentCameraConstraints[i]; + input.title = "Previously was: " + data.currentCameraConstraints[i]; + } else { + label.innerText = i; + } + if ("step" in data.cameraConstraints[i]) { + input.step = data.cameraConstraints[i].step; + } + input.type = "range"; + input.dataset.keyname = i; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;margin: 8px 0;"; + input.name = "constraints_" + i; + + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.keyname + ": " + e.target.value; + //updateVideoConstraints(e.target.dataset.keyname, e.target.value); + requestVideoHack(e.target.dataset.keyname, e.target.value, UUID); + }; + + + videoEle.appendChild(label); + videoEle.appendChild(input); + } else if ((typeof data.cameraConstraints[i] === 'object') && (data.cameraConstraints[i] !== null)) { + if (i == "resizeMode") { + continue; + } + + var div = document.createElement("div"); + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = i + ":"; + label.style = "display:inline-block; padding:0;margin: 5px 0px 9px;"; + label.dataset.keyname = i; + var input = document.createElement("select"); + var c = document.createElement("option"); + + if (data.cameraConstraints[i].length > 1) { + for (var opts in data.cameraConstraints[i]) { + log(opts); + var opt = new Option(data.cameraConstraints[i][opts], data.cameraConstraints[i][opts]); + input.options.add(opt); + if (i in data.currentCameraConstraints) { + if (data.cameraConstraints[i][opts] == data.currentCameraConstraints[i]) { + opt.selected = true; + } + } + } + } else if (i.toLowerCase == "torch") { + var opt = new Option("Off", false); + input.options.add(opt); + opt = new Option("On", true); + input.options.add(opt); + } else { + continue; + } + + input.id = "constraints_" + i; + input.className = "constraintCameraInput"; + input.name = "constraints_" + i; + input.style = "display:inline; padding:2px; margin:0 10px;"; + input.dataset.keyname = i; + input.onchange = function(e) { + //getById("label_"+e.target.dataset.keyname).innerText =e.target.dataset.keyname+": "+e.target.value; + //updateVideoConstraints(e.target.dataset.keyname, e.target.value); + requestVideoHack(e.target.dataset.keyname, e.target.value, UUID); + log(e.target.dataset.keyname, e.target.value); + }; + videoEle.appendChild(div); + div.appendChild(label); + div.appendChild(input); + } else if (typeof data.cameraConstraints[i] === 'boolean') { + + var div = document.createElement("div"); + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = i + ":"; + label.style = "display:inline-block; padding:0;margin: 5px 0px 9px;"; + label.dataset.keyname = i; + var input = document.createElement("select"); + var c = document.createElement("option"); + + var opt = new Option("Off", false); + input.options.add(opt); + opt = new Option("On", true); + input.options.add(opt); + + input.id = "constraints_" + i; + input.className = "constraintCameraInput"; + input.name = "constraints_" + i; + input.style = "display:inline; padding:2px; margin:0 10px;"; + input.dataset.keyname = i; + input.onchange = function(e) { + //getById("label_"+e.target.dataset.keyname).innerText =e.target.dataset.keyname+": "+e.target.value; + //updateVideoConstraints(e.target.dataset.keyname, e.target.value); + requestVideoHack(e.target.dataset.keyname, e.target.value, UUID); + log(e.target.dataset.keyname, e.target.value); + }; + videoEle.appendChild(div); + div.appendChild(label); + div.appendChild(input); + } + } catch (e) { + errorlog(e); + } + } + + getById("advanced_video_director_" + UUID).innerHTML = ""; + getById("advanced_video_director_" + UUID).appendChild(videoEle); + getById("advanced_video_director_" + UUID).className = ""; +} + +/////// + +function listAudioSettings() { + getById("popupSelector_constraints_audio").innerHTML = ""; + try { + var track0 = session.streamSrc.getAudioTracks(); + if (track0.length) { + track0 = track0[0]; + if (track0.getCapabilities) { + session.audioConstraints = track0.getCapabilities(); + } + log(session.audioConstraints); + } else { + warnlog("session.streamSrc contains no audio tracks"); + return; + } + } catch (e) { + warnlog("session.streamSrc contains no audio tracks"); + errorlog(e); + return; + } + try { + if (track0.getSettings) { + session.currentAudioConstraints = track0.getSettings(); + } + } catch (e) { + errorlog(e); + } + ////// + + if (session.lowcut) { + if (getById("popupSelector_constraints_audio").style.display == "none") { + getById("advancedOptionsAudio").style.display = "inline-block"; + } + + var label = document.createElement("label"); + var i = "Low_Cut"; + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerText = "Low Cut:"; + + var input = document.createElement("input"); + input.min = 50; + input.max = 400; + + input.type = "range"; + input.dataset.keyname = i; + input.dataset.labelname = label.innerHTML; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + + for (var webAudio in session.webAudios) { + if (session.webAudios[webAudio].lowcut1.frequency) { + input.value = session.webAudios[webAudio].lowcut1.frequency.value; + label.innerHTML += " " + session.webAudios[webAudio].lowcut1.frequency.value; + } + } + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.labelname + " " + e.target.value; + changeLowCut(e.target.value, 0); + }; + + getById("popupSelector_constraints_audio").appendChild(label); + getById("popupSelector_constraints_audio").appendChild(input); + } + + if (session.equalizer) { + if (getById("popupSelector_constraints_audio").style.display == "none") { + getById("advancedOptionsAudio").style.display = "inline-block"; + } + + var label = document.createElement("label"); + var i = "Low_EQ"; + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = "Low EQ:"; + + var input = document.createElement("input"); + input.min = -50; + input.max = 50; + + input.type = "range"; + input.dataset.keyname = i; + input.dataset.labelname = label.innerHTML; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + + for (var webAudio in session.webAudios) { + if (session.webAudios[webAudio].lowEQ.gain) { + input.value = session.webAudios[webAudio].lowEQ.gain.value; + label.innerHTML += " " + session.webAudios[webAudio].lowEQ.gain.value; + } + } + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.labelname + " " + e.target.value; + changeLowEQ(e.target.value, 0); + }; + + getById("popupSelector_constraints_audio").appendChild(label); + getById("popupSelector_constraints_audio").appendChild(input); + // + if (getById("popupSelector_constraints_audio").style.display == "none") { + getById("advancedOptionsAudio").style.display = "inline-block"; + } + + var label = document.createElement("label"); + var i = "Mid_EQ"; + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = "Mid EQ:"; + + var input = document.createElement("input"); + input.min = -50; + input.max = 50; + + input.type = "range"; + input.dataset.keyname = i; + input.dataset.labelname = label.innerHTML; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + + + for (var webAudio in session.webAudios) { + if (session.webAudios[webAudio].midEQ.gain) { + input.value = session.webAudios[webAudio].midEQ.gain.value; + label.innerHTML += " " + session.webAudios[webAudio].midEQ.gain.value; + } + } + + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.labelname + " " + e.target.value; + changeMidEQ(e.target.value, 0); + }; + + getById("popupSelector_constraints_audio").appendChild(label); + getById("popupSelector_constraints_audio").appendChild(input); + // + if (getById("popupSelector_constraints_audio").style.display == "none") { + getById("advancedOptionsAudio").style.display = "inline-block"; + } + + var label = document.createElement("label"); + var i = "High_EQ"; + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = "High EQ:"; + + var input = document.createElement("input"); + input.min = -50; + input.max = 50; + + + input.type = "range"; + input.dataset.keyname = i; + input.dataset.labelname = label.innerHTML; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + + for (var webAudio in session.webAudios) { + if (session.webAudios[webAudio].highEQ.gain) { + input.value = session.webAudios[webAudio].highEQ.gain.value; + label.innerHTML += " " + session.webAudios[webAudio].highEQ.gain.value; + } + } + + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.labelname + " " + e.target.value; + changeHighEQ(e.target.value, 0); + }; + + getById("popupSelector_constraints_audio").appendChild(label); + getById("popupSelector_constraints_audio").appendChild(input); + } + //////// + for (var i in session.audioConstraints) { + try { + log(i); + log(session.audioConstraints[i]); + if ((typeof session.audioConstraints[i] === 'object') && (session.audioConstraints[i] !== null) && ("max" in session.audioConstraints[i]) && ("min" in session.audioConstraints[i])) { + if (i === "aspectRatio") { + continue; + } else if (i === "width") { + continue; + } else if (i === "height") { + continue; + } else if (i === "frameRate") { + continue; + } else if (i === "latency") { + continue; + } else if (i === "sampleRate") { + continue; + } else if (i === "channelCount") { + continue; + } + + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = i + ":"; + + + var input = document.createElement("input"); + input.min = session.audioConstraints[i].min; + input.max = session.audioConstraints[i].max; + + if (parseFloat(input.min) == parseFloat(input.max)) { + continue; + } + + if (getById("popupSelector_constraints_audio").style.display == "none") { + getById("advancedOptionsAudio").style.display = "inline-block"; + } + + + if (i in session.currentAudioConstraints) { + input.value = session.currentAudioConstraints[i]; + label.innerHTML = i + ": " + session.currentAudioConstraints[i]; + label.title = "Previously was: " + session.currentAudioConstraints[i]; + input.title = "Previously was: " + session.currentAudioConstraints[i]; + } else { + label.innerHTML = i; + } + if ("step" in session.audioConstraints[i]) { + input.step = session.audioConstraints[i].step; + } + input.type = "range"; + input.dataset.keyname = i; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.keyname + ": " + e.target.value; + //updateAudioConstraints(e.target.dataset.keyname, e.target.value); + applyAudioHack(e.target.dataset.keyname, e.target.value); + }; + + + getById("popupSelector_constraints_audio").appendChild(label); + getById("popupSelector_constraints_audio").appendChild(input); + } else if ((typeof session.audioConstraints[i] === 'object') && (session.audioConstraints[i] !== null)) { + if (i == "resizeMode") { + continue; + } + + var div = document.createElement("div"); + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = i + ":"; + label.style = "display:inline-block; padding:0;margin: 15px 0px 29px;"; + label.dataset.keyname = i; + var input = document.createElement("select"); + var c = document.createElement("option"); + + if (session.audioConstraints[i].length > 1) { + for (var opts in session.audioConstraints[i]) { + log(opts); + var opt = new Option(session.audioConstraints[i][opts], session.audioConstraints[i][opts]); + input.options.add(opt); + + if (i in session.currentAudioConstraints) { + if (session.audioConstraints[i][opts] == session.currentAudioConstraints[i]) { + opt.selected = true; + } + } + + } + } else if (i.toLowerCase == "torch") { + var opt = new Option("Off", false); + input.options.add(opt); + opt = new Option("On", true); + input.options.add(opt); + } else { + continue; + } + + if (getById("popupSelector_constraints_audio").style.display == "none") { + getById("advancedOptionsAudio").style.display = "inline-block"; + } + + input.id = "constraints_" + i; + input.className = "constraintCameraInput"; + input.name = "constraints_" + i; + input.style = "display:inline; padding:2px; margin:0 10px;"; + input.dataset.keyname = i; + input.onchange = function(e) { + //getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value; + //updateAudioConstraints(e.target.dataset.keyname, e.target.value); + applyAudioHack(e.target.dataset.keyname, e.target.value); + log(e.target.dataset.keyname, e.target.value); + }; + getById("popupSelector_constraints_audio").appendChild(div); + div.appendChild(label); + div.appendChild(input); + } else if (typeof session.audioConstraints[i] === 'boolean') { + + var div = document.createElement("div"); + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = i + ":"; + label.style = "display:inline-block; padding:0;margin: 15px 0px 29px;"; + label.dataset.keyname = i; + var input = document.createElement("select"); + var c = document.createElement("option"); + + var opt = new Option("Off", false); + input.options.add(opt); + opt = new Option("On", true); + input.options.add(opt); + + if (getById("popupSelector_constraints_audio").style.display == "none") { + getById("advancedOptionsAudio").style.display = "inline-block"; + } + + input.id = "constraints_" + i; + input.className = "constraintCameraInput"; + input.name = "constraints_" + i; + input.style = "display:inline; padding:2px; margin:0 10px;"; + input.dataset.keyname = i; + input.onchange = function(e) { + //getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value; + //updateAudioConstraints(e.target.dataset.keyname, e.target.value); + applyAudioHack(e.target.dataset.keyname, e.target.value); + log(e.target.dataset.keyname, e.target.value); + }; + getById("popupSelector_constraints_audio").appendChild(div); + div.appendChild(label); + div.appendChild(input); + } + } catch (e) { + errorlog(e); + } + + } +} + + +function applyAudioHack(constraint, value = null) { + if (value == parseFloat(value)) { + value = parseFloat(value); + value = { + exact: value + }; + } else if (value == "true") { + value = true; + } else if (value == "false") { + value = false; + } + log(constraint); + //////////////// + try { + var track0 = session.streamSrc.getAudioTracks(); + if (track0.length) { + track0 = track0[0]; + if (track0.getCapabilities) { + session.audioConstraints = track0.getCapabilities(); + } + log(session.audioConstraints); + } else { + warnlog("session.streamSrc contains no audio tracks"); + return; + } + } catch (e) { + warnlog("session.streamSrc contains no audio tracks"); + errorlog(e); + return; + } + try { + if (track0.getSettings) { + session.currentAudioConstraints = track0.getSettings(); + } + } catch (e) { + errorlog(e); + } + //////// + + var new_constraints = Object.assign(track0.getSettings(), { + [constraint]: value + }, ); + new_constraints = { + audio: new_constraints + , video: false + }; + log(new_constraints); + activatedPreview = false; + enumerateDevices().then(gotDevices2).then(function() { + grabAudio("videosource", "#audioSource3", null, new_constraints); + }); + +} + +function updateAudioConstraints(constraint, value = null) { // this is what it SHOULD be, but this doesn't work yet. + var track0 = session.streamSrc.getAudioTracks(); + track0 = track0[0]; + if (value == parseFloat(value)) { + value = parseFloat(value); + } else if (value == "true") { + value = true; + } else if (value == "false") { + value = false; + } + log({ + advanced: [{ + [constraint]: value + }] + }); + track0.applyConstraints({ + advanced: [{ + [constraint]: value + }] + }); + return; + +} + +function listCameraSettings() { + getById("popupSelector_constraints_video").innerHTML = ""; + + if (session.controlRoomBitrate===true){ + session.controlRoomBitrate = session.totalRoomBitrate; + } + + if (session.roomid && (session.view !== "") && (session.controlRoomBitrate!==false)) { + log("LISTING OPTION FOR BITRATE CONTROL"); + var i = "room video bitrate (kbps)"; + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = i + ":"; + label.title = "If you're on a slow network, you can improve frame rate and audio quality by reducing the amount of video data that others send you"; + + var input = document.createElement("input"); + input.min = 0; + input.max = parseInt(session.totalRoomBitrate); + + if (getById("popupSelector_constraints_video").style.display == "none") { + getById("advancedOptionsCamera").style.display = "inline-block"; + } + + input.value = session.controlRoomBitrate; + label.innerHTML = i + ": " + session.controlRoomBitrate; + + input.type = "range"; + input.dataset.keyname = i; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + input.title = "If you're on a slow network, you can improve frame rate and audio quality by reducing the amount of video data that others send you"; + + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.keyname + ": " + e.target.value; + + if (e.target.value > session.totalRoomBitrate) { + return; + } else { + session.controlRoomBitrate = parseInt(e.target.value); + } + updateMixer(); + }; + + + getById("popupSelector_constraints_video").appendChild(label); + getById("popupSelector_constraints_video").appendChild(input); + + } + try { + var track0 = session.streamSrc.getVideoTracks(); + if (track0.length) { + track0 = track0[0]; + if (track0.getCapabilities) { + session.cameraConstraints = track0.getCapabilities(); + } + log(session.cameraConstraints); + } + } catch (e) { + errorlog(e); + return; + } + + try { + + if (track0.getSettings) { + session.currentCameraConstraints = track0.getSettings(); + } + } catch (e) { + errorlog(e); + } + + for (var i in session.cameraConstraints) { + try { + log(i); + log(session.cameraConstraints[i]); + if ((typeof session.cameraConstraints[i] === 'object') && (session.cameraConstraints[i] !== null) && ("max" in session.cameraConstraints[i]) && ("min" in session.cameraConstraints[i])) { + if (i === "aspectRatio") { + continue; + } else if (i === "width") { + continue; + } else if (i === "height") { + continue; + } else if (i === "frameRate") { + continue; + } + + + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = i + ":"; + + var input = document.createElement("input"); + input.min = session.cameraConstraints[i].min; + input.max = session.cameraConstraints[i].max; + + if (parseFloat(input.min) == parseFloat(input.max)) { + continue; + } + + if (getById("popupSelector_constraints_video").style.display == "none") { + getById("advancedOptionsCamera").style.display = "inline-block"; + } + + if (i in session.currentCameraConstraints) { + input.value = session.currentCameraConstraints[i]; + label.innerHTML = i + ": " + session.currentCameraConstraints[i]; + label.title = "Previously was: " + session.currentCameraConstraints[i]; + input.title = "Previously was: " + session.currentCameraConstraints[i]; + } else { + label.innerHTML = i; + } + if ("step" in session.cameraConstraints[i]) { + input.step = session.cameraConstraints[i].step; + } + input.type = "range"; + input.dataset.keyname = i; + input.id = "constraints_" + i; + input.style = "display:block; width:100%;"; + input.name = "constraints_" + i; + + + input.onchange = function(e) { + getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.keyname + ": " + e.target.value; + updateCameraConstraints(e.target.dataset.keyname, e.target.value); + }; + + + getById("popupSelector_constraints_video").appendChild(label); + getById("popupSelector_constraints_video").appendChild(input); + } else if ((typeof session.cameraConstraints[i] === 'object') && (session.cameraConstraints[i] !== null)) { + if (i == "resizeMode") { + continue; + } + + var div = document.createElement("div"); + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = i + ":"; + label.style = "display:inline-block; padding:0;margin: 15px 0px 29px;"; + label.dataset.keyname = i; + var input = document.createElement("select"); + var c = document.createElement("option"); + + if (session.cameraConstraints[i].length > 1) { + for (var opts in session.cameraConstraints[i]) { + log(opts); + var opt = new Option(session.cameraConstraints[i][opts], session.cameraConstraints[i][opts]); + input.options.add(opt); + if (i in session.currentCameraConstraints) { + if (session.cameraConstraints[i][opts] == session.currentCameraConstraints[i]) { + opt.selected = true; + } + } + } + } else if (i.toLowerCase == "torch") { + var opt = new Option("Off", false); + input.options.add(opt); + opt = new Option("On", true); + input.options.add(opt); + } else { + continue; + } + + if (getById("popupSelector_constraints_video").style.display == "none") { + getById("advancedOptionsCamera").style.display = "inline-block"; + } + + input.id = "constraints_" + i; + input.className = "constraintCameraInput"; + input.name = "constraints_" + i; + input.style = "display:inline; padding:2px; margin:0 10px;"; + input.dataset.keyname = i; + input.onchange = function(e) { + //getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value; + updateCameraConstraints(e.target.dataset.keyname, e.target.value); + log(e.target.dataset.keyname, e.target.value); + }; + getById("popupSelector_constraints_video").appendChild(div); + div.appendChild(label); + div.appendChild(input); + } else if (typeof session.cameraConstraints[i] === 'boolean') { + + var div = document.createElement("div"); + var label = document.createElement("label"); + label.id = "label_" + i; + label.htmlFor = "constraints_" + i; + label.innerHTML = i + ":"; + label.style = "display:inline-block; padding:0;margin: 15px 0px 29px;"; + label.dataset.keyname = i; + var input = document.createElement("select"); + var c = document.createElement("option"); + + var opt = new Option("Off", false); + input.options.add(opt); + opt = new Option("On", true); + input.options.add(opt); + + if (getById("popupSelector_constraints_video").style.display == "none") { + getById("advancedOptionsCamera").style.display = "inline-block"; + } + + input.id = "constraints_" + i; + input.className = "constraintCameraInput"; + input.name = "constraints_" + i; + input.style = "display:inline; padding:2px; margin:0 10px;"; + input.dataset.keyname = i; + input.onchange = function(e) { + //getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value; + updateCameraConstraints(e.target.dataset.keyname, e.target.value); + log(e.target.dataset.keyname, e.target.value); + }; + getById("popupSelector_constraints_video").appendChild(div); + div.appendChild(label); + div.appendChild(input); + } + } catch (e) { + errorlog(e); + } + + } +} + +function updateCameraConstraints(constraint, value = null) { + var track0 = session.streamSrc.getVideoTracks(); + track0 = track0[0]; + if (value == parseFloat(value)) { + value = parseFloat(value); + } else if (value == "true") { + value = true; + } else if (value == "false") { + value = false; + } + log({ + advanced: [{ + [constraint]: value + }] + }); + track0.applyConstraints({ + advanced: [{ + [constraint]: value + }] + }); + return; + +} + +function setupWebcamSelection(stream = null) { + log("setup webcam"); + + if (stream) { + log(getById("previewWebcam")); + session.streamSrc = stream; + getById("previewWebcam").srcObject = outboundAudioPipeline(session.streamSrc); + } else { + log("THIS IS NO STREAM??"); + } + + if (!session.videoElement) { + session.videoElement = getById("previewWebcam"); + } + + try { + return enumerateDevices().then(gotDevices).then(function() { + + if (getById("webcamquality").elements && parseInt(getById("webcamquality").elements.namedItem("resolution").value) == 3) { + if (session.maxframerate===false){ + session.maxframerate = 30; + session.maxframerate_q2 = true; + } + } else if (session.maxframerate_q2){ + session.maxframerate = false; + session.maxframerate_q2 = false; + } + + var audioSelect = getById('audioSource'); + var videoSelect = getById('videoSourceSelect'); + var outputSelect = getById('outputSource'); + + audioSelect.onchange = function() { + + var gowebcam = getById("gowebcam"); + if (gowebcam) { + gowebcam.disabled = true; + gowebcam.dataset.ready = "true"; + gowebcam.style.backgroundColor = "#DDDDDD"; + gowebcam.style.fontWeight = "normal"; + gowebcam.innerHTML = "Waiting for Camera to load"; + miniTranslate(gowebcam, "waiting-for-camera-to-load"); + } + activatedPreview = false; + grabAudio(); + }; + videoSelect.onchange = function() { + + var gowebcam = getById("gowebcam"); + if (gowebcam) { + gowebcam.disabled = true; + gowebcam.dataset.ready = "true"; + gowebcam.style.backgroundColor = "#DDDDDD"; + gowebcam.style.fontWeight = "normal"; + gowebcam.innerHTML = "Waiting for Camera to load"; + miniTranslate(gowebcam, "waiting-for-camera-to-load"); + } + warnlog("video source changed"); + + activatedPreview = false; + if (session.quality !== false) { + grabVideo(session.quality); + } else { + session.quality_wb = parseInt(getById("webcamquality").elements.namedItem("resolution").value); + grabVideo(session.quality_wb); + } + }; + + outputSelect.onchange = function() { + + if ((iOS) || (iPad)) { + return; + } + try{ + session.sink = outputSelect.options[outputSelect.selectedIndex].value; + } catch(e){errorlog(e);} + + if (!session.sink){return;} + + try{ + getById("previewWebcam").setSinkId(session.sink).then(() => { + log("New Output Device:" + session.sink); + }).catch(error => { + errorlog("6597"); + errorlog(error); + //setTimeout(function(){warnUser("Failed to change audio output destination.");},1); + }); + } catch(e){errorlog(e);} + } + + getById("webcamquality").onchange = function() { + var gowebcam = getById("gowebcam"); + if (gowebcam) { + gowebcam.disabled = true; + gowebcam.dataset.ready = "true"; + gowebcam.style.backgroundColor = "#DDDDDD"; + gowebcam.style.fontWeight = "normal"; + gowebcam.innerHTML = "Waiting for Camera to load"; + miniTranslate(gowebcam, "waiting-for-camera-to-load"); + } + + if (parseInt(getById("webcamquality").elements.namedItem("resolution").value) == 2) { + if (session.maxframerate===false){ + session.maxframerate = 30; + session.maxframerate_q2 = true; + } + } else if (session.maxframerate_q2){ + session.maxframerate = false; + session.maxframerate_q2 = false; + } + + activatedPreview = false; + session.quality_wb = parseInt(getById("webcamquality").elements.namedItem("resolution").value); + grabVideo(session.quality_wb); + }; + + if (session.audioDevice!==0) { // change from Auto to Selected Audio Device + log("SETTING AUDIO DEVICE!!"); + activatedPreview = false; + grabAudio(); + } + + if (session.videoDevice === 0) { + if (session.autostart) { + publishWebcam(); // no need to mirror as there is no video... + return; + } else { + var gowebcam = getById("gowebcam"); + if (gowebcam) { + gowebcam.disabled = false; + gowebcam.dataset.ready = "true"; + gowebcam.innerHTML = "START"; + miniTranslate(gowebcam, "start"); + } + return; + } + } else { + log("GRabbing video: " + session.quality); + activatedPreview = false; + if (session.quality !== false) { + grabVideo(session.quality); + } else { + session.quality_wb = parseInt(getById("webcamquality").elements.namedItem("resolution").value); + grabVideo(session.quality_wb); + } + } + + if ((iOS) || (iPad)) { + return; + } + try { + if (outputSelect.selectedIndex >= 0) { + session.sink = outputSelect.options[outputSelect.selectedIndex].value; + } + } catch(e){errorlog(e);} + + if (document.getElementById("previewWebcam") && document.getElementById("previewWebcam").setSinkId) { + if (session.sink) { + getById("previewWebcam").setSinkId(session.sink).then(() => {}).catch(error => { + warnlog("6665"); + warnlog(error); + }); + } + } + + }).catch(e => { + errorlog(e); + }); + } catch (e) { + errorlog(e); + } +} + +Promise.wait = function(ms) { + return new Promise(function(resolve) { + setTimeout(resolve, ms); + }); +}; + +Promise.prototype.timeout = function(ms) { + return Promise.race([ + this, Promise.wait(ms).then(function() { + var errormsg = new Error("Time Out\nDid you accept camera permissions in time? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling it.\n\nPlease also ensure your camera and audio device are correctly connected and not already in use. You may also need to refresh the page."); + errormsg.name = "timedOut"; + errormsg.message = "Time Out\nDid you accept camera permissions in time? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling it.\n\nPlease also ensure your camera and audio device are correctly connected and not already in use. You may also need to refresh the page." + throw errormsg; + + }) + ]) +}; + + +function shareWebsite(autostart=false){ + if (session.iframeSrc){ + session.iframeSrc = false; + + if (session.director){ + setStorage("directorWebsiteShare", {"website":session.iframeSrc, "roomid":session.roomid}); + } + getById("websitesharetoggle").classList.add("la-window-maximize"); + getById("websitesharetoggle").classList.remove("la-window-close"); + + getById("websitesharebutton").classList.remove("float2"); + getById("websitesharebutton").classList.add("float"); + + var data = {}; + data.iframeSrc = false; + for (var UUID in session.pcs){ + if (session.pcs[UUID].allowIframe===true){ + session.sendMessage(data, UUID); + } + } + return + } + if (autostart===false){ + window.focus(); + var iframeURL = prompt("Enter a website URL to share", "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); + } else { + var iframeURL = autostart; + } + if (!iframeURL){ + return; + } + if (iframeURL == session.iframeSrc){return;} + + if (!(iframeURL.startsWith("https://") || iframeURL.startsWith("http://"))){ + iframeURL = "https://"+iframeURL; + } + + var domain = new URL(iframeURL); + domain = domain.hostname; + log(domain); + if ((domain=="www.youtube.com") || (domain=="youtube.com")){ + var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; + var match = iframeURL.match(regExp); + var vidid = (match&&match[7].length==11)? match[7] : false; + + if(vidid){ + iframeURL = "https://www.youtube.com/embed/"+vidid+"?autoplay=1&modestbranding=1"; + log(iframeURL); + } + } else if (domain=="www.twitch.tv"){ + var vidid = iframeURL.split('/').pop().split('#')[0].split('?')[0]; + if (vidid){ + iframeURL = "https://player.twitch.tv/?channel="+vidid+"&parent="+location.hostname; + log(iframeURL); + } + } else if (domain=="twitch.tv"){ + var vidid = iframeURL.split('/').pop().split('#')[0].split('?')[0]; + if (vidid){ + iframeURL = "https://player.twitch.tv/?channel="+vidid+"&parent="+location.hostname; + log(iframeURL); + } + } + + session.iframeSrc = iframeURL; + if (session.director){ + setStorage("directorWebsiteShare", {"website":session.iframeSrc, "roomid":session.roomid}); + } + getById("websitesharetoggle").classList.remove("la-window-maximize"); + getById("websitesharetoggle").classList.add("la-window-close"); + + getById("websitesharebutton").classList.add("float2"); + getById("websitesharebutton").classList.remove("float"); + + var data = {}; + data.iframeSrc = iframeURL; + for (var UUID in session.pcs){ + if (session.pcs[UUID].allowIframe===true){ + session.sendMessage(data, UUID); + } + } +} + +function createIframePopup() { + + if (session.screenShareElement) { + session.screenShareElement.contentWindow.postMessage({ + "close": true + }, '*'); + session.screenShareElement.parentNode.removeChild(session.screenShareElement); + session.screenShareElement = false; + updateMixer(); + getById("screenshare2button").classList.add("float"); + getById("screenshare2button").classList.remove("float2"); + return; + } + + if (session.queue || session.transferred){ + getById("screenshare2button").classList.add("advanced"); + getById("screensharebutton").classList.remove("advanced"); + toggleScreenShare(); + return; + } // can't secondary-screen share if in a queue. + + if (session.screenshareid) { + var iFrameID = session.screenshareid; + } else { + var iFrameID = session.streamID.substring(0, 12) + "_" + session.generateStreamID(5); + } + + if (session.exclude) { + session.exclude.push(iFrameID); + } else { + session.exclude = []; + session.exclude.push(iFrameID); + } + + var iframe = document.createElement("iframe"); + iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;transparency;"; + iframe.allowtransparency = "true"; + + var extras = ""; + if (session.password){ + extras += "&password=" + session.password; // encodeURIComponent( + } + + if (session.privacy){ + extras += "&privacy"; + } + + if (session.screensharequality!==false){ + extras += "&q="+session.screensharequality; + } else if (session.quality){ + extras += "&q="+session.quality; + } else { + extras += "&q=0"; + } + + if (session.screensharefps!==false){ + extras += "&maxframerate="+session.screensharefps; + } + + if (session.muted){ + iframe.src = "./?audiodevice=1&screenshare&transparent&cleanish&noheader&autostart&view&muted&room=" + session.roomid + "&push=" + iFrameID + extras; + } else { + iframe.src = "./?audiodevice=1&screenshare&transparent&cleanish&noheader&autostart&view&room=" + session.roomid + "&push=" + iFrameID + extras; + } + + iframe.style.width = "100%"; + iframe.style.height = "100%"; + iframe.style.overflow = "hidden"; + iframe.id = "screensharesource"; + iframe.style.zIndex = "0"; + + + session.screenShareElement = iframe; + session.screenShareElement.dataset.doNotMove = true; + + + document.getElementById("main").appendChild(iframe); + + + updateMixer(); + getById("screenshare2button").classList.add("float2"); + getById("screenshare2button").classList.remove("float"); + + return; // ignore the rest. +} + +function previewWebcam() { + + if (session.taintedSession === null) { + log("STILL WAITING ON HASH TO VALIDATE"); + setTimeout(function() { + previewWebcam(); + }, 1000); + return; + } else if (session.taintedSession === true) { + warnlog("HASH FAILED; PASSWORD NOT VALID"); + return; + } else { + log("NOT TAINTED"); + } + + if (activatedPreview == true) { + log("activeated preview return 1"); + return; + } + activatedPreview = true; + + if (session.audioDevice === 0) { // OFF + var constraint = { + audio: false + }; + } else if ((session.echoCancellation !== false) && (session.autoGainControl !== false) && (session.noiseSuppression !== false)) { // AUTO + var constraint = { + audio: true + }; + } else { // Disable Echo Cancellation and stuff for the PREVIEW (DEFAULT CAM/MIC) + var constraint = { + audio: {} + }; + if (session.echoCancellation !== false) { // if not disabled, we assume it's on + constraint.audio.echoCancellation = true; + } else { + constraint.audio.echoCancellation = false; + } + if (session.autoGainControl !== false) { + constraint.audio.autoGainControl = true; + } else { + constraint.audio.autoGainControl = false; + } + if (session.noiseSuppression !== false) { + constraint.audio.noiseSuppression = true; + } else { + constraint.audio.noiseSuppression = false; + } + } + + if (session.videoDevice === 0) { + constraint.video = false; + } else { + constraint.video = true; + } + + if ((constraint.video === false) && (constraint.audio === false)){ + + if (session.autostart) { + publishWebcam(); // no need to mirror as there is no video... + return; + } else { + var gowebcam = document.getElementById("gowebcam"); + getById("getPermissions").style.display = "none"; + if (gowebcam) { + gowebcam.style.display = ""; + gowebcam.disabled = false; + gowebcam.dataset.ready = "true"; + gowebcam.innerHTML = "START"; + miniTranslate(gowebcam, "start"); + } + } + return; + } + + enumerateDevices().then(function(devices) { + log("enumeratated"); + log(devices); + var vtrue = false; + var atrue = false; + devices.forEach(function(device) { + if (device.kind === 'audioinput') { + atrue = true; + } else if (device.kind === 'videoinput') { + vtrue = true; + } + }); + if (atrue === false) { + constraint.audio = false; + } + if (vtrue === false) { + constraint.video = false; + } + setTimeout(function(constraint) { + requestBasicPermissions(constraint); + }, 0, constraint); + }).catch((error) => { + log("enumeratated failed. Seeking permissions."); + setTimeout(function(constraint) { + requestBasicPermissions(constraint); + }, 0, constraint); + }); + +} + +function requestBasicPermissions(constraint = {video: true, audio: true}) { + if (session.taintedSession === null) { + log("STILL WAITING ON HASH TO VALIDATE"); + setTimeout(function(constraint) { + requestBasicPermissions(constraint); + }, 1000, constraint); + return; + } else if (session.taintedSession === true) { + warnlog("HASH FAILED; PASSWORD NOT VALID"); + return; + } else { + log("NOT TAINTED 1"); + } + setTimeout(function() { + getById("getPermissions").style.display = "none"; + getById("gowebcam").style.display = ""; + }, 0); + log("REQUESTING BASIC PERMISSIONS"); + + try { + var timerBasicCheck = null; + if (!(session.cleanOutput)) { + log("Setting Timer for getUserMedia"); + timerBasicCheck = setTimeout(function() { + if (!(session.cleanOutput)) { + warnUser("Camera Access Request Timed Out\nDid you accept camera permissions? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling NDI tools.\n\nPlease also ensure that your camera and audio devices are correctly connected and not already in use. You may also need to refresh the page."); + } + }, 10000); + } + + if (session.audioInputChannels) { + if (constraint.audio === true) { + constraint.audio = {}; + constraint.audio.channelCount = session.audioInputChannels; + } else if (constraint.audio) { + constraint.audio.channelCount = session.audioInputChannels; + } + } + + log("CONSTRAINT"); + log(constraint); + navigator.mediaDevices.getUserMedia(constraint).then(function(stream) { // Apple needs thi to happen before I can access EnumerateDevices. + log("got first stream"); + clearTimeout(timerBasicCheck); + setupWebcamSelection(stream); + }).catch(function(err) { + clearTimeout(timerBasicCheck); + warnlog("some error with GetUSERMEDIA"); + errorlog(err); /* handle the error */ + if (err.name == "NotFoundError" || err.name == "DevicesNotFoundError") { + //required track is missing + } else if (err.name == "NotReadableError" || err.name == "TrackStartError") { + //webcam or mic are already in use + } else if (err.name == "OverconstrainedError" || err.name == "ConstraintNotSatisfiedError") { + //constraints can not be satisfied by avb. devices + } else if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") { + //permission denied in browser + if (!(session.cleanOutput)) { + setTimeout(function() { + warnUser("Permissions denied. Please ensure you have allowed the mic/camera permissions."); + }, 1); + } + return; + } else if (err.name == "TypeError" || err.name == "TypeError") { + //empty constraints object + } else { + //permission denied in browser + if (!(session.cleanOutput)) { + setTimeout(function() { + warnUser(err); + }, 1); + } + } + errorlog("trying to list webcam again"); + setupWebcamSelection(); + }); + } catch (e) { + errorlog(e); + if (!(session.cleanOutput)) { + if (window.isSecureContext) { + warnUser("An error has occured when trying to access the webcam or microphone. The reason is not known."); + } else if ((iOS) || (iPad)) { + warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported."); + } else { + warnUser("Error acessing camera or microphone.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia"); + } + } + } +} + + +function copyFunction(copyText) { + + try { + copyText.select(); + copyText.setSelectionRange(0, 99999); + document.execCommand("copy"); + } catch (e) { + var dummy = document.createElement('input'); + document.body.appendChild(dummy); + dummy.value = copyText; + dummy.select(); + document.execCommand('copy'); + document.body.removeChild(dummy); + return false; + } +} + +function generateQRPage() { + var pass = sanitizePassword(getById("invite_password").value); + if (pass.length) { + return session.generateHash(pass + session.salt, 4).then(function(hash) { + generateQRPageCallback(hash); + }); + } else { + generateQRPageCallback(""); + } +} + +function updateLinkWebP(arg, input) { + if (input.checked){ + if (!((getById("director_block_" + arg).dataset.raw.includes("&broadcast")) || (getById("director_block_" + arg).dataset.raw.includes("?broadcast")))){ + getById("broadcastSlider").checked=true; + updateLink(arg, getById("broadcastSlider")); + } + } + updateLink(arg, input); +} + +function updateLink(arg, input) { + log("updateLink"); + log(input.dataset.param); + if (input.checked) { + + getById("director_block_" + arg).dataset.raw += input.dataset.param; + + var string = getById("director_block_" + arg).dataset.raw; + + if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { + string = obfuscateURL(string); + } + + getById("director_block_" + arg).href = string; + getById("director_block_" + arg).innerText = string; + } else { + var string = getById("director_block_" + arg).dataset.raw + "&"; + string = string.replace(input.dataset.param + "&", "&"); + string = string.substring(0, string.length - 1); + getById("director_block_" + arg).dataset.raw = string; + + if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { + string = obfuscateURL(string); + } + + getById("director_block_" + arg).href = string; + getById("director_block_" + arg).innerText = string; + } + saveDirectorSettings(); +} + + +function updateLinkInverse(arg, input) { + log("updateLinkInverse"); + log(input.dataset.param); + if (!(input.checked)) { + + getById("director_block_" + arg).dataset.raw += input.dataset.param; + + var string = getById("director_block_" + arg).dataset.raw; + + if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { + string = obfuscateURL(string); + } + + + getById("director_block_" + arg).href = string; + getById("director_block_" + arg).innerText = string; + } else { + var string = getById("director_block_" + arg).dataset.raw + "&"; + string = string.replace(input.dataset.param + "&", "&"); + string = string.substring(0, string.length - 1); + getById("director_block_" + arg).dataset.raw = string; + + if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { + string = obfuscateURL(string); + } + + getById("director_block_" + arg).href = string; + getById("director_block_" + arg).innerText = string; + } +} + +function updateLinkScene(arg, input) { + log("updateLinkScene"); + var string = getById("director_block_" + arg).dataset.raw; + + if (input.checked) { + string = changeParam(string, "scene", "0"); + } else { + string = changeParam(string, "scene", "1"); + } + getById("director_block_" + arg).dataset.raw = string; + + if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { + string = obfuscateURL(string); + } + + getById("director_block_" + arg).href = string; + getById("director_block_" + arg).innerText = string; +} + +function resetGen() { + getById("gencontent").style.display = "block"; + getById("gencontent2").style.display = "none"; + getById("gencontent2").className = ""; //container-inner + getById("gencontent").className = "container-inner"; // + getById("gencontent2").innerHTML = ""; + getById("videoname4").focus(); +} + +function generateQRPageCallback(hash) { + try { + var title = getById("videoname4").value; + if (title.length) { + title = title.replace(/[\W]+/g, "_").replace(/_+/g, '_'); // but not what others might get. + title = "&label=" + title; + } + var sid = session.generateStreamID(); + + var viewstr = ""; + var sendstr = ""; + + if (getById("invite_bitrate").checked) { + viewstr += "&bitrate=20000"; + } + if (getById("invite_vp9").checked) { + viewstr += "&codec=vp9"; + } + if (getById("invite_stereo").checked) { + viewstr += "&stereo"; + sendstr += "&stereo"; + } + if (getById("invite_automic").checked) { + sendstr += "&audiodevice=1"; + } + if (getById("invite_hidescreen").checked) { + sendstr += "&webcam"; + } + + if (getById("invite_remotecontrol").checked) { // + var remote_gen_id = session.generateStreamID(); + sendstr += "&remote=" + remote_gen_id; // security + viewstr += "&remote=" + remote_gen_id; + } + + if (getById("invite_joinroom").value.trim().length) { + sendstr += "&room=" + getById("invite_joinroom").value.trim(); + viewstr += "&scene&room=" + getById("invite_joinroom").value.trim(); + } + + if (getById("invite_password").value.trim().length) { + sendstr += "&hash=" + hash; + viewstr += "&password=" + getById("invite_password").value.trim(); + } + + + if (getById("invite_group_chat_type").value) { // 0 is default + if (getById("invite_group_chat_type").value == 1) { // no video + sendstr += "&novideo"; + } else if (getById("invite_group_chat_type").value == 2) { // no view or audio + sendstr += "&view"; + } + } + + if (getById("invite_quality").value) { + if (getById("invite_quality").value == 0) { + sendstr += "&quality=0"; + } else if (getById("invite_quality").value == 1) { + sendstr += "&quality=1"; + } else if (getById("invite_quality").value == 2) { + sendstr += "&quality=2"; + } + } + + var pie = ""; + if (session.pie){ + if (session.pie!==true){ + pie = "&pie="+session.pie; + } + } + + sendstr = 'https://' + location.host + location.pathname + '?push=' + sid + sendstr + title + pie; + + if (getById("invite_obfuscate").checked) { + sendstr = obfuscateURL(sendstr); + } + + viewstr = 'https://' + location.host + location.pathname + '?view=' + sid + viewstr + title + pie; + getById("gencontent").style.display = "none"; + getById("gencontent").className = ""; // + getById("gencontent2").style.display = "block"; + getById("gencontent2").className = "container-inner"; // + getById("gencontent2").innerHTML = '
\ +

Guest Invite Link:

\ + ' + sendstr + '

\ +

and don\'t forget the

OBS Browser Source Link:

' + viewstr + ' \ +

\ + This invite link and OBS ingestion link are reusable. Only one person may use a specific invite at a time.

'; + var qrcode = new QRCode(getById("qrcode"), { + width: 300 + , height: 300 + , colorDark: "#000000" + , colorLight: "#FFFFFF" + , useSVG: false + }); + qrcode.makeCode(sendstr); + setTimeout(function() { + getById("qrcode").title = ""; + if (getById("qrcode").getElementsByTagName('img').length) { + getById("qrcode").getElementsByTagName('img')[0].style.cursor = "none"; + } + }, 100); // i really hate the title overlay that the qrcode function makes + + } catch (e) { + errorlog(e); + } +} + + +function initSceneList(UUID){ + Object.keys(session.sceneList).forEach((scene, index) => { + if (getById("container_" + UUID).querySelectorAll('[data-scene="'+scene+'"]').length){return;} // already exists. + var newScene = document.createElement("div"); + newScene.innerHTML = ''; + getById("container_" + UUID).appendChild(newScene); + }); +} + +function updateSceneList(scene){ + if (!session.director){return;} + if (scene in session.sceneList){return;} + if ((parseInt(scene)+"")===scene){ + if ((parseInt(scene)>=0) && (parseInt(scene)<=8)){ + return; + } + } + session.sceneList[scene] = true; + for (var UUID in session.rpcs){ + var newScene = document.createElement("span"); + newScene.innerHTML = ''; + getById("container_" + UUID).appendChild(newScene); + } + + if (session.showDirector){ + if (document.getElementById("container_director")){ + var newScene = document.createElement("div"); + newScene.innerHTML = ''; + getById("container_director").appendChild(newScene); + } + } +} + +function safariVersion() { + try { + var ver = navigator.appVersion.split("Version/"); + if (ver.length > 1) { + ver = ver[1].split(" Safari"); + } + if (ver.length > 1) { + ver = ver[0].split("."); + } + if (ver.length > 1) { + ver = parseInt(ver[0]); + } else { + ver = 0; + } + } catch (e) { + return 0; + } + return ver; +} + + +var vis = (function() { + var stateKey, eventKey, keys = { + hidden: "visibilitychange" + , webkitHidden: "webkitvisibilitychange" + , mozHidden: "mozvisibilitychange" + , msHidden: "msvisibilitychange" + }; + for (stateKey in keys) { + if (stateKey in document) { + eventKey = keys[stateKey]; + break; + } + } + return function(c) { + if (c) { + document.addEventListener(eventKey, c); + //document.addEventListener("blur", c); + //document.addEventListener("focus", c); + } + return !document[stateKey]; + }; +})(); + +(function rightclickmenuthing() { // right click menu + "use strict"; + + function clickInsideElement(e, className) { + var el = e.srcElement || e.target; + + if (el.classList.contains(className)) { + return el; + } else { + while (el = el.parentNode) { + if (el.classList && el.classList.contains(className)) { + return el; + } + } + } + + return false; + } + + function getPosition(event2) { + var posx = 0; + var posy = 0; + + if (!event2) var event = window.event; + + if (event2.pageX || event2.pageY) { + posx = event2.pageX; + posy = event2.pageY; + } else if (event2.clientX || event2.clientY) { + posx = event2.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + posy = event2.clientY + document.body.scrollTop + document.documentElement.scrollTop; + } + + return { + x: posx + , y: posy + }; + } + var contextMenuClassName = "context-menu"; + var contextMenuItemClassName = "context-menu__item"; + var contextMenuLinkClassName = "context-menu__link"; + var contextMenuActive = "context-menu--active"; + + var taskItemClassName = "task"; + var taskItemInContext; + + var clickCoords; + var clickCoordsX; + var clickCoordsY; + + var menu = getById("context-menu"); + var menuItems = menu.querySelectorAll(".context-menu__item"); + var menuState = 0; + var menuWidth; + var menuHeight; + var menuPosition; + var menuPositionX; + var menuPositionY; + + var windowWidth; + var windowHeight; + + function init() { + contextListener(); + clickListener(); + keyupListener(); + resizeListener(); + } + + function contextListener() { + document.addEventListener("contextmenu", function(e) { + taskItemInContext = clickInsideElement(e, taskItemClassName); + + if (taskItemInContext) { + e.preventDefault(); + toggleMenuOn(); + positionMenu(e); + } else { + taskItemInContext = null; + toggleMenuOff(); + } + }); + } + + function clickListener() { + document.addEventListener("click", function(e) { + var clickeElIsLink = clickInsideElement(e, contextMenuLinkClassName); + + if (clickeElIsLink) { + e.preventDefault(); + menuItemListener(clickeElIsLink); + } else { + var button = e.which || e.button; + if (button === 1) { + toggleMenuOff(); + } + } + }); + } + + function keyupListener() { + window.onkeyup = function(e) { + // if ( e.keyCode === 27 ) { + // toggleMenuOff(); + // } + if (e.altKey && e.shiftKey && e.keyCode === 67 /* C */) { + toggleControlBar(); + } + }; + } + + function resizeListener() { + //window.onresize = function(e) { + // toggleMenuOff(); + // }; + } + + function toggleMenuOn() { + if (menuState !== 1) { + menuState = 1; + menu.classList.add(contextMenuActive); + } + } + + function toggleMenuOff() { + if (menuState !== 0) { + menuState = 0; + menu.classList.remove(contextMenuActive); + } + } + + function toggleControlBar() { + if (getById("controlButtons").style.display != 'none') { + // Dont hardcode style here. Copy it over to data-style before changing to none; + getById("controlButtons").dataset.style = getById("controlButtons").style.display; + getById("controlButtons").style.display = 'none'; + } else { + // Copy the style over from the data-style attribute. + getById("controlButtons").style.display = getById("controlButtons").dataset.style; + }; + } + + function positionMenu(e) { + clickCoords = getPosition(e); + clickCoordsX = clickCoords.x; + clickCoordsY = clickCoords.y; + + menuWidth = menu.offsetWidth + 4; + menuHeight = menu.offsetHeight + 4; + + windowWidth = window.innerWidth; + windowHeight = window.innerHeight; + + if ((windowWidth - clickCoordsX) < menuWidth) { + menu.style.left = windowWidth - menuWidth + "px"; + } else { + menu.style.left = clickCoordsX + "px"; + } + + if ((windowHeight - clickCoordsY) < menuHeight) { + menu.style.top = windowHeight - menuHeight + "px"; + } else { + menu.style.top = clickCoordsY + "px"; + } + } + + function menuItemListener(link) { + if (link.getAttribute("data-action") == "Open") { + window.open(taskItemInContext.value); + } else { + // nothing needed + } + log("Task ID - " + taskItemInContext + ", Task action - " + link.getAttribute("data-action")); + toggleMenuOff(); + } + + init(); + +})(); + +function popupMessage(e, message = "Copied to Clipboard") { // right click menu + + var posx = 0; + var posy = 0; + + if (!e) var e = window.event; + + if (e.pageX || e.pageY) { + posx = e.pageX; + posy = e.pageY; + } else if (e.clientX || e.clientY) { + posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; + } + + posx += 10; + + + var menu = getById("messagePopup"); + menu.innerHTML = "
" + message + "
"; + var menuState = 0; + var menuWidth; + var menuHeight; + var menuPosition; + var menuPositionX; + var menuPositionY; + + var windowWidth; + var windowHeight; + + if (menuState !== 1) { + menuState = 1; + menu.classList.add("context-menu--active"); + } + + menuWidth = menu.offsetWidth + 4; + menuHeight = menu.offsetHeight + 4; + + windowWidth = window.innerWidth; + windowHeight = window.innerHeight; + + if ((windowWidth - posx) < menuWidth) { + menu.style.left = windowWidth - menuWidth + "px"; + } else { + menu.style.left = posx + "px"; + } + + if ((windowHeight - posy) < menuHeight) { + menu.style.top = windowHeight - menuHeight + "px"; + } else { + menu.style.top = posy + "px"; + } + + function toggleMenuOff() { + if (menuState !== 0) { + menuState = 0; + menu.classList.remove("context-menu--active"); + } + } + setTimeout(function() { + toggleMenuOff(); + }, 1000); + event.preventDefault(); +} + +function timeSince(date) { + + var seconds = Math.floor((new Date() - date) / 1000); + + var interval = seconds / 31536000; + + if (interval > 1) { + return Math.floor(interval) + " years"; + } + interval = seconds / 2592000; + if (interval > 1) { + return Math.floor(interval) + " months"; + } + interval = seconds / 86400; + if (interval > 1) { + return Math.floor(interval) + " days"; + } + interval = seconds / 3600; + if (interval > 1) { + return Math.floor(interval) + " hours"; + } + interval = seconds / 60; + if (interval > 1) { + return Math.floor(interval) + " minutes"; + } + return "Seconds ago"; +} + +var messageList = [] +function sendChatMessage(chatMsg = false) { // filtered + visual + var data = {}; + if (chatMsg === false) { + var msg = document.getElementById('chatInput').value; + } else { + var msg = chatMsg; + } + //msg = sanitizeChat(msg); + if (msg == "") { + return; + } + + msg = convertShortcodes(msg); + + if (msg.trim()==="/list"){ + var listMsg = null; + for (var UUID in session.rpcs){ + if (session.rpcs[UUID].label){ + listMsg = UUID+": "+session.rpcs[UUID].label + } else if (session.directorUUID === UUID){ + listMsg = UUID+": Director"; + } else { + listMsg = UUID+": Unknown User"; + } + var data = {}; + data.msg = listMsg; + data.label = false; + data.type = "alert"; + data.time = Date.now(); + messageList.push(data); + } + for (var UUID in session.pcs){ + if (UUID in session.rpcs){continue;} + if (session.pcs[UUID].label){ + listMsg = UUID+"; "+session.pcs[UUID].label + } else if (session.directorUUID === UUID){ + listMsg = UUID+"; Director"; + } else { + listMsg = UUID+"; Unknown User"; + } + var data = {}; + data.msg = listMsg; + data.label = false; + data.type = "alert"; + data.time = Date.now(); + messageList.push(data); + } + if (listMsg===null){ + data.msg = "No other users are connected to you"; + data.label = false; + data.type = "alert"; + data.time = Date.now(); + messageList.push(data); + } + } else if (msg.startsWith("\/msg ")){ + var msg = msg.split("\/msg ")[1]; + msg = msg.split(" "); + uid = msg.shift().toLowerCase(); + msg = msg.join(" "); + if (msg == ""){return;} + var sent = false; + for (var UUID in session.rpcs){ + if (UUID.startsWith(uid)){ + sendChat(msg, UUID); // send message to peers + var data = {}; + data.time = Date.now(); + data.msg = sanitizeChat(msg); // this is what the other person should see + data.label = false; + data.type = "sent"; + messageList.push(data); + sent=true; + } else if (session.rpcs[UUID].label && session.rpcs[UUID].label.toLowerCase().startsWith(uid)){ + sendChat(msg, UUID); // send message to peers + var data = {}; + data.time = Date.now(); + data.msg = sanitizeChat(msg); // this is what the other person should see + data.label = false; + data.type = "sent"; + messageList.push(data); + sent=true; + } else if ((session.directorUUID === UUID) && "director".startsWith(uid)){ + sendChat(msg, UUID); // send message to peers + var data = {}; + data.time = Date.now(); + data.msg = sanitizeChat(msg); // this is what the other person should see + data.label = false; + data.type = "sent"; + messageList.push(data); + sent=true; + } + } + for (var UUID in session.pcs){ + if (UUID in session.rpcs){continue;} + if (UUID.startsWith(uid)){ + sendChat(msg, UUID); // send message to peers + var data = {}; + data.time = Date.now(); + data.msg = sanitizeChat(msg); // this is what the other person should see + data.label = false; + data.type = "sent"; + messageList.push(data); + sent=true; + } else if (session.pcs[UUID].label && session.pcs[UUID].label.toLowerCase().startsWith(uid)){ + sendChat(msg, UUID); // send message to peers + var data = {}; + data.time = Date.now(); + data.msg = sanitizeChat(msg); // this is what the other person should see + data.label = false; + data.type = "sent"; + messageList.push(data); + sent=true; + } else if ((session.directorUUID === UUID) && "director".startsWith(uid)){ + sendChat(msg, UUID); // send message to peers + var data = {}; + data.time = Date.now(); + data.msg = sanitizeChat(msg); // this is what the other person should see + data.label = false; + data.type = "sent"; + messageList.push(data); + sent=true; + } + } + if (sent == false){ + var data = {}; + data.msg = "No user found. Message not sent."; + data.label = false; + data.type = "alert"; + data.time = Date.now(); + messageList.push(data); + updateMessages(); + return; + } + } else if (msg.startsWith("\/")){ + data.msg = "Unknown command. Try '/list' or '/msg username message'."; + data.label = false; + data.type = "alert"; + data.time = Date.now(); + messageList.push(data); + updateMessages(); + return; + } else if (session.directorChat===true){ + if (session.directorUUID){ + sendChat(msg, session.directorUUID); // send message to peers + var data = {}; + data.time = Date.now(); + data.msg = sanitizeChat(msg); // this is what the other person should see + data.label = false; + data.type = "sent"; + messageList.push(data); + } + } else { + sendChat(msg); // send message to peers + data.time = Date.now(); + data.msg = sanitizeChat(msg); // this is what the other person should see + data.label = false; + data.type = "sent"; + messageList.push(data); + } + document.getElementById('chatInput').value = ""; + + messageList = messageList.slice(-100); + if (session.broadcastChannel !== false) { + log(session.broadcastChannel); + session.broadcastChannel.postMessage(data); + } + updateMessages(); +} + +function toggleQualityDirector(bitrate, UUID, ele = null) { // ele is specific to the button in the director's room + var eles = ele.parentNode.childNodes; + for (var i=0;i "; + } else { + data.label = "" + data.label + ": "; + } + label = label+":"; + } else if (director) { + data.label = "Director: "; + label = "Director:"; + } else { + if (session.director){ + data.label = "Someone: "; + } else { + data.label = ""; + } + label = ""; + } + data.type = "recv"; + + if (overlay) { + if (!(session.cleanOutput && session.cleanish==false)){ + var textOverlay = getById("overlayMsgs"); + if (textOverlay) { + var spanOverlay = document.createElement("span"); + spanOverlay.innerHTML = "" + label + " " + msg + "
"; + textOverlay.appendChild(spanOverlay); + textOverlay.style.display = "block"; + var showtime = msg.length * 200 + 3000; + if (showtime > 8000) { + showtime = 8000; + } + setTimeout(function(ele) { + ele.parentNode.removeChild(ele); + }, showtime, spanOverlay); + } + } + } + + if (isIFrame) { + parent.postMessage({ + "gotChat": data + }, "*"); + } + + if (session.chatbutton===false){return;} // messages can still appear as overlays ^ + + messageList.push(data); + messageList = messageList.slice(-100); + + if (session.beepToNotify) { + playtone(); + } + updateMessages(); + + if (session.chat == false) { + getById("chattoggle").className = "las la-comments my-float toggleSize puslate"; + getById("chatbutton").className = "float"; + + if (getById("chatNotification").value) { + getById("chatNotification").value = getById("chatNotification").value + 1; + } else { + getById("chatNotification").value = 1; + } + getById("chatNotification").classList.add("notification"); + + } + + + if (session.broadcastChannel !== false) { + session.broadcastChannel.postMessage(data); /* send */ + } + +} + +function updateClosedCaptions(msg, label, UUID) { + msg.counter = parseInt(msg.counter); + var transcript = sanitizeChat(msg.transcript); // keep it clean. + if (transcript == "") { + return; + } + transcript = transcript.toUpperCase(); + + if (label) { + label = sanitizeLabel(label); + label = "" + label + ": "; + } else { + label = ""; + } + + var textOverlay = getById("overlayMsgs"); + if (textOverlay) { + if (document.getElementById(UUID + "_" + msg.counter)) { + var spanOverlay = document.getElementById(UUID + "_" + msg.counter); + } else { + var spanOverlay = document.createElement("span"); + spanOverlay.id = UUID + "_" + msg.counter; + textOverlay.appendChild(spanOverlay); + textOverlay.style.height = "unset"; + textOverlay.style.textAlign = "left"; + textOverlay.style.display = "block"; + textOverlay.style.position = "fixed"; + textOverlay.style.bottom = "0"; + + } + spanOverlay.innerHTML = label + transcript + "
"; + spanOverlay.style.fontSize = (parseInt(session.labelsize || 100) / 100.0 * 4.5) + "vh"; + spanOverlay.style.lineHeight = (parseInt(session.labelsize || 100) / 100 * 6) + "vh"; + spanOverlay.style.margin = (parseInt(session.labelsize || 100) / 100.0 * 0.75) + "vh"; + + if (msg.isFinal) { + var showtime = 3000; + clearTimeout(spanOverlay.timeout); + spanOverlay.timeout = setTimeout(function(ele) { + ele.parentNode.removeChild(ele); + }, showtime, spanOverlay); + } else { + clearTimeout(spanOverlay.timeout); + spanOverlay.timeout = setTimeout(function(ele) { + ele.parentNode.removeChild(ele); + }, 30000, spanOverlay); + } + + } +} + +var chatUpdateTimeout = null; +function updateMessages() { + if (session.chatbutton===false){return;} + document.getElementById("chatBody").innerHTML = ""; + for (i in messageList) { + + var time = timeSince(messageList[i].time) || ""; + var msg = document.createElement("div"); + //console.log(messageList[i].msg); // Display received messages for View-Only clients. + ///////////////////////////// + if (messageList[i].type == "sent") { + msg.innerHTML = messageList[i].msg + " - " + time + ""; + msg.classList.add("outMessage"); + } else if (messageList[i].type == "recv") { + var label = ""; + if (messageList[i].label) { + label = messageList[i].label; + } + msg.innerHTML = label + messageList[i].msg + " - " + time + ""; + msg.classList.add("inMessage"); + } else if (messageList[i].type == "alert") { + msg.innerHTML = messageList[i].msg + " - " + time + ""; + msg.classList.add("inMessage"); + } else { + msg.innerHTML = messageList[i].msg; + msg.classList.add("outMessage"); + } + + document.getElementById("chatBody").appendChild(msg); + } + if (chatUpdateTimeout) { + clearInterval(chatUpdateTimeout); + } + document.getElementById("chatBody").scrollTop = document.getElementById("chatBody").scrollHeight; + chatUpdateTimeout = setTimeout(function() { + updateMessages(); + }, 60000); +} + +function EnterButtonChat(event) { + // Number 13 is the "Enter" key on the keyboard + var key = event.which || event.keyCode; + if (key === 13) { + // Cancel the default action, if needed + event.preventDefault(); + // Trigger the button element with a click + sendChatMessage(); + } +} + +function showCustomizer(arg, ele) { + //getById("directorLinksButton").innerHTML=' LINKS (GUEST INVITES & SCENES)' + getById("showCustomizerButton1").style.backgroundColor = ""; + getById("showCustomizerButton2").style.backgroundColor = ""; + getById("showCustomizerButton3").style.backgroundColor = ""; + getById("showCustomizerButton4").style.backgroundColor = ""; + getById("showCustomizerButton1").style.boxShadow = ""; + getById("showCustomizerButton2").style.boxShadow = ""; + getById("showCustomizerButton3").style.boxShadow = ""; + getById("showCustomizerButton4").style.boxShadow = ""; + + + if (getById("customizeLinks" + arg).style.display != "none") { + getById("customizeLinks").style.display = "none"; + getById("customizeLinks" + arg).style.display = "none"; + } else { + //directorLinks").style.display="none"; + getById("showCustomizerButton" + arg).style.backgroundColor = "#1e0000"; + getById("showCustomizerButton" + arg).style.boxShadow = "inset 0px 0px 1px #b90000"; + getById("customizeLinks1").style.display = "none"; + getById("customizeLinks3").style.display = "none"; + getById("customizeLinks").style.display = "block"; + getById("customizeLinks" + arg).style.display = "block"; + } +} + + +var defaultRecordingBitrate = false; + +function recordVideo(target, event, videoKbps = false) { // event.currentTarget,this.parentNode.parentNode.dataset.UUID + + var UUID = target.dataset.UUID; + var video = session.rpcs[UUID].videoElement; + var audioKbps = false; + + if (event === null) { + if (defaultRecordingBitrate === null) { + updateLocalRecordButton(UUID, -1); + //target.style.backgroundColor = null; + //target.innerHTML = ' record local'; + return; + } + } else if ((event.ctrlKey) || (event.metaKey)) { + updateLocalRecordButton(UUID, -3); + //target.innerHTML = ' ARMED'; + //target.style.backgroundColor = "#BF3F3F"; + Callbacks.push([recordVideo, target, null, false]); + log("Record Video queued"); + defaultRecordingBitrate = false; + return; + } else { + defaultRecordingBitrate = false; + } + + log("Record Video Clicked"); + if ("recording" in video) { + log("ALREADY RECORDING!"); + //target.style.backgroundColor = null; + //target.innerHTML = ' record local'; + updateLocalRecordButton(UUID, -2); + video.recorder.stop(); + session.requestRateLimit(35, UUID); // 100kbps + if (session.audiobitrate===false){ + session.requestAudioRateLimit(-1,UUID); + } + + var elements = document.querySelectorAll('[data-action-type="change-quality2"][data--u-u-i-d="' + UUID + '"]'); + if (elements[0]) { + elements[0].classList.add("pressed"); + } + var elements = document.querySelectorAll('[data-action-type="change-quality1"][data--u-u-i-d="' + UUID + '"]'); + if (elements[0]) { + elements[0].classList.remove("pressed"); + } + var elements = document.querySelectorAll('[data-action-type="change-quality3"][data--u-u-i-d="' + UUID + '"]'); + if (elements[0]) { + elements[0].classList.remove("pressed"); + } + return; + } else { + updateLocalRecordButton(UUID, 0); + //target.style.backgroundColor = "#FCC"; + //target.innerHTML = " Download"; + video.recording = true; + } + + video.recorder = {}; + + if (videoKbps == false) { + if (defaultRecordingBitrate == false) { + videoKbps = 4000; // 4mbps recording bitrate + window.focus(); + videoKbps = prompt("Press OK to start recording. Press again to stop and download.\n\nWarning: Keep this browser tab active to continue recording.\n\nYou can change the default video bitrate if desired below (kbps)", videoKbps); + if (videoKbps === null) { + //target.style.backgroundColor = null; + //target.innerHTML = ' record local'; + updateLocalRecordButton(UUID, -1); + target.style.backgroundColor = ""; + delete(video.recorder); + delete(video.recording); + defaultRecordingBitrate = null; + return; + } + videoKbps = parseInt(videoKbps); + defaultRecordingBitrate = videoKbps; + } else { + videoKbps = defaultRecordingBitrate; + } + } + + if (videoKbps <= 0) { + audioKbps = videoKbps * (-1); + videoKbps = false; + if (session.audiobitrate===false){ + if ((audioKbps>0) && (audioKbps>=128)){ + session.requestAudioRateLimit(128,UUID); // no point going higher + } else if (audioKbps==0){ + session.requestAudioRateLimit(256,UUID); // PCM + } else { + session.requestAudioRateLimit(parseInt(audioKbps),UUID); // exact? sure. why not. + } + } + } else if (videoKbps < 50) { // this just makes sure you can't set 0 on the record bitrate. + videoKbps = 50; + session.requestRateLimit(parseInt(videoKbps * 0.8), UUID); // 3200kbps transfer bitrate. Less than the recording bitrate, to avoid waste. + } else { + session.requestRateLimit(parseInt(videoKbps * 0.8), UUID); // 3200kbps transfer bitrate. Less than the recording bitrate, to avoid waste. + + if (videoKbps>4000){ + if (session.audiobitrate===false){ + if (session.pcm){ + session.requestAudioRateLimit(256,UUID); + } else { + session.requestAudioRateLimit(128,UUID); + } + } + } else if (videoKbps>2500){ + if (session.audiobitrate===false){ + if (session.pcm){ + session.requestAudioRateLimit(256,UUID); + } else { + session.requestAudioRateLimit(80,UUID); + } + } + } + + } + + var timestamp = Date.now(); + var filename = ""; + if (session.rpcs[UUID].label || session.rpcs[UUID].streamID) { + filename = session.rpcs[UUID].label || session.rpcs[UUID].streamID; + filename = filename.replace(/[\W]+/g, "_"); + filename = filename.substring(0, 200); + } + + filename += "_" + timestamp.toString(); + + var cancell = false; + if (typeof video.srcObject === "undefined" || !video.srcObject) { + return; + } + + const {readable, writable} = new TransformStream({ + transform: (chunk, ctrl) => chunk.arrayBuffer().then(b => ctrl.enqueue(new Uint8Array(b))) + }); + readable.pipeTo(streamSaver.createWriteStream(filename + '.webm')); + var writer = writable.getWriter(); + video.recorder.writer = writer; + video.recorder.stop = function() { + if (!video.recording) { + errorlog("ALREADY STOPPED"); + updateLocalRecordButton(UUID, -1); + return; + } + video.recording = false; + updateLocalRecordButton(UUID, -2); + try { + if (video.recorder.mediaRecorder.state !== "inactive") { + video.recorder.mediaRecorder.stop(); + } + } catch (e) { + errorlog(e); + } + + session.requestRateLimit(35, UUID); // 100kbps + if (session.audiobitrate===false){ + session.requestAudioRateLimit(-1,UUID); + } + var elements = document.querySelectorAll('[data-action-type="change-quality2"][data--u-u-i-d="' + UUID + '"]'); + if (elements[0]) { + elements[0].classList.add("pressed"); + } + var elements = document.querySelectorAll('[data-action-type="change-quality1"][data--u-u-i-d="' + UUID + '"]'); + if (elements[0]) { + elements[0].classList.remove("pressed"); + } + var elements = document.querySelectorAll('[data-action-type="change-quality3"][data--u-u-i-d="' + UUID + '"]'); + if (elements[0]) { + elements[0].classList.remove("pressed"); + } + + cancell = true; + // log('Recorded Blobs: ', recordedBlobs); + // download(); + setTimeout(() => { + writer.close(); + updateLocalRecordButton(UUID, -1); + delete(video.recorder); + delete(video.recording); + }, 1200); + }; + + let options = {}; + + if (videoKbps) { + options.mimeType = "video/webm"; + if (session.pcm){ + options.mimeType += ";codecs=pcm"; + } + if (videoKbps < 1000) { + options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio + } else { + options.bitsPerSecond = parseInt(videoKbps * 1024); // 100 to 132 kbps audio + } + video.recorder.mediaRecorder = new MediaRecorder(video.srcObject, options); + } else { + options.mimeType = "audio/webm"; + if (audioKbps == 0) { + if (MediaRecorder.isTypeSupported("audio/webm;codecs=pcm")) { + options.mimeType = "audio/webm;codecs=pcm"; + } + } else { + options.bitsPerSecond = parseInt(audioKbps * 1024); + } + var stream = new MediaStream(); + video.srcObject.getAudioTracks().forEach((track) => { + stream.addTrack(track, video.srcObject); + }); + video.recorder.mediaRecorder = new MediaRecorder(stream, options); + } + log(options); + + function download() { + const blob = new Blob(recordedBlobs, { + type: "video/webm" + }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.style.display = 'none'; + a.href = url; + a.download = filename + ".webm"; + document.body.appendChild(a); + a.click(); + setTimeout(() => { + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }, 100); + } + + function handleDataAvailable(event) { + if (event.data && event.data.size > 0) { + //recordedBlobs.push(event.data); + writer.write(event.data); //////////// + if (video.recording) { + updateLocalRecordButton(UUID, (parseInt((Date.now() - timestamp) / 1000) || 0)); + } + } + } + + video.recorder.mediaRecorder.ondataavailable = handleDataAvailable; + + video.recorder.mediaRecorder.onerror = function(event) { + errorlog(event); + video.recorder.stop(); + session.requestRateLimit(35, UUID); + if (!(session.cleanOutput)) { + setTimeout(function() { + warnUser("an error occured with the media recorder; stopping recording"); + }, 1); + } + }; + + video.srcObject.ended = function(event) { + video.recorder.stop(); + session.requestRateLimit(35, UUID); + if (!(session.cleanOutput)) { + setTimeout(function() { + warnUser("stream ended! stopping recording"); + }, 1); + } + }; + + + setTimeout(function(v) { + v.recorder.mediaRecorder.start(1000); + }, 500, video); // 100ms chunks + + return; +} + +function updateRemoteRecordButton(UUID, recorder) { + var elements = document.querySelectorAll('[data-action-type="recorder-remote"][data--u-u-i-d="' + UUID + '"]'); + if (elements[0]) { + var time = parseInt(recorder) || 0; + if (time == -3) { + elements[0].classList.remove("pressed"); + elements[0].disabled = true; + elements[0].innerHTML = ' Not Supported'; + if (!(session.cleanOutput)) { + setTimeout(function() { + warnUser('The remote browser does not support recording.\n\nPerhaps try local recording instead.'); + }, 0); + } + + } else if (time == -2) { + elements[0].classList.add("pressed"); + elements[0].innerHTML = ' stopping...'; + } else if (time == -1) { + elements[0].classList.remove("pressed"); + elements[0].innerHTML = ' Record Remote'; + } else { + var minutes = Math.floor(time / 60); + var seconds = time - minutes * 60; + elements[0].classList.add("pressed"); + elements[0].innerHTML = ' ' + minutes + "m : " + (seconds + "").padStart(2, '0') + "s"; + } + } +} + +function updateLocalRecordButton(UUID, recorder) { + var elements = document.querySelectorAll('[data-action-type="recorder-local"][data--u-u-i-d="' + UUID + '"]'); + if (elements[0]) { + var time = parseInt(recorder) || 0; + + //target.innerHTML = ' ARMED'; + // + if (time == -3) { + elements[0].classList.add("pressed"); + elements[0].innerHTML = ' ARMED'; + elements[0].style.backgroundColor = "#BF3F3F"; + } else if (time == -2) { + elements[0].classList.add("pressed"); + elements[0].innerHTML = ' stopping...'; + elements[0].style.backgroundColor = ""; + } else if (time == -1) { + elements[0].classList.remove("pressed"); + elements[0].innerHTML = ' Record Local'; + elements[0].style.backgroundColor = ""; + } else { + var minutes = Math.floor(time / 60); + var seconds = time - minutes * 60; + elements[0].classList.add("pressed"); + elements[0].innerHTML = ' ' + minutes + "m : " + (seconds + "").padStart(2, '0') + "s"; + elements[0].style.backgroundColor = ""; + } + } +} + +function recordLocalVideoToggle() { + var ele = getById("recordLocalbutton"); + if (ele.dataset.state == "0") { + ele.dataset.state = "1"; + ele.style.backgroundColor = "red"; + ele.innerHTML = ''; + if ("recording" in session.videoElement) { + + } else { + recordLocalVideo("start"); + } + + if (session.director){ + var elements = document.querySelectorAll('[data-action-type="recorder-local"][data-sid="' + session.streamID + '"]'); + if (elements[0]) { + elements[0].classList.add("pressed"); + elements[0].innerHTML = ' Record'; + } + } + + } else { + if ("recording" in session.videoElement) { + recordLocalVideo("stop"); + } + ele.dataset.state = "0"; + ele.style.backgroundColor = ""; + ele.innerHTML = ''; + + if (session.director){ + var elements = document.querySelectorAll('[data-action-type="recorder-local"][data-sid="' + session.streamID + '"]'); + if (elements[0]) { + elements[0].classList.remove("pressed"); + elements[0].innerHTML = ' Record'; + } + } + } + +} + +function setupSensorData(pollrate = 30) { + session.sensors = {}; + session.sensors.data = {}; + session.sensors.data.sensors = true; + + if (window.Accelerometer) { + session.sensors.data.acc = {}; + session.sensors.Accelerometer = new Accelerometer({ + frequency: pollrate + }); + session.sensors.Accelerometer.addEventListener('reading', e => { + session.sensors.data.acc.x = session.sensors.Accelerometer.x; + session.sensors.data.acc.y = session.sensors.Accelerometer.y; + session.sensors.data.acc.z = session.sensors.Accelerometer.z; + session.sensors.data.acc.t = parseInt(Math.round(session.sensors.Accelerometer.timestamp)); + }); + session.sensors.Accelerometer.start(); + } + if (window.Gyroscope) { + session.sensors.data.gyro = {}; + session.sensors.Gyroscope = new Gyroscope({ + frequency: pollrate + }); + session.sensors.Gyroscope.addEventListener('reading', e => { + session.sensors.data.gyro.x = session.sensors.Gyroscope.x; + session.sensors.data.gyro.y = session.sensors.Gyroscope.y; + session.sensors.data.gyro.z = session.sensors.Gyroscope.z; + session.sensors.data.gyro.t = parseInt(Math.round(session.sensors.Gyroscope.timestamp)); + }); + session.sensors.Gyroscope.start(); + } + if (window.Magnetometer) { + session.sensors.data.mag = {}; + session.sensors.Magnetometer = new Magnetometer({ + frequency: pollrate + }); + session.sensors.Magnetometer.addEventListener('reading', e => { + session.sensors.data.mag.x = session.sensors.Magnetometer.x; + session.sensors.data.mag.y = session.sensors.Magnetometer.y; + session.sensors.data.mag.z = session.sensors.Magnetometer.z; + session.sensors.data.mag.t = parseInt(Math.round(session.sensors.Magnetometer.timestamp)); + + }); + session.sensors.Magnetometer.start(); + } + if (window.LinearAccelerationSensor) { + session.sensors.data.lin = {}; + session.sensors.LinearAccelerationSensor = new LinearAccelerationSensor({ + frequency: pollrate + }); + session.sensors.LinearAccelerationSensor.addEventListener('reading', e => { + session.sensors.data.lin.x = session.sensors.LinearAccelerationSensor.x; + session.sensors.data.lin.y = session.sensors.LinearAccelerationSensor.y; + session.sensors.data.lin.z = session.sensors.LinearAccelerationSensor.z; + session.sensors.data.lin.t = parseInt(Math.round(session.sensors.LinearAccelerationSensor.timestamp)); + }); + session.sensors.LinearAccelerationSensor.start(); + } + setInterval(function() { + session.sendMessage(session.sensors.data); + }, parseInt(1000 / pollrate)); +} + + +async function chunkedVideoTransfer(videoKbps = 500) { + + var video = session.videoElement; + var recorder = {}; + + var options = {}; + options.mimeType = "video/webm"; + if (videoKbps < 1000) { + options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio + } else { + options.bitsPerSecond = parseInt(videoKbps * 1024); // 100 to 132 kbps audio + } + + recorder.mediaRecorder = new MediaRecorder(video.srcObject, options); + + async function handleDataAvailable(event) { + if (event.data && event.data.size > 0) { + try{ + recorder.mediaRecorder.stop(); + setTimeout(function(){recorder.mediaRecorder.start(500);},500); + } catch(e){ + return; + } + + const arrayBuffer = await event.data.arrayBuffer(); + for (var i in session.pcs){ + session.pcs[i].sendChannel.send(arrayBuffer); + + } + } + + } + + recorder.mediaRecorder.ondataavailable = handleDataAvailable; + + recorder.mediaRecorder.onerror = function(event) { + errorlog(event); + }; + + video.srcObject.ended = function(event) { + errorlog(event); + }; + + recorder.mediaRecorder.start(500); // 100ms chunks + +} + +function recordLocalVideo(action = null, videoKbps = 6000) { // event.currentTarget,this.parentNode.parentNode.dataset.UUID + var audioKbps = false; + var video = session.videoElement; + if ("recording" in video) { + if (action == "stop") { + log("Stopping RECORDING!"); + video.recorder.stop(); + delete(video.recorder); + delete(video.recording); + return; + } else if (action == "start") { + log("ALREADY RECORDING!"); + getById("recordLocalbutton").dataset.state = "1"; + getById("recordLocalbutton").style.backgroundColor = "red"; + getById("recordLocalbutton").innerHTML = ''; + return; + } else { + log("STOPPING RECORDING by default toggle!"); + video.recorder.stop(); + return; + } + return; + } else if (action == "start") { + if (safariVersion()) { + var msg = {}; + msg.UUID = session.directorUUID; + msg.recorder = -3; + session.sendMessage(msg, msg.UUID); + return; + } + video.recording = true; + getById("recordLocalbutton").dataset.state = "1"; + getById("recordLocalbutton").style.backgroundColor = "red"; + getById("recordLocalbutton").innerHTML = ''; + } else if (action == "stop") { + return; + } else { + getById("recordLocalbutton").dataset.state = "1"; + getById("recordLocalbutton").style.backgroundColor = "red"; + getById("recordLocalbutton").innerHTML = ''; + video.recording = true; + } + + video.recorder = {}; + + if (session.recordLocal !== false) { + videoKbps = session.recordLocal; + } + + if (videoKbps <= 0) { + audioKbps = videoKbps * (-1); + videoKbps = false; + } else if (videoKbps < 50) { // this just makes sure you can't set 0 on the record bitrate. + videoKbps = 50; + } + + if (typeof video.srcObject === "undefined" || !video.srcObject) { + return; + } + + const {readable, writable} = new TransformStream({ + transform: (chunk, ctrl) => chunk.arrayBuffer().then(b => ctrl.enqueue(new Uint8Array(b))) + }); + + var timestamp = Date.now(); + var filename = ""; + if (session.label || session.streamID) { + filename = session.label || session.streamID; + filename = filename.replace(/[\W]+/g, "_"); + filename = filename.substring(0, 200); + } + + filename += "_" + timestamp.toString(); + readable.pipeTo(streamSaver.createWriteStream(filename.toString() + '.webm')); + + var writer = writable.getWriter(); + video.recorder.writer = writer; + pokeIframeAPI("recording-started"); + + video.recorder.stop = function(restart = false) { + if (restart) { + if (getById("recordLocalbutton").dataset.state == 2) { + getById("recordLocalbutton").dataset.state = "0"; + getById("recordLocalbutton").style.backgroundColor = ""; + getById("recordLocalbutton").innerHTML = ''; + restart = false; + warnUser("Media Recording Stopped due to an error."); + } else { + getById("recordLocalbutton").innerHTML = ''; + getById("recordLocalbutton").dataset.state = "2"; + } + } else { + getById("recordLocalbutton").dataset.state = "0"; + getById("recordLocalbutton").style.backgroundColor = ""; + getById("recordLocalbutton").innerHTML = ''; + } + if (!video.recording) { + errorlog("ALREADY STOPPED"); + return; + } + video.recording = false; + try { + if (video.recorder.mediaRecorder.state !== "inactive") { + video.recorder.mediaRecorder.stop(); + } + } catch (e) { + errorlog(e); + } + + setTimeout(() => { + writer.close(); + pokeIframeAPI("recording-stopped"); + try { + if (session.directorUUID) { + var msg = {}; + msg.UUID = session.directorUUID; + msg.recorder = -1; + session.sendMessage(msg, msg.UUID); + } + } catch (e) { + errorlog(e); + } + delete(video.recorder); + delete(video.recording); + + if (restart) { + setTimeout(function() { + recordLocalVideo("start", videoKbps); + }, 0); + } + + }, 500); + try { + if (session.directorUUID) { + var msg = {}; + msg.UUID = session.directorUUID; + msg.recorder = -2; + session.sendMessage(msg, msg.UUID); + } + } catch (e) { + errorlog(e); + } + + }; + + let options = {}; + + if (videoKbps) { + options.mimeType = "video/webm"; + if (session.pcm){ + options.mimeType += ";codecs=pcm"; + } + if (videoKbps < 1000) { + options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio + } else { + options.bitsPerSecond = parseInt(videoKbps * 1024); // 100 to 132 kbps audio + } + video.recorder.mediaRecorder = new MediaRecorder(video.srcObject, options); + } else { + options.mimeType = "audio/webm"; + if (audioKbps == 0) { + if (MediaRecorder.isTypeSupported("audio/webm;codecs=pcm")) { + options.mimeType = "audio/webm;codecs=pcm"; + } + } else { + options.bitsPerSecond = parseInt(audioKbps * 1024); + } + var stream = new MediaStream(); + video.srcObject.getAudioTracks().forEach((track) => { + stream.addTrack(track, video.srcObject); + }); + video.recorder.mediaRecorder = new MediaRecorder(stream, options); + } + log(options); + + function handleDataAvailable(event) { + if (event.data && event.data.size > 0) { + writer.write(event.data); + if (session.directorUUID) { + if (video.recording) { + var msg = {}; + msg.UUID = session.directorUUID; + msg.recorder = parseInt((Date.now() - timestamp) / 1000) || 0; + session.sendMessage(msg, msg.UUID); + } + } + } + } + + video.recorder.mediaRecorder.ondataavailable = handleDataAvailable; + + video.recorder.mediaRecorder.onerror = function(event) { + errorlog(event); + video.recorder.stop(true); + }; + + video.srcObject.ended = function(event) { + video.recorder.stop(); + }; + + video.recorder.mediaRecorder.start(1000); // 100ms chunks + + if (session.directorUUID) { + var msg = {}; + msg.UUID = session.directorUUID; + msg.recorder = 0; + session.sendMessage(msg, msg.UUID); + } + return; +} + + +function changeAudioOutputDevice(ele) { + if (session.sink){ + if ((iOS) || (iPad)){return;} // iOS devices do not support this. + + if (typeof ele.sinkId !== 'undefined'){ + navigator.mediaDevices.getUserMedia({audio:true,video:false}).then(function (stream){ + ele.setSinkId(session.sink).then(() => { + log("New Output Device:"+session.sink); + }).catch(errorlog); + stream.getTracks().forEach(track => { + track.stop(); + }); + }).catch(function canplayspecificaudio(){errorlog("Can't play out to specific audio device without mic permissions allowed");}); + } else { + warnlog("Your browser does not support alternative audio sources."); + } + } +} + +function addAudioPipeline(stream, UUID, track){ // INBOUND AUDIO EFFECTS + try{ + log("Triggered webaudio effects path"); + + if (session.audioEffects!==true){ // audio effects is not enable. Do not apply. + errorlog("Add Audio Pipeline tried to add effects but should be disabled?"); + return stream; + } + for (var tid in session.rpcs[UUID].inboundAudioPipeline){ + delete session.rpcs[UUID].inboundAudioPipeline[tid]; // get rid of old nodes. + } + var trackid = track.id; + session.rpcs[UUID].inboundAudioPipeline[trackid] = {}; + + session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream = new MediaStream(); + session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream.addTrack(track); + session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio = new Audio(); + session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio.muted = true; + session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio.srcObject = session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream; // needs to be added as an streamed element to be usable, even if its hidden + + session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio.play().then(_ => { + log("playing"); + }).catch(warnlog); + + // https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createMediaStreamTrackSource + source = session.audioCtx.createMediaStreamSource(session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream); + + ////////////////// + + var screwedUp = false; + session.rpcs[UUID].inboundAudioPipeline[trackid].destination = false; + if (session.sync!==false){ + log("adding a delay node to audio"); + source = addDelayNode( source, UUID, trackid); + screwedUp = true; + } + + if (session.style===2){ + log("adding a fftwave node to audio"); + source = fftWaveform( source, UUID, trackid); + } else if (session.style===3){ + log("adding a loudness meter node to audio"); + source = audioMeterGuest(source, UUID, trackid); + } else if (session.audioMeterGuest){ + log("adding a loudness meter node to audio"); + source = audioMeterGuest(source, UUID, trackid); + } else if (session.activeSpeaker){ + log("adding a loudness meter node to audio"); + source = audioMeterGuest(source, UUID, trackid); + } + + if (session.rpcs[UUID].channelOffset !== false){ + log("custom offset set"); + session.rpcs[UUID].inboundAudioPipeline[trackid].destination = session.audioCtx.createMediaStreamDestination(); + source = offsetChannel( session.rpcs[UUID].inboundAudioPipeline[trackid].destination, source, session.rpcs[UUID].channelOffset); + screwedUp = true; + } else if (session.offsetChannel !== false){ // proably better to do this last. + log("adding offset channels"); + session.rpcs[UUID].inboundAudioPipeline[trackid].destination = session.audioCtx.createMediaStreamDestination(); + source = offsetChannel( session.rpcs[UUID].inboundAudioPipeline[trackid].destination, source, session.offsetChannel); + screwedUp = true; + } + + if (screwedUp){ + if (session.rpcs[UUID].inboundAudioPipeline[trackid].destination===false){ + session.rpcs[UUID].inboundAudioPipeline[trackid].destination = session.audioCtx.createMediaStreamDestination(); + } + source.connect(session.rpcs[UUID].inboundAudioPipeline[trackid].destination); + stream.getTracks().forEach((trk)=>{ + if (trackid != trk.id){ + session.rpcs[UUID].inboundAudioPipeline[trackid].destination.stream.addTrack(trk); + log("secondary stream added"); + log(trk); + } + }); + + return session.rpcs[UUID].inboundAudioPipeline[trackid].destination.stream; + } + return stream; + } catch(e) {errorlog(e);} + return stream; +} + +function changeChannelOffset(UUID, channel){ + + + var ele = document.querySelectorAll('[data-action-type="add-channel"][data--u-u-i-d="' + UUID + '"]'); + for (var i=0;i ((val-128.0)*(val-128.0))); + var Sum = Squares.reduce((acum, val) => (acum + val)); + var Mean = Sum/loudness.length; + loudness = Math.sqrt(Mean)*10; + session.rpcs[uuid].stats.Audio_Loudness = parseInt(loudness); + + if (session.pushLoudness==true){ + var loudnessObj = {}; + loudnessObj[session.rpcs[uuid].streamID] = session.rpcs[uuid].stats.Audio_Loudness; + + if (isIFrame){ + parent.postMessage({"loudness": loudnessObj, "action":"loudness", "value":loudness, "UUID":uuid}, "*"); + } + } + + if (loudness<2){return;} + + //log(bufferLength); + session.rpcs[uuid].canvasCtx.beginPath(); + var m = session.rpcs[uuid].canvas.height / 256.0; + session.rpcs[uuid].canvasCtx.moveTo(0, dataArray[0]*m); + for (var i = 1; i < bufferLength; i++){ + var y = dataArray[i] * m; + session.rpcs[uuid].canvasCtx.lineTo(x, y); + x += sliceWidth; + } + session.rpcs[uuid].canvasCtx.lineTo(session.rpcs[uuid].canvas.width, session.rpcs[uuid].canvas.height / 2); + session.rpcs[uuid].canvasCtx.stroke(); + } catch(e){ + warnlog(e); + warnlog("Did the remote source disconnect?"); + clearInterval(fftInterval); + warnlog(session.rpcs[uuid]); + } + },50, UUID); + return session.rpcs[UUID].inboundAudioPipeline[trackid].analyser; +} + +function audioMeterGuest(mediaStreamSource, UUID, trackid){ + log("audioMeterGuest started"); + session.rpcs[UUID].inboundAudioPipeline[trackid].analyser = session.audioCtx.createAnalyser(); + mediaStreamSource.connect(session.rpcs[UUID].inboundAudioPipeline[trackid].analyser); + session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.fftSize = 256; + session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.smoothingTimeConstant = 0.05; + + var bufferLength = session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.frequencyBinCount; + var dataArray = new Uint8Array(bufferLength); + + function updateLevels() { + if (!(UUID in session.rpcs)){return;} + try { + session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.getByteFrequencyData(dataArray); + var total = 0; + for (var i = 0; i < dataArray.length; i++){ + total += dataArray[i]; + } + total = total/100; + session.rpcs[UUID].stats.Audio_Loudness = parseInt(total); + + if (session.pushLoudness==true){ + var loudnessObj = {}; + loudnessObj[session.rpcs[UUID].streamID] = session.rpcs[UUID].stats.Audio_Loudness; + + if (isIFrame){ + parent.postMessage({"loudness": loudnessObj, "action":"loudness", "value":session.rpcs[UUID].stats.Audio_Loudness, "UUID":UUID}, "*"); + } + } + + try{ + clearTimeout(session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.interval); + session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.interval = setTimeout(function(){updateLevels();},100); + } catch(e){ + log("closing old inaudio pipeline"); + } + + if (session.scene!==false){return;} // don't show if a scene + if (session.audioMeterGuest===false){return;} // don't show if we just want the volume levels + + if (session.rpcs[UUID].voiceMeter){ + session.rpcs[UUID].voiceMeter.dataset.level = total; + if (session.meterStyle==1){ + session.rpcs[UUID].voiceMeter.style.height = Math.min(total,100) + "%"; + if (total>75){ + total = Math.min(100,(total - 75)*4); + var R = parseInt((255 * total) / 100).toString(16).padStart(2, '0'); + var G = parseInt(255 * (100 - total) / 100).toString(16).padStart(2, '0'); + session.rpcs[UUID].voiceMeter.style.backgroundColor = "#" + R + G + "00"; + } else { + session.rpcs[UUID].voiceMeter.style.backgroundColor = "#00FF00"; + } + } else { + if (total>15){ + session.rpcs[UUID].voiceMeter.style.opacity = 100; // temporary + } else { + session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary + } + } + + } else { + if (session.meterStyle==1){ + session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate2").cloneNode(true); + } else { + session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate").cloneNode(true); + if (total>15){ + session.rpcs[UUID].voiceMeter.style.opacity = 100; // temporary + } else { + session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary + } + } + session.rpcs[UUID].voiceMeter.id = "voiceMeter_"+UUID; + session.rpcs[UUID].voiceMeter.dataset.level = total; + updateMixer(); + } + + } catch(e){ + warnlog(e); + return; + } + }; + clearTimeout(session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.interval); + session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.interval = setTimeout(function(){updateLevels();},100); + return session.rpcs[UUID].inboundAudioPipeline[trackid].analyser; +} + +function effectsDynamicallyUpdate(event, ele, preview=true){ + + var effect = ele.options[ele.selectedIndex].value; + getById("selectImageTFLITE").style.display = "none"; + if (effect === "0"){ + session.effects = 0; + activatedPreview=false; + if (preview){ + grabVideo(); + } else { + grabVideo(session.quality, "videosource", "select#videoSource3"); + } + if (ele.id == "effectSelector"){ + getById("selectImageTFLITE").style.display = "none"; + } else { + getById("selectImageTFLITE3").style.display = "none"; + } + return; + } else if (effect === "3"){ + if ((session.effects<3) || (session.effects>5)){ + session.effects = 3; + activatedPreview=false; + if (preview){ + grabVideo(); + } else { + grabVideo(session.quality, "videosource", "select#videoSource3"); + } + } else { + session.effects = 3; + } + } else if (effect === "4"){ + if ((session.effects<3) || (session.effects>5)){ + session.effects = 4; + activatedPreview=false; + if (preview){ + grabVideo(); + } else { + grabVideo(session.quality, "videosource", "select#videoSource3"); + } + } else { + session.effects = 4; + } + } else if (effect === "5"){ + if (session.tfliteModule.img){ + session.tfliteModule.img.src = "./media/bg_sample.webp"; + } + if ((session.effects<3) || (session.effects>5)){ + session.effects = 5; + activatedPreview=false; + if (preview){ + grabVideo(); + } else { + grabVideo(session.quality, "videosource", "select#videoSource3"); + } + } else { + session.effects = 5; + } + if (ele.id == "effectSelector"){ + getById("selectImageTFLITE").style.display = "block"; + } else { + getById("selectImageTFLITE3").style.display = "block"; + } + } else if (effect === "6"){ + session.effects = 6; + activatedPreview=false; + if (preview){ + grabVideo(); + } else { + grabVideo(session.quality, "videosource", "select#videoSource3"); + } + } + + if (session.effects !== 5){ + if (ele.id == "effectSelector"){ + getById("selectImageTFLITE").style.display = "none"; + } else { + getById("selectImageTFLITE3").style.display = "none"; + } + } + + if (session.tfliteModule===false){ + attemptTFLiteJsFileLoad(); + } +} +var TFLITELOADING = false; +function attemptTFLiteJsFileLoad(){ + if (session.tfliteModule!==false){ + return true; + } + TFLITELOADING=true; + session.tfliteModule={}; + + if (!document.getElementById("tflitesimdjs")){ + var tmpScript = document.createElement('script'); + tmpScript.onload = loadTFLiteModel; + tmpScript.type = 'text/javascript'; + tmpScript.src = "./thirdparty/tflite/tflite-simd.js?ver=2"; + tmpScript.id = "tflitesimdjs"; + document.head.appendChild(tmpScript); + } + + return false; +} +async function changeTFLiteImage(ev, ele){ + + if (ele.files && ele.files[0]) { + session.tfliteModule.img = document.querySelector('img'); + session.tfliteModule.img.ready=false; + session.tfliteModule.img.onload = () => { + URL.revokeObjectURL(session.tfliteModule.img.src); // no longer needed, free memory + session.tfliteModule.img.ready=true; + } + session.tfliteModule.img.src = URL.createObjectURL(ele.files[0]); // set src to blob url + } else if (ele.tagName.toLowerCase() == "img"){ + session.tfliteModule.img = ele + session.tfliteModule.img.ready=true; + } +} + + +async function loadTFLiteModel(){ + try{ + if (session.tfliteModule && (session.tfliteModule.img)){ + var img = session.tfliteModule.img; + session.tfliteModule = await createTFLiteSIMDModule(); + session.tfliteModule.img = img; + } else { + session.tfliteModule = {}; + session.tfliteModule = await createTFLiteSIMDModule(); + } + if (!session.tfliteModule.simd){ + var elements = document.querySelectorAll('[data-warnSimdNotice]') + for (let i = 0; i < elements.length; i++) { + elements[i].style.display = "inline-block"; + } + } + } catch(e){ + warnlog("TF-LITE FAILED TO LOAD"); + return; + } + const modelResponse = await fetch("./thirdparty/tflite/segm_full_v679.tflite"); + session.tfliteModule.model = await modelResponse.arrayBuffer(); + console.log('Model buffer size:', session.tfliteModule.model.byteLength); + session.tfliteModule.HEAPU8.set(new Uint8Array(session.tfliteModule.model), session.tfliteModule._getModelBufferMemoryOffset()); + session.tfliteModule._loadModel(session.tfliteModule.model.byteLength); + session.tfliteModule.activelyProcessing = false; + TFLITELOADING = false; + if ((session.effects>=3) && (session.effects<=5)){ + if (document.getElementById("videosource")){ + activatedPreview=false; + grabVideo(session.quality, "videosource", "select#videoSource3"); + } + } + if (LaunchTFWorkerCallback){TFLiteWorker();} +} + + + +function playbackMIDI(msg){ + if (session.midiIn===false){return;} // just in case. + else if (session.midiHotkeys || session.midiOut){return;} + //msg.midi.d = e.data; + //msg.midi.s = e.timestamp; + //msg.midi.t = e.type; + log(msg); + if (session.midiIn===true){ + if ("d" in msg){ + for (var i in WebMidi.outputs){ + try { + WebMidi.outputs[i].send(msg.d[0], [msg.d[1] || 0, msg.d[2] || 0]); + } catch(e){errorlog(e);} + } + } + } else if (session.midiIn==parseInt(session.midiIn)){ + try { + var i = parseInt(session.midiIn)-1; + if ("d" in msg){ + WebMidi.outputs[i].send(msg.d[0], [msg.d[1] || 0, msg.d[2] || 0]); + } + } catch(e){errorlog(e);}; + } + //var output = WebMidi.getOutputById("123456789"); + //output = WebMidi.getOutputByName("Axiom Pro 25 Ext Out"); + //output = WebMidi.outputs[0]; +} + +function addEventToAll(targets, trigger, callback) { // js helper + const target = document.querySelectorAll(targets); + var triggers = trigger.split(" "); + for (let i = 0; i < target.length; i++) { + for (let j = 0; j < triggers.length; j++) { + setTimeout(function(t1,t2){ + t1.addEventListener(t2, function(e) { + callback(e, t1); + }); + },0,target[i],triggers[j]); + } + } +} +addEventToAll(".column", 'click', function(e, ele) { + if (ele.classList.contains("skip-animation")) { + return; + } + var bounding_box = ele.getBoundingClientRect(); + ele.style.top = bounding_box.top + "px"; + ele.style.left = (bounding_box.left - 20) + "px"; + ele.classList.add('in-animation'); + ele.classList.remove('pointer'); + if (document.getElementById("empty-container")) { + getById("empty-container").parentNode.removeChid(getById("empty-container")); + } + var empty = document.createElement("DIV"); + empty.id = "empty-container"; + empty.className = "column"; + ele.parentNode.insertBefore(empty, ele.nextSibling); + const styles = "\ + @keyframes outlightbox {\ + 0% {\ + height: 100%;\ + width: 100%;\ + top: 0px;\ + left: 0px;\ + }\ + 50% {\ + height: 200px;\ + top: " + bounding_box.y + "px;\ + }\ + 100% {\ + height: 200px;\ + width: " + bounding_box.width + "px;\ + top: " + bounding_box.y + "px;\ + left: " + bounding_box.x + "px;\ + }\ + }\ + "; + if (document.getElementById('lightbox-animations')) { + getById("lightbox-animations").innerHTML = styles; + } + document.body.style.overflow = "hidden"; +}); +addEventToAll(".close", 'click', function(e, ele) { + cleanupMediaTracks(); + ele.style.display = "none"; + mapToAll(".container-inner", function(target) { + target.style.display = "none"; + }); + document.body.style.overflow = "auto"; + var bounding_box = getById("empty-container").parentNode.getBoundingClientRect(); + setTimeout(function() { // just smoothes things out; breathing room to clean up things first. + ele.parentNode.classList.add('out-animation'); + }, 1); + ele.parentNode.style.top = bounding_box.top + 'px'; + ele.parentNode.style.left = bounding_box.left + 'px'; + e.stopPropagation(); +}); +addEventToAll(".column", 'animationend', function(e, ele) { + if (e.animationName == 'inlightbox') { + ele.classList.add("skip-animation"); + mapToAll(".close", function(target) { + target.style.display = "block"; + }, ele); + mapToAll(".container-inner", function(target) { + target.style.display = "block"; + }, ele); + } else if (e.animationName == 'outlightbox') { + ele.classList.remove('in-animation'); + ele.classList.remove('out-animation'); + ele.classList.remove("skip-animation"); + ele.classList.remove('columnfade'); + ele.classList.add('pointer'); + getById("empty-container").parentNode.removeChild(getById("empty-container")); + getById("lightbox-animations").sheet.deleteRule(0); + } +}); +addEventToAll("#audioSource", 'mousedown touchend focusin focusout', function(e, ele) { + var state = getById('multiselect-trigger').dataset.state || 0; + if (state == 0) { + getById('multiselect-trigger').dataset.state = 1; + getById('multiselect-trigger').classList.add('open'); + getById('multiselect-trigger').classList.remove('closed'); + mapToAll('.chevron', function(ele) { + ele.classList.remove('bottom'); + }, parentElement = getById('multiselect-trigger')); + mapToAll('.multiselect-contents', function(ele) { + ele.style.display = "block"; + mapToAll('input[type="checkbox"]', function(ele2) { + ele2.parentNode.style.display = "block"; + ele2.style.display = "inline-block"; + }, ele); + }, parentElement = getById('multiselect-trigger').parentNode); + } + e.stopPropagation(); + //e.preventDefault(); +}); +addEventToAll("#audioSource3", 'mousedown touchend focusin focusout', function(e, ele) { + var state = getById('multiselect-trigger3').dataset.state || 0; + if (state == 0) { + getById('multiselect-trigger3').dataset.state = 1; + getById('multiselect-trigger3').classList.add('open'); + getById('multiselect-trigger3').classList.remove('closed'); + mapToAll(".chevron", function(target) { + target.classList.remove('bottom'); + }, getById('multiselect-trigger3')); + mapToAll(".multiselect-contents", function(target) { + target.style.display = "block"; + }, getById('multiselect-trigger3').parentNode); + mapToAll(".multiselect-contents", function(target) { + mapToAll('input[type="checkbox"]', function(target2) { + target2.style.display = "inline-block"; + target2.parentNode.style.display = "block"; + }, target); + }, getById('multiselect-trigger3').parentNode); + } + e.stopPropagation(); + //e.preventDefault(); +}); +addEventToAll("#multiselect-trigger", 'mousedown touchend focusin focusout', function(e, ele) { + var state = ele.dataset.state || 0; + if (state == 0) { // open the dropdown + ele.dataset.state = 1; + ele.classList.add('open'); + ele.classList.remove('closed'); + mapToAll(".chevron", function(target) { + target.classList.remove('bottom'); + }, getById('multiselect-trigger')); + mapToAll(".multiselect-contents", function(target) { + target.style.display = "block"; + }, ele.parentNode); + mapToAll(".multiselect-contents", function(target) { + mapToAll('input[type="checkbox"]', function(target2) { + target2.style.display = "inline-block"; + target2.parentNode.style.display = "block"; + }, target); + }, ele.parentNode); + } else { // close the dropdown + ele.dataset.state = 0; + ele.classList.add('closed'); + ele.classList.remove('open'); + mapToAll(".chevron", function(target) { + target.classList.add('bottom'); + }, ele); + mapToAll(".multiselect-contents", function(target) { + mapToAll('input[type="checkbox"]', function(target2) { + target2.style.display = "none"; + if (!target2.checked) { + target2.parentNode.style.display = "none"; + } + }, target); + }, ele.parentNode); + } + e.preventDefault(); + e.stopPropagation(); +}); +addEventToAll("#multiselect-trigger3", 'mousedown touchend focusin focusout', function(e, ele) { + var state = ele.dataset.state || 0; + if (state == 0) { // open the dropdown + ele.dataset.state = 1; + ele.classList.add('open'); + ele.classList.remove('closed'); + mapToAll(".chevron", function(target) { + target.classList.remove('bottom'); + }, ele); + mapToAll(".multiselect-contents", function(target) { + target.style.display = "block"; + }, ele.parentNode); + mapToAll(".multiselect-contents", function(target) { + mapToAll('input[type="checkbox"]', function(target2) { + target2.style.display = "inline-block"; + target2.parentNode.style.display = "block"; + }, target); + }, ele.parentNode); + } else { // close the dropdown + ele.dataset.state = 0; + ele.classList.add('closed'); + ele.classList.remove('open'); + mapToAll(".chevron", function(target) { + target.classList.add('bottom'); + }, ele); + mapToAll(".multiselect-contents", function(target) { + mapToAll('input[type="checkbox"]', function(target2) { + target2.style.display = "none"; + if (!target2.checked) { + target2.parentNode.style.display = "none"; + } + }, target); + }, ele.parentNode); + } + e.preventDefault(); + e.stopPropagation(); +}); + + + + + diff --git a/main.css b/main.css index 90df284..09903b1 100644 --- a/main.css +++ b/main.css @@ -2755,12 +2755,12 @@ input:checked + .slider:before { } -#promptModal, #roomSettings { +#promptModal, #roomSettings, .promptModal { position: absolute; background-color: rgb(221 221 221); box-shadow: 0 0 30px 10px #0000005c; color: black; - font-size: 1.2em; + font-size: 1.0em; top: 50%; left: 50%; transform: translate(-50%, -50%); @@ -2773,9 +2773,9 @@ input:checked + .slider:before { } .largeTextEntry { - width:300px; - margin: 0 0 0 55px; - font-size: 1em; + width: 90%; + margin: 10px 5%; + font-size: .8em; padding: 0.4em; display: block; @@ -2783,6 +2783,14 @@ input:checked + .slider:before { .promptModalInner { position: relative; padding: 1em; + max-width: 400px; +} + +.promptModalMessage { + position: relative; + display: block; + width: 98%; + margin: 0 5%; } #iframe_source{ diff --git a/main.js b/main.js index dca7921..0779613 100644 --- a/main.js +++ b/main.js @@ -7,2189 +7,1442 @@ * */ /*jshint esversion: 6 */ +async function main(){ // main asyncronous thread; mostly initializes the user settings. -var formSubmitting = true; -var activatedPreview = false; + var delayedStartupFuncs = []; -// function log(msg){ // uncomment to enable logging. - // console.log(msg); -// } -// function warnlog(msg, url=false, lineNumber=false){ - // onsole.warn(msg); - // if (lineNumber){ - // console.warn(lineNumber); - // } -// } -// function errorlog(msg, url=false, lineNumber=false){ - // console.error(msg); - // if (lineNumber){ - // console.error(lineNumber); - // } -// } - -function addEventToAll(targets, trigger, callback) { // js helper - const target = document.querySelectorAll(targets); - var triggers = trigger.split(" "); - for (let i = 0; i < target.length; i++) { - for (let j = 0; j < triggers.length; j++) { - setTimeout(function(t1,t2){ - t1.addEventListener(t2, function(e) { - callback(e, t1); - }); - },0,target[i],triggers[j]); - } - } -} - -function mapToAll(targets, callback, parentElement = document) { // js helper - if (!targets) { - return; - } - if (!parentElement) { - return; - } - const target = parentElement.querySelectorAll(targets); - for (let i = 0; i < target.length; i++) { - callback(target[i]); - } -} - -var isIFrame = false; -if ( parent && (window.location !== window.parent.location )) { - isIFrame = true; -} - -function changeParam(url, paramName, paramValue) { - paramName = paramName.replace("?", ""); - var qind = url.indexOf('?'); - url = url.replace("?", "&"); - var params = url.substring(qind + 1).split('&'); - var query = ''; - var match = false; - for (var i = 0; i < params.length; i++) { - var tokens = params[i].split('='); - var name = tokens[0]; - var value = ""; - if (tokens.length > 1 && tokens[1] !== '') { - value = tokens[1]; - } - - if (name == paramName) { - if (match) { - continue; - } // already matched the first time. - match = true; - value = paramValue; - } - if (value !== "") { - value = '=' + value; - } - - if (query == '') { - query = "?" + name + value; - } else { - query = query + '&' + name + value; - } - } - return url.substring(0, qind) + query; -} - -function updateURL(param, force = false, cleanUrl = false) { - param = param.replace("?", ""); - var para = param.split('='); - if (cleanUrl) { - if (history.pushState) { - var href = new URL(cleanUrl); - if (para.length == 1) { - href = changeParam(cleanUrl, para[0], ""); - } else { - href = changeParam(cleanUrl, para[0], para[1]); - } - log("--" + href.toString()); - window.history.pushState({path: href.toString()}, '', href.toString()); - } - } else if (!(urlParams.has(para[0]))) { // don't need to replace as it doesn't exist. - if (history.pushState) { - var href = window.location.href; - href = href.replace("??", "?"); - var arr = href.split('?'); - var newurl; - if (arr.length > 1 && arr[1] !== '') { - newurl = href + '&' + param; - } else { - newurl = href + '?' + param; - } - - window.history.pushState({path: newurl.toString()}, '', newurl.toString()); - } - } else if (force) { - if (history.pushState) { - var href = new URL(window.location.href); - if (para.length == 1) { - href = changeParam(window.location.href, para[0], ""); - } else { - href = changeParam(window.location.href, para[0], para[1]); - } - log("---" + href.toString()); - window.history.pushState({path: href.toString()}, '', href.toString()); - } - } - if (session.sticky) { - setStorage("settings", encodeURI(window.location.href), 90); - } - urlParams = new URLSearchParams(window.location.search); -} - -function changeGuestSettings(ele){ - var eles = ele.querySelectorAll('[data-param]'); - var UUID = ele.dataset.UUID; - var settings = {}; - for (var i = 0;i< eles.length; i++){ - if (eles[i].tagName.toLowerCase() == "input"){ - if (eles[i].checked===true){ - settings[eles[i].dataset.param] = true; - } else if (eles[i].checked===false){ - settings[eles[i].dataset.param] = false; - } else { - settings[eles[i].dataset.param] = eles[i].value; + if (!isIFrame){ + if (getStorage("redirect") == "yes") { + setStorage("redirect", "", 0); + session.sticky = true; + } else if (getStorage("settings") != "") { + if (!(session.cleanOutput)){ + window.focus(); + session.sticky = confirm("Would you like you load your previous session's settings?"); + if (!session.sticky) { + setStorage("settings", "", 0); + log("deleting cookie as user said no"); + } else { + var cookieSettings = decodeURI(getStorage("settings")); + setStorage("redirect", "yes", 1); + window.location.replace(cookieSettings); + } } } - } - warnlog(settings); - - if (!settings.changepassword){ - delete settings.password; - } - - delete settings.changepassword; - - if (!settings.changeroom){ - // send Migration message - delete settings.roomid; - } - delete settings.roomid; - delete settings.changeroom; - - warnlog(UUID); - var msg = {}; - msg.changeParams = settings; - session.sendRequest(msg, UUID); - closeModal(); -} -// proper room migration needs to happen; in sync. -// updateMixer after settings changed -// password needs to be special cased -// room shouldn't be sent - -function applyNewParams(changeParams){ - for (var key in changeParams){ - session[key] = changeParams[key]; - log(key); - } - log(changeParams); - updateMixer(); -} - -function promptUser(eleId, UUID=null){ - if (document.getElementById("modalBackdrop")){ - getById("promptModal").innerHTML = ''; // Delete modal - getById("promptModal").remove(); - getById("modalBackdrop").innerHTML = ''; // Delete modal - getById("modalBackdrop").remove(); - } - - zindex = 30 + document.querySelectorAll('#promptModal').length; - modalTemplate = - `
-
- ร— - -
-
-
`; - document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end - - getById("promptModalMessage").innerHTML = getById(eleId).innerHTML; - if (UUID){ - getById("promptModalMessage").dataset.UUID = UUID; - } - - - document.getElementById("modalBackdrop").addEventListener("click", closeModal); - - getById("promptModal").addEventListener("click", function(e) { - e.stopPropagation(); - return false; - }); - -} -var warnUserTimeout=null; -function warnUser(message, timeout=false){ - // Allows for multiple alerts to stack better. - // Every modal and backdrop has an increasing z-index - // to block the previous modal - if (document.getElementById("modalBackdrop")){ - getById("alertModal").innerHTML = ''; // Delete modal - getById("alertModal").remove(); - getById("modalBackdrop").innerHTML = ''; // Delete modal - getById("modalBackdrop").remove(); - } - - zindex = 31 + document.querySelectorAll('.alertModal').length; - message = message.replace(/\n/g,"
"); - modalTemplate = - `
-
- ร— - ${message} -
-
-
`; - document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end - - document.getElementById("modalBackdrop").addEventListener("click", closeModal); - - clearTimeout(warnUserTimeout); - if (timeout){ - warnUserTimeout = setTimeout(closeModal, timeout); - } - getById("alertModal").addEventListener("click", function(e) { - e.stopPropagation(); - return false; - }); - -} -function closeModal(){ - getById("modalBackdrop").innerHTML = ''; // Delete modal - getById("modalBackdrop").remove(); - getById("alertModal").innerHTML = ''; // Delete modal - getById("alertModal").remove(); - getById("promptModal").innerHTML = ''; // Delete modal - getById("promptModal").remove(); -} - -var filename = false; -try { - filename = window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1); - filename = filename.replace("??", "?"); - filename2 = filename.split("?")[0]; - // split at ??? - if (filename.split(".").length == 1) { - if (filename2.length < 2) { // easy win - filename = false; - } else if (filename.startsWith("&")) { // easy win - var tmpHref = window.location.href.substring(0, window.location.href.lastIndexOf('/')) + "/?" + filename.split("&").slice(1).join("&"); - log("TMP " + tmpHref); - updateURL(filename.split("&")[1], true, tmpHref); - filename = false; - } else if (filename2.split("&")[0].includes("=")) { - log("asdf " + filename.split("&")[0]); - if (history.pushState) { - var tmpHref = window.location.href.substring(0, window.location.href.lastIndexOf('/')); - tmpHref = tmpHref + "/?" + filename; - filename = false; - //warnUser("Please ensure your URL is correctly formatted."); - window.history.pushState({path: tmpHref.toString()}, '', tmpHref.toString()); - } - } else { - filename = filename2.split("&")[0]; - if (filename2 != filename) { - warnUser("Warning: Please ensure your URL is correctly formatted."); - } + if (urlParams.has('sticky')){ // won't work with iframes. + + //if (getStorage("permission") == "") { + // session.sticky = confirm("Would you allow us to store a cookie to keep your session settings persistent?"); + //} else { + session.sticky = true; + //} + //if (session.sticky) { + setStorage("permission", "yes", 999); + setStorage("settings", encodeURI(window.location.href), 90); + //} } + } + + if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { + try { + getById("electronDragZone").style.cursor="grab"; + const ipcRenderer = require('electron').ipcRenderer; + window.prompt = function(title, val){ + return ipcRenderer.sendSync('prompt', {title, val}); + }; + } catch(e){} + } + + if (urlParams.has('cleanoutput') || urlParams.has('clean') || urlParams.has('cleanish')) { + session.cleanOutput = true; + } + + if (urlParams.has('retrytimeout')) { + session.retryTimeout = parseInt(urlParams.get('retrytimeout')); + } + + if (urlParams.has('ptz')){ + session.ptz=true; + } + + if (urlParams.has('optimize')) { + session.optimize = parseInt(urlParams.get('optimize')) || 0; + } + + if (urlParams.has('nosettings') || urlParams.has('ns')) { + screensharebutton = false; + session.showSettings = false; + } + + if (urlParams.has('nomicbutton') || urlParams.has('nmb')) { + getById("mutebutton").setAttribute('style', "display: none !important"); + } + + + if (urlParams.has('novideobutton') || urlParams.has('nvb')) { + getById("mutevideobutton").setAttribute('style', "display: none !important"); + } + + if (urlParams.has('screenshareid') || urlParams.has('ssid')) { + if (urlParams.get('screenshareid') || urlParams.get('ssid')) { + session.screenshareid = urlParams.get('screenshareid') || urlParams.get('ssid'); + session.screenshareid = sanitizeStreamID(session.screenshareid); + } + } + + if (urlParams.has('screensharefps') || urlParams.has('ssfps')) { + if (urlParams.get('screensharefps') || urlParams.get('ssfps')) { + session.screensharefps = urlParams.get('screensharefps') || urlParams.get('ssfps'); + session.screensharefps = parseInt(session.screensharefps) || 2; + } + } + + if (urlParams.has('screensharequality') || urlParams.has('ssq')) { + if (urlParams.get('screensharequality') || urlParams.get('ssq')) { + session.screensharequality = urlParams.get('screensharequality') || urlParams.get('ssq'); + session.screensharequality = parseInt(session.screensharequality) || 1; + } + } + + if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { + //session.webcamonly = true; + session.mobile = true; + getById("shareScreenGear").style.display = "none"; + screensharebutton = false; + screensharesupport = false; + getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile + getById("dropButton").style.display = "none"; + //session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? + session.audioEffects = false; // disable audio inbound effects also. + session.audioMeterGuest = false; + + } else if ((iOS) || (iPad)) { + getById("shareScreenGear").style.display = "none"; + session.mobile = true; + screensharebutton = false; + screensharesupport = false; + getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile + getById("dropButton").style.display = "none"; + //session.audiobitrate = false; // iOS devices seem to get distortion with custom audio bitrates. Disable for now. + //session.maxiosbitrate = 10; // this is 10-kbps by default already. + //session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? + session.audioEffects = false; // disable audio inbound effects also. + session.audioMeterGuest = false; } else { - filename = false; - } - log(filename); -} catch (e) { - errorlog(e); -} - - -(function(w) { - w.URLSearchParams = w.URLSearchParams || function(searchString) { - var self = this; - searchString = searchString.replace("??", "?"); - self.searchString = searchString; - self.get = function(name) { - var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString); - if (results == null) { - return null; - } else { - return decodeURI(results[1]) || 0; - } - }; - }; - -})(window); - -var urlEdited = window.location.search.replace(/\?\?/g, "?"); -urlEdited = urlEdited.replace(/\?/g, "&"); -urlEdited = urlEdited.replace(/\&/, "?"); - -if (urlEdited !== window.location.search){ - warnlog(window.location.search + " changed to " + urlEdited); - window.history.pushState({path: urlEdited.toString()}, '', urlEdited.toString()); -} -var urlParams = new URLSearchParams(urlEdited); - -var sanitizeStreamID = function(streamID) { - streamID = streamID.trim(); - - if (streamID.length < 1) { - streamID = session.generateStreamID(8); - if (!(session.cleanOutput)) { - warnUser("No streamID was provided; one will be generated randomily.\n\nStream ID: " + streamID); - } - } - var streamID_sanitized = streamID.replace(/[\W]+/g, "_"); - if (streamID !== streamID_sanitized) { - if (!(session.cleanOutput)) { - warnUser("Info: Only AlphaNumeric characters should be used for the stream ID.\n\nThe offending characters have been replaced by an underscore"); - } - } - if (streamID_sanitized.length > 44) { - streamID_sanitized = streamID_sanitized.substring(0, 44); - if (!(session.cleanOutput)) { - warnUser("The Stream ID should be less than 45 alPhaNuMeric characters long.\n\nWe will trim it to length."); - } - } - return streamID_sanitized; -}; - -var checkStrength = function(string) { - var matcher = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{7,30}$/; - if (string.match(matcher)) { - return true; - } else if (string.length > 20) { - return true; - } else { - return false; - } -}; - -var checkStrengthRoom = function() { - var result1 = checkStrength(getById('videoname1').value); - var result2 = getById('passwordRoom').value.length; - var target = getById('securityLevelRoom'); - target.style.display = "block"; - if (result1) { - if (result2) { - target.innerHTML = "Share only with those you trust"; - } else { - target.innerHTML = "A password is recommended"; - } - } else { - target.innerHTML = "Insecure room name. Allowed chars: A-Z, a-z, 0-9, _"; - } -}; - -var emojiShortCodes ={":joy:":"๐Ÿ˜‚",":heart:":"โค๏ธ",":heart_eyes:":"๐Ÿ˜",":sob:":"๐Ÿ˜ญ",":blush:":"๐Ÿ˜Š",":unamused:":"๐Ÿ˜’",":two_hearts:":"๐Ÿ’•",":weary:":"๐Ÿ˜ฉ",":ok_hand:":"๐Ÿ‘Œ",":pensive:":"๐Ÿ˜”",":smirk:":"๐Ÿ˜",":grin:":"๐Ÿ˜",":wink:":"๐Ÿ˜‰",":thumbsup:":"๐Ÿ‘",":pray:":"๐Ÿ™",":relieved:":"๐Ÿ˜Œ",":notes:":"๐ŸŽถ",":flushed:":"๐Ÿ˜ณ",":raised_hands:":"๐Ÿ™Œ",":see_no_evil:":"๐Ÿ™ˆ",":cry:":"๐Ÿ˜ข",":sunglasses:":"๐Ÿ˜Ž",":v:":"โœŒ๏ธ",":eyes:":"๐Ÿ‘€",":sweat_smile:":"๐Ÿ˜…",":sparkles:":"โœจ",":sleeping:":"๐Ÿ˜ด",":smile:":"๐Ÿ˜„",":purple_heart:":"๐Ÿ’œ",":broken_heart:":"๐Ÿ’”",":blue_heart:":"๐Ÿ’™",":confused:":"๐Ÿ˜•",":disappointed:":"๐Ÿ˜ž",":yum:":"๐Ÿ˜‹",":neutral_face:":"๐Ÿ˜",":sleepy:":"๐Ÿ˜ช",":clap:":"๐Ÿ‘",":cupid:":"๐Ÿ’˜",":heartpulse:":"๐Ÿ’—",":kiss:":"๐Ÿ’‹",":point_right:":"๐Ÿ‘‰",":scream:":"๐Ÿ˜ฑ",":fire:":"๐Ÿ”ฅ",":rage:":"๐Ÿ˜ก",":smiley:":"๐Ÿ˜ƒ",":tada:":"๐ŸŽ‰",":tired_face:":"๐Ÿ˜ซ",":camera:":"๐Ÿ“ท",":rose:":"๐ŸŒน",":muscle:":"๐Ÿ’ช",":skull:":"๐Ÿ’€",":sunny:":"โ˜€๏ธ",":yellow_heart:":"๐Ÿ’›",":triumph:":"๐Ÿ˜ค",":laughing:":"๐Ÿ˜†",":sweat:":"๐Ÿ˜“",":point_left:":"๐Ÿ‘ˆ",":grinning:":"๐Ÿ˜€",":mask:":"๐Ÿ˜ท",":green_heart:":"๐Ÿ’š",":wave:":"๐Ÿ‘‹",":persevere:":"๐Ÿ˜ฃ",":heartbeat:":"๐Ÿ’“",":crown:":"๐Ÿ‘‘",":innocent:":"๐Ÿ˜‡",":headphones:":"๐ŸŽง",":confounded:":"๐Ÿ˜–",":angry:":"๐Ÿ˜ ",":grimacing:":"๐Ÿ˜ฌ",":star2:":"๐ŸŒŸ",":gun:":"๐Ÿ”ซ",":raising_hand:":"๐Ÿ™‹",":thumbsdown:":"๐Ÿ‘Ž",":dancer:":"๐Ÿ’ƒ",":musical_note:":"๐ŸŽต",":no_mouth:":"๐Ÿ˜ถ",":dizzy:":"๐Ÿ’ซ",":fist:":"โœŠ",":point_down:":"๐Ÿ‘‡",":no_good:":"๐Ÿ™…",":boom:":"๐Ÿ’ฅ",":tongue:":"๐Ÿ‘…",":poop:":"๐Ÿ’ฉ",":cold_sweat:":"๐Ÿ˜ฐ",":gem:":"๐Ÿ’Ž",":ok_woman:":"๐Ÿ™†",":pizza:":"๐Ÿ•",":joy_cat:":"๐Ÿ˜น",":leaves:":"๐Ÿƒ",":sweat_drops:":"๐Ÿ’ฆ",":penguin:":"๐Ÿง",":zzz:":"๐Ÿ’ค",":walking:":"๐Ÿšถ",":airplane:":"โœˆ๏ธ",":balloon:":"๐ŸŽˆ",":star:":"โญ",":ribbon:":"๐ŸŽ€",":worried:":"๐Ÿ˜Ÿ",":underage:":"๐Ÿ”ž",":fearful:":"๐Ÿ˜จ",":hibiscus:":"๐ŸŒบ",":microphone:":"๐ŸŽค",":open_hands:":"๐Ÿ‘",":ghost:":"๐Ÿ‘ป",":palm_tree:":"๐ŸŒด",":nail_care:":"๐Ÿ’…",":alien:":"๐Ÿ‘ฝ",":bow:":"๐Ÿ™‡",":cloud:":"โ˜",":soccer:":"โšฝ",":angel:":"๐Ÿ‘ผ",":dancers:":"๐Ÿ‘ฏ",":snowflake:":"โ„๏ธ",":point_up:":"โ˜๏ธ",":rainbow:":"๐ŸŒˆ",":gift_heart:":"๐Ÿ’",":gift:":"๐ŸŽ",":beers:":"๐Ÿป",":anguished:":"๐Ÿ˜ง",":earth_africa:":"๐ŸŒ",":movie_camera:":"๐ŸŽฅ",":anchor:":"โš“",":zap:":"โšก",":runner:":"๐Ÿƒ",":sunflower:":"๐ŸŒป",":bouquet:":"๐Ÿ’",":dog:":"๐Ÿถ",":moneybag:":"๐Ÿ’ฐ",":herb:":"๐ŸŒฟ",":couple:":"๐Ÿ‘ซ",":fallen_leaf:":"๐Ÿ‚",":tulip:":"๐ŸŒท",":birthday:":"๐ŸŽ‚",":cat:":"๐Ÿฑ",":coffee:":"โ˜•",":dizzy_face:":"๐Ÿ˜ต",":point_up_2:":"๐Ÿ‘†",":open_mouth:":"๐Ÿ˜ฎ",":hushed:":"๐Ÿ˜ฏ",":basketball:":"๐Ÿ€",":ring:":"๐Ÿ’",":astonished:":"๐Ÿ˜ฒ",":hear_no_evil:":"๐Ÿ™‰",":dash:":"๐Ÿ’จ",":cactus:":"๐ŸŒต",":hotsprings:":"โ™จ๏ธ",":telephone:":"โ˜Ž๏ธ",":maple_leaf:":"๐Ÿ",":princess:":"๐Ÿ‘ธ",":massage:":"๐Ÿ’†",":love_letter:":"๐Ÿ’Œ",":trophy:":"๐Ÿ†",":blossom:":"๐ŸŒผ",":lips:":"๐Ÿ‘„",":fries:":"๐ŸŸ",":doughnut:":"๐Ÿฉ",":frowning:":"๐Ÿ˜ฆ",":ocean:":"๐ŸŒŠ",":bomb:":"๐Ÿ’ฃ",":cyclone:":"๐ŸŒ€",":rocket:":"๐Ÿš€",":umbrella:":"โ˜”",":couplekiss:":"๐Ÿ’",":lollipop:":"๐Ÿญ",":clapper:":"๐ŸŽฌ",":pig:":"๐Ÿท",":smiling_imp:":"๐Ÿ˜ˆ",":imp:":"๐Ÿ‘ฟ",":bee:":"๐Ÿ",":kissing_cat:":"๐Ÿ˜ฝ",":anger:":"๐Ÿ’ข",":santa:":"๐ŸŽ…",":earth_asia:":"๐ŸŒ",":football:":"๐Ÿˆ",":guitar:":"๐ŸŽธ",":panda_face:":"๐Ÿผ",":strawberry:":"๐Ÿ“",":smirk_cat:":"๐Ÿ˜ผ",":banana:":"๐ŸŒ",":watermelon:":"๐Ÿ‰",":snowman:":"โ›„",":smile_cat:":"๐Ÿ˜ธ",":eggplant:":"๐Ÿ†",":crystal_ball:":"๐Ÿ”ฎ",":calling:":"๐Ÿ“ฒ",":iphone:":"๐Ÿ“ฑ",":partly_sunny:":"โ›…",":warning:":"โš ๏ธ",":scream_cat:":"๐Ÿ™€",":baby:":"๐Ÿ‘ถ",":feet:":"๐Ÿพ",":footprints:":"๐Ÿ‘ฃ",":beer:":"๐Ÿบ",":wine_glass:":"๐Ÿท",":video_camera:":"๐Ÿ“น",":rabbit:":"๐Ÿฐ",":smoking:":"๐Ÿšฌ",":peach:":"๐Ÿ‘",":snake:":"๐Ÿ",":turtle:":"๐Ÿข",":cherries:":"๐Ÿ’",":kissing:":"๐Ÿ˜—",":frog:":"๐Ÿธ",":milky_way:":"๐ŸŒŒ",":closed_book:":"๐Ÿ“•",":candy:":"๐Ÿฌ",":hamburger:":"๐Ÿ”",":bear:":"๐Ÿป",":tiger:":"๐Ÿฏ",":icecream:":"๐Ÿฆ",":pineapple:":"๐Ÿ",":ear_of_rice:":"๐ŸŒพ",":syringe:":"๐Ÿ’‰",":tv:":"๐Ÿ“บ",":pill:":"๐Ÿ’Š",":octopus:":"๐Ÿ™",":grapes:":"๐Ÿ‡",":smiley_cat:":"๐Ÿ˜บ",":cd:":"๐Ÿ’ฟ",":cocktail:":"๐Ÿธ",":cake:":"๐Ÿฐ",":video_game:":"๐ŸŽฎ",":lipstick:":"๐Ÿ’„",":whale:":"๐Ÿณ",":cookie:":"๐Ÿช",":dolphin:":"๐Ÿฌ",":loud_sound:":"๐Ÿ”Š",":man:":"๐Ÿ‘จ",":monkey:":"๐Ÿ’",":books:":"๐Ÿ“š",":guardsman:":"๐Ÿ’‚",":loudspeaker:":"๐Ÿ“ข",":scissors:":"โœ‚๏ธ",":girl:":"๐Ÿ‘ง",":mortar_board:":"๐ŸŽ“",":baseball:":"โšพ๏ธ",":woman:":"๐Ÿ‘ฉ",":fireworks:":"๐ŸŽ†",":stars:":"๐ŸŒ ",":mushroom:":"๐Ÿ„",":pouting_cat:":"๐Ÿ˜พ",":left_luggage:":"๐Ÿ›…",":high_heel:":"๐Ÿ‘ ",":dart:":"๐ŸŽฏ",":swimmer:":"๐ŸŠ",":key:":"๐Ÿ”‘",":bikini:":"๐Ÿ‘™",":family:":"๐Ÿ‘ช",":pencil2:":"โœ",":elephant:":"๐Ÿ˜",":droplet:":"๐Ÿ’ง",":seedling:":"๐ŸŒฑ",":apple:":"๐ŸŽ",":dollar:":"๐Ÿ’ต",":book:":"๐Ÿ“–",":haircut:":"๐Ÿ’‡",":computer:":"๐Ÿ’ป",":bulb:":"๐Ÿ’ก",":boy:":"๐Ÿ‘ฆ",":tangerine:":"๐ŸŠ",":sunrise:":"๐ŸŒ…",":poultry_leg:":"๐Ÿ—",":shaved_ice:":"๐Ÿง",":bird:":"๐Ÿฆ",":eyeglasses:":"๐Ÿ‘“",":goat:":"๐Ÿ",":older_woman:":"๐Ÿ‘ต",":new_moon:":"๐ŸŒ‘",":customs:":"๐Ÿ›ƒ",":house:":"๐Ÿ ",":full_moon:":"๐ŸŒ•",":lemon:":"๐Ÿ‹",":baby_bottle:":"๐Ÿผ",":spaghetti:":"๐Ÿ",":wind_chime:":"๐ŸŽ",":fish_cake:":"๐Ÿฅ",":nose:":"๐Ÿ‘ƒ",":pig_nose:":"๐Ÿฝ",":fish:":"๐ŸŸ",":koala:":"๐Ÿจ",":ear:":"๐Ÿ‘‚",":shower:":"๐Ÿšฟ",":bug:":"๐Ÿ›",":ramen:":"๐Ÿœ",":tophat:":"๐ŸŽฉ",":fuelpump:":"โ›ฝ",":horse:":"๐Ÿด",":watch:":"โŒš",":monkey_face:":"๐Ÿต",":baby_symbol:":"๐Ÿšผ",":sparkler:":"๐ŸŽ‡",":corn:":"๐ŸŒฝ",":tennis:":"๐ŸŽพ",":battery:":"๐Ÿ”‹",":wolf:":"๐Ÿบ",":moyai:":"๐Ÿ—ฟ",":cow:":"๐Ÿฎ",":mega:":"๐Ÿ“ฃ",":older_man:":"๐Ÿ‘ด",":dress:":"๐Ÿ‘—",":link:":"๐Ÿ”—",":chicken:":"๐Ÿ”",":whale2:":"๐Ÿ‹",":bento:":"๐Ÿฑ",":pushpin:":"๐Ÿ“Œ",":dragon:":"๐Ÿ‰",":hamster:":"๐Ÿน",":golf:":"โ›ณ",":surfer:":"๐Ÿ„",":mouse:":"๐Ÿญ",":blue_car:":"๐Ÿš™",":bread:":"๐Ÿž",":cop:":"๐Ÿ‘ฎ",":tea:":"๐Ÿต",":bike:":"๐Ÿšฒ",":rice:":"๐Ÿš",":radio:":"๐Ÿ“ป",":baby_chick:":"๐Ÿค",":sheep:":"๐Ÿ‘",":lock:":"๐Ÿ”’",":green_apple:":"๐Ÿ",":racehorse:":"๐ŸŽ",":fried_shrimp:":"๐Ÿค",":volcano:":"๐ŸŒ‹",":rooster:":"๐Ÿ“",":inbox_tray:":"๐Ÿ“ฅ",":wedding:":"๐Ÿ’’",":sushi:":"๐Ÿฃ",":ice_cream:":"๐Ÿจ",":tomato:":"๐Ÿ…",":rabbit2:":"๐Ÿ‡",":beetle:":"๐Ÿž",":bath:":"๐Ÿ›€",":no_entry:":"โ›”",":crocodile:":"๐ŸŠ",":dog2:":"๐Ÿ•",":cat2:":"๐Ÿˆ",":hammer:":"๐Ÿ”จ",":meat_on_bone:":"๐Ÿ–",":shell:":"๐Ÿš",":poodle:":"๐Ÿฉ",":stew:":"๐Ÿฒ",":jeans:":"๐Ÿ‘–",":honey_pot:":"๐Ÿฏ",":unlock:":"๐Ÿ”“",":black_nib:":"โœ’",":snowboarder:":"๐Ÿ‚",":white_flower:":"๐Ÿ’ฎ",":necktie:":"๐Ÿ‘”",":womens:":"๐Ÿšบ",":ant:":"๐Ÿœ",":city_sunset:":"๐ŸŒ‡",":dragon_face:":"๐Ÿฒ",":snail:":"๐ŸŒ",":dvd:":"๐Ÿ“€",":shirt:":"๐Ÿ‘•",":game_die:":"๐ŸŽฒ",":dolls:":"๐ŸŽŽ",":8ball:":"๐ŸŽฑ",":bus:":"๐ŸšŒ",":custard:":"๐Ÿฎ",":camel:":"๐Ÿซ",":curry:":"๐Ÿ›",":hospital:":"๐Ÿฅ",":bell:":"๐Ÿ””",":pear:":"๐Ÿ",":door:":"๐Ÿšช",":saxophone:":"๐ŸŽท",":church:":"โ›ช",":bicyclist:":"๐Ÿšด",":dango:":"๐Ÿก",":office:":"๐Ÿข",":rowboat:":"๐Ÿšฃ",":womans_hat:":"๐Ÿ‘’",":mans_shoe:":"๐Ÿ‘ž",":love_hotel:":"๐Ÿฉ",":mount_fuji:":"๐Ÿ—ป",":handbag:":"๐Ÿ‘œ",":hourglass:":"โŒ›",":trumpet:":"๐ŸŽบ",":school:":"๐Ÿซ",":cow2:":"๐Ÿ„",":toilet:":"๐Ÿšฝ",":pig2:":"๐Ÿ–",":violin:":"๐ŸŽป",":credit_card:":"๐Ÿ’ณ",":ferris_wheel:":"๐ŸŽก",":bowling:":"๐ŸŽณ",":barber:":"๐Ÿ’ˆ",":purse:":"๐Ÿ‘›",":rat:":"๐Ÿ€",":date:":"๐Ÿ“…",":ram:":"๐Ÿ",":tokyo_tower:":"๐Ÿ—ผ",":kimono:":"๐Ÿ‘˜",":ship:":"๐Ÿšข",":mag_right:":"๐Ÿ”Ž",":mag:":"๐Ÿ”",":fire_engine:":"๐Ÿš’",":police_car:":"๐Ÿš“",":black_joker:":"๐Ÿƒ",":package:":"๐Ÿ“ฆ",":calendar:":"๐Ÿ“†",":horse_racing:":"๐Ÿ‡",":tiger2:":"๐Ÿ…",":boot:":"๐Ÿ‘ข",":ambulance:":"๐Ÿš‘",":boar:":"๐Ÿ—",":pound:":"๐Ÿ’ท",":ox:":"๐Ÿ‚",":rice_ball:":"๐Ÿ™",":sandal:":"๐Ÿ‘ก",":tent:":"โ›บ",":seat:":"๐Ÿ’บ",":taxi:":"๐Ÿš•",":briefcase:":"๐Ÿ’ผ",":newspaper:":"๐Ÿ“ฐ",":circus_tent:":"๐ŸŽช",":mens:":"๐Ÿšน",":flashlight:":"๐Ÿ”ฆ",":foggy:":"๐ŸŒ",":bamboo:":"๐ŸŽ",":ticket:":"๐ŸŽซ",":helicopter:":"๐Ÿš",":minidisc:":"๐Ÿ’ฝ",":oncoming_bus:":"๐Ÿš",":melon:":"๐Ÿˆ",":notebook:":"๐Ÿ““",":no_bell:":"๐Ÿ”•",":oden:":"๐Ÿข",":flags:":"๐ŸŽ",":blowfish:":"๐Ÿก",":sweet_potato:":"๐Ÿ ",":ski:":"๐ŸŽฟ",":construction:":"๐Ÿšง",":satellite:":"๐Ÿ“ก",":euro:":"๐Ÿ’ถ",":ledger:":"๐Ÿ“’",":leopard:":"๐Ÿ†",":truck:":"๐Ÿšš",":sake:":"๐Ÿถ",":railway_car:":"๐Ÿšƒ",":speedboat:":"๐Ÿšค",":vhs:":"๐Ÿ“ผ",":yen:":"๐Ÿ’ด",":mute:":"๐Ÿ”‡",":wheelchair:":"โ™ฟ",":paperclip:":"๐Ÿ“Ž",":atm:":"๐Ÿง",":telescope:":"๐Ÿ”ญ",":rice_scene:":"๐ŸŽ‘",":blue_book:":"๐Ÿ“˜",":postbox:":"๐Ÿ“ฎ",":e-mail:":"๐Ÿ“ง",":mouse2:":"๐Ÿ",":nut_and_bolt:":"๐Ÿ”ฉ",":hotel:":"๐Ÿจ",":wc:":"๐Ÿšพ",":green_book:":"๐Ÿ“—",":tractor:":"๐Ÿšœ",":fountain:":"โ›ฒ",":metro:":"๐Ÿš‡",":clipboard:":"๐Ÿ“‹",":no_smoking:":"๐Ÿšญ",":slot_machine:":"๐ŸŽฐ",":bathtub:":"๐Ÿ›",":scroll:":"๐Ÿ“œ",":station:":"๐Ÿš‰",":rice_cracker:":"๐Ÿ˜",":bank:":"๐Ÿฆ",":wrench:":"๐Ÿ”ง",":bar_chart:":"๐Ÿ“Š",":minibus:":"๐Ÿš",":tram:":"๐ŸšŠ",":microscope:":"๐Ÿ”ฌ",":bookmark:":"๐Ÿ”–",":pouch:":"๐Ÿ‘",":fax:":"๐Ÿ“ ",":sound:":"๐Ÿ”‰",":chart:":"๐Ÿ’น",":floppy_disk:":"๐Ÿ’พ",":post_office:":"๐Ÿฃ",":speaker:":"๐Ÿ”ˆ",":japan:":"๐Ÿ—พ",":mahjong:":"๐Ÿ€„",":orange_book:":"๐Ÿ“™",":restroom:":"๐Ÿšป",":train:":"๐Ÿš‹",":trolleybus:":"๐ŸšŽ",":postal_horn:":"๐Ÿ“ฏ",":factory:":"๐Ÿญ",":train2:":"๐Ÿš†",":pager:":"๐Ÿ“Ÿ",":outbox_tray:":"๐Ÿ“ค",":mailbox:":"๐Ÿ“ซ",":light_rail:":"๐Ÿšˆ",":busstop:":"๐Ÿš",":file_folder:":"๐Ÿ“",":card_index:":"๐Ÿ“‡",":monorail:":"๐Ÿš",":no_bicycles:":"๐Ÿšณ",":hugging:":"๐Ÿค—",":thinking:":"๐Ÿค”",":nerd:":"๐Ÿค“",":zipper_mouth:":"๐Ÿค",":rolling_eyes:":"๐Ÿ™„",":upside_down:":"๐Ÿ™ƒ",":slight_smile:":"๐Ÿ™‚",":writing_hand:":"โœ",":eye:":"๐Ÿ‘",":man_in_suit:":"๐Ÿ•ด",":golfer:":"๐ŸŒ",":golfer_woman:":"๐ŸŒโ€โ™€",":anger_right:":"๐Ÿ—ฏ",":coffin:":"โšฐ",":gear:":"โš™",":alembic:":"โš—",":scales:":"โš–",":keyboard:":"โŒจ",":shield:":"๐Ÿ›ก",":bed:":"๐Ÿ›",":ballot_box:":"๐Ÿ—ณ",":compression:":"๐Ÿ—œ",":wastebasket:":"๐Ÿ—‘",":file_cabinet:":"๐Ÿ—„",":trackball:":"๐Ÿ–ฒ",":printer:":"๐Ÿ–จ",":joystick:":"๐Ÿ•น",":hole:":"๐Ÿ•ณ",":candle:":"๐Ÿ•ฏ",":prayer_beads:":"๐Ÿ“ฟ",":amphora:":"๐Ÿบ",":label:":"๐Ÿท",":film_frames:":"๐ŸŽž",":level_slider:":"๐ŸŽš",":thermometer:":"๐ŸŒก",":motorway:":"๐Ÿ›ฃ",":synagogue:":"๐Ÿ•",":mosque:":"๐Ÿ•Œ",":kaaba:":"๐Ÿ•‹",":stadium:":"๐ŸŸ",":desert:":"๐Ÿœ",":cityscape:":"๐Ÿ™",":camping:":"๐Ÿ•",":rosette:":"๐Ÿต",":volleyball:":"๐Ÿ",":medal:":"๐Ÿ…",":popcorn:":"๐Ÿฟ",":champagne:":"๐Ÿพ",":hot_pepper:":"๐ŸŒถ",":burrito:":"๐ŸŒฏ",":taco:":"๐ŸŒฎ",":hotdog:":"๐ŸŒญ",":shamrock:":"โ˜˜",":comet:":"โ˜„",":turkey:":"๐Ÿฆƒ",":scorpion:":"๐Ÿฆ‚",":lion_face:":"๐Ÿฆ",":crab:":"๐Ÿฆ€",":spider_web:":"๐Ÿ•ธ",":spider:":"๐Ÿ•ท",":chipmunk:":"๐Ÿฟ",":fog:":"๐ŸŒซ",":chains:":"โ›“",":pick:":"โ›",":stopwatch:":"โฑ",":ferry:":"โ›ด",":mountain:":"โ›ฐ",":ice_skate:":"โ›ธ",":skier:":"โ›ท",":sad:":"๐Ÿ˜ฅ",":egg:":"๐Ÿฅš",":drum:":"๐Ÿฅ"}; -function convertShortcodes(string){ - if (string.split(":").length>2){ - for (var i in emojiShortCodes) { - if (string.includes(i)) { - string = string.replaceAll(i, emojiShortCodes[i]); - } - } - } - return string; -} - - -var sanitizeChat = function(string) { - var temp = document.createElement('div'); - temp.innerText = string; - temp.innerText = temp.innerHTML; - temp = temp.textContent || temp.innerText || ""; - temp = temp.substring(0, Math.min(temp.length, 500)); - return temp.trim(); -}; - -var sanitizeString = function(str) { - str = str.replace(/[^a-z0-9รกรฉรญรณรบรฑรผ \.,_-]/gim, ""); - return str.trim(); -}; - -var sanitizeLabel = function(string) { - let temp = document.createElement("div"); - temp.innerText = string; - temp.innerText = temp.innerHTML; - temp = temp.textContent || temp.innerText || ""; - temp = temp.substring(0, Math.min(temp.length, 50)); - return temp.trim(); -}; - -var sanitizeRoomName = function(roomid) { - roomid = roomid.trim(); - if (roomid === "") { - return roomid; - } else if (roomid === false) { - return roomid; - } - - var sanitized = roomid.replace(/[\W]+/g, "_"); - if (sanitized !== roomid) { - if (!(session.cleanOutput)) { - warnUser("Info: Only AlphaNumeric characters should be used for the room name.\n\nThe offending characters have been replaced by an underscore"); - } - } - if (sanitized.length > 30) { - sanitized = sanitized.substring(0, 30); - if (!(session.cleanOutput)) { - warnUser("The Room name should be less than 31 alPhaNuMeric characters long.\n\nWe will trim it to length."); - } - } - return sanitized; -}; - -var sanitizePassword = function(passwrd) { - if (passwrd === "") { - return passwrd; - } else if (passwrd === false) { - return passwrd; - } else if (passwrd === null) { - return passwrd; - } - passwrd = passwrd.trim(); - if (passwrd.length < 1) { - if (!(session.cleanOutput)) { - warnUser("The password provided was blank."); - } - } - var sanitized = encodeURIComponent(passwrd);//.replace(/[\W]+/g, "_"); - //if (sanitized !== passwrd) { - // if (!(session.cleanOutput)) { - // warnUser("Info: Only AlphaNumeric characters should be used in the password.\n\nThe offending characters have been replaced by an underscore"); - // } - //} - return sanitized; -}; - -function isOperaGX(){ - return (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/75') >= 0; -} - -function getChromeVersion() { - var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); - return raw ? parseInt(raw[2], 10) : false; -} - -if (!(getChromeVersion()>=57)){ - getById("effectSelector").disabled=true; - getById("effectSelector3").disabled=true; - getById("effectSelector").title = "Effects are only support on Chromium-based browsers"; - getById("effectSelector3").title = "Effects are only support on Chromium-based browsers"; - var elements = document.querySelectorAll('[data-effectsNotice]'); - for (let i = 0; i < elements.length; i++) { - elements[i].style.display = "inline-block"; - } -} - -function safariVersion() { - var ver = 0; - try { - ver = navigator.appVersion.split("Version/"); - if (ver.length > 1) { - ver = ver[1].split(" Safari"); - } - if (ver.length > 1) { - ver = ver[0].split("."); - } - if (ver.length > 1) { - ver = parseInt(ver[0]); - } else { - ver = 0; - } - } catch (e) { - return 0; - } - return ver; -} - -if (urlParams.has('optimize')) { - session.optimize = parseInt(urlParams.get('optimize')) || 0; -} -var visAudioTimeout = null -document.addEventListener("visibilitychange", function() { - //log("hidden : " +document.hidden); - log("vis : "+document.visibilityState); - if ((iOS) || (iPad)) { // fixes a bug on iOS devices. Not need with other devices? - clearTimeout(visAudioTimeout); - if (document.visibilityState === 'visible') { - visAudioTimeout = setTimeout(function() { - resetupAudioOut(); - activatedPreview=false; - grabAudio("videosource", "#audioSource3"); - }, 500); - } - } -}); -function obsSceneChanged(event){ - log(event.detail.name); - window.obsstudio.getCurrentScene(function(scene) { - log("OBS SCENE"); - log(scene); - }); -} -function obsStreamingStarted(event){ - session.obsState.streaming = true; - session.obsStateSync(); -} -function obsStreamingStopped(event){ - session.obsState.streaming = false; - session.obsStateSync(); -} -function obsRecordingStarted(event){ - session.obsState.recording = true; - session.obsStateSync(); -} -function obsRecordingStopped(event){ - session.obsState.recording = false; - session.obsStateSync(); -} -function obsSourceActiveChanged(event){ - warnlog("obsSourceActiveChanged"); - warnlog( event.detail); - - try { - if (typeof event==="boolean"){var sourceActive = event;} - else if (typeof event.detail === "boolean"){var sourceActive = event.detail;} - else if (typeof event.detail.active === "boolean"){var sourceActive = event.detail.active;} - else {var sourceActive = event.detail.active;} + log("MAKE DRAGGABLE"); + delayedStartupFuncs.push([makeDraggableElement, document.getElementById("subControlButtons")]); - if (typeof sourceActive === "undefined"){return;} // Just fail. - - if (session.obsState.sourceActive!==sourceActive){ // only move forward if there is a change; the event likes to double fire you see. - session.obsState.sourceActive = sourceActive; - session.obsStateSync(); + if (safariVersion() && !getChromeVersion()){ + getById("SafariWarning").style.display = "block"; } - - } catch (e){errorlog(e);} -} + } -function obsSourceVisibleChanged(event){ // accounts for visible in VDO.Ninja scene AND visible in OBS scene - warnlog("obsSourceVisibleChanged"); - warnlog(event.detail); - try { - if (typeof event==="boolean"){var visibility = event;} - else if (typeof event.detail === "boolean"){var visibility = event.detail;} - else if (typeof event.detail.visible === "boolean"){var visibility = event.detail.visible;} - else {var visibility = event.detail.visible;} - - if (typeof visibility === "undefined"){ // fall back - if (typeof document.visibilityState !== "undefined"){ - visibility = document.visibilityState==="visible"; // modern - } else if (typeof document.hidden !== "undefined"){ - visibility = !document.hidden; // legacy - } else { - return; // ... unknown input? fail. - } - } - errorlog("visibility: "+visibility); - - if (session.obsState.visibility!==visibility){ // only move forward if there is a change; the event likes to double fire you see. - session.obsState.visibility = visibility; - session.obsStateSync(); - } - - } catch (e){errorlog(e);} -} - -if (window.obsstudio) { - session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? - session.audioMeterGuest = false; - session.audioEffects = false; - session.obsfix = 15; // can be manually set via URL. ; VP8=15, VP9=30. (previous was 20.) - try { - log("OBS VERSION:" + window.obsstudio.pluginVersion); - log("macOS: " + navigator.userAgent.indexOf('Mac OS X') != -1); - log(window.obsstudio); - - if (typeof document.visibilityState !== "undefined"){ - session.obsState.visibility = document.visibilityState==="visible"; - //session.obsState.sourceActive = session.obsState.visibility; - } - - window.obsstudio.getStatus(function(obsStatus) { - log("OBS STATUS:"); - log(obsStatus); - // TODO: update state here - if ("recording" in obsStatus){ - session.obsState.recording = obsStatus.recording; - } - if ("streaming" in obsStatus){ - session.obsState.streaming = obsStatus.streaming; - } + if ((iOS) || (iPad)) { + window.addEventListener('resize', function() { // Safari is the new IE. + var msg = {}; + msg.requestSceneUpdate = true; + session.sendMessage(msg); + if ( window.matchMedia("(orientation: portrait)").matches ) { + document.getElementsByTagName("html")[0].style.height = "100vh"; + setTimeout(function(){ + document.getElementsByTagName("html")[0].style.height = "100%"; + }, 1000); + } else if ( window.matchMedia("(orientation: landscape)").matches ) { + document.getElementsByTagName("html")[0].style.height = "100vh"; + setTimeout(function(){ + document.getElementsByTagName("html")[0].style.height = "100%"; + }, 1000); + } }); - - if (!(urlParams.has('streamlabs'))) { - - var ver = window.obsstudio.pluginVersion; - ver1 = ver.split("."); - - var cefVersion = getChromeVersion(); - - if (ver1.length == 3) { // Should be 3, but disabled3 - if ((ver1.length == 3) && (parseInt(ver1[0]) == 2) && (cefVersion < 76) && (navigator.userAgent.indexOf('Mac OS X') != -1)) { - updateURL("streamlabs"); - getById("main").innerHTML = "

Update OBS Studio to v26.1.2 or newer; older versions and StreamLabs OBS are not supported on macOS.\ -
download here: https://github.com/obsproject/obs-studio/releases/tag/26.1.2\ -



\ -

Please use the Electron Capture app if there are further problems or if you wish to use StreamLabs on macOS still.

\ -
You can find more details within our wiki guide - https://github.com/steveseguin/obsninja/wiki/FAQ#mac-os\ -
You can bypass this error message by refreshing, Clicking Here, or by adding &streamlabs to the URL, but it may still not actually work.\ - \ -
Please report this problem to steve@seguin.email if you feel it is an error.\ -
"; - } - } - } - - if (navigator.userAgent.indexOf('Mac OS X') != -1) { - session.codec = "h264"; // default the codec to h264 if OBS is on macOS (that's all it supports with hardware) - } - - if (session.disableOBS===false){ - window.addEventListener("obsSourceVisibleChanged", obsSourceVisibleChanged); - window.addEventListener("obsSourceActiveChanged", obsSourceActiveChanged); - window.addEventListener("obsSceneChanged", obsSceneChanged); - window.addEventListener("obsStreamingStarted", obsStreamingStarted); - window.addEventListener("obsStreamingStopped", obsStreamingStopped); - window.addEventListener("obsRecordingStarted", obsRecordingStarted); - window.addEventListener("obsRecordingStopped", obsRecordingStopped); - } - - } catch (e) { - errorlog(e); - } -} - -function manageSceneState(data, UUID){ - if (session.disableOBS){return;} - var processNeeded = false - try{ - if ("sceneDisplay" in data){ - processNeeded=true; - session.pcs[UUID].sceneDisplay = data.sceneDisplay; - } - if ("sceneMute" in data){ - processNeeded=true; - session.pcs[UUID].sceneMute = data.sceneMute; - } - if ("obsSourceActive" in data){ - processNeeded=true; - session.pcs[UUID].obsSourceActive = data.obsSourceActive; - } - if ("obsVisibility" in data){ - processNeeded=true; - session.pcs[UUID].obsVisibility = data.obsVisibility; - session.optimizeBitrate(UUID); // &optimize flag; sets video bitrate to target value if this flag == HIDDEN (if optimize=0, disables both audio and video) - } - if ("obsStreaming" in data){ - processNeeded=true; - session.pcs[UUID].obsStreaming = data.obsStreaming; - } - if ("obsRecording" in data){ - processNeeded=true; - session.pcs[UUID].obsRecording = data.obsRecording; - } - } catch(e){} // just in case the client has disconnected. - - if (processNeeded){ - applySceneState(); - } -} - -function applySceneState(){ - if (session.disableOBS){return;} - if (session.cleanOutput===false){ - if (document.getElementById("videosource")){ - var visibility = false; - var ondeck = false; - var recording = false; - for (var uid in session.pcs){ - - if (session.pcs[uid].obsSourceActive!==false && session.pcs[uid].obsVisibility && (session.pcs[uid].sceneDisplay!==false)){ - visibility=true; - } else if (session.pcs[uid].obsVisibility && (session.pcs[uid].sceneDisplay!==false)){ - ondeck=true; - } - if ((session.pcs[uid].obsRecording || session.pcs[uid].obsStreaming) && (session.pcs[uid].obsSourceActive!==false && session.pcs[uid].obsVisibility && (session.pcs[uid].sceneDisplay!==false))){ // the scene that is recording must be visible also. - recording=true; - } - } - - if (recording){ - getById("obsState").classList.remove("ondeck"); - getById("obsState").classList.add("recording"); // TODO: this needs to check all peers to make sure it's valid - getById("obsState").innerHTML = "ON AIR"; - } else if (ondeck && !visibility){ - getById("obsState").classList.remove("recording"); - getById("obsState").classList.add("ondeck"); // TODO: this needs to check all peers to make sure it's valid - getById("obsState").innerHTML = "STAND BY"; - } else { - getById("obsState").classList.remove("recording"); - getById("obsState").classList.remove("ondeck"); - getById("obsState").innerHTML = "ACTIVE"; - } - - if (visibility){ // BASIC TALLY LIGHT (on deck disabled) - getById("obsState").classList.add("onair"); // LIVE - } else { - getById("obsState").classList.remove("onair"); - - } - } - } -} - -window.onload = function winonLoad() { // This just keeps people from killing the live stream accidentally. Also give me a headsup that the stream is ending - window.addEventListener("beforeunload", function(e) { - try { - session.ws.close(); - if (session.videoElement.recording) { - session.videoElement.recorder.writer.close(); - session.videoElement.recording = false; - } - for (var i in session.rpcs) { - if (session.rpcs[i].videoElement) { - if (session.rpcs[i].videoElement.recording) { - session.rpcs[i].videoElement.recorder.writer.close(); - session.rpcs[i].videoElement.recording = false; - } - } - } - } catch (e) {} - //setTimeout(function(){session.hangup();},0); - return undefined; // ADDED OCT 29th; get rid of popup. Just close the socket connection if the user is refreshing the page. It's one or the other. - - }); -}; - -getById("credits").innerHTML = "Version: " + session.version + " - " + getById("credits").innerHTML; - -var lastTouchEnd = 0; -document.addEventListener('touchend', function(event) { - var now = (new Date()).getTime(); - if (now - lastTouchEnd <= 300) { - event.preventDefault(); - } - lastTouchEnd = now; -}, false); - - -document.addEventListener('click', function(event) { - if (session.firstPlayTriggered == false) { - playAllVideos(); - session.firstPlayTriggered = true; - history.pushState({}, ''); - } -}); -var Callbacks = []; -var CtrlPressed = false; // global -var AltPressed = false; -document.addEventListener("keydown", event => { - - if ((event.ctrlKey) || (event.metaKey)) { // detect if CTRL is pressed - CtrlPressed = true; - } else { - CtrlPressed = false; - } - if (event.altKey) { - AltPressed = true; - } else { - AltPressed = false; } - - if (CtrlPressed && event.keyCode) { - - if (event.keyCode == 77) { // m - if (event.metaKey) { - if (AltPressed) { - toggleMute(); // macOS - } - } else { - toggleMute(); // Windows - } - // } else if (event.keyCode == 69) { // e - // hangup(); - } else if (event.keyCode == 66) { // b - toggleVideoMute(); - } - } - - -}); - -document.addEventListener("keyup", event => { - if (!((event.ctrlKey) || (event.metaKey))) { - if (CtrlPressed) { - CtrlPressed = false; - for (var i in Callbacks) { - var cb = Callbacks[i]; - log(cb.slice(1)); - cb[0](...cb.slice(1)); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#A_better_apply - } - Callbacks = []; - } - } - if (!(event.altKey)) { - AltPressed = false; - } -}); - -window.onpopstate = function() { - if (session.firstPlayTriggered) { - window.location.reload(true); - } -}; - -if (typeof session === 'undefined') { // make sure to init the WebRTC if not exists. - var session = WebRTC.Media; - session.streamID = session.generateStreamID(); - errorlog("Serious error: WebRTC session didn't load in time"); -} - -if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { - try { - getById("electronDragZone").style.cursor="grab"; - const ipcRenderer = require('electron').ipcRenderer; - window.prompt = function(title, val){ - return ipcRenderer.sendSync('prompt', {title, val}); - }; - } catch(e){} -} - -function makeDraggableElement(elmnt) { - try { - elmnt.dragElement = false; - elmnt.style.bottom = "auto"; - elmnt.style.cursor = "grab"; - elmnt.stashonmouseup = null; - elmnt.stashonmousemove = null; - - } catch (e) { - errorlog(e); - return; - } - - var pos1 = 0; - var pos2 = 0; - var pos3 = 0; - var pos4 = 0; - - function dragMouseDown(e) { - e = e || window.event; - e.preventDefault(); - - pos3 = e.clientX; - pos4 = e.clientY; - elmnt.stashonmouseup = document.onmouseup; // I don't want to interfere with other drag events. - elmnt.stashonmousemove = document.onmousemove; - - document.onmouseup = closeDragElement; - document.onmousemove = elementDrag; - } - - function elementDrag(e) { - e = e || window.event; - e.preventDefault(); - - elmnt.dragElement = true; - pos1 = pos3 - e.clientX; - pos2 = pos4 - e.clientY; - pos3 = e.clientX; - pos4 = e.clientY; - - var topDrag = (elmnt.offsetTop - pos2); - if (topDrag > -3) { - topDrag = -3; - } - elmnt.style.top = topDrag + "px"; - elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; - - } - - elmnt.onmousedown = dragMouseDown; - function closeDragElement() { - document.onmouseup = elmnt.stashonmouseup; - document.onmousemove = elmnt.stashonmousemove; - } -} - -function setStorage(cname, cvalue, exdays=999){ // not actually a cookie - var now = new Date(); - var item = { - value: cvalue, - expiry: now.getTime() + (exdays * 24 * 60 * 60 * 1000), - }; - localStorage.setItem(cname, JSON.stringify(item)); -} - -function getStorage(cname) { - var itemStr = localStorage.getItem(cname); - if (!itemStr) { - return ""; - } - var item = JSON.parse(itemStr); - var now = new Date(); - if (now.getTime() > item.expiry) { - localStorage.removeItem(cname); - return ""; - } - return item.value; -} - -if (!isIFrame){ - if (getStorage("redirect") == "yes") { - setStorage("redirect", "", 0); - session.sticky = true; - } else if (getStorage("settings") != "") { - if (!(session.cleanOutput)){ - window.focus(); - session.sticky = confirm("Would you like you load your previous session's settings?"); - if (!session.sticky) { - setStorage("settings", "", 0); - log("deleting cookie as user said no"); - } else { - var cookieSettings = decodeURI(getStorage("settings")); - setStorage("redirect", "yes", 1); - window.location.replace(cookieSettings); - } - } - } - - if (urlParams.has('sticky')){ // won't work with iframes. - - //if (getStorage("permission") == "") { - // session.sticky = confirm("Would you allow us to store a cookie to keep your session settings persistent?"); - //} else { - session.sticky = true; - //} - //if (session.sticky) { - setStorage("permission", "yes", 999); - setStorage("settings", encodeURI(window.location.href), 90); - //} - } -} - -if (urlParams.has('cleanoutput') || urlParams.has('clean') || urlParams.has('cleanish')) { - session.cleanOutput = true; -} - -if (urlParams.has('retrytimeout')) { - session.retryTimeout = parseInt(urlParams.get('retrytimeout')); -} - -if (urlParams.has('ptz')){ - session.ptz=true; -} - -var screensharebutton = true; -var screensharesupport = true; -if (urlParams.has('nosettings') || urlParams.has('ns')) { - screensharebutton = false; - session.showSettings = false; -} - -if (urlParams.has('nomicbutton') || urlParams.has('nmb')) { - getById("mutebutton").setAttribute('style', "display: none !important"); -} - - -if (urlParams.has('novideobutton') || urlParams.has('nvb')) { - getById("mutevideobutton").setAttribute('style', "display: none !important"); -} - -if (urlParams.has('screenshareid') || urlParams.has('ssid')) { - if (urlParams.get('screenshareid') || urlParams.get('ssid')) { - session.screenshareid = urlParams.get('screenshareid') || urlParams.get('ssid'); - session.screenshareid = sanitizeStreamID(session.screenshareid); - } -} - -if (urlParams.has('screensharefps') || urlParams.has('ssfps')) { - if (urlParams.get('screensharefps') || urlParams.get('ssfps')) { - session.screensharefps = urlParams.get('screensharefps') || urlParams.get('ssfps'); - session.screensharefps = parseInt(session.screensharefps) || 2; - } -} - -if (urlParams.has('screensharequality') || urlParams.has('ssq')) { - if (urlParams.get('screensharequality') || urlParams.get('ssq')) { - session.screensharequality = urlParams.get('screensharequality') || urlParams.get('ssq'); - session.screensharequality = parseInt(session.screensharequality) || 1; - } -} - -if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { - //session.webcamonly = true; - session.mobile = true; - getById("shareScreenGear").style.display = "none"; - screensharebutton = false; - screensharesupport = false; - getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("dropButton").style.display = "none"; - //session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? - session.audioEffects = false; // disable audio inbound effects also. - session.audioMeterGuest = false; - -} else if ((iOS) || (iPad)) { - getById("shareScreenGear").style.display = "none"; - session.mobile = true; - screensharebutton = false; - screensharesupport = false; - getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("dropButton").style.display = "none"; - //session.audiobitrate = false; // iOS devices seem to get distortion with custom audio bitrates. Disable for now. - //session.maxiosbitrate = 10; // this is 10-kbps by default already. - //session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? - session.audioEffects = false; // disable audio inbound effects also. - session.audioMeterGuest = false; -} else { - log("MAKE DRAGGABLE"); - setTimeout(function(){makeDraggableElement(document.getElementById("subControlButtons"));},100); - - if (safariVersion() && !getChromeVersion()){ - getById("SafariWarning").style.display = "block"; - } -} - - -if ((iOS) || (iPad)) { - window.addEventListener('resize', function() { // Safari is the new IE. - var msg = {}; - msg.requestSceneUpdate = true; - session.sendMessage(msg); - - if ( window.matchMedia("(orientation: portrait)").matches ) { - document.getElementsByTagName("html")[0].style.height = "100vh"; - setTimeout(function(){ - document.getElementsByTagName("html")[0].style.height = "100%"; - }, 1000); - } else if ( window.matchMedia("(orientation: landscape)").matches ) { - document.getElementsByTagName("html")[0].style.height = "100vh"; - setTimeout(function(){ - document.getElementsByTagName("html")[0].style.height = "100%"; - }, 1000); - } - }); -} - -if (/CriOS/i.test(navigator.userAgent) && (iOS || iPad)) { - if (!(session.cleanOutput)) { - try { - navigator.mediaDevices.getUserMedia; - } catch (e) { - warnUser("Chrome on this device does not support the required technology to use this site.\n\nPlease use Safari instead or update your iOS and browser version."); - } - } -} - -if (urlParams.has('broadcast') || urlParams.has('bc')) { - log("Broadcast flag set"); - session.broadcast = urlParams.get('broadcast') || urlParams.get('bc') || null; - //if ((iOS) || (iPad)) { - // session.nopreview = false; - //} else { - // session.nopreview = true; - //} - session.minipreview = 2; // full screen if nothing else on screen. - session.style = 1; - getById("header").style.display = "none"; - getById("header").style.opacity = 0; - session.showList=false; -} - -if (urlParams.has('showlist')) { - session.showList = urlParams.get('showlist'); - if (session.showList === "false") { - session.showList = false; - } else if (session.showList=== "0") { - session.showList = false; - } else if (session.showList === "no") { - session.showList = false; - } else if (session.showList === "off") { - session.showList = false; - } else { - session.showList = true; - } -} - -var directorLanding = false; -if (urlParams.has('director') || urlParams.has('dir')) { - directorLanding = urlParams.get('director') || urlParams.get('dir') || null; - if (directorLanding === null) { - directorLanding = true; - } else if (directorLanding.length === 0) { - directorLanding = true; - } else { - directorLanding = false; - } - session.meterStyle = 1; -} else if (filename === "director") { - directorLanding = true; - filename = false; - session.meterStyle = 1; -} - -if (urlParams.has('rooms')) { - session.rooms = urlParams.get('rooms').split(",").map(function(e) { - return sanitizeRoomName(e); - }); - getById("rooms").classList.remove('advanced'); -} - -if (urlParams.has('showdirector')) { - session.showDirector = true; -} - -if (urlParams.has('midi') || urlParams.has('hotkeys')) { - session.midiHotkeys = urlParams.get('midi') || urlParams.get ('hotkeys') || 1; - session.midiHotkeys = parseInt(session.midiHotkeys); -} - -if (urlParams.has('midipush') || urlParams.has('midiout') || urlParams.has('mo')){ - session.midiOut = urlParams.get('midipush') || urlParams.get('midiout') || urlParams.get('mo') || true; -} - -if (urlParams.has('midipull') || urlParams.has('midiin') || urlParams.has('mi')){ - session.midiIn = urlParams.get('midipull') || urlParams.get('midiin') || urlParams.get('mi') || true; -} - -var loadedQRCode = false; -function loadQR(){ - if (loadedQRCode==false){ - loadedQRCode=true; - var script = document.createElement('script'); - script.src = "./thirdparty/qrcode.min.js"; // dynamically load this only if its needed. Keeps loading time down. - document.head.appendChild(script); - } -} - -if (urlParams.has('webcam') || urlParams.has('wc')) { - session.webcamonly = true; - screensharebutton = false; -} else if (urlParams.has('screenshare') || urlParams.has('ss')) { - session.screenshare = true; - if (urlParams.get('screenshare') || urlParams.get('ss')){ - session.screenshare = parseInt(urlParams.get('screenshare')); - } -} else if (urlParams.has('fileshare') || urlParams.has('fs')) { - getById("container-5").classList.remove('advanced'); - getById("container-5").classList.add("skip-animation"); - getById("container-5").classList.remove('pointer'); -} else if (directorLanding) { - getById("container-1").classList.remove('advanced'); - getById("container-1").classList.add("skip-animation"); - getById("container-1").classList.remove('pointer'); -} else if (urlParams.has('website') || urlParams.has('iframe')) { - getById("container-6").classList.remove('advanced'); - getById("container-6").classList.add("skip-animation"); - getById("container-6").classList.remove('pointer'); - session.website = urlParams.get('website') || urlParams.get('iframe') || false; - - if (session.website){ - if (session.director){ - setTimeout(function(){shareWebsite(session.website);},100); - } else { - setTimeout(function(){session.publishIFrame(session.website);},100); - - } - } -} - - -if (urlParams.has('ssb')) { - screensharebutton = true; -} - -if (urlParams.has('mute') || urlParams.has('muted') || urlParams.has('m')) { - session.muted = true; -} - -if (urlParams.has('videomute') || urlParams.has('videomuted') || urlParams.has('vm')) { - session.videoMutedFlag = true; -} - - -if (urlParams.has('deaf') || urlParams.has('deafen')) { - session.directorSpeakerMuted=true; // false == true in this case. -} - -if (urlParams.has('blind')) { - session.directorDisplayMuted=true; // false == true in this case. -} - - -if (urlParams.has('dpi') || urlParams.has('dpr')) { - session.devicePixelRatio = urlParams.get('dpi') || urlParams.get('dpr') || 2.0; -} //else if (window.devicePixelRatio && window.devicePixelRatio!==1){ -// session.devicePixelRatio = window.devicePixelRatio; // this annoys me to no end. -//} - -if (urlParams.has('speakermute') || urlParams.has('mutespeaker') || urlParams.has('sm') || urlParams.has('ms')) { - session.speakerMuted = true; - getById("mutespeakertoggle").className = "las la-volume-mute my-float toggleSize"; - //getById("mutespeakerbutton").className="advanced float2 red"; - getById("mutespeakerbutton").classList.add("red"); - getById("mutespeakerbutton").classList.add("float2"); - getById("mutespeakerbutton").classList.remove("float"); - - var sounds = document.getElementsByTagName("video"); - for (var i = 0; i < sounds.length; ++i) { - sounds[i].muted = session.speakerMuted; - } -} - -if (urlParams.has('chatbutton') || urlParams.has('chat') || urlParams.has('cb')) { - session.chatbutton = urlParams.get('chatbutton') || urlParams.get('chat') || urlParams.get('cb') || null; - if (session.chatbutton === "false") { - session.chatbutton = false; - } else if (session.chatbutton === "0") { - session.chatbutton = false; - } else if (session.chatbutton === "no") { - session.chatbutton = false; - } else if (session.chatbutton === "off") { - session.chatbutton = false; - } else { - session.chatbutton = true; - getById("chatbutton").classList.remove("advanced"); - } -} - -if (session.screenshare !== false) { - getById("container-3").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("container-2").classList.add("skip-animation"); - getById("container-2").classList.remove('pointer'); -} - -if (urlParams.has('manual')) { - session.manual = true; -} - -if (urlParams.has('hands') || urlParams.has('hand')) { - session.raisehands = true; -} - -if (urlParams.has('portrait') || urlParams.has('916') || urlParams.has('vertical')) { - session.aspectratio = 1; // 9:16 (default of 0 is 16:9) -} else if (urlParams.has('square') || urlParams.has('11')) { - session.aspectratio = 2; //1:1 ? -} - -if (urlParams.has('cover')) { - session.cover = true; - document.documentElement.style.setProperty('--fit-style', 'cover'); -} - -if (urlParams.has('record')) { - if (safariVersion()) { + if (/CriOS/i.test(navigator.userAgent) && (iOS || iPad)) { if (!(session.cleanOutput)) { - warnUser("Your browser or device is not supported. Try Chrome if on macOS."); + try { + navigator.mediaDevices.getUserMedia; + } catch (e) { + warnUser("Chrome on this device does not support the required technology to use this site.\n\nPlease use Safari instead or update your iOS and browser version."); + } } - } else { - session.recordLocal = urlParams.get('record'); + } - if (session.recordLocal != parseInt(session.recordLocal)) { - session.recordLocal = 6000; + + if (urlParams.has('broadcast') || urlParams.has('bc')) { + log("Broadcast flag set"); + session.broadcast = urlParams.get('broadcast') || urlParams.get('bc') || null; + //if ((iOS) || (iPad)) { + // session.nopreview = false; + //} else { + // session.nopreview = true; + //} + session.minipreview = 2; // full screen if nothing else on screen. + session.style = 1; + getById("header").style.display = "none"; + getById("header").style.opacity = 0; + session.showList=false; + } + + if (urlParams.has('showlist')) { + session.showList = urlParams.get('showlist'); + if (session.showList === "false") { + session.showList = false; + } else if (session.showList=== "0") { + session.showList = false; + } else if (session.showList === "no") { + session.showList = false; + } else if (session.showList === "off") { + session.showList = false; } else { - session.recordLocal = parseInt(session.recordLocal); + session.showList = true; } } -} -if (urlParams.has('pcm')) { - session.pcm = true; -} + + var filename = false; + try { + filename = window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1); + filename = filename.replace("??", "?"); + filename2 = filename.split("?")[0]; + // split at ??? + if (filename.split(".").length == 1) { + if (filename2.length < 2) { // easy win + filename = false; + } else if (filename.startsWith("&")) { // easy win + var tmpHref = window.location.href.substring(0, window.location.href.lastIndexOf('/')) + "/?" + filename.split("&").slice(1).join("&"); + log("TMP " + tmpHref); + updateURL(filename.split("&")[1], true, tmpHref); + filename = false; + } else if (filename2.split("&")[0].includes("=")) { + log("asdf " + filename.split("&")[0]); + if (history.pushState) { + var tmpHref = window.location.href.substring(0, window.location.href.lastIndexOf('/')); + tmpHref = tmpHref + "/?" + filename; + filename = false; + //warnUser("Please ensure your URL is correctly formatted."); + window.history.pushState({path: tmpHref.toString()}, '', tmpHref.toString()); + } + } else { + filename = filename2.split("&")[0]; + if (filename2 != filename) { + warnUser("Warning: Please ensure your URL is correctly formatted."); + } + } + } else { + filename = false; + } + log(filename); + } catch (e) { + errorlog(e); + } -if (urlParams.has('bigbutton')) { - session.bigmutebutton = true; - getById("mutebutton").style.width = "min(40vh,40vw)"; - getById("mutebutton").style.height = "min(40vh,40vw)"; - getById("mutetoggle").style.width = "min(40vh,40vw)"; - getById("mutetoggle").style.height = "min(40vh,40vw)"; -} + var directorLanding = false; + if (urlParams.has('director') || urlParams.has('dir')) { + directorLanding = urlParams.get('director') || urlParams.get('dir') || null; + if (directorLanding === null) { + directorLanding = true; + } else if (directorLanding.length === 0) { + directorLanding = true; + } else { + directorLanding = false; + } + session.meterStyle = 1; + } else if (filename === "director") { + directorLanding = true; + filename = false; + session.meterStyle = 1; + } -if (urlParams.has('scene')) { - session.scene = urlParams.get('scene') || 0; - if (typeof session.scene === "string"){ - session.scene = session.scene.replace(/[\W]+/g, "_"); - } else { - session.scene = (parseInt(session.scene) || 0) + ""; + if (urlParams.has('rooms')) { + session.rooms = urlParams.get('rooms').split(",").map(function(e) { + return sanitizeRoomName(e); + }); + getById("rooms").classList.remove('advanced'); + } + + if (urlParams.has('showdirector')) { + session.showDirector = true; + } + + if (urlParams.has('midi') || urlParams.has('hotkeys')) { + session.midiHotkeys = urlParams.get('midi') || urlParams.get ('hotkeys') || 1; + session.midiHotkeys = parseInt(session.midiHotkeys); + } + + if (urlParams.has('midipush') || urlParams.has('midiout') || urlParams.has('mo')){ + session.midiOut = urlParams.get('midipush') || urlParams.get('midiout') || urlParams.get('mo') || true; + } + + if (urlParams.has('midipull') || urlParams.has('midiin') || urlParams.has('mi')){ + session.midiIn = urlParams.get('midipull') || urlParams.get('midiin') || urlParams.get('mi') || true; + } + + + if (urlParams.has('webcam') || urlParams.has('wc')) { + session.webcamonly = true; + screensharebutton = false; + } else if (urlParams.has('screenshare') || urlParams.has('ss')) { + session.screenshare = true; + if (urlParams.get('screenshare') || urlParams.get('ss')){ + session.screenshare = parseInt(urlParams.get('screenshare')); + } + } else if (urlParams.has('fileshare') || urlParams.has('fs')) { + getById("container-5").classList.remove('advanced'); + getById("container-5").classList.add("skip-animation"); + getById("container-5").classList.remove('pointer'); + } else if (directorLanding) { + getById("container-1").classList.remove('advanced'); + getById("container-1").classList.add("skip-animation"); + getById("container-1").classList.remove('pointer'); + } else if (urlParams.has('website') || urlParams.has('iframe')) { + getById("container-6").classList.remove('advanced'); + getById("container-6").classList.add("skip-animation"); + getById("container-6").classList.remove('pointer'); + session.website = urlParams.get('website') || urlParams.get('iframe') || false; + if (session.website){ + if (session.director){ + delayedStartupFuncs.push([shareWebsite, session.website]); + } else { + delayedStartupFuncs.push([session.publishIFrame, session.website]); + } + } } - session.disableWebAudio = true; - session.audioEffects = false; - session.audioMeterGuest = false; -} -if (session.scene!=="1"){ // scene =0 and 1 should load instantly. - session.hiddenSceneViewBitrate = 0; // By default this is ~ 400kbps, but if you have 10 scenes, i don't want to kill things. -} -if (urlParams.has('scenetype') || urlParams.has('type')) { - session.sceneType = parseInt(urlParams.get('scenetype')) || parseInt(urlParams.get('type')) || false; -} - -if (urlParams.has('mediasettings')) { - session.forceMediaSettings = true; -} - - -if (urlParams.has('transcript') || urlParams.has('transcribe') || urlParams.has('trans')) { - session.transcript = urlParams.get('transcript') || urlParams.get('transcribe') || urlParams.get('trans') || "en-US"; -} - - -if (urlParams.has('cc') || urlParams.has('closedcaptions') || urlParams.has('captions')) { - session.closedCaptions = true; -} - -if (session.webcamonly == true) { - getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("container-3").classList.add("skip-animation"); - getById("container-3").classList.remove('pointer'); - setTimeout(function() { - previewWebcam(); - }, 100); -} - -if (urlParams.has('css')){ - var cssURL = urlParams.get('css'); - cssURL = decodeURI(cssURL); - log(cssURL); - var cssStylesheet = document.createElement('link'); - cssStylesheet.rel = 'stylesheet'; - cssStylesheet.type = 'text/css'; - cssStylesheet.media = 'screen'; - cssStylesheet.href = cssURL; - document.getElementsByTagName('head')[0].appendChild(cssStylesheet); - - cssStylesheet.onload = function() { - getById("main").classList.remove('hidden'); - log("loaded remote style sheet"); - }; - - cssStylesheet.onerror = function() { - getById("main").classList.remove('hidden'); - errorlog("REMOTE STYLE SHEET HAD ERROR"); - }; - -} else { - getById("main").classList.remove('hidden'); -} - -if (urlParams.has('password') || urlParams.has('pass') || urlParams.has('pw') || urlParams.has('p')) { - session.password = urlParams.get('password') || urlParams.get('pass') || urlParams.get('pw') || urlParams.get('p'); - if (!session.password) { - window.focus(); - session.password = prompt("Please enter the password below: \n\n(Note: Passwords are case-sensitive and you will not be alerted if it is incorrect.)"); - } else if (session.password === "false") { - session.password = false; - session.defaultPassword = false; - } else if (session.password === "0") { - session.password = false; - session.defaultPassword = false; - } else if (session.password === "off") { - session.password = false; - session.defaultPassword = false; + if (urlParams.has('ssb')) { + screensharebutton = true; } -} -if (session.password) { - session.password = sanitizePassword(session.password); - getById("passwordRoom").value = session.password; - session.defaultPassword = false; - getById("addPasswordBasic").style.display = "none"; -} + if (urlParams.has('mute') || urlParams.has('muted') || urlParams.has('m')) { + session.muted = true; + } + + if (urlParams.has('videomute') || urlParams.has('videomuted') || urlParams.has('vm')) { + session.videoMutedFlag = true; + } -if (urlParams.has('hash') || urlParams.has('crc') || urlParams.has('check')) { // could be brute forced in theory, so not as safe as just not using a hash check. - session.taintedSession = null; // waiting to see if valid or not. - var hash_input = urlParams.get('hash') || urlParams.get('crc') || urlParams.get('check'); - if (session.password === false) { - window.focus(); - session.password = prompt("Please enter the password below: \n\n(Note: Passwords are case-sensitive.)"); + if (urlParams.has('deaf') || urlParams.has('deafen')) { + session.directorSpeakerMuted=true; // false == true in this case. + } + + if (urlParams.has('blind')) { + session.directorDisplayMuted=true; // false == true in this case. + } + + + if (urlParams.has('dpi') || urlParams.has('dpr')) { + session.devicePixelRatio = urlParams.get('dpi') || urlParams.get('dpr') || 2.0; + } //else if (window.devicePixelRatio && window.devicePixelRatio!==1){ + // session.devicePixelRatio = window.devicePixelRatio; // this annoys me to no end. + //} + + if (urlParams.has('speakermute') || urlParams.has('mutespeaker') || urlParams.has('sm') || urlParams.has('ms')) { + session.speakerMuted = true; + getById("mutespeakertoggle").className = "las la-volume-mute my-float toggleSize"; + //getById("mutespeakerbutton").className="advanced float2 red"; + getById("mutespeakerbutton").classList.add("red"); + getById("mutespeakerbutton").classList.add("float2"); + getById("mutespeakerbutton").classList.remove("float"); + + var sounds = document.getElementsByTagName("video"); + for (var i = 0; i < sounds.length; ++i) { + sounds[i].muted = session.speakerMuted; + } + } + + if (urlParams.has('chatbutton') || urlParams.has('chat') || urlParams.has('cb')) { + session.chatbutton = urlParams.get('chatbutton') || urlParams.get('chat') || urlParams.get('cb') || null; + if (session.chatbutton === "false") { + session.chatbutton = false; + } else if (session.chatbutton === "0") { + session.chatbutton = false; + } else if (session.chatbutton === "no") { + session.chatbutton = false; + } else if (session.chatbutton === "off") { + session.chatbutton = false; + } else { + session.chatbutton = true; + getById("chatbutton").classList.remove("advanced"); + } + } + + if (session.screenshare !== false) { + getById("container-3").className = 'column columnfade advanced'; // Hide screen share on mobile + getById("container-2").classList.add("skip-animation"); + getById("container-2").classList.remove('pointer'); + } + + if (urlParams.has('manual')) { + session.manual = true; + } + + if (urlParams.has('hands') || urlParams.has('hand')) { + session.raisehands = true; + } + + if (urlParams.has('portrait') || urlParams.has('916') || urlParams.has('vertical')) { + session.aspectratio = 1; // 9:16 (default of 0 is 16:9) + } else if (urlParams.has('square') || urlParams.has('11')) { + session.aspectratio = 2; //1:1 ? + } + + if (urlParams.has('cover')) { + session.cover = true; + document.documentElement.style.setProperty('--fit-style', 'cover'); + } + + if (urlParams.has('record')) { + if (safariVersion()) { + if (!(session.cleanOutput)) { + warnUser("Your browser or device is not supported. Try Chrome if on macOS."); + } + } else { + session.recordLocal = urlParams.get('record'); + + if (session.recordLocal != parseInt(session.recordLocal)) { + session.recordLocal = 6000; + } else { + session.recordLocal = parseInt(session.recordLocal); + } + } + } + if (urlParams.has('pcm')) { + session.pcm = true; + } + + if (urlParams.has('bigbutton')) { + session.bigmutebutton = true; + getById("mutebutton").style.width = "min(40vh,40vw)"; + getById("mutebutton").style.height = "min(40vh,40vw)"; + getById("mutetoggle").style.width = "min(40vh,40vw)"; + getById("mutetoggle").style.height = "min(40vh,40vw)"; + + } + + if (urlParams.has('scene')) { + session.scene = urlParams.get('scene') || 0; + if (typeof session.scene === "string"){ + session.scene = session.scene.replace(/[\W]+/g, "_"); + } else { + session.scene = (parseInt(session.scene) || 0) + ""; + + } + session.disableWebAudio = true; + session.audioEffects = false; + session.audioMeterGuest = false; + } + if (session.scene!=="1"){ // scene =0 and 1 should load instantly. + session.hiddenSceneViewBitrate = 0; // By default this is ~ 400kbps, but if you have 10 scenes, i don't want to kill things. + } + + if (urlParams.has('scenetype') || urlParams.has('type')) { + session.sceneType = parseInt(urlParams.get('scenetype')) || parseInt(urlParams.get('type')) || false; + } + + if (urlParams.has('mediasettings')) { + session.forceMediaSettings = true; + } + + + if (urlParams.has('transcript') || urlParams.has('transcribe') || urlParams.has('trans')) { + session.transcript = urlParams.get('transcript') || urlParams.get('transcribe') || urlParams.get('trans') || "en-US"; + } + + + if (urlParams.has('cc') || urlParams.has('closedcaptions') || urlParams.has('captions')) { + session.closedCaptions = true; + } + + if (session.webcamonly == true) { + getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile + getById("container-3").classList.add("skip-animation"); + getById("container-3").classList.remove('pointer'); + delayedStartupFuncs.push([previewWebcam]); + } + + if (urlParams.has('css')){ + var cssURL = urlParams.get('css'); + cssURL = decodeURI(cssURL); + log(cssURL); + var cssStylesheet = document.createElement('link'); + cssStylesheet.rel = 'stylesheet'; + cssStylesheet.type = 'text/css'; + cssStylesheet.media = 'screen'; + cssStylesheet.href = cssURL; + document.getElementsByTagName('head')[0].appendChild(cssStylesheet); + + cssStylesheet.onload = function() { + getById("main").classList.remove('hidden'); + log("loaded remote style sheet"); + }; + + cssStylesheet.onerror = function() { + getById("main").classList.remove('hidden'); + errorlog("REMOTE STYLE SHEET HAD ERROR"); + }; + + } else { + getById("main").classList.remove('hidden'); + } + + if (urlParams.has('password') || urlParams.has('pass') || urlParams.has('pw') || urlParams.has('p')) { + session.password = urlParams.get('password') || urlParams.get('pass') || urlParams.get('pw') || urlParams.get('p'); + if (!session.password) { + window.focus(); + session.password = await promptAlt("Please enter the password below: \n\n(Note: Passwords are case-sensitive and you will not be alerted if it is incorrect.)"); + } else if (session.password === "false") { + session.password = false; + session.defaultPassword = false; + } else if (session.password === "0") { + session.password = false; + session.defaultPassword = false; + } else if (session.password === "off") { + session.password = false; + session.defaultPassword = false; + } + } + + if (session.password) { session.password = sanitizePassword(session.password); getById("passwordRoom").value = session.password; session.defaultPassword = false; + getById("addPasswordBasic").style.display = "none"; } - session.generateHash(session.password + session.salt, 6).then(function(hash) { // million to one error. - log("hash is " + hash); - if (hash.substring(0, 4) !== hash_input) { // hash crc checks are just first 4 characters. - session.taintedSession = true; - if (!(session.cleanOutput)) { - getById("request_info_prompt").innerHTML = "The password was incorrect.\n\nRefresh and try again."; - getById("request_info_prompt").style.display = "block"; - getById("mainmenu").style.display = "none"; - getById("head1").style.display = "none"; - session.cleanOutput = true; + if (urlParams.has('hash') || urlParams.has('crc') || urlParams.has('check')) { // could be brute forced in theory, so not as safe as just not using a hash check. + session.taintedSession = null; // waiting to see if valid or not. + var hash_input = urlParams.get('hash') || urlParams.get('crc') || urlParams.get('check'); + if (session.password === false) { + window.focus(); + session.password = await promptAlt("Please enter the password below: \n\n(Note: Passwords are case-sensitive.)"); + session.password = sanitizePassword(session.password); + getById("passwordRoom").value = session.password; + session.defaultPassword = false; + } + + session.generateHash(session.password + session.salt, 6).then(function(hash) { // million to one error. + log("hash is " + hash); + if (hash.substring(0, 4) !== hash_input) { // hash crc checks are just first 4 characters. + session.taintedSession = true; + if (!(session.cleanOutput)) { + getById("request_info_prompt").innerHTML = "The password was incorrect.\n\nRefresh and try again."; + getById("request_info_prompt").style.display = "block"; + getById("mainmenu").style.display = "none"; + getById("head1").style.display = "none"; + session.cleanOutput = true; + + } else { + getById("request_info_prompt").innerHTML = ""; + getById("request_info_prompt").style.display = "block"; + getById("mainmenu").style.display = "none"; + getById("head1").style.display = "none"; + } } else { - getById("request_info_prompt").innerHTML = ""; - getById("request_info_prompt").style.display = "block"; - getById("mainmenu").style.display = "none"; - getById("head1").style.display = "none"; + session.taintedSession = false; + session.hash = hash; } + }); + } + + if (session.defaultPassword !== false) { + session.password = session.defaultPassword; // no user entered password; let's use the default password if its not disabled. + } + + if (urlParams.has('showlabels') || urlParams.has('showlabel') || urlParams.has('sl')) { + session.showlabels = urlParams.get('showlabels') || urlParams.get('showlabel') || urlParams.get('sl') || ""; + session.showlabels = sanitizeLabel(session.showlabels.replace(/[\W]+/g, "_").replace(/_+/g, '_')); + if (session.showlabels == "") { + session.showlabels = true; + session.labelstyle = false; } else { - session.taintedSession = false; - session.hash = hash; + session.labelstyle = session.showlabels; + session.showlabels = true; } - }); -} - -if (session.defaultPassword !== false) { - session.password = session.defaultPassword; // no user entered password; let's use the default password if its not disabled. -} - -if (urlParams.has('showlabels') || urlParams.has('showlabel') || urlParams.has('sl')) { - session.showlabels = urlParams.get('showlabels') || urlParams.get('showlabel') || urlParams.get('sl') || ""; - session.showlabels = sanitizeLabel(session.showlabels.replace(/[\W]+/g, "_").replace(/_+/g, '_')); - if (session.showlabels == "") { - session.showlabels = true; - session.labelstyle = false; - } else { - session.labelstyle = session.showlabels; - session.showlabels = true; } -} -if (urlParams.has('sizelabel') || urlParams.has('labelsize') || urlParams.has('fontsize')) { - session.labelsize = urlParams.get('sizelabel') || urlParams.get('labelsize') || urlParams.get('fontsize') || 100; - session.labelsize = parseInt(session.labelsize); -} - -if (urlParams.has('label') || urlParams.has('l')) { - session.label = urlParams.get('label') || urlParams.get('l') || null; - var updateURLAsNeed = true; - if (session.label == null || session.label.length == 0) { - window.focus(); - session.label = prompt("Please enter your display name:"); - } else { - var updateURLAsNeed = false; - session.label = decodeURIComponent(session.label); - session.label = session.label.replace(/_/g, " ") + if (urlParams.has('sizelabel') || urlParams.has('labelsize') || urlParams.has('fontsize')) { + session.labelsize = urlParams.get('sizelabel') || urlParams.get('labelsize') || urlParams.get('fontsize') || 100; + session.labelsize = parseInt(session.labelsize); } - if (session.label != null) { - session.label = sanitizeLabel(session.label); // alphanumeric was too strict. - document.title = session.label; // what the result is. + + if (urlParams.has('label') || urlParams.has('l')) { + session.label = urlParams.get('label') || urlParams.get('l') || null; + var updateURLAsNeed = true; + if (session.label == null || session.label.length == 0) { + window.focus(); + session.label = await promptAlt("Please enter your display name:"); + } else { + var updateURLAsNeed = false; + session.label = decodeURIComponent(session.label); + session.label = session.label.replace(/_/g, " ") + } + if (session.label != null) { + session.label = sanitizeLabel(session.label); // alphanumeric was too strict. + document.title = session.label; // what the result is. - if (updateURLAsNeed) { - var label = encodeURIComponent(session.label); - if (urlParams.has('l')) { - updateURL("l=" + label, true, false); - } else { - updateURL("label=" + label, true, false); + if (updateURLAsNeed) { + var label = encodeURIComponent(session.label); + if (urlParams.has('l')) { + updateURL("l=" + label, true, false); + } else { + updateURL("label=" + label, true, false); + } } } } -} -if (urlParams.has('transparent')) { // sets the window to be transparent - useful for IFRAMES? - getById("main").style.backgroundColor = "rgba(0,0,0,0)"; - document.documentElement.style.setProperty('--container-color', '#0000'); - document.documentElement.style.setProperty('--background-color', '#0000'); - document.documentElement.style.setProperty('--regular-margin', '0'); - document.documentElement.style.setProperty('--director-margin', '0 25px 0 0'); - getById("directorLinksButton").style.color = "black"; - session.transparent=true; -} - -if (urlParams.has('stereo') || urlParams.has('s') || urlParams.has('proaudio')) { // both peers need this enabled for HD stereo to be on. If just pub, you get no echo/noise cancellation. if just viewer, you get high bitrate mono - log("STEREO ENABLED"); - session.stereo = urlParams.get('stereo') || urlParams.get('s') || urlParams.get('proaudio'); - - if (session.stereo) { - session.stereo = session.stereo.toLowerCase(); + if (urlParams.has('transparent')) { // sets the window to be transparent - useful for IFRAMES? + getById("main").style.backgroundColor = "rgba(0,0,0,0)"; + document.documentElement.style.setProperty('--container-color', '#0000'); + document.documentElement.style.setProperty('--background-color', '#0000'); + document.documentElement.style.setProperty('--regular-margin', '0'); + document.documentElement.style.setProperty('--director-margin', '0 25px 0 0'); + getById("directorLinksButton").style.color = "black"; + session.transparent=true; } - //var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); - //supportedConstraints.channelCount; + if (urlParams.has('stereo') || urlParams.has('s') || urlParams.has('proaudio')) { // both peers need this enabled for HD stereo to be on. If just pub, you get no echo/noise cancellation. if just viewer, you get high bitrate mono + log("STEREO ENABLED"); + session.stereo = urlParams.get('stereo') || urlParams.get('s') || urlParams.get('proaudio'); - if (session.stereo === "false") { - session.stereo = 0; - session.audioInputChannels = 1; - } else if (session.stereo === "0") { - session.stereo = 0; - session.audioInputChannels = 1; - } else if (session.stereo === "no") { - session.stereo = 0; - session.audioInputChannels = 1; - } else if (session.stereo === "off") { - session.stereo = 0; - session.audioInputChannels = 1; - - } else if (session.stereo === "1") { - session.stereo = 1; - } else if (session.stereo === "both") { - session.stereo = 1; - } else if (session.stereo === "3") { - session.stereo = 3; - } else if (session.stereo === "out") { - session.stereo = 3; - } else if (session.stereo === "mono") { - session.stereo = 3; - session.audiobitrate = 128; - } else if (session.stereo === "4") { - session.stereo = 4; - } else if (session.stereo === "multi") { - session.stereo = 4; - } else if (session.stereo === "2") { - session.stereo = 2; - } else if (session.stereo === "in") { - session.stereo = 2; - } else { - session.stereo = 5; // guests; no stereo in, no high bitrate in, but otherwise like stereo=1 - } -} - - -if (urlParams.has('pie')){ - session.pie = urlParams.get('pie') || false; // If session.pie == true, then there is no need to set parameters via URL - if (session.pie){ - session.wss = "wss://us-nyc-1.websocket.me/v3/1?api_key="+session.pie; // if URL param is set, it will use the API key. - } -} - -if ((session.stereo == 1) || (session.stereo == 3) || (session.stereo == 4) || (session.stereo == 5)) { - session.echoCancellation = false; - session.autoGainControl = false; - session.noiseSuppression = false; -} - -if (urlParams.has('mono')) { - session.mono = true; - if ((session.stereo == 1) || (session.stereo == 4)) { - session.stereo = 3; - session.audiobitrate = 128; - } else if (session.stereo == 5) { - session.stereo = 3; - session.audiobitrate = 128; - } else if (session.stereo == 2) { - session.stereo = 0; - session.audiobitrate = 128; - } -} - -if (urlParams.has("channelcount") || urlParams.has("ac")) { - session.audioInputChannels = urlParams.get('channelcount') || urlParams.get('ac'); - session.audioInputChannels = parseInt(session.audioInputChannels); - if (!session.audioInputChannels) { - session.audioInputChannels = false; - } -} - - -if (urlParams.has("aec") || urlParams.has("ec")) { - - session.echoCancellation = urlParams.get('aec') || urlParams.get('ec'); - - if (session.echoCancellation) { - session.echoCancellation = session.echoCancellation.toLowerCase(); - } - if (session.echoCancellation == "false") { - session.echoCancellation = false; - } else if (session.echoCancellation == "0") { - session.echoCancellation = false; - } else if (session.echoCancellation == "no") { - session.echoCancellation = false; - } else if (session.echoCancellation == "off") { - session.echoCancellation = false; - } else { - session.echoCancellation = true; - } -} - - -if (urlParams.has("autogain") || urlParams.has("ag")) { - - session.autoGainControl = urlParams.get('autogain') || urlParams.get('ag'); - if (session.autoGainControl) { - session.autoGainControl = session.autoGainControl.toLowerCase(); - } - if (session.autoGainControl == "false") { - session.autoGainControl = false; - } else if (session.autoGainControl == "0") { - session.autoGainControl = false; - } else if (session.autoGainControl == "no") { - session.autoGainControl = false; - } else if (session.autoGainControl == "off") { - session.autoGainControl = false; - } else { - session.autoGainControl = true; - } -} - -if (urlParams.has("denoise") || urlParams.has("dn")) { - - session.noiseSuppression = urlParams.get('denoise') || urlParams.get('dn'); - - if (session.noiseSuppression) { - session.noiseSuppression = session.noiseSuppression.toLowerCase(); - } - if (session.noiseSuppression == "false") { - session.noiseSuppression = false; - } else if (session.noiseSuppression == "0") { - session.noiseSuppression = false; - } else if (session.noiseSuppression == "no") { - session.noiseSuppression = false; - } else if (session.noiseSuppression == "off") { - session.noiseSuppression = false; - } else { - session.noiseSuppression = true; - } -} - - -if (urlParams.has('roombitrate') || urlParams.has('roomvideobitrate') || urlParams.has('rbr')) { - log("Room BITRATE SET"); - session.roombitrate = urlParams.get('roombitrate') || urlParams.get('rbr') || urlParams.get('roomvideobitrate'); - session.roombitrate = parseInt(session.roombitrate); - if (session.roombitrate < 1) { - session.roombitrate = 0; - } -} - -if ( urlParams.has('outboundaudiobitrate') || urlParams.has('oab')) { - session.outboundAudioBitrate = parseInt(urlParams.get('outboundaudiobitrate')) || parseInt(urlParams.get('oab')) || false; -} -if (urlParams.has('outboundvideobitrate') || urlParams.has('ovb')) { - session.outboundVideoBitrate = parseInt(urlParams.get('outboundvideobitrate')) || parseInt(urlParams.get('ovb')) || false; -} - -if (urlParams.has('webp')){ - session.webp = true; -} - -if (urlParams.has('webpquality') || urlParams.has('webpq') || urlParams.has('wq')){ - session.webPquality = parseInt(urlParams.get('webpquality')) || parseInt(urlParams.get('webpq')) || parseInt(urlParams.get('wq')) || 4; -} - - -if (urlParams.has('audiobitrate') || urlParams.has('ab')) { // both peers need this enabled for HD stereo to be on. If just pub, you get no echo/noise cancellation. if just viewer, you get high bitrate mono - log("AUDIO BITRATE SET"); - session.audiobitrate = urlParams.get('audiobitrate') || urlParams.get('ab'); - session.audiobitrate = parseInt(session.audiobitrate); - if (session.audiobitrate < 1) { - session.audiobitrate = false; - } else if (session.audiobitrate > 510) { - session.audiobitrate = 510; - } // this is to just prevent abuse -} -if ((iOS) || (iPad)) { - session.audiobitrate = false; // iOS devices seem to get distortion with custom audio bitrates. Disable for now. -} - -/* if (urlParams.has('whitebalance') || urlParams.has('temp')){ // Need to be applied after the camera is selected. bleh. not enforcible. remove for now. - var temperature = urlParams.get('whitebalance') || urlParams.get('temp'); - try{ - updateCameraConstraints('colorTemperature', parseFloat(temperature)); - } catch (e){errorlog(e);} -} */ - -if (urlParams.has('streamid') || urlParams.has('view') || urlParams.has('v') || urlParams.has('pull')) { // the streams we want to view; if set, but let blank, we will request no streams to watch. - session.view = urlParams.get('streamid') || urlParams.get('view') || urlParams.get('v') || urlParams.get('pull') || null; // this value can be comma seperated for multiple streams to pull - - getById("headphonesDiv2").style.display = "inline-block"; - getById("headphonesDiv").style.display = "inline-block"; - getById("addPasswordBasic").style.display = "none"; - - if (session.view == null) { - session.view = ""; - } - if (session.view) { - if (session.view.split(",").length > 1) { - session.view_set = session.view.split(","); + if (session.stereo) { + session.stereo = session.stereo.toLowerCase(); } - } -} -//if (urlParams.has('directorview') || urlParams.has('dv')){ -// session.directorView = true; -// if (!session.view){ -// session.view = true; -// } -//} + //var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); + //supportedConstraints.channelCount; -if (urlParams.has('nopreview') || urlParams.has('np')) { - log("preview OFF"); - session.nopreview = true; -} else if ((urlParams.has('preview')) || (urlParams.has('showpreview'))) { - log("preview ON"); - session.nopreview = false; -} else if ((urlParams.has('minipreview')) || (urlParams.has('mini'))) { - var mini = urlParams.has('minipreview') || urlParams.has('mini') || true; // 2 is a valid option. - log("preview ON"); - session.nopreview = false; - session.minipreview = mini; -} + if (session.stereo === "false") { + session.stereo = 0; + session.audioInputChannels = 1; + } else if (session.stereo === "0") { + session.stereo = 0; + session.audioInputChannels = 1; + } else if (session.stereo === "no") { + session.stereo = 0; + session.audioInputChannels = 1; + } else if (session.stereo === "off") { + session.stereo = 0; + session.audioInputChannels = 1; -if (urlParams.has('obsfix')) { - session.obsfix = urlParams.get('obsfix'); - if (session.obsfix) { - session.obsfix = session.obsfix.toLowerCase(); - } - if (session.obsfix == "false") { - session.obsfix = false; - } else if (session.obsfix == "0") { - session.obsfix = false; - } else if (session.obsfix == "no") { - session.obsfix = false; - } else if (session.obsfix == "off") { - session.obsfix = false; - } else if (parseInt(session.obsfix) > 0) { - session.obsfix = parseInt(session.obsfix); - } else { - session.obsfix = 1; // aggressive. - } -} - -if (urlParams.has('controlroombitrate') || urlParams.has('crb')) { - session.controlRoomBitrate = true; -} - -if (urlParams.has('remote') || urlParams.has('rem')) { - log("remote ENABLED"); - session.remote = urlParams.get('remote') || urlParams.get('rem') || "nosecurity"; - session.remote = session.remote.trim(); -} - -if (urlParams.has('latency') || urlParams.has('al') || urlParams.has('audiolatency')) { - log("latency ENABLED"); - session.audioLatency = urlParams.get('latency') || urlParams.get('al') || urlParams.get('audiolatency'); - session.audioLatency = parseInt(session.audioLatency) || 0; - session.disableWebAudio = false; -} - - - -if (urlParams.has('micdelay') || urlParams.has('delay') || urlParams.has('md')) { - log("audio gain ENABLED"); - session.micDelay = urlParams.get('micdelay') || urlParams.get('delay') || urlParams.get('md'); - session.micDelay = parseInt(session.micDelay) || 0; - session.disableWebAudio = false; -} - -if (urlParams.has('tips')){ - getById("guestTips").style.display="flex"; -} - -if (urlParams.has('audiogain') || urlParams.has('gain') || urlParams.has('g')) { - log("audio gain ENABLED"); - session.audioGain = urlParams.get('audiogain') || urlParams.get('gain') || urlParams.get('g'); - session.audioGain = parseInt(session.audioGain) || 0; - session.disableWebAudio = false; -} -if (urlParams.has('compressor') || urlParams.has('comp')) { - log("audio gain ENABLED"); - session.compressor = 1; - session.disableWebAudio = false; -} else if (urlParams.has('limiter')) { - log("audio gain ENABLED"); - session.compressor = 2; - session.disableWebAudio = false; -} -if ((urlParams.has('equalizer')) || (urlParams.has('eq'))) { - session.equalizer = true; - session.disableWebAudio = false; -} -if ((urlParams.has('lowcut')) || (urlParams.has('lc')) || (urlParams.has('higpass'))) { - session.lowcut = urlParams.get('lowcut') || urlParams.get('lc') || urlParams.get('higpass') || 100; - session.lowcut = parseInt(session.lowcut); - session.disableWebAudio = false; -} - -if (urlParams.has('pip')) { - session.pip = true; // togglePip - //session.manual=true; - //innerHTML = -} - -if (urlParams.has('keyframeinterval') || urlParams.has('keyframerate') || urlParams.has('keyframe') || urlParams.has('fki')) { - log("keyframerate ENABLED"); - session.keyframerate = parseInt(urlParams.get('keyframeinterval') || urlParams.get('keyframerate') || urlParams.get('keyframe') || urlParams.get('fki')) || 0; -} - -if (urlParams.has('tallyoff') || urlParams.has('obsoff') || urlParams.has('oo') || urlParams.has('disableobs')) { - log("OBS feedback disabled"); - session.disableOBS = true; - getById("obsState").style.display = "none !important"; -} - - -if (urlParams.has('chroma')) { - log("Chroma ENABLED"); - getById("main").style.backgroundColor = "#" + (urlParams.get('chroma') || "0F0"); -} - -if (urlParams.has('margin')) { - if (urlParams.get('margin') || 10){ - try { - var videoMargin = urlParams.get('margin') || 10; - videoMargin = parseInt(videoMargin); - videoMargin+="px"; - document.querySelector(':root').style.setProperty('--video-margin', videoMargin); - } catch(e){errorlog("variable css failed");} - } -} - -if (urlParams.has('fadein')) { - session.fadein=true; - if (urlParams.get('fadein') || 0){ - try { - var fadeinspeed = parseInt(urlParams.get('fadein') || 0)/1000.0; - fadeinspeed+="s"; - document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed); - } catch(e){errorlog("variable css failed");} - } else { - try { - var fadeinspeed = 0.5; - fadeinspeed+="s"; - document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed); - } catch(e){errorlog("variable css failed");} - } -} - - -if (urlParams.has("videodevice") || urlParams.has("vdevice") || urlParams.has('vd') || urlParams.has('device') || urlParams.has('d')) { - - session.videoDevice = urlParams.get("videodevice") || urlParams.get("vdevice") || urlParams.get("vd") || urlParams.get("device") || urlParams.get("d"); - - if (session.videoDevice === null) { - session.videoDevice = "1"; - } else if (session.videoDevice) { - session.videoDevice = session.videoDevice.toLowerCase().replace(/[\W]+/g, "_"); - } - if (session.videoDevice == "false") { - session.videoDevice = 0; - } else if (session.videoDevice == "0") { - session.videoDevice = 0; - } else if (session.videoDevice == "no") { - session.videoDevice = 0; - } else if (session.videoDevice == "off") { - session.videoDevice = 0; - } else if (session.videoDevice == "snapcam") { - session.videoDevice = "snap_camera"; - } else if (session.videoDevice == "canon") { - session.videoDevice = "eos"; - } else if (session.videoDevice == "camlink") { - session.videoDevice = "cam_link"; - } else if (session.videoDevice == "ndi") { - session.videoDevice = "newtek_ndi_video"; - } else if (session.videoDevice == "") { - session.videoDevice = 1; - } else if (session.videoDevice == "1") { - session.videoDevice = 1; - } else if (session.videoDevice == "default") { - session.videoDevice = 1; - } else { - // whatever the user entered I guess, santitized. - session.videoDevice = session.videoDevice.replace(/[\W]+/g, "_").toLowerCase(); - } - - if (session.videoDevice === 0) { - getById("add_camera").innerHTML = "Share your Microphone"; - miniTranslate(getById("add_camera"), "share-your-mic"); - } - - getById("videoMenu").style.display = "none"; - log("session.videoDevice:" + session.videoDevice); -} - -// audioDevice -if (urlParams.has('audiodevice') || urlParams.has('adevice') || urlParams.has('ad') || urlParams.has('device') || urlParams.has('d')) { - - session.audioDevice = urlParams.get("audiodevice") || urlParams.get("adevice") || urlParams.get("ad") || urlParams.get("device") || urlParams.get("d"); - - if (session.audioDevice === null) { - session.audioDevice = "1"; - } else if (session.audioDevice) { - session.audioDevice = session.audioDevice.toLowerCase().replace(/[\W]+/g, "_"); - } - - if (session.audioDevice == "false") { - session.audioDevice = 0; - } else if (session.audioDevice == "0") { - session.audioDevice = 0; - } else if (session.audioDevice == "no") { - session.audioDevice = 0; - } else if (session.audioDevice == "off") { - session.audioDevice = 0; - } else if (session.audioDevice == "") { - session.audioDevice = 1; - } else if (session.audioDevice == "1") { - session.audioDevice = 1; - } else if (session.audioDevice == "default") { - session.audioDevice = 1; - } else if (session.audioDevice == "ndi") { - session.audioDevice = "line_newtek_ndi_audio"; - } else { - // whatever the user entered I guess - session.audioDevice = session.audioDevice.replace(/[\W]+/g, "_").toLowerCase(); - } - - - if (session.videoDevice === 0) { - if (session.audioDevice === 0) { - getById("add_camera").innerHTML = "Click Start to Join"; - miniTranslate(getById("add_camera"), "click-start-to-join"); - getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("container-3").classList.add("skip-animation"); - getById("container-3").classList.remove('pointer'); - setTimeout(function() { - previewWebcam(); - }, 100); - session.webcamonly = true; + } else if (session.stereo === "1") { + session.stereo = 1; + } else if (session.stereo === "both") { + session.stereo = 1; + } else if (session.stereo === "3") { + session.stereo = 3; + } else if (session.stereo === "out") { + session.stereo = 3; + } else if (session.stereo === "mono") { + session.stereo = 3; + session.audiobitrate = 128; + } else if (session.stereo === "4") { + session.stereo = 4; + } else if (session.stereo === "multi") { + session.stereo = 4; + } else if (session.stereo === "2") { + session.stereo = 2; + } else if (session.stereo === "in") { + session.stereo = 2; + } else { + session.stereo = 5; // guests; no stereo in, no high bitrate in, but otherwise like stereo=1 } } - log("session.audioDevice:" + session.audioDevice); - getById("audioMenu").style.display = "none"; - getById("headphonesDiv").style.display = "none"; - getById("headphonesDiv2").style.display = "none"; - getById("audioScreenShare1").style.display = "none"; - -} - - -if (urlParams.has('autojoin') || urlParams.has('autostart') || urlParams.has('aj') || urlParams.has('as')) { - session.autostart = true; - if (session.screenshare!==false) { - setTimeout(function() { - publishScreen(); - }, 2000); + if (urlParams.has('pie')){ + session.pie = urlParams.get('pie') || false; // If session.pie == true, then there is no need to set parameters via URL + if (session.pie){ + session.wss = "wss://us-nyc-1.websocket.me/v3/1?api_key="+session.pie; // if URL param is set, it will use the API key. + } } -} -if (urlParams.has('noiframe') || urlParams.has('noiframes') || urlParams.has('nif')) { - - session.noiframe = urlParams.get('noiframe') || urlParams.get('noiframes') || urlParams.get('nif'); - - if (!(session.noiframe)) { - session.noiframe = []; - } else { - session.noiframe = session.noiframe.split(","); + if ((session.stereo == 1) || (session.stereo == 3) || (session.stereo == 4) || (session.stereo == 5)) { + session.echoCancellation = false; + session.autoGainControl = false; + session.noiseSuppression = false; } - log("disable iframe playback"); - log(session.noiframe); -} - -if (urlParams.has('exclude') || urlParams.has('ex')) { - - session.exclude = urlParams.get('exclude') || urlParams.get('ex'); - - if (!(session.exclude)) { - session.exclude = false; - } else { - session.exclude = session.exclude.split(","); + if (urlParams.has('mono')) { + session.mono = true; + if ((session.stereo == 1) || (session.stereo == 4)) { + session.stereo = 3; + session.audiobitrate = 128; + } else if (session.stereo == 5) { + session.stereo = 3; + session.audiobitrate = 128; + } else if (session.stereo == 2) { + session.stereo = 0; + session.audiobitrate = 128; + } } - log("exclude video playback"); - log(session.exclude); -} - -if (urlParams.has('novideo') || urlParams.has('nv') || urlParams.has('hidevideo') || urlParams.has('showonly')) { - - session.novideo = urlParams.get('novideo') || urlParams.get('nv') || urlParams.get('hidevideo') || urlParams.get('showonly'); - - if (!(session.novideo)) { - session.novideo = []; - } else { - session.novideo = session.novideo.split(","); + if (urlParams.has("channelcount") || urlParams.has("ac")) { + session.audioInputChannels = urlParams.get('channelcount') || urlParams.get('ac'); + session.audioInputChannels = parseInt(session.audioInputChannels); + if (!session.audioInputChannels) { + session.audioInputChannels = false; + } } - log("disable video playback"); - log(session.novideo); -} -if (urlParams.has('noaudio') || urlParams.has('na') || urlParams.has('hideaudio')) { - session.noaudio = urlParams.get('noaudio') || urlParams.get('na') || urlParams.get('hideaudio'); + if (urlParams.has("aec") || urlParams.has("ec")) { - if (!(session.noaudio)) { - session.noaudio = []; - } else { - session.noaudio = session.noaudio.split(","); + session.echoCancellation = urlParams.get('aec') || urlParams.get('ec'); + + if (session.echoCancellation) { + session.echoCancellation = session.echoCancellation.toLowerCase(); + } + if (session.echoCancellation == "false") { + session.echoCancellation = false; + } else if (session.echoCancellation == "0") { + session.echoCancellation = false; + } else if (session.echoCancellation == "no") { + session.echoCancellation = false; + } else if (session.echoCancellation == "off") { + session.echoCancellation = false; + } else { + session.echoCancellation = true; + } } - log("disable audio playback"); -} -if (urlParams.has('forceios')) { - log("allow iOS to work in video group chat; for this user at least"); - session.forceios = true; -} -if (urlParams.has('nocursor')) { - session.nocursor = true; - log("DISABLE CURSOR"); - var style = document.createElement('style'); - style.innerHTML = ` - video { - margin: 0; - padding: 0; - overflow: hidden; - cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=), none; - user-select: none; + if (urlParams.has("autogain") || urlParams.has("ag")) { + + session.autoGainControl = urlParams.get('autogain') || urlParams.get('ag'); + if (session.autoGainControl) { + session.autoGainControl = session.autoGainControl.toLowerCase(); + } + if (session.autoGainControl == "false") { + session.autoGainControl = false; + } else if (session.autoGainControl == "0") { + session.autoGainControl = false; + } else if (session.autoGainControl == "no") { + session.autoGainControl = false; + } else if (session.autoGainControl == "off") { + session.autoGainControl = false; + } else { + session.autoGainControl = true; + } } - `; - document.head.appendChild(style); - -} -if (urlParams.has('vbr')) { - session.cbr = 0; -} + if (urlParams.has("denoise") || urlParams.has("dn")) { -if (urlParams.has('order')) { - session.order = parseInt(urlParams.get('order')) || 0; -} -if (urlParams.has('sensors') || urlParams.has('sensor') || urlParams.has('gyro') || urlParams.has('gyros') || urlParams.has('accelerometer')) { - session.sensorData = urlParams.get('sensors') || urlParams.get('sensor') || urlParams.get('gyro') || urlParams.get('gyros') || urlParams.get('accelerometer') || 30; - session.sensorData = parseInt(session.sensorData); -} + session.noiseSuppression = urlParams.get('denoise') || urlParams.get('dn'); -if (urlParams.has('minptime')) { - session.minptime = parseInt(urlParams.get('minptime')) || 10; - if (session.minptime < 10) { - session.minptime = 10; + if (session.noiseSuppression) { + session.noiseSuppression = session.noiseSuppression.toLowerCase(); + } + if (session.noiseSuppression == "false") { + session.noiseSuppression = false; + } else if (session.noiseSuppression == "0") { + session.noiseSuppression = false; + } else if (session.noiseSuppression == "no") { + session.noiseSuppression = false; + } else if (session.noiseSuppression == "off") { + session.noiseSuppression = false; + } else { + session.noiseSuppression = true; + } } - if (session.minptime > 300) { - session.minptime = 300; - } -} - -if (urlParams.has('maxptime')) { - session.maxptime = parseInt(urlParams.get('maxptime')) || 60; - if (session.maxptime < 10) { - session.maxptime = 10; - } - if (session.maxptime > 300) { - session.maxptime = 300; - } -} - -if (urlParams.has('ptime')) { - session.ptime = parseInt(urlParams.get('ptime')) || 20; - if (session.minptime < 10) { - session.ptime = 10; - } - if (session.minptime > 300) { - session.ptime = 300; - } -} -if (urlParams.has('codec')) { - log("CODEC CHANGED"); - session.codec = urlParams.get('codec').toLowerCase(); - if (session.codec=="webp"){ + if (urlParams.has('roombitrate') || urlParams.has('roomvideobitrate') || urlParams.has('rbr')) { + log("Room BITRATE SET"); + session.roombitrate = urlParams.get('roombitrate') || urlParams.get('rbr') || urlParams.get('roomvideobitrate'); + session.roombitrate = parseInt(session.roombitrate); + if (session.roombitrate < 1) { + session.roombitrate = 0; + } + } + + if ( urlParams.has('outboundaudiobitrate') || urlParams.has('oab')) { + session.outboundAudioBitrate = parseInt(urlParams.get('outboundaudiobitrate')) || parseInt(urlParams.get('oab')) || false; + } + if (urlParams.has('outboundvideobitrate') || urlParams.has('ovb')) { + session.outboundVideoBitrate = parseInt(urlParams.get('outboundvideobitrate')) || parseInt(urlParams.get('ovb')) || false; + } + + if (urlParams.has('webp')){ session.webp = true; - session.codec = false; } -} else if (isOperaGX()){ - session.codec = "vp8"; - warnlog("Defaulting to VP8 manually, as H264 with remote iOS devices is not supported"); -} -if (urlParams.has('nonacks')){ // disables error control / throttling. - session.noNacks = true; -} -if (urlParams.has('nopli')){ // disables error control / throttling. - session.noPLIs = true; -} -if (urlParams.has('noremb')){ // disables error control / throttling. - session.noREMB = true; -} - -if (urlParams.has('scale')) { - if (urlParams.get('scale') == "false") {} else if (urlParams.get('scale') == "0") {} else if (urlParams.get('scale') == "no") {} else if (urlParams.get('scale') == "off") {} else { - log("Resolution scale requested"); - session.scale = parseInt(urlParams.get('scale')) || 100; + if (urlParams.has('webpquality') || urlParams.has('webpq') || urlParams.has('wq')){ + session.webPquality = parseInt(urlParams.get('webpquality')) || parseInt(urlParams.get('webpq')) || parseInt(urlParams.get('wq')) || 4; } - session.dynamicScale = false; // default true -} -var ConfigSettings = getById("main-js"); -var ln_template = false; -var translation = false; -try { - if (ConfigSettings) { - ln_template = ConfigSettings.getAttribute('data-translation'); // Translations - if (typeof ln_template === "undefined") { - ln_template = false; - } else if (ln_template === null) { - ln_template = false; + + if (urlParams.has('audiobitrate') || urlParams.has('ab')) { // both peers need this enabled for HD stereo to be on. If just pub, you get no echo/noise cancellation. if just viewer, you get high bitrate mono + log("AUDIO BITRATE SET"); + session.audiobitrate = urlParams.get('audiobitrate') || urlParams.get('ab'); + session.audiobitrate = parseInt(session.audiobitrate); + if (session.audiobitrate < 1) { + session.audiobitrate = false; + } else if (session.audiobitrate > 510) { + session.audiobitrate = 510; + } // this is to just prevent abuse + } + if ((iOS) || (iPad)) { + session.audiobitrate = false; // iOS devices seem to get distortion with custom audio bitrates. Disable for now. + } + + /* if (urlParams.has('whitebalance') || urlParams.has('temp')){ // Need to be applied after the camera is selected. bleh. not enforcible. remove for now. + var temperature = urlParams.get('whitebalance') || urlParams.get('temp'); + try{ + updateCameraConstraints('colorTemperature', parseFloat(temperature)); + } catch (e){errorlog(e);} + } */ + + if (urlParams.has('streamid') || urlParams.has('view') || urlParams.has('v') || urlParams.has('pull')) { // the streams we want to view; if set, but let blank, we will request no streams to watch. + session.view = urlParams.get('streamid') || urlParams.get('view') || urlParams.get('v') || urlParams.get('pull') || null; // this value can be comma seperated for multiple streams to pull + + getById("headphonesDiv2").style.display = "inline-block"; + getById("headphonesDiv").style.display = "inline-block"; + getById("addPasswordBasic").style.display = "none"; + + if (session.view == null) { + session.view = ""; + } + if (session.view) { + if (session.view.split(",").length > 1) { + session.view_set = session.view.split(","); + } } } - if (urlParams.has('ln')) { - ln_template = urlParams.get('ln'); + //if (urlParams.has('directorview') || urlParams.has('dv')){ + // session.directorView = true; + // if (!session.view){ + // session.view = true; + // } + //} + + if (urlParams.has('nopreview') || urlParams.has('np')) { + log("preview OFF"); + session.nopreview = true; + } else if ((urlParams.has('preview')) || (urlParams.has('showpreview'))) { + log("preview ON"); + session.nopreview = false; + } else if ((urlParams.has('minipreview')) || (urlParams.has('mini'))) { + var mini = urlParams.has('minipreview') || urlParams.has('mini') || true; // 2 is a valid option. + log("preview ON"); + session.nopreview = false; + session.minipreview = mini; } -} catch (e) { - errorlog(e); -} -if (ln_template) { // checking if manual lanuage override enabled - try { - log("Template: " + ln_template); - fetch("./translations/" + ln_template + '.json').then(function(response) { - if (response.status !== 200) { - log('Looks like there was a problem. Status Code: ' + - response.status); - return; + if (urlParams.has('obsfix')) { + session.obsfix = urlParams.get('obsfix'); + if (session.obsfix) { + session.obsfix = session.obsfix.toLowerCase(); + } + if (session.obsfix == "false") { + session.obsfix = false; + } else if (session.obsfix == "0") { + session.obsfix = false; + } else if (session.obsfix == "no") { + session.obsfix = false; + } else if (session.obsfix == "off") { + session.obsfix = false; + } else if (parseInt(session.obsfix) > 0) { + session.obsfix = parseInt(session.obsfix); + } else { + session.obsfix = 1; // aggressive. + } + } + + if (urlParams.has('controlroombitrate') || urlParams.has('crb')) { + session.controlRoomBitrate = true; + } + + if (urlParams.has('remote') || urlParams.has('rem')) { + log("remote ENABLED"); + session.remote = urlParams.get('remote') || urlParams.get('rem') || "nosecurity"; + session.remote = session.remote.trim(); + } + + if (urlParams.has('latency') || urlParams.has('al') || urlParams.has('audiolatency')) { + log("latency ENABLED"); + session.audioLatency = urlParams.get('latency') || urlParams.get('al') || urlParams.get('audiolatency'); + session.audioLatency = parseInt(session.audioLatency) || 0; + session.disableWebAudio = false; + } + + + + if (urlParams.has('micdelay') || urlParams.has('delay') || urlParams.has('md')) { + log("audio gain ENABLED"); + session.micDelay = urlParams.get('micdelay') || urlParams.get('delay') || urlParams.get('md'); + session.micDelay = parseInt(session.micDelay) || 0; + session.disableWebAudio = false; + } + + if (urlParams.has('tips')){ + getById("guestTips").style.display="flex"; + } + + if (urlParams.has('audiogain') || urlParams.has('gain') || urlParams.has('g')) { + log("audio gain ENABLED"); + session.audioGain = urlParams.get('audiogain') || urlParams.get('gain') || urlParams.get('g'); + session.audioGain = parseInt(session.audioGain) || 0; + session.disableWebAudio = false; + } + if (urlParams.has('compressor') || urlParams.has('comp')) { + log("audio gain ENABLED"); + session.compressor = 1; + session.disableWebAudio = false; + } else if (urlParams.has('limiter')) { + log("audio gain ENABLED"); + session.compressor = 2; + session.disableWebAudio = false; + } + if ((urlParams.has('equalizer')) || (urlParams.has('eq'))) { + session.equalizer = true; + session.disableWebAudio = false; + } + if ((urlParams.has('lowcut')) || (urlParams.has('lc')) || (urlParams.has('higpass'))) { + session.lowcut = urlParams.get('lowcut') || urlParams.get('lc') || urlParams.get('higpass') || 100; + session.lowcut = parseInt(session.lowcut); + session.disableWebAudio = false; + } + + if (urlParams.has('pip')) { + session.pip = true; // togglePip + //session.manual=true; + //innerHTML = + } + + if (urlParams.has('keyframeinterval') || urlParams.has('keyframerate') || urlParams.has('keyframe') || urlParams.has('fki')) { + log("keyframerate ENABLED"); + session.keyframerate = parseInt(urlParams.get('keyframeinterval') || urlParams.get('keyframerate') || urlParams.get('keyframe') || urlParams.get('fki')) || 0; + } + + if (urlParams.has('tallyoff') || urlParams.has('obsoff') || urlParams.has('oo') || urlParams.has('disableobs')) { + log("OBS feedback disabled"); + session.disableOBS = true; + getById("obsState").style.display = "none !important"; + } + + if (window.obsstudio) { + session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? + session.audioMeterGuest = false; + session.audioEffects = false; + session.obsfix = 15; // can be manually set via URL. ; VP8=15, VP9=30. (previous was 20.) + try { + log("OBS VERSION:" + window.obsstudio.pluginVersion); + log("macOS: " + navigator.userAgent.indexOf('Mac OS X') != -1); + log(window.obsstudio); + + if (typeof document.visibilityState !== "undefined"){ + session.obsState.visibility = document.visibilityState==="visible"; + //session.obsState.sourceActive = session.obsState.visibility; } - response.json().then(function(data) { - log(data); - translation = data; - var trans = data.innerHTML; - var allItems = document.querySelectorAll('[data-translate]'); - allItems.forEach(function(ele) { - if (ele.dataset.translate in trans) { - ele.innerHTML = trans[ele.dataset.translate]; + + window.obsstudio.getStatus(function(obsStatus) { + log("OBS STATUS:"); + log(obsStatus); + // TODO: update state here + if ("recording" in obsStatus){ + session.obsState.recording = obsStatus.recording; + } + if ("streaming" in obsStatus){ + session.obsState.streaming = obsStatus.streaming; + } + + }); + + if (!(urlParams.has('streamlabs'))) { + + var ver1 = window.obsstudio.pluginVersion.split("."); + var cefVersion = getChromeVersion(); + + if (ver1.length == 3) { // Should be 3, but disabled3 + if ((ver1.length == 3) && (parseInt(ver1[0]) == 2) && (cefVersion < 76) && (navigator.userAgent.indexOf('Mac OS X') != -1)) { + updateURL("streamlabs"); + getById("main").innerHTML = "

Update OBS Studio to v26.1.2 or newer; older versions and StreamLabs OBS are not supported on macOS.\ +
download here: https://github.com/obsproject/obs-studio/releases/tag/26.1.2\ +



\ +

Please use the Electron Capture app if there are further problems or if you wish to use StreamLabs on macOS still.

\ +
You can find more details within our wiki guide - https://github.com/steveseguin/obsninja/wiki/FAQ#mac-os\ +
You can bypass this error message by refreshing, Clicking Here, or by adding &streamlabs to the URL, but it may still not actually work.\ + \ +
Please report this problem to steve@seguin.email if you feel it is an error.\ +
"; } - }); - trans = data.titles; - var allTitles = document.querySelectorAll('[title]'); - allTitles.forEach(function(ele) { - var key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.title = trans[key]; - } - }); - trans = data.placeholders; - var allPlaceholders = document.querySelectorAll('[placeholder]'); - allPlaceholders.forEach(function(ele) { - var key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.placeholder = trans[key]; - } - }); + } + } + + if (navigator.userAgent.indexOf('Mac OS X') != -1) { + session.codec = "h264"; // default the codec to h264 if OBS is on macOS (that's all it supports with hardware) + } + + if (session.disableOBS===false){ + window.addEventListener("obsSourceVisibleChanged", obsSourceVisibleChanged); + window.addEventListener("obsSourceActiveChanged", obsSourceActiveChanged); + window.addEventListener("obsSceneChanged", obsSceneChanged); + window.addEventListener("obsStreamingStarted", obsStreamingStarted); + window.addEventListener("obsStreamingStopped", obsStreamingStopped); + window.addEventListener("obsRecordingStarted", obsRecordingStarted); + window.addEventListener("obsRecordingStopped", obsRecordingStopped); + } + + } catch (e) { + errorlog(e); + } + } - getById("mainmenu").style.opacity = 1; + if (urlParams.has('chroma')) { + log("Chroma ENABLED"); + getById("main").style.backgroundColor = "#" + (urlParams.get('chroma') || "0F0"); + } + + if (urlParams.has('margin')) { + if (urlParams.get('margin') || 10){ + try { + var videoMargin = urlParams.get('margin') || 10; + videoMargin = parseInt(videoMargin); + videoMargin+="px"; + document.querySelector(':root').style.setProperty('--video-margin', videoMargin); + } catch(e){errorlog("variable css failed");} + } + } + + if (urlParams.has('fadein')) { + session.fadein=true; + if (urlParams.get('fadein') || 0){ + try { + var fadeinspeed = parseInt(urlParams.get('fadein') || 0)/1000.0; + fadeinspeed+="s"; + document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed); + } catch(e){errorlog("variable css failed");} + } else { + try { + var fadeinspeed = 0.5; + fadeinspeed+="s"; + document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed); + } catch(e){errorlog("variable css failed");} + } + } + + + if (urlParams.has("videodevice") || urlParams.has("vdevice") || urlParams.has('vd') || urlParams.has('device') || urlParams.has('d')) { + + session.videoDevice = urlParams.get("videodevice") || urlParams.get("vdevice") || urlParams.get("vd") || urlParams.get("device") || urlParams.get("d"); + + if (session.videoDevice === null) { + session.videoDevice = "1"; + } else if (session.videoDevice) { + session.videoDevice = session.videoDevice.toLowerCase().replace(/[\W]+/g, "_"); + } + if (session.videoDevice == "false") { + session.videoDevice = 0; + } else if (session.videoDevice == "0") { + session.videoDevice = 0; + } else if (session.videoDevice == "no") { + session.videoDevice = 0; + } else if (session.videoDevice == "off") { + session.videoDevice = 0; + } else if (session.videoDevice == "snapcam") { + session.videoDevice = "snap_camera"; + } else if (session.videoDevice == "canon") { + session.videoDevice = "eos"; + } else if (session.videoDevice == "camlink") { + session.videoDevice = "cam_link"; + } else if (session.videoDevice == "ndi") { + session.videoDevice = "newtek_ndi_video"; + } else if (session.videoDevice == "") { + session.videoDevice = 1; + } else if (session.videoDevice == "1") { + session.videoDevice = 1; + } else if (session.videoDevice == "default") { + session.videoDevice = 1; + } else { + // whatever the user entered I guess, santitized. + session.videoDevice = session.videoDevice.replace(/[\W]+/g, "_").toLowerCase(); + } + + if (session.videoDevice === 0) { + getById("add_camera").innerHTML = "Share your Microphone"; + miniTranslate(getById("add_camera"), "share-your-mic"); + } + + getById("videoMenu").style.display = "none"; + log("session.videoDevice:" + session.videoDevice); + } + + // audioDevice + if (urlParams.has('audiodevice') || urlParams.has('adevice') || urlParams.has('ad') || urlParams.has('device') || urlParams.has('d')) { + + session.audioDevice = urlParams.get("audiodevice") || urlParams.get("adevice") || urlParams.get("ad") || urlParams.get("device") || urlParams.get("d"); + + if (session.audioDevice === null) { + session.audioDevice = "1"; + } else if (session.audioDevice) { + session.audioDevice = session.audioDevice.toLowerCase().replace(/[\W]+/g, "_"); + } + + if (session.audioDevice == "false") { + session.audioDevice = 0; + } else if (session.audioDevice == "0") { + session.audioDevice = 0; + } else if (session.audioDevice == "no") { + session.audioDevice = 0; + } else if (session.audioDevice == "off") { + session.audioDevice = 0; + } else if (session.audioDevice == "") { + session.audioDevice = 1; + } else if (session.audioDevice == "1") { + session.audioDevice = 1; + } else if (session.audioDevice == "default") { + session.audioDevice = 1; + } else if (session.audioDevice == "ndi") { + session.audioDevice = "line_newtek_ndi_audio"; + } else { + // whatever the user entered I guess + session.audioDevice = session.audioDevice.replace(/[\W]+/g, "_").toLowerCase(); + } + + + if (session.videoDevice === 0) { + if (session.audioDevice === 0) { + getById("add_camera").innerHTML = "Click Start to Join"; + miniTranslate(getById("add_camera"), "click-start-to-join"); + getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile + getById("container-3").classList.add("skip-animation"); + getById("container-3").classList.remove('pointer'); + delayedStartupFuncs.push([previewWebcam]); + session.webcamonly = true; + } + } + + log("session.audioDevice:" + session.audioDevice); + + getById("audioMenu").style.display = "none"; + getById("headphonesDiv").style.display = "none"; + getById("headphonesDiv2").style.display = "none"; + getById("audioScreenShare1").style.display = "none"; + + } + + + if (urlParams.has('autojoin') || urlParams.has('autostart') || urlParams.has('aj') || urlParams.has('as')) { + session.autostart = true; + if (session.screenshare!==false) { + delayedStartupFuncs.push([publishScreen]); + } + } + + if (urlParams.has('noiframe') || urlParams.has('noiframes') || urlParams.has('nif')) { + + session.noiframe = urlParams.get('noiframe') || urlParams.get('noiframes') || urlParams.get('nif'); + + if (!(session.noiframe)) { + session.noiframe = []; + } else { + session.noiframe = session.noiframe.split(","); + } + log("disable iframe playback"); + log(session.noiframe); + } + + + if (urlParams.has('exclude') || urlParams.has('ex')) { + + session.exclude = urlParams.get('exclude') || urlParams.get('ex'); + + if (!(session.exclude)) { + session.exclude = false; + } else { + session.exclude = session.exclude.split(","); + } + log("exclude video playback"); + log(session.exclude); + } + + + if (urlParams.has('novideo') || urlParams.has('nv') || urlParams.has('hidevideo') || urlParams.has('showonly')) { + + session.novideo = urlParams.get('novideo') || urlParams.get('nv') || urlParams.get('hidevideo') || urlParams.get('showonly'); + + if (!(session.novideo)) { + session.novideo = []; + } else { + session.novideo = session.novideo.split(","); + } + log("disable video playback"); + log(session.novideo); + } + + if (urlParams.has('noaudio') || urlParams.has('na') || urlParams.has('hideaudio')) { + + session.noaudio = urlParams.get('noaudio') || urlParams.get('na') || urlParams.get('hideaudio'); + + if (!(session.noaudio)) { + session.noaudio = []; + } else { + session.noaudio = session.noaudio.split(","); + } + log("disable audio playback"); + } + + if (urlParams.has('forceios')) { + log("allow iOS to work in video group chat; for this user at least"); + session.forceios = true; + } + + if (urlParams.has('nocursor')) { + session.nocursor = true; + log("DISABLE CURSOR"); + var styletmp = document.createElement('style'); + styletmp.innerHTML = ` + video { + margin: 0; + padding: 0; + overflow: hidden; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=), none; + user-select: none; + } + `; + document.head.appendChild(styletmp); + + } + + if (urlParams.has('vbr')) { + session.cbr = 0; + } + + if (urlParams.has('order')) { + session.order = parseInt(urlParams.get('order')) || 0; + } + if (urlParams.has('sensors') || urlParams.has('sensor') || urlParams.has('gyro') || urlParams.has('gyros') || urlParams.has('accelerometer')) { + session.sensorData = urlParams.get('sensors') || urlParams.get('sensor') || urlParams.get('gyro') || urlParams.get('gyros') || urlParams.get('accelerometer') || 30; + session.sensorData = parseInt(session.sensorData); + } + + if (urlParams.has('minptime')) { + session.minptime = parseInt(urlParams.get('minptime')) || 10; + if (session.minptime < 10) { + session.minptime = 10; + } + if (session.minptime > 300) { + session.minptime = 300; + } + } + + if (urlParams.has('maxptime')) { + session.maxptime = parseInt(urlParams.get('maxptime')) || 60; + if (session.maxptime < 10) { + session.maxptime = 10; + } + if (session.maxptime > 300) { + session.maxptime = 300; + } + } + + if (urlParams.has('ptime')) { + session.ptime = parseInt(urlParams.get('ptime')) || 20; + if (session.minptime < 10) { + session.ptime = 10; + } + if (session.minptime > 300) { + session.ptime = 300; + } + } + + + if (urlParams.has('codec')) { + log("CODEC CHANGED"); + session.codec = urlParams.get('codec').toLowerCase(); + if (session.codec=="webp"){ + session.webp = true; + session.codec = false; + } + } else if (isOperaGX()){ + session.codec = "vp8"; + warnlog("Defaulting to VP8 manually, as H264 with remote iOS devices is not supported"); + } + + if (urlParams.has('nonacks')){ // disables error control / throttling. + session.noNacks = true; + } + if (urlParams.has('nopli')){ // disables error control / throttling. + session.noPLIs = true; + } + if (urlParams.has('noremb')){ // disables error control / throttling. + session.noREMB = true; + } + + if (urlParams.has('scale')) { + if (urlParams.get('scale') == "false") {} else if (urlParams.get('scale') == "0") {} else if (urlParams.get('scale') == "no") {} else if (urlParams.get('scale') == "off") {} else { + log("Resolution scale requested"); + session.scale = parseInt(urlParams.get('scale')) || 100; + } + session.dynamicScale = false; // default true + } + + var ConfigSettings = getById("main-js"); + var ln_template = false; + + try { + if (ConfigSettings) { + ln_template = ConfigSettings.getAttribute('data-translation'); // Translations + if (typeof ln_template === "undefined") { + ln_template = false; + } else if (ln_template === null) { + ln_template = false; + } + } + + if (urlParams.has('ln')) { + ln_template = urlParams.get('ln'); + } + } catch (e) { + errorlog(e); + } + + if (ln_template) { // checking if manual lanuage override enabled + try { + log("Template: " + ln_template); + fetch("./translations/" + ln_template + '.json').then(function(response) { + if (response.status !== 200) { + log('Looks like there was a problem. Status Code: ' + + response.status); + return; + } + response.json().then(function(data) { + log(data); + translation = data; + var trans = data.innerHTML; + var allItems = document.querySelectorAll('[data-translate]'); + allItems.forEach(function(ele) { + if (ele.dataset.translate in trans) { + ele.innerHTML = trans[ele.dataset.translate]; + } + }); + trans = data.titles; + var allTitles = document.querySelectorAll('[title]'); + allTitles.forEach(function(ele) { + var key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); + if (key in trans) { + ele.title = trans[key]; + } + }); + trans = data.placeholders; + var allPlaceholders = document.querySelectorAll('[placeholder]'); + allPlaceholders.forEach(function(ele) { + var key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); + if (key in trans) { + ele.placeholder = trans[key]; + } + }); + + + getById("mainmenu").style.opacity = 1; + }).catch(function(err) { + errorlog(err); + getById("mainmenu").style.opacity = 1; + }); }).catch(function(err) { errorlog(err); getById("mainmenu").style.opacity = 1; }); - }).catch(function(err) { - errorlog(err); - getById("mainmenu").style.opacity = 1; - }); - } catch (error) { - errorlog(error); + } catch (error) { + errorlog(error); + getById("mainmenu").style.opacity = 1; + } + } else if (location.hostname !== "vdo.ninja") { + if (location.hostname === "rtc.ninja"){ + try { + if (session.label === false) { + document.title = ""; + } + getById("qos").innerHTML = ""; + getById("logoname").innerHTML = ""; + getById("helpbutton").style.display = "none"; + getById("helpbutton").style.opacity = 0; + getById("reportbutton").style.display = "none"; + getById("reportbutton").style.opacity = 0; + getById("mainmenu").style.opacity = 1; + getById("mainmenu").style.margin = "30px 0"; + getById("translateButton").style.display = "none"; + getById("translateButton").style.opacity = 0; + getById("info").style.display = "none"; + getById("info").style.opacity = 0; + getById("chatBody").innerHTML = ""; + } catch (e) {} + } + try { + fetch("./translations/blank.json").then(function(response) { + if (response.status !== 200) { + log('Looks like there was a problem. Status Code: ' + + response.status); + return; + } + response.json().then(function(data) { + log(data); + + var trans = data.innerHTML; + var allItems = document.querySelectorAll('[data-translate]'); + allItems.forEach(function(ele) { + if (ele.dataset.translate in trans) { + ele.innerHTML = trans[ele.dataset.translate]; + } + }); + trans = data.titles; + var allTitles = document.querySelectorAll('[title]'); + allTitles.forEach(function(ele) { + var key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); + if (key in trans) { + ele.title = trans[key]; + } + }); + trans = data.placeholders; + var allPlaceholders = document.querySelectorAll('[placeholder]'); + allPlaceholders.forEach(function(ele) { + var key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); + if (key in trans) { + ele.placeholder = trans[key]; + } + }); + + if (session.label === false) { + document.title = location.hostname; + } + getById("qos").innerHTML = location.hostname; + getById("logoname").innerHTML = getById("qos").outerHTML; + getById("helpbutton").style.display = "none"; + getById("reportbutton").style.display = "none"; + getById("mainmenu").style.opacity = 1; + }).catch(function(err) { + errorlog(err); + getById("mainmenu").style.opacity = 1; + }); + }).catch(function(err) { + errorlog(err); + getById("mainmenu").style.opacity = 1; + }); + if (session.label === false) { + document.title = location.hostname; + } + getById("qos").innerHTML = location.hostname; + getById("logoname").innerHTML = getById("qos").outerHTML; + getById("helpbutton").style.display = "none"; + getById("reportbutton").style.display = "none"; + getById("chatBody").innerHTML = ""; + } catch (error) { + errorlog(error); + } + } else { // check if automatic language translation is available getById("mainmenu").style.opacity = 1; } -} else if (location.hostname !== "vdo.ninja") { - if (location.hostname === "rtc.ninja"){ - try { + + try { + if (location.hostname === "rtc.ninja"){ // an extra-brand-free version of vdo.ninja if (session.label === false) { document.title = ""; } @@ -2206,3035 +1459,767 @@ if (ln_template) { // checking if manual lanuage override enabled getById("info").style.display = "none"; getById("info").style.opacity = 0; getById("chatBody").innerHTML = ""; - } catch (e) {} - } - try { - fetch("./translations/blank.json").then(function(response) { - if (response.status !== 200) { - log('Looks like there was a problem. Status Code: ' + - response.status); - return; + } else if (location.hostname !== "vdo.ninja") { + if (session.label === false) { + document.title = location.hostname; } - response.json().then(function(data) { - log(data); - - var trans = data.innerHTML; - var allItems = document.querySelectorAll('[data-translate]'); - allItems.forEach(function(ele) { - if (ele.dataset.translate in trans) { - ele.innerHTML = trans[ele.dataset.translate]; - } - }); - trans = data.titles; - var allTitles = document.querySelectorAll('[title]'); - allTitles.forEach(function(ele) { - var key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.title = trans[key]; - } - }); - trans = data.placeholders; - var allPlaceholders = document.querySelectorAll('[placeholder]'); - allPlaceholders.forEach(function(ele) { - var key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.placeholder = trans[key]; - } - }); - - if (session.label === false) { - document.title = location.hostname; - } - getById("qos").innerHTML = location.hostname; - getById("logoname").innerHTML = getById("qos").outerHTML; - getById("helpbutton").style.display = "none"; - getById("reportbutton").style.display = "none"; - getById("mainmenu").style.opacity = 1; - }).catch(function(err) { - errorlog(err); - getById("mainmenu").style.opacity = 1; - }); - }).catch(function(err) { - errorlog(err); - getById("mainmenu").style.opacity = 1; - }); - if (session.label === false) { - document.title = location.hostname; + getById("qos").innerHTML = sanitizeLabel(location.hostname); + getById("logoname").innerHTML = getById("qos").outerHTML; + getById("helpbutton").style.display = "none"; + getById("reportbutton").style.display = "none"; } - getById("qos").innerHTML = location.hostname; - getById("logoname").innerHTML = getById("qos").outerHTML; - getById("helpbutton").style.display = "none"; - getById("reportbutton").style.display = "none"; - getById("chatBody").innerHTML = ""; - } catch (error) { - errorlog(error); - } -} else { // check if automatic language translation is available - getById("mainmenu").style.opacity = 1; -} -try { - if (location.hostname === "rtc.ninja"){ // an extra-brand-free version of vdo.ninja - if (session.label === false) { - document.title = ""; - } - getById("qos").innerHTML = ""; - getById("logoname").innerHTML = ""; + } catch (e) {} + + if (isIFrame) { getById("helpbutton").style.display = "none"; getById("helpbutton").style.opacity = 0; getById("reportbutton").style.display = "none"; getById("reportbutton").style.opacity = 0; - getById("mainmenu").style.opacity = 1; - getById("mainmenu").style.margin = "30px 0"; - getById("translateButton").style.display = "none"; - getById("translateButton").style.opacity = 0; - getById("info").style.display = "none"; - getById("info").style.opacity = 0; getById("chatBody").innerHTML = ""; - } else if (location.hostname !== "vdo.ninja") { - if (session.label === false) { - document.title = location.hostname; - } - getById("qos").innerHTML = sanitizeLabel(location.hostname); - getById("logoname").innerHTML = getById("qos").outerHTML; - getById("helpbutton").style.display = "none"; - getById("reportbutton").style.display = "none"; } -} catch (e) {} - -if (isIFrame) { - getById("helpbutton").style.display = "none"; - getById("helpbutton").style.opacity = 0; - getById("reportbutton").style.display = "none"; - getById("reportbutton").style.opacity = 0; - getById("chatBody").innerHTML = ""; -} - -function miniTranslate(ele, ident = false) { - if (ident) { - ele.dataset.translate = ident; - } else { - ident = ele.dataset.translate; - } - try { - if (ident in translation.innerHTML) { - ele.innerHTML = translation.innerHTML[ident]; - } - } catch (e) {} -} - -function changeLg(lang) { - fetch("./translations/" + lang + '.json').then(function(response) { - if (response.status !== 200) { - logerror('Language translation file not found.' + response.status); - return; - } - response.json().then(function(data) { - log(data); - translation = data; // translation.innerHTML[ele.dataset.translate] - var trans = data.innerHTML; - var allItems = document.querySelectorAll('[data-translate]'); - allItems.forEach(function(ele) { - if (ele.dataset.translate in trans) { - ele.innerHTML = trans[ele.dataset.translate]; - } - }); - trans = data.titles; - var allTitles = document.querySelectorAll('[title]'); - allTitles.forEach(function(ele) { - var key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.title = trans[key]; - } - }); - trans = data.placeholders; - var allPlaceholders = document.querySelectorAll('[placeholder]'); - allPlaceholders.forEach(function(ele) { - var key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.placeholder = trans[key]; - } - }); - }); - }).catch(function(err) { - errorlog(err); - }); -} - -if (urlParams.has('beep') || urlParams.has('notify') || urlParams.has('tone')) { - session.beepToNotify = true; -} - -if (urlParams.has('r2d2')) { - getById("testtone").innerHTML = ""; - getById("testtone").src = "./media/robot.mp3"; - session.beepToNotify = true; -} - -if (urlParams.has('videobitrate') || urlParams.has('bitrate') || urlParams.has('vb')) { - session.bitrate = urlParams.get('videobitrate') || urlParams.get('bitrate') || urlParams.get('vb'); - if (session.bitrate) { - if ((session.view_set) && (session.bitrate.split(",").length > 1)) { - session.bitrate_set = session.bitrate.split(","); - session.bitrate = parseInt(session.bitrate_set[0]); - } else { - session.bitrate = parseInt(session.bitrate); - } - if (session.bitrate < 1) { - session.bitrate = false; - } - log("BITRATE ENABLED"); - log(session.bitrate); - - } -} - -if (urlParams.has('maxvideobitrate') || urlParams.has('maxbitrate') || urlParams.has('mvb')) { - session.maxvideobitrate = urlParams.get('maxvideobitrate') || urlParams.get('maxbitrate') || urlParams.get('mvb'); - session.maxvideobitrate = parseInt(session.maxvideobitrate); - - if (session.maxvideobitrate < 1) { - session.maxvideobitrate = false; - } - log("maxvideobitrate ENABLED"); - log(session.maxvideobitrate); -} - -if (urlParams.has('totalroombitrate') || urlParams.has('totalroomvideobitrate') || urlParams.has('trb')) { - session.totalRoomBitrate = urlParams.get('totalroombitrate') || urlParams.get('totalroomvideobitrate') || urlParams.get('trb'); - session.totalRoomBitrate = parseInt(session.totalRoomBitrate); - - if (session.totalRoomBitrate < 1) { - session.totalRoomBitrate = false; - } - log("totalRoomBitrate ENABLED"); - log(session.totalRoomBitrate); - -} -if (session.totalRoomBitrate===false){ - session.totalRoomBitrate = session.totalRoomBitrate_default; -} else { - session.totalRoomBitrate_default = session.totalRoomBitrate; // trb_default doesn't change dynamically, but trb can (per director I guess) -} - - -if (urlParams.has('limittotalbitrate') || urlParams.has('ltb')){ - session.limitTotalBitrate = urlParams.get('limittotalbitrate') || urlParams.get('ltb') || 2500; - session.limitTotalBitrate = parseInt(session.limitTotalBitrate); -} - - - -if (urlParams.has('height') || urlParams.has('h')) { - session.height = urlParams.get('height') || urlParams.get('h'); - session.height = parseInt(session.height); -} - -if (urlParams.has('width') || urlParams.has('w')) { - session.width = urlParams.get('width') || urlParams.get('w'); - session.width = parseInt(session.width); -} - -if (urlParams.has('quality') || urlParams.has('q')) { - try { - session.quality = urlParams.get('quality') || urlParams.get('q') || 0; - session.quality = parseInt(session.quality); - getById("gear_screen").parentNode.removeChild(getById("gear_screen")); - getById("gear_webcam").parentNode.removeChild(getById("gear_webcam")); - } catch (e) { - errorlog(e); - } -} - -if (urlParams.has('sink')) { - session.sink = urlParams.get('sink'); -} else if (urlParams.has('outputdevice') || urlParams.has('od') || urlParams.has('audiooutput')) { - session.outputDevice = urlParams.get('outputdevice') || urlParams.get('od') || urlParams.get('audiooutput') || null; - - if (session.outputDevice) { - session.outputDevice = session.outputDevice.toLowerCase().replace(/[\W]+/g, "_"); - } else { - session.outputDevice = null; - getById("headphonesDiv3").style.display = "none"; // + if (urlParams.has('beep') || urlParams.has('notify') || urlParams.has('tone')) { + session.beepToNotify = true; } - if (session.outputDevice) { - try { - enumerateDevices().then(function(deviceInfos) { - for (let i = 0; i !== deviceInfos.length; ++i) { - if (deviceInfos[i].kind === 'audiooutput') { - if (deviceInfos[i].label.replace(/[\W]+/g, "_").toLowerCase().includes(session.outputDevice)) { - session.sink = deviceInfos[i].deviceId; - log("AUDIO OUT DEVICE: " + deviceInfos[i].deviceId); - break; - } - } - } - }); - } catch (e) {} - } - - getById("headphonesDiv").style.display = "none"; - getById("headphonesDiv2").style.display = "none"; -} - -if (window.obsstudio || (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1)){ - session.fullscreen = true; -} else if (urlParams.has('fullscreen')) { - session.fullscreen = true; -} - -if (urlParams.has('stats')) { - session.statsMenu = true; -} - - -if (urlParams.has('cleandirector') || urlParams.has('cdv')) { - session.cleanDirector = true; -} - - -if (session.cleanOutput){ - getById("translateButton").style.display = "none"; - getById("credits").style.display = "none"; - getById("header").style.display = "none"; - getById("controlButtons").style.display = "none"; - var style = document.createElement('style'); - style.innerHTML = ` - video { - background-image: none; - } - `; - document.head.appendChild(style); -} - -if (urlParams.has('cleanish')) { - session.cleanish = true; -} - -if (urlParams.has('channels')) { // must be loaded before channelOffset - session.audioChannels = parseInt(urlParams.get('channels')); - session.offsetChannel = 0; - log("max channels is 32; channels offset"); - session.audioEffects = true; -} -if (urlParams.has('channeloffset')) { - session.offsetChannel = parseInt(urlParams.get('channeloffset')); - log("max channels is 32; channels offset"); - session.audioEffects = true; -} - - - -if (urlParams.has('enhance')) { - //if (parseInt(urlParams.get('enhance')>0){ - session.enhance = true; //parseInt(urlParams.get('enhance')); - //} -} - -if (urlParams.has('maxviewers') || urlParams.has('mv')) { - - session.maxviewers = urlParams.get('maxviewers') || urlParams.get('mv'); - if (session.maxviewers.length == 0) { - session.maxviewers = 1; - } else { - session.maxviewers = parseInt(session.maxviewers); - } - log("maxviewers set"); -} - -if (urlParams.has('maxpublishers') || urlParams.has('mp')) { - - session.maxpublishers = urlParams.get('maxpublishers') || urlParams.get('mp'); - if (session.maxpublishers.length == 0) { - session.maxpublishers = 1; - } else { - session.maxpublishers = parseInt(session.maxpublishers); - } - log("maxpublishers set"); -} - -if (urlParams.has('maxconnections') || urlParams.has('mc')) { - - session.maxconnections = urlParams.get('maxconnections') || urlParams.get('maxconnections'); - if (session.maxconnections.length == 0) { - session.maxconnections = 1; - } else { - session.maxconnections = parseInt(session.maxconnections); + if (urlParams.has('r2d2')) { + getById("testtone").innerHTML = ""; + getById("testtone").src = "./media/robot.mp3"; + session.beepToNotify = true; } - log("maxconnections set"); -} - - -if (urlParams.has('secure')) { - session.security = true; - if (!(session.cleanOutput)) { - setTimeout(function() { - warnUser("Enhanced Security Mode Enabled."); - }, 100); - } -} - -if (urlParams.has('random') || urlParams.has('randomize')) { - session.randomize = true; -} - -if (urlParams.has('framerate') || urlParams.has('fr') || urlParams.has('fps')) { - session.framerate = urlParams.get('framerate') || urlParams.get('fr') || urlParams.get('fps'); - session.framerate = parseInt(session.framerate); - log("framerate Changed"); - log(session.framerate); -} - -if (urlParams.has('maxframerate') || urlParams.has('mfr') || urlParams.has('mfps')) { - session.maxframerate = urlParams.get('maxframerate') || urlParams.get('mfr') || urlParams.get('mfps'); - session.maxframerate = parseInt(session.maxframerate); - log("max framerate assigned"); - log(session.maxframerate); -} - -if (urlParams.has('buffer')) { // needs to be before sync - session.buffer = parseFloat(urlParams.get('buffer')) || 0; - log("buffer Changed: " + session.buffer); - session.sync = 0; - session.audioEffects = true; -} - -if (urlParams.has('sync')) { - session.sync = parseFloat(urlParams.get('sync')); - log("sync Changed; in milliseconds. If not set, defaults to auto."); - log(session.sync); - session.audioEffects = true; - if (session.buffer === false) { - session.buffer = 0; - } -} - -if (urlParams.has('mirror')) { - if (urlParams.get('mirror') == "3") { - getById("main").classList.add("mirror"); - } else if (urlParams.get('mirror') == "2") { - session.mirrored = 2; - } else if (urlParams.get('mirror') == "0") { - session.mirrored = 0; - } else if (urlParams.get('mirror') == "false") { - session.mirrored = 0; - } else if (urlParams.get('mirror') == "off") { - session.mirrored = 0; - } else { - session.mirrored = 1; - } -} - -if (urlParams.has('flip')) { - if (urlParams.get('flip') == "0") { - session.flipped = false; - } else if (urlParams.get('flip') == "false") { - session.flipped = false; - } else if (urlParams.get('flip') == "off") { - session.flipped = false; - } else { - session.flipped = true; - } -} - -if ((session.mirrored) && (session.flipped)) { - try { - log("Mirror all videos"); - var mirrorStyle = document.createElement('style'); - mirrorStyle.innerHTML = "video {transform: scaleX(-1) scaleY(-1); }"; - document.getElementsByTagName("head")[0].appendChild(mirrorStyle); - } catch (e) { - errorlog(e); - } -} else if (session.mirrored) { // mirror the video horizontally - try { - log("Mirror all videos"); - var mirrorStyle = document.createElement('style'); - mirrorStyle.innerHTML = "video {transform: scaleX(-1);}"; - document.getElementsByTagName("head")[0].appendChild(mirrorStyle); - } catch (e) { - errorlog(e); - } -} else if (session.flipped) { // mirror the video vertically - try { - log("Mirror all videos"); - var mirrorStyle = document.createElement('style'); - mirrorStyle.innerHTML = "video {transform: scaleY(-1);}"; - document.getElementsByTagName("head")[0].appendChild(mirrorStyle); - } catch (e) { - errorlog(e); - } -} - - -if (urlParams.has('icefilter')) { - log("ICE FILTER ENABLED"); - session.icefilter = urlParams.get('icefilter'); -} - - -if (urlParams.has('effects') || urlParams.has('effect')) { - session.effects = urlParams.get('effects') || urlParams.get('effect') || null; - if (session.effects === null){ - getById("effectsDiv").style.display = "block"; - session.effects = 0; - } else if (session.effects === "0" || session.effects === "false" || session.effects === "off"){ - session.effects = false; - getById("effectSelector3").style.display = "none"; - getById("effectsDiv3").style.display = "none"; - getById("effectSelector").style.display = "none"; - getById("effectsDiv").style.display = "none"; - } else { - session.effects = parseInt(session.effects); - } - - if (session.effects === 5){ - getById("selectImageTFLITE").style.display = "block"; - getById("selectImageTFLITE3").style.display = "block"; - getById("effectSelector").style.display = "none"; - getById("effectsDiv").style.display = "block"; - } - // mirror == 2 - // face == 1 - // blur = 3 - // green = 4 - // image = 5 -} - -if (urlParams.has('viewereffect') || urlParams.has('viewereffects') || urlParams.has('ve')) { - session.viewereffects = parseInt(urlParams.get('viewereffect')) || parseInt(urlParams.get('ve')) || false; -} - -if (urlParams.has('activespeaker') || urlParams.has('speakerview') || urlParams.has('sas')){ - session.activeSpeaker = true; - session.audioEffects = true; - session.audioMeterGuest = true; - setInterval(function(){activeSpeaker(false);},100); -} - -if (urlParams.has('meter') || urlParams.has('meterstyle')){ - session.meterStyle = urlParams.get('meter') || urlParams.get('meterstyle') || 1; -} - -if (urlParams.has('directorchat') || urlParams.has('dc')){ - session.directorChat = true; -} - -if (urlParams.has('style') || urlParams.has('st')) { - session.style = urlParams.get('style') || urlParams.get('st') || 1; - if ((parseInt(session.style) == 1) || (session.style == "justvideo")) { // no audio only - session.style = 1; - } else if ((parseInt(session.style) == 2) || (session.style == "waveform")) { // audio waveform - session.style = 2; - session.audioEffects = true; ////!!!!!!! Do I want to enable the audioEffects myself? or do it here? - } else if ((parseInt(session.style) == 3) || (session.style == "volume")) { // photo is taken? upload option? canvas? - session.style = 3; - session.audioEffects = true; - } else { - session.style = 1; - } -} - - -if (urlParams.has('samplerate') || urlParams.has('sr')) { - session.sampleRate = parseInt(urlParams.get('samplerate')) || parseInt(urlParams.get('samplerate')) || 48000; - if (session.audioCtx) { - session.audioCtx.close(); // close the default audio context. - } - session.audioCtx = new AudioContext({ // create a new audio context with a higher sample rate. - sampleRate: session.sampleRate - }); - session.audioEffects = true; -} - - -if (urlParams.has('noaudioprocessing') || urlParams.has('noap')) { - session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? - session.audioEffects = false; // disable audio inbound effects also. - session.audioMeterGuest = false; -} - -if (urlParams.has('tcp')){ // forces the TURN servers to use TCP mode; still need to add &private to force TURN also tho - session.forceTcpMode = true; -} -if (urlParams.has('speedtest')){ // forces essentially UDP mode, unless TCP is specified, and some other stuff - session.speedtest = true; -} - -if (urlParams.has('turn')) { - var turnstring = urlParams.get('turn'); - if (turnstring == "twilio") { // a sample function on loading remote credentials for TURN servers. - try { - - session.ws = false; // prevents connection - var twillioRequest = new XMLHttpRequest(); - twillioRequest.onreadystatechange = function() { - if (twillioRequest.status === 200) { - try{ - var res = JSON.parse(twillioRequest.responseText); - } catch(e){return;} - session.configuration = { - iceServers: [{ - "username": res["1"], - "credential": res["2"], - "url": "turn:global.turn.twilio.com:3478?transport=tcp", - "urls": "turn:global.turn.twilio.com:3478?transport=tcp" - }, - { - "username": res["1"], - "credential": res["2"], - "url": "turn:global.turn.twilio.com:443?transport=tcp", - "urls": "turn:global.turn.twilio.com:443?transport=tcp" - } - ], - sdpSemantics: 'unified-plan' // future-proofing - }; - if (session.ws===false){ - session.ws=null; // allows connection (clears state) - session.connect(); // connect if not already connected. - } - } - // system does not connect if twilio API does not respond. - }; - twillioRequest.open('GET', 'https://api.obs.ninja:1443/twilio', true); // `false` makes the request synchronous - twillioRequest.send(); - - - } catch (e) { - errorlog("Twilio Failed"); - } - } else if (turnstring == "nostun") { // disable TURN servers - session.configuration = { - sdpSemantics: 'unified-plan' // future-proofing - }; - } else if ((turnstring == "false") || (turnstring == "off") || (turnstring == "0")) { // disable TURN servers - session.configuration = { - iceServers: [ - { urls: ["stun:stun.l.google.com:19302", "stun:stun4.l.google.com:19302"]} // more than 4 stun+turn servers will cause firefox issues? (2 + 2 for now then) - ], - sdpSemantics: 'unified-plan' // future-proofing - }; - } else { - try { - //session.configuration = {iceServers: [], sdpSemantics: 'unified-plan'}; - turnstring = turnstring.split(";"); - if (turnstring !== "false") { // false disables the TURN server. Useful for debuggin - var turn = {}; - turn.username = turnstring[0]; // myusername - turn.credential = turnstring[1]; //mypassword - turn.urls = [turnstring[2]]; // ["turn:turn.obs.ninja:443"]; - - session.configuration = { - iceServers: [ - { urls: ["stun:stun.l.google.com:19302", "stun:stun4.l.google.com:19302"]} // more than 4 stun+turn servers will cause firefox issues? (2 + 2 for now then) - ], - sdpSemantics: 'unified-plan' // future-proofing - }; - - session.configuration.iceServers.push(turn); + if (urlParams.has('videobitrate') || urlParams.has('bitrate') || urlParams.has('vb')) { + session.bitrate = urlParams.get('videobitrate') || urlParams.get('bitrate') || urlParams.get('vb'); + if (session.bitrate) { + if ((session.view_set) && (session.bitrate.split(",").length > 1)) { + session.bitrate_set = session.bitrate.split(","); + session.bitrate = parseInt(session.bitrate_set[0]); + } else { + session.bitrate = parseInt(session.bitrate); } - } catch (e) { - if (!(session.cleanOutput)) { - warnUser("TURN server parameters were wrong."); + if (session.bitrate < 1) { + session.bitrate = false; } + log("BITRATE ENABLED"); + log(session.bitrate); + + } + } + + if (urlParams.has('maxvideobitrate') || urlParams.has('maxbitrate') || urlParams.has('mvb')) { + session.maxvideobitrate = urlParams.get('maxvideobitrate') || urlParams.get('maxbitrate') || urlParams.get('mvb'); + session.maxvideobitrate = parseInt(session.maxvideobitrate); + + if (session.maxvideobitrate < 1) { + session.maxvideobitrate = false; + } + log("maxvideobitrate ENABLED"); + log(session.maxvideobitrate); + } + + if (urlParams.has('totalroombitrate') || urlParams.has('totalroomvideobitrate') || urlParams.has('trb')) { + session.totalRoomBitrate = urlParams.get('totalroombitrate') || urlParams.get('totalroomvideobitrate') || urlParams.get('trb'); + session.totalRoomBitrate = parseInt(session.totalRoomBitrate); + + if (session.totalRoomBitrate < 1) { + session.totalRoomBitrate = false; + } + log("totalRoomBitrate ENABLED"); + log(session.totalRoomBitrate); + + } + if (session.totalRoomBitrate===false){ + session.totalRoomBitrate = session.totalRoomBitrate_default; + } else { + session.totalRoomBitrate_default = session.totalRoomBitrate; // trb_default doesn't change dynamically, but trb can (per director I guess) + } + + + if (urlParams.has('limittotalbitrate') || urlParams.has('ltb')){ + session.limitTotalBitrate = urlParams.get('limittotalbitrate') || urlParams.get('ltb') || 2500; + session.limitTotalBitrate = parseInt(session.limitTotalBitrate); + } + + if (urlParams.has('height') || urlParams.has('h')) { + session.height = urlParams.get('height') || urlParams.get('h'); + session.height = parseInt(session.height); + } + + if (urlParams.has('width') || urlParams.has('w')) { + session.width = urlParams.get('width') || urlParams.get('w'); + session.width = parseInt(session.width); + } + + if (urlParams.has('quality') || urlParams.has('q')) { + try { + session.quality = urlParams.get('quality') || urlParams.get('q') || 0; + session.quality = parseInt(session.quality); + getById("gear_screen").parentNode.removeChild(getById("gear_screen")); + getById("gear_webcam").parentNode.removeChild(getById("gear_webcam")); + } catch (e) { errorlog(e); } } -} else { - chooseBestTURN(); // vdo.ninja turn servers, if needed. -} - -if (urlParams.has('privacy') || urlParams.has('private') || urlParams.has('relay')) { // please only use if you are also using your own TURN service. - session.privacy = true; - - try { - session.configuration.iceTransportPolicy = "relay"; // https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate/address - } catch (e) { - if (!(session.cleanOutput)) { - warnUser("Privacy mode failed to configure."); - } - errorlog(e); - } - - if (session.speedtest){ - if (session.maxvideobitrate !== false) { - if (session.maxvideobitrate > 6000) { - session.maxvideobitrate = 6000; // Please feel free to get rid of this if using your own TURN servers... - } + if (urlParams.has('sink')) { + session.sink = urlParams.get('sink'); + } else if (urlParams.has('outputdevice') || urlParams.has('od') || urlParams.has('audiooutput')) { + session.outputDevice = urlParams.get('outputdevice') || urlParams.get('od') || urlParams.get('audiooutput') || null; + + if (session.outputDevice) { + session.outputDevice = session.outputDevice.toLowerCase().replace(/[\W]+/g, "_"); } else { - session.maxvideobitrate = 6000; // don't let people pull more than 2500 from you - } - if (session.bitrate !== false) { - if (session.bitrate > 6000) { - session.bitrate = 6000; // Please feel free to get rid of this if using your own TURN servers... - } - } - } else { - if (session.maxvideobitrate !== false) { - if (session.maxvideobitrate > 2500) { - session.maxvideobitrate = 2500; // Please feel free to get rid of this if using your own TURN servers... - } - } else { - session.maxvideobitrate = 2500; // don't let people pull more than 2500 from you - } - if (session.bitrate !== false) { - if (session.bitrate > 2500) { - session.bitrate = 2500; // Please feel free to get rid of this if using your own TURN servers... - } - } - } -} - -if (urlParams.has('wss')) { - if (urlParams.get('wss')) { - session.wss = "wss://" + urlParams.get('wss'); - } -} - -if (urlParams.has('queue')) { - session.queue = true; -} - -if (isIFrame) { // reduce CPU load if not needed. - window.onmessage = function(e) { // iFRAME support - log(e); - try { - if ("function" in e.data) { // these are calling in-app functions, with perhaps a callback -- TODO: add callbacks - var ret = null; - if (e.data.function === "previewWebcam") { - ret = previewWebcam(); - } else if (e.data.function === "changeHTML") { - ret = getById(e.data.target); - ret.innerHTML = e.data.value; - } else if (e.data.function === "publishScreen") { - ret = publishScreen(); - } else if (e.data.function === "eval") { - eval(e.data.value); // eval == evil ; feedback welcomed - } - } - } catch (err) { - errorlog(err); + session.outputDevice = null; + getById("headphonesDiv3").style.display = "none"; // } - if ("sendChat" in e.data) { - sendChat(e.data.sendChat); // sends to all peers; more options down the road - } - // Chat out gets called via getChatMessage function - // Related code: parent.postMessage({"chat": {"msg":-----,"type":----,"time":---} }, "*"); - - if ("mic" in e.data) { // this should work for the director's mic mute button as well. Needs to be manually enabled the first time still tho. - if (e.data.mic === true) { // unmute - session.muted = false; // set - log(session.muted); - toggleMute(true); // apply - } else if (e.data.mic === false) { // mute - session.muted = true; // set - log(session.muted); - toggleMute(true); // apply - } else if (e.data.mic === "toggle") { // toggle - toggleMute(); - } - } - - if ("camera" in e.data) { // this should work for the director's mic mute button as well. Needs to be manually enabled the first time still tho. - if (e.data.camera === true) { // unmute - session.videoMuted = false; // set - log(session.videoMuted); - toggleVideoMute(true); // apply - } else if (e.data.camera === false) { // mute - session.videoMuted = true; // set - log(session.videoMuted); - toggleVideoMute(true); // apply - } else if (e.data.camera === "toggle") { // toggle - toggleVideoMute(); - } - } - - if ("keyframe" in e.data) { - session.sendKeyFrameScenes(); - } - - if ("mute" in e.data) { - if (e.data.mute === true) { // unmute - session.speakerMuted = true; // set - toggleSpeakerMute(true); // apply - } else if (e.data.mute === false) { // mute - session.speakerMuted = false; // set - toggleSpeakerMute(true); // apply - } else if (e.data.mute === "toggle") { // toggle - toggleSpeakerMute(); - } - } else if ("speaker" in e.data) { // same thing as mute. - if (e.data.speaker === true) { // unmute - session.speakerMuted = false; // set - toggleSpeakerMute(true); // apply - } else if (e.data.speaker === false) { // mute - session.speakerMuted = true; // set - toggleSpeakerMute(true); // apply - } else if (e.data.speaker === "toggle") { // toggle - toggleSpeakerMute(); - } - } - - if ("record" in e.data) { - if (e.data.record == false) { // mute - if ("recording" in session.videoElement) { - recordLocalVideo("stop"); - } - } else if (e.data.record == true){ - if ("recording" in session.videoElement) { - // already recording - } else { - recordLocalVideo("start"); - } - } - } - - - if ("volume" in e.data) { - for (var i in session.rpcs) { - try { - session.rpcs[i].videoElement.volume = parseFloat(e.data.volume); - } catch (e) { - errorlog(e); - } - } - } - - if ("bitrate" in e.data) { - for (var i in session.rpcs) { - try { - session.requestRateLimit(parseInt(e.data.bitrate), i); - } catch (e) { - errorlog(e); - } - } - } - - if ("audiobitrate" in e.data) { - for (var i in session.rpcs) { - try { - session.requestAudioRateLimit(parseInt(e.data.audiobitrate), i); - } catch (e) { - errorlog(e); - } - } - } - - if ("changeVideoDevice" in e.data) { - warnlog(e.data.changeVideoDevice); - changeVideoDevice(e.data.changeVideoDevice); - } - - if ("changeAudioDevice" in e.data) { - warnlog(e.data.changeAudioDevice); - changeAudioDevice(e.data.changeAudioDevice); - } - - - if ("sceneState" in e.data) { // TRUE OR FALSE - tells the connected peers if they are live or not via a tally light change. - - var visibility = e.data.sceneState; - - if (session.obsState.visibility !== visibility) { // only move forward if there is a change; the event likes to double fire you see. - session.obsStateSync(); - } - } - - if ("sendMessage" in e.data) { // webrtc send to viewers - session.sendMessage(e.data); - } - - if ("sendRequest" in e.data) { // webrtc send to publishers - session.sendRequest(e.data); - } - - if ("sendPeers" in e.data) { // webrtc send message to every connected peer; like send and request; a hammer vs a knife. - session.sendPeers(e.data); - } - - if ("reload" in e.data) { - location.reload(); - } - - if ("getStats" in e.data) { - - var stats = {}; - stats.total_outbound_connections = Object.keys(session.pcs).length; - stats.total_inbound_connections = Object.keys(session.rpcs).length; - stats.inbound_stats = {}; - for (var i in session.rpcs) { - stats.inbound_stats[session.rpcs[i].streamID] = session.rpcs[i].stats; - } - - - for (var uuid in session.pcs) { - setTimeout(function(UUID) { - session.pcs[UUID].getStats().then(function(stats) { - stats.forEach(stat => { - if (stat.type == "outbound-rtp") { - if (stat.kind == "video") { - - if ("qualityLimitationReason" in stat) { - session.pcs[UUID].stats.quality_limitation_reason = stat.qualityLimitationReason; - } - if ("framesPerSecond" in stat) { - session.pcs[UUID].stats.resolution = stat.frameWidth + " x " + stat.frameHeight + " @ " + stat.framesPerSecond; - } - if ("encoderImplementation" in stat) { - session.pcs[UUID].stats.encoder = stat.encoderImplementation; - } - } - } else if (stat.type == "remote-candidate") { - if ("relayProtocol" in stat) { - if ("ip" in stat) { - session.pcs[UUID].stats.remote_relay_IP = stat.ip; - } - session.pcs[UUID].stats.remote_relayProtocol = stat.relayProtocol; - } - if ("candidateType" in stat) { - session.pcs[UUID].stats.remote_candidateType = stat.candidateType; - } - } else if (stat.type == "local-candidate") { - if ("relayProtocol" in stat) { - if ("ip" in stat) { - session.pcs[UUID].stats.local_relayIP = stat.ip; - } - session.pcs[UUID].stats.local_relayProtocol = stat.relayProtocol; - } - if ("candidateType" in stat) { - session.pcs[UUID].stats.local_candidateType = stat.candidateType; - } - } else if ((stat.type == "candidate-pair" ) && (stat.nominated)) { - - if ("availableOutgoingBitrate" in stat){ - session.pcs[UUID].stats.available_outgoing_bitrate_kbps = parseInt(stat.availableOutgoingBitrate/1024); - } - if ("totalRoundTripTime" in stat){ - if ("responsesReceived" in stat){ - session.pcs[UUID].stats.average_roundTripTime_ms = parseInt((stat.totalRoundTripTime/stat.responsesReceived)*1000); - } - - } - } - return; - }); - return; - }); - }, 0, uuid); - } - setTimeout(function() { - stats.outbound_stats = {}; - for (var i in session.pcs) { - stats.outbound_stats[i] = session.pcs[i].stats; - } - parent.postMessage({ - "stats": stats - }, "*"); - }, 1000); - } - - if ("getRemoteStats" in e.data) { - session.sendRequest({"requestStats":true, "remote":session.remote}); - } - - if ("getLoudness" in e.data) { - log("GOT LOUDNESS REQUEST"); - if (e.data.getLoudness == true) { - session.pushLoudness = true; - var loudness = {}; - - for (var i in session.rpcs) { - loudness[session.rpcs[i].streamID] = session.rpcs[i].stats.Audio_Loudness; - } - - parent.postMessage({ - "loudness": loudness - }, "*"); - - } else { - session.pushLoudness = false; - } - } - - if ("getStreamIDs" in e.data) { - if (e.data.getStreamIDs == true) { - var streamIDs = {}; - for (var i in session.rpcs) { - streamIDs[session.rpcs[i].streamID] = session.rpcs[i].label; - } - parent.postMessage({ - "streamIDs": streamIDs - }, "*"); - - } - } - - if ("close" in e.data) { - for (var i in session.rpcs) { - try { - session.rpcs[i].close(); - } catch (e) { - errorlog(e); - } - } - } - - if ("style" in e.data) { + if (session.outputDevice) { try { - const style = document.createElement('style'); - style.textContent = e.data.style; - document.head.append(style); - log(style); - } catch (e) { - errorlog(e); - } - } - - - if ("automixer" in e.data) { - if (e.data.automixer == true) { - session.manual = false; - try { - updateMixer(); - } catch (e) {} - } else if (e.data.automixer == false) { - session.manual = true; - } - } - - if ("target" in e.data) { - log(e.data); - for (var i in session.rpcs) { - try { - if ("streamID" in session.rpcs[i]) { - if ((session.rpcs[i].streamID == e.data.target) || (e.data.target == "*")) { - try { - if ("settings" in e.data) { - for (const property in e.data.settings) { - session.rpcs[i].videoElement[property] = e.data.settings[property]; - } - } - if ("add" in e.data) { - getById("gridlayout").appendChild(session.rpcs[i].videoElement); - - } else if ("remove" in e.data) { - try { - session.rpcs[i].videoElement.parentNode.removeChild(session.rpcs[i].videoElement); - } catch (e) { - try { - session.rpcs[i].videoElement.parentNode.parentNode.removeChild(session.rpcs[i].videoElement.parentNode); - } catch (e) {} - } - } - } catch (e) { - errorlog(e); + enumerateDevices().then(function(deviceInfos) { + for (let i = 0; i !== deviceInfos.length; ++i) { + if (deviceInfos[i].kind === 'audiooutput') { + if (deviceInfos[i].label.replace(/[\W]+/g, "_").toLowerCase().includes(session.outputDevice)) { + session.sink = deviceInfos[i].deviceId; + log("AUDIO OUT DEVICE: " + deviceInfos[i].deviceId); + break; } } } - } catch (e) { - errorlog(e); - } - } - } - }; -} - -function setupIncomingVideoTracking(v, UUID){ // video element. - - if (session.directorUUID===UUID){ - v.muted=false; - } else { - v.muted = session.speakerMuted; - } - - v.onpause = (event) => { // prevent things from pausing; human or other - if (!((event.ctrlKey) || (event.metaKey) )){ - warnlog("Video paused; force it to play again"); - //return; - //session.audioCtx.resume(); - //log("ctx resume"); - - event.currentTarget.play().then(_ => { - log("playing"); - }).catch(error => { - warnlog("didnt play 1"); - }); - - } - } - - v.onplay = function(){ - try { - var bigPlayButton = document.getElementById("bigPlayButton"); - if (bigPlayButton){ - bigPlayButton.parentNode.removeChild(bigPlayButton); - } - } catch(e){} - if (session.pip){ - if (v.readyState >= 3){ - if (!(v.pip)){ - v.pip=true; - toggleSystemPip(v, true); - } - } + }); + } catch (e) {} } - } - - if (session.pip){ - v.onloadedmetadata = function(){ - if (!v.paused){ - if (!(v.pip)){ - v.pip=true; - toggleSystemPip(v, true); - } - } - } + getById("headphonesDiv").style.display = "none"; + getById("headphonesDiv2").style.display = "none"; } - - v.addEventListener('resize', (e) => { - log("resize event"); - var aspectRatio = parseFloat(e.target.videoWidth/e.target.videoHeight); - if (v.dataset.aspectRatio){ - if (aspectRatio != v.dataset.aspectRatio){ - setTimeout(function(){updateMixer();},1); // We don't want to run this on the first resize? just subsequent ones. - } - } else { - log("ASPECT RATIO CHANGED"); - setTimeout(function(){updateMixer();},1); - } - v.dataset.aspectRatio = parseFloat(e.target.videoWidth/e.target.videoHeight); - }); - - v.volume = 1.0; // play audio automatically - v.autoplay = true; - v.controls = false; - v.classList.add("tile"); - v.setAttribute("playsinline",""); - v.controlTimer = null; - - changeAudioOutputDevice(v); // if enabled, changes to desired output audio device. - - if (document.getElementById("mainmenu")){ - var m = getById("mainmenu"); - m.remove(); - } - - if (session.director){ - v.controls = true; - var container = getById("videoContainer_"+UUID); - v.disablePictureInPicture = false - v.setAttribute("controls","controls") - container.appendChild(v); - session.requestRateLimit(session.directorViewBitrate,UUID); /// limit resolution for director - - if (session.beepToNotify) { - playtone(); - } - - } else if (session.scene!==false){ - v.controls = false; - - if (session.view){ // specific video to be played - v.style.display="block"; - } else if (session.scene==="0"){ - v.style.display="block"; - } else { // group scene I guess; needs to be added manually - v.style.display="none"; - v.muted= true; - } - - setTimeout(function(){updateMixer();},1); - } else if (session.roomid!==false){ - if (session.cleanOutput){ - v.controls = false; - } else if (window.obsstudio) { - v.controls = false; - } else { - v.controls = true; - } - if ((session.roomid==="") && (session.bitrate)){ - // let's keep the default bitrates, since this isn't a real room and bitrates are specified. - } else if (session.novideo !== false){ - if (session.novideo.includes(session.rpcs[UUID].streamID)){ - session.requestRateLimit(0,UUID);// limit resolution for guests see ln: 1804 in main.js also - } - } else { - session.requestRateLimit(0,UUID);// limit resolution for guests see ln: 1804 in main.js also - } - setTimeout(function(){updateMixer();},1); - } else { - v.style.display="block"; - if (window.obsstudio) { - v.controls = false; - } - setTimeout(function(){updateMixer();},1); - } - - - v.addEventListener('click', function(e) { // show stats of video if double clicked - log("clicked"); - try { - if ((e.ctrlKey)||(e.metaKey)){ - e.preventDefault(); - var uid = e.currentTarget.dataset.UUID; - if ("stats" in session.rpcs[uid]){ - - var [menu, innerMenu] = statsMenuCreator(); - - printViewStats(innerMenu, uid ); - - menu.interval = setInterval(printViewStats,3000, innerMenu, uid); - - - } - e.stopPropagation(); - return false; - } - } catch(e){errorlog(e);} - }); - - if (session.statsMenu){ - if ("stats" in session.rpcs[UUID]){ - - if (getById("menuStatsBox")){ - clearInterval(getById("menuStatsBox").interval); - getById("menuStatsBox").remove(); - } - - var [menu, innerMenu] = statsMenuCreator(); - - printViewStats(innerMenu, UUID ); - - menu.interval = setInterval(printViewStats,3000, innerMenu, UUID); - - } - } - - - v.touchTimeOut = null; - v.touchLastTap = 0; - v.touchCount = 0; - v.addEventListener('touchend', function(event) { - log("touched"); - - document.ontouchup = null; - document.onmouseup = null; - document.onmousemove = null; - document.ontouchmove = null; - - var currentTime = new Date().getTime(); - var tapLength = currentTime - v.touchLastTap; - clearTimeout(v.touchTimeOut); - if (tapLength < 500 && tapLength > 0) { - /// - log("double touched"); - v.touchCount+=1; - event.preventDefault(); - if (v.touchCount<5){ - v.touchLastTap = currentTime; - return false; - } - v.touchLastTap = 0; - v.touchCount=0; - - log("double touched"); - var uid = event.currentTarget.dataset.UUID; - if ("stats" in session.rpcs[uid]){ - - var [menu, innerMenu] = statsMenuCreator(); - - printViewStats(innerMenu, uid ); - - menu.interval = setInterval(printViewStats,3000, innerMenu, uid); - - - } - event.stopPropagation(); - return false; - ////// - } else { - v.touchCount=1; - v.touchTimeOut = setTimeout(function(vv) { - clearTimeout(vv.touchTimeOut); - vv.touchLastTap = 0; - vv.touchCount=0; - }, 5000, v); - v.touchLastTap = currentTime; - } - - }); - - - if (session.remote){ - v.addEventListener("wheel", session.remoteControl); + if (window.obsstudio || (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1)){ + session.fullscreen = true; + } else if (urlParams.has('fullscreen')) { + session.fullscreen = true; } - if (v.controls == false){ - v.addEventListener("click", function () { - if (v.paused){ - log("PLAYING MANUALLY?"); - v.play().then(_ => { - log("playing"); - }).catch(warnlog); - } - }); - if (session.nocursor==false){ // we do not want to show the controls. This is because MacOS + OBS does not work; so electron app needs this. - if (!(session.cleanOutput)){ - if (!(window.obsstudio)){ - if (v.controlTimer){ - clearInterval(v.controlTimer); - } - v.controlTimer = setTimeout(showControlBar.bind(null,v),3000); - //v.controlTimer = setTimeout(function (){v.controls=true;},3000); // 3 seconds before I enable the controls automatically. This way it doesn't auto appear during loading. 3s enough, right? - } - } - } + if (urlParams.has('stats')) { + session.statsMenu = true; } - - if (session.fadein){ - v.addEventListener('animationend', function(e) { - v.classList.remove("fadein"); // allows the video to fade in. - }); - v.classList.add("fadein"); // allows the video to fade in. - } - - setTimeout(session.processStats, 1000, UUID); - -} -function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a giant function that runs when there are changes to screensize, video track statuses, etc. - if (getById("subControlButtons").dragElement){ - if (parseInt(getById("subControlButtons").style.top) > 0){ - getById("subControlButtons").style.top = "0px"; - } else if (parseInt(getById("subControlButtons").style.top) < parseInt(50 - window.innerHeight) ){ - getById("subControlButtons").style.top = parseInt( 50 - window.innerHeight)+"px"; - } - if (parseInt(getById("subControlButtons").style.left) < 0){ - getById("subControlButtons").style.left = "0px"; - } else if (parseInt(getById("subControlButtons").style.left) > parseInt( window.innerWidth - getById("subControlButtons").offsetWidth) ){ - getById("subControlButtons").style.left = parseInt( window.innerWidth -getById("subControlButtons").offsetWidth )+"px"; - } + if (urlParams.has('cleandirector') || urlParams.has('cdv')) { + session.cleanDirector = true; } - if (session.director){return;} - if (session.manual === true){return;} - - var header = getById("header"); - - var hi = header.offsetHeight ; - var w = window.innerWidth; - var h = window.innerHeight - hi; - - if ( window.innerHeight<=700 ){ - if (document.getElementById("controlButtons")){ - var h = window.innerHeight - hi - document.getElementById("controlButtons").offsetHeight; - } else { - var h = window.innerHeight - hi; - } - } - - var arW = 16.0; - var arH = 9.0; - - if (session.aspectratio){ - if (session.aspectratio==1){ - arW = 9.0; - arH = 16.0; - } else if (session.aspectratio==2){ - arW = 12.0; // square root; cause why not. - arH = 12.0; - } - } - - var ww = w/arW; - var hh = h/arH; - - var mediaPool = []; - var mediaPool_invisible = []; - - if (session.videoElement){ // I, myself, exist - if (session.videoElement.style.display!="none"){ // local feed - if (session.minipreview && (session.infocus!==true)){ - - session.videoElement.onclick = function(){ - if (session.infocus === true){ - session.infocus = false; - } else { - session.infocus = true; - log("session: myself"); - } - setTimeout(()=>updateMixer(),10); - }; - - } else { - if (session.order!==false){ - session.videoElement.order=session.order; - } else { - session.videoElement.order=0; - } - if (session.activeSpeaker && (!session.activelySpeaking)){ - mediaPool_invisible.push(session.videoElement); - } else { - mediaPool.push(session.videoElement); - } - } - } - } - - if (session.screenShareElement){ // I, myself, exist - if (session.screenShareElement.style.display!="none"){ // local feed - if (session.order!==false){ - session.screenShareElement.order=session.order; - } else { - session.screenShareElement.order=0; - } - - if (session.infocus!==false){ - mediaPool_invisible.push(session.screenShareElement); - } else if (session.activeSpeaker && (!session.activelySpeaking)){ - mediaPool_invisible.push(session.screenShareElement); - } else { - mediaPool.push(session.screenShareElement); - } - } - } - - if (session.iframeEle){ // I, myself, exist - if (session.iframeEle.style.display!="none"){ // local feed - if (session.order!==false){ - session.iframeEle.order=session.order; - } else { - session.iframeEle.order=0; - } - if (session.activeSpeaker && (!session.activelySpeaking)){ - mediaPool_invisible.push(session.iframeEle); - } else { - mediaPool.push(session.iframeEle); - } - } - } - - if ((session.infocus) && (session.infocus in session.rpcs)){ // remote guest being full screened; infocus == UUID - log(session.infocus+" set fullscreen"); - mediaPool = []; // remove myself from fullscreen - for (var j in session.rpcs){ - if (j != session.infocus){ - session.requestRateLimit(0, j); // disable the video of non-fullscreen videos - try { - if (session.rpcs[j].videoElement.style.display!="none"){ // Add it if not hidden - mediaPool_invisible.push(session.rpcs[j].videoElement); - } - } catch(e){} - } else { // in focus video - //////// - try { - if (session.rpcs[j].order!==false){ - session.rpcs[j].videoElement.order=session.rpcs[j].order; - } else { - session.rpcs[j].videoElement.order=0; - } - /////////// - if (session.activeSpeaker && (!session.rpcs[j].activelySpeaking)){ - mediaPool_invisible.push(session.rpcs[j].videoElement); - } else { - mediaPool.push(session.rpcs[j].videoElement); - } - - session.rpcs[j].videoElement.style.visibility = "visible"; - if ((session.rpcs[j].targetBandwidth!==-1) && (session.rpcs[j].targetBandwidth
"; - - controls.innerHTML += "
\ -
\ - " + soloLink + "\ - \ -

This is you, the director.
You are also a performer.

"; - - - controls.querySelectorAll('[data-action-type]').forEach((ele) => { // give action buttons some self-reference - ele.dataset.sid = session.streamID; - }); - - container.innerHTML = buttons; - container.appendChild(controls); - - Object.keys(session.sceneList).forEach((scene, index) => { - if (session.showDirector){ - if (document.getElementById("container_director")){ - if (!(getById("container_director").querySelectorAll('[data-scene="'+scene+'"]').length)){ - var newScene = document.createElement("div"); - newScene.innerHTML = ''; - getById("container_director").appendChild(newScene); - } - } - } - }); - - - var labelID = document.getElementById("label_director"); - - labelID.onclick = function(ee){ - var oldlabel = ee.target.innerText; - if (session.label===false){ - oldlabel = ""; - } - window.focus(); - var newlabel = prompt("Enter a new Display Name for this stream", oldlabel); - if (newlabel!==null){ - if (newlabel == ""){ - newlabel = false; - ee.target.innerText = "Add a label"; - } else { - ee.target.innerText = newlabel; - } - session.label = newlabel; - var data = {}; - data.changeLabel = true; - data.value = session.label; - session.sendMessage(data); - } - } - labelID.style.float = "left"; - labelID.style.top = "2px"; - labelID.style.marginLeft = "5px"; - labelID.style.position = "relative"; - labelID.style.cursor="pointer"; - if (session.label){ - labelID.innerText = session.label; - } -} - -function createControlBox(UUID, soloLink, streamID) { - if (document.getElementById("deleteme")) { - getById("deleteme").parentNode.removeChild(getById("deleteme")); - } - var controls = getById("controls_blank").cloneNode(true); - - var container = document.createElement("div"); - container.id = "container_" + UUID; // needed to delete on user disconnect - container.className = "vidcon directorMargins"; - controls.style.display = "block"; - controls.id = "controls_" + UUID; - getById("guestFeeds").appendChild(container); - - var buttons = "
ID: " + streamID + "\ - \ - \ -
"; - - if (!session.rpcs[UUID].voiceMeter) { - if (session.meterStyle==1){ - session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate2").cloneNode(true); - } else { - session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate").cloneNode(true); - session.rpcs[UUID].voiceMeter.classList.add("video-meter-director"); - session.rpcs[UUID].voiceMeter.style.opacity = 0; - } - session.rpcs[UUID].voiceMeter.id = "voiceMeter_" + UUID; - session.rpcs[UUID].voiceMeter.dataset.level = 0; - } - - session.rpcs[UUID].remoteMuteElement = getById("muteStateTemplate").cloneNode(true); - session.rpcs[UUID].remoteMuteElement.id = ""; - session.rpcs[UUID].remoteMuteElement.style.top = "5px"; - session.rpcs[UUID].remoteMuteElement.style.right = "7px"; - - session.rpcs[UUID].remoteVideoMuteElement = getById("videoMuteStateTemplate").cloneNode(true); - session.rpcs[UUID].remoteVideoMuteElement.id = ""; - session.rpcs[UUID].remoteVideoMuteElement.style.top = "5px"; - session.rpcs[UUID].remoteVideoMuteElement.style.right = "28px"; - - session.rpcs[UUID].remoteRaisedHandElement = getById("raisedHandTemplate").cloneNode(true); - session.rpcs[UUID].remoteRaisedHandElement.id = ""; - session.rpcs[UUID].remoteRaisedHandElement.style.top = "5px"; - session.rpcs[UUID].remoteRaisedHandElement.style.right = "49px"; - - - var videoContainer = document.createElement("div"); - videoContainer.id = "videoContainer_" + UUID; // needed to delete on user disconnect - videoContainer.style.margin = "0"; - videoContainer.style.position = "relative"; - - controls.innerHTML += "
"; - controls.innerHTML += "
"; - - var handsID = "hands_" + UUID; - - controls.innerHTML += "
\ -
\ - " + soloLink + "\ - \ -
\ - \ -
"; - - controls.querySelectorAll('[data-action-type]').forEach((ele) => { // give action buttons some self-reference - ele.dataset.UUID = UUID; - ele.dataset.sid = streamID; - }); - - container.innerHTML = buttons; - container.appendChild(videoContainer); - videoContainer.appendChild(session.rpcs[UUID].voiceMeter); - videoContainer.appendChild(session.rpcs[UUID].remoteMuteElement); - videoContainer.appendChild(session.rpcs[UUID].remoteVideoMuteElement); - videoContainer.appendChild(session.rpcs[UUID].remoteRaisedHandElement); - container.appendChild(controls); - initSceneList(UUID); -} - -function createDirectorCam(vid) { - - getById("press2talk").innerHTML = ""; - getById("press2talk").outerHTML = ""; - if (document.getElementById("videoContainer_director")){ - getById("videoContainer_director").appendChild(vid); - } else { - getById("miniPerformer").appendChild(vid); - } - vid.title = "This is the preview of the Director's audio and video output."; - getById("press2talk").dataset.value = 1; - session.muted = false; - toggleMute(true); - getById("screensharebutton").classList.remove("advanced"); - getById("hangupbutton2").classList.remove("advanced"); - setTimeout(function() { - toggleSettings(); - }, 200); - - if (urlParams.has('permaid')) { - updateURL("permaid=" + session.streamID); - } else { - updateURL("push=" + session.streamID); - } -} - -function press2talk(clean = false) { - var ele = getById("press2talk"); - ele.style.minWidth = "127px"; - ele.style.padding = "7px"; - getById("settingsbutton").classList.remove("advanced"); - - - if (!document.getElementById("controls_director") && session.showDirector){createDirectorOnlyBox();} - - - if (session.videoDevice || (session.audioDevice && session.audioDevice!==1)){ - if ((session.videoDevice === 1) && (session.audioDevice===false || session.audioDevice==1)){ - session.publishDirector(clean, true); - session.muted = false; - toggleMute(true); - return; - } else { - enumerateDevices().then(function(deviceInfos) { - var vdevice = false; - var adevice = true; - if (session.audioDevice==0){ - adevice=false; - } - if (session.videoDevice && (session.videoDevice!=1)){ - for (let i = 0; i !== deviceInfos.length; ++i) { - var deviceInfo = deviceInfos[i]; - if ((deviceInfo.kind === 'videoinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.videoDevice))) { - vdevice = {deviceId: {exact: deviceInfo.deviceId}}; - break; - } else if (deviceInfo.deviceId === session.videoDevice){ - vdevice = {deviceId: {exact: deviceInfo.deviceId}}; - break; - } - } - } - if (session.audioDevice && (session.audioDevice!=1)){ - for (let i = 0; i !== deviceInfos.length; ++i) { - var deviceInfo = deviceInfos[i]; - if ((deviceInfo.kind === 'audioinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.audioDevice))) { - adevice = {deviceId: {exact: deviceInfo.deviceId}}; - break; - } else if (deviceInfo.deviceId === session.audioDevice){ - adevice = {deviceId: {exact: deviceInfo.deviceId}}; - break; - } - } - } - session.publishDirector(clean, vdevice, adevice); - session.muted = false; - toggleMute(true); - }); - return; - } - } - - session.publishDirector(clean); - session.muted = false; - toggleMute(true); - -} - -function addToGoogleCalendar(){ - var title = "Live Stream"; - //var dates = "20180512T230000Z/20180513T030000Z"; - var linkout = getById("director_block_1").innerText; - var details = "Join the live stream as a performer at the following link:

===> "+linkout+"

To test your connection and camera ahead of time, please visit https://vdo.ninja/speedtest

Do not share the details of this invite with others, unless explicitly told to."; - details = details.split(' ').join('+'); - details = details.split('&').join('%26'); - var linkToOpen = "https://calendar.google.com/calendar/r/eventedit?text="+title+"&details="+details; - //https://calendar.google.com/calendar/r/eventedit?text=My+Custom+Event&dates=20180512T230000Z/20180513T030000Z&details=For+details,+link+here:+https://example.com/tickets-43251101208&location=Garage+Boston+-+20+Linden+Street+-+Allston,+MA+02134 - - window.open(linkToOpen); - -} - -function addToOutlookCalendar(){ - var title = "Live Stream"; - var linkout = getById("director_block_1").innerText; - var details = "Join the live stream as a performer at the following link:

===> "+linkout+"

To test your connection and camera ahead of time, please visit https://vdo.ninja/speedtest

Do not share the details of this invite with others, unless explicitly told to."; - details = details.split(' ').join('%20'); - details = details.split('&').join('%26'); - - - var linkToOpen = "https://outlook.live.com/owa/?path=%2Fcalendar%2Faction%2Fcompose&rru=addevent&subject="+title+"&body="+details; - //https://calendar.google.com/calendar/r/eventedit?text=My+Custom+Event&dates=20180512T230000Z/20180513T030000Z&details=For+details,+link+here:+https://example.com/tickets-43251101208&location=Garage+Boston+-+20+Linden+Street+-+Allston,+MA+02134 - - window.open(linkToOpen); -} - -function addToYahooCalendar(){ - var title = "Live Stream"; - var linkout = getById("director_block_1").innerText; - var details = "Join the live stream as a performer at the following link:

===> "+linkout+"

To test your connection and camera ahead of time, please visit https://vdo.ninja/speedtest

Do not share the details of this invite with others, unless explicitly told to."; - details = details.split(' ').join('%20'); - details = details.split('&').join('%26'); - var linkToOpen = "https://calendar.yahoo.com?v60&title="+title+"&desc="+details; - //https://calendar.google.com/calendar/r/eventedit?text=My+Custom+Event&dates=20180512T230000Z/20180513T030000Z&details=For+details,+link+here:+https://example.com/tickets-43251101208&location=Garage+Boston+-+20+Linden+Street+-+Allston,+MA+02134 - - window.open(linkToOpen); -} - -function toggle(ele, tog = false, inline = true) { - var x = ele; - if (x.style.display === "none") { - if (inline) { - x.style.display = "inline-block"; - } else { - x.style.display = "block"; - } - } else { - x.style.display = "none"; - } - if (tog) { - if (tog.dataset.saved) { - tog.innerHTML = tog.dataset.saved; - delete(tog.dataset.saved); - } else { - tog.dataset.saved = tog.innerHTML; - tog.innerHTML = "Hide This"; - } - } -} - -function toggleByDataset(filter) { - var elements = document.querySelectorAll('[data-cluster="'+filter+'"]'); // ie: .cluster1 - for (var i = 0; i < elements.length; i++) { - elements[i].classList.toggle('hidden'); - } -} - - -var SelectedAudioOutputDevices = []; // order matters. -var SelectedAudioInputDevices = []; // .. -var SelectedVideoInputDevices = []; // .. - -function enumerateDevices() { - - log("enumerated start"); - - if (typeof navigator.enumerateDevices === "function") { - log("enumerated failed 1"); - return navigator.enumerateDevices(); - } else if (typeof navigator.mediaDevices === "object" && typeof navigator.mediaDevices.enumerateDevices === "function") { - return navigator.mediaDevices.enumerateDevices(); - } else { - return new Promise((resolve, reject) => { - try { - if (window.MediaStreamTrack == null || window.MediaStreamTrack.getSources == null) { - throw new Error(); - } - window.MediaStreamTrack.getSources((devices) => { - resolve(devices - .filter(device => { - return device.kind.toLowerCase() === "video" || device.kind.toLowerCase() === "videoinput"; - }) - .map(device => { - return { - deviceId: device.deviceId != null ? device.deviceId : "" - , groupId: device.groupId - , kind: "videoinput" - , label: device.label - , toJSON: /* istanbul ignore next */ function() { - return this; - } - }; - })); - }); - } catch (e) { - errorlog(e); - } - }); - } -} - -function requestOutputAudioStream() { - try { - //warnlog("GET USER MEDIA"); - return navigator.mediaDevices.getUserMedia({ - audio: true - , video: false - }).then(function(stream1) { // Apple needs thi to happen before I can access EnumerateDevices. - log("get media sources; request audio stream"); - return enumerateDevices().then(function(deviceInfos) { - stream1.getTracks().forEach(function(track) { // We don't want to keep it without audio; so we are going to try to add audio now. - track.stop(); // I need to do this after the enumeration step, else it breaks firefox's labels - }); - const audioOutputSelect = getById('outputSourceScreenshare'); - audioOutputSelect.remove(0); - audioOutputSelect.removeAttribute("onclick"); - - for (let i = 0; i !== deviceInfos.length; ++i) { - const deviceInfo = deviceInfos[i]; - if (deviceInfo == null) { - continue; - } - const option = document.createElement('option'); - option.value = deviceInfo.deviceId; - if (deviceInfo.kind === 'audiooutput') { - const option = document.createElement('option'); - if (audioOutputSelect.length === 0) { - option.dataset.default = true; - } else { - option.dataset.default = false; - } - option.value = deviceInfo.deviceId || "default"; - if (option.value == session.sink) { - option.selected = true; - } - option.text = deviceInfo.label || `Speaker ${audioOutputSelect.length + 1}`; - audioOutputSelect.appendChild(option); - } else { - log('Some other kind of source/device: ', deviceInfo); - } - } - }); - }); - } catch (e) { - if (!(session.cleanOutput)) { - if (window.isSecureContext) { - warnUser("An error has occured when trying to access the default audio device. The reason is not known."); - } else if ((iOS) || (iPad)) { - warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported."); - } else { - warnUser("Error acessing the default audio device.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia"); - } - } - } -} - - -function requestAudioStream() { - try { - //warnlog("GET USER MEDIA"); - return navigator.mediaDevices.getUserMedia({ - audio: true - , video: false - }).then(function(stream1) { // Apple needs thi to happen before I can access EnumerateDevices. - log("get media sources; request audio stream"); - return enumerateDevices().then(function(deviceInfos) { - stream1.getTracks().forEach(function(track) { // We don't want to keep it without audio; so we are going to try to add audio now. - track.stop(); // I need to do this after the enumeration step, else it breaks firefox's labels - }); - log("updating audio"); - const audioInputSelect = getById('audioSourceScreenshare'); - audioInputSelect.remove(1); - audioInputSelect.removeAttribute("onchange"); - - - for (let i = 0; i !== deviceInfos.length; ++i) { - const deviceInfo = deviceInfos[i]; - if (deviceInfo == null) { - continue; - } - const option = document.createElement('option'); - option.value = deviceInfo.deviceId; - if (deviceInfo.kind === 'audioinput') { - option.text = deviceInfo.label || `Microphone ${audioInputSelect.length + 1}`; - audioInputSelect.appendChild(option); - } else { - log('Some other kind of source/device: ', deviceInfo); - } - } - audioInputSelect.style.minHeight = ((audioInputSelect.childElementCount + 1) * 1.15 * 16) + 'px'; - audioInputSelect.style.minWidth = "342px"; - }); - }); - } catch (e) { - if (!(session.cleanOutput)) { - if (window.isSecureContext) { - warnUser("An error has occured when trying to access the default audio device. The reason is not known."); - } else if ((iOS) || (iPad)) { - warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported."); - } else { - warnUser("Error acessing the default audio device.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia"); - } - } - } -} - - -function gotDevices(deviceInfos) { // https://github.com/webrtc/samples/blob/gh-pages/src/content/devices/input-output/js/main.js#L19 - - log("got devices!"); - log(deviceInfos); - try { - const audioInputSelect = getById('audioSource'); - - audioInputSelect.innerHTML = ""; - - var option = document.createElement('input'); - option.type = "checkbox"; - option.value = "ZZZ"; - option.name = "multiselect1"; - option.id = "multiselect1"; - option.style.display = "none"; - option.checked = true; - - - var label = document.createElement('label'); - label.for = option.name; - label.innerHTML = 'No Audio'; - - var listele = document.createElement('li'); - listele.appendChild(option); - listele.appendChild(label); - audioInputSelect.appendChild(listele); - - - option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected - if (!(getById("multiselect1").checked)) { - getById("multiselect1").checked = true; - - if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { - SelectedAudioInputDevices.push(event.currentTarget.value); - } - - log("CHECKED 1"); - } else { - - var list = document.querySelectorAll("#audioSource>li>input"); - for (var i = 0; i < list.length; i++) { - if (list[i].id !== "multiselect1") { - list[i].checked = false; - } - } - - while (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) { - SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(event.currentTarget.value), 1); - } - } - }; - - getById('multiselect-trigger').dataset.state = '0'; - getById('multiselect-trigger').classList.add('closed'); - getById('multiselect-trigger').classList.remove('open'); - getById('chevarrow1').classList.add('bottom'); - - const videoSelect = getById('videoSourceSelect'); - const audioOutputSelect = getById('outputSource'); - const selectors = [videoSelect]; - - const values = selectors.map(select => select.value); - selectors.forEach(select => { - while (select.firstChild) { - select.removeChild(select.firstChild); - } - }); - - - function comp(a, b) { - if (a.kind === 'audioinput') { - return 0; - } else if (a.kind === 'audiooutput') { - return 0; - } - const labelA = a.label.toUpperCase(); - const labelB = b.label.toUpperCase(); - if (labelA > labelB) { - return 1; - } else if (labelA < labelB) { - return -1; - } - return 0; - } - //deviceInfos.sort(comp); // I like this idea, but it messes with the defaults. I just don't know what it will do. - - // This is to hide NDI from default device. NDI Tools fucks up. - var tmp = []; - for (let i = 0; i !== deviceInfos.length; ++i) { - deviceInfo = deviceInfos[i]; - if (!((deviceInfo.kind === 'videoinput') && (deviceInfo.label.toLowerCase().startsWith("ndi") || deviceInfo.label.toLowerCase().startsWith("newtek")))) { - tmp.push(deviceInfo); - } - } - - for (let i = 0; i !== deviceInfos.length; ++i) { - deviceInfo = deviceInfos[i]; - if ((deviceInfo.kind === 'videoinput') && (deviceInfo.label.toLowerCase().startsWith("ndi") || deviceInfo.label.toLowerCase().startsWith("newtek"))) { - tmp.push(deviceInfo); - log("V DEVICE FOUND = " + deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase()); - } - } - deviceInfos = tmp; - log(deviceInfos); - - if ((session.audioDevice) && (session.audioDevice !== 1)) { // this sorts according to users's manual selection - var tmp = []; - for (let i = 0; i !== deviceInfos.length; ++i) { - deviceInfo = deviceInfos[i]; - if ((deviceInfo.kind === 'audioinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.audioDevice))) { - tmp.push(deviceInfo); - log("A DEVICE FOUND = " + deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase()); - } else if (deviceInfo.deviceId === session.audioDevice){ - tmp.push(deviceInfo); - log("EXACT A DEVICE FOUND"); - } - } - for (let i = 0; i !== deviceInfos.length; ++i) { - deviceInfo = deviceInfos[i]; - if (!((deviceInfo.kind === 'audioinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.audioDevice)))) { - if (deviceInfo.deviceId !== session.audioDevice){ - tmp.push(deviceInfo); - } - } - } - - deviceInfos = tmp; - log(session.audioDevice); - log(deviceInfos); - } - - - if ((session.videoDevice) && (session.videoDevice !== 1)) { // this sorts according to users's manual selection - var tmp = []; - for (let i = 0; i !== deviceInfos.length; ++i) { - deviceInfo = deviceInfos[i]; - if ((deviceInfo.kind === 'videoinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.videoDevice))) { - tmp.push(deviceInfo); - log("V DEVICE FOUND = " + deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase()); - } else if (deviceInfo.deviceId === session.videoDevice){ - tmp.push(deviceInfo); - log("EXACT V DEVICE FOUND"); - } - } - for (let i = 0; i !== deviceInfos.length; ++i) { - deviceInfo = deviceInfos[i]; - if (!((deviceInfo.kind === 'videoinput') && (deviceInfo.label.replace(/[\W]+/g, "_").toLowerCase().includes(session.videoDevice)))) { - if (deviceInfo.deviceId !== session.videoDevice){ - tmp.push(deviceInfo); - } - } - } - deviceInfos = tmp; - log("VDECICE:" + session.videoDevice); - log(deviceInfos); - } - - - var counter = 1; - for (let i = 0; i !== deviceInfos.length; ++i) { - const deviceInfo = deviceInfos[i]; - if (deviceInfo == null) { - continue; - } - - if (deviceInfo.kind === 'audioinput') { - option = document.createElement('input'); - option.type = "checkbox"; - counter++; - listele = document.createElement('li'); - if (counter == 2) { - option.checked = true; - listele.style.display = "block"; - option.style.display = "none"; - getById("multiselect1").checked = false; - try{ - getById("multiselect1").parentNode.style.display = "none"; - } catch(e){} - } else { - listele.style.display = "none"; - } - - - option.value = deviceInfo.deviceId || "default"; - option.name = "multiselect" + counter; - option.id = "multiselect" + counter; - label = document.createElement('label'); - label.for = option.name; - - label.innerHTML = " " + (deviceInfo.label || ("microphone " + ((audioInputSelect.length || 0) + 1))); - - listele.appendChild(option); - listele.appendChild(label); - audioInputSelect.appendChild(listele); - - option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected - getById("multiselect1").checked = false; - log("UNCHECKED"); - if (!(CtrlPressed)) { - document.querySelectorAll("#audioSource input[type='checkbox']").forEach(function(item) { - if (event.currentTarget.id !== item.id) { - item.checked = false; - - while (SelectedAudioInputDevices.indexOf(item.value) > -1) { - SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); - } - - } else { - item.checked = true; - if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { - SelectedAudioInputDevices.push(event.currentTarget.value); - } - } - }); - } - }; - - } else if (deviceInfo.kind === 'videoinput') { - option = document.createElement('option'); - option.value = deviceInfo.deviceId || "default"; - option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`; - videoSelect.appendChild(option); - } else if (deviceInfo.kind === 'audiooutput') { - option = document.createElement('option'); - if (audioOutputSelect.length === 0) { - option.dataset.default = true; - } else { - option.dataset.default = false; - } - option.value = deviceInfo.deviceId || "default"; - if (option.value == session.sink) { - option.selected = true; - } - option.text = deviceInfo.label || `Speaker ${audioOutputSelect.length + 1}`; - audioOutputSelect.appendChild(option); - } else { - log('Some other kind of source/device: ', deviceInfo); - } - } - - if (audioOutputSelect.childNodes.length == 0) { - option = document.createElement('option'); - option.value = "default"; - option.text = "System Default"; - audioOutputSelect.appendChild(option); - } - - option = document.createElement('option'); - option.text = "Disable Video"; - option.value = "ZZZ"; - videoSelect.appendChild(option); // NO AUDIO OPTION - - selectors.forEach((select, selectorIndex) => { - if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) { - select.value = values[selectorIndex]; - } - }); - - } catch (e) { - errorlog(e); - } -} - - -if (location.protocol !== 'https:') { - if (!(session.cleanOutput)) { - warnUser("SSL (https) is not enabled. This site will not work without it!

Try accessing the site from here instead."); - } -} - - -function getUserMediaVideoParams(resolutionFallbackLevel, isSafariBrowser) { - switch (resolutionFallbackLevel) { - case 0: - if (isSafariBrowser) { - return { - width: { - min: 360 - , ideal: 1920 - , max: 1920 - } - , height: { - min: 360 - , ideal: 1080 - , max: 1080 - } - }; - } else { - return { - width: { - min: 720 - , ideal: 1920 - , max: 1920 - } - , height: { - min: 720 - , ideal: 1080 - , max: 1920 - } - }; - } - case 1: - if (isSafariBrowser) { - return { - width: { - min: 360 - , ideal: 1280 - , max: 1280 - } - , height: { - min: 360 - , ideal: 720 - , max: 720 - } - }; - } else { - return { - width: { - min: 720 - , ideal: 1280 - , max: 1280 - } - , height: { - min: 720 - , ideal: 720 - , max: 1280 - } - }; - } - case 2: - if (isSafariBrowser) { - return { - width: { - min: 640 - } - , height: { - min: 360 - } - }; - } else { - return { - width: { - min: 240 - , ideal: 640 - , max: 1280 - } - , height: { - min: 240 - , ideal: 360 - , max: 1280 - } - }; - } - case 3: - if (isSafariBrowser) { - return { - width: { - min: 360 - , ideal: 1280 - , max: 1440 - } - }; - } else { - return { - width: { - min: 360 - , ideal: 1280 - , max: 1440 - } - }; - } - case 4: - if (isSafariBrowser) { - return { - height: { - min: 360 - , ideal: 720 - , max: 960 - } - }; - } else { - return { - height: { - ideal: 720 - , max: 960 - } - }; - } - case 5: - if (isSafariBrowser) { - return { - width: { - min: 360 - , ideal: 640 - , max: 1440 - } - , height: { - min: 360 - , ideal: 360 - , max: 720 - } - }; - } else { - return { - width: { - ideal: 640 - , max: 1920 - } - , height: { - ideal: 360 - , max: 1920 - } - }; // same as default, but I didn't want to mess with framerates until I gave it all a try first - } - case 6: - if (isSafariBrowser) { - return {}; // iphone users probably don't need to wait any longer, so let them just get to it - } else { - return { - width: { - min: 360 - , ideal: 640 - , max: 3840 - } - , height: { - min: 360 - , ideal: 360 - , max: 2160 - } - }; - - } - case 7: - return { // If the camera is recording in low-light, it may have a low framerate. It coudl also be recording at a very high resolution. - width: { - min: 360 - , ideal: 640 - } - , height: { - min: 360 - , ideal: 360 - } - , }; - - case 8: - return { - width: { - min: 360 - } - , height: { - min: 360 - } - , frameRate: 10 - }; // same as default, but I didn't want to mess with framerates until I gave it all a try first - case 9: - return { - frameRate: 0 - }; // Some Samsung Devices report they can only support a framerate of 0. - case 10: - return {} - default: - return {}; - } -} - -function addScreenDevices(device) { - if (device.kind == "audio") { - const audioInputSelect = getById('audioSource3'); - const listele = document.createElement('li'); - listele.style.display = "block"; - - const option = document.createElement('input'); - option.type = "checkbox"; - option.checked = true; - - if (getById('multiselect-trigger3').dataset.state == 0) { - option.style.display = "none"; - } - - option.value = device.id; - option.name = device.label; - option.dataset.type = "screen"; - option.label = device.label; - - const label = document.createElement('label'); - label.for = option.name; - label.innerHTML = " " + device.label; - listele.appendChild(option); - listele.appendChild(label); - - option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected - log("change 4644"); - if (!(CtrlPressed)) { - document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { - if (event.currentTarget.value !== item.value) { // this shoulnd't happen, but if it does. - - item.checked = false; - - if (item.dataset.type == "screen") { - item.parentElement.parentElement.removeChild(item.parentElement); - } - - while (SelectedAudioInputDevices.indexOf(item.value) > -1) { - SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); - } - - activatedPreview = false; - grabAudio("videosource", "#audioSource3"); // exclude item.id - - } else { - if (SelectedAudioInputDevices.indexOf(item.value) > -1) {} else { - SelectedAudioInputDevices.push(item.value); - } - - item.checked = true; - activatedPreview = false; - grabAudio("videosource", "#audioSource3", item.value); // exclude item.id. we will reconnect, even if already connected, as a way to 'reset' a device if it isn't working. - } - }); - } - event.stopPropagation(); - return false; - }; - audioInputSelect.appendChild(listele); - getById("audioSourceNoAudio2").checked = false; - - } else if (device.kind == "video") { - const videoSelect = getById('videoSource3'); - //const selectors = [ videoSelect]; - //const values = selectors.map(select => select.value); - const option = document.createElement('option'); - option.value = device.id; - option.text = device.label; - option.selected = true; - option.label = device.label; - videoSelect.appendChild(option); - } -} - -function gotDevices2(deviceInfos) { - log("got devices!"); - log(deviceInfos); - - getById("multiselect-trigger3").dataset.state = "0"; - getById("multiselect-trigger3").classList.add('closed'); - getById("multiselect-trigger3").classList.remove('open'); - getById("chevarrow2").classList.add('bottom'); - - var knownTrack = false; - - try { - const audioInputSelect = getById('audioSource3'); - const videoSelect = getById('videoSource3'); - const audioOutputSelect = getById('outputSource3'); - const selectors = [videoSelect]; - - - [audioInputSelect].forEach(select => { - while (select.firstChild) { - select.removeChild(select.firstChild); - } - }); - - const values = selectors.map(select => select.value); - selectors.forEach(select => { - while (select.firstChild) { - select.removeChild(select.firstChild); - } - }); - - [audioOutputSelect].forEach(select => { - while (select.firstChild) { - select.removeChild(select.firstChild); - } - }); - - var counter = 0; - for (let i = 0; i !== deviceInfos.length; ++i) { - const deviceInfo = deviceInfos[i]; - if (deviceInfo == null) { - continue; - } - - if (deviceInfo.kind === 'audioinput') { - const option = document.createElement('input'); - option.type = "checkbox"; - counter++; - const listele = document.createElement('li'); - listele.style.display = "none"; - - try { - session.streamSrc.getAudioTracks().forEach(function(track) { - if (deviceInfo.label == track.label) { - option.checked = true; - listele.style.display = "inherit"; - } - }); - } catch (e) { - errorlog(e); - } - - option.style.display = "none" - option.value = deviceInfo.deviceId || "default"; - option.name = "multiselecta" + counter; - option.id = "multiselecta" + counter; - option.dataset.label = deviceInfo.label || ("microphone " + ((audioInputSelect.length || 0) + 1)); - - const label = document.createElement('label'); - label.for = option.name; - - label.innerHTML = " " + (deviceInfo.label || ("microphone " + ((audioInputSelect.length || 0) + 1))); - - listele.appendChild(option); - listele.appendChild(label); - audioInputSelect.appendChild(listele); - - option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected - log("change 4768"); - if (!(CtrlPressed)) { - document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { - if (event.currentTarget.value !== item.value) { - item.checked = false; - if (item.dataset.type == "screen") { - item.parentElement.parentElement.removeChild(item.parentElement); - } - while (SelectedAudioInputDevices.indexOf(item.value) > -1) { - SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); - } - } else { - item.checked = true; - if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { - SelectedAudioInputDevices.push(event.currentTarget.value); - } - } - }); - } else { - - if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { - SelectedAudioInputDevices.push(event.currentTarget.value); - } - - getById("audioSourceNoAudio2").checked = false; - } - }; - - } else if (deviceInfo.kind === 'videoinput') { - const option = document.createElement('option'); - option.value = deviceInfo.deviceId || "default"; - option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`; - try { - if (!knownTrack){ - if (session.canvasSource){ - session.canvasSource.srcObject.getVideoTracks().forEach(function(track) { - if (option.text == track.label) { - option.selected = true; - knownTrack = true; - } - }); - } - } - if (!knownTrack){ - session.streamSrc.getVideoTracks().forEach(function(track) { - if (option.text == track.label) { - option.selected = true; - knownTrack = true; - } - }); - } - } catch (e) { - errorlog(e); - } - videoSelect.appendChild(option); - - } else if (deviceInfo.kind === 'audiooutput') { - const option = document.createElement('option'); - if (audioOutputSelect.length === 0) { - option.dataset.default = true; - } else { - option.dataset.default = false; - } - option.value = deviceInfo.deviceId || "default"; - if (option.value == session.sink) { - option.selected = true; - } - option.text = deviceInfo.label || `Speaker ${outputSelect.length + 1}`; - audioOutputSelect.appendChild(option); - - } else { - log('Some other kind of source/device: ', deviceInfo); - } - } - - if (audioOutputSelect.childNodes.length == 0) { - const option = document.createElement('option'); - option.value = "default"; - option.text = "System Default"; - audioOutputSelect.appendChild(option); - } - - //////////// - - session.streamSrc.getAudioTracks().forEach(function(track) { // add active ScreenShare audio tracks to the list - log("Checking for screenshare audio"); - var matched = false; - for (var i = 0; i !== deviceInfos.length; ++i) { - var deviceInfo = deviceInfos[i]; - if (deviceInfo == null) { - continue; - } - log("---"); - if (track.label == deviceInfo.label) { - matched = true; - continue; - } - } - if (matched == false) { // Not a gUM device - - var listele = document.createElement('li'); - listele.style.display = "block"; - var option = document.createElement('input'); - option.type = "checkbox"; - option.value = track.id; - option.checked = true; - option.style.display = "none"; - option.name = track.label; - option.label = track.label; - option.dataset.type = "screen"; - const label = document.createElement('label'); - label.for = option.name; - label.innerHTML = " " + track.label; - listele.appendChild(option); - listele.appendChild(label); - option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected - log("change 4873"); - var trackid = null; - if (!(CtrlPressed)) { - - document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { - if (event.currentTarget.value !== item.value) { // this shoulnd't happen, but if it does. - item.checked = false; - if (item.dataset.type == "screen") { - item.parentElement.parentElement.removeChild(item.parentElement); - } - } else { - event.currentTarget.checked = true; - trackid = item.value; - } - }); - } else { - //getById("audioSourceNoAudio2").checked=false; - if (event.currentTarget.dataset.type == "screen") { - event.currentTarget.parentElement.parentElement.removeChild(event.currentTarget.parentElement); - } - } - activatedPreview = false; - grabAudio("videosource", "#audioSource3", trackid); // exclude item.id. - event.stopPropagation(); - return false; - }; - audioInputSelect.appendChild(listele); - } - }); - /////////// no video option - var optionss = false; - if (screensharesupport) { - optionss = document.createElement('option'); - optionss.text = "New Screen Share"; - optionss.value = "XXX"; - optionss.previous = - videoSelect.appendChild(optionss); // NO AUDIO OPTION - } - - option = document.createElement('option'); // no video - option.text = "Disable Video"; - option.value = "ZZZ"; - videoSelect.appendChild(option); - if (session.streamSrc.getVideoTracks().length == 0) { - option.selected = true; - } else if (knownTrack == false) { - option = document.createElement('option'); // no video - option.text = session.streamSrc.getVideoTracks()[0].label; - option.value = "YYY"; - videoSelect.appendChild(option); - option.selected = true; - - } - - if (optionss) { - optionss.lastSelected = videoSelect.selectedIndex; - } - - ///////////// /// NO AUDIO appended option - - var option = document.createElement('input'); - option.type = "checkbox"; - option.value = "ZZZ"; - option.style.display = "none" - option.id = "audioSourceNoAudio2"; - - var label = document.createElement('label'); - label.for = option.name; - label.innerHTML = " No Audio"; - var listele = document.createElement('li'); - - if (session.streamSrc.getAudioTracks().length == 0) { - option.checked = true; - } else { - listele.style.display = "none"; - option.checked = false; - } - option.onchange = function(event) { // make sure to clear 'no audio option' if anything else is selected - log("change 4938"); - if (!(CtrlPressed)) { - document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { - if (event.currentTarget.value !== item.value) { - item.checked = false; - if (item.dataset.type == "screen") { - item.parentElement.parentElement.removeChild(item.parentElement); - } - - while (SelectedAudioInputDevices.indexOf(item.value) > -1) { - SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); - } - } else { - item.checked = true; - if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) { - // - } else { - SelectedAudioInputDevices.push(event.currentTarget.value); - } - } - }); - } else { - document.querySelectorAll("#audioSource3 input[type='checkbox']").forEach(function(item) { - if (event.currentTarget.value === item.value) { - event.currentTarget.checked = true; - if (SelectedAudioInputDevices.indexOf(event.currentTarget.value) > -1) {} else { - SelectedAudioInputDevices.push(event.currentTarget.value); - } - } else { - item.checked = false; - if (item.dataset.type == "screen") { - item.parentElement.parentElement.removeChild(item.parentElement); - } - while (SelectedAudioInputDevices.indexOf(item.value) > -1) { - SelectedAudioInputDevices.splice(SelectedAudioInputDevices.indexOf(item.value), 1); - } - } - - }); - } - }; - listele.appendChild(option); - listele.appendChild(label); - audioInputSelect.appendChild(listele); - - //////////// - - - selectors.forEach((select, selectorIndex) => { - if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) { - select.value = values[selectorIndex]; - } - }); - - audioInputSelect.onchange = function() { - log("Audio OPTION HAS CHANGED? 2"); - activatedPreview = false; - setTimeout(function(){ - grabAudio("videosource", "#audioSource3"); - },10) - }; - videoSelect.onchange = function(event) { - try { - if (event.target.options[event.target.options.selectedIndex].value === "XXX") { - videoSelect.selectedIndex = event.target.options[event.target.options.selectedIndex].lastSelected; - if (session.screenShareState == false) { - toggleScreenShare(); - } else { - toggleScreenShare(true); - } - return; - } - } catch (e) {} - log("video source changed"); - activatedPreview = false; - grabVideo(session.quality, "videosource", "select#videoSource3"); - enumerateDevices().then(gotDevices2).then(function() { - session.screenShareState = false; - pokeIframeAPI("screen-share-ended"); - getById("screensharebutton").classList.add("float"); - getById("screensharebutton").classList.remove("float2"); - }); - }; - getById("refreshVideoButton").onclick = function() { - if (session.screenShareState) { - log("can't refresh a screenshare"); - return; - } - log("video source changed"); - activatedPreview = false; - grabVideo(session.quality, "videosource", "select#videoSource3"); - }; - - audioOutputSelect.onchange = function() { - - if ((iOS) || (iPad)) { - return; - } - - try { - var outputSelect = getById('outputSource3'); - session.sink = outputSelect.options[outputSelect.selectedIndex].value; - } catch (e) { - errorlog(e); - } - if (!session.sink){return;} - - try { - if (document.getElementById("videosource")){ - getById("videosource").setSinkId(session.sink).then(() => { - log("New Output Device:" + session.sink); - }).catch(error => { - errorlog(error); - }); - } - - for (UUID in session.rpcs) { - try{ - if (session.rpcs[UUID].videoElement){ - session.rpcs[UUID].videoElement.setSinkId(session.sink).then(() => { - log("New Output Device for: " + UUID); - }).catch(error => { - errorlog(error); - }); - } - } catch(e){warnlog(e);} - } - } catch (e) { - errorlog(e); - } - } - - } catch (e) { - errorlog(e); - } -} - -function gotDevicesRemote(deviceInfos, UUID) { - - try { - if (document.getElementById("remoteVideoSelect_"+UUID)){ - var videoSelect = document.getElementById("remoteVideoSelect_"+UUID); - var length = videoSelect.options.length; - for (i = length-1; i >= 0; i--) { - videoSelect.options[i] = null; - } - } else { - var videoSelect = document.createElement("select"); - videoSelect.id = "remoteVideoSelect_"+UUID; - videoSelect.style = "max-width:180px;font-size: 70% !important; margin: 5px 5px 5px 0; padding:2px;"; - var buttonGO = document.createElement("button"); - buttonGO.innerHTML = ' Apply'; - buttonGO.style = "padding: 5px;"; - buttonGO.title = "This will ask the remote guest for permission to change"; - buttonGO.onclick = function(){ - var data = {} - data.changeCamera = videoSelect.value; - data.UUID = UUID; - session.sendRequest(data, UUID); // Viewer is requesting the PUBLISHER - }; - - getById("advanced_video_director_" + UUID).appendChild(videoSelect); - getById("advanced_video_director_" + UUID).appendChild(buttonGO); - } - - if (document.getElementById("remoteAudioSelect_"+UUID)){ - var audioSelect = document.getElementById("remoteAudioSelect_"+UUID); - var length = audioSelect.options.length; - for (i = length-1; i >= 0; i--) { - audioSelect.options[i] = null; - } - } else { - var audioSelect = document.createElement("select"); - audioSelect.id = "remoteAudioSelect_"+UUID; - audioSelect.style = "max-width:180px;font-size: 70% !important; margin: 5px 5px 5px 0; padding:2px;"; - var buttonGO = document.createElement("button"); - buttonGO.innerHTML = ' Apply'; - buttonGO.style = "padding: 5px;"; - buttonGO.title = "This will ask the remote guest for permission to change"; - buttonGO.onclick = function(){ - var data = {} - data.changeMicrophone = audioSelect.value; - data.UUID = UUID; - session.sendRequest(data, UUID); // Viewer is requesting the PUBLISHER - } - var audioSelectDiv = document.createElement("div"); - getById("advanced_audio_director_" + UUID).appendChild(audioSelectDiv); - audioSelectDiv.appendChild(audioSelect); - audioSelectDiv.appendChild(buttonGO); - - } - - if (document.getElementById("remoteAudioOutputSelect_"+UUID)){ - var audioOutputSelect = document.getElementById("remoteAudioOutputSelect_"+UUID); - var length = audioOutputSelect.options.length; - for (i = length-1; i >= 0; i--) { - audioOutputSelect.options[i] = null; - } - } else { - var audioOutputSelect = document.createElement("select"); - audioOutputSelect.id = "remoteAudioOutputSelect_"+UUID; - audioOutputSelect.style = "max-width:180px;font-size: 70% !important; margin: 5px 5px 5px 0; padding:2px;"; - var buttonGO = document.createElement("button"); - buttonGO.innerHTML = ' Apply'; - buttonGO.style = "padding: 5px;"; - buttonGO.title = "This will ask the remote guest for permission to change"; - buttonGO.onclick = function(){ - var data = {} - data.changeSpeaker = audioOutputSelect.value; - data.UUID = UUID; - session.sendRequest(data, UUID); // Viewer is requesting the PUBLISHER - } - getById("advanced_audio_director_" + UUID).appendChild(audioOutputSelect); - getById("advanced_audio_director_" + UUID).appendChild(buttonGO); - getById("advanced_audio_director_" + UUID).appendChild(buttonGO); - } - - - for (let i = 0; i !== deviceInfos.length; ++i) { - const deviceInfo = deviceInfos[i]; - if (deviceInfo == null) { - continue; - } - if (deviceInfo.kind === 'videoinput'){ - const option = document.createElement('option'); - option.value = deviceInfo.deviceId || "default"; - option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`; - videoSelect.appendChild(option); - - } else if (deviceInfo.kind === 'audioinput'){ - const option = document.createElement('option'); - option.value = deviceInfo.deviceId || "default"; - option.text = deviceInfo.label || `microphone ${audioSelect.length + 1}`; - audioSelect.appendChild(option); - - } else if (deviceInfo.kind === 'audiooutput'){ - const option = document.createElement('option'); - option.value = deviceInfo.deviceId || "default"; - option.text = deviceInfo.label || `microphone ${audioOutputSelect.length + 1}`; - audioOutputSelect.appendChild(option); - } - } - - } catch(e){errorlog(e);} -} - -function playtone(screen = false) { - - if ((iOS) || (iPad)) { - // try{ - // session.audioContext.resume(); - // } catch(e){errorlog(e);} - var testtone = document.getElementById("testtone"); - if (testtone) { - testtone.mute - testtone.play(); - } - return; - } - - if (screen) { - try{ - var outputSelect = getById('outputSourceScreenshare'); - session.sink = outputSelect.options[outputSelect.selectedIndex].value; - } catch(e){errorlog(e);} - } - - var testtone = document.getElementById("testtone"); - if (testtone) { - if (session.sink) { - try { - testtone.setSinkId(session.sink).then(() => { // TODO: iOS doens't support sink. Needs to bypass if IOS - log("changing audio sink:" + session.sink); - testtone.play(); - }).catch(error => { - errolog("couldn't set sink"); - errorlog(error); - }); - } catch (e) { - warnlog(e); // firefox? - testtone.play(); - } - } else { - testtone.play(); - } - } -} - -async function getAudioOnly(selector, trackid = null, override = false) { - var audioSelect = document.querySelector(selector).querySelectorAll("input"); - var audioList = []; - var streams = []; - log("getAudioOnly()"); - for (var i = 0; i < audioSelect.length; i++) { - if (audioSelect[i].value == "ZZZ") { - continue; - } else if (trackid == audioSelect[i].value) { // skip already excluded - continue; - } else if ("screen" == audioSelect[i].dataset.type) { // skip already excluded ---------- !!!!!! DOES THIS MAKE SENSE? TODO: CHECK - continue; - } else if (audioSelect[i].checked) { - log(audioSelect[i]); - audioList.push(audioSelect[i]); - } - } - for (var i = 0; i < audioList.length; i++) { - - if ((session.echoCancellation !== false) && (session.autoGainControl !== false) && (session.noiseSuppression !== false)) { - var constraint = { - audio: { - deviceId: audioList[i].value - } - }; - } else { // Just trying to avoid problems with some systems that don't support these features - var constraint = { - audio: { - deviceId: { - exact: audioList[i].value - } - } - }; - if (session.echoCancellation === false) { - constraint.audio.echoCancellation = false; - } else { - constraint.audio.echoCancellation = true; - } - if (session.autoGainControl === false) { - constraint.audio.autoGainControl = false; - } else { - constraint.audio.autoGainControl = true; - } - if (session.noiseSuppression === false) { - constraint.audio.noiseSuppression = false; - } else { - constraint.audio.noiseSuppression = true; - } - } - constraint.video = false; - if (override !== false) { - try { - if (override.audio.deviceId == audioList[i].value) { - constraint = override; - } - } catch (e) {} - } - - if (session.audioInputChannels) { - if (constraint.audio === true) { - constraint.audio = {}; - constraint.audio.channelCount = session.audioInputChannels; - } else if (constraint.audio) { - constraint.audio.channelCount = session.audioInputChannels; - } - } - log("CONSTRAINT"); - log(constraint); - var stream = await navigator.mediaDevices.getUserMedia(constraint).then(function(stream2) { - return stream2; - }).catch(function(err) { - warnlog(err); - if (!(session.cleanOutput)) { - if (override !== false) { - if (err.name) { - if (err.constraint) { - warnUser(err['name'] + ": " + err['constraint']); - } - } - } - } - }); // More error reporting maybe? - if (stream) { - streams.push(stream); - } - } - - return streams; -} - -function applyMirror(mirror, eleName = 'previewWebcam') { // true unmirrors as its already mirrored - - var transFlip = ""; - var transNorm = ""; - if ((eleName == 'videosource') && (session.windowed)) { - transFlip = " translate(0, 50%)"; - transNorm = " translate(0, -50%)"; - } - - if (session.mirrored == 2) { - mirror = true; - } else if (session.mirrored === 0) { - mirror = true; - } - - - if (mirror) { - if (session.mirrored && session.flipped) { - getById(eleName).style.transform = " scaleX(-1) scaleY(-1)" + transFlip; - getById(eleName).classList.add("mirrorControl"); - } else if (session.mirrored) { - getById(eleName).style.transform = "scaleX(-1)" + transNorm; - getById(eleName).classList.add("mirrorControl"); - } else if (session.flipped) { - getById(eleName).style.transform = "scaleY(-1) scaleX(1)" + transFlip; - getById(eleName).classList.remove("mirrorControl"); - } else { - getById(eleName).style.transform = "scaleX(1)" + transNorm; - getById(eleName).classList.remove("mirrorControl"); - } - } else { - if (session.mirrored && session.flipped) { - getById(eleName).style.transform = " scaleX(1) scaleY(-1)" + transFlip; - getById(eleName).classList.remove("mirrorControl"); - } else if (session.mirrored) { - getById(eleName).style.transform = "scaleX(1)" + transNorm; - getById(eleName).classList.remove("mirrorControl"); - } else if (session.flipped) { - getById(eleName).style.transform = "scaleY(-1) scaleX(-1)" + transFlip; - getById(eleName).classList.add("mirrorControl"); - } else { - getById(eleName).style.transform = "scaleX(-1)" + transNorm; - getById(eleName).classList.add("mirrorControl"); - } - } -} - -function cleanupMediaTracks() { - try { - if (session.streamSrc) { - session.streamSrc.getTracks().forEach(function(track) { - session.streamSrc.removeTrack(track); - track.stop(); - log("stopping old track"); - }); - } - if (session.videoElement) { - session.videoElement.srcObject.getTracks().forEach(function(track) { - session.videoElement.srcObject.removeTrack(track); - track.stop(); - log("stopping old track"); - }); - } - activatedPreview = false; - } catch (e) { - errorlog(e); - } -} - -/// Detect system changes; handle change or use for debugging -var lastAudioDevice = null; -var lastVideoDevice = null; -var lastPlaybackDevice = null; - -var audioReconnectTimeout = null; -var videoReconnectTimeout = null; -var grabDevicesTimeout = null; -var playbackReconnectTimeout = null; - -function reconnectDevices(event) { /// TODO: Perhaps change this to only if there is a DISCONNECT; rather than ON NEW DEVICE? - if ((iOS) || (iPad)) { - // try{ - // session.audioContext.resume(); - // } catch(e){errorlog(e);} - // resetupAudioOut(); - return; - } - warnlog("A media device has changed"); - - if (document.getElementById("previewWebcam")) { - var outputSelect = document.getElementById("outputSource"); - if (!outputSelect) { - errorlog("resetup audio failed"); - return; - } - try { - session.sink = outputSelect.options[outputSelect.selectedIndex].value; } catch (e) { errorlog(e); - } - if (session.sink){ + }; + } + + if ((session.view) && (session.roomid === false)) { + getById("container-4").className = 'column columnfade'; + getById("container-3").className = 'column columnfade'; + getById("container-2").className = 'column columnfade'; + getById("container-1").className = 'column columnfade'; + //getById("header").className = 'advanced'; + getById("info").className = 'advanced'; + getById("header").className = 'advanced'; + getById("head1").className = 'advanced'; + getById("head2").className = 'advanced'; + getById("head3").className = 'advanced'; + + + getById("mainmenu").style.backgroundRepeat = "no-repeat"; + getById("mainmenu").style.backgroundPosition = "bottom center"; + getById("mainmenu").style.minHeight = "300px"; + getById("mainmenu").style.backgroundSize = "100px 100px"; + getById("mainmenu").innerHTML = ''; + + setTimeout(function() { try { - getById("previewWebcam").setSinkId(session.sink).then(() => {}).catch(error => { - warnlog(error); - }); - } catch(e){errorlog(e);} + if ((session.view) && (!(session.cleanOutput))) { + if (document.getElementById("mainmenu")) { + getById("mainmenu").style.backgroundImage = "url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZpZXdCb3g9IjAgMCA0MCA0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7IiB4PSIwcHgiIHk9IjBweCI+CiAgICA8ZGVmcz4KICAgICAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhW0NEQVRBWwogICAgICAgICAgICBALXdlYmtpdC1rZXlmcmFtZXMgc3BpbiB7CiAgICAgICAgICAgICAgZnJvbSB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoLTM1OWRlZykKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQGtleWZyYW1lcyBzcGluIHsKICAgICAgICAgICAgICBmcm9tIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKC0zNTlkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHN2ZyB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7CiAgICAgICAgICAgICAgICAtd2Via2l0LWFuaW1hdGlvbjogc3BpbiAxLjVzIGxpbmVhciBpbmZpbml0ZTsKICAgICAgICAgICAgICAgIC13ZWJraXQtYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuOwogICAgICAgICAgICAgICAgYW5pbWF0aW9uOiBzcGluIDEuNXMgbGluZWFyIGluZmluaXRlOwogICAgICAgICAgICB9CiAgICAgICAgXV0+PC9zdHlsZT4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJvdXRlciI+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwwQzIyLjIwNTgsMCAyMy45OTM5LDEuNzg4MTMgMjMuOTkzOSwzLjk5MzlDMjMuOTkzOSw2LjE5OTY4IDIyLjIwNTgsNy45ODc4MSAyMCw3Ljk4NzgxQzE3Ljc5NDIsNy45ODc4MSAxNi4wMDYxLDYuMTk5NjggMTYuMDA2MSwzLjk5MzlDMTYuMDA2MSwxLjc4ODEzIDE3Ljc5NDIsMCAyMCwwWiIgc3R5bGU9ImZpbGw6YmxhY2s7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNNS44NTc4Niw1Ljg1Nzg2QzcuNDE3NTgsNC4yOTgxNSA5Ljk0NjM4LDQuMjk4MTUgMTEuNTA2MSw1Ljg1Nzg2QzEzLjA2NTgsNy40MTc1OCAxMy4wNjU4LDkuOTQ2MzggMTEuNTA2MSwxMS41MDYxQzkuOTQ2MzgsMTMuMDY1OCA3LjQxNzU4LDEzLjA2NTggNS44NTc4NiwxMS41MDYxQzQuMjk4MTUsOS45NDYzOCA0LjI5ODE1LDcuNDE3NTggNS44NTc4Niw1Ljg1Nzg2WiIgc3R5bGU9ImZpbGw6cmdiKDIxMCwyMTAsMjEwKTsiLz4KICAgICAgICA8L2c+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwzMi4wMTIyQzIyLjIwNTgsMzIuMDEyMiAyMy45OTM5LDMzLjgwMDMgMjMuOTkzOSwzNi4wMDYxQzIzLjk5MzksMzguMjExOSAyMi4yMDU4LDQwIDIwLDQwQzE3Ljc5NDIsNDAgMTYuMDA2MSwzOC4yMTE5IDE2LjAwNjEsMzYuMDA2MUMxNi4wMDYxLDMzLjgwMDMgMTcuNzk0MiwzMi4wMTIyIDIwLDMyLjAxMjJaIiBzdHlsZT0iZmlsbDpyZ2IoMTMwLDEzMCwxMzApOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksMjguNDkzOUMzMC4wNTM2LDI2LjkzNDIgMzIuNTgyNCwyNi45MzQyIDM0LjE0MjEsMjguNDkzOUMzNS43MDE5LDMwLjA1MzYgMzUuNzAxOSwzMi41ODI0IDM0LjE0MjEsMzQuMTQyMUMzMi41ODI0LDM1LjcwMTkgMzAuMDUzNiwzNS43MDE5IDI4LjQ5MzksMzQuMTQyMUMyNi45MzQyLDMyLjU4MjQgMjYuOTM0MiwzMC4wNTM2IDI4LjQ5MzksMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxMDEsMTAxLDEwMSk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMy45OTM5LDE2LjAwNjFDNi4xOTk2OCwxNi4wMDYxIDcuOTg3ODEsMTcuNzk0MiA3Ljk4NzgxLDIwQzcuOTg3ODEsMjIuMjA1OCA2LjE5OTY4LDIzLjk5MzkgMy45OTM5LDIzLjk5MzlDMS43ODgxMywyMy45OTM5IDAsMjIuMjA1OCAwLDIwQzAsMTcuNzk0MiAxLjc4ODEzLDE2LjAwNjEgMy45OTM5LDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoMTg3LDE4NywxODcpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTUuODU3ODYsMjguNDkzOUM3LjQxNzU4LDI2LjkzNDIgOS45NDYzOCwyNi45MzQyIDExLjUwNjEsMjguNDkzOUMxMy4wNjU4LDMwLjA1MzYgMTMuMDY1OCwzMi41ODI0IDExLjUwNjEsMzQuMTQyMUM5Ljk0NjM4LDM1LjcwMTkgNy40MTc1OCwzNS43MDE5IDUuODU3ODYsMzQuMTQyMUM0LjI5ODE1LDMyLjU4MjQgNC4yOTgxNSwzMC4wNTM2IDUuODU3ODYsMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxNjQsMTY0LDE2NCk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMzYuMDA2MSwxNi4wMDYxQzM4LjIxMTksMTYuMDA2MSA0MCwxNy43OTQyIDQwLDIwQzQwLDIyLjIwNTggMzguMjExOSwyMy45OTM5IDM2LjAwNjEsMjMuOTkzOUMzMy44MDAzLDIzLjk5MzkgMzIuMDEyMiwyMi4yMDU4IDMyLjAxMjIsMjBDMzIuMDEyMiwxNy43OTQyIDMzLjgwMDMsMTYuMDA2MSAzNi4wMDYxLDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoNzQsNzQsNzQpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksNS44NTc4NkMzMC4wNTM2LDQuMjk4MTUgMzIuNTgyNCw0LjI5ODE1IDM0LjE0MjEsNS44NTc4NkMzNS43MDE5LDcuNDE3NTggMzUuNzAxOSw5Ljk0NjM4IDM0LjE0MjEsMTEuNTA2MUMzMi41ODI0LDEzLjA2NTggMzAuMDUzNiwxMy4wNjU4IDI4LjQ5MzksMTEuNTA2MUMyNi45MzQyLDkuOTQ2MzggMjYuOTM0Miw3LjQxNzU4IDI4LjQ5MzksNS44NTc4NloiIHN0eWxlPSJmaWxsOnJnYig1MCw1MCw1MCk7Ii8+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4K')"; + getById("mainmenu").innerHTML = '

Attempting to load video stream.

'; + getById("mainmenu").innerHTML += 'The stream is not available yet or an error occured.

'; + + } + } + } catch (e) { + errorlog("Error handling QR Code failure"); + } + }, 15000); + + log("auto playing"); + var SafariVer = safariVersion(); + if ((iPad || iOS) && navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1 && SafariVer > 13) { // Modern iOS doesn't need pop up + play(); + } else if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) { // Safari on Desktop does require pop up + if (!(session.cleanOutput)) { + warnUser("Safari requires us to ask for an audio permission to use peer-to-peer technology. You will need to accept it in a moment if asked to view this live video", 20000); + } + navigator.mediaDevices.getUserMedia({ + audio: true + }).then(function() { + closeModal(); + play(); + }).catch(function() { + play(); + }); + } else { // everything else is OK. + play(); } - return; - } + } else if (session.roomid) { + try { + if (session.label === false) { + if (document.title == "") { + document.title = "Room=" + session.roomid.toString(); + } else { + document.title += ": " + session.roomid.toString(); + } + } + } catch (e) { + errorlog(e); + }; - - if (session.streamSrc === null) { - return; } - if (document.getElementById("videosource") === null) { - return; + setTimeout(function(){ + for (var i in delayedStartupFuncs) { + var cb = delayedStartupFuncs[i]; + log(cb.slice(1)); + cb[0](...cb.slice(1)); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#A_better_apply + } + delayedStartupFuncs = []; + },50); + + if ((session.effects==3) || (session.effects==4) || (session.effects==5)){ + attemptTFLiteJsFileLoad(); + } else if (session.effects==6){ + var script = document.createElement('script'); + var script2 = document.createElement('script'); + var script3 = document.createElement('script'); + var script4 = document.createElement('script'); + model = false; + script.onload = function() { + document.head.appendChild(script2); + } + script2.onload = function() { + document.head.appendChild(script3); + } + script3.onload = function() { + document.head.appendChild(script4); + } + script4.onload = function() { + async function loadModel(){ + model = await faceLandmarksDetection.load(faceLandmarksDetection.SupportedPackages.mediapipeFacemesh); + + } + loadModel(); + } + script.src = "https://unpkg.com/@tensorflow/tfjs-core@2.4.0/dist/tf-core.js"; + script2.src = "https://unpkg.com/@tensorflow/tfjs-converter@2.4.0/dist/tf-converter.js"; + script3.src = "https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.4.0/dist/tf-backend-webgl.js"; + script4.src = "https://unpkg.com/@tensorflow-models/face-landmarks-detection@0.0.1/dist/face-landmarks-detection.js"; + + script.type = 'text/javascript';script2.type = 'text/javascript';script3.type = 'text/javascript';script4.type = 'text/javascript'; + document.head.appendChild(script); + } + + if (location.protocol !== 'https:') { + if (!(session.cleanOutput)) { + warnUser("SSL (https) is not enabled. This site will not work without it!

Try accessing the site from here instead."); + } + } + + if (session.sensorData) { + setupSensorData(parseInt(session.sensorData)); } try { - session.streamSrc.getTracks().forEach(function(track) { - - if (track.readyState == "ended") { - if (track.kind == "audio") { - lastAudioDevice = track.label; - } else if (track.kind == "video") { - lastVideoDevice = track.label; - } - session.streamSrc.removeTrack(track); - log("remove ended old track"); - } - }); - - session.videoElement.srcObject.getTracks().forEach(function(track) { - if (track.readyState == "ended") { - session.videoElement.srcObject.removeTrack(track); - log("remove ended old track"); - } - }); - + navigator.mediaDevices.ondevicechange = reconnectDevices; } catch (e) { errorlog(e); } - clearTimeout(audioReconnectTimeout); - audioReconnectTimeout = null; - if (lastAudioDevice) { - audioReconnectTimeout = setTimeout(function() { // only reconnect same audio device. If reconnected, clear the disconnected flag. - enumerateDevices().then(gotDevices2).then(function() { - // TODO: check to see if any audio is connected? - var streamConnected = false; - var audioSelect = getById("audioSource3").querySelectorAll("input"); - for (var i = 0; i < audioSelect.length; i++) { - if (audioSelect[i].value == "ZZZ") { - continue; - } else if (audioSelect[i].checked) { - log("checked"); - streamConnected = true; - break; + if (isIFrame) { // reduce CPU load if not needed. + window.onmessage = function(e) { // iFRAME support + log(e); + try { + if ("function" in e.data) { // these are calling in-app functions, with perhaps a callback -- TODO: add callbacks + var ret = null; + if (e.data.function === "previewWebcam") { + ret = previewWebcam(); + } else if (e.data.function === "changeHTML") { + ret = getById(e.data.target); + ret.innerHTML = e.data.value; + } else if (e.data.function === "publishScreen") { + ret = publishScreen(); + } else if (e.data.function === "eval") { + eval(e.data.value); // eval == evil ; feedback welcomed } } + } catch (err) { + errorlog(err); + } - if (!streamConnected) { - for (var i = 0; i < audioSelect.length; i++) { - if (audioSelect[i].value == "ZZZ") { - continue; - } - //errorlog(lastAudioDevice + " : " + audioSelect[i].dataset.label); - if (lastAudioDevice == audioSelect[i].dataset.label) { // if the last disconnected device matches. - audioSelect[i].checked = true; - streamConnected = true; - lastAudioDevice = null; - warnlog("DISCONNECTED AUDIO DEVICE RECONNECTED"); - //for (var j=0; j check if session.sink still exists -> if not, select default default (track past last sink) -> if last disconnected devices comes back, reconnect it. - - // lastPlaybackDevice - //if (session.sink){ // Let Chrome handle the audio automatically, since not manually specified. - clearTimeout(playbackReconnectTimeout); - playbackReconnectTimeout = setTimeout(function() { - enumerateDevices().then(gotDevices2).then(function() { - resetupAudioOut(); - }); - }, 500); - -} - -function resetupAudioOut() { - if (iOS || iPad) { - for (var UUID in session.rpcs) { - if (session.rpcs[UUID].videoElement){ - try{ - log("10076"); - session.rpcs[UUID].videoElement.pause().then(() => { - setTimeout(function(uuid) { - log("win"); - try{ - session.rpcs[uuid].videoElement.play().then(() => { - log("toggle pause/play"); - }); - } catch(e){errorlog(e);} - }, 0, UUID); - }); - } catch(e){errorlog(e);} - } - } - return; - } - - var outputSelect = document.getElementById("outputSource3"); - if (!outputSelect) { - errorlog("resetup audio failed"); - return; - } - log("Resetting Audio Output"); - var sinkSet = false; - for (var i = 0; i < outputSelect.options.length; i++) { - if (outputSelect.options[i].value == session.sink) { - outputSelect.options[i].selected = true; - sinkSet = true; - } - } - if (sinkSet == false) { - if (outputSelect.options[0]) { - outputSelect.options[0].selected = true; - sinkSet = outputSelect.value; - } - } else { - sinkSet = session.sink; - } - if (sinkSet) { - if (session.videoElement){ - session.videoElement.setSinkId(sinkSet).then(() => {}).catch(error => { - errorlog(error); - }); - } - for (UUID in session.rpcs) { - try{ - if (session.rpcs[UUID].videoElement){ - session.rpcs[UUID].videoElement.setSinkId(sinkSet).then(() => { - log("New Output Device for: " + UUID); - }).catch(error => { - errorlog(error); - }); - } - } catch(e){warnlog(e);} - } - } -} - -function obfuscateURL(input) { - if (input.startsWith("https://obs.ninja/")) { - input = input.replace('https://obs.ninja/', ''); - } else if (input.startsWith("http://obs.ninja/")) { - input = input.replace('http://obs.ninja/', ''); - } else if (input.startsWith("obs.ninja/")) { - input = input.replace('obs.ninja/', ''); - } else if (input.startsWith("https://vdo.ninja/")) { - input = input.replace('https://vdo.ninja/', ''); - } else if (input.startsWith("http://vdo.ninja/")) { - input = input.replace('http://vdo.ninja/', ''); - } else if (input.startsWith("vdo.ninja/")) { - input = input.replace('vdo.ninja/', ''); - } - - input = input.replace('&view=', '&v='); - input = input.replace('&view&', '&v&'); - input = input.replace('?view&', '?v&'); - input = input.replace('?view=', '?v='); - - input = input.replace('&videobitrate=', '&vb='); - input = input.replace('?videobitrate=', '?vb='); - input = input.replace('&bitrate=', '&vb='); - input = input.replace('?bitrate=', '?vb='); - - input = input.replace('?audiodevice=', '?ad='); - input = input.replace('&audiodevice=', '&ad='); - - input = input.replace('?label=', '?l='); - input = input.replace('&label=', '&l='); - - input = input.replace('?stereo=', '?s='); - input = input.replace('&stereo=', '&s='); - input = input.replace('&stereo&', '&s&'); - input = input.replace('?stereo&', '?s&'); - - input = input.replace('?webcam&', '?wc&'); - input = input.replace('&webcam&', '&wc&'); - - input = input.replace('?remote=', '?rm='); - input = input.replace('&remote=', '&rm='); - - input = input.replace('?password=', '?p='); - input = input.replace('&password=', '&p='); - - input = input.replace('&maxvideobitrate=', '&mvb='); - input = input.replace('?maxvideobitrate=', '?mvb='); - - input = input.replace('&maxbitrate=', '&mvb='); - input = input.replace('?maxbitrate=', '?mvb='); - - input = input.replace('&height=', '&h='); - input = input.replace('?height=', '?h='); - - input = input.replace('&width=', '&w='); - input = input.replace('?width=', '?w='); - - input = input.replace('&quality=', '&q='); - input = input.replace('?quality=', '?q='); - - input = input.replace('&cleanoutput=', '&clean='); - input = input.replace('?cleanoutput=', '?clean='); - - input = input.replace('&maxviewers=', '&clean='); - input = input.replace('?maxviewers=', '?clean='); - - input = input.replace('&framerate=', '&fr='); - input = input.replace('?framerate=', '?fr='); - - input = input.replace('&fps=', '&fr='); - input = input.replace('?fps=', '?fr='); - - input = input.replace('&permaid=', '&push='); - input = input.replace('?permaid=', '?push='); - - input = input.replace('&roomid=', '&r='); - input = input.replace('?roomid=', '?r='); - - input = input.replace('&room=', '&r='); - input = input.replace('?room=', '?r='); - - log(input); - var key = "OBSNINJAFORLIFE"; - var encrypted = CryptoJS.AES.encrypt(input, key); - var output = "https://invite.cam/" + encrypted.toString(); - return output; -} - - - -try { - navigator.mediaDevices.ondevicechange = reconnectDevices; -} catch (e) { - errorlog(e); -} - - -function updateConnectionStatus() { - warnlog("Connection type changed from " + session.stats.network_type + " to " + Connection.effectiveType); - session.stats.network_type = Connection.effectiveType + " / " + Connection.type; - session.ping(); -} - -try { - var Connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; - session.stats.network_type = Connection.effectiveType + " / " + Connection.type; - Connection.addEventListener('change', updateConnectionStatus); -} catch (e) {} - - - -var beforeScreenShare = null; // video -var screenShareAudioTrack = null; -async function toggleScreenShare(reload = false) { //////////////////////////// - - if (reload) { - await grabScreen(quality = 0, audio = true, videoOnEnd = true).then(res => { - if (res != false) { - session.screenShareState = true; - getById("screensharebutton").classList.add("float2"); - getById("screensharebutton").classList.remove("float"); - enumerateDevices().then(gotDevices2).then(function() {}); } - }); - return; - } + if ("bitrate" in e.data) { + for (var i in session.rpcs) { + try { + session.requestRateLimit(parseInt(e.data.bitrate), i); + } catch (e) { + errorlog(e); + } + } + } + + if ("audiobitrate" in e.data) { + for (var i in session.rpcs) { + try { + session.requestAudioRateLimit(parseInt(e.data.audiobitrate), i); + } catch (e) { + errorlog(e); + } + } + } + + if ("changeVideoDevice" in e.data) { + warnlog(e.data.changeVideoDevice); + changeVideoDevice(e.data.changeVideoDevice); + } + + if ("changeAudioDevice" in e.data) { + warnlog(e.data.changeAudioDevice); + changeAudioDevice(e.data.changeAudioDevice); + } + + if ("sceneState" in e.data) { // TRUE OR FALSE - tells the connected peers if they are live or not via a tally light change. - if (session.screenShareState == false) { // adding a screen - - await grabScreen(quality = 0, audio = true, videoOnEnd = true).then(res => { - if (res != false) { - session.screenShareState = true; - getById("screensharebutton").classList.add("float2"); - getById("screensharebutton").classList.remove("float"); - enumerateDevices().then(gotDevices2).then(function() {}); + if (session.obsState.visibility !== e.data.sceneState) { // only move forward if there is a change; the event likes to double fire you see. + session.obsStateSync(); + } } - }); + if ("sendMessage" in e.data) { // webrtc send to viewers + session.sendMessage(e.data); + } - } else { // removing a screen . session.screenShareState already true true ///////////////////////////////// + if ("sendRequest" in e.data) { // webrtc send to publishers + session.sendRequest(e.data); + } + if ("sendPeers" in e.data) { // webrtc send message to every connected peer; like send and request; a hammer vs a knife. + session.sendPeers(e.data); + } - session.screenShareState = false; - pokeIframeAPI("screen-share-ended"); + if ("reload" in e.data) { + location.reload(); + } - if (beforeScreenShare) { + if ("getStats" in e.data) { - session.streamSrc.getAudioTracks().forEach(function(track) { // previous video track; saving it. Must remove the track at some point. - if (screenShareAudioTrack == track) { // since there are more than one audio track, lets see if we can remove JUST the audio track for the screen share. - session.streamSrc.removeTrack(track); - track.stop(); + var stats = {}; + stats.total_outbound_connections = Object.keys(session.pcs).length; + stats.total_inbound_connections = Object.keys(session.rpcs).length; + stats.inbound_stats = {}; + for (var i in session.rpcs) { + stats.inbound_stats[session.rpcs[i].streamID] = session.rpcs[i].stats; } - }); - session.streamSrc.getVideoTracks().forEach(function(track) { - //errorlog(track); - session.streamSrc.removeTrack(track); - track.stop(); - }); - session.videoElement.srcObject.getVideoTracks().forEach(function(track) { - //errorlog(track); - session.videoElement.srcObject.removeTrack(track); - track.stop(); - }); + for (var uuid in session.pcs) { + setTimeout(function(UUID) { + session.pcs[UUID].getStats().then(function(stats) { + stats.forEach(stat => { + if (stat.type == "outbound-rtp") { + if (stat.kind == "video") { - getById("screensharebutton").classList.add("float"); - getById("screensharebutton").classList.remove("float2"); - - session.streamSrc.addTrack(beforeScreenShare); // add back in the video track we had before we started screen sharing. It should be NULL if we changed the video track else where (such as via the settings). #TODO: - session.videoElement.srcObject.addTrack(beforeScreenShare); - - toggleVideoMute(true); - for (UUID in session.pcs) { - try { - if ((session.pcs[UUID].guest == true) && (session.roombitrate === 0)) { - log("room rate restriction detected. No videos will be published to other guests"); - } else if (session.pcs[UUID].allowVideo == true) { // allow - var senders = session.pcs[UUID].getSenders(); // for any connected peer, update the video they have if connected with a video already. - var added = false; - senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? - if (sender.track) { - if (sender.track && sender.track.kind == "video") { - sender.replaceTrack(beforeScreenShare); // replace may not be supported by all browsers. eek. - sender.track.enabled = true; - added = true; + if ("qualityLimitationReason" in stat) { + session.pcs[UUID].stats.quality_limitation_reason = stat.qualityLimitationReason; + } + if ("framesPerSecond" in stat) { + session.pcs[UUID].stats.resolution = stat.frameWidth + " x " + stat.frameHeight + " @ " + stat.framesPerSecond; + } + if ("encoderImplementation" in stat) { + session.pcs[UUID].stats.encoder = stat.encoderImplementation; + } + } + } else if (stat.type == "remote-candidate") { + if ("relayProtocol" in stat) { + if ("ip" in stat) { + session.pcs[UUID].stats.remote_relay_IP = stat.ip; + } + session.pcs[UUID].stats.remote_relayProtocol = stat.relayProtocol; + } + if ("candidateType" in stat) { + session.pcs[UUID].stats.remote_candidateType = stat.candidateType; + } + } else if (stat.type == "local-candidate") { + if ("relayProtocol" in stat) { + if ("ip" in stat) { + session.pcs[UUID].stats.local_relayIP = stat.ip; + } + session.pcs[UUID].stats.local_relayProtocol = stat.relayProtocol; + } + if ("candidateType" in stat) { + session.pcs[UUID].stats.local_candidateType = stat.candidateType; + } + } else if ((stat.type == "candidate-pair" ) && (stat.nominated)) { + + if ("availableOutgoingBitrate" in stat){ + session.pcs[UUID].stats.available_outgoing_bitrate_kbps = parseInt(stat.availableOutgoingBitrate/1024); + } + if ("totalRoundTripTime" in stat){ + if ("responsesReceived" in stat){ + session.pcs[UUID].stats.average_roundTripTime_ms = parseInt((stat.totalRoundTripTime/stat.responsesReceived)*1000); + } + + } } - } + return; + }); + return; }); - if (added == false) { - session.pcs[UUID].addTrack(beforeScreenShare, stream); - setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker - } + }, 0, uuid); + } + setTimeout(function() { + stats.outbound_stats = {}; + for (var i in session.pcs) { + stats.outbound_stats[i] = session.pcs[i].stats; } + parent.postMessage({ + "stats": stats + }, "*"); + }, 1000); + } + + if ("getRemoteStats" in e.data) { + session.sendRequest({"requestStats":true, "remote":session.remote}); + } + + if ("getLoudness" in e.data) { + log("GOT LOUDNESS REQUEST"); + if (e.data.getLoudness == true) { + session.pushLoudness = true; + var loudness = {}; + + for (var i in session.rpcs) { + loudness[session.rpcs[i].streamID] = session.rpcs[i].stats.Audio_Loudness; + } + + parent.postMessage({ + "loudness": loudness + }, "*"); + + } else { + session.pushLoudness = false; + } + } + + if ("getStreamIDs" in e.data) { + if (e.data.getStreamIDs == true) { + var streamIDs = {}; + for (var i in session.rpcs) { + streamIDs[session.rpcs[i].streamID] = session.rpcs[i].label; + } + parent.postMessage({ + "streamIDs": streamIDs + }, "*"); + + } + } + + if ("close" in e.data) { + for (var i in session.rpcs) { + try { + session.rpcs[i].close(); + } catch (e) { + errorlog(e); + } + } + } + + if ("style" in e.data) { + try { + const style = document.createElement('style'); + style.textContent = e.data.style; + document.head.append(style); + log(style); } catch (e) { errorlog(e); } } - session.refreshScale(); - beforeScreenShare = null; - } - toggleSettings(forceShow = true); - //enumerateDevices().then(gotDevices2).then(function(){ - //grabVideo(); - //grabAudio(); - // toggleSettings(forceShow=true); - //}); - } -} -var ElectronDesktopCapture = false; -if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { // this enables Screen Capture in Electron - try { - const { desktopCapturer} = require('electron'); // This is definitely Electron specific. Requires Node Integration to be on, which is a potential security hazzard - window.navigator.mediaDevices.getDisplayMedia = () => { - return new Promise(async (resolve, reject) => { - try { - - if (session.autostart){ - var sscid = 0 - if (typeof session.screenshare === "number"){ - sscid = session.screenshare-1; - if (sscid<0){sscid=0;} - } - const sources = await desktopCapturer.getSources({ types: ['screen'] }); - const stream = await window.navigator.mediaDevices.getUserMedia({ - audio: false, - video: { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: sources[sscid].id, - maxFrameRate: 60 - } - } - }); - resolve(stream) - } else { - const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] }); - const selectionElem = document.createElement('div'); - selectionElem.classList = 'desktop-capturer-selection'; - selectionElem.innerHTML = ` -
-
    - ${sources.map(({id, name, thumbnail, display_id, appIcon}) => ` -
  • - -
  • - `).join('')} - -
-
- `; - - document.body.appendChild(selectionElem); - - document.getElementById('cancelscreenshare').addEventListener('click', async () => { - selectionElem.remove(); - reject(err); - }); - document.querySelectorAll('.desktop-capturer-selection__btn').forEach(button => { - button.addEventListener('click', async () => { - try { - const id = button.getAttribute('data-id'); - const source = sources.find(source => source.id === id); - if(!source) { - throw new Error(`Source with id ${id} does not exist`); - } - - const stream = await window.navigator.mediaDevices.getUserMedia({ - audio: false, - video: { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: source.id, - maxFrameRate: 60 - } - } - }); - resolve(stream); - - selectionElem.remove(); - } catch (err) { - errorlog('Error selecting desktop capture source:', err); - reject(err); - } - }) - }); + if ("automixer" in e.data) { + if (e.data.automixer == true) { + session.manual = false; + try { + updateMixer(); + } catch (e) {} + } else if (e.data.automixer == false) { + session.manual = true; } - } catch (err) { - errorlog('Error displaying desktop capture sources:', err); - reject(err); } - }) - } - ElectronDesktopCapture = true; - } catch(e){ - warnlog("couldn't load electron's screen capture; you might need to decrease security permissions a bit."); - } -} -async function grabScreen(quality = 0, audio = true, videoOnEnd = false) { - if (!navigator.mediaDevices.getDisplayMedia) { - if (!(session.cleanOutput)) { - setTimeout(function() { - warnUser("Sorry, your browser is not supported. Please use the desktop versions of Firefox or Chrome instead"); - }, 1); - } - return false; - } - - if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { - if (!ElectronDesktopCapture){ - if (!(session.cleanOutput)) { - warnUser("Your Electron app does not support Screen Capture.

Update your Electron Capture app and then enable Elevated Privileges (right click) to access screen-sharing."); - } - return false; - } - } - - if (quality == 0) { // I'm going to go with default quality in most cases, as I assume Dynamic screenshare is going to want low-fps / high def. - var width = { - ideal: 1920 - }; - var height = { - ideal: 1080 - }; - } else if (quality == 1) { - var width = { - ideal: 1280 - }; - var height = { - ideal: 720 - }; - } else if (quality == 2) { - var width = { - ideal: 640 - }; - var height = { - ideal: 360 - }; - } else if (quality >= 3) { // lowest - var width = { - ideal: 320 - }; - var height = { - ideal: 180 - }; - } - - if (session.width) { - width = { - ideal: session.width - }; - } - if (session.height) { - height = { - ideal: session.height - }; - } - - var constraints = { // this part is a bit annoying. Do I use the same settings? I can add custom setting controls here later - audio: { - echoCancellation: false, // For screen sharing, we want it off by default. - autoGainControl: false - , noiseSuppression: false - } - , video: { - width: width - , height: height - } - //,cursor: {exact: "none"} - }; - - try { - let supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); - if (supportedConstraints.cursor) { - constraints.video.cursor = "never"; - } - } catch(e){ - warnlog("navigator.mediaDevices.getSupportedConstraints() not supported"); - } - - if (session.echoCancellation === true) { - constraints.audio.echoCancellation = true; - } - if (session.autoGainControl === true) { - constraints.audio.autoGainControl = true; - } - if (session.noiseSuppression === true) { - constraints.audio.noiseSuppression = true; - } - if (audio == false) { - constraints.audio = false; - } - - if (session.framerate) { - constraints.video.frameRate = session.framerate; - } else if (session.maxframerate !== false){ // not limiting screen share's fps with quality=2 due to gaming centric nature - constraints.video.frameRate = { - ideal: session.maxframerate, - max: session.maxframerate - }; - } - - return navigator.mediaDevices.getDisplayMedia(constraints).then(function(stream) { - log("adding video tracks 2245"); - - var eleName = "videosource"; - try { - if (session.streamSrc) { - session.streamSrc.getVideoTracks().forEach(function(track) { - //track.stop(); - beforeScreenShare = track; - session.streamSrc.removeTrack(track); - log("stopping video track"); - }); - session.videoElement.srcObject.getVideoTracks().forEach(function(track) { - //track.stop(); - session.videoElement.srcObject.removeTrack(track); - log("stopping video track 2"); - }); - } else { - session.streamSrc = new MediaStream(); - session.videoElement.srcObject = session.streamSrc; - log("CREATE NEW STREAM"); - } - } catch (e) { - warnlog(e); - } - //session.videoElement.srcObject = session.streamSrc; - - // Let's not pass the AUDIO thru the webaudio filter. It's screen share after all. - - try { - stream.getVideoTracks()[0].onended = function() { // if screen share stops, - - session.streamSrc.getVideoTracks().forEach(function(track) { - session.streamSrc.removeTrack(track); - track.stop(); - log("stopping video track 3"); - }); - session.videoElement.srcObject.getVideoTracks().forEach(function(track) { - session.videoElement.srcObject.removeTrack(track); - track.stop(); - log("stopping video track 4"); - }); - - session.screenShareState = false; - pokeIframeAPI("screen-share-ended"); - - getById("screensharebutton").classList.add("float"); - getById("screensharebutton").classList.remove("float2"); - - if (videoOnEnd == true) { - //activatedPreview = false; - - if (beforeScreenShare) { - session.streamSrc.addTrack(beforeScreenShare); - session.videoElement.srcObject.addTrack(beforeScreenShare); - if (beforeScreenShare.kind == "video") { - toggleVideoMute(true); - for (UUID in session.pcs) { + if ("target" in e.data) { + log(e.data); + for (var i in session.rpcs) { + try { + if ("streamID" in session.rpcs[i]) { + if ((session.rpcs[i].streamID == e.data.target) || (e.data.target == "*")) { try { - if ((session.pcs[UUID].guest == true) && (session.roombitrate === 0)) { - log("room rate restriction detected. No videos will be published to other guests"); - } else if (session.pcs[UUID].allowVideo == true) { // allow - var senders = session.pcs[UUID].getSenders(); // for any connected peer, update the video they have if connected with a video already. - var added = false; - senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? - if (sender.track) { - if (sender.track && sender.track.kind == "video") { - sender.replaceTrack(beforeScreenShare); // replace may not be supported by all browsers. eek. - sender.track.enabled = true; - added = true; - } - } - }); - if (added == false) { - session.pcs[UUID].addTrack(beforeScreenShare, stream); - setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker + if ("settings" in e.data) { + for (const property in e.data.settings) { + session.rpcs[i].videoElement[property] = e.data.settings[property]; + } + } + if ("add" in e.data) { + getById("gridlayout").appendChild(session.rpcs[i].videoElement); + + } else if ("remove" in e.data) { + try { + session.rpcs[i].videoElement.parentNode.removeChild(session.rpcs[i].videoElement); + } catch (e) { + try { + session.rpcs[i].videoElement.parentNode.parentNode.removeChild(session.rpcs[i].videoElement.parentNode); + } catch (e) {} } } } catch (e) { errorlog(e); } } - session.refreshScale(); - } - beforeScreenShare = null; - } - - toggleSettings(forceShow = true); - //grabVideo(eleName='videosource', selector="select#videoSource3"); - - - } else { - grabScreen(); - } - }; - } catch (e) { - log("No Video selected; screensharing?"); - } - - stream.getTracks().forEach(function(track) { - addScreenDevices(track); - - session.streamSrc.addTrack(track, stream); // Lets not add the audio to this preview; echo can be annoying - session.videoElement.srcObject.addTrack(track, stream); // I should probably add the remote control to his ; #TODO: - - if (track.kind == "video") { - toggleVideoMute(true); - for (UUID in session.pcs) { - try { - if ((session.pcs[UUID].guest == true) && (session.roombitrate === 0)) { - log("room rate restriction detected. No videos will be published to other guests"); - } else if (session.pcs[UUID].allowVideo == true) { // allow - var senders = session.pcs[UUID].getSenders(); // for any connected peer, update the video they have if connected with a video already. - var added = false; - senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? - if (sender.track) { - if (sender.track && sender.track.kind == "video") { - sender.replaceTrack(track); // replace may not be supported by all browsers. eek. - sender.track.enabled = true; - added = true; - } - } - }); - if (added == false) { - session.pcs[UUID].addTrack(track, stream); - setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker - } } } catch (e) { errorlog(e); } } - session.refreshScale(); - } else { - toggleMute(true); // I might want to move this outside the loop, but whatever - for (UUID in session.pcs) { - try { - if (session.pcs[UUID].allowAudio == true) { - session.pcs[UUID].addTrack(track, stream); // If screen sharing, we will add audio; not replace. - } - } catch (e) { - errorlog(log); - } - } - screenShareAudioTrack = track; } - }); - applyMirror(true, eleName); - return true; - }).catch(function(err) { - errorlog(err); - if ((err.name == "NotAllowedError") || (err.name == "PermissionDeniedError")) { - // User Stopped it. - } else { - if (audio == true) { - setTimeout(function() { - grabScreen(quality, false); - }, 1); - } - if (!(session.cleanOutput)) { - setTimeout(function(e) { - errorlog(e); - }, 1, err); // TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio capture is not supported - } - } - return false; - }); -} - -function toggleRoomSettings(){ - - toggle(getById('roomSettings')); - - - if (document.getElementById("modalBackdrop")){ - getById("modalBackdrop").innerHTML = ''; // Delete modal - getById("modalBackdrop").remove(); - } else { - zindex = 25; - getById('roomSettings').style.zIndex = 25; - var modalTemplate = `
`; - document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end - document.getElementById("modalBackdrop").addEventListener("click", toggleRoomSettings); - document.getElementById('trbSettingInput').value = session.totalRoomBitrate; - document.getElementById('trbSettingInputFeedback').innerHTML = session.totalRoomBitrate; - - } - -} - -function changeTRB(ele){ - session.totalRoomBitrate = parseInt(ele.value); - var msg = {}; - msg.directorSettings={}; - msg.directorSettings.totalRoomBitrate=session.totalRoomBitrate; - session.sendMessage(msg); -} - -function sendMediaDevices(UUID){ - enumerateDevices().then(function(deviceInfos){ - var data = {}; - data.UUID = UUID; - data.mediaDevices = deviceInfos; - session.sendMessage(data, data.UUID); - }); -} - -function changeVideoDevice(index, quality=0){ - enumerateDevices().then(gotDevices2).then(function() { - activatedPreview=false; - document.getElementById("videoSource3").selectedIndex = index+""; - grabVideo(quality, "videosource", "#videoSource3"); - }); -} - -function changeAudioDevice(index){ - enumerateDevices().then(gotDevices2).then(function() { - activatedPreview=false; - var audioSelect = document.getElementById("audioSource3").querySelectorAll("input"); - for (var i = 0; i < audioSelect.length; i++) { - audioSelect[i].checked = false; - } - audioSelect[index-1].checked = true; - grabAudio("videosource", "#audioSource3"); - }); -} - -function changeVideoDeviceById(deviceID, UUID){ - enumerateDevices().then(gotDevices2).then(function() { - var opts = document.getElementById("videoSource3").options; - var index = false - for (var opt, j = 0; opt = opts[j]; j++) { - if (opt.value == deviceID) { - index = j; - break; - } - } - var allow = false - if (index!==false){ - window.focus(); - allow = confirm("Allow the director to change your video device to :"+opts[index].text+" ?"); - } - if (allow){ - document.getElementById("videoSource3").selectedIndex = j; - activatedPreview=false; - grabVideo(0, "videosource", "#videoSource3"); - setTimeout(function(uuid){ - var data = {}; - data.UUID = uuid; - data.videoOptions = listVideoSettingsPrep(); - sendMediaDevices(data.UUID); - session.sendMessage(data, data.UUID); - },1000, UUID); - } - }); -} - -function changeAudioDeviceById(deviceID, UUID){ - var allow = false; - window.focus(); - allow = confirm("Allow the director to change your audio mic source?"); - if (allow){ - enumerateDevices().then(gotDevices2).then(function() { - var audioSelect = document.getElementById("audioSource3").querySelectorAll("input"); - for (var i = 0; i < audioSelect.length; i++) { - if (audioSelect[i].value == deviceID){ - audioSelect[i].checked=true; - } else { - audioSelect[i].checked = false; - } - } - activatedPreview=false; - grabAudio("videosource", "#audioSource3"); - setTimeout(function(uuid){ - var data = {}; - data.UUID = uuid; - data.audioOptions = listAudioSettingsPrep(); - sendMediaDevices(data.UUID); - session.sendMessage(data, data.UUID); - },1000, UUID); - }); - } -} - -function changeAudioOutputDeviceById(deviceID, UUID){ - errorlog(deviceID); - enumerateDevices().then(gotDevices2).then(function() { - if (!document.getElementById("outputSource3")){return;} - var opts = document.getElementById("outputSource3").options; - var index = false - for (var opt, j = 0; opt = opts[j]; j++) { - if (opt.value == deviceID) { - index = j; - break; - } - } - var allow = false - if (index!==false){ - window.focus(); - allow = confirm("Allow the director to change your audio's speaker to :"+opts[index].text+" ?"); - } - if (allow){ - document.getElementById("outputSource3").selectedIndex = j; - session.sink = document.getElementById("outputSource3").options[document.getElementById("outputSource3").selectedIndex].value; - resetupAudioOut(); - setTimeout(function(uuid){ - var data = {}; - data.UUID = uuid; - data.videoOptions = listVideoSettingsPrep(); - sendMediaDevices(data.UUID); - session.sendMessage(data, data.UUID); - },1000, UUID); - } - }); -} - - - -var getUserMediaRequestID = 0; -var grabVideoUserMediaTimeout = null; -var grabVideoTimer = null; - -async function grabVideo(quality = 0, eleName = 'previewWebcam', selector = "select#videoSourceSelect") { - if (activatedPreview == true) { - log("activated preview return 2"); - return; - } - activatedPreview = true; - log("Grabbing video: " + quality); - if (grabVideoTimer) { - clearTimeout(grabVideoTimer); - } - log("element:" + eleName); - - var wasDisabled = true; - try { - if (session.streamSrc) { - - if (session.canvasSource){ - session.canvasSource.srcObject.getTracks().forEach(function(trk) { - session.canvasSource.srcObject.removeTrack(trk); - wasDisabled=false; - }); - } - - if (session.videoElement.srcObject) { - session.videoElement.srcObject.getVideoTracks().forEach(function(track) { - session.videoElement.srcObject.removeTrack(track); - session.videoElement.load(); - wasDisabled=false; - }); - } - session.streamSrc.getVideoTracks().forEach(function(track) { - session.streamSrc.removeTrack(track); - track.stop(); - log("track removed"); - wasDisabled=false; - }); - - } else { - //log(session.videoElement.srcObject.getTracks()); - session.streamSrc = new MediaStream(); - session.videoElement.srcObject = session.streamSrc; - log("CREATE NEW STREAM"); - } - } catch (e) { - errorlog(e); - } - - session.videoElement.controls = false; - - log("selector: " + selector); - var videoSelect = document.querySelector(selector); // document.querySelector("videoSource3").value == "ZZZ" - log(videoSelect); - var mirror = false; - - if (!videoSelect || videoSelect.value == "ZZZ") { // if there is no video, or if manually set to audio ready, then do this step. - warnlog("ZZZ SET - so no VIDEO"); - if ((eleName == "previewWebcam") && document.getElementById("previewWebcam")){ - if (session.autostart) { - publishWebcam(); // no need to mirror as there is no video... - return; - } else { - log("4462"); - updateStats(); - var gowebcam = getById("gowebcam"); - if (gowebcam) { - gowebcam.disabled = false; - gowebcam.dataset.ready = "true"; - gowebcam.innerHTML = "START"; - miniTranslate(gowebcam, "start"); - } - } - } else { // If they disabled the video but not in preview mode; but actualy live. We will want to remove the stream from the publishing - // we don't want to do this otherwise, as we are "replacing" the track in other cases. - // this does cause a problem, as previous bitrate settings & resolutions might not be applied if switched back.... must test - for (UUID in session.pcs) { - var senders = session.pcs[UUID].getSenders(); // for any connected peer, update the video they have if connected with a video already. - senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? - if (sender.track && sender.track.kind == "video") { - sender.track.enabled = false; - getById("mutevideobutton").classList.add("advanced"); // hide the mute button, so they can't unmute while no video. - //session.pcs[UUID].removeTrack(sender); // replace may not be supported by all browsers. eek. - errorlog("DELETED SENDER"); - } - }); - - } - var msg = {}; - msg.videoMuted = true; - session.sendMessage(msg); - } - // end - } else { - var sq = 0; - if (session.quality === false) { - sq = session.quality_wb; - } else if (session.quality > 2) { // 1080, 720, and 360p - sq = 2; // hacking my own code. TODO: ugly, so I need to revisit this. - } else { - sq = session.quality; - } - - if (session.director && (quality !== false)){ // URL-based quality won't matter if DIRECTOR; - // quality = quality; - } else if ((quality === false) || (quality < sq)) { - quality = sq; // override the user's setting - } - - - if ((iOS) || (iPad)) { // iOS will not work correctly at 1080p; likely a h264 codec issue. - if (quality == 0) { - quality = 1; - } - } - - var constraints = { - audio: false, - video: getUserMediaVideoParams(quality, iOS) }; + } - log("Quality selected:" + quality); - var _, sUsrAg = navigator.userAgent; + if (session.midiHotkeys || session.midiOut!==false) { + + var script = document.createElement('script'); + script.onload = function() { + WebMidi.enable(function(err) { // hotkeys - - if ((iOS) || (iPad)) { - constraints.video.deviceId = { - exact: videoSelect.value - }; // iPhone 6s compatible ? Needs to be exact for iPhone 6s - - } else if (sUsrAg.indexOf("Firefox") > -1) { - constraints.video.deviceId = { - exact: videoSelect.value - }; // Firefox is a dick. Needs it to be exact. - - } else if (videoSelect.options[videoSelect.selectedIndex].text.includes("NDI Video")) { // NDI does not like "EXACT" - constraints.video.deviceId = videoSelect.value; - - } else { - constraints.video.deviceId = { - exact: videoSelect.value - }; // Default. Should work for Logitech, etc. - } - - if (session.width) { - constraints.video.width = { - exact: session.width - }; // manually specified - so must be exact - } - if (session.height) { - constraints.video.height = { - exact: session.height - }; - } - if (session.framerate) { - constraints.video.frameRate = { - exact: session.framerate - }; - } else if (session.maxframerate != false){ - constraints.video.frameRate = { - ideal: session.maxframerate, - max: session.maxframerate - }; - } - if (session.ptz){ - if (constraints.video && constraints.video!==true){ - if (getChromeVersion() && getChromeVersion()>80){ - constraints.video.pan=true; - constraints.video.tilt=true; - constraints.video.zoom=true; + if (err) { + errorlog(err); } - } - } - var obscam = false; - log(videoSelect.options[videoSelect.selectedIndex].text); - if (videoSelect.options[videoSelect.selectedIndex].text.startsWith("OBS-Camera")) { // OBS Virtualcam - mirror = true; - obscam = true; - } else if (videoSelect.options[videoSelect.selectedIndex].text.startsWith("OBS Virtual Camera")) { // OBS Virtualcam - mirror = true; - obscam = true; - } else if (videoSelect.options[videoSelect.selectedIndex].text.includes(" back")) { // Android - mirror = true; - } else if (videoSelect.options[videoSelect.selectedIndex].text.includes(" rear")) { // Android - mirror = true; - } else if (videoSelect.options[videoSelect.selectedIndex].text.includes("NDI Video")) { // NDI Virtualcam - mirror = true; - } else if (videoSelect.options[videoSelect.selectedIndex].text.startsWith("Back Camera")) { // iPhone and iOS - mirror = true; - } else { - mirror = false; - } - session.mirrorExclude = mirror; - log(constraints); - clearTimeout(grabVideoUserMediaTimeout); - getUserMediaRequestID += 1; - grabVideoUserMediaTimeout = setTimeout(function(gumID) { - navigator.mediaDevices.getUserMedia(constraints).then(function(stream) { + WebMidi.addListener("connected", function(e) { + log(e); + }); - if (getUserMediaRequestID !== gumID) { - errorlog("GET USER MEDIA CALL HAS EXPIRED"); - return; - } - log("adding video tracks 2412"); - stream.getVideoTracks().forEach(function(track) { - if (!session.streamSrc) { - session.streamSrc = new MediaStream(); - } - if (!session.videoElement) { - if (document.getElementById("previewWebcam")) { - session.videoElement = document.getElementById("previewWebcam"); - } else if (document.getElementById("videosource")) { - session.videoElement = document.getElementById("videosource"); - } + WebMidi.addListener("disconnected", function(e) { + log(e); + }); + + console.log(WebMidi.inputs); + + if (session.midiOut===true){ + for (var i = 0; i < WebMidi.inputs.length; i++) { + var input = WebMidi.inputs[i]; - } - - if (session.effects) { - track = applyEffects(track,stream); - } else { - log(session.videoElement); - session.streamSrc.addTrack(track, stream); // add video track to the preview video - session.videoElement.srcObject.addTrack(track, stream); // add video track to the preview video - } - - toggleVideoMute(true); - for (UUID in session.pcs) { - try { - if (((iOS) || (iPad)) && (session.pcs[UUID].guest == true)) { - warnlog("iOS and GUest detected"); - } else if ((session.pcs[UUID].guest == true) && (session.roombitrate === 0)) { - log("room rate restriction detected. No videos will be published to other guests"); - } else if (session.pcs[UUID].allowVideo == true) { // allow - - // for any connected peer, update the video they have if connected with a video already. - var added = false; - session.pcs[UUID].getSenders().forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? - - if (sender.track && sender.track.kind == "video") { - sender.replaceTrack(track); // replace may not be supported by all browsers. eek. - sender.track.enabled = true; - added = true; - } - - }); - if (added == false) { - session.pcs[UUID].addTrack(track, stream); // can't replace, so adding - setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker + input.addListener("midimessage", "all", function(e) { + log(e); + var msg = {}; + msg.midi = {}; + msg.midi.d = e.data; + msg.midi.s = e.timestamp; + msg.midi.t = e.type; + + for (var UUID in session.pcs){ + if (session.pcs[UUID].allowMIDI){ + session.sendMessage(msg, UUID); } } - - } catch (e) { - errorlog(e); - } + }); } - - if (wasDisabled && !session.videoMuted){ - var msg = {}; - msg.videoMuted = session.videoMuted; - session.sendMessage(msg); - } - - session.refreshScale(); - }); - - applyMirror(mirror, eleName); - - if ((eleName == "previewWebcam") && document.getElementById("previewWebcam")){ - if (session.autostart) { - publishWebcam(); - } else { - log("4620"); - if (document.getElementById("gear_webcam")) { - updateStats(obscam); - } - var gowebcam = getById("gowebcam"); - if (gowebcam) { - gowebcam.disabled = false; - gowebcam.dataset.ready = "true"; - gowebcam.innerHTML = "START"; - miniTranslate(gowebcam, "start"); - } - } - } else if (getById("gear_webcam3").style.display === "inline-block") { - updateStats(obscam); + } else if (session.midiOut==parseInt(session.midiOut)){ + try{ + var input = WebMidi.inputs[parseInt(session.midiOut)-1]; + input.addListener("midimessage", "all", function(e) { + log(e); + var msg = {}; + msg.midi = {}; + msg.midi.d = e.data; + msg.midi.s = e.timestamp; + msg.midi.t = e.type; + + for (var UUID in session.pcs){ + if (session.pcs[UUID].allowMIDI){ + session.sendMessage(msg, UUID); + } + } + }); + } catch(e){errorlog(e);}; } - - // Once crbug.com/711524 is fixed, we won't need to wait anymore. This is - // currently needed because capabilities can only be retrieved after the - // device starts streaming. This happens after and asynchronously w.r.t. - // getUserMedia() returns. - if (grabVideoTimer) { - clearTimeout(grabVideoTimer); - if ((eleName == "previewWebcam") && document.getElementById("previewWebcam")){ - session.videoElement.controls = true; - } - } - if (getById("popupSelector_constraints_video")) { - getById("popupSelector_constraints_video").innerHTML = ""; - } - if (getById("popupSelector_constraints_audio")) { - getById("popupSelector_constraints_audio").innerHTML = ""; - } - if (getById("popupSelector_constraints_loading")) { - getById("popupSelector_constraints_loading").style.display = ""; - } - - grabVideoTimer = setTimeout(function() { - if (getById("popupSelector_constraints_loading")) { - getById("popupSelector_constraints_loading").style.display = "none"; - } - if ((eleName == "previewWebcam") && document.getElementById("previewWebcam")){ - session.videoElement.controls = true; - } else { - updateConstraintSliders(); - } - - dragElement(session.videoElement); - }, 1000); // focus - - makeImages(true); - - log("DONE - found stream"); - }).catch(function(e) { - activatedPreview = false; - warnlog(e); - if (e.name === "OverconstrainedError") { - warnlog(e.message); - log("Resolution or framerate didn't work"); - } else if (e.name === "NotReadableError") { - if (quality <= 10) { - grabVideo(quality + 1, eleName, selector); - } else { - if (!(session.cleanOutput)) { - if (iOS) { - warnUser("An error occured. Closing existing tabs in Safari may solve this issue."); - } else { - warnUser("Error: Could not start video source.\n\nTypically this means the Camera is already be in use elsewhere. Most webcams can only be accessed by one program at a time.\n\nTry a different camera or perhaps try re-plugging in the device."); + + for (var i = 0; i < WebMidi.inputs.length; i++) { + var input = WebMidi.inputs[i]; + input.addListener('noteon', "all", function(e) { + log(e); + if (session.midiHotkeys==1){ + log(e); + var note = e.note.name + e.note.octave; + if (note == "G3") { // open and close the chat window + toggleChat(); + } else if (note == "A3") { // mute your audio output + toggleMute(); + } else if (note == "B3") { // mute your video output + toggleVideoMute(); + } else if (note == "C4") { // enable / disable screenshare + toggleScreenShare(); + } else if (note == "D4") { // completely kill your connection/session + hangup(); + } else if (note == "E4") { // raise your hand; director sees this + raisehand(); + } else if (note == "F4") { // start/stop local recording + recordLocalVideoToggle(); + } else if (note == "G4") { // Director Enables their Audio output + press2talk(true); + } else if (note == "A4") { // Director cut's their audio/video output + hangup2(); + } + } else if (session.midiHotkeys==2){ + log(e); + var note = e.note.name + e.note.octave; + if (note == "G1") { // open and close the chat window + toggleChat(); + } else if (note == "A1") { // mute your audio output + toggleMute(); + } else if (note == "B1") { // mute your video output + toggleVideoMute(); + } else if (note == "C2") { // enable / disable screenshare + toggleScreenShare(); + } else if (note == "D2") { // completely kill your connection/session + hangup(); + } else if (note == "E2") { // raise your hand; director sees this + raisehand(); + } else if (note == "F2") { // start/stop local recording + recordLocalVideoToggle(); + } else if (note == "G2") { // Director Enables their Audio output + press2talk(true); + } else if (note == "A2") { // Director cut's their audio/video output + hangup2(); + } + } else if (session.midiHotkeys==3){ + log(e); + var note = e.note.name + e.note.octave; + var velocity = e.velocity; + if (note == "C1"){ + if (velocity == "0") { // open and close the chat window + toggleChat(); + } else if (note == "1") { // mute your audio output + toggleMute(); + } else if (note == "2") { // mute your video output + toggleVideoMute(); + } else if (note == "3") { // enable / disable screenshare + toggleScreenShare(); + } else if (note == "4") { // completely kill your connection/session + hangup(); + } else if (note == "5") { // raise your hand; director sees this + raisehand(); + } else if (note == "6") { // start/stop local recording + recordLocalVideoToggle(); + } else if (note == "7") { // Director Enables their Audio output + press2talk(true); + } else if (note == "8") { // Director cut's their audio/video output + hangup2(); + } } } - activatedPreview = true; - if (getById('gowebcam')) { - getById('gowebcam').innerHTML = "Problem with Camera"; - } - - } - return; - } else if (e.name === "NavigatorUserMediaError") { - if (getById('gowebcam')) { - getById('gowebcam').innerHTML = "Problem with Camera"; - } - if (!(session.cleanOutput)) { - warnUser("Unknown error: 'NavigatorUserMediaError'"); - } - return; - } else if (e.name === "timedOut") { - activatedPreview = true; - if (getById('gowebcam')) { - getById('gowebcam').innerHTML = "Problem with Camera"; - } - if (!(session.cleanOutput)) { - warnUser(e.message); - } - return; - } else { - errorlog("An unknown camera error occured"); - } - - if (quality <= 10) { - grabVideo(quality + 1, eleName, selector); - } else { - errorlog("********Camera failed to work"); - activatedPreview = true; - if (getById('gowebcam')) { - getById('gowebcam').innerHTML = "Problem with Camera"; - } - if (!(session.cleanOutput)) { - if (session.width || session.height || session.framerate) { - warnUser(" Camera failed to load.\n\nPlease ensure your camera supports the resolution and framerate that has been manually specified. Perhaps use &quality=0 instead."); - } else { - warnUser(" Camera failed to load.\n\nPlease make sure it is not already in use by another application.\n\nPlease make sure you have accepted the camera permissions."); - } - } - } - }); - }, 100, getUserMediaRequestID); - } -} - - -async function grabAudio(eleName = "previewWebcam", selector = "#audioSource", trackid = null, override = false) { // trackid is the excluded track - if (activatedPreview == true) { - log("activated preview return 2"); - return; - } - activatedPreview = true; - warnlog("GRABBING AUDIO"); - log("TRACK EXCLUDED:" + trackid); - - - try { - if (session.videoElement.srcObject) { - var audioSelect = document.querySelector(selector).querySelectorAll("input"); - var audioExcludeList = []; - for (var i = 0; i < audioSelect.length; i++) { - try { - if ("screen" == audioSelect[i].dataset.type) { // skip already excluded ---------- !!!!!! DOES THIS MAKE SENSE? TODO: CHECK - if (audioSelect[i].checked) { - audioExcludeList.push(audioSelect[i]); - } - } - } catch (e) { - errorlog(e); - } - } - - session.videoElement.srcObject.getAudioTracks().forEach(function(track) { - for (var i = 0; i < audioExcludeList.length; i++) { - try { - if (audioExcludeList[i].label == track.label) { - warnlog("DONE"); - return; - } - } catch (e) {} - } - if (trackid && (track.id == trackid)) { - warnlog("SKIPPED EXCLUDED TRACK?"); - return; - } - session.videoElement.srcObject.removeTrack(track); - track.stop(); - }); - - session.streamSrc.getAudioTracks().forEach(function(track) { - for (var i = 0; i < audioExcludeList.length; i++) { - try { - if (audioExcludeList[i].label == track.label) { - warnlog("EXCLUDING TRACK; PROBABLY SCREEN SHARE"); - return; - } - } catch (e) {} - } - if (trackid && (track.id == trackid)) { - warnlog("SKIPPED EXCLUDED TRACK?"); - return; - } - session.streamSrc.removeTrack(track); - track.stop(); - }); - - - } else { // if no stream exists - session.streamSrc = new MediaStream(); - session.videoElement.srcObject = session.streamSrc; - log("CREATE NEW SOURCE FOR AUDIO"); - } - } catch (e) { - errorlog(e); - } - - var streams = await getAudioOnly(selector, trackid, override); // Get audio streams - warnlog(streams); - try { - for (var i = 0; i < streams.length; i++) { - streams[i].getAudioTracks().forEach(function(track) { - session.streamSrc.addTrack(track, streams[i]); // add video track to the preview video - }); - } - - session.videoElement.srcObject = outboundAudioPipeline(session.streamSrc); - - toggleMute(true); - if (session.videoElement.srcObject.getAudioTracks()) { - - for (UUID in session.pcs) { - if (session.pcs[UUID].allowAudio == true) { - var tracks = session.videoElement.srcObject.getAudioTracks(); - - session.pcs[UUID].getSenders().forEach((sender) => { - var good = false; - if (sender.track && sender.track.id && (sender.track.kind == "audio")) { - tracks.forEach(function(track) { - if (track.id == sender.track.id) { - good = true; - } - }); - } else { // video or something else; ignore it. - return; - } - if (good) { - return; - } - sender.track.enabled = false; - //session.pcs[UUID].removeTrack(sender); // Apparently removeTrack causes renogiation; also kills send/recv. }); - - if (tracks.length) { - tracks.forEach(function(track) { - var matched = false; - session.pcs[UUID].getSenders().forEach((sender) => { - if (sender.track && sender.track.id && (sender.track.kind !== "video")) { - warnlog(sender.track.id + " " + track.id); - if (sender.track.id == track.id) { - warnlog("MATCHED 1"); - matched = true; + input.addListener('controlchange', "all", function(e) { + + if (session.midiHotkeys==4){ + /* channel: 1 + controller: {number: 110, name: undefined} + data: Uint8Array(3) [176, 110, 3] + target: Input {_userHandlers: {โ€ฆ}, _midiInput: MIDIInput, โ€ฆ} + timestamp: 98235.34000001382 + type: "controlchange" + value: 3 */ + log(e); + if (e.channel!==1){ + errorlog("VDO.Ninja is currently configured for use on channel 1 for MIDI hotkeys"); + return; + } // channel 1? + + var command = e.controller.number; + var value = e.value; + + if (command == 110){ + if (value == 0) { // open and close the chat window + toggleChat(); + } else if (value == 1) { // mute your audio output + toggleMute(); + } else if (value == 2) { // mute your video output + toggleVideoMute(); + } else if (value == 3) { // enable / disable screenshare + toggleScreenShare(); + } else if (value == 4) { // completely kill your connection/session + hangup(); + } else if (value == 5) { // raise your hand; director sees this + raisehand(); + } else if (value == 6) { // start/stop local recording + recordLocalVideoToggle(); + } else if (value == 7) { // Director Enables their Audio output + press2talk(true); + } else if (value == 8) { // Director cut's their audio/video output + hangup2(); + } + } else if (command > 110){ + var guestslot = command-111; + if (value == 0) { + var elements = document.querySelectorAll('[data-action-type="forward"][data--u-u-i-d]'); + if (elements[guestslot]) { + directMigrate(elements[guestslot], true); + } + } else if (value == 1) { + var elements = document.querySelectorAll('[data-action-type="addToScene"][data--u-u-i-d]'); + if (elements[guestslot]) { + directEnable(elements[guestslot], true); + } + } else if (value == 2) { + var elements = document.querySelectorAll('[data-action-type="mute-scene"][data--u-u-i-d]'); + if (elements[guestslot]) { + directMute(elements[guestslot], true); + } + } else if (value == 3) { + var elements = document.querySelectorAll('[data-action-type="mute-guest"][data--u-u-i-d]'); + if (elements[guestslot]) { + remoteMute(elements[guestslot], true); + } + } else if (value == 4) { + var elements = document.querySelectorAll('[data-action-type="hangup"][data--u-u-i-d]'); + if (elements[guestslot]) { + directHangup(elements[guestslot], true); + } + } else if (value == 5) { + var elements = document.querySelectorAll('[data-action-type="solo-chat"][data--u-u-i-d]'); + if (elements[guestslot]) { + session.toggleSoloChat(elements[guestslot].dataset.UUID); + } + } else if (value == 6) { + var elements = document.querySelectorAll('[data-action-type="toggle-remote-speaker"][data--u-u-i-d]'); + if (elements[guestslot]) { + remoteSpeakerMute(elements[guestslot]); + } + } else if (value == 7) { + var elements = document.querySelectorAll('[data-action-type="toggle-remote-display"][data--u-u-i-d]'); + if (elements[guestslot]) { + remoteDisplayMute(elements[guestslot]); + } + } else if ((value => 27)) { + var elements = document.querySelectorAll('[data-action-type="volume"][data--u-u-i-d]'); + if (elements[guestslot]) { + elements[guestslot].value = parseInt(value-27); + remoteVolume(elements[guestslot]); } } - }); - if (matched) { - return; } - var added = false; - session.pcs[UUID].getSenders().forEach((sender) => { - if (added) { - return; - } - if (sender.track && (sender.track.enabled == false)) { - sender.replaceTrack(track); - sender.track.enabled = true; - added = true; - warnlog("ADDED 2"); - } - }); - if (added) { - return; - } - var sender = session.pcs[UUID].addTrack(track, session.videoElement.srcObject); - }); - } else { - session.pcs[UUID].getSenders().forEach((sender) => { - if (sender.track && sender.track.kind == "audio") { - sender.track.enabled = false; // (trying this instead) - //session.pcs[UUID].removeTrack(sender); // Apparently removeTrack causes renogiation; also kills send/recv. - } - }); - } - + } + }); } - } - } - } catch (e) { - errorlog(e); - } - var gowebcam = getById("gowebcam"); - if (gowebcam) { - gowebcam.disabled = false; - gowebcam.dataset.ready = "true"; - gowebcam.innerHTML = "START"; - miniTranslate(gowebcam, "start"); - } -} - - -// WEBCAM -session.publishDirector = async function(clean, vdevice=false, adevice=true){ // stream is used to generated an SDP - log("DIRECTOR STREAM SETUP"); - - if (getById("press2talk").dataset.enabled){log("already enabled");return;} - getById("press2talk").dataset.enabled = 1; - - if (session.streamSrc){ - //if (!session.streamSrc){ - // session.streamSrc = new MediaStream(); - //} - if (document.getElementById("videosource")){ - var v = document.getElementById("videosource"); - v.muted = true; - v.autoplay = true; - v.controls = false; - v.setAttribute("playsinline",""); - session.videoElement = v; - } else if (session.videoElement){ - var v = session.videoElement; - v.muted = true; - v.autoplay = true; - v.controls = false; - v.setAttribute("playsinline",""); - getById("miniPerformer").appendChild(v); - } else { - var v = document.createElement("video"); - session.videoElement = v; - v.muted = true; - v.autoplay = true; - v.controls = false; - v.setAttribute("playsinline",""); - getById("miniPerformer").appendChild(v); - } - - if (session.streamID){ - session.videoElement.dataset.sid = session.streamID; - } - - v.title = "This is the mini-preview of the Director's audio and video output. The director cannot be muted by guest and does not show up in scenes."; - getById("press2talk").innerHTML = ""; - getById("press2talk").outerHTML = ""; - - session.muted = false; - toggleMute(true); - getById("screensharebutton").classList.remove("advanced"); - getById("hangupbutton2").classList.remove("advanced"); - - - v.muted = true; - v.autoplay = true; - v.controls = false; - v.setAttribute("playsinline",""); - v.srcObject = session.streamSrc; // blank, no worries. - - if (session.screenShareState) { - log("can't refresh a screenshare"); - getById("screensharebutton").classList.add("float2"); - getById("screensharebutton").classList.remove("float"); - session.screenShareState = false; - } - - - activatedPreview = false; - await grabAudio("videosource", "#audioSource3"); - - - enumerateDevices().then(gotDevices2).then(function() { - activatedPreview = false; - grabVideo(session.quality, "videosource", "select#videoSource3"); - }); - - toggleSettings(true); - - var msg = {}; - msg.videoMuted = session.videoMuted; - session.sendMessage(msg); - - return; - } - - - var title = "Director"; - var v = document.createElement("video"); - session.videoElement = v; - if (session.streamID){ - session.videoElement.dataset.sid = session.streamID; - } - v.id = "videosource"; // could be set to UUID in the future - v.muted = true; - v.autoplay = true; - v.controls = false; - v.setAttribute("playsinline",""); - - session.streamSrc = new MediaStream(); - v.srcObject = session.streamSrc; // blank, no worries. we dont need outbound. - - //createDirectorCam(v,clean); - - var quality = 1; - var framerate = 30; - - - if (session.quality!==false){ - quality = parseInt(session.quality) || 0; - if (quality>2){quality=2;} else if (quality<0){quality = 0;} - } - - if (session.showDirector){ - if (quality<2){ - framerate = 60; - } - } - - if (session.framerate!==false){ - framerate = parseInt(session.framerate) || 30; - } - - if (session.maxframerate){ - if (framerate > session.maxframerate){ - framerate = session.maxframerate || framerate; - } - } - - if (vdevice){ - if (vdevice===true){ - vdevice = {}; - } - if (quality===0){ - vdevice.width = {ideal:1920}; //{deviceId: {exact: deviceInfo.deviceId}}; - vdevice.height = {ideal:1080}; - vdevice.framerate = {ideal:framerate}; - } else if (quality===1){ - vdevice.width = {ideal:1280}; //{deviceId: {exact: deviceInfo.deviceId}}; - vdevice.height = {ideal:720}; - vdevice.framerate = {ideal:framerate}; - } else if (quality===2){ - vdevice.width = {ideal:640}; //{deviceId: {exact: deviceInfo.deviceId}}; - vdevice.height = {ideal:360}; - vdevice.framerate = {ideal:framerate}; - } - if (session.framerate){ - vdevice.framerate.ideal = parseInt(session.framerate) || 30; - } - if (session.maxframerate){ - vdevice.framerate.max = parseInt(session.maxframerate) || 60; - } - if (session.width){ - vdevice.width = {exact: session.width}; //{deviceId: {exact: deviceInfo.deviceId}}; - } - if (session.height){ - vdevice.height = {exact: session.height}; //{deviceId: {exact: deviceInfo.deviceId}}; - } - } - - var constraints = {audio: adevice, video: vdevice}; - - if (session.audioInputChannels){ - if (constraints.audio === true){ - constraints.audio = {}; - constraints.audio.channelCount = session.audioInputChannels; - } else if (constraints.audio){ - constraints.audio.channelCount = session.audioInputChannels; - } - } - - //if (session.echoCancellation===false){ - if (constraints.audio === true){ - constraints.audio = {}; - } - if (constraints.audio){ - if (session.echoCancellation===false || session.autoGainControl===false || session.noiseSuppression===false){ - if (session.echoCancellation===false){ - constraints.audio.echoCancellation=false; - } else { - constraints.audio.echoCancellation=true; - } - if (session.autoGainControl===false){ - constraints.audio.autoGainControl=false; - } else { - constraints.audio.autoGainControl=true; - } - if (session.noiseSuppression===false){ - constraints.audio.noiseSuppression=false; - } else { - constraints.audio.noiseSuppression=true; - } - } - } - - - try { - getById("webcamquality3").elements.namedItem("resolution").value = quality; - getById("gear_webcam3").style.display = "inline-block"; - getById("webcamquality3").onchange = function(event) { - if (parseInt(getById("webcamquality3").elements.namedItem("resolution").value) == 2) { - if (session.maxframerate===false){ - session.maxframerate = 30; - session.maxframerate_q2 = true; - } - } else if (session.maxframerate_q2){ - session.maxframerate = false; - session.maxframerate_q2 = false; - } - activatedPreview = false; - session.quality_wb = parseInt(getById("webcamquality3").elements.namedItem("resolution").value); - - grabVideo(session.quality_wb, "videosource", "select#videoSource3"); + }); }; + script.src = "./thirdparty/webmidi.js"; // dynamically load this only if its needed. Keeps loading time down. + document.head.appendChild(script); + } else if (session.midiIn){ + var script = document.createElement('script'); + script.src = "./thirdparty/webmidi.js"; // dynamically load this only if its needed. Keeps loading time down. + script.onload = function() { + WebMidi.enable(function(err) { // hotkeys + if (err) { + errorlog(err); + } + console.log(WebMidi.outputs); + + }); + } + document.head.appendChild(script); + } + + + + + var languages = getById('languagesList').querySelectorAll('li a'); + var timezones = []; + + languages.forEach(language => { + if (language.dataset.tz) { + var languageTimezones = language.dataset.tz.split(';'); // each link can have multiple timezones separated by ; + languageTimezones.forEach(element => { + timezones.push(element); + }); + } + }); + + var currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + + if (timezones.includes(currentTimezone)) { + var el = getById('languagesList').querySelector("li a[data-tz*='" + currentTimezone +"']"); // select language li + el.parentElement.removeChild(el); // remove it + getById('languagesList').insertBefore(el, getById('languagesList').querySelector('li:nth-child(2)')); // insert it after English + } + + var visAudioTimeout = null + document.addEventListener("visibilitychange", function() { + //log("hidden : " +document.hidden); + log("vis : "+document.visibilityState); + if ((iOS) || (iPad)) { // fixes a bug on iOS devices. Not need with other devices? + clearTimeout(visAudioTimeout); + if (document.visibilityState === 'visible') { + visAudioTimeout = setTimeout(function() { + resetupAudioOut(); + activatedPreview=false; + grabAudio("videosource", "#audioSource3"); + }, 500); + } + } + }); + + // Warns user about network going down + window.addEventListener("offline", function (e) { + if ((session.view) && (session.permaid === false)) { + log("VDO.Ninja has no network connectivity and can't work properly." ); + } else if (session.scene !== false) { + log("VDO.Ninja has no network connectivity and can't work properly." ); + } else if (!session.cleanOutput) { + warnUser("Network connection lost."); + } else { + log("VDO.Ninja has no network connectivity and can't work properly."); + } + }); + + window.addEventListener("online", function (e) { + closeModal(); + }); + + function updateConnectionStatus() { + warnlog("Connection type changed from " + session.stats.network_type + " to " + Connection.effectiveType); + session.stats.network_type = Connection.effectiveType + " / " + Connection.type; + session.ping(); + } + try { + var Connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; + session.stats.network_type = Connection.effectiveType + " / " + Connection.type; + Connection.addEventListener('change', updateConnectionStatus); } catch (e) {} - - log("constraint"); - navigator.mediaDevices.getUserMedia(constraints).then(function(stream){ // very simple. - session.streamSrc = stream; - v.srcObject = outboundAudioPipeline(session.streamSrc); // not blank, so now we worry - - for (UUID in session.pcs){ - session.initialPublish(UUID); // Start publishing! - } - enumerateDevices().then(gotDevices2).then(function(){}); - createDirectorCam(v, clean); - }); - - changeAudioOutputDevice(v); - v.onpause = (event) => { // prevent things from pausing; human or other - if (!((event.ctrlKey) || (event.metaKey) )){ - log("Video paused; auto playing"); - event.currentTarget.play().then(_ => { - log("playing"); - }).catch(warnlog); - } - }; - - v.addEventListener('click', function(e) { // show stats of video if double clicked - log("click"); - try { - if ((e.ctrlKey)||(e.metaKey)){ - e.preventDefault(); - - //////////////////////// - - var [menu, innerMenu] = statsMenuCreator(); - - ////////////////////////////////// - - menu.interval = setInterval(printMyStats,3000, innerMenu); - printMyStats(innerMenu); - e.stopPropagation(); - - return false; - } - } catch(e){errorlog(e);} - }); - - if (session.directorEnabledPPT){ - return; - } - - if (session.videoMutedFlag){ - session.videoMuted = true; - toggleVideoMute(true); - } - - session.title=title; - session.directorEnabledPPT = true; - - - if (session.seeding){ - return; - } - - session.seeding=true; - session.seedStream(); - -}; + setInterval(function() { + checkConnection(); + }, 5000); -function statsMenuCreator(){ - - if (getById("menuStatsBox")){ - clearInterval(getById("menuStatsBox").interval); - getById("menuStatsBox").remove(); - } - - var menu = document.createElement("div"); - menu.id = "menuStatsBox"; - menu.className = "debugStats remotestats"; - getById('main').appendChild(menu); - - menu.style.left = parseInt(Math.random()*10)+15+"px" - menu.style.top = parseInt(Math.random()*10)+"px" - - menu.innerHTML="

Statistics

"; - var menuCloseBtn = document.createElement("button"); - menuCloseBtn.className="close"; - menuCloseBtn.innerHTML="ร—"; - menu.appendChild(menuCloseBtn); - - var innerMenu = document.createElement("div"); - menu.appendChild(innerMenu); - - menuCloseBtn.addEventListener('click', function(eve) { - clearInterval(menu.interval); - eve.currentTarget.parentNode.remove(); - }); - return [menu, innerMenu]; -} - - -// WEBCAM -session.publishStream = function(v, title="Stream Sharing Session"){ // stream is used to generated an SDP - log("STREAM SETUP"); - - try { - //session.streamSrc = v.srcObject; // this shoulnd't be needed - v.parentNode.removeChild(v); // remove the preview video element after we switch streams to avoid bug on iOS beta 14 - v.className = ""; - } catch (e){ - errorlog(e); - return; - } - - if (session.transcript){ - setTimeout(function(){setupClosedCaptions();},1000); - } - - toggleMute(true); // apply mute state - - if (!session.streamSrc){ - log("no stream selected"); - session.streamSrc = new MediaStream(); // this is just for backup. - } - - session.streamSrc.oninactive = function streamoninactive() { - errorlog('Stream inactive'); - if (session.videoElement.recording){ - session.videoElement.recorder.stop(); - } - }; - - if (session.streamSrc.getVideoTracks().length==0){ - warnlog("NO VIDEO TRACK INCLUDED"); - } - - if (session.streamSrc.getAudioTracks().length==0){ - warnlog("NO AUDIO TRACK INCLUDED"); - } - - - var container = document.createElement("div"); - container.id = "container"; - - if (session.cleanOutput){ - container.style.height = "100%"; - v.style.maxWidth = "100%"; - v.style.boxShadow = "none"; - } - - container.className = "vidcon"; - getById("gridlayout").appendChild(container); - - v.className = "tile"; - - v.muted = true; - v.autoplay = true; - v.controls = false; - v.setAttribute("playsinline",""); - v.id = "videosource"; // could be set to UUID in the future - v.oncanplay = null; - container.appendChild(v); - - if (session.nopreview){ - v.style.display="none"; - container.style.display="none"; - } - - changeAudioOutputDevice(v); - - if (session.mirrored && session.flipped){ - v.style.transform = "scaleX(1) scaleY(-1) "; - } else if (session.mirrored){ - v.style.transform = "scaleX(1) "; - } else if (session.flipped){ - v.style.transform = "scaleY(-1) scaleX(-1)"; - } else { - v.style.transform = "scaleX(-1) "; - } - - var bigPlayButton = document.getElementById("bigPlayButton"); - if (bigPlayButton){ - bigPlayButton.parentNode.removeChild(bigPlayButton); - } - - session.videoElement = v; - - if (session.streamID){ - session.videoElement.dataset.sid = session.streamID; - } - - if (session.director){ - // audio is not mucked with - } else if (session.scene!==false){ - setTimeout(function(){updateMixer();},1); - } else if (session.roomid!==false){ - if (session.roomid===""){ - if (!(session.view) || (session.view==="")){ - - - if (session.fullscreen){ - session.windowed = false; - } else { - v.className = "myVideo"; - session.windowed = true; - } - getById("mutespeakerbutton").classList.add("advanced"); - - applyMirror(session.mirrorExclude, 'videosource'); - - container.style.width="100%"; - //container.style.height="100%"; - - container.style.alignItems = "center"; - container.backgroundColor = "#666"; - - setTimeout(function (){dragElement(v);},1000); - play(); - } else { - session.windowed = false; - applyMirror(session.mirrorExclude, 'videosource'); - play(); - setTimeout(function(){updateMixer();},1); - } + // Remove modal if network comes back up + window.addEventListener("online", function (e) { + if (!session.cleanOutput) { + // Remove last inserted modal; Could be improved by tagging the + // modal elements and only removing modals tagged 'offline' + userWarnings = document.querySelectorAll('.alertModal'); + closeModal(userWarnings[userWarnings.length- 1]); } else { - //session.cbr=0; // we're just going to override it - if (session.stereo==5){ // not a scene or director, so we will assume its a guest. changing to stereo=3 - session.stereo=3; - } - session.windowed = false; - applyMirror(session.mirrorExclude, 'videosource'); - - setTimeout(function(){updateMixer();},1); - } - } else { - - - if (session.fullscreen){ - session.windowed = false; - } else { - v.className = "myVideo"; - session.windowed = true; - } - getById("mutespeakerbutton").classList.add("advanced"); - - applyMirror(session.mirrorExclude, 'videosource'); - - container.style.width="100%"; - //container.style.height="100%"; - //container.style.display = "flex"; - - container.style.alignItems = "center"; - container.backgroundColor = "#666"; - - setTimeout(function (){dragElement(v);},1000); - - } - - v.onpause = (event) => { // prevent things from pausing; human or other - if (!((event.ctrlKey) || (event.metaKey) )){ - log("Video paused; auto playing"); - event.currentTarget.play().then(_ => { - log("playing"); - }).catch(warnlog); - } - }; - - v.addEventListener('click', function(e) { - log("click"); - try { - if ((e.ctrlKey)||(e.metaKey)){ - e.preventDefault(); - - var [menu, innerMenu] = statsMenuCreator(); - - menu.interval = setInterval(printMyStats,3000, innerMenu); - - printMyStats(innerMenu); - e.stopPropagation(); - return false; - } - } catch(e){errorlog(e);} - }); - - v.touchTimeOut = null; - v.touchLastTap = 0; - v.touchCount = 0; - v.addEventListener('touchend', function(event) { - log("touched"); - - document.ontouchup = null; - document.onmouseup = null; - document.onmousemove = null; - document.ontouchmove = null; - - var currentTime = new Date().getTime(); - var tapLength = currentTime - v.touchLastTap; - clearTimeout(v.touchTimeOut); - if (tapLength < 500 && tapLength > 0) { - /// - log("double touched"); - v.touchCount+=1; - event.preventDefault(); - if (v.touchCount<5){ - v.touchLastTap = currentTime; - return false; - } - v.touchLastTap = 0; - v.touchCount=0; - - var [menu, innerMenu] = statsMenuCreator(); - - menu.interval = setInterval(printMyStats,3000, innerMenu); - - printMyStats(innerMenu); - event.stopPropagation(); - return false; - ////// - } else { - v.touchCount=1; - v.touchLastTap = currentTime; - - v.touchTimeOut = setTimeout(function(vv) { - clearTimeout(vv.touchTimeOut); - vv.touchLastTap = 0; - vv.touchCount=0; - }, 5000, v); - - } - - }); - - try{ - var m = getById("mainmenu"); - m.remove(); - } catch (e){} - - var added = ""; - if (session.defaultPassword===false){ - if (session.password){ - added="&pw="+session.password; - } - } - - var pie = ""; - if (session.pie){ - if (session.pie!==true){ - pie = "&pie="+session.pie; - } - } - - getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+added+pie; - getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+added+pie; - getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px'; - pokeIframeAPI('started-camera'); - - - - if (session.videoMutedFlag){ - session.videoMuted = true; - toggleVideoMute(true); - } - - clearInterval(session.updateLocalStatsInterval); - session.updateLocalStatsInterval = setInterval(function(){updateLocalStats();},3000); - - session.title=title; - session.seeding=true; - session.seedStream(); - - if (iOS || iPad) { - setTimeout(function(){ - try{ - enumerateDevices().then(gotDevices2); - } catch(e){} - },100); - } -}; - - -session.publishScreen = function(constraints, title="Screen Sharing Session", audioList=[], audio=true){ // webcam stream is used to generated an SDP - log("SCREEN SHARE SETUP"); - if (!navigator.mediaDevices.getDisplayMedia){ - setTimeout(function(){warnUser("Sorry, your browser is not supported. Please use the desktop versions of Firefox or Chrome instead");},1); - return false; - } - if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { - if (!ElectronDesktopCapture){ - if (!(session.cleanOutput && session.cleanish==false)){ - warnUser("Your Electron app does not support Screen Capture.

Update your Electron Capture app and then enable Elevated Privileges to access screen-sharing."); - } - return false; - } - } - - var streams = []; - for (var i=1; i{ - streams.push(stream); - }).catch(errorlog); - } - } - - if (session.audioDevice === 0 ){ - constraints.audio = false; - } - - log(constraints); - return navigator.mediaDevices.getDisplayMedia(constraints).then(function (stream){ - /// RETURN stream for preview? rather than jumping right in. - session.screenShareState=true; - try { - stream.getVideoTracks()[0].onended = function () { - session.screenShareState=false; - pokeIframeAPI("screen-share-ended"); - grabScreen(); - }; - } catch(e){log("No Video selected; screensharing?");} - - // OR, jump right in, and let user change from there - if (session.roomid!==false){ - if ((session.roomid==="") && ((!(session.view)) || (session.view===""))){ - - } else { - getById("head3").className = 'advanced'; - - log("ROOMID EANBLED"); - log("Update Mixer Event on REsize SET"); - window.addEventListener("resize", updateMixer); - window.addEventListener("orientationchange", updateMixer); - joinRoom(session.roomid); - } - - } else { - getById("head3").className = ''; - getById("logoname").style.display = 'none'; - } - - if (urlParams.has('permaid')){ - updateURL("permaid="+session.streamID); - } else { - updateURL("push="+session.streamID); - } - - log("adding tracks"); - for (var i=0; i{ - stream.addTrack(track); - }); - } - streams = null; - if (session.audioDevice !== 0){ - if (stream.getAudioTracks().length==0){ - if (!(session.cleanOutput)){ - if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1){ - // Electron has no audio. - } else { - setTimeout(function(){warnUser("No Audio Source was detected.\n\nIf you were wanting to capture an Application's Audio, please see:\nhttps://docs.vdo.ninja/help/guides-and-how-tos#audio for some guides.");},300); - } - } - } - } - - - - try { - session.streamSrc = stream; - } catch (e){errorlog(e);} - - toggleMute(true); - - var v = document.createElement("video"); - - session.videoElement = v; - - - if (session.streamID){ - session.videoElement.dataset.sid = session.streamID; - } - - - var container = document.createElement("div"); - container.id = "container"; - - if (session.cleanOutput){ - container.style.height = "100%"; - v.style.maxWidth = "100%"; - v.style.boxShadow = "none"; - } - - container.className = "vidcon"; - getById("gridlayout").appendChild(container); - - if (session.nopreview){ - v.style.display="none"; - container.style.display="none"; - } - - container.appendChild(v); - - - v.className = "tile"; - - changeAudioOutputDevice(v); - - if (session.director){ - } else if (session.scene!==false){ - setTimeout(function(){updateMixer();},1); - } else if (session.roomid!==false){ - if (session.roomid===""){ - if (!(session.view) || (session.view==="")){ - - getById("mutespeakerbutton").classList.add("advanced"); - - if (session.fullscreen){ - session.windowed = false; - if (session.mirrored && session.flipped){ - v.style.transform = " scaleX(-1) scaleY(-1)"; - v.classList.add("mirrorControl"); - } else if (session.mirrored){ - v.style.transform = "scaleX(-1)"; - v.classList.add("mirrorControl"); - } else if (session.flipped){ - v.style.transform = "scaleY(-1)"; - v.classList.remove("mirrorControl"); - } else { - v.style.transform = ""; - v.classList.remove("mirrorControl"); - } - } else { - v.className = "myVideo"; - session.windowed = true; - if (session.mirrored && session.flipped){ - v.style.transform = " scaleX(-1) scaleY(-1) translate(0, 50%)"; - v.classList.add("mirrorControl"); - } else if (session.mirrored){ - v.style.transform = "scaleX(-1) translate(0, -50%)"; - v.classList.add("mirrorControl"); - } else if (session.flipped){ - v.style.transform = "scaleY(-1) translate(0, 50%)"; - v.classList.remove("mirrorControl"); - } else { - v.style.transform = " translate(0, -50%)"; - v.classList.remove("mirrorControl"); - } - } - - container.style.width="100%"; - //container.style.height="100%"; - container.style.alignItems = "center"; - container.backgroundColor = "#666"; - - setTimeout(function (){dragElement(v);},1000); - play(); - } else { - play(); - setTimeout(function(){updateMixer();},1); - } - } else { - setTimeout(function(){updateMixer();},1); - } - } else { - - getById("mutespeakerbutton").classList.add("advanced"); - if (session.fullscreen){ - session.windowed = false; - if (session.mirrored && session.flipped){ - v.style.transform = " scaleX(-1) scaleY(-1)"; - v.classList.add("mirrorControl"); - } else if (session.mirrored){ - v.style.transform = "scaleX(-1)"; - v.classList.add("mirrorControl"); - } else if (session.flipped){ - v.style.transform = "scaleY(-1)"; - v.classList.remove("mirrorControl"); - } else { - v.style.transform = ""; - v.classList.remove("mirrorControl"); - } - } else { - v.className = "myVideo"; - session.windowed = true; - if (session.mirrored && session.flipped){ - v.style.transform = " scaleX(-1) scaleY(-1) translate(0, 50%)"; - v.classList.add("mirrorControl"); - } else if (session.mirrored){ - v.style.transform = "scaleX(-1) translate(0, -50%)"; - v.classList.add("mirrorControl"); - } else if (session.flipped){ - v.style.transform = "scaleY(-1) translate(0, 50%)"; - v.classList.remove("mirrorControl"); - } else { - v.style.transform = " translate(0, -50%)"; - v.classList.remove("mirrorControl"); - } - } - - - - - container.style.width="100%"; - //container.style.height="100%"; - container.style.alignItems = "center"; - container.backgroundColor = "#666"; - } - - v.autoplay = true; - v.controls = false; - v.setAttribute("playsinline",""); - v.muted = true; - v.id = "videosource"; - - //if (!v.srcObject || v.srcObject.id !== stream.id) { - // v.srcObject = stream; - v.srcObject = outboundAudioPipeline(session.streamSrc); - //} - - v.onpause = (event) => { // prevent things from pausing; human or other - if (!((event.ctrlKey) || (event.metaKey) )){ - log("Video paused; auto playing"); - event.currentTarget.play().then(_ => { - log("playing"); - }).catch(warnlog); - } - }; - - v.addEventListener('click', function(e) { // show stats of video if double clicked - log("click"); - try { - if ((e.ctrlKey)||(e.metaKey)){ - e.preventDefault(); - - var [menu, innerMenu] = statsMenuCreator(); - - menu.interval = setInterval(printMyStats,3000, innerMenu); - - printMyStats(innerMenu); - e.stopPropagation(); - return false; - } - } catch(e){errorlog(e);} - }); - - try{ - var m = getById("mainmenu"); - m.remove(); - } catch (e){} - - var pie = ""; - if (session.pie){ - if (session.pie!==true){ - pie = "&pie="+session.pie; - } - } - - getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+pie; - getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+pie; - getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px'; - - - if (session.videoMutedFlag){ - session.videoMuted = true; - toggleVideoMute(true); - } - - clearInterval(session.updateLocalStatsInterval); - session.updateLocalStatsInterval = setInterval(function(){updateLocalStats();},3000); - - session.title=title; - session.seeding=true; - session.seedStream(); - - pokeIframeAPI('started-screenshare'); - - return true; - }).catch(function(err){ - warnlog(err); /* handle the error */ - if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { - if (!ElectronDesktopCapture){ - if (!(session.cleanOutput)) { - warnUser("Your Electron app does not support Screen Capture.

Update your Electron Capture app and then enable Elevated Privileges to access screen-sharing."); - } - return false; - } - } - if ((err.name == "NotAllowedError") || (err.name == "PermissionDeniedError")){ - // User Stopped it. - session.screenShareState=false; - pokeIframeAPI("screen-share-ended"); - return false; - } else { - if (audio==true){ - constraints.audio=false; - if (!(session.cleanOutput)){ - setTimeout(function(){warnUser(err);},1); // TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio capture is not supported - } - return session.publishScreen(constraints, title, audioList, false); - } else { - if (!(session.cleanOutput)){ - setTimeout(function(){warnUser(err);},1); // TypeError: Failed to execute 'getDisplayMedia' on 'MediaDevices': Audio capture is not supported - } - return false; - } - + log( + "Network connectivity has been restored." + ); } }); - -}; -session.publishFile = function(ele, event, title="Video File Sharing Session"){ // webcam stream is used to generated an SDP - log("FILE SHARE SETUP"); - - if (session.transcript){ - setTimeout(function(){setupClosedCaptions();},1000); - } - - var files = []; - for (var i = 0; i < ele.files.length; i++){ // changing from a FileList to an Array. Arrays are easier to modify later on - files.push(ele.files[i]); - } - log(files); - //var type = file.type; - - var fileURL = URL.createObjectURL(files[0]); - var container = document.createElement("div"); - container.id = "container"; - - - - container.className = "vidcon"; - var v = document.createElement("video"); - - if (session.cleanOutput){ - container.style.height = "100%"; - v.style.maxWidth = "100%"; - v.style.boxShadow = "none"; - } - - if (session.streamID){ - v.dataset.sid = session.streamID; - } - - getById("gridlayout").appendChild(container); - - if (session.roomid!==false){ - if ((session.roomid==="") && ((!(session.view)) || (session.view===""))){ - - } else { - log("ROOMID EANBLED"); - log("Update Mixer Event on REsize SET"); - //window.addEventListener("resize", updateMixer);// TODO FIX - //window.addEventListener("orientationchange", updateMixer);// TODO FIX - getById("head3").className = 'advanced'; - joinRoom(session.roomid); - } - - } else { - getById("head3").className = ''; - getById("logoname").style.display = 'none'; - } - getById("head1").className = 'advanced'; - - if (urlParams.has('permaid')){ - updateURL("permaid="+session.streamID); - } else { - updateURL("push="+session.streamID); - } - - getById("head1").className = 'advanced'; - getById("head2").className = 'advanced'; - - if (!(session.cleanOutput)){ - getById("chatbutton").className="float"; - getById("hangupbutton").className="float"; - getById("controlButtons").style.display="flex"; - getById("helpbutton").style.display = "inherit"; - getById("reportbutton").style.display = ""; - } else { - getById("controlButtons").style.display="none"; - } - - var bigPlayButton = document.getElementById("bigPlayButton"); - if (bigPlayButton){ - bigPlayButton.parentNode.removeChild(bigPlayButton); - } - - v.autoplay = false; - v.controls = true; - v.muted = false; - - if (files.length ==1){ // we don't want to do the complex logic if there is just one video - v.loop = true; - } else { - v.loop = false; // triggers the complex track/rtc logic. - } - - v.setAttribute("playsinline",""); - v.src = fileURL; - - try { - session.streamSrc=v.captureStream(); - } catch (e){ - errorlog(e); - return; - } - - v.className = "tile clean fileshare"; - v.id = "videosource"; // could be set to UUID in the future - v.playlist = files; - - v.addEventListener('ended',myHandler,false); // only fires if the video doesn't loop. - - - function myHandler(e) { - log("MY HANDLER TRIGGERED"); - var vid = getById("videosource"); - log(vid.playlist); - vid.playlist.unshift(vid.playlist.pop()); - vid.src = URL.createObjectURL(vid.playlist[0]); - vid.onloadeddata = function(){ - session.streamSrc=vid.captureStream(); - - session.streamSrc.getTracks().forEach(function(track){ - for (UUID in session.pcs){ - var senders = session.pcs[UUID].getSenders(); - log(track); - if (track.kind == "video"){ - try { - if ((session.pcs[UUID].guest==true) && (session.roombitrate===0)) { - log("room rate restriction detected. No videos will be published to other guests"); - } else if (session.pcs[UUID].allowVideo==true){ // allow - // for any connected peer, update the video they have if connected with a video already. - var added=false; - senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams? - - if (sender.track && sender.track.kind == "video"){ - sender.replaceTrack(track); // replace may not be supported by all browsers. eek. - added=true; - } - - }); - if (added==false){ - session.pcs[UUID].addTrack(track, session.streamSrc); - setTimeout(function(uuid){session.optimizeBitrate(uuid);},session.rampUpTime, UUID); // 3 seconds lets us ramp up the quality a bit and figure out the total bandwidth quicker - } - } - } catch (e){ - errorlog(e); - } - - } else { - session.pcs[UUID].addTrack(track, session.streamSrc); - } - } - }); - session.refreshScale(); - } - vid.load(); - log(session.streamSrc); - vid.play().then(_ => { - log("playing"); - }).catch(warnlog); - - } - - // no preview doesn't work, so just stop it from doing its thing. - - - container.appendChild(v); - changeAudioOutputDevice(v); - - if (session.mirrored && session.flipped){ - v.style.transform = "scaleX(1) scaleY(-1) "; - } else if (session.mirrored){ - v.style.transform = "scaleX(1) "; - } else if (session.flipped){ - v.style.transform = "scaleY(-1) scaleX(-1)"; - } else { - v.style.transform = "scaleX(-1) "; - } - - session.mirrorExclude=true; - - if (session.director){ - } else if (session.scene!==false){ - //setTimeout(function(){updateMixer();},1);// TODO FIX - } else if (session.roomid!==false){ - if (session.roomid===""){ - if (!(session.view) || (session.view==="")){ - - if (session.fullscreen){ - session.windowed = false; - } else { - v.className = "myVideo clean fileshare"; - session.windowed = true; - } - getById("mutespeakerbutton").classList.add("advanced"); - - applyMirror(session.mirrorExclude, 'videosource'); - - container.style.width="100%"; - //container.style.height="100%"; - - container.style.alignItems = "center"; - container.backgroundColor = "#666"; - - play(); - } else { - session.windowed = false; - applyMirror(session.mirrorExclude, 'videosource'); - play(); - //setTimeout(function(){updateMixer();},1);// TODO FIX - } - } else { - //session.cbr=0; // we're just going to override it - if (session.stereo==5){ - session.stereo=3; - } - session.windowed = false; - applyMirror(session.mirrorExclude, 'videosource'); - //setTimeout(function(){updateMixer();},1); // TODO FIX - } - } else { - - - if (session.fullscreen){ - session.windowed = false; - } else { - v.className = "myVideo clean fileshare"; - session.windowed = true; - } - getById("mutespeakerbutton").classList.add("advanced"); - - applyMirror(session.mirrorExclude, 'videosource'); - - container.style.width="100%"; - //container.style.height="100%"; - //container.style.display = "flex"; - - container.style.alignItems = "center"; - container.backgroundColor = "#666"; - - } - - - v.addEventListener('click', function(e){ - log("click"); - try { - if ((e.ctrlKey)||(e.metaKey)){ - e.preventDefault(); - - var [menu, innerMenu] = statsMenuCreator(); - - menu.interval = setInterval(printMyStats,3000, innerMenu); - - printMyStats(innerMenu); - e.stopPropagation(); - return false; - } - } catch(e){errorlog(e);} - }); - - - v.touchTimeOut = null; - v.touchLastTap = 0; - v.touchCount = 0; - v.addEventListener('touchend', function(event) { - log("touched"); - - document.ontouchup = null; - document.onmouseup = null; - document.onmousemove = null; - document.ontouchmove = null; - - var currentTime = new Date().getTime(); - var tapLength = currentTime - v.touchLastTap; - clearTimeout(v.touchTimeOut); - if (tapLength < 500 && tapLength > 0) { - /// - log("double touched"); - v.touchCount+=1; - event.preventDefault(); - if (v.touchCount<5){ - v.touchLastTap = currentTime; - return false; - } - v.touchLastTap = 0; - v.touchCount=0; - - var [menu, innerMenu] = statsMenuCreator(); - - menu.interval = setInterval(printMyStats,3000, innerMenu); - - printMyStats(innerMenu); - event.stopPropagation(); - return false; - ////// - } else { - v.touchCount=1; - v.touchTimeOut = setTimeout(function(vv) { - clearTimeout(vv.touchTimeOut); - vv.touchLastTap = 0; - vv.touchCount=0; - }, 5000, v); - v.touchLastTap = currentTime; - } - - }); - - try{ - var m = getById("mainmenu"); - m.remove(); - } catch (e){} - - var pie = ""; - if (session.pie){ - if (session.pie!==true){ - pie = "&pie="+session.pie; - } - } - - getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID+pie; - getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID+pie; - getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px'; - pokeIframeAPI('started-fileshare'); - - clearInterval(session.updateLocalStatsInterval); - session.updateLocalStatsInterval = setInterval(function(){updateLocalStats();},3000); - - session.title=title; - session.seeding=true; - - if (session.videoMutedFlag){ - session.videoMuted = true; - toggleVideoMute(true); - } - - session.seedStream(); -}; - - -function tryAgain(event) { // audio or video agnostic track reconnect ------------not actually in use,. maybe out of date - log("TRY AGAIN TRIGGERED"); - warnlog(event); -} - - -function enterPressedClick(event, ele) { - if (event.keyCode === 13) { - event.preventDefault(); - ele.click(); - } -} - -function enterPressed(event, callback) { - // Number 13 is the "Enter" key on the keyboard - if (event.keyCode === 13) { - event.preventDefault(); - callback(); - } -} - - -function dragElement(elmnt) { - var millis = Date.now(); - try { - var input = getById("zoomSlider"); - var stream = elmnt.srcObject; - try { - var track0 = stream.getVideoTracks(); - } catch (e) { + document.addEventListener("dragstart", event => { + var url = event.target.href || event.target.value; + if (!url || !url.startsWith('https://')) return; + if (event.target.dataset.drag != "1") { return; } + //event.target.ondragend = function(){event.target.blur();} - if (!(track0.length)) { - return; - } + var streamId = url.split('view='); + var label = url.split('label='); - track0 = track0[0]; - if (track0.getCapabilities) { - var capabilities = track0.getCapabilities(); - var settings = track0.getSettings(); - - // Check whether zoom is supported or not. - if (!('zoom' in capabilities)) { - log('Zoom is not supported by ' + track0.label); - return; - } - - // Map zoom to a slider element. - input.min = capabilities.zoom.min; - input.max = capabilities.zoom.max; - input.step = capabilities.zoom.step; - input.value = settings.zoom; - } - } catch (e) { - errorlog(e); - return; - } - - log("drag on"); - elmnt.onmousedown = dragMouseDown; - elmnt.onclick = onvideoclick; - elmnt.ontouchstart = dragMouseDown; - - var pos0 = 1; - - function onvideoclick(e) { - log(e); - log("onvideoclick"); - e = e || window.event; - e.preventDefault(); - return false; - } - - function dragMouseDown(e) { - log(e); - log("dragMouseDown"); - - //closeDragElement(null); - - //elmnt.controls = false; - e = e || window.event; - e.preventDefault(); - - pos0 = input.value; - if (e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel') { - var touch = e.touches[0] || e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; - pos3 = touch.clientX; - pos4 = touch.clientY; - } else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover' || e.type == 'mouseout' || e.type == 'mouseenter' || e.type == 'mouseleave') { - pos3 = e.clientX; - pos4 = e.clientY; - } - document.ontouchup = closeDragElement; - document.onmouseup = closeDragElement; - - document.ontouchmove = elementDrag; - document.onmousemove = elementDrag; - } - - function elementDrag(e) { - e = e || window.event; - e.preventDefault(); - // calculate the new cursor position: - - if (Date.now() - millis < 50) { - return; - } - millis = Date.now(); - - if (e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel') { - var touch = e.touches[0] || e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; - pos1 = touch.clientX; - pos2 = touch.clientY; - } else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover' || e.type == 'mouseout' || e.type == 'mouseenter' || e.type == 'mouseleave') { - pos1 = e.clientX; - pos2 = e.clientY; - } - - var zoom = parseFloat((pos4 - pos2) * 2 / elmnt.offsetHeight); - - if (zoom > 1) { - zoom = 1.0; - } else if (zoom < -1) { - zoom = -1.0; - } - input.value = zoom * (input.max - input.min) + input.min; - if (input.value != pos0) { - track0.applyConstraints({ - advanced: [{ - zoom: input.value - }] - }); - } - } - - function closeDragElement(e) { - log(e); - log("closeDragElement"); - //if (e!==null){ - // elmnt.controls=true; - //} - /* stop moving when mouse button is released:*/ - document.ontouchup = null; - document.onmouseup = null; - document.onmousemove = null; - document.ontouchmove = null; - } -} - -function previewIframe(iframesrc) { // this is pretty important if you want to avoid camera permission popup problems. You can also call it automatically via: loadIframe();"> , but don't call it before the page loads. - - var iframe = document.createElement("iframe"); - iframe.allow = "autoplay;camera;microphone;fullscreen;transparency;picture-in-picture;"; - iframe.style.width = "100%"; - iframe.style.height = "100%"; - iframe.style.border = "10px dashed rgb(64 65 62)"; - - if (iframesrc == "") { - iframesrc = "./"; - } - - - if (iframesrc.startsWith("https://") || iframesrc.startsWith("http://")){ - var domain = (new URL(iframesrc)); - domain = domain.hostname; - log(domain); - if ((domain=="www.youtube.com") || (domain=="youtube.com")){ - var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; - var match = iframesrc.match(regExp); - var vidid = (match&&match[7].length==11)? match[7] : false; - - if(vidid){ - iframesrc = "https://www.youtube.com/embed/"+vidid+"?autoplay=1&modestbranding=1"; - log(iframesrc); - } - } else if (domain=="www.twitch.tv"){ - var vidid = iframesrc.split('/').pop().split('#')[0].split('?')[0]; - if (vidid){ - iframesrc = "https://player.twitch.tv/?channel="+vidid+"&parent="+location.hostname; - log(iframesrc); - } - } else if (domain=="twitch.tv"){ - var vidid = iframesrc.split('/').pop().split('#')[0].split('?')[0]; - if (vidid){ - iframesrc = "https://player.twitch.tv/?channel="+vidid+"&parent="+location.hostname; - log(iframesrc); - } - } - - } - - iframe.src = iframesrc; - getById("previewIframe").innerHTML = ""; - getById("previewIframe").style.width = "640px"; - getById("previewIframe").style.height = "360px"; - getById("previewIframe").style.margin = "auto"; - getById("previewIframe").appendChild(iframe); -} - -function loadIframe(iframesrc) { // this is pretty important if you want to avoid camera permission popup problems. You can also call it automatically via: loadIframe();"> , but don't call it before the page loads. - - var iframe = document.createElement("iframe"); - iframe.allow = "autoplay;camera;microphone;fullscreen;transparency;picture-in-picture;"; - iframe.style.width = "100%"; - iframe.style.height = "100%"; - iframe.style.border = "10px dashed rgb(64 65 62)"; - - if (iframesrc == "") { - iframesrc = "./"; - iframe.style.border = "0"; - } - - if (iframesrc.startsWith("https://vdo.ninja/")){ - iframe.style.border = "0"; - } else if (iframesrc.startsWith("https://youtube.com/")){ - iframe.style.border = "0"; - } else if (iframesrc.startsWith("https://www.youtube.com/")){ - iframe.style.border = "0"; - } else if (iframesrc.startsWith("https://youtube.com/")){ - iframe.style.border = "0"; - } else if (iframesrc.startsWith("https://player.twitch.tv/")){ - iframe.style.border = "0"; - } else if (iframesrc.startsWith("https://meshcast.io/")){ - iframe.style.border = "0"; - } - - if (document.getElementById("mainmenu")) { - var m = getById("mainmenu"); - m.remove(); - } - iframe.src = iframesrc; - return iframe -} - -function dropDownButtonAction(ele) { - var ele = getById("dropButton"); - if (ele) { - ele.parentNode.removeChild(ele); - getById('container-5').classList.remove('advanced'); - getById('container-8').classList.remove('advanced'); - getById('container-6').classList.remove('advanced'); - getById('container-7').classList.remove('advanced'); - } -} - -function updateConstraintSliders() { - log("updateConstraintSliders"); - if (session.roomid !== false && session.roomid !== "" && session.director !== true && session.forceMediaSettings == false) { - if (session.controlRoomBitrate !== false) { - listCameraSettings(); - } - if (session.effects!==false){ - if ((iOS) || (iPad)){ - } else { - getById("effectsDiv3").style.display = "block"; - getById("effectSelector3").value = (parseInt(session.effects) || 0) +""; - } - } - } else { - listAudioSettings(); - listCameraSettings(); - if ((iOS) || (iPad)){ + if (session.label !== false) { + url += '&layer-name=' + session.label; } else { - if (session.effects!==false){ - getById("effectsDiv3").style.display = "block"; - try{ - getById("effectSelector3").value = (parseInt(session.effects) || 0) +""; - } catch(E){} - } - } - } - //checkIfPIP(); // this doesn't actually work on iOS still, so whatever. -} - -function checkIfPIP() { - try { - if (session.videoElement && ((session.videoElement.webkitSupportsPresentationMode && typeof session.videoElement.webkitSetPresentationMode === "function") || (document.pictureInPictureEnabled || !videoElement.disablePictureInPicture))) { - // Toggle PiP when the user clicks the button. - - getById("pIpStartButton").addEventListener("click", function(event) { - // if ( (document.pictureInPictureEnabled || !videoElement.disablePictureInPicture)){ - //session.videoElement.requestPictureInPicture(); - // } else { - session.videoElement.webkitSetPresentationMode(session.videoElement.webkitPresentationMode === "picture-in-picture" ? "inline" : "picture-in-picture"); - // } - }); - getById("pIpStartButton").style.display = "inline-block"; + url += '&layer-name=VDO.Ninja'; } - } catch (e) { - errorlog(e); - } -} + if (streamId.length > 1) url += ': ' + streamId[1].split('&')[0]; + if (label.length > 1) url += ' - ' + decodeURI(label[1].split('&')[0]); -function listAudioSettingsPrep() { - try { - var tracks = session.streamSrc.getAudioTracks(); - if (!tracks.length) { - warnlog("session.streamSrc contains no audio tracks"); - return; - } - } catch (e) { - warnlog(e); - return; - } - - var data = []; - - for (var i = 0; i < tracks.length; i += 1) { - track0 = tracks[i]; - var trackSet = {}; - - if (track0.getCapabilities) { - trackSet.audioConstraints = track0.getCapabilities(); - } - - if (track0.getSettings) { - trackSet.currentAudioConstraints = track0.getSettings(); - } - - trackSet.trackLabel = "unknown or none"; - if (track0.label) { - trackSet.trackLabel = track0.label; - } - - if (i == 0) { - trackSet.equalizer = session.equalizer; // only supporting the first track at the moment. - } else { - trackSet.equalizer = false; - } - - if (i == 0) { - trackSet.lowcut = session.lowcut; // only supporting the first track at the moment. - } else { - trackSet.lowcut = false; - } - - data.push(trackSet); - } - return data; -} - -function listVideoSettingsPrep() { - try { - var track0 = session.streamSrc.getVideoTracks(); - if (track0.length) { - track0 = track0[0]; - if (track0.getCapabilities) { - session.cameraConstraints = track0.getCapabilities(); - } - log(session.cameraConstraints); - } - } catch (e) { - warnlog(e); - return; - } - - try { - if (track0.getSettings) { - session.currentCameraConstraints = track0.getSettings(); - } - } catch (e) { - warnlog(e); - return; - } - var msg = {}; - msg.trackLabel = "unknown or none"; - if (track0.label) { - msg.trackLabel = track0.label; - } - msg.currentCameraConstraints = session.currentCameraConstraints; - msg.cameraConstraints = session.cameraConstraints; - return msg; -} - - -var Final_transcript = ""; -var Interim_transcript = ""; -var Recognition = null; - -if ("webkitSpeechRecognition" in window) { - var SpeechRecognition = webkitSpeechRecognition; -} else if ("SpeechRecognition" in window) { - var SpeechRecognition = window.SpeechRecognition; -} else { - var SpeechRecognition = false; -} - -var TranscriptionCounter = 0; -var retriesRecognition = 0; -var activeRecognition=false; -var timeoutRecognition = null; -function setupClosedCaptions() { - - if (activeRecognition){return;} - activeRecognition=true; - - log("CLOSED CAPTIONING SETUP"); - - if (SpeechRecognition) { - Recognition = new SpeechRecognition(); - - Recognition.lang = session.transcript; - - Recognition.continuous = true; - Recognition.interimResults = true; - Recognition.maxAlternatives = 0; - - Recognition.onstart = function() { - log("started transcription: "+Date.now()); - clearTimeout(timeoutRecognition); - timeoutRecognition = setTimeout(function(){ - retriesRecognition=0; - },10000); - }; - Recognition.onerror = function(event) { - errorlog(event); - }; - Recognition.onend = function(e) { - warnlog(e); - log("Stopped transcription "+Date.now()); - clearTimeout(timeoutRecognition); - timeoutRecognition = setTimeout(function() { - Recognition.start(); - }, parseInt(500*retriesRecognition*retriesRecognition)); // restart it if it fails. - retriesRecognition+=1; - }; - - Recognition.onresult = function(event) { - - Interim_transcript = ''; - if (typeof(event.results) == 'undefined') { - log(event); - return; - } - for (var i = event.resultIndex; i < event.results.length; ++i) { - if (event.results[i].isFinal) { - Final_transcript += event.results[i][0].transcript; - } else { - Interim_transcript += event.results[i][0].transcript; - } - } - - if (Final_transcript.length > 0) { - log("FINAL:" + Final_transcript); - try { - var data = {}; - data.isFinal = true; - data.transcript = Final_transcript; - data.counter = TranscriptionCounter; - session.sendMessage(data); - TranscriptionCounter += 1; - Final_transcript = ""; - Interim_transcript = ""; - } catch (e) { - errorlog(e); - } - - } else { - try { - var data = {}; - data.isFinal = false; - data.transcript = Interim_transcript; - data.counter = TranscriptionCounter; - session.sendMessage(data); - } catch (e) { - errorlog(e); - Interim_transcript = ""; - } - } - }; - - Recognition.start(); - } -} - - -function requestVideoRecord(ele) { - var UUID = ele.dataset.UUID - if (ele.classList.contains("pressed")) { - var msg = {}; - msg.requestVideoRecord = false; - msg.UUID = UUID; - session.sendRequest(msg, msg.UUID); - ele.classList.remove("pressed"); - } else { - var msg = {}; - msg.requestVideoRecord = true; - msg.UUID = UUID; - window.focus(); - var bitrate = prompt("What bitrate would you like to record at? (kbps)", 6000); - if (bitrate) { - msg.value = bitrate; - session.sendRequest(msg, msg.UUID); - ele.classList.add("pressed"); - } - } -} - -function changeOrderDirector(value) { - if (session.order==false){ - session.order=0; - } - session.order += parseInt(value) || 0; - - var elements = document.querySelectorAll('[data-action-type="order-value-director"]'); - //log(elements); - if (elements[0]){ - elements[0].innerText = parseInt(session.order) || 0; - } - - var data = {}; - data = {}; - data.order = session.order; - session.sendPeers(data); -} - - - -function changeOrder(value, UUID) { - var msg = {}; - msg.changeOrder = value; - msg.UUID = UUID; - session.sendRequest(msg, msg.UUID); -} - -function requestVideoHack(keyname, value, UUID) { - var msg = {}; - msg.requestVideoHack = true; - msg.keyname = keyname; - msg.value = value; - msg.UUID = UUID; - session.sendRequest(msg, msg.UUID); -} - -function requestAudioHack(keyname, value, UUID, track = 0) { // updateCameraConstraints - var msg = {}; - msg.requestAudioHack = true; - msg.keyname = keyname; - msg.value = value; - msg.UUID = UUID; - msg.track = track; - session.sendRequest(msg, msg.UUID); -} - -function requestChangeEQ(keyname, value, UUID, track = 0) { // updateCameraConstraints - var msg = {}; - msg.requestChangeEQ = true; - msg.keyname = keyname; - msg.value = value; - msg.UUID = UUID; - msg.track = track; - session.sendRequest(msg, msg.UUID); -} - -function requestChangeLowcut(value, UUID, track = 0) { // updateCameraConstraints - var msg = {}; - msg.requestChangeLowcut = true; - msg.value = value; - msg.UUID = UUID; - msg.track = track; - session.sendRequest(msg, msg.UUID); -} - -function toggleSystemPip(vid) { - if (vid.webkitSupportsPresentationMode && (typeof vid.webkitSetPresentationMode === "function")) { - vid.webkitSetPresentationMode( - vid.webkitPresentationMode === "picture-in-picture" - ? "inline" - : "picture-in-picture" - ); - } else { - if (document.pictureInPictureElemen) { - document.exitPictureInPicture(); - vid.requestPictureInPicture(); - } else { - vid.requestPictureInPicture(); - } - - } -} - -function updateDirectorsAudio(dataN, UUID) { - var audioEle = document.createElement("div"); - getById("advanced_audio_director_" + UUID).innerHTML = ""; - getById("advanced_audio_director_" + UUID).className = ""; - - //log(dataN); - if (!dataN.length) { - return; - } - - for (var n = 0; n < dataN.length; n += 1) { - var data = dataN[n]; - - if (data.trackLabel) { - var label = document.createElement("span"); - label.innerText = data.trackLabel; - label.style.marginBottom = "10px"; - label.style.display = "block"; - audioEle.appendChild(label); - } - if (n !== 0) { - //var label = document.createElement("span"); - //label.innerText = "Coming Soon"; - //audioEle.appendChild(label); - continue; // remove to more than one audio device (assuming other fixes are applied) - } - - - if (data.lowcut) { - var label = document.createElement("label"); - var i = "Low_Cut"; - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = "low cut:"; - - var input = document.createElement("input"); - input.min = 50; - input.max = 150; - - input.type = "range"; - input.dataset.keyname = i; - input.dataset.labelname = label.innerText; - input.dataset.track = n; - input.dataset.UUID = UUID; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - input.style.margin = "8px 0"; - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value; - requestChangeLowcut(parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track)); - }; - - audioEle.appendChild(label); - audioEle.appendChild(input); - } - - if (data.equalizer) { - var label = document.createElement("label"); - var i = "Low_EQ"; - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = "low EQ:"; - - var input = document.createElement("input"); - input.min = -50; - input.max = 50; - - input.type = "range"; - input.dataset.keyname = i; - input.dataset.labelname = label.innerText; - input.dataset.track = n; - input.dataset.UUID = UUID; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - input.style.margin = "8px 0"; - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value; - //changeLowEQ( e.target.value); - requestChangeEQ("low", parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track)); - }; - - audioEle.appendChild(label); - audioEle.appendChild(input); - - var label = document.createElement("label"); - var i = "Mid_EQ"; - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = "mid EQ:"; - - var input = document.createElement("input"); - input.min = -50; - input.max = 50; - - input.type = "range"; - input.dataset.keyname = i; - input.dataset.labelname = label.innerText; - input.dataset.track = n; - input.dataset.UUID = UUID; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - input.style.margin = "8px 0"; - - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value; - //changeMidEQ( e.target.value); - requestChangeEQ("mid", parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track)); - }; - - audioEle.appendChild(label); - audioEle.appendChild(input); - - - var label = document.createElement("label"); - var i = "High_EQ"; - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = "high EQ:"; - - var input = document.createElement("input"); - input.min = -50; - input.max = 50; - - input.type = "range"; - input.dataset.keyname = i; - input.dataset.labelname = label.innerText; - input.dataset.track = n; - input.dataset.UUID = UUID; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - input.style.margin = "8px 0"; - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value; - requestChangeEQ("high", parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track)); - }; - - audioEle.appendChild(label); - audioEle.appendChild(input); - } - for (var i in data.audioConstraints) { - try { - log(i); - log(data.audioConstraints[i]); - if ((typeof data.audioConstraints[i] === 'object') && (data.audioConstraints[i] !== null) && ("max" in data.audioConstraints[i]) && ("min" in data.audioConstraints[i])) { - if (i === "aspectRatio") { - continue; - } else if (i === "width") { - continue; - } else if (i === "height") { - continue; - } else if (i === "frameRate") { - continue; - } else if (i === "latency") { - continue; - } else if (i === "sampleRate") { - continue; - } else if (i === "channelCount") { - continue; - } - - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = i + ":"; - - var input = document.createElement("input"); - input.min = data.audioConstraints[i].min; - input.max = data.audioConstraints[i].max; - - if (parseFloat(input.min) == parseFloat(input.max)) { - continue; - } - - if (i in data.currentAudioConstraints) { - input.value = data.currentAudioConstraints[i]; - label.innerText = i + ": " + data.currentAudioConstraints[i]; - label.title = "Previously was: " + data.currentAudioConstraints[i]; - input.title = "Previously was: " + data.currentAudioConstraints[i]; - } else { - label.innerText = i; - } - if ("step" in data.audioConstraints[i]) { - input.step = data.audioConstraints[i].step; - } - input.type = "range"; - input.dataset.keyname = i; - input.dataset.track = n; - input.dataset.UUID = UUID; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.keyname + ": " + e.target.value; - //updateAudioConstraints(e.target.dataset.keyname, e.target.value); - requestAudioHack(e.target.dataset.keyname, e.target.value, e.target.dataset.UUID, e.target.dataset.track); - }; - - audioEle.appendChild(label); - audioEle.appendChild(input); - } else if ((typeof data.audioConstraints[i] === 'object') && (data.audioConstraints[i] !== null)) { - if (i == "resizeMode") { - continue; - } - - var div = document.createElement("div"); - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = i + ":"; - label.style = "display:inline-block; padding:0;margin: 5px 0px 9px;"; - label.dataset.keyname = i; - var input = document.createElement("select"); - var c = document.createElement("option"); - - if (data.audioConstraints[i].length > 1) { - for (var opts in data.audioConstraints[i]) { - log(opts); - var opt = new Option(data.audioConstraints[i][opts], data.audioConstraints[i][opts]); - input.options.add(opt); - if (i in data.currentAudioConstraints) { - if (data.audioConstraints[i][opts] == data.currentAudioConstraints[i]) { - opt.selected = true; - } - } - } - } else if (i.toLowerCase == "torch") { - var opt = new Option("Off", false); - input.options.add(opt); - opt = new Option("On", true); - input.options.add(opt); - } else { - continue; - } - - input.id = "constraints_" + i; - input.className = "constraintCameraInput"; - input.name = "constraints_" + i; - input.style = "display:inline; padding:2px; margin:0 10px;"; - input.dataset.keyname = i; - input.dataset.track = n; - input.dataset.UUID = UUID; - input.onchange = function(e) { - //getById("label_"+e.target.dataset.keyname).innerText =e.target.dataset.keyname+": "+e.target.value; - //updateAudioConstraints(e.target.dataset.keyname, e.target.value); - requestAudioHack(e.target.dataset.keyname, e.target.value, e.target.dataset.UUID, e.target.dataset.track); - log(e.target.dataset.keyname, e.target.value); - }; - audioEle.appendChild(div); - div.appendChild(label); - div.appendChild(input); - } else if (typeof data.audioConstraints[i] === 'boolean') { - - var div = document.createElement("div"); - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = i + ":"; - label.style = "display:inline-block; padding:0;margin: 5px 0px 9px;"; - label.dataset.keyname = i; - var input = document.createElement("select"); - var c = document.createElement("option"); - - var opt = new Option("Off", false); - input.options.add(opt); - opt = new Option("On", true); - input.options.add(opt); - - input.id = "constraints_" + i; - input.className = "constraintCameraInput"; - input.name = "constraints_" + i; - input.style = "display:inline; padding:2px; margin:0 10px;"; - input.dataset.keyname = i; - input.dataset.track = n; - input.dataset.UUID = UUID; - input.onchange = function(e) { - //getById("label_"+e.target.dataset.keyname).innerText =e.target.dataset.keyname+": "+e.target.value; - //updateAudioConstraints(e.target.dataset.keyname, e.target.value); - requestAudioHack(e.target.dataset.keyname, e.target.value, e.target.dataset.UUID, e.target.dataset.track); - log(e.target.dataset.keyname, e.target.value); - }; - audioEle.appendChild(div); - div.appendChild(label); - div.appendChild(input); - } - } catch (e) { - errorlog(e); - } - } - getById("advanced_audio_director_" + UUID).appendChild(audioEle); - } -} - -function updateDirectorsVideo(data, UUID) { - var videoEle = document.createElement("div"); - if (data.trackLabel) { - var label = document.createElement("span"); - label.innerText = data.trackLabel; - label.style.marginBottom = "10px"; - label.style.display = "block"; - videoEle.appendChild(label); - } - - - for (var i in data.cameraConstraints) { try { - log(i); - log(data.cameraConstraints[i]); - if ((typeof data.cameraConstraints[i] === 'object') && (data.cameraConstraints[i] !== null) && ("max" in data.cameraConstraints[i]) && ("min" in data.cameraConstraints[i])) { - if (i === "aspectRatio") { - continue; - } else if (i === "width") { - continue; - } else if (i === "height") { - continue; - } else if (i === "frameRate") { - continue; - } else if (i === "latency") { - continue; - } else if (i === "sampleRate") { - continue; - } else if (i === "channelCount") { - continue; - } - - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = i + ":"; - - var input = document.createElement("input"); - input.min = data.cameraConstraints[i].min; - input.max = data.cameraConstraints[i].max; - - if (parseFloat(input.min) == parseFloat(input.max)) { - continue; - } - - - if (i in data.currentCameraConstraints) { - input.value = data.currentCameraConstraints[i]; - label.innerText = i + ": " + data.currentCameraConstraints[i]; - label.title = "Previously was: " + data.currentCameraConstraints[i]; - input.title = "Previously was: " + data.currentCameraConstraints[i]; + if (document.getElementById("videosource")) { + var video = getById('videosource'); + if (typeof(video.videoWidth) == "undefined") { + url += '&layer-width=1920'; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough + url += '&layer-height=1080'; + } else if ((parseInt(video.videoWidth) < 360) || (video.videoHeight < 640)) { + url += '&layer-width=1920'; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough + url += '&layer-height=1080'; } else { - label.innerText = i; - } - if ("step" in data.cameraConstraints[i]) { - input.step = data.cameraConstraints[i].step; - } - input.type = "range"; - input.dataset.keyname = i; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;margin: 8px 0;"; - input.name = "constraints_" + i; - - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.keyname + ": " + e.target.value; - //updateVideoConstraints(e.target.dataset.keyname, e.target.value); - requestVideoHack(e.target.dataset.keyname, e.target.value, UUID); - }; - - - videoEle.appendChild(label); - videoEle.appendChild(input); - } else if ((typeof data.cameraConstraints[i] === 'object') && (data.cameraConstraints[i] !== null)) { - if (i == "resizeMode") { - continue; - } - - var div = document.createElement("div"); - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = i + ":"; - label.style = "display:inline-block; padding:0;margin: 5px 0px 9px;"; - label.dataset.keyname = i; - var input = document.createElement("select"); - var c = document.createElement("option"); - - if (data.cameraConstraints[i].length > 1) { - for (var opts in data.cameraConstraints[i]) { - log(opts); - var opt = new Option(data.cameraConstraints[i][opts], data.cameraConstraints[i][opts]); - input.options.add(opt); - if (i in data.currentCameraConstraints) { - if (data.cameraConstraints[i][opts] == data.currentCameraConstraints[i]) { - opt.selected = true; - } - } - } - } else if (i.toLowerCase == "torch") { - var opt = new Option("Off", false); - input.options.add(opt); - opt = new Option("On", true); - input.options.add(opt); - } else { - continue; - } - - input.id = "constraints_" + i; - input.className = "constraintCameraInput"; - input.name = "constraints_" + i; - input.style = "display:inline; padding:2px; margin:0 10px;"; - input.dataset.keyname = i; - input.onchange = function(e) { - //getById("label_"+e.target.dataset.keyname).innerText =e.target.dataset.keyname+": "+e.target.value; - //updateVideoConstraints(e.target.dataset.keyname, e.target.value); - requestVideoHack(e.target.dataset.keyname, e.target.value, UUID); - log(e.target.dataset.keyname, e.target.value); - }; - videoEle.appendChild(div); - div.appendChild(label); - div.appendChild(input); - } else if (typeof data.cameraConstraints[i] === 'boolean') { - - var div = document.createElement("div"); - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = i + ":"; - label.style = "display:inline-block; padding:0;margin: 5px 0px 9px;"; - label.dataset.keyname = i; - var input = document.createElement("select"); - var c = document.createElement("option"); - - var opt = new Option("Off", false); - input.options.add(opt); - opt = new Option("On", true); - input.options.add(opt); - - input.id = "constraints_" + i; - input.className = "constraintCameraInput"; - input.name = "constraints_" + i; - input.style = "display:inline; padding:2px; margin:0 10px;"; - input.dataset.keyname = i; - input.onchange = function(e) { - //getById("label_"+e.target.dataset.keyname).innerText =e.target.dataset.keyname+": "+e.target.value; - //updateVideoConstraints(e.target.dataset.keyname, e.target.value); - requestVideoHack(e.target.dataset.keyname, e.target.value, UUID); - log(e.target.dataset.keyname, e.target.value); - }; - videoEle.appendChild(div); - div.appendChild(label); - div.appendChild(input); - } - } catch (e) { - errorlog(e); - } - } - - getById("advanced_video_director_" + UUID).innerHTML = ""; - getById("advanced_video_director_" + UUID).appendChild(videoEle); - getById("advanced_video_director_" + UUID).className = ""; -} - -/////// - -function listAudioSettings() { - getById("popupSelector_constraints_audio").innerHTML = ""; - try { - var track0 = session.streamSrc.getAudioTracks(); - if (track0.length) { - track0 = track0[0]; - if (track0.getCapabilities) { - session.audioConstraints = track0.getCapabilities(); - } - log(session.audioConstraints); - } else { - warnlog("session.streamSrc contains no audio tracks"); - return; - } - } catch (e) { - warnlog("session.streamSrc contains no audio tracks"); - errorlog(e); - return; - } - try { - if (track0.getSettings) { - session.currentAudioConstraints = track0.getSettings(); - } - } catch (e) { - errorlog(e); - } - ////// - - if (session.lowcut) { - if (getById("popupSelector_constraints_audio").style.display == "none") { - getById("advancedOptionsAudio").style.display = "inline-block"; - } - - var label = document.createElement("label"); - var i = "Low_Cut"; - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerText = "Low Cut:"; - - var input = document.createElement("input"); - input.min = 50; - input.max = 400; - - input.type = "range"; - input.dataset.keyname = i; - input.dataset.labelname = label.innerHTML; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - - for (var webAudio in session.webAudios) { - if (session.webAudios[webAudio].lowcut1.frequency) { - input.value = session.webAudios[webAudio].lowcut1.frequency.value; - label.innerHTML += " " + session.webAudios[webAudio].lowcut1.frequency.value; - } - } - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.labelname + " " + e.target.value; - changeLowCut(e.target.value, 0); - }; - - getById("popupSelector_constraints_audio").appendChild(label); - getById("popupSelector_constraints_audio").appendChild(input); - } - - if (session.equalizer) { - if (getById("popupSelector_constraints_audio").style.display == "none") { - getById("advancedOptionsAudio").style.display = "inline-block"; - } - - var label = document.createElement("label"); - var i = "Low_EQ"; - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = "Low EQ:"; - - var input = document.createElement("input"); - input.min = -50; - input.max = 50; - - input.type = "range"; - input.dataset.keyname = i; - input.dataset.labelname = label.innerHTML; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - - for (var webAudio in session.webAudios) { - if (session.webAudios[webAudio].lowEQ.gain) { - input.value = session.webAudios[webAudio].lowEQ.gain.value; - label.innerHTML += " " + session.webAudios[webAudio].lowEQ.gain.value; - } - } - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.labelname + " " + e.target.value; - changeLowEQ(e.target.value, 0); - }; - - getById("popupSelector_constraints_audio").appendChild(label); - getById("popupSelector_constraints_audio").appendChild(input); - // - if (getById("popupSelector_constraints_audio").style.display == "none") { - getById("advancedOptionsAudio").style.display = "inline-block"; - } - - var label = document.createElement("label"); - var i = "Mid_EQ"; - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = "Mid EQ:"; - - var input = document.createElement("input"); - input.min = -50; - input.max = 50; - - input.type = "range"; - input.dataset.keyname = i; - input.dataset.labelname = label.innerHTML; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - - - for (var webAudio in session.webAudios) { - if (session.webAudios[webAudio].midEQ.gain) { - input.value = session.webAudios[webAudio].midEQ.gain.value; - label.innerHTML += " " + session.webAudios[webAudio].midEQ.gain.value; - } - } - - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.labelname + " " + e.target.value; - changeMidEQ(e.target.value, 0); - }; - - getById("popupSelector_constraints_audio").appendChild(label); - getById("popupSelector_constraints_audio").appendChild(input); - // - if (getById("popupSelector_constraints_audio").style.display == "none") { - getById("advancedOptionsAudio").style.display = "inline-block"; - } - - var label = document.createElement("label"); - var i = "High_EQ"; - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = "High EQ:"; - - var input = document.createElement("input"); - input.min = -50; - input.max = 50; - - - input.type = "range"; - input.dataset.keyname = i; - input.dataset.labelname = label.innerHTML; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - - for (var webAudio in session.webAudios) { - if (session.webAudios[webAudio].highEQ.gain) { - input.value = session.webAudios[webAudio].highEQ.gain.value; - label.innerHTML += " " + session.webAudios[webAudio].highEQ.gain.value; - } - } - - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.labelname + " " + e.target.value; - changeHighEQ(e.target.value, 0); - }; - - getById("popupSelector_constraints_audio").appendChild(label); - getById("popupSelector_constraints_audio").appendChild(input); - } - //////// - for (var i in session.audioConstraints) { - try { - log(i); - log(session.audioConstraints[i]); - if ((typeof session.audioConstraints[i] === 'object') && (session.audioConstraints[i] !== null) && ("max" in session.audioConstraints[i]) && ("min" in session.audioConstraints[i])) { - if (i === "aspectRatio") { - continue; - } else if (i === "width") { - continue; - } else if (i === "height") { - continue; - } else if (i === "frameRate") { - continue; - } else if (i === "latency") { - continue; - } else if (i === "sampleRate") { - continue; - } else if (i === "channelCount") { - continue; - } - - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = i + ":"; - - - var input = document.createElement("input"); - input.min = session.audioConstraints[i].min; - input.max = session.audioConstraints[i].max; - - if (parseFloat(input.min) == parseFloat(input.max)) { - continue; - } - - if (getById("popupSelector_constraints_audio").style.display == "none") { - getById("advancedOptionsAudio").style.display = "inline-block"; - } - - - if (i in session.currentAudioConstraints) { - input.value = session.currentAudioConstraints[i]; - label.innerHTML = i + ": " + session.currentAudioConstraints[i]; - label.title = "Previously was: " + session.currentAudioConstraints[i]; - input.title = "Previously was: " + session.currentAudioConstraints[i]; - } else { - label.innerHTML = i; - } - if ("step" in session.audioConstraints[i]) { - input.step = session.audioConstraints[i].step; - } - input.type = "range"; - input.dataset.keyname = i; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.keyname + ": " + e.target.value; - //updateAudioConstraints(e.target.dataset.keyname, e.target.value); - applyAudioHack(e.target.dataset.keyname, e.target.value); - }; - - - getById("popupSelector_constraints_audio").appendChild(label); - getById("popupSelector_constraints_audio").appendChild(input); - } else if ((typeof session.audioConstraints[i] === 'object') && (session.audioConstraints[i] !== null)) { - if (i == "resizeMode") { - continue; - } - - var div = document.createElement("div"); - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = i + ":"; - label.style = "display:inline-block; padding:0;margin: 15px 0px 29px;"; - label.dataset.keyname = i; - var input = document.createElement("select"); - var c = document.createElement("option"); - - if (session.audioConstraints[i].length > 1) { - for (var opts in session.audioConstraints[i]) { - log(opts); - var opt = new Option(session.audioConstraints[i][opts], session.audioConstraints[i][opts]); - input.options.add(opt); - - if (i in session.currentAudioConstraints) { - if (session.audioConstraints[i][opts] == session.currentAudioConstraints[i]) { - opt.selected = true; - } - } - - } - } else if (i.toLowerCase == "torch") { - var opt = new Option("Off", false); - input.options.add(opt); - opt = new Option("On", true); - input.options.add(opt); - } else { - continue; - } - - if (getById("popupSelector_constraints_audio").style.display == "none") { - getById("advancedOptionsAudio").style.display = "inline-block"; - } - - input.id = "constraints_" + i; - input.className = "constraintCameraInput"; - input.name = "constraints_" + i; - input.style = "display:inline; padding:2px; margin:0 10px;"; - input.dataset.keyname = i; - input.onchange = function(e) { - //getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value; - //updateAudioConstraints(e.target.dataset.keyname, e.target.value); - applyAudioHack(e.target.dataset.keyname, e.target.value); - log(e.target.dataset.keyname, e.target.value); - }; - getById("popupSelector_constraints_audio").appendChild(div); - div.appendChild(label); - div.appendChild(input); - } else if (typeof session.audioConstraints[i] === 'boolean') { - - var div = document.createElement("div"); - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = i + ":"; - label.style = "display:inline-block; padding:0;margin: 15px 0px 29px;"; - label.dataset.keyname = i; - var input = document.createElement("select"); - var c = document.createElement("option"); - - var opt = new Option("Off", false); - input.options.add(opt); - opt = new Option("On", true); - input.options.add(opt); - - if (getById("popupSelector_constraints_audio").style.display == "none") { - getById("advancedOptionsAudio").style.display = "inline-block"; - } - - input.id = "constraints_" + i; - input.className = "constraintCameraInput"; - input.name = "constraints_" + i; - input.style = "display:inline; padding:2px; margin:0 10px;"; - input.dataset.keyname = i; - input.onchange = function(e) { - //getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value; - //updateAudioConstraints(e.target.dataset.keyname, e.target.value); - applyAudioHack(e.target.dataset.keyname, e.target.value); - log(e.target.dataset.keyname, e.target.value); - }; - getById("popupSelector_constraints_audio").appendChild(div); - div.appendChild(label); - div.appendChild(input); - } - } catch (e) { - errorlog(e); - } - - } -} - - -function applyAudioHack(constraint, value = null) { - if (value == parseFloat(value)) { - value = parseFloat(value); - value = { - exact: value - }; - } else if (value == "true") { - value = true; - } else if (value == "false") { - value = false; - } - log(constraint); - //////////////// - try { - var track0 = session.streamSrc.getAudioTracks(); - if (track0.length) { - track0 = track0[0]; - if (track0.getCapabilities) { - session.audioConstraints = track0.getCapabilities(); - } - log(session.audioConstraints); - } else { - warnlog("session.streamSrc contains no audio tracks"); - return; - } - } catch (e) { - warnlog("session.streamSrc contains no audio tracks"); - errorlog(e); - return; - } - try { - if (track0.getSettings) { - session.currentAudioConstraints = track0.getSettings(); - } - } catch (e) { - errorlog(e); - } - //////// - - var new_constraints = Object.assign(track0.getSettings(), { - [constraint]: value - }, ); - new_constraints = { - audio: new_constraints - , video: false - }; - log(new_constraints); - activatedPreview = false; - enumerateDevices().then(gotDevices2).then(function() { - grabAudio("videosource", "#audioSource3", null, new_constraints); - }); - -} - -function updateAudioConstraints(constraint, value = null) { // this is what it SHOULD be, but this doesn't work yet. - var track0 = session.streamSrc.getAudioTracks(); - track0 = track0[0]; - if (value == parseFloat(value)) { - value = parseFloat(value); - } else if (value == "true") { - value = true; - } else if (value == "false") { - value = false; - } - log({ - advanced: [{ - [constraint]: value - }] - }); - track0.applyConstraints({ - advanced: [{ - [constraint]: value - }] - }); - return; - -} - -function listCameraSettings() { - getById("popupSelector_constraints_video").innerHTML = ""; - - if (session.controlRoomBitrate===true){ - session.controlRoomBitrate = session.totalRoomBitrate; - } - - if (session.roomid && (session.view !== "") && (session.controlRoomBitrate!==false)) { - log("LISTING OPTION FOR BITRATE CONTROL"); - var i = "room video bitrate (kbps)"; - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = i + ":"; - label.title = "If you're on a slow network, you can improve frame rate and audio quality by reducing the amount of video data that others send you"; - - var input = document.createElement("input"); - input.min = 0; - input.max = parseInt(session.totalRoomBitrate); - - if (getById("popupSelector_constraints_video").style.display == "none") { - getById("advancedOptionsCamera").style.display = "inline-block"; - } - - input.value = session.controlRoomBitrate; - label.innerHTML = i + ": " + session.controlRoomBitrate; - - input.type = "range"; - input.dataset.keyname = i; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - input.title = "If you're on a slow network, you can improve frame rate and audio quality by reducing the amount of video data that others send you"; - - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.keyname + ": " + e.target.value; - - if (e.target.value > session.totalRoomBitrate) { - return; - } else { - session.controlRoomBitrate = parseInt(e.target.value); - } - updateMixer(); - }; - - - getById("popupSelector_constraints_video").appendChild(label); - getById("popupSelector_constraints_video").appendChild(input); - - } - try { - var track0 = session.streamSrc.getVideoTracks(); - if (track0.length) { - track0 = track0[0]; - if (track0.getCapabilities) { - session.cameraConstraints = track0.getCapabilities(); - } - log(session.cameraConstraints); - } - } catch (e) { - errorlog(e); - return; - } - - try { - - if (track0.getSettings) { - session.currentCameraConstraints = track0.getSettings(); - } - } catch (e) { - errorlog(e); - } - - for (var i in session.cameraConstraints) { - try { - log(i); - log(session.cameraConstraints[i]); - if ((typeof session.cameraConstraints[i] === 'object') && (session.cameraConstraints[i] !== null) && ("max" in session.cameraConstraints[i]) && ("min" in session.cameraConstraints[i])) { - if (i === "aspectRatio") { - continue; - } else if (i === "width") { - continue; - } else if (i === "height") { - continue; - } else if (i === "frameRate") { - continue; - } - - - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = i + ":"; - - var input = document.createElement("input"); - input.min = session.cameraConstraints[i].min; - input.max = session.cameraConstraints[i].max; - - if (parseFloat(input.min) == parseFloat(input.max)) { - continue; - } - - if (getById("popupSelector_constraints_video").style.display == "none") { - getById("advancedOptionsCamera").style.display = "inline-block"; - } - - if (i in session.currentCameraConstraints) { - input.value = session.currentCameraConstraints[i]; - label.innerHTML = i + ": " + session.currentCameraConstraints[i]; - label.title = "Previously was: " + session.currentCameraConstraints[i]; - input.title = "Previously was: " + session.currentCameraConstraints[i]; - } else { - label.innerHTML = i; - } - if ("step" in session.cameraConstraints[i]) { - input.step = session.cameraConstraints[i].step; - } - input.type = "range"; - input.dataset.keyname = i; - input.id = "constraints_" + i; - input.style = "display:block; width:100%;"; - input.name = "constraints_" + i; - - - input.onchange = function(e) { - getById("label_" + e.target.dataset.keyname).innerHTML = e.target.dataset.keyname + ": " + e.target.value; - updateCameraConstraints(e.target.dataset.keyname, e.target.value); - }; - - - getById("popupSelector_constraints_video").appendChild(label); - getById("popupSelector_constraints_video").appendChild(input); - } else if ((typeof session.cameraConstraints[i] === 'object') && (session.cameraConstraints[i] !== null)) { - if (i == "resizeMode") { - continue; - } - - var div = document.createElement("div"); - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = i + ":"; - label.style = "display:inline-block; padding:0;margin: 15px 0px 29px;"; - label.dataset.keyname = i; - var input = document.createElement("select"); - var c = document.createElement("option"); - - if (session.cameraConstraints[i].length > 1) { - for (var opts in session.cameraConstraints[i]) { - log(opts); - var opt = new Option(session.cameraConstraints[i][opts], session.cameraConstraints[i][opts]); - input.options.add(opt); - if (i in session.currentCameraConstraints) { - if (session.cameraConstraints[i][opts] == session.currentCameraConstraints[i]) { - opt.selected = true; - } - } - } - } else if (i.toLowerCase == "torch") { - var opt = new Option("Off", false); - input.options.add(opt); - opt = new Option("On", true); - input.options.add(opt); - } else { - continue; - } - - if (getById("popupSelector_constraints_video").style.display == "none") { - getById("advancedOptionsCamera").style.display = "inline-block"; - } - - input.id = "constraints_" + i; - input.className = "constraintCameraInput"; - input.name = "constraints_" + i; - input.style = "display:inline; padding:2px; margin:0 10px;"; - input.dataset.keyname = i; - input.onchange = function(e) { - //getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value; - updateCameraConstraints(e.target.dataset.keyname, e.target.value); - log(e.target.dataset.keyname, e.target.value); - }; - getById("popupSelector_constraints_video").appendChild(div); - div.appendChild(label); - div.appendChild(input); - } else if (typeof session.cameraConstraints[i] === 'boolean') { - - var div = document.createElement("div"); - var label = document.createElement("label"); - label.id = "label_" + i; - label.htmlFor = "constraints_" + i; - label.innerHTML = i + ":"; - label.style = "display:inline-block; padding:0;margin: 15px 0px 29px;"; - label.dataset.keyname = i; - var input = document.createElement("select"); - var c = document.createElement("option"); - - var opt = new Option("Off", false); - input.options.add(opt); - opt = new Option("On", true); - input.options.add(opt); - - if (getById("popupSelector_constraints_video").style.display == "none") { - getById("advancedOptionsCamera").style.display = "inline-block"; - } - - input.id = "constraints_" + i; - input.className = "constraintCameraInput"; - input.name = "constraints_" + i; - input.style = "display:inline; padding:2px; margin:0 10px;"; - input.dataset.keyname = i; - input.onchange = function(e) { - //getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value; - updateCameraConstraints(e.target.dataset.keyname, e.target.value); - log(e.target.dataset.keyname, e.target.value); - }; - getById("popupSelector_constraints_video").appendChild(div); - div.appendChild(label); - div.appendChild(input); - } - } catch (e) { - errorlog(e); - } - - } -} - -function updateCameraConstraints(constraint, value = null) { - var track0 = session.streamSrc.getVideoTracks(); - track0 = track0[0]; - if (value == parseFloat(value)) { - value = parseFloat(value); - } else if (value == "true") { - value = true; - } else if (value == "false") { - value = false; - } - log({ - advanced: [{ - [constraint]: value - }] - }); - track0.applyConstraints({ - advanced: [{ - [constraint]: value - }] - }); - return; - -} - -function setupWebcamSelection(stream = null) { - log("setup webcam"); - - if (stream) { - log(getById("previewWebcam")); - session.streamSrc = stream; - getById("previewWebcam").srcObject = outboundAudioPipeline(session.streamSrc); - } else { - log("THIS IS NO STREAM??"); - } - - if (!session.videoElement) { - session.videoElement = getById("previewWebcam"); - } - - try { - return enumerateDevices().then(gotDevices).then(function() { - - if (getById("webcamquality").elements && parseInt(getById("webcamquality").elements.namedItem("resolution").value) == 3) { - if (session.maxframerate===false){ - session.maxframerate = 30; - session.maxframerate_q2 = true; - } - } else if (session.maxframerate_q2){ - session.maxframerate = false; - session.maxframerate_q2 = false; - } - - var audioSelect = getById('audioSource'); - var videoSelect = getById('videoSourceSelect'); - var outputSelect = getById('outputSource'); - - audioSelect.onchange = function() { - - var gowebcam = getById("gowebcam"); - if (gowebcam) { - gowebcam.disabled = true; - gowebcam.dataset.ready = "true"; - gowebcam.style.backgroundColor = "#DDDDDD"; - gowebcam.style.fontWeight = "normal"; - gowebcam.innerHTML = "Waiting for Camera to load"; - miniTranslate(gowebcam, "waiting-for-camera-to-load"); - } - activatedPreview = false; - grabAudio(); - }; - videoSelect.onchange = function() { - - var gowebcam = getById("gowebcam"); - if (gowebcam) { - gowebcam.disabled = true; - gowebcam.dataset.ready = "true"; - gowebcam.style.backgroundColor = "#DDDDDD"; - gowebcam.style.fontWeight = "normal"; - gowebcam.innerHTML = "Waiting for Camera to load"; - miniTranslate(gowebcam, "waiting-for-camera-to-load"); - } - warnlog("video source changed"); - - activatedPreview = false; - if (session.quality !== false) { - grabVideo(session.quality); - } else { - session.quality_wb = parseInt(getById("webcamquality").elements.namedItem("resolution").value); - grabVideo(session.quality_wb); - } - }; - - outputSelect.onchange = function() { - - if ((iOS) || (iPad)) { - return; - } - try{ - session.sink = outputSelect.options[outputSelect.selectedIndex].value; - } catch(e){errorlog(e);} - - if (!session.sink){return;} - - try{ - getById("previewWebcam").setSinkId(session.sink).then(() => { - log("New Output Device:" + session.sink); - }).catch(error => { - errorlog("6597"); - errorlog(error); - //setTimeout(function(){warnUser("Failed to change audio output destination.");},1); - }); - } catch(e){errorlog(e);} - } - - getById("webcamquality").onchange = function() { - var gowebcam = getById("gowebcam"); - if (gowebcam) { - gowebcam.disabled = true; - gowebcam.dataset.ready = "true"; - gowebcam.style.backgroundColor = "#DDDDDD"; - gowebcam.style.fontWeight = "normal"; - gowebcam.innerHTML = "Waiting for Camera to load"; - miniTranslate(gowebcam, "waiting-for-camera-to-load"); - } - - if (parseInt(getById("webcamquality").elements.namedItem("resolution").value) == 2) { - if (session.maxframerate===false){ - session.maxframerate = 30; - session.maxframerate_q2 = true; - } - } else if (session.maxframerate_q2){ - session.maxframerate = false; - session.maxframerate_q2 = false; - } - - activatedPreview = false; - session.quality_wb = parseInt(getById("webcamquality").elements.namedItem("resolution").value); - grabVideo(session.quality_wb); - }; - - if (session.audioDevice!==0) { // change from Auto to Selected Audio Device - log("SETTING AUDIO DEVICE!!"); - activatedPreview = false; - grabAudio(); - } - - if (session.videoDevice === 0) { - if (session.autostart) { - publishWebcam(); // no need to mirror as there is no video... - return; - } else { - var gowebcam = getById("gowebcam"); - if (gowebcam) { - gowebcam.disabled = false; - gowebcam.dataset.ready = "true"; - gowebcam.innerHTML = "START"; - miniTranslate(gowebcam, "start"); - } - return; + url += '&layer-width=' + video.videoWidth; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough + url += '&layer-height=' + video.videoHeight; } } else { - log("GRabbing video: " + session.quality); - activatedPreview = false; - if (session.quality !== false) { - grabVideo(session.quality); - } else { - session.quality_wb = parseInt(getById("webcamquality").elements.namedItem("resolution").value); - grabVideo(session.quality_wb); - } - } - - if ((iOS) || (iPad)) { - return; - } - try { - if (outputSelect.selectedIndex >= 0) { - session.sink = outputSelect.options[outputSelect.selectedIndex].value; - } - } catch(e){errorlog(e);} - - if (document.getElementById("previewWebcam") && document.getElementById("previewWebcam").setSinkId) { - if (session.sink) { - getById("previewWebcam").setSinkId(session.sink).then(() => {}).catch(error => { - warnlog("6665"); - warnlog(error); - }); - } - } - - }).catch(e => { - errorlog(e); - }); - } catch (e) { - errorlog(e); - } -} - -Promise.wait = function(ms) { - return new Promise(function(resolve) { - setTimeout(resolve, ms); - }); -}; - -Promise.prototype.timeout = function(ms) { - return Promise.race([ - this, Promise.wait(ms).then(function() { - var errormsg = new Error("Time Out\nDid you accept camera permissions in time? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling it.\n\nPlease also ensure your camera and audio device are correctly connected and not already in use. You may also need to refresh the page."); - errormsg.name = "timedOut"; - errormsg.message = "Time Out\nDid you accept camera permissions in time? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling it.\n\nPlease also ensure your camera and audio device are correctly connected and not already in use. You may also need to refresh the page." - throw errormsg; - - }) - ]) -}; - - -function shareWebsite(autostart=false){ - if (session.iframeSrc){ - session.iframeSrc = false; - - if (session.director){ - setStorage("directorWebsiteShare", {"website":session.iframeSrc, "roomid":session.roomid}); - } - getById("websitesharetoggle").classList.add("la-window-maximize"); - getById("websitesharetoggle").classList.remove("la-window-close"); - - getById("websitesharebutton").classList.remove("float2"); - getById("websitesharebutton").classList.add("float"); - - var data = {}; - data.iframeSrc = false; - for (var UUID in session.pcs){ - if (session.pcs[UUID].allowIframe===true){ - session.sendMessage(data, UUID); - } - } - return - } - if (autostart===false){ - window.focus(); - var iframeURL = prompt("Enter a website URL to share", "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); - } else { - var iframeURL = autostart; - } - if (!iframeURL){ - return; - } - if (iframeURL == session.iframeSrc){return;} - - if (!(iframeURL.startsWith("https://") || iframeURL.startsWith("http://"))){ - iframeURL = "https://"+iframeURL; - } - - var domain = new URL(iframeURL); - domain = domain.hostname; - log(domain); - if ((domain=="www.youtube.com") || (domain=="youtube.com")){ - var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; - var match = iframeURL.match(regExp); - var vidid = (match&&match[7].length==11)? match[7] : false; - - if(vidid){ - iframeURL = "https://www.youtube.com/embed/"+vidid+"?autoplay=1&modestbranding=1"; - log(iframeURL); - } - } else if (domain=="www.twitch.tv"){ - var vidid = iframeURL.split('/').pop().split('#')[0].split('?')[0]; - if (vidid){ - iframeURL = "https://player.twitch.tv/?channel="+vidid+"&parent="+location.hostname; - log(iframeURL); - } - } else if (domain=="twitch.tv"){ - var vidid = iframeURL.split('/').pop().split('#')[0].split('?')[0]; - if (vidid){ - iframeURL = "https://player.twitch.tv/?channel="+vidid+"&parent="+location.hostname; - log(iframeURL); - } - } - - session.iframeSrc = iframeURL; - if (session.director){ - setStorage("directorWebsiteShare", {"website":session.iframeSrc, "roomid":session.roomid}); - } - getById("websitesharetoggle").classList.remove("la-window-maximize"); - getById("websitesharetoggle").classList.add("la-window-close"); - - getById("websitesharebutton").classList.add("float2"); - getById("websitesharebutton").classList.remove("float"); - - var data = {}; - data.iframeSrc = iframeURL; - for (var UUID in session.pcs){ - if (session.pcs[UUID].allowIframe===true){ - session.sendMessage(data, UUID); - } - } -} - -function createIframePopup() { - - if (session.screenShareElement) { - session.screenShareElement.contentWindow.postMessage({ - "close": true - }, '*'); - session.screenShareElement.parentNode.removeChild(session.screenShareElement); - session.screenShareElement = false; - updateMixer(); - getById("screenshare2button").classList.add("float"); - getById("screenshare2button").classList.remove("float2"); - return; - } - - if (session.queue || session.transferred){ - getById("screenshare2button").classList.add("advanced"); - getById("screensharebutton").classList.remove("advanced"); - toggleScreenShare(); - return; - } // can't secondary-screen share if in a queue. - - if (session.screenshareid) { - var iFrameID = session.screenshareid; - } else { - var iFrameID = session.streamID.substring(0, 12) + "_" + session.generateStreamID(5); - } - - if (session.exclude) { - session.exclude.push(iFrameID); - } else { - session.exclude = []; - session.exclude.push(iFrameID); - } - - var iframe = document.createElement("iframe"); - iframe.allow = "autoplay;camera;microphone;fullscreen;picture-in-picture;transparency;"; - iframe.allowtransparency = "true"; - - var extras = ""; - if (session.password){ - extras += "&password=" + session.password; // encodeURIComponent( - } - - if (session.privacy){ - extras += "&privacy"; - } - - if (session.screensharequality!==false){ - extras += "&q="+session.screensharequality; - } else if (session.quality){ - extras += "&q="+session.quality; - } else { - extras += "&q=0"; - } - - if (session.screensharefps!==false){ - extras += "&maxframerate="+session.screensharefps; - } - - if (session.muted){ - iframe.src = "./?audiodevice=1&screenshare&transparent&cleanish&noheader&autostart&view&muted&room=" + session.roomid + "&push=" + iFrameID + extras; - } else { - iframe.src = "./?audiodevice=1&screenshare&transparent&cleanish&noheader&autostart&view&room=" + session.roomid + "&push=" + iFrameID + extras; - } - - iframe.style.width = "100%"; - iframe.style.height = "100%"; - iframe.style.overflow = "hidden"; - iframe.id = "screensharesource"; - iframe.style.zIndex = "0"; - - - session.screenShareElement = iframe; - session.screenShareElement.dataset.doNotMove = true; - - - document.getElementById("main").appendChild(iframe); - - - updateMixer(); - getById("screenshare2button").classList.add("float2"); - getById("screenshare2button").classList.remove("float"); - - return; // ignore the rest. -} - -function previewWebcam() { - - if (session.taintedSession === null) { - log("STILL WAITING ON HASH TO VALIDATE"); - setTimeout(function() { - previewWebcam(); - }, 1000); - return; - } else if (session.taintedSession === true) { - warnlog("HASH FAILED; PASSWORD NOT VALID"); - return; - } else { - log("NOT TAINTED"); - } - - if (activatedPreview == true) { - log("activeated preview return 1"); - return; - } - activatedPreview = true; - - if (session.audioDevice === 0) { // OFF - var constraint = { - audio: false - }; - } else if ((session.echoCancellation !== false) && (session.autoGainControl !== false) && (session.noiseSuppression !== false)) { // AUTO - var constraint = { - audio: true - }; - } else { // Disable Echo Cancellation and stuff for the PREVIEW (DEFAULT CAM/MIC) - var constraint = { - audio: {} - }; - if (session.echoCancellation !== false) { // if not disabled, we assume it's on - constraint.audio.echoCancellation = true; - } else { - constraint.audio.echoCancellation = false; - } - if (session.autoGainControl !== false) { - constraint.audio.autoGainControl = true; - } else { - constraint.audio.autoGainControl = false; - } - if (session.noiseSuppression !== false) { - constraint.audio.noiseSuppression = true; - } else { - constraint.audio.noiseSuppression = false; - } - } - - if (session.videoDevice === 0) { - constraint.video = false; - } else { - constraint.video = true; - } - - if ((constraint.video === false) && (constraint.audio === false)){ - - if (session.autostart) { - publishWebcam(); // no need to mirror as there is no video... - return; - } else { - var gowebcam = document.getElementById("gowebcam"); - getById("getPermissions").style.display = "none"; - if (gowebcam) { - gowebcam.style.display = ""; - gowebcam.disabled = false; - gowebcam.dataset.ready = "true"; - gowebcam.innerHTML = "START"; - miniTranslate(gowebcam, "start"); - } - } - return; - } - - enumerateDevices().then(function(devices) { - log("enumeratated"); - log(devices); - var vtrue = false; - var atrue = false; - devices.forEach(function(device) { - if (device.kind === 'audioinput') { - atrue = true; - } else if (device.kind === 'videoinput') { - vtrue = true; - } - }); - if (atrue === false) { - constraint.audio = false; - } - if (vtrue === false) { - constraint.video = false; - } - setTimeout(function(constraint) { - requestBasicPermissions(constraint); - }, 0, constraint); - }).catch((error) => { - log("enumeratated failed. Seeking permissions."); - setTimeout(function(constraint) { - requestBasicPermissions(constraint); - }, 0, constraint); - }); - -} - -function requestBasicPermissions(constraint = { - video: true - , audio: true -}) { - if (session.taintedSession === null) { - log("STILL WAITING ON HASH TO VALIDATE"); - setTimeout(function(constraint) { - requestBasicPermissions(constraint); - }, 1000, constraint); - return; - } else if (session.taintedSession === true) { - warnlog("HASH FAILED; PASSWORD NOT VALID"); - return; - } else { - log("NOT TAINTED 1"); - } - setTimeout(function() { - getById("getPermissions").style.display = "none"; - getById("gowebcam").style.display = ""; - }, 0); - log("REQUESTING BASIC PERMISSIONS"); - - try { - var timerBasicCheck = null; - if (!(session.cleanOutput)) { - log("Setting Timer for getUserMedia"); - timerBasicCheck = setTimeout(function() { - if (!(session.cleanOutput)) { - warnUser("Camera Access Request Timed Out\nDid you accept camera permissions? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling NDI tools.\n\nPlease also ensure that your camera and audio devices are correctly connected and not already in use. You may also need to refresh the page."); - } - }, 10000); - } - - if (session.audioInputChannels) { - if (constraint.audio === true) { - constraint.audio = {}; - constraint.audio.channelCount = session.audioInputChannels; - } else if (constraint.audio) { - constraint.audio.channelCount = session.audioInputChannels; - } - } - - log("CONSTRAINT"); - log(constraint); - navigator.mediaDevices.getUserMedia(constraint).then(function(stream) { // Apple needs thi to happen before I can access EnumerateDevices. - log("got first stream"); - clearTimeout(timerBasicCheck); - setupWebcamSelection(stream); - }).catch(function(err) { - clearTimeout(timerBasicCheck); - warnlog("some error with GetUSERMEDIA"); - errorlog(err); /* handle the error */ - if (err.name == "NotFoundError" || err.name == "DevicesNotFoundError") { - //required track is missing - } else if (err.name == "NotReadableError" || err.name == "TrackStartError") { - //webcam or mic are already in use - } else if (err.name == "OverconstrainedError" || err.name == "ConstraintNotSatisfiedError") { - //constraints can not be satisfied by avb. devices - } else if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") { - //permission denied in browser - if (!(session.cleanOutput)) { - setTimeout(function() { - warnUser("Permissions denied. Please ensure you have allowed the mic/camera permissions."); - }, 1); - } - return; - } else if (err.name == "TypeError" || err.name == "TypeError") { - //empty constraints object - } else { - //permission denied in browser - if (!(session.cleanOutput)) { - setTimeout(function() { - warnUser(err); - }, 1); - } - } - errorlog("trying to list webcam again"); - setupWebcamSelection(); - }); - } catch (e) { - errorlog(e); - if (!(session.cleanOutput)) { - if (window.isSecureContext) { - warnUser("An error has occured when trying to access the webcam or microphone. The reason is not known."); - } else if ((iOS) || (iPad)) { - warnUser("iOS version 13.4 and up is generally recommended; older than iOS 11 is not supported."); - } else { - warnUser("Error acessing camera or microphone.\n\nThe website may be loaded in an insecure context.\n\nPlease see: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia"); - } - } - } -} - - -function copyFunction(copyText) { - - try { - copyText.select(); - copyText.setSelectionRange(0, 99999); - document.execCommand("copy"); - } catch (e) { - var dummy = document.createElement('input'); - document.body.appendChild(dummy); - dummy.value = copyText; - dummy.select(); - document.execCommand('copy'); - document.body.removeChild(dummy); - return false; - } -} - -function generateQRPage() { - var pass = sanitizePassword(getById("invite_password").value); - if (pass.length) { - return session.generateHash(pass + session.salt, 4).then(function(hash) { - generateQRPageCallback(hash); - }); - } else { - generateQRPageCallback(""); - } -} - -function updateLinkWebP(arg, input) { - if (input.checked){ - if (!((getById("director_block_" + arg).dataset.raw.includes("&broadcast")) || (getById("director_block_" + arg).dataset.raw.includes("?broadcast")))){ - getById("broadcastSlider").checked=true; - updateLink(arg, getById("broadcastSlider")); - } - } - updateLink(arg, input); -} - -function updateLink(arg, input) { - log("updateLink"); - log(input.dataset.param); - if (input.checked) { - - getById("director_block_" + arg).dataset.raw += input.dataset.param; - - var string = getById("director_block_" + arg).dataset.raw; - - if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { - string = obfuscateURL(string); - } - - getById("director_block_" + arg).href = string; - getById("director_block_" + arg).innerText = string; - } else { - var string = getById("director_block_" + arg).dataset.raw + "&"; - string = string.replace(input.dataset.param + "&", "&"); - string = string.substring(0, string.length - 1); - getById("director_block_" + arg).dataset.raw = string; - - if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { - string = obfuscateURL(string); - } - - getById("director_block_" + arg).href = string; - getById("director_block_" + arg).innerText = string; - } - saveDirectorSettings(); -} - - -function updateLinkInverse(arg, input) { - log("updateLinkInverse"); - log(input.dataset.param); - if (!(input.checked)) { - - getById("director_block_" + arg).dataset.raw += input.dataset.param; - - var string = getById("director_block_" + arg).dataset.raw; - - if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { - string = obfuscateURL(string); - } - - - getById("director_block_" + arg).href = string; - getById("director_block_" + arg).innerText = string; - } else { - var string = getById("director_block_" + arg).dataset.raw + "&"; - string = string.replace(input.dataset.param + "&", "&"); - string = string.substring(0, string.length - 1); - getById("director_block_" + arg).dataset.raw = string; - - if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { - string = obfuscateURL(string); - } - - getById("director_block_" + arg).href = string; - getById("director_block_" + arg).innerText = string; - } -} - -function updateLinkScene(arg, input) { - log("updateLinkScene"); - var string = getById("director_block_" + arg).dataset.raw; - - if (input.checked) { - string = changeParam(string, "scene", "0"); - } else { - string = changeParam(string, "scene", "1"); - } - getById("director_block_" + arg).dataset.raw = string; - - if ((arg==1) && (getById("obfuscate_director_" + arg).checked)) { - string = obfuscateURL(string); - } - - getById("director_block_" + arg).href = string; - getById("director_block_" + arg).innerText = string; -} - -function resetGen() { - getById("gencontent").style.display = "block"; - getById("gencontent2").style.display = "none"; - getById("gencontent2").className = ""; //container-inner - getById("gencontent").className = "container-inner"; // - getById("gencontent2").innerHTML = ""; - getById("videoname4").focus(); -} - -function generateQRPageCallback(hash) { - try { - var title = getById("videoname4").value; - if (title.length) { - title = title.replace(/[\W]+/g, "_").replace(/_+/g, '_'); // but not what others might get. - title = "&label=" + title; - } - var sid = session.generateStreamID(); - - var viewstr = ""; - var sendstr = ""; - - if (getById("invite_bitrate").checked) { - viewstr += "&bitrate=20000"; - } - if (getById("invite_vp9").checked) { - viewstr += "&codec=vp9"; - } - if (getById("invite_stereo").checked) { - viewstr += "&stereo"; - sendstr += "&stereo"; - } - if (getById("invite_automic").checked) { - sendstr += "&audiodevice=1"; - } - if (getById("invite_hidescreen").checked) { - sendstr += "&webcam"; - } - - if (getById("invite_remotecontrol").checked) { // - var remote_gen_id = session.generateStreamID(); - sendstr += "&remote=" + remote_gen_id; // security - viewstr += "&remote=" + remote_gen_id; - } - - if (getById("invite_joinroom").value.trim().length) { - sendstr += "&room=" + getById("invite_joinroom").value.trim(); - viewstr += "&scene&room=" + getById("invite_joinroom").value.trim(); - } - - if (getById("invite_password").value.trim().length) { - sendstr += "&hash=" + hash; - viewstr += "&password=" + getById("invite_password").value.trim(); - } - - - if (getById("invite_group_chat_type").value) { // 0 is default - if (getById("invite_group_chat_type").value == 1) { // no video - sendstr += "&novideo"; - } else if (getById("invite_group_chat_type").value == 2) { // no view or audio - sendstr += "&view"; - } - } - - if (getById("invite_quality").value) { - if (getById("invite_quality").value == 0) { - sendstr += "&quality=0"; - } else if (getById("invite_quality").value == 1) { - sendstr += "&quality=1"; - } else if (getById("invite_quality").value == 2) { - sendstr += "&quality=2"; - } - } - - var pie = ""; - if (session.pie){ - if (session.pie!==true){ - pie = "&pie="+session.pie; - } - } - - sendstr = 'https://' + location.host + location.pathname + '?push=' + sid + sendstr + title + pie; - - if (getById("invite_obfuscate").checked) { - sendstr = obfuscateURL(sendstr); - } - - viewstr = 'https://' + location.host + location.pathname + '?view=' + sid + viewstr + title + pie; - getById("gencontent").style.display = "none"; - getById("gencontent").className = ""; // - getById("gencontent2").style.display = "block"; - getById("gencontent2").className = "container-inner"; // - getById("gencontent2").innerHTML = '
\ -

Guest Invite Link:

\ - ' + sendstr + '

\ -

and don\'t forget the

OBS Browser Source Link:

' + viewstr + ' \ -

\ - This invite link and OBS ingestion link are reusable. Only one person may use a specific invite at a time.

'; - var qrcode = new QRCode(getById("qrcode"), { - width: 300 - , height: 300 - , colorDark: "#000000" - , colorLight: "#FFFFFF" - , useSVG: false - }); - qrcode.makeCode(sendstr); - setTimeout(function() { - getById("qrcode").title = ""; - if (getById("qrcode").getElementsByTagName('img').length) { - getById("qrcode").getElementsByTagName('img')[0].style.cursor = "none"; - } - }, 100); // i really hate the title overlay that the qrcode function makes - - } catch (e) { - errorlog(e); - } -} - - -if (session.view) { - getById("main").className = ""; - getById("credits").style.display = 'none'; - try { - if (session.label === false) { - if (document.title == "") { - document.title = "View=" + session.view.toString(); - } else { - document.title += ", View=" + session.view.toString(); - } - } - } catch (e) { - errorlog(e); - }; -} - - -function initSceneList(UUID){ - Object.keys(session.sceneList).forEach((scene, index) => { - if (getById("container_" + UUID).querySelectorAll('[data-scene="'+scene+'"]').length){return;} // already exists. - var newScene = document.createElement("div"); - newScene.innerHTML = ''; - getById("container_" + UUID).appendChild(newScene); - }); -} - -function updateSceneList(scene){ - if (!session.director){return;} - if (scene in session.sceneList){return;} - if ((parseInt(scene)+"")===scene){ - if ((parseInt(scene)>=0) && (parseInt(scene)<=8)){ - return; - } - } - session.sceneList[scene] = true; - for (var UUID in session.rpcs){ - var newScene = document.createElement("span"); - newScene.innerHTML = ''; - getById("container_" + UUID).appendChild(newScene); - } - - if (session.showDirector){ - if (document.getElementById("container_director")){ - var newScene = document.createElement("div"); - newScene.innerHTML = ''; - getById("container_director").appendChild(newScene); - } - } -} - -function safariVersion() { - try { - var ver = navigator.appVersion.split("Version/"); - if (ver.length > 1) { - ver = ver[1].split(" Safari"); - } - if (ver.length > 1) { - ver = ver[0].split("."); - } - if (ver.length > 1) { - ver = parseInt(ver[0]); - } else { - ver = 0; - } - } catch (e) { - return 0; - } - return ver; -} - -if ((session.view) && (session.roomid === false)) { - getById("container-4").className = 'column columnfade'; - getById("container-3").className = 'column columnfade'; - getById("container-2").className = 'column columnfade'; - getById("container-1").className = 'column columnfade'; - //getById("header").className = 'advanced'; - getById("info").className = 'advanced'; - getById("header").className = 'advanced'; - getById("head1").className = 'advanced'; - getById("head2").className = 'advanced'; - getById("head3").className = 'advanced'; - - - getById("mainmenu").style.backgroundRepeat = "no-repeat"; - getById("mainmenu").style.backgroundPosition = "bottom center"; - getById("mainmenu").style.minHeight = "300px"; - getById("mainmenu").style.backgroundSize = "100px 100px"; - getById("mainmenu").innerHTML = ''; - - setTimeout(function() { - try { - if ((session.view) && (!(session.cleanOutput))) { - if (document.getElementById("mainmenu")) { - getById("mainmenu").style.backgroundImage = "url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZpZXdCb3g9IjAgMCA0MCA0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7IiB4PSIwcHgiIHk9IjBweCI+CiAgICA8ZGVmcz4KICAgICAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhW0NEQVRBWwogICAgICAgICAgICBALXdlYmtpdC1rZXlmcmFtZXMgc3BpbiB7CiAgICAgICAgICAgICAgZnJvbSB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoLTM1OWRlZykKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQGtleWZyYW1lcyBzcGluIHsKICAgICAgICAgICAgICBmcm9tIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKC0zNTlkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHN2ZyB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7CiAgICAgICAgICAgICAgICAtd2Via2l0LWFuaW1hdGlvbjogc3BpbiAxLjVzIGxpbmVhciBpbmZpbml0ZTsKICAgICAgICAgICAgICAgIC13ZWJraXQtYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuOwogICAgICAgICAgICAgICAgYW5pbWF0aW9uOiBzcGluIDEuNXMgbGluZWFyIGluZmluaXRlOwogICAgICAgICAgICB9CiAgICAgICAgXV0+PC9zdHlsZT4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJvdXRlciI+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwwQzIyLjIwNTgsMCAyMy45OTM5LDEuNzg4MTMgMjMuOTkzOSwzLjk5MzlDMjMuOTkzOSw2LjE5OTY4IDIyLjIwNTgsNy45ODc4MSAyMCw3Ljk4NzgxQzE3Ljc5NDIsNy45ODc4MSAxNi4wMDYxLDYuMTk5NjggMTYuMDA2MSwzLjk5MzlDMTYuMDA2MSwxLjc4ODEzIDE3Ljc5NDIsMCAyMCwwWiIgc3R5bGU9ImZpbGw6YmxhY2s7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNNS44NTc4Niw1Ljg1Nzg2QzcuNDE3NTgsNC4yOTgxNSA5Ljk0NjM4LDQuMjk4MTUgMTEuNTA2MSw1Ljg1Nzg2QzEzLjA2NTgsNy40MTc1OCAxMy4wNjU4LDkuOTQ2MzggMTEuNTA2MSwxMS41MDYxQzkuOTQ2MzgsMTMuMDY1OCA3LjQxNzU4LDEzLjA2NTggNS44NTc4NiwxMS41MDYxQzQuMjk4MTUsOS45NDYzOCA0LjI5ODE1LDcuNDE3NTggNS44NTc4Niw1Ljg1Nzg2WiIgc3R5bGU9ImZpbGw6cmdiKDIxMCwyMTAsMjEwKTsiLz4KICAgICAgICA8L2c+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwzMi4wMTIyQzIyLjIwNTgsMzIuMDEyMiAyMy45OTM5LDMzLjgwMDMgMjMuOTkzOSwzNi4wMDYxQzIzLjk5MzksMzguMjExOSAyMi4yMDU4LDQwIDIwLDQwQzE3Ljc5NDIsNDAgMTYuMDA2MSwzOC4yMTE5IDE2LjAwNjEsMzYuMDA2MUMxNi4wMDYxLDMzLjgwMDMgMTcuNzk0MiwzMi4wMTIyIDIwLDMyLjAxMjJaIiBzdHlsZT0iZmlsbDpyZ2IoMTMwLDEzMCwxMzApOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksMjguNDkzOUMzMC4wNTM2LDI2LjkzNDIgMzIuNTgyNCwyNi45MzQyIDM0LjE0MjEsMjguNDkzOUMzNS43MDE5LDMwLjA1MzYgMzUuNzAxOSwzMi41ODI0IDM0LjE0MjEsMzQuMTQyMUMzMi41ODI0LDM1LjcwMTkgMzAuMDUzNiwzNS43MDE5IDI4LjQ5MzksMzQuMTQyMUMyNi45MzQyLDMyLjU4MjQgMjYuOTM0MiwzMC4wNTM2IDI4LjQ5MzksMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxMDEsMTAxLDEwMSk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMy45OTM5LDE2LjAwNjFDNi4xOTk2OCwxNi4wMDYxIDcuOTg3ODEsMTcuNzk0MiA3Ljk4NzgxLDIwQzcuOTg3ODEsMjIuMjA1OCA2LjE5OTY4LDIzLjk5MzkgMy45OTM5LDIzLjk5MzlDMS43ODgxMywyMy45OTM5IDAsMjIuMjA1OCAwLDIwQzAsMTcuNzk0MiAxLjc4ODEzLDE2LjAwNjEgMy45OTM5LDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoMTg3LDE4NywxODcpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTUuODU3ODYsMjguNDkzOUM3LjQxNzU4LDI2LjkzNDIgOS45NDYzOCwyNi45MzQyIDExLjUwNjEsMjguNDkzOUMxMy4wNjU4LDMwLjA1MzYgMTMuMDY1OCwzMi41ODI0IDExLjUwNjEsMzQuMTQyMUM5Ljk0NjM4LDM1LjcwMTkgNy40MTc1OCwzNS43MDE5IDUuODU3ODYsMzQuMTQyMUM0LjI5ODE1LDMyLjU4MjQgNC4yOTgxNSwzMC4wNTM2IDUuODU3ODYsMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxNjQsMTY0LDE2NCk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMzYuMDA2MSwxNi4wMDYxQzM4LjIxMTksMTYuMDA2MSA0MCwxNy43OTQyIDQwLDIwQzQwLDIyLjIwNTggMzguMjExOSwyMy45OTM5IDM2LjAwNjEsMjMuOTkzOUMzMy44MDAzLDIzLjk5MzkgMzIuMDEyMiwyMi4yMDU4IDMyLjAxMjIsMjBDMzIuMDEyMiwxNy43OTQyIDMzLjgwMDMsMTYuMDA2MSAzNi4wMDYxLDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoNzQsNzQsNzQpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksNS44NTc4NkMzMC4wNTM2LDQuMjk4MTUgMzIuNTgyNCw0LjI5ODE1IDM0LjE0MjEsNS44NTc4NkMzNS43MDE5LDcuNDE3NTggMzUuNzAxOSw5Ljk0NjM4IDM0LjE0MjEsMTEuNTA2MUMzMi41ODI0LDEzLjA2NTggMzAuMDUzNiwxMy4wNjU4IDI4LjQ5MzksMTEuNTA2MUMyNi45MzQyLDkuOTQ2MzggMjYuOTM0Miw3LjQxNzU4IDI4LjQ5MzksNS44NTc4NloiIHN0eWxlPSJmaWxsOnJnYig1MCw1MCw1MCk7Ii8+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4K')"; - getById("mainmenu").innerHTML = '

Attempting to load video stream.

'; - getById("mainmenu").innerHTML += 'The stream is not available yet or an error occured.

'; - - } - } - } catch (e) { - errorlog("Error handling QR Code failure"); - } - }, 15000); - - log("auto playing"); - var SafariVer = safariVersion(); - if ((iPad || iOS) && navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1 && SafariVer > 13) { // Modern iOS doesn't need pop up - play(); - } else if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) { // Safari on Desktop does require pop up - if (!(session.cleanOutput)) { - warnUser("Safari requires us to ask for an audio permission to use peer-to-peer technology. You will need to accept it in a moment if asked to view this live video", 20000); - } - navigator.mediaDevices.getUserMedia({ - audio: true - }).then(function() { - closeModal(); - play(); - }).catch(function() { - play(); - }); - } else { // everything else is OK. - play(); - } -} else if (session.roomid) { - try { - if (session.label === false) { - if (document.title == "") { - document.title = "Room=" + session.roomid.toString(); - } else { - document.title += ": " + session.roomid.toString(); - } - } - } catch (e) { - errorlog(e); - }; - -} - - -var vis = (function() { - var stateKey, eventKey, keys = { - hidden: "visibilitychange" - , webkitHidden: "webkitvisibilitychange" - , mozHidden: "mozvisibilitychange" - , msHidden: "msvisibilitychange" - }; - for (stateKey in keys) { - if (stateKey in document) { - eventKey = keys[stateKey]; - break; - } - } - return function(c) { - if (c) { - document.addEventListener(eventKey, c); - //document.addEventListener("blur", c); - //document.addEventListener("focus", c); - } - return !document[stateKey]; - }; -})(); - -(function rightclickmenuthing() { // right click menu - "use strict"; - - function clickInsideElement(e, className) { - var el = e.srcElement || e.target; - - if (el.classList.contains(className)) { - return el; - } else { - while (el = el.parentNode) { - if (el.classList && el.classList.contains(className)) { - return el; - } - } - } - - return false; - } - - function getPosition(event2) { - var posx = 0; - var posy = 0; - - if (!event2) var event = window.event; - - if (event2.pageX || event2.pageY) { - posx = event2.pageX; - posy = event2.pageY; - } else if (event2.clientX || event2.clientY) { - posx = event2.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; - posy = event2.clientY + document.body.scrollTop + document.documentElement.scrollTop; - } - - return { - x: posx - , y: posy - }; - } - var contextMenuClassName = "context-menu"; - var contextMenuItemClassName = "context-menu__item"; - var contextMenuLinkClassName = "context-menu__link"; - var contextMenuActive = "context-menu--active"; - - var taskItemClassName = "task"; - var taskItemInContext; - - var clickCoords; - var clickCoordsX; - var clickCoordsY; - - var menu = getById("context-menu"); - var menuItems = menu.querySelectorAll(".context-menu__item"); - var menuState = 0; - var menuWidth; - var menuHeight; - var menuPosition; - var menuPositionX; - var menuPositionY; - - var windowWidth; - var windowHeight; - - function init() { - contextListener(); - clickListener(); - keyupListener(); - resizeListener(); - } - - function contextListener() { - document.addEventListener("contextmenu", function(e) { - taskItemInContext = clickInsideElement(e, taskItemClassName); - - if (taskItemInContext) { - e.preventDefault(); - toggleMenuOn(); - positionMenu(e); - } else { - taskItemInContext = null; - toggleMenuOff(); - } - }); - } - - function clickListener() { - document.addEventListener("click", function(e) { - var clickeElIsLink = clickInsideElement(e, contextMenuLinkClassName); - - if (clickeElIsLink) { - e.preventDefault(); - menuItemListener(clickeElIsLink); - } else { - var button = e.which || e.button; - if (button === 1) { - toggleMenuOff(); - } - } - }); - } - - function keyupListener() { - window.onkeyup = function(e) { - // if ( e.keyCode === 27 ) { - // toggleMenuOff(); - // } - if (e.altKey && e.shiftKey && e.keyCode === 67 /* C */) { - toggleControlBar(); - } - }; - } - - function resizeListener() { - //window.onresize = function(e) { - // toggleMenuOff(); - // }; - } - - function toggleMenuOn() { - if (menuState !== 1) { - menuState = 1; - menu.classList.add(contextMenuActive); - } - } - - function toggleMenuOff() { - if (menuState !== 0) { - menuState = 0; - menu.classList.remove(contextMenuActive); - } - } - - function toggleControlBar() { - if (getById("controlButtons").style.display != 'none') { - // Dont hardcode style here. Copy it over to data-style before changing to none; - getById("controlButtons").dataset.style = getById("controlButtons").style.display; - getById("controlButtons").style.display = 'none'; - } else { - // Copy the style over from the data-style attribute. - getById("controlButtons").style.display = getById("controlButtons").dataset.style; - }; - } - - function positionMenu(e) { - clickCoords = getPosition(e); - clickCoordsX = clickCoords.x; - clickCoordsY = clickCoords.y; - - menuWidth = menu.offsetWidth + 4; - menuHeight = menu.offsetHeight + 4; - - windowWidth = window.innerWidth; - windowHeight = window.innerHeight; - - if ((windowWidth - clickCoordsX) < menuWidth) { - menu.style.left = windowWidth - menuWidth + "px"; - } else { - menu.style.left = clickCoordsX + "px"; - } - - if ((windowHeight - clickCoordsY) < menuHeight) { - menu.style.top = windowHeight - menuHeight + "px"; - } else { - menu.style.top = clickCoordsY + "px"; - } - } - - function menuItemListener(link) { - if (link.getAttribute("data-action") == "Open") { - window.open(taskItemInContext.value); - } else { - // nothing needed - } - log("Task ID - " + taskItemInContext + ", Task action - " + link.getAttribute("data-action")); - toggleMenuOff(); - } - - init(); - -})(); - -document.addEventListener("dragstart", event => { - var url = event.target.href || event.target.value; - if (!url || !url.startsWith('https://')) return; - if (event.target.dataset.drag != "1") { - return; - } - //event.target.ondragend = function(){event.target.blur();} - - var streamId = url.split('view='); - var label = url.split('label='); - - if (session.label !== false) { - url += '&layer-name=' + session.label; - } else { - url += '&layer-name=VDO.Ninja'; - } - if (streamId.length > 1) url += ': ' + streamId[1].split('&')[0]; - if (label.length > 1) url += ' - ' + decodeURI(label[1].split('&')[0]); - - try { - if (document.getElementById("videosource")) { - var video = getById('videosource'); - if (typeof(video.videoWidth) == "undefined") { url += '&layer-width=1920'; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough url += '&layer-height=1080'; - } else if ((parseInt(video.videoWidth) < 360) || (video.videoHeight < 640)) { - url += '&layer-width=1920'; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough - url += '&layer-height=1080'; - } else { - url += '&layer-width=' + video.videoWidth; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough - url += '&layer-height=' + video.videoHeight; } - } else { + } catch (error) { url += '&layer-width=1920'; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough url += '&layer-height=1080'; } - } catch (error) { - url += '&layer-width=1920'; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough - url += '&layer-height=1080'; - } - event.dataTransfer.setDragImage( getById('dragImage'), 24, 24); - event.dataTransfer.setData("text/uri-list", encodeURI(url)); - //event.dataTransfer.setData("url", encodeURI(url)); + event.dataTransfer.setDragImage( getById('dragImage'), 24, 24); + event.dataTransfer.setData("text/uri-list", encodeURI(url)); + //event.dataTransfer.setData("url", encodeURI(url)); -}); - -function popupMessage(e, message = "Copied to Clipboard") { // right click menu - - var posx = 0; - var posy = 0; - - if (!e) var e = window.event; - - if (e.pageX || e.pageY) { - posx = e.pageX; - posy = e.pageY; - } else if (e.clientX || e.clientY) { - posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; - posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; - } - - posx += 10; - - - var menu = getById("messagePopup"); - menu.innerHTML = "
" + message + "
"; - var menuState = 0; - var menuWidth; - var menuHeight; - var menuPosition; - var menuPositionX; - var menuPositionY; - - var windowWidth; - var windowHeight; - - if (menuState !== 1) { - menuState = 1; - menu.classList.add("context-menu--active"); - } - - menuWidth = menu.offsetWidth + 4; - menuHeight = menu.offsetHeight + 4; - - windowWidth = window.innerWidth; - windowHeight = window.innerHeight; - - if ((windowWidth - posx) < menuWidth) { - menu.style.left = windowWidth - menuWidth + "px"; - } else { - menu.style.left = posx + "px"; - } - - if ((windowHeight - posy) < menuHeight) { - menu.style.top = windowHeight - menuHeight + "px"; - } else { - menu.style.top = posy + "px"; - } - - function toggleMenuOff() { - if (menuState !== 0) { - menuState = 0; - menu.classList.remove("context-menu--active"); - } - } - setTimeout(function() { - toggleMenuOff(); - }, 1000); - event.preventDefault(); -} - -function timeSince(date) { - - var seconds = Math.floor((new Date() - date) / 1000); - - var interval = seconds / 31536000; - - if (interval > 1) { - return Math.floor(interval) + " years"; - } - interval = seconds / 2592000; - if (interval > 1) { - return Math.floor(interval) + " months"; - } - interval = seconds / 86400; - if (interval > 1) { - return Math.floor(interval) + " days"; - } - interval = seconds / 3600; - if (interval > 1) { - return Math.floor(interval) + " hours"; - } - interval = seconds / 60; - if (interval > 1) { - return Math.floor(interval) + " minutes"; - } - return "Seconds ago"; -} -var chatUpdateTimeout = null; -var messageList = [] - -function sendChatMessage(chatMsg = false) { // filtered + visual - var data = {}; - if (chatMsg === false) { - var msg = document.getElementById('chatInput').value; - } else { - var msg = chatMsg; - } - //msg = sanitizeChat(msg); - if (msg == "") { - return; - } - - msg = convertShortcodes(msg); - - if (msg.trim()==="/list"){ - var listMsg = null; - for (var UUID in session.rpcs){ - if (session.rpcs[UUID].label){ - listMsg = UUID+": "+session.rpcs[UUID].label - } else if (session.directorUUID === UUID){ - listMsg = UUID+": Director"; - } else { - listMsg = UUID+": Unknown User"; - } - var data = {}; - data.msg = listMsg; - data.label = false; - data.type = "alert"; - data.time = Date.now(); - messageList.push(data); - } - for (var UUID in session.pcs){ - if (UUID in session.rpcs){continue;} - if (session.pcs[UUID].label){ - listMsg = UUID+"; "+session.pcs[UUID].label - } else if (session.directorUUID === UUID){ - listMsg = UUID+"; Director"; - } else { - listMsg = UUID+"; Unknown User"; - } - var data = {}; - data.msg = listMsg; - data.label = false; - data.type = "alert"; - data.time = Date.now(); - messageList.push(data); - } - if (listMsg===null){ - data.msg = "No other users are connected to you"; - data.label = false; - data.type = "alert"; - data.time = Date.now(); - messageList.push(data); - } - } else if (msg.startsWith("\/msg ")){ - var msg = msg.split("\/msg ")[1]; - msg = msg.split(" "); - uid = msg.shift().toLowerCase(); - msg = msg.join(" "); - if (msg == ""){return;} - var sent = false; - for (var UUID in session.rpcs){ - if (UUID.startsWith(uid)){ - sendChat(msg, UUID); // send message to peers - var data = {}; - data.time = Date.now(); - data.msg = sanitizeChat(msg); // this is what the other person should see - data.label = false; - data.type = "sent"; - messageList.push(data); - sent=true; - } else if (session.rpcs[UUID].label && session.rpcs[UUID].label.toLowerCase().startsWith(uid)){ - sendChat(msg, UUID); // send message to peers - var data = {}; - data.time = Date.now(); - data.msg = sanitizeChat(msg); // this is what the other person should see - data.label = false; - data.type = "sent"; - messageList.push(data); - sent=true; - } else if ((session.directorUUID === UUID) && "director".startsWith(uid)){ - sendChat(msg, UUID); // send message to peers - var data = {}; - data.time = Date.now(); - data.msg = sanitizeChat(msg); // this is what the other person should see - data.label = false; - data.type = "sent"; - messageList.push(data); - sent=true; - } - } - for (var UUID in session.pcs){ - if (UUID in session.rpcs){continue;} - if (UUID.startsWith(uid)){ - sendChat(msg, UUID); // send message to peers - var data = {}; - data.time = Date.now(); - data.msg = sanitizeChat(msg); // this is what the other person should see - data.label = false; - data.type = "sent"; - messageList.push(data); - sent=true; - } else if (session.pcs[UUID].label && session.pcs[UUID].label.toLowerCase().startsWith(uid)){ - sendChat(msg, UUID); // send message to peers - var data = {}; - data.time = Date.now(); - data.msg = sanitizeChat(msg); // this is what the other person should see - data.label = false; - data.type = "sent"; - messageList.push(data); - sent=true; - } else if ((session.directorUUID === UUID) && "director".startsWith(uid)){ - sendChat(msg, UUID); // send message to peers - var data = {}; - data.time = Date.now(); - data.msg = sanitizeChat(msg); // this is what the other person should see - data.label = false; - data.type = "sent"; - messageList.push(data); - sent=true; - } - } - if (sent == false){ - var data = {}; - data.msg = "No user found. Message not sent."; - data.label = false; - data.type = "alert"; - data.time = Date.now(); - messageList.push(data); - updateMessages(); - return; - } - } else if (msg.startsWith("\/")){ - data.msg = "Unknown command. Try '/list' or '/msg username message'."; - data.label = false; - data.type = "alert"; - data.time = Date.now(); - messageList.push(data); - updateMessages(); - return; - } else if (session.directorChat===true){ - if (session.directorUUID){ - sendChat(msg, session.directorUUID); // send message to peers - var data = {}; - data.time = Date.now(); - data.msg = sanitizeChat(msg); // this is what the other person should see - data.label = false; - data.type = "sent"; - messageList.push(data); - } - } else { - sendChat(msg); // send message to peers - data.time = Date.now(); - data.msg = sanitizeChat(msg); // this is what the other person should see - data.label = false; - data.type = "sent"; - messageList.push(data); - } - document.getElementById('chatInput').value = ""; - - messageList = messageList.slice(-100); - if (session.broadcastChannel !== false) { - log(session.broadcastChannel); - session.broadcastChannel.postMessage(data); - } - updateMessages(); -} - -function toggleQualityDirector(bitrate, UUID, ele = null) { // ele is specific to the button in the director's room - var eles = ele.parentNode.childNodes; - for (var i=0;i "; - } else { - data.label = "" + data.label + ": "; - } - label = label+":"; - } else if (director) { - data.label = "Director: "; - label = "Director:"; - } else { - if (session.director){ - data.label = "Someone: "; - } else { - data.label = ""; - } - label = ""; - } - data.type = "recv"; - - if (overlay) { - if (!(session.cleanOutput && session.cleanish==false)){ - var textOverlay = getById("overlayMsgs"); - if (textOverlay) { - var spanOverlay = document.createElement("span"); - spanOverlay.innerHTML = "" + label + " " + msg + "
"; - textOverlay.appendChild(spanOverlay); - textOverlay.style.display = "block"; - var showtime = msg.length * 200 + 3000; - if (showtime > 8000) { - showtime = 8000; - } - setTimeout(function(ele) { - ele.parentNode.removeChild(ele); - }, showtime, spanOverlay); - } - } - } - - if (isIFrame) { - parent.postMessage({ - "gotChat": data - }, "*"); - } - - if (session.chatbutton===false){return;} // messages can still appear as overlays ^ - - messageList.push(data); - messageList = messageList.slice(-100); - - if (session.beepToNotify) { - playtone(); - } - updateMessages(); - - if (session.chat == false) { - getById("chattoggle").className = "las la-comments my-float toggleSize puslate"; - getById("chatbutton").className = "float"; - - if (getById("chatNotification").value) { - getById("chatNotification").value = getById("chatNotification").value + 1; - } else { - getById("chatNotification").value = 1; - } - getById("chatNotification").classList.add("notification"); - - } - - - if (session.broadcastChannel !== false) { - session.broadcastChannel.postMessage(data); /* send */ - } - -} - -function updateClosedCaptions(msg, label, UUID) { - msg.counter = parseInt(msg.counter); - var transcript = sanitizeChat(msg.transcript); // keep it clean. - if (transcript == "") { - return; - } - transcript = transcript.toUpperCase(); - - if (label) { - label = sanitizeLabel(label); - label = "" + label + ": "; - } else { - label = ""; - } - - var textOverlay = getById("overlayMsgs"); - if (textOverlay) { - if (document.getElementById(UUID + "_" + msg.counter)) { - var spanOverlay = document.getElementById(UUID + "_" + msg.counter); - } else { - var spanOverlay = document.createElement("span"); - spanOverlay.id = UUID + "_" + msg.counter; - textOverlay.appendChild(spanOverlay); - textOverlay.style.height = "unset"; - textOverlay.style.textAlign = "left"; - textOverlay.style.display = "block"; - textOverlay.style.position = "fixed"; - textOverlay.style.bottom = "0"; - - } - spanOverlay.innerHTML = label + transcript + "
"; - spanOverlay.style.fontSize = (parseInt(session.labelsize || 100) / 100.0 * 4.5) + "vh"; - spanOverlay.style.lineHeight = (parseInt(session.labelsize || 100) / 100 * 6) + "vh"; - spanOverlay.style.margin = (parseInt(session.labelsize || 100) / 100.0 * 0.75) + "vh"; - - if (msg.isFinal) { - var showtime = 3000; - clearTimeout(spanOverlay.timeout); - spanOverlay.timeout = setTimeout(function(ele) { - ele.parentNode.removeChild(ele); - }, showtime, spanOverlay); - } else { - clearTimeout(spanOverlay.timeout); - spanOverlay.timeout = setTimeout(function(ele) { - ele.parentNode.removeChild(ele); - }, 30000, spanOverlay); - } - - } -} - -function updateMessages() { - if (session.chatbutton===false){return;} - document.getElementById("chatBody").innerHTML = ""; - for (i in messageList) { - - var time = timeSince(messageList[i].time) || ""; - var msg = document.createElement("div"); - //console.log(messageList[i].msg); // Display received messages for View-Only clients. - ///////////////////////////// - if (messageList[i].type == "sent") { - msg.innerHTML = messageList[i].msg + " - " + time + ""; - msg.classList.add("outMessage"); - } else if (messageList[i].type == "recv") { - var label = ""; - if (messageList[i].label) { - label = messageList[i].label; - } - msg.innerHTML = label + messageList[i].msg + " - " + time + ""; - msg.classList.add("inMessage"); - } else if (messageList[i].type == "alert") { - msg.innerHTML = messageList[i].msg + " - " + time + ""; - msg.classList.add("inMessage"); - } else { - msg.innerHTML = messageList[i].msg; - msg.classList.add("outMessage"); - } - - document.getElementById("chatBody").appendChild(msg); - } - if (chatUpdateTimeout) { - clearInterval(chatUpdateTimeout); - } - document.getElementById("chatBody").scrollTop = document.getElementById("chatBody").scrollHeight; - chatUpdateTimeout = setTimeout(function() { - updateMessages(); - }, 60000); -} - -function EnterButtonChat(event) { - // Number 13 is the "Enter" key on the keyboard - var key = event.which || event.keyCode; - if (key === 13) { - // Cancel the default action, if needed - event.preventDefault(); - // Trigger the button element with a click - sendChatMessage(); - } -} - -function showCustomizer(arg, ele) { - //getById("directorLinksButton").innerHTML=' LINKS (GUEST INVITES & SCENES)' - getById("showCustomizerButton1").style.backgroundColor = ""; - getById("showCustomizerButton2").style.backgroundColor = ""; - getById("showCustomizerButton3").style.backgroundColor = ""; - getById("showCustomizerButton4").style.backgroundColor = ""; - getById("showCustomizerButton1").style.boxShadow = ""; - getById("showCustomizerButton2").style.boxShadow = ""; - getById("showCustomizerButton3").style.boxShadow = ""; - getById("showCustomizerButton4").style.boxShadow = ""; - - - if (getById("customizeLinks" + arg).style.display != "none") { - getById("customizeLinks").style.display = "none"; - getById("customizeLinks" + arg).style.display = "none"; - } else { - //directorLinks").style.display="none"; - getById("showCustomizerButton" + arg).style.backgroundColor = "#1e0000"; - getById("showCustomizerButton" + arg).style.boxShadow = "inset 0px 0px 1px #b90000"; - getById("customizeLinks1").style.display = "none"; - getById("customizeLinks3").style.display = "none"; - getById("customizeLinks").style.display = "block"; - getById("customizeLinks" + arg).style.display = "block"; - } -} - - -var defaultRecordingBitrate = false; - -function recordVideo(target, event, videoKbps = false) { // event.currentTarget,this.parentNode.parentNode.dataset.UUID - - var UUID = target.dataset.UUID; - var video = session.rpcs[UUID].videoElement; - var audioKbps = false; - - if (event === null) { - if (defaultRecordingBitrate === null) { - updateLocalRecordButton(UUID, -1); - //target.style.backgroundColor = null; - //target.innerHTML = ' record local'; - return; - } - } else if ((event.ctrlKey) || (event.metaKey)) { - updateLocalRecordButton(UUID, -3); - //target.innerHTML = ' ARMED'; - //target.style.backgroundColor = "#BF3F3F"; - Callbacks.push([recordVideo, target, null, false]); - log("Record Video queued"); - defaultRecordingBitrate = false; - return; - } else { - defaultRecordingBitrate = false; - } - - log("Record Video Clicked"); - if ("recording" in video) { - log("ALREADY RECORDING!"); - //target.style.backgroundColor = null; - //target.innerHTML = ' record local'; - updateLocalRecordButton(UUID, -2); - video.recorder.stop(); - session.requestRateLimit(35, UUID); // 100kbps - if (session.audiobitrate===false){ - session.requestAudioRateLimit(-1,UUID); - } - - var elements = document.querySelectorAll('[data-action-type="change-quality2"][data--u-u-i-d="' + UUID + '"]'); - if (elements[0]) { - elements[0].classList.add("pressed"); - } - var elements = document.querySelectorAll('[data-action-type="change-quality1"][data--u-u-i-d="' + UUID + '"]'); - if (elements[0]) { - elements[0].classList.remove("pressed"); - } - var elements = document.querySelectorAll('[data-action-type="change-quality3"][data--u-u-i-d="' + UUID + '"]'); - if (elements[0]) { - elements[0].classList.remove("pressed"); - } - return; - } else { - updateLocalRecordButton(UUID, 0); - //target.style.backgroundColor = "#FCC"; - //target.innerHTML = " Download"; - video.recording = true; - } - - video.recorder = {}; - - if (videoKbps == false) { - if (defaultRecordingBitrate == false) { - videoKbps = 4000; // 4mbps recording bitrate - window.focus(); - videoKbps = prompt("Press OK to start recording. Press again to stop and download.\n\nWarning: Keep this browser tab active to continue recording.\n\nYou can change the default video bitrate if desired below (kbps)", videoKbps); - if (videoKbps === null) { - //target.style.backgroundColor = null; - //target.innerHTML = ' record local'; - updateLocalRecordButton(UUID, -1); - target.style.backgroundColor = ""; - delete(video.recorder); - delete(video.recording); - defaultRecordingBitrate = null; - return; - } - videoKbps = parseInt(videoKbps); - defaultRecordingBitrate = videoKbps; - } else { - videoKbps = defaultRecordingBitrate; - } - } - - if (videoKbps <= 0) { - audioKbps = videoKbps * (-1); - videoKbps = false; - if (session.audiobitrate===false){ - if ((audioKbps>0) && (audioKbps>=128)){ - session.requestAudioRateLimit(128,UUID); // no point going higher - } else if (audioKbps==0){ - session.requestAudioRateLimit(256,UUID); // PCM - } else { - session.requestAudioRateLimit(parseInt(audioKbps),UUID); // exact? sure. why not. - } - } - } else if (videoKbps < 50) { // this just makes sure you can't set 0 on the record bitrate. - videoKbps = 50; - session.requestRateLimit(parseInt(videoKbps * 0.8), UUID); // 3200kbps transfer bitrate. Less than the recording bitrate, to avoid waste. - } else { - session.requestRateLimit(parseInt(videoKbps * 0.8), UUID); // 3200kbps transfer bitrate. Less than the recording bitrate, to avoid waste. - - if (videoKbps>4000){ - if (session.audiobitrate===false){ - if (session.pcm){ - session.requestAudioRateLimit(256,UUID); - } else { - session.requestAudioRateLimit(128,UUID); - } - } - } else if (videoKbps>2500){ - if (session.audiobitrate===false){ - if (session.pcm){ - session.requestAudioRateLimit(256,UUID); - } else { - session.requestAudioRateLimit(80,UUID); - } - } - } - - } - - var timestamp = Date.now(); - var filename = ""; - if (session.rpcs[UUID].label || session.rpcs[UUID].streamID) { - filename = session.rpcs[UUID].label || session.rpcs[UUID].streamID; - filename = filename.replace(/[\W]+/g, "_"); - filename = filename.substring(0, 200); - } - - filename += "_" + timestamp.toString(); - - var cancell = false; - if (typeof video.srcObject === "undefined" || !video.srcObject) { - return; - } - - const {readable, writable} = new TransformStream({ - transform: (chunk, ctrl) => chunk.arrayBuffer().then(b => ctrl.enqueue(new Uint8Array(b))) - }); - readable.pipeTo(streamSaver.createWriteStream(filename + '.webm')); - var writer = writable.getWriter(); - video.recorder.writer = writer; - video.recorder.stop = function() { - if (!video.recording) { - errorlog("ALREADY STOPPED"); - updateLocalRecordButton(UUID, -1); - return; - } - video.recording = false; - updateLocalRecordButton(UUID, -2); - try { - if (video.recorder.mediaRecorder.state !== "inactive") { - video.recorder.mediaRecorder.stop(); - } - } catch (e) { - errorlog(e); - } - - session.requestRateLimit(35, UUID); // 100kbps - if (session.audiobitrate===false){ - session.requestAudioRateLimit(-1,UUID); - } - var elements = document.querySelectorAll('[data-action-type="change-quality2"][data--u-u-i-d="' + UUID + '"]'); - if (elements[0]) { - elements[0].classList.add("pressed"); - } - var elements = document.querySelectorAll('[data-action-type="change-quality1"][data--u-u-i-d="' + UUID + '"]'); - if (elements[0]) { - elements[0].classList.remove("pressed"); - } - var elements = document.querySelectorAll('[data-action-type="change-quality3"][data--u-u-i-d="' + UUID + '"]'); - if (elements[0]) { - elements[0].classList.remove("pressed"); - } - - cancell = true; - // log('Recorded Blobs: ', recordedBlobs); - // download(); - setTimeout(() => { - writer.close(); - updateLocalRecordButton(UUID, -1); - delete(video.recorder); - delete(video.recording); - }, 1200); - }; - - let options = {}; - - if (videoKbps) { - options.mimeType = "video/webm"; - if (session.pcm){ - options.mimeType += ";codecs=pcm"; - } - if (videoKbps < 1000) { - options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio - } else { - options.bitsPerSecond = parseInt(videoKbps * 1024); // 100 to 132 kbps audio - } - video.recorder.mediaRecorder = new MediaRecorder(video.srcObject, options); - } else { - options.mimeType = "audio/webm"; - if (audioKbps == 0) { - if (MediaRecorder.isTypeSupported("audio/webm;codecs=pcm")) { - options.mimeType = "audio/webm;codecs=pcm"; - } - } else { - options.bitsPerSecond = parseInt(audioKbps * 1024); - } - var stream = new MediaStream(); - video.srcObject.getAudioTracks().forEach((track) => { - stream.addTrack(track, video.srcObject); - }); - video.recorder.mediaRecorder = new MediaRecorder(stream, options); - } - log(options); - - function download() { - const blob = new Blob(recordedBlobs, { - type: "video/webm" - }); - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.style.display = 'none'; - a.href = url; - a.download = filename + ".webm"; - document.body.appendChild(a); - a.click(); - setTimeout(() => { - document.body.removeChild(a); - window.URL.revokeObjectURL(url); - }, 100); - } - - function handleDataAvailable(event) { - if (event.data && event.data.size > 0) { - //recordedBlobs.push(event.data); - writer.write(event.data); //////////// - if (video.recording) { - updateLocalRecordButton(UUID, (parseInt((Date.now() - timestamp) / 1000) || 0)); - } - } - } - - video.recorder.mediaRecorder.ondataavailable = handleDataAvailable; - - video.recorder.mediaRecorder.onerror = function(event) { - errorlog(event); - video.recorder.stop(); - session.requestRateLimit(35, UUID); - if (!(session.cleanOutput)) { - setTimeout(function() { - warnUser("an error occured with the media recorder; stopping recording"); - }, 1); - } - }; - - video.srcObject.ended = function(event) { - video.recorder.stop(); - session.requestRateLimit(35, UUID); - if (!(session.cleanOutput)) { - setTimeout(function() { - warnUser("stream ended! stopping recording"); - }, 1); - } - }; - - - setTimeout(function(v) { - v.recorder.mediaRecorder.start(1000); - }, 500, video); // 100ms chunks - - return; -} - -function updateRemoteRecordButton(UUID, recorder) { - var elements = document.querySelectorAll('[data-action-type="recorder-remote"][data--u-u-i-d="' + UUID + '"]'); - if (elements[0]) { - var time = parseInt(recorder) || 0; - if (time == -3) { - elements[0].classList.remove("pressed"); - elements[0].disabled = true; - elements[0].innerHTML = ' Not Supported'; - if (!(session.cleanOutput)) { - setTimeout(function() { - warnUser('The remote browser does not support recording.\n\nPerhaps try local recording instead.'); - }, 0); - } - - } else if (time == -2) { - elements[0].classList.add("pressed"); - elements[0].innerHTML = ' stopping...'; - } else if (time == -1) { - elements[0].classList.remove("pressed"); - elements[0].innerHTML = ' Record Remote'; - } else { - var minutes = Math.floor(time / 60); - var seconds = time - minutes * 60; - elements[0].classList.add("pressed"); - elements[0].innerHTML = ' ' + minutes + "m : " + (seconds + "").padStart(2, '0') + "s"; - } - } -} - -function updateLocalRecordButton(UUID, recorder) { - var elements = document.querySelectorAll('[data-action-type="recorder-local"][data--u-u-i-d="' + UUID + '"]'); - if (elements[0]) { - var time = parseInt(recorder) || 0; - - //target.innerHTML = ' ARMED'; - // - if (time == -3) { - elements[0].classList.add("pressed"); - elements[0].innerHTML = ' ARMED'; - elements[0].style.backgroundColor = "#BF3F3F"; - } else if (time == -2) { - elements[0].classList.add("pressed"); - elements[0].innerHTML = ' stopping...'; - elements[0].style.backgroundColor = ""; - } else if (time == -1) { - elements[0].classList.remove("pressed"); - elements[0].innerHTML = ' Record Local'; - elements[0].style.backgroundColor = ""; - } else { - var minutes = Math.floor(time / 60); - var seconds = time - minutes * 60; - elements[0].classList.add("pressed"); - elements[0].innerHTML = ' ' + minutes + "m : " + (seconds + "").padStart(2, '0') + "s"; - elements[0].style.backgroundColor = ""; - } - } -} - -function recordLocalVideoToggle() { - var ele = getById("recordLocalbutton"); - if (ele.dataset.state == "0") { - ele.dataset.state = "1"; - ele.style.backgroundColor = "red"; - ele.innerHTML = ''; - if ("recording" in session.videoElement) { - - } else { - recordLocalVideo("start"); - } - - if (session.director){ - var elements = document.querySelectorAll('[data-action-type="recorder-local"][data-sid="' + session.streamID + '"]'); - if (elements[0]) { - elements[0].classList.add("pressed"); - elements[0].innerHTML = ' Record'; - } - } - - } else { - if ("recording" in session.videoElement) { - recordLocalVideo("stop"); - } - ele.dataset.state = "0"; - ele.style.backgroundColor = ""; - ele.innerHTML = ''; - - if (session.director){ - var elements = document.querySelectorAll('[data-action-type="recorder-local"][data-sid="' + session.streamID + '"]'); - if (elements[0]) { - elements[0].classList.remove("pressed"); - elements[0].innerHTML = ' Record'; - } - } - } - -} - -function setupSensorData(pollrate = 30) { - session.sensors = {}; - session.sensors.data = {}; - session.sensors.data.sensors = true; - - if (window.Accelerometer) { - session.sensors.data.acc = {}; - session.sensors.Accelerometer = new Accelerometer({ - frequency: pollrate - }); - session.sensors.Accelerometer.addEventListener('reading', e => { - session.sensors.data.acc.x = session.sensors.Accelerometer.x; - session.sensors.data.acc.y = session.sensors.Accelerometer.y; - session.sensors.data.acc.z = session.sensors.Accelerometer.z; - session.sensors.data.acc.t = parseInt(Math.round(session.sensors.Accelerometer.timestamp)); - }); - session.sensors.Accelerometer.start(); - } - if (window.Gyroscope) { - session.sensors.data.gyro = {}; - session.sensors.Gyroscope = new Gyroscope({ - frequency: pollrate - }); - session.sensors.Gyroscope.addEventListener('reading', e => { - session.sensors.data.gyro.x = session.sensors.Gyroscope.x; - session.sensors.data.gyro.y = session.sensors.Gyroscope.y; - session.sensors.data.gyro.z = session.sensors.Gyroscope.z; - session.sensors.data.gyro.t = parseInt(Math.round(session.sensors.Gyroscope.timestamp)); - }); - session.sensors.Gyroscope.start(); - } - if (window.Magnetometer) { - session.sensors.data.mag = {}; - session.sensors.Magnetometer = new Magnetometer({ - frequency: pollrate - }); - session.sensors.Magnetometer.addEventListener('reading', e => { - session.sensors.data.mag.x = session.sensors.Magnetometer.x; - session.sensors.data.mag.y = session.sensors.Magnetometer.y; - session.sensors.data.mag.z = session.sensors.Magnetometer.z; - session.sensors.data.mag.t = parseInt(Math.round(session.sensors.Magnetometer.timestamp)); - - }); - session.sensors.Magnetometer.start(); - } - if (window.LinearAccelerationSensor) { - session.sensors.data.lin = {}; - session.sensors.LinearAccelerationSensor = new LinearAccelerationSensor({ - frequency: pollrate - }); - session.sensors.LinearAccelerationSensor.addEventListener('reading', e => { - session.sensors.data.lin.x = session.sensors.LinearAccelerationSensor.x; - session.sensors.data.lin.y = session.sensors.LinearAccelerationSensor.y; - session.sensors.data.lin.z = session.sensors.LinearAccelerationSensor.z; - session.sensors.data.lin.t = parseInt(Math.round(session.sensors.LinearAccelerationSensor.timestamp)); - }); - session.sensors.LinearAccelerationSensor.start(); - } - setInterval(function() { - firehoseSensorData(); - }, parseInt(1000 / pollrate)); -} - - -function firehoseSensorData() { - session.sendMessage(session.sensors.data); -} -if (session.sensorData) { - setupSensorData(parseInt(session.sensorData)); -} - -async function chunkedVideoTransfer(videoKbps = 500) { - - var video = session.videoElement; - var recorder = {}; - - var options = {}; - options.mimeType = "video/webm"; - if (videoKbps < 1000) { - options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio - } else { - options.bitsPerSecond = parseInt(videoKbps * 1024); // 100 to 132 kbps audio - } - - recorder.mediaRecorder = new MediaRecorder(video.srcObject, options); - - async function handleDataAvailable(event) { - if (event.data && event.data.size > 0) { - try{ - recorder.mediaRecorder.stop(); - setTimeout(function(){recorder.mediaRecorder.start(500);},500); - } catch(e){ - return; - } - - const arrayBuffer = await event.data.arrayBuffer(); - for (var i in session.pcs){ - session.pcs[i].sendChannel.send(arrayBuffer); - - } - } - - } - - recorder.mediaRecorder.ondataavailable = handleDataAvailable; - - recorder.mediaRecorder.onerror = function(event) { - errorlog(event); - }; - - video.srcObject.ended = function(event) { - errorlog(event); - }; - - recorder.mediaRecorder.start(500); // 100ms chunks - -} - -function recordLocalVideo(action = null, videoKbps = 6000) { // event.currentTarget,this.parentNode.parentNode.dataset.UUID - var audioKbps = false; - var video = session.videoElement; - if ("recording" in video) { - if (action == "stop") { - log("Stopping RECORDING!"); - video.recorder.stop(); - delete(video.recorder); - delete(video.recording); - return; - } else if (action == "start") { - log("ALREADY RECORDING!"); - getById("recordLocalbutton").dataset.state = "1"; - getById("recordLocalbutton").style.backgroundColor = "red"; - getById("recordLocalbutton").innerHTML = ''; - return; - } else { - log("STOPPING RECORDING by default toggle!"); - video.recorder.stop(); - return; - } - return; - } else if (action == "start") { - if (safariVersion()) { - var msg = {}; - msg.UUID = session.directorUUID; - msg.recorder = -3; - session.sendMessage(msg, msg.UUID); - return; - } - video.recording = true; - getById("recordLocalbutton").dataset.state = "1"; - getById("recordLocalbutton").style.backgroundColor = "red"; - getById("recordLocalbutton").innerHTML = ''; - } else if (action == "stop") { - return; - } else { - getById("recordLocalbutton").dataset.state = "1"; - getById("recordLocalbutton").style.backgroundColor = "red"; - getById("recordLocalbutton").innerHTML = ''; - video.recording = true; - } - - video.recorder = {}; - - if (session.recordLocal !== false) { - videoKbps = session.recordLocal; - } - - if (videoKbps <= 0) { - audioKbps = videoKbps * (-1); - videoKbps = false; - } else if (videoKbps < 50) { // this just makes sure you can't set 0 on the record bitrate. - videoKbps = 50; - } - - if (typeof video.srcObject === "undefined" || !video.srcObject) { - return; - } - - const {readable, writable} = new TransformStream({ - transform: (chunk, ctrl) => chunk.arrayBuffer().then(b => ctrl.enqueue(new Uint8Array(b))) }); - var timestamp = Date.now(); - var filename = ""; - if (session.label || session.streamID) { - filename = session.label || session.streamID; - filename = filename.replace(/[\W]+/g, "_"); - filename = filename.substring(0, 200); - } - - filename += "_" + timestamp.toString(); - readable.pipeTo(streamSaver.createWriteStream(filename.toString() + '.webm')); - - var writer = writable.getWriter(); - video.recorder.writer = writer; - pokeIframeAPI("recording-started"); - - video.recorder.stop = function(restart = false) { - if (restart) { - if (getById("recordLocalbutton").dataset.state == 2) { - getById("recordLocalbutton").dataset.state = "0"; - getById("recordLocalbutton").style.backgroundColor = ""; - getById("recordLocalbutton").innerHTML = ''; - restart = false; - warnUser("Media Recording Stopped due to an error."); - } else { - getById("recordLocalbutton").innerHTML = ''; - getById("recordLocalbutton").dataset.state = "2"; - } - } else { - getById("recordLocalbutton").dataset.state = "0"; - getById("recordLocalbutton").style.backgroundColor = ""; - getById("recordLocalbutton").innerHTML = ''; - } - if (!video.recording) { - errorlog("ALREADY STOPPED"); - return; - } - video.recording = false; - try { - if (video.recorder.mediaRecorder.state !== "inactive") { - video.recorder.mediaRecorder.stop(); - } - } catch (e) { - errorlog(e); - } - - setTimeout(() => { - writer.close(); - pokeIframeAPI("recording-stopped"); + window.onload = function winonLoad() { // This just keeps people from killing the live stream accidentally. Also give me a headsup that the stream is ending + window.addEventListener("beforeunload", function(e) { try { - if (session.directorUUID) { - var msg = {}; - msg.UUID = session.directorUUID; - msg.recorder = -1; - session.sendMessage(msg, msg.UUID); + session.ws.close(); + if (session.videoElement.recording) { + session.videoElement.recorder.writer.close(); + session.videoElement.recording = false; } - } catch (e) { - errorlog(e); - } - delete(video.recorder); - delete(video.recording); - - if (restart) { - setTimeout(function() { - recordLocalVideo("start", videoKbps); - }, 0); - } - - }, 500); - try { - if (session.directorUUID) { - var msg = {}; - msg.UUID = session.directorUUID; - msg.recorder = -2; - session.sendMessage(msg, msg.UUID); - } - } catch (e) { - errorlog(e); - } - - }; - - let options = {}; - - if (videoKbps) { - options.mimeType = "video/webm"; - if (session.pcm){ - options.mimeType += ";codecs=pcm"; - } - if (videoKbps < 1000) { - options.videoBitsPerSecond = parseInt(videoKbps * 1024); // 100 kbps audio - } else { - options.bitsPerSecond = parseInt(videoKbps * 1024); // 100 to 132 kbps audio - } - video.recorder.mediaRecorder = new MediaRecorder(video.srcObject, options); - } else { - options.mimeType = "audio/webm"; - if (audioKbps == 0) { - if (MediaRecorder.isTypeSupported("audio/webm;codecs=pcm")) { - options.mimeType = "audio/webm;codecs=pcm"; - } - } else { - options.bitsPerSecond = parseInt(audioKbps * 1024); - } - var stream = new MediaStream(); - video.srcObject.getAudioTracks().forEach((track) => { - stream.addTrack(track, video.srcObject); - }); - video.recorder.mediaRecorder = new MediaRecorder(stream, options); - } - log(options); - - function handleDataAvailable(event) { - if (event.data && event.data.size > 0) { - writer.write(event.data); - if (session.directorUUID) { - if (video.recording) { - var msg = {}; - msg.UUID = session.directorUUID; - msg.recorder = parseInt((Date.now() - timestamp) / 1000) || 0; - session.sendMessage(msg, msg.UUID); - } - } - } - } - - video.recorder.mediaRecorder.ondataavailable = handleDataAvailable; - - video.recorder.mediaRecorder.onerror = function(event) { - errorlog(event); - video.recorder.stop(true); - }; - - video.srcObject.ended = function(event) { - video.recorder.stop(); - }; - - video.recorder.mediaRecorder.start(1000); // 100ms chunks - - if (session.directorUUID) { - var msg = {}; - msg.UUID = session.directorUUID; - msg.recorder = 0; - session.sendMessage(msg, msg.UUID); - } - return; -} - - -function changeAudioOutputDevice(ele) { - if (session.sink){ - if ((iOS) || (iPad)){return;} // iOS devices do not support this. - - if (typeof ele.sinkId !== 'undefined'){ - navigator.mediaDevices.getUserMedia({audio:true,video:false}).then(function (stream){ - ele.setSinkId(session.sink).then(() => { - log("New Output Device:"+session.sink); - }).catch(errorlog); - stream.getTracks().forEach(track => { - track.stop(); - }); - }).catch(function canplayspecificaudio(){errorlog("Can't play out to specific audio device without mic permissions allowed");}); - } else { - warnlog("Your browser does not support alternative audio sources."); - } - } -} - -function addAudioPipeline(stream, UUID, track){ // INBOUND AUDIO EFFECTS - try{ - log("Triggered webaudio effects path"); - - if (session.audioEffects!==true){ // audio effects is not enable. Do not apply. - errorlog("Add Audio Pipeline tried to add effects but should be disabled?"); - return stream; - } - for (var tid in session.rpcs[UUID].inboundAudioPipeline){ - delete session.rpcs[UUID].inboundAudioPipeline[tid]; // get rid of old nodes. - } - var trackid = track.id; - session.rpcs[UUID].inboundAudioPipeline[trackid] = {}; - - session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream = new MediaStream(); - session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream.addTrack(track); - session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio = new Audio(); - session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio.muted = true; - session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio.srcObject = session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream; // needs to be added as an streamed element to be usable, even if its hidden - - session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio.play().then(_ => { - log("playing"); - }).catch(warnlog); - - // https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createMediaStreamTrackSource - source = session.audioCtx.createMediaStreamSource(session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream); - - ////////////////// - - var screwedUp = false; - session.rpcs[UUID].inboundAudioPipeline[trackid].destination = false; - if (session.sync!==false){ - log("adding a delay node to audio"); - source = addDelayNode( source, UUID, trackid); - screwedUp = true; - } - - if (session.style===2){ - log("adding a fftwave node to audio"); - source = fftWaveform( source, UUID, trackid); - } else if (session.style===3){ - log("adding a loudness meter node to audio"); - source = audioMeterGuest(source, UUID, trackid); - } else if (session.audioMeterGuest){ - log("adding a loudness meter node to audio"); - source = audioMeterGuest(source, UUID, trackid); - } else if (session.activeSpeaker){ - log("adding a loudness meter node to audio"); - source = audioMeterGuest(source, UUID, trackid); - } - - if (session.rpcs[UUID].channelOffset !== false){ - log("custom offset set"); - session.rpcs[UUID].inboundAudioPipeline[trackid].destination = session.audioCtx.createMediaStreamDestination(); - source = offsetChannel( session.rpcs[UUID].inboundAudioPipeline[trackid].destination, source, session.rpcs[UUID].channelOffset); - screwedUp = true; - } else if (session.offsetChannel !== false){ // proably better to do this last. - log("adding offset channels"); - session.rpcs[UUID].inboundAudioPipeline[trackid].destination = session.audioCtx.createMediaStreamDestination(); - source = offsetChannel( session.rpcs[UUID].inboundAudioPipeline[trackid].destination, source, session.offsetChannel); - screwedUp = true; - } - - if (screwedUp){ - if (session.rpcs[UUID].inboundAudioPipeline[trackid].destination===false){ - session.rpcs[UUID].inboundAudioPipeline[trackid].destination = session.audioCtx.createMediaStreamDestination(); - } - source.connect(session.rpcs[UUID].inboundAudioPipeline[trackid].destination); - stream.getTracks().forEach((trk)=>{ - if (trackid != trk.id){ - session.rpcs[UUID].inboundAudioPipeline[trackid].destination.stream.addTrack(trk); - log("secondary stream added"); - log(trk); - } - }); - - return session.rpcs[UUID].inboundAudioPipeline[trackid].destination.stream; - } - return stream; - } catch(e) {errorlog(e);} - return stream; -} - -function changeChannelOffset(UUID, channel){ - - - var ele = document.querySelectorAll('[data-action-type="add-channel"][data--u-u-i-d="' + UUID + '"]'); - for (var i=0;i ((val-128.0)*(val-128.0))); - var Sum = Squares.reduce((acum, val) => (acum + val)); - var Mean = Sum/loudness.length; - loudness = Math.sqrt(Mean)*10; - session.rpcs[uuid].stats.Audio_Loudness = parseInt(loudness); - - if (session.pushLoudness==true){ - var loudnessObj = {}; - loudnessObj[session.rpcs[uuid].streamID] = session.rpcs[uuid].stats.Audio_Loudness; - - if (isIFrame){ - parent.postMessage({"loudness": loudnessObj, "action":"loudness", "value":loudness, "UUID":uuid}, "*"); - } - } - - if (loudness<2){return;} - - //log(bufferLength); - session.rpcs[uuid].canvasCtx.beginPath(); - var m = session.rpcs[uuid].canvas.height / 256.0; - session.rpcs[uuid].canvasCtx.moveTo(0, dataArray[0]*m); - for (var i = 1; i < bufferLength; i++){ - var y = dataArray[i] * m; - session.rpcs[uuid].canvasCtx.lineTo(x, y); - x += sliceWidth; - } - session.rpcs[uuid].canvasCtx.lineTo(session.rpcs[uuid].canvas.width, session.rpcs[uuid].canvas.height / 2); - session.rpcs[uuid].canvasCtx.stroke(); - } catch(e){ - warnlog(e); - warnlog("Did the remote source disconnect?"); - clearInterval(fftInterval); - warnlog(session.rpcs[uuid]); - } - },50, UUID); - return session.rpcs[UUID].inboundAudioPipeline[trackid].analyser; -} - -function audioMeterGuest(mediaStreamSource, UUID, trackid){ - log("audioMeterGuest started"); - session.rpcs[UUID].inboundAudioPipeline[trackid].analyser = session.audioCtx.createAnalyser(); - mediaStreamSource.connect(session.rpcs[UUID].inboundAudioPipeline[trackid].analyser); - session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.fftSize = 256; - session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.smoothingTimeConstant = 0.05; - - var bufferLength = session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.frequencyBinCount; - var dataArray = new Uint8Array(bufferLength); - - function updateLevels() { - if (!(UUID in session.rpcs)){return;} - try { - session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.getByteFrequencyData(dataArray); - var total = 0; - for (var i = 0; i < dataArray.length; i++){ - total += dataArray[i]; - } - total = total/100; - session.rpcs[UUID].stats.Audio_Loudness = parseInt(total); - - if (session.pushLoudness==true){ - var loudnessObj = {}; - loudnessObj[session.rpcs[UUID].streamID] = session.rpcs[UUID].stats.Audio_Loudness; - - if (isIFrame){ - parent.postMessage({"loudness": loudnessObj, "action":"loudness", "value":session.rpcs[UUID].stats.Audio_Loudness, "UUID":UUID}, "*"); - } - } - - try{ - clearTimeout(session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.interval); - session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.interval = setTimeout(function(){updateLevels();},100); - } catch(e){ - log("closing old inaudio pipeline"); - } - - if (session.scene!==false){return;} // don't show if a scene - if (session.audioMeterGuest===false){return;} // don't show if we just want the volume levels - - if (session.rpcs[UUID].voiceMeter){ - session.rpcs[UUID].voiceMeter.dataset.level = total; - if (session.meterStyle==1){ - session.rpcs[UUID].voiceMeter.style.height = Math.min(total,100) + "%"; - if (total>75){ - total = Math.min(100,(total - 75)*4); - var R = parseInt((255 * total) / 100).toString(16).padStart(2, '0'); - var G = parseInt(255 * (100 - total) / 100).toString(16).padStart(2, '0'); - session.rpcs[UUID].voiceMeter.style.backgroundColor = "#" + R + G + "00"; - } else { - session.rpcs[UUID].voiceMeter.style.backgroundColor = "#00FF00"; - } - } else { - if (total>15){ - session.rpcs[UUID].voiceMeter.style.opacity = 100; // temporary - } else { - session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary - } - } - - } else { - if (session.meterStyle==1){ - session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate2").cloneNode(true); - } else { - session.rpcs[UUID].voiceMeter = getById("voiceMeterTemplate").cloneNode(true); - if (total>15){ - session.rpcs[UUID].voiceMeter.style.opacity = 100; // temporary - } else { - session.rpcs[UUID].voiceMeter.style.opacity = 0; // temporary - } - } - session.rpcs[UUID].voiceMeter.id = "voiceMeter_"+UUID; - session.rpcs[UUID].voiceMeter.dataset.level = total; - updateMixer(); - } - - } catch(e){ - warnlog(e); - return; - } - }; - clearTimeout(session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.interval); - session.rpcs[UUID].inboundAudioPipeline[trackid].analyser.interval = setTimeout(function(){updateLevels();},100); - return session.rpcs[UUID].inboundAudioPipeline[trackid].analyser; -} - -function effectsDynamicallyUpdate(event, ele, preview=true){ - - var effect = ele.options[ele.selectedIndex].value; - getById("selectImageTFLITE").style.display = "none"; - if (effect === "0"){ - session.effects = 0; - activatedPreview=false; - if (preview){ - grabVideo(); - } else { - grabVideo(session.quality, "videosource", "select#videoSource3"); - } - if (ele.id == "effectSelector"){ - getById("selectImageTFLITE").style.display = "none"; - } else { - getById("selectImageTFLITE3").style.display = "none"; - } - return; - } else if (effect === "3"){ - if ((session.effects<3) || (session.effects>5)){ - session.effects = 3; - activatedPreview=false; - if (preview){ - grabVideo(); - } else { - grabVideo(session.quality, "videosource", "select#videoSource3"); - } - } else { - session.effects = 3; - } - } else if (effect === "4"){ - if ((session.effects<3) || (session.effects>5)){ - session.effects = 4; - activatedPreview=false; - if (preview){ - grabVideo(); - } else { - grabVideo(session.quality, "videosource", "select#videoSource3"); - } - } else { - session.effects = 4; - } - } else if (effect === "5"){ - if (session.tfliteModule.img){ - session.tfliteModule.img.src = "./media/bg_sample.webp"; - } - if ((session.effects<3) || (session.effects>5)){ - session.effects = 5; - activatedPreview=false; - if (preview){ - grabVideo(); - } else { - grabVideo(session.quality, "videosource", "select#videoSource3"); - } - } else { - session.effects = 5; - } - if (ele.id == "effectSelector"){ - getById("selectImageTFLITE").style.display = "block"; - } else { - getById("selectImageTFLITE3").style.display = "block"; - } - } else if (effect === "6"){ - session.effects = 6; - activatedPreview=false; - if (preview){ - grabVideo(); - } else { - grabVideo(session.quality, "videosource", "select#videoSource3"); - } - } - - if (session.effects !== 5){ - if (ele.id == "effectSelector"){ - getById("selectImageTFLITE").style.display = "none"; - } else { - getById("selectImageTFLITE3").style.display = "none"; - } - } - - if (session.tfliteModule===false){ - attemptTFLiteJsFileLoad(); - } -} -var TFLITELOADING = false; -function attemptTFLiteJsFileLoad(){ - if (session.tfliteModule!==false){ - return true; - } - TFLITELOADING=true; - session.tfliteModule={}; - - if (!document.getElementById("tflitesimdjs")){ - var tmpScript = document.createElement('script'); - tmpScript.onload = loadTFLiteModel; - tmpScript.type = 'text/javascript'; - tmpScript.src = "./thirdparty/tflite/tflite-simd.js?ver=2"; - tmpScript.id = "tflitesimdjs"; - document.head.appendChild(tmpScript); - } - - return false; -} -async function changeTFLiteImage(ev, ele){ - - if (ele.files && ele.files[0]) { - session.tfliteModule.img = document.querySelector('img'); - session.tfliteModule.img.ready=false; - session.tfliteModule.img.onload = () => { - URL.revokeObjectURL(session.tfliteModule.img.src); // no longer needed, free memory - session.tfliteModule.img.ready=true; - } - session.tfliteModule.img.src = URL.createObjectURL(ele.files[0]); // set src to blob url - } else if (ele.tagName.toLowerCase() == "img"){ - session.tfliteModule.img = ele - session.tfliteModule.img.ready=true; - } -} - - -async function loadTFLiteModel(){ - try{ - if (session.tfliteModule && (session.tfliteModule.img)){ - var img = session.tfliteModule.img; - session.tfliteModule = await createTFLiteSIMDModule(); - session.tfliteModule.img = img; - } else { - session.tfliteModule = {}; - session.tfliteModule = await createTFLiteSIMDModule(); - } - if (!session.tfliteModule.simd){ - var elements = document.querySelectorAll('[data-warnSimdNotice]') - for (let i = 0; i < elements.length; i++) { - elements[i].style.display = "inline-block"; - } - } - } catch(e){ - warnlog("TF-LITE FAILED TO LOAD"); - return; - } - const modelResponse = await fetch("./thirdparty/tflite/segm_full_v679.tflite"); - session.tfliteModule.model = await modelResponse.arrayBuffer(); - console.log('Model buffer size:', session.tfliteModule.model.byteLength); - session.tfliteModule.HEAPU8.set(new Uint8Array(session.tfliteModule.model), session.tfliteModule._getModelBufferMemoryOffset()); - session.tfliteModule._loadModel(session.tfliteModule.model.byteLength); - session.tfliteModule.activelyProcessing = false; - TFLITELOADING = false; - if ((session.effects>=3) && (session.effects<=5)){ - if (document.getElementById("videosource")){ - activatedPreview=false; - grabVideo(session.quality, "videosource", "select#videoSource3"); - } - } - if (LaunchTFWorkerCallback){TFLiteWorker();} -} - - -if ((session.effects==3) || (session.effects==4) || (session.effects==5)){ - attemptTFLiteJsFileLoad(); -} else if (session.effects==6){ - var script = document.createElement('script'); - var script2 = document.createElement('script'); - var script3 = document.createElement('script'); - var script4 = document.createElement('script'); - var model = false; - script.onload = function() { - document.head.appendChild(script2); - } - script2.onload = function() { - document.head.appendChild(script3); - } - script3.onload = function() { - document.head.appendChild(script4); - } - script4.onload = function() { - async function loadModel(){ - model = await faceLandmarksDetection.load(faceLandmarksDetection.SupportedPackages.mediapipeFacemesh); - - } - loadModel(); - } - script.src = "https://unpkg.com/@tensorflow/tfjs-core@2.4.0/dist/tf-core.js"; - script2.src = "https://unpkg.com/@tensorflow/tfjs-converter@2.4.0/dist/tf-converter.js"; - script3.src = "https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.4.0/dist/tf-backend-webgl.js"; - script4.src = "https://unpkg.com/@tensorflow-models/face-landmarks-detection@0.0.1/dist/face-landmarks-detection.js"; - - script.type = 'text/javascript';script2.type = 'text/javascript';script3.type = 'text/javascript';script4.type = 'text/javascript'; - document.head.appendChild(script); -} - - - -if (session.midiHotkeys || session.midiOut!==false) { - - var script = document.createElement('script'); - script.onload = function() { - WebMidi.enable(function(err) { // hotkeys - - if (err) { - errorlog(err); - } - - WebMidi.addListener("connected", function(e) { - log(e); - }); - - WebMidi.addListener("disconnected", function(e) { - log(e); - }); - - console.log(WebMidi.inputs); - - if (session.midiOut===true){ - for (var i = 0; i < WebMidi.inputs.length; i++) { - var input = WebMidi.inputs[i]; - - input.addListener("midimessage", "all", function(e) { - log(e); - var msg = {}; - msg.midi = {}; - msg.midi.d = e.data; - msg.midi.s = e.timestamp; - msg.midi.t = e.type; - - for (var UUID in session.pcs){ - if (session.pcs[UUID].allowMIDI){ - session.sendMessage(msg, UUID); - } - } - }); - } - } else if (session.midiOut==parseInt(session.midiOut)){ - try{ - var input = WebMidi.inputs[parseInt(session.midiOut)-1]; - input.addListener("midimessage", "all", function(e) { - log(e); - var msg = {}; - msg.midi = {}; - msg.midi.d = e.data; - msg.midi.s = e.timestamp; - msg.midi.t = e.type; - - for (var UUID in session.pcs){ - if (session.pcs[UUID].allowMIDI){ - session.sendMessage(msg, UUID); - } - } - }); - } catch(e){errorlog(e);}; - } - - for (var i = 0; i < WebMidi.inputs.length; i++) { - var input = WebMidi.inputs[i]; - input.addListener('noteon', "all", function(e) { - log(e); - if (session.midiHotkeys==1){ - log(e); - var note = e.note.name + e.note.octave; - if (note == "G3") { // open and close the chat window - toggleChat(); - } else if (note == "A3") { // mute your audio output - toggleMute(); - } else if (note == "B3") { // mute your video output - toggleVideoMute(); - } else if (note == "C4") { // enable / disable screenshare - toggleScreenShare(); - } else if (note == "D4") { // completely kill your connection/session - hangup(); - } else if (note == "E4") { // raise your hand; director sees this - raisehand(); - } else if (note == "F4") { // start/stop local recording - recordLocalVideoToggle(); - } else if (note == "G4") { // Director Enables their Audio output - press2talk(true); - } else if (note == "A4") { // Director cut's their audio/video output - hangup2(); - } - } else if (session.midiHotkeys==2){ - log(e); - var note = e.note.name + e.note.octave; - if (note == "G1") { // open and close the chat window - toggleChat(); - } else if (note == "A1") { // mute your audio output - toggleMute(); - } else if (note == "B1") { // mute your video output - toggleVideoMute(); - } else if (note == "C2") { // enable / disable screenshare - toggleScreenShare(); - } else if (note == "D2") { // completely kill your connection/session - hangup(); - } else if (note == "E2") { // raise your hand; director sees this - raisehand(); - } else if (note == "F2") { // start/stop local recording - recordLocalVideoToggle(); - } else if (note == "G2") { // Director Enables their Audio output - press2talk(true); - } else if (note == "A2") { // Director cut's their audio/video output - hangup2(); - } - } else if (session.midiHotkeys==3){ - log(e); - var note = e.note.name + e.note.octave; - var velocity = e.velocity; - if (note == "C1"){ - if (velocity == "0") { // open and close the chat window - toggleChat(); - } else if (note == "1") { // mute your audio output - toggleMute(); - } else if (note == "2") { // mute your video output - toggleVideoMute(); - } else if (note == "3") { // enable / disable screenshare - toggleScreenShare(); - } else if (note == "4") { // completely kill your connection/session - hangup(); - } else if (note == "5") { // raise your hand; director sees this - raisehand(); - } else if (note == "6") { // start/stop local recording - recordLocalVideoToggle(); - } else if (note == "7") { // Director Enables their Audio output - press2talk(true); - } else if (note == "8") { // Director cut's their audio/video output - hangup2(); - } + for (var i in session.rpcs) { + if (session.rpcs[i].videoElement) { + if (session.rpcs[i].videoElement.recording) { + session.rpcs[i].videoElement.recorder.writer.close(); + session.rpcs[i].videoElement.recording = false; } } - }); - input.addListener('controlchange', "all", function(e) { - - if (session.midiHotkeys==4){ - /* channel: 1 - controller: {number: 110, name: undefined} - data: Uint8Array(3) [176, 110, 3] - target: Input {_userHandlers: {โ€ฆ}, _midiInput: MIDIInput, โ€ฆ} - timestamp: 98235.34000001382 - type: "controlchange" - value: 3 */ - log(e); - if (e.channel!==1){ - errorlog("VDO.Ninja is currently configured for use on channel 1 for MIDI hotkeys"); - return; - } // channel 1? - - var command = e.controller.number; - var value = e.value; - - if (command == 110){ - if (value == 0) { // open and close the chat window - toggleChat(); - } else if (value == 1) { // mute your audio output - toggleMute(); - } else if (value == 2) { // mute your video output - toggleVideoMute(); - } else if (value == 3) { // enable / disable screenshare - toggleScreenShare(); - } else if (value == 4) { // completely kill your connection/session - hangup(); - } else if (value == 5) { // raise your hand; director sees this - raisehand(); - } else if (value == 6) { // start/stop local recording - recordLocalVideoToggle(); - } else if (value == 7) { // Director Enables their Audio output - press2talk(true); - } else if (value == 8) { // Director cut's their audio/video output - hangup2(); - } - } else if (command > 110){ - var guestslot = command-111; - if (value == 0) { - var elements = document.querySelectorAll('[data-action-type="forward"][data--u-u-i-d]'); - if (elements[guestslot]) { - directMigrate(elements[guestslot], true); - } - } else if (value == 1) { - var elements = document.querySelectorAll('[data-action-type="addToScene"][data--u-u-i-d]'); - if (elements[guestslot]) { - directEnable(elements[guestslot], true); - } - } else if (value == 2) { - var elements = document.querySelectorAll('[data-action-type="mute-scene"][data--u-u-i-d]'); - if (elements[guestslot]) { - directMute(elements[guestslot], true); - } - } else if (value == 3) { - var elements = document.querySelectorAll('[data-action-type="mute-guest"][data--u-u-i-d]'); - if (elements[guestslot]) { - remoteMute(elements[guestslot], true); - } - } else if (value == 4) { - var elements = document.querySelectorAll('[data-action-type="hangup"][data--u-u-i-d]'); - if (elements[guestslot]) { - directHangup(elements[guestslot], true); - } - } else if (value == 5) { - var elements = document.querySelectorAll('[data-action-type="solo-chat"][data--u-u-i-d]'); - if (elements[guestslot]) { - session.toggleSoloChat(elements[guestslot].dataset.UUID); - } - } else if (value == 6) { - var elements = document.querySelectorAll('[data-action-type="toggle-remote-speaker"][data--u-u-i-d]'); - if (elements[guestslot]) { - remoteSpeakerMute(elements[guestslot]); - } - } else if (value == 7) { - var elements = document.querySelectorAll('[data-action-type="toggle-remote-display"][data--u-u-i-d]'); - if (elements[guestslot]) { - remoteDisplayMute(elements[guestslot]); - } - } else if ((value => 27)) { - var elements = document.querySelectorAll('[data-action-type="volume"][data--u-u-i-d]'); - if (elements[guestslot]) { - elements[guestslot].value = parseInt(value-27); - remoteVolume(elements[guestslot]); - } - } - } - } - }); - } + } + } catch (e) {} + //setTimeout(function(){session.hangup();},0); + return undefined; // ADDED OCT 29th; get rid of popup. Just close the socket connection if the user is refreshing the page. It's one or the other. + }); }; - script.src = "./thirdparty/webmidi.js"; // dynamically load this only if its needed. Keeps loading time down. - document.head.appendChild(script); -} else if (session.midiIn){ - var script = document.createElement('script'); - script.src = "./thirdparty/webmidi.js"; // dynamically load this only if its needed. Keeps loading time down. - script.onload = function() { - WebMidi.enable(function(err) { // hotkeys - if (err) { - errorlog(err); - } - console.log(WebMidi.outputs); - }); - } - document.head.appendChild(script); -} - -function playbackMIDI(msg){ - if (session.midiIn===false){return;} // just in case. - else if (session.midiHotkeys || session.midiOut){return;} - //msg.midi.d = e.data; - //msg.midi.s = e.timestamp; - //msg.midi.t = e.type; - log(msg); - if (session.midiIn===true){ - if ("d" in msg){ - for (var i in WebMidi.outputs){ - try { - WebMidi.outputs[i].send(msg.d[0], [msg.d[1] || 0, msg.d[2] || 0]); - } catch(e){errorlog(e);} - } + var lastTouchEnd = 0; + document.addEventListener('touchend', function(event) { + var now = (new Date()).getTime(); + if (now - lastTouchEnd <= 300) { + event.preventDefault(); } - } else if (session.midiIn==parseInt(session.midiIn)){ - try { - var i = parseInt(session.midiIn)-1; - if ("d" in msg){ - WebMidi.outputs[i].send(msg.d[0], [msg.d[1] || 0, msg.d[2] || 0]); - } - } catch(e){errorlog(e);}; - } - //var output = WebMidi.getOutputById("123456789"); - //output = WebMidi.getOutputByName("Axiom Pro 25 Ext Out"); - //output = WebMidi.outputs[0]; -} + lastTouchEnd = now; + }, false); -document.body.innerHTML += ''; -addEventToAll(".column", 'click', function(e, ele) { - if (ele.classList.contains("skip-animation")) { - return; - } - var bounding_box = ele.getBoundingClientRect(); - ele.style.top = bounding_box.top + "px"; - ele.style.left = (bounding_box.left - 20) + "px"; - ele.classList.add('in-animation'); - ele.classList.remove('pointer'); - if (document.getElementById("empty-container")) { - getById("empty-container").parentNode.removeChid(getById("empty-container")); - } - var empty = document.createElement("DIV"); - empty.id = "empty-container"; - empty.className = "column"; - ele.parentNode.insertBefore(empty, ele.nextSibling); - const styles = "\ - @keyframes outlightbox {\ - 0% {\ - height: 100%;\ - width: 100%;\ - top: 0px;\ - left: 0px;\ - }\ - 50% {\ - height: 200px;\ - top: " + bounding_box.y + "px;\ - }\ - 100% {\ - height: 200px;\ - width: " + bounding_box.width + "px;\ - top: " + bounding_box.y + "px;\ - left: " + bounding_box.x + "px;\ - }\ - }\ - "; - if (document.getElementById('lightbox-animations')) { - getById("lightbox-animations").innerHTML = styles; - } - document.body.style.overflow = "hidden"; -}); -addEventToAll(".close", 'click', function(e, ele) { - cleanupMediaTracks(); - ele.style.display = "none"; - mapToAll(".container-inner", function(target) { - target.style.display = "none"; + + document.addEventListener('click', function(event) { + if (session.firstPlayTriggered == false) { + playAllVideos(); + session.firstPlayTriggered = true; + history.pushState({}, ''); + } }); - document.body.style.overflow = "auto"; - var bounding_box = getById("empty-container").parentNode.getBoundingClientRect(); - setTimeout(function() { // just smoothes things out; breathing room to clean up things first. - ele.parentNode.classList.add('out-animation'); - }, 1); - ele.parentNode.style.top = bounding_box.top + 'px'; - ele.parentNode.style.left = bounding_box.left + 'px'; - e.stopPropagation(); -}); -addEventToAll(".column", 'animationend', function(e, ele) { - if (e.animationName == 'inlightbox') { - ele.classList.add("skip-animation"); - mapToAll(".close", function(target) { - target.style.display = "block"; - }, ele); - mapToAll(".container-inner", function(target) { - target.style.display = "block"; - }, ele); - } else if (e.animationName == 'outlightbox') { - ele.classList.remove('in-animation'); - ele.classList.remove('out-animation'); - ele.classList.remove("skip-animation"); - ele.classList.remove('columnfade'); - ele.classList.add('pointer'); - getById("empty-container").parentNode.removeChild(getById("empty-container")); - getById("lightbox-animations").sheet.deleteRule(0); - } -}); -addEventToAll("#audioSource", 'mousedown touchend focusin focusout', function(e, ele) { - var state = getById('multiselect-trigger').dataset.state || 0; - if (state == 0) { - getById('multiselect-trigger').dataset.state = 1; - getById('multiselect-trigger').classList.add('open'); - getById('multiselect-trigger').classList.remove('closed'); - mapToAll('.chevron', function(ele) { - ele.classList.remove('bottom'); - }, parentElement = getById('multiselect-trigger')); - mapToAll('.multiselect-contents', function(ele) { - ele.style.display = "block"; - mapToAll('input[type="checkbox"]', function(ele2) { - ele2.parentNode.style.display = "block"; - ele2.style.display = "inline-block"; - }, ele); - }, parentElement = getById('multiselect-trigger').parentNode); - } - e.stopPropagation(); - //e.preventDefault(); -}); -addEventToAll("#audioSource3", 'mousedown touchend focusin focusout', function(e, ele) { - var state = getById('multiselect-trigger3').dataset.state || 0; - if (state == 0) { - getById('multiselect-trigger3').dataset.state = 1; - getById('multiselect-trigger3').classList.add('open'); - getById('multiselect-trigger3').classList.remove('closed'); - mapToAll(".chevron", function(target) { - target.classList.remove('bottom'); - }, getById('multiselect-trigger3')); - mapToAll(".multiselect-contents", function(target) { - target.style.display = "block"; - }, getById('multiselect-trigger3').parentNode); - mapToAll(".multiselect-contents", function(target) { - mapToAll('input[type="checkbox"]', function(target2) { - target2.style.display = "inline-block"; - target2.parentNode.style.display = "block"; - }, target); - }, getById('multiselect-trigger3').parentNode); - } - e.stopPropagation(); - //e.preventDefault(); -}); -addEventToAll("#multiselect-trigger", 'mousedown touchend focusin focusout', function(e, ele) { - var state = ele.dataset.state || 0; - if (state == 0) { // open the dropdown - ele.dataset.state = 1; - ele.classList.add('open'); - ele.classList.remove('closed'); - mapToAll(".chevron", function(target) { - target.classList.remove('bottom'); - }, getById('multiselect-trigger')); - mapToAll(".multiselect-contents", function(target) { - target.style.display = "block"; - }, ele.parentNode); - mapToAll(".multiselect-contents", function(target) { - mapToAll('input[type="checkbox"]', function(target2) { - target2.style.display = "inline-block"; - target2.parentNode.style.display = "block"; - }, target); - }, ele.parentNode); - } else { // close the dropdown - ele.dataset.state = 0; - ele.classList.add('closed'); - ele.classList.remove('open'); - mapToAll(".chevron", function(target) { - target.classList.add('bottom'); - }, ele); - mapToAll(".multiselect-contents", function(target) { - mapToAll('input[type="checkbox"]', function(target2) { - target2.style.display = "none"; - if (!target2.checked) { - target2.parentNode.style.display = "none"; + + document.addEventListener("keydown", event => { + + if ((event.ctrlKey) || (event.metaKey)) { // detect if CTRL is pressed + CtrlPressed = true; + } else { + CtrlPressed = false; + } + if (event.altKey) { + AltPressed = true; + } else { + AltPressed = false; + } + + + if (CtrlPressed && event.keyCode) { + + if (event.keyCode == 77) { // m + if (event.metaKey) { + if (AltPressed) { + toggleMute(); // macOS + } + } else { + toggleMute(); // Windows } - }, target); - }, ele.parentNode); - } - e.preventDefault(); - e.stopPropagation(); -}); -addEventToAll("#multiselect-trigger3", 'mousedown touchend focusin focusout', function(e, ele) { - var state = ele.dataset.state || 0; - if (state == 0) { // open the dropdown - ele.dataset.state = 1; - ele.classList.add('open'); - ele.classList.remove('closed'); - mapToAll(".chevron", function(target) { - target.classList.remove('bottom'); - }, ele); - mapToAll(".multiselect-contents", function(target) { - target.style.display = "block"; - }, ele.parentNode); - mapToAll(".multiselect-contents", function(target) { - mapToAll('input[type="checkbox"]', function(target2) { - target2.style.display = "inline-block"; - target2.parentNode.style.display = "block"; - }, target); - }, ele.parentNode); - } else { // close the dropdown - ele.dataset.state = 0; - ele.classList.add('closed'); - ele.classList.remove('open'); - mapToAll(".chevron", function(target) { - target.classList.add('bottom'); - }, ele); - mapToAll(".multiselect-contents", function(target) { - mapToAll('input[type="checkbox"]', function(target2) { - target2.style.display = "none"; - if (!target2.checked) { - target2.parentNode.style.display = "none"; + // } else if (event.keyCode == 69) { // e + // hangup(); + } else if (event.keyCode == 66) { // b + toggleVideoMute(); + } + } + + + }); + + document.addEventListener("keyup", event => { + if (!((event.ctrlKey) || (event.metaKey))) { + if (CtrlPressed) { + CtrlPressed = false; + for (var i in Callbacks) { + var cb = Callbacks[i]; + log(cb.slice(1)); + cb[0](...cb.slice(1)); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#A_better_apply } - }, target); - }, ele.parentNode); - } - e.preventDefault(); - e.stopPropagation(); -}); + Callbacks = []; + } + } + if (!(event.altKey)) { + AltPressed = false; + } + }); +} +main(); // asyncronous load -// Warns user about network going down -window.addEventListener("offline", function (e) { - if ((session.view) && (session.permaid === false)) { - log("VDO.Ninja has no network connectivity and can't work properly." ); - } else if (session.scene !== false) { - log("VDO.Ninja has no network connectivity and can't work properly." ); - } else if (!session.cleanOutput) { - warnUser("Network connection lost."); - } else { - log("VDO.Ninja has no network connectivity and can't work properly."); - } -}); - -window.addEventListener("online", function (e) { - closeModal(); -}); - -// Remove modal if network comes back up -window.addEventListener("online", function (e) { - if (!session.cleanOutput) { - // Remove last inserted modal; Could be improved by tagging the - // modal elements and only removing modals tagged 'offline' - userWarnings = document.querySelectorAll('.alertModal'); - closeModal(userWarnings[userWarnings.length- 1]); - } else { - log( - "Network connectivity has been restored." - ); - } - }); +setTimeout(function(){ // lazy load + var script = document.createElement('script'); + document.head.appendChild(script); + script.onload = function() { + var script = document.createElement('script'); + document.head.appendChild(script); + script.src = "./thirdparty/StreamSaver.js"; // dynamically load this only if its needed. Keeps loading time down. + }; + script.src = "./thirdparty/polyfill.min.js"; // dynamically load this only if its needed. Keeps loading time down. +},0); \ No newline at end of file diff --git a/webrtc.js b/webrtc.js index bd26ae0..8e920eb 100644 --- a/webrtc.js +++ b/webrtc.js @@ -6,4 +6,4 @@ * No warranty, explicit or implicit, provided. * */ -var _0x149c=['minipreview','seedStream','[data-action-type=\x22mute-guest\x22][data--u-u-i-d=\x22','isDirector\x20','new','framesDecoded','next\x20stream\x20loading:\x20','packetsReceived','quality_wb','new-view-connection','directorVideoMuted','_bytesReceived','createObjectURL','yFwat','muteState','Someone\x20published\x20a\x20video\x20to\x20the\x20Room','RECONNECTING\x20to\x20HSS;\x20DISCONNECTING\x20FROM\x20TRANSFERRED\x20ROOM','list','videoCodecs','quality_url','pingTimeout','maxvb_url','1.0','UFnhc','Setting\x20view\x20to\x20null\x20disables\x20all\x20playback','wss','directorSpeakerMuted','byoRI','removeTrack','KpFRK','indexOf','gGYbl','toString','gAPjS','directorSpeakerMute','HsLCb','mQfmd','maxptime','2px','muted_savedState','^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}','applySoloChat','Round_Trip_Time_ms','paused','directorUUID','width','scaleFactor','received\x20data\x20from\x20viewer','_trackID','The\x20request\x20failed;\x20the\x20remote\x20user\x20did\x20not\x20recognize\x20you\x20as\x20the\x20director','offerSDP','_sync_offset','setupIncoming','setResolution','networkPriority','stopPropagation','audioContext','PROBLEM!\x20RESENDING\x20SDP\x20OFFER\x20SHOULD\x20NOT\x20HAPPEN','limitAudio','showDirector','jwk','listPromise','random','deferring\x20with\x20a\x20promise;\x20hashed\x20room','cameraConstraints','turn:www.turn.obs.ninja:3478','setParameters','[data-action-type=\x22volume\x22][data--u-u-i-d=\x22','stereo','iceServers','running','transcript','rejected','sampleRate','rampUpTime','Video\x20Track','onconnectionstatechange\x20pcs\x20ice\x20--\x20disconnected,\x20but\x20not\x20yet\x20closed?\x20','start','stun:stun.l.google.com:19302','location','917937vkAqfP','connectPeer','TRYING\x20TO\x20RECONNECT\x201','RLqjw','_jitter_delay','oninactive','roomid','create\x20offer\x20worked','pleaseDoNotAbuse','deltaY','codecs','style','dVvgz','cover','limitAudioBitrate','3manaoj','sendMessage','obsVisibility','screensharefps','yYaXh','iceBundle','zhagk','ICE\x20target\x20no\x20longer\x20exists?','FMzTb','tkAlN','sensorData','lHQrP','Inbound\x20User-based\x20Message\x20from\x20Room','remove','audio_delay\x20:\x20','preventDefault','rpcs','connectionState','changeCamera','decryptMessage','beepToNotify','getVideoTracks','videoOptions','sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message','SYhIA','forceios','getParameters','resolve','[data-action-type=\x22solo-chat\x22][data--u-u-i-d=\x22','delayTime','TImQo','playoutdelay','opacity','muted','Mute\x20video\x20-306','forcePLI','JSgdH','GOT\x20ICE!!','ACTION\x20REJECTED:\x20','overlay','75540SDCClK','LuhgM','warn','URL','requestAudioHack','&pie=','videosource_','Audio_Sync_Delay_ms','bitrateTimeout','ping','sid','left','watchStream','salt','23785EsWYoP','obsStreaming','queue','noPLIs','pathname','Trying\x20to\x20reconnect\x202','volume','seeding\x20blocked','noaudio','title','statsMenu','pcs','maxsamplerate','gtwOQ','icefilter','configuration','subtle','inboundAudioPipeline','5px','focus\x20success','disconnected','EVENT\x20TRACK\x20instead\x20of\x20event\x20Stream','5iJPzDO','KBmIA','order','Not\x20director','PCS:\x20ICE\x20Disconnected;\x20wait\x20for\x20retry?\x20pcs','seedAttempts','Update\x20Mixer\x20Event\x20on\x20REsize\x20SET','echoCancellation','QhBOf','MediaStreamAudioDestinationNode','emGVD','level','directVideoMuted','forEach','iceConnectionState\x20==\x20connected','trackIdentifier','**\x20connected','ZblHV','allowBroadcast','Shspq','maxBitrate','[data-action-type=\x22solo-chat\x22]','broadcast','changeLabel','RSA','The\x20Director\x20has\x20disabled\x20your\x20vision\x20temporarily
','firefox','jdxbw','recordLocal','scaleDueToBitrate','Buffer_Delay_in_ms','label_','getAudioTracks','UOyHC','miRNi','pressed','optimize','max','label=','now','host','turn:turn-usw1.obs.ninja:443','RS1','initialPublish','browserDetails','firstPlayTriggered','Not\x20a\x20scene','werAJ','guest','priority','_codecIdTrackId','map','ZISfT','changeSpeaker','importKey','gSeqX','ngtCO','xUeRx','aspectratio','display','mediaDevices','ieAUb','Generate\x20Some\x20Crypto\x20keys\x20first','processIce2','This\x20shouldn\x27t\x20happen','displayMute','ICE\x20DID\x20NOT\x20FIND\x20A\x20PC\x20OPTION?','JUFVA','scene','soloVideo','apply','innerText','videosource','dropped\x20candidate\x20due\x20to\x20filter','privacy','MJHXv','readyState','director','setValueAtTime','labelsize','nopreview','maxiosbitrate','postMessage','RPC\x20closed','processStats','sensors','getVideoBitrates','sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message;\x20RTC\x20peers\x20only','38163jUvKpw','privateKey','min','gmbys','what\x20is\x20this?','quality','hssConnection','zoom','_frameWidth','setupYourOwnPlease','pre\x20pixel\x20fix\x20','turn:turn-au1.vdo.ninja:3478','17tuQMCL','relayProtocol','watchTimeoutList:','vb_url','NYHUo','done\x20replacing/adding\x20tracks','ptz','obsStateSync','directorDisplayMute','toggleSoloChat','track','bandwidth','WaAzM','sort','pip','currentCameraConstraints','enhanceaudio','cursor','Viewer\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit','message','requestFocusChange','remoteVideoMuteElement','video','sceneType','resolution\x20scale','You\x27ve\x20been\x20transferred','hash','name','data','queuebutton','midiIn','vector','sendChannel','remoteStats','fnTrb','generateKey','audioCodecs','join','resending\x20message','position','allowMIDI','VFlhE','sdp','adaptivePtime','sourceActive','sendPeers','aYoGT','resolution\x20scale:\x20','addTrack','createDataChannel','wfBJX','onconnectionstatechange','includes','successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS\x20to\x20all\x20RTC\x20Peers','permaid','sync','keyframeTimeout','HDgac','requestResolution','focus','audioCtx','pliCount','TOO\x20MANY\x20PUBLISHING\x20PEERS','Kftuu','localVoiceMeter','innerHTML','_codecId','enhance_audio','successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS','someonejoined','WebRTC\x20Connection\x20Closed.\x20Clean\x20up.\x20657','applyConstraints','controlRoomBitrate','scale\x20set!','SIUXY','_last_time','Hlbua','screenshareid','Stream\x20ID\x20is\x20already\x20in\x20use.','flipped','scaleResolutionDownBy','HfOKU','Un-mute\x20guest','hiddenSceneViewBitrate','joiningRoom','already\x20connected','verify','ELrZi','aXFav','constructor','iframe_','play','audioGain','requestSceneUpdate','TqVcX','new-push-connection','New\x20Label:\x20','SDP\x20Sessions\x20Match.\x20I\x20assume\x20ADDING\x20TRACKS','Uzaie','audioDevice','zLPeT','frameWidth','Someone\x20sent\x20us\x20an\x20ANSWER\x20sdp??','empty\x20ice..','_packetsReceived','play\x20stream:\x20','235817qnNXaG','queueList','TAmCu','getVideoSettings','limitTotalBitrate','midi','delayNode','Remote\x20peer\x20disconnected.\x20Due\x20to\x20enhanced\x20security,\x20please\x20refresh\x20to\x20create\x20a\x20new\x20connection.','vp9','Press\x20OK\x20to\x20submit\x20any\x20error\x20logs\x20to\x20VDO.Ninja.\x20Error\x20logs\x20may\x20contain\x20private\x20information.','remoteZoom','novideo','active','acc','actual\x20bitrate:','failed\x20to\x20disconnect','Members\x20in\x20Room','taintedSession','noiseSuppression','MzTEt','Firefox','removeEventListener','device\x20does\x20not\x20support\x20playout\x20delay','JGpoz','closed','infocus','HANG\x20UP\x20COMPLETE','replace','broadcastIFrame','room\x20rate\x20restriction\x20detected.\x20No\x20videos\x20will\x20be\x20published\x20to\x20other\x20guests','10px','changeURL','midiHotkeys','nocursor','videoMutedFlag','audioOptions','_timestampStart','currentRoundTripTime','AQAB','safari','midiOut','screenshare','enabled','activelySpeaking','stats','pNziF','network_type','allowIframe','send','cleanup','already\x20closed\x20PCS','getTracks','_local_ice_id','autoGainControl','?view=','signData','RTC\x20Connection','_frameHeight','QfhbB','RSASSA-PKCS1-v1_5','CqzeR','noiframe','Media','height_url','pushLoudness','Failed\x20to\x20request\x20video\x20and\x20audio;\x20iOS\x20device\x20asking?','session','onnegotiationneeded','kind','forceMediaSettings','span','none','Someone\x20Joined\x20the\x20Room\x20with\x20a\x20video','undefined','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x201','KmcWJ','querySelectorAll','problem','xXToF','disabled','..\x20waiting\x20for\x20user\x20gesture','Android','tabernac','jbsrn','fiJIy','BfONd','CAHqz','audioLevel','className','New\x20ON\x20TRACK\x20event','Enter\x20a\x20new\x20Display\x20Name\x20for\x20this\x20stream','candidateType','relative','playback_audio_samplerate','inbound-rtp','Ipctn','maxviewers','send\x20channel\x20closed','BKMtE','packetLoss_in_percentage','playback_audio_volume_meter','gTnTv','label','aec_url','action','requestChangeLowcut','length','connected','float2','gainNode','encryptMessage','importCrypto','could\x20not\x20be\x20sent;\x20queuing\x20it','LjFBC','request\x20focus\x20change:\x20','cgBvH','ZuBEl','The\x20director\x20wishes\x20to\x20redirect\x20you\x20to\x20the\x20URL:\x20','bind','allowVideo','OfiYg','generateStreamID','dynamicScale','Create\x20a\x20new\x20RTC\x20connection;\x20offering\x20SDP\x20on\x20request','steve','video/VP8','Someone\x20Joined\x20the\x20Room','fDxHd','localstats','chatbutton','encrypt','nUHDT','stereo_url','gyro','OqRPn','mid','randomize','speakerMute','MmBMI','mwPCL','tRfWP','NHuWw','receiveChannel','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x204','setRemoteDescription','roombitrate','Fznda','YpJbS','controls','MVOgW','visibility','optimizedBitrate','security','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x202','time_active_minutes','msg','Adjusting\x20Gain;\x20only\x20track\x200\x20in\x20all\x20likely\x20hood,\x20unless\x20more\x20than\x20track\x200\x20support\x20is\x20added.','UN-MUTED','pie','soloChatUUID','imageElement','resume','recording_audio_ctx_latency','localMuteElement','cleanOutput','adding\x20track','SYdnL','useragent','alert','ctrlKey','disconnectedTimeout','candidate','rpc\x20datachannel\x20closed','codecId','Message\x20to\x20be\x20sent:\x20','audio\x20bandwidth\x20set!','\x20is\x20not\x20defined;\x20skipping.','allowAudio','metaKey','YRqUi','digest','can\x27t\x20change\x20audio\x20bitrate;\x20no\x20audio\x20sender\x20found','remoteMuteElement','Does\x20Local\x20Stream\x20Source\x20EXIST?','&pie','streams','frameHeight','OSkau','block','split','gridlayout','offer','version','yfQow','pointer','SET\x20SCALING\x20IS\x20FIRING,\x20which\x20is\x20GOOD\x20!!!!!!','\x0aPress\x20OK\x20to\x20be\x20redirected.','mutedState','session.videoElement.srcObject\x20failed;\x20but\x20streamSrc\x20worked?','onoAl','encodering\x20being\x20kicked','framesPerSecond','xtJRY','hangupDirector','substring','ptime','Enable\x20the\x20director\x27s\x20microphone\x20first.','fPRHs','sticky','getOpusBitrate','candidates','ICE\x20FAILed.\x20bad?','userAgent','limitTotalBitrateGuests','FAIL\x20rpcs','mute','anyrequest','setLocalDescription','delta','byteLength','abs','forceTcpMode','UUID\x20not\x20found\x20in\x20pcs','classList','speedtest','fromCharCode','Unable\x20to\x20set\x20update\x20OBS\x20Visibility','totalRoomBitrate','video\x20element\x20is\x20being\x20created\x20and\x20media\x20track\x20added','_remote_ice_id','writer','stereo\x20enabled','aBSng','UUID','streaming','failed\x20to\x20send\x20focus\x20change\x20request','uvRzc','migrate','sceneSync','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x203','AudioContext','turn:turn.obs.ninja:3478','closedCaptions','state','requestStats','obsninja','iOS\x20devices\x20do\x20not\x20support\x20dynamic\x20bitrates\x20correctly;\x20skipping','onopen','remoteDescription','BKaNH','ROOMID\x20EANBLED','send\x20channel\x20open\x20pcs','libKq','Unmute\x20video','anysend','localDescription','Raised\x20hand','inline-block','ILanm','listing','Audio_Loudness','type','desaltStreamID','YoxDk','mag','add','udp','post\x20pixel\x20fix\x20','YqpoK','MORE\x20THAN\x20ONE\x20VIDEO\x20TRACK\x20IS\x20BEING\x20ADDED','31ucJrIQ','mykey','mGqQU','focusDistance','vagtV','recorder','saOeu','audioCtx\x20:\x20','iframeSrc','value','requestKeyframe','FORCING\x20A\x20KEY\x20FRAME:\x20','publicKey','IwndP','disableNACK','outboundAudioBitrate','null\x20ice\x20rpcs','CZwfS','Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit','sendRequest','sceneDisplay','website','object','disableWebAudio','signature','ontrack','onmessage','getSenders','successfully\x20requested\x20audio\x20and\x20video','Browser','_type','Notice:\x20The\x20system\x20is\x20currently\x20slow\x20to\x20respond\x20or\x20not\x20accessible.\x0a\x0aClick\x20OK\x20to\x20continue.\x0a\x0aIf\x20the\x20site\x20fails\x20to\x20work\x20though,\x20please\x20try\x20https://backup.obs.ninja\x20instead\x20or\x20contact\x20steve@seguin.email\x20for\x20help.\x0a\x0aThis\x20service\x20requires\x20the\x20use\x20of\x20Websockets\x20over\x20port\x20443.','generateHash','uQqDo','enhance','SHA-256','heTkV','outboundVideoBitrate','production','done\x20clearing\x20audio','Your\x20room\x20has\x20changed','hanging\x20up','remoteMuteState_','push','iframeEle','mono','Track\x20was\x20removed','OBS\x20PLI\x20FIX\x20MODE\x20ON','micDelay','bXHnP','webAudios','setOpusAttributes','slice','uDHHh','CsuXP','failed\x20to\x20send\x20zoom\x20change\x20request','Stream\x20ID\x20pre:','starting\x20kicker','AYefl','Answer\x20SDP\x20does\x20not\x20have\x20a\x20matching\x20session\x20ID','tJDoO','RTC\x20connection\x20is\x20ALREADY\x20ready;\x20we\x20can\x20already\x20accept\x20answers','info','pixelFix','remoteMuteState','chrome','HANG\x20UP\x202\x20COMPLETE','LpEDV','FPS','bSEkb','browser','createAnswer','username','iframe','getSettings','requestVideoRecord','seedPlz','hostname','directorEnabledPPT','generateCrypto','crypto','Remote\x20peer\x20connected\x20to\x20video\x20stream.\x0a\x0aConnection\x20to\x20handshake\x20server\x20being\x20killed\x20on\x20request.\x20This\x20increases\x20security,\x20but\x20the\x20peer\x20will\x20not\x20be\x20able\x20to\x20reconnect\x20automatically\x20on\x20connection\x20failure.\x0a\x0aPress\x20OK\x20to\x20start\x20the\x20stream!','sign','pcm','_timestamp','pcs\x20RTC\x20Failed','getTimezoneOffset','denoise_url','FORCE\x20KEYFRAME\x20FOR\x20SCENE','mainmenu','turns:turn.obs.ninja:443','nackCount','obsRecording','recording_audio_pipeline','ICE:\x20','recording_audio_gain','directorSettings','mediaType','mimeType','right','parentNode','bytesReceived','code','AES-CBC','directorDisplayMuted','iceConnectionState','directorViewBitrate','CLOSED','POST','local_candidateType',',\x20isDirector:\x20','vKsta','Lowered\x20hand','startTime','totalRoomBitrate_default','string','psVVC','quality_ss','framerate','GOT\x20ICES!!','webcamonly','bit\x20rate\x20being\x20munged','rleoD','The\x20stream\x20ID\x20you\x20are\x20publishing\x20to\x20is\x20already\x20in\x20use.\x0a\x0aPlease\x20try\x20with\x20a\x20different\x20invite\x20link\x20or\x20refresh\x20to\x20retry\x20again.\x0a\x0aYou\x20will\x20now\x20be\x20disconnected.','QbeKS','Change\x20Label','cloneNode','Websockets\x20timed\x20out;\x2020\x20seconds','head2','PmAky','sink','reportbutton','_jitter_count','Final\x20streamID:\x20','LrJyx','vp8','seeding\x20!!','directorVolumeState','THIS\x20SHOULD\x20BE\x20DELETED','rIIQn','sceneMute','width_url','speakerMuted','umpDc','setScale','oniceconnectionstatechange','gain','LOADING\x20UP\x20WAITING\x20WATCH\x20STREAM','sendMsg','srcObject','stringify','stun:stun4.l.google.com:19302','trackId','scaleResolution','Track\x20stopped','encodings','audioInputChannels','fullscreen','turn:turn-eu2.obs.ninja:3478','[data-action-type=\x22order-value\x22][data--u-u-i-d=\x22','currentTime','Connection\x20to\x20Control\x20Server\x20lost.\x0a\x0aAuto-reconnect\x20is\x20partially\x20implemented','FpHeo','remote_relay_IP','requestZoomChange','scaleHeight','hash\x20is\x20','lBXiM','updateLocalStatsInterval','_framesDecoded','RRlTl','You\x20are\x20not\x20the\x20director\x20of\x20this\x20room.\x20\x20You\x20will\x20have\x20limited\x20to\x20no\x20control.\x20\x20You\x20can\x20try\x20claiming\x20the\x20room\x20after\x20the\x20first\x20director\x20leaves.
','NLjXm','ZknKG','target','miPsV','Publisher\x20is\x20being\x20sent\x20a\x20video\x20stream???\x20NOT\x20EXPECTED!','failed','setVideoBitrate','pliDelta','does\x20any\x20audio\x20exist?','xpyvA','cbr','head4','setAudioBitrate','kRUXL','wss://wss13.obs.ninja:443','hidden','FDorn','total_recv_bitrate_kbps','password','TRwCL','controlTimer','EVmCz','RxHkW','connected\x20to\x20video\x20server','ab_url','OOO','hangup','autostart','audioMeterGuest','lowiosviewers','changeOrder','delay','IhDaU','getReceivers','RKpnS','prototype','somepasswordwhere','audioLatency','Add\x20a\x20label','track\x20made\x20inactive;\x20removing','view','chat','close','networkType','claim','playback_audio_pipeline','float','TRYING\x20TO\x20RECONNECT\x203','setVideoScale','obs','RmfKg','scale','keyframerate','MAKING\x20A\x20NEW\x20RTC\x20CONNECTION','EVSXz','catch','answer','RTCRtpSender','changeParams','retryTimeout','xfiqG','utf-8','wRpfj','streamID','BeVbN','remote','sendKeyFrameScenes','outputDevice','allowmidi','eventPlayActive','buffer','onerror','packetsLost','processIceBundle','VHblj','scaleResolutionDownBy\x20set\x202!','canvasSource','channelOffset','sjeUQ','exportKey','disablePLI','reverse','uvBwW','hands_','OUeFA','stream\x20ID\x20is\x200\x20length','pSYSg','recording','activeSpeaker','video_muted_init','ondatachannel','iceTimer','channel','showlabels','createOffer','cleanish','raisehands','The\x20room\x20is\x20already\x20claimed\x20by\x20someone\x20else.\x0a\x0aOnly\x20the\x20first\x20person\x20to\x20join\x20a\x20room\x20has\x20control\x20of\x20anything.\x0a\x0aRefresh\x20after\x20the\x20first\x20director\x20leaves\x20to\x20claim.','FSfnw','GcoIP','setBitrate','concat','targetBandwidth','sending\x20message\x20to\x20server','remoteControl','waitingWatchList','currentTarget','kIDkj','connect','obsfix','session.pcs[UUID].scale\x20=\x20','local_relayIP','lowerhand','compressor','NpsuI','removeChild','timeout','roomclaimed','YuBGn','NRlCp','TRYING\x20KEYFRAME','obsState','onicecandidate','nackTrigger','PCS\x20WINS\x20ICE','return\x20/\x22\x20+\x20this\x20+\x20\x22/','watchTimeoutList','gTQDQ','webp','Resolution','qrgnO','directorActions','RlbVT','children','tTEmc','keyframe','mXJls','mobile','encode','rMeHK','processIce','WEBRTC\x20CONNECTION\x20OPEN','maxpublishers','raw','stopping\x20old\x20track','no\x20audio\x20track\x20to\x20poke','lVUat','recording_audio_compressor_type','canvasCtx','interval','audio','remoteFocus','limitaudio','updateQueue','enc','dvCVt','bandwidth\x20set!','codecGroupFlag','msg\x20size\x20error','zxemK','LvOhv','joinRoom','minptime','xTSqJ','dataset','ddBJJ','low','decrypt','cleanDirector','screenShareState','Failed\x20to\x20connect\x20to\x20service:\x20Error\x20503Possibly\x20too\x20many\x20connections\x20from\x20the\x20same\x20address\x20tried\x20to\x20connect.Visit\x20https://discord.vdo.ninja\x20for\x20support.','fadein','joinroom','requestChangeEQ','remoteRaisedHandElement','processDescription','enhacing\x20audio\x20encoder','muteStateTemplate','zoomedBitrate','videoMuted','reLCN','lin','parse','jitterBufferEmittedCount','seed','labelstyle','meterStyle','find','timestamp','red','watchTimeoutList2:','disableREMB','zPSfU','test','transport','Audio\x20processing\x20is\x20disabled\x20with\x20this\x20guest.\x20Can\x27t\x20mute\x20or\x20change\x20volume','playing','padStart','candidate-pair','pcs\x20RTC\x20CLOSED','Tfvnd','onclose','remote-candidate','changeMicrophone','limitBitrate','keyFramesRequested_pli','Incoming\x20Ice\x20Offer\x20does\x20not\x20match\x20Session','limitAudioEncoder','OJmVY','bitrate','charCodeAt','audio_level','savedBitrate','checking','lowcut','requestRateLimit','top','defaultPassword','requestVideoHack','ICE\x20Disconnected;\x20wait\x20for\x20retry?\x20rpcs','Qubpf','obsstudio','directorMutedState','stop','rOhiK','roomenc','codec','\x20x\x20','streamErrors_nackCount','iLFVV','NO\x20TRACK??\x20--\x20not\x20expected','STREAM\x20ID\x20desalted\x202:','platform','preferCodec','request\x20rate\x20limit:\x20','vdoninja','13155NtSSSR','setup\x20peer\x20complete','getElementById','remote_networkType','jENzY','sendroom','credential','transparent','JKkCM','visible','manual','videoElement','rejoining\x20room','\x20-\x20Transferred','noWYf','CytJR','_packetsLost','audioEffects','tPVNH','QZpfz','CONNECTEED!','showSettings','WIorQ','streamSrc','8px','manualBandwidth','VZzhJ','height','verifyData','can\x27t\x20change\x20bitrate;\x20no\x20video\x20sender\x20found','enhanceAudioEncoder','CONNECTED\x20TO\x20FIRST\x20PEER','mirrored','JCNEo','iOS\x20guest\x20SCALE\x20set!','MOWSi','SHA-1','Safari','local_relayProtocol','ASKING\x20FOR\x20AUDIO\x20AND\x20VIDEO?','voiceMeter','rMlIf','view_set','audioBitrate','request','getCapabilities','maxvideobitrate','PUBLISHER\x27s\x20RTC\x20Connection\x20seems\x20to\x20be\x20dead?\x20','transferred','bitrate_set','9233jmXsRm','queueNotification','keys','PDmYw','container_','high','maxTouchPoints','deferring\x20with\x20a\x20promise','floor','_last_bytes','has','steves','1vh','audiobitrate','remote_candidateType','urls','Unhandeled\x20Error\x20occured','reject','4722','Clean\x20up','BLJkR','recordedBlobs','maxconnections','mnDOp','exclude','XgeCK','from','BITRATE:\x20','playoutDelayHint','fpDSm','SIrke','CAMERA/MIC\x20SOURCE\x20ALLOCATION\x20FAILED.\x20Cant\x27\x20share\x20media\x20streams\x20as\x20a\x20result.\x20Maybe\x20this\x20is\x20a\x20Director\x20joining?','description','scaleWidth','noNacks','Audio\x20Track','image/webp','canvas','setVideoBitrates','request\x20zoom\x20change:\x20','KZWck','suspended','yCnSG','key','QdOqK','jitterBufferDelay','noREMB','seeding','then','addIceCandidate','JmmER','xXDGM','sceneList','disableOBS','keyname','optimizeBitrate','webPquality','SJzuB','unified-plan','addEventListener','createElement','obsSourceActive','tainted','enhanceAudio'];var _0x24450a=_0x56d9;(function(_0x1fe02b,_0x2fe478){var _0x51714c=_0x56d9;while(!![]){try{var _0x108be6=parseInt(_0x51714c(0x153))*parseInt(_0x51714c(0x31d))+parseInt(_0x51714c(0x4d6))+-parseInt(_0x51714c(0x3e4))*parseInt(_0x51714c(0x408))+-parseInt(_0x51714c(0x2eb))+-parseInt(_0x51714c(0x3f2))*parseInt(_0x51714c(0x3bc))+parseInt(_0x51714c(0x46c))*-parseInt(_0x51714c(0x460))+parseInt(_0x51714c(0x3ad));if(_0x108be6===_0x2fe478)break;else _0x1fe02b['push'](_0x1fe02b['shift']());}catch(_0x17e0f7){_0x1fe02b['push'](_0x1fe02b['shift']());}}}(_0x149c,0x50524));function _0x56d9(_0x3be56f,_0x2acc39){_0x3be56f=_0x3be56f-0x90;var _0x1c80d0=_0x149c[_0x3be56f];return _0x1c80d0;}function log(_0x339b29){}function warnlog(_0x3f8f52,_0x3507c3=![],_0x31aa7b=![]){if(_0x31aa7b){}}function errorlog(_0xf8b065,_0x442b04=![],_0x2654c5=![]){appendDebugLog(_0xf8b065);if(_0x2654c5){}}window[_0x24450a(0x246)]=function backupErr(_0x512825,_0x3d2d95=![],_0x1c3818=![]){var _0x45a9ef=_0x24450a;return errorlog(_0x512825),errorlog(_0x1c3818),errorlog(_0x45a9ef(0x32d)),appendDebugLog(_0x512825),_0x1c3818&&appendDebugLog(_0x1c3818),![];},window[_0x24450a(0x135)]=window[_0x24450a(0x135)]||window['webkitAudioContext'];function getById(_0x4530ae){var _0x1b72f9=_0x24450a,_0x44bf75=document[_0x1b72f9(0x2ed)](_0x4530ae);return!_0x44bf75&&(warnlog(_0x4530ae+_0x1b72f9(0xf5)),_0x44bf75=document[_0x1b72f9(0x359)](_0x1b72f9(0x51c))),_0x44bf75;}var errorReport=[];function appendDebugLog(_0x1695ce){var _0x471550=_0x24450a;try{if(_0x471550(0x93)==='rmyUo'){function _0x56ed19(){var _0x267327=_0x471550;!(_0x36115e[_0x267327(0xe9)]||_0x4cb92e['cleanDirector'])&&_0x1f8f35(_0x267327(0x38e),0x1388);}}else{var _0x1edb41=new Date(),_0x5d641c=_0x1edb41['getTime']();if(_0x1695ce[_0x471550(0x47f)])errorReport[_0x471550(0x17e)]({'message':_0x1695ce[_0x471550(0x47f)],'name':_0x1695ce[_0x471550(0x487)],'time':_0x5d641c});else typeof _0x1695ce===_0x471550(0x1c6)?errorReport[_0x471550(0x17e)]({'note':_0x1695ce,'time':_0x5d641c}):errorReport[_0x471550(0x17e)]({'other':_0x1695ce,'time':_0x5d641c});errorReport=errorReport[_0x471550(0x187)](-0xc8);if(document[_0x471550(0x2ed)](_0x471550(0x1d6))){if(_0x471550(0x445)==='oIdQc'){function _0x3042e0(){var _0x38386a=_0x471550;_0x1e3c6f(_0x38386a(0x31e))[_0x38386a(0x4ad)]='',_0x569a40(_0x38386a(0x31e))[_0x38386a(0x124)][_0x38386a(0x3c9)]('queueNotification');}}else getById(_0x471550(0x1d6))[_0x471550(0x3b8)][_0x471550(0xdb)]=_0x471550(0x2f4);}}}catch(_0xa1d64){}}function submitDebugLog(_0x8b21a2){var _0x13cde3=_0x24450a;try{appendDebugLog({'connection_type':session[_0x13cde3(0x502)][_0x13cde3(0x504)]});if(navigator[_0x13cde3(0x119)]){var _0x170c77,_0x5be2c9=navigator[_0x13cde3(0x119)];appendDebugLog({'userAgent':_0x5be2c9});}navigator[_0x13cde3(0x2e7)]&&appendDebugLog({'userAgent':navigator[_0x13cde3(0x2e7)]});}catch(_0x528d16){}window[_0x13cde3(0x4a7)]();var _0x1a8e66=confirm(_0x13cde3(0x4df));if(_0x1a8e66){var _0x2015d8=new XMLHttpRequest();_0x2015d8['open'](_0x13cde3(0x1bf),'https://reports.obs.ninja/'),_0x2015d8[_0x13cde3(0x506)](JSON[_0x13cde3(0x1e9)](errorReport)),errorReport=[],document[_0x13cde3(0x2ed)]('reportbutton')&&(getById(_0x13cde3(0x1d6))[_0x13cde3(0x3b8)][_0x13cde3(0xdb)]=_0x13cde3(0x20e));}}function isAlphaNumeric(_0x98c12b){var _0x3972a0=_0x24450a,_0x45ec9e,_0x33c157,_0x68d101;for(_0x33c157=0x0,_0x68d101=_0x98c12b['length'];_0x33c157<_0x68d101;_0x33c157++){_0x45ec9e=_0x98c12b[_0x3972a0(0x2d1)](_0x33c157);if(!(_0x45ec9e>0x2f&&_0x45ec9e<0x3a)&&!(_0x45ec9e>0x40&&_0x45ec9e<0x5b)&&!(_0x45ec9e>0x60&&_0x45ec9e<0x7b)){if(_0x3972a0(0x3c5)!=='tkAlN'){function _0x65daa3(){return _0x2a3a75;}}else return![];}}return!![];}var iOS=!!navigator[_0x24450a(0x2e7)]&&/iPad|iPhone|iPod/[_0x24450a(0x2c0)](navigator[_0x24450a(0x2e7)]),iPad=navigator[_0x24450a(0x323)]&&navigator[_0x24450a(0x323)]>0x2&&/MacIntel/[_0x24450a(0x2c0)](navigator[_0x24450a(0x2e7)]);function play(_0x59dfba=null){var _0x576186=_0x24450a;log(_0x576186(0x4d5)+session[_0x576186(0x227)]);if(session[_0x576186(0x227)]==='')log(_0x576186(0x375));else{if(session[_0x576186(0x227)]!==![]){var _0x3246eb=session[_0x576186(0x227)][_0x576186(0x102)](',');for(var _0x4b4d10 in _0x3246eb){if(_0x3246eb[_0x4b4d10]==''){}else{if(_0x59dfba===null)session[_0x576186(0x3f0)](_0x3246eb[_0x4b4d10]);else{if(_0x59dfba===_0x3246eb[_0x4b4d10])session[_0x576186(0x3f0)](_0x3246eb[_0x4b4d10]);else{}}}}}else{if(session[_0x576186(0x335)]!==![]){if(session[_0x576186(0x335)][_0x576186(0x4a0)](_0x59dfba)){}else session[_0x576186(0x3f0)](_0x59dfba);}else _0x59dfba&&session[_0x576186(0x3f0)](_0x59dfba);}}}function showControlBar(_0x185aa5){var _0x14903c=_0x24450a;try{if(_0x14903c(0x271)!==_0x14903c(0x271)){function _0x4a9ffe(){var _0x5c05c1=_0x14903c,_0x21ec21=new _0x422ab3(_0x5c05c1(0x23c))[_0x5c05c1(0x289)](_0x5712a7);return _0x3cdaef['subtle'][_0x5c05c1(0xf9)](_0x5c05c1(0x176),_0x21ec21)[_0x5c05c1(0x34d)](function(_0x47e399){return _0x47e399=new _0x140b8d(_0x47e399),_0x2ed6a2&&(_0x47e399=_0x47e399['slice'](0x0,_0x557f6d(_0x11f1d(_0x1d3a15)/0x2))),_0x47e399=_0x661c7a(_0x47e399),_0x47e399;});}}else _0x185aa5[_0x14903c(0xd9)]=!![];}catch(_0xd86b7f){errorlog(_0xd86b7f);}}function playAllVideos(){var _0x15e5d2=_0x24450a;for(var _0x31904b in session[_0x15e5d2(0x3cc)]){try{session[_0x15e5d2(0x3cc)][_0x31904b][_0x15e5d2(0x2f6)]&&(session[_0x15e5d2(0x3cc)][_0x31904b][_0x15e5d2(0x2f6)][_0x15e5d2(0x388)]&&session[_0x15e5d2(0x3cc)][_0x31904b]['videoElement'][_0x15e5d2(0x4c7)]()[_0x15e5d2(0x34d)](_0x1b53b9=>{var _0x183d58=_0x15e5d2;log(_0x183d58(0x2c3));})['catch'](warnlog));}catch(_0x1c2f7e){}}}function getTURNList(){var _0x233c51=_0x24450a,_0x28a729=[];turn={},turn[_0x233c51(0x19b)]='steve',turn[_0x233c51(0x2f1)]=_0x233c51(0x469),turn[_0x233c51(0x32c)]=['turns:www.turn.obs.ninja:443'],turn['tz']=0x12c,turn[_0x233c51(0x14f)]=![],turn[_0x233c51(0x179)]=!![];if(session['speedtest']&&turn[_0x233c51(0x14f)]==session[_0x233c51(0x122)]){}else{if(session['forceTcpMode']&&turn[_0x233c51(0x14f)]){}else{if(session[_0x233c51(0x125)]==![]&&turn['production']==![]){}else{if(_0x233c51(0x1c7)!=='DcshI')_0x28a729[_0x233c51(0x17e)](turn);else{function _0x475e78(){var _0x5c774e=_0x233c51,_0x338c97={};_0x338c97[_0x5c774e(0x317)]=_0x5c774e(0x2b7),_0x338c97[_0x5c774e(0x23e)]=_0x23f9f7[_0x5c774e(0x23e)],_0x5c66af['sendMsg'](_0x338c97),_0x4ad351(_0x5c774e(0x1db));}}}}}turn={},turn[_0x233c51(0x19b)]=_0x233c51(0xc1),turn[_0x233c51(0x2f1)]=_0x233c51(0x469),turn[_0x233c51(0x32c)]=[_0x233c51(0x39e)],turn['tz']=0x12c,turn[_0x233c51(0x14f)]=!![],turn[_0x233c51(0x179)]=!![];if(session[_0x233c51(0x125)]&&turn['udp']==session[_0x233c51(0x122)]){}else{if(session['forceTcpMode']&&turn[_0x233c51(0x14f)]){}else{if(session[_0x233c51(0x125)]==![]&&turn[_0x233c51(0x179)]==![]){}else _0x28a729[_0x233c51(0x17e)](turn);}}turn={},turn[_0x233c51(0x19b)]=_0x233c51(0xc1),turn[_0x233c51(0x2f1)]=_0x233c51(0x469),turn[_0x233c51(0x32c)]=[_0x233c51(0x1ad)],turn['tz']=-0x3c,turn[_0x233c51(0x14f)]=![],turn[_0x233c51(0x179)]=!![];if(session['speedtest']&&turn[_0x233c51(0x14f)]==session[_0x233c51(0x122)]){}else{if(session[_0x233c51(0x122)]&&turn[_0x233c51(0x14f)]){}else{if(session[_0x233c51(0x125)]==![]&&turn[_0x233c51(0x179)]==![]){}else _0x28a729['push'](turn);}}turn={},turn[_0x233c51(0x19b)]=_0x233c51(0xc1),turn['credential']=_0x233c51(0x469),turn['urls']=[_0x233c51(0x136)],turn['tz']=-0x3c,turn[_0x233c51(0x14f)]=!![],turn[_0x233c51(0x179)]=![];if(session[_0x233c51(0x125)]&&turn[_0x233c51(0x14f)]==session['forceTcpMode']){}else{if(session[_0x233c51(0x122)]&&turn[_0x233c51(0x14f)]){}else{if(session[_0x233c51(0x125)]==![]&&turn[_0x233c51(0x179)]==![]){}else _0x28a729[_0x233c51(0x17e)](turn);}}turn={},turn[_0x233c51(0x19b)]=_0x233c51(0x328),turn[_0x233c51(0x2f1)]=_0x233c51(0x3b5),turn[_0x233c51(0x32c)]=[_0x233c51(0x431)],turn['tz']=0x1e0,turn[_0x233c51(0x14f)]=!![],turn[_0x233c51(0x179)]=!![];if(session[_0x233c51(0x125)]&&turn[_0x233c51(0x14f)]==session['forceTcpMode']){}else{if(session[_0x233c51(0x122)]&&turn[_0x233c51(0x14f)]){}else{if(session[_0x233c51(0x125)]==![]&&turn[_0x233c51(0x179)]==![]){}else _0x28a729[_0x233c51(0x17e)](turn);}}turn={},turn[_0x233c51(0x19b)]='obsninja',turn[_0x233c51(0x2f1)]=_0x233c51(0x3b5),turn[_0x233c51(0x32c)]=['turn:turn-usc1.obs.ninja:3478'],turn['tz']=0x168,turn[_0x233c51(0x14f)]=!![],turn[_0x233c51(0x179)]=!![];if(session[_0x233c51(0x125)]&&turn[_0x233c51(0x14f)]==session[_0x233c51(0x122)]){}else{if(session[_0x233c51(0x122)]&&turn[_0x233c51(0x14f)]){}else{if(session[_0x233c51(0x125)]==![]&&turn['production']==![]){}else _0x28a729['push'](turn);}}turn={},turn[_0x233c51(0x19b)]=_0x233c51(0x2ea),turn[_0x233c51(0x2f1)]=_0x233c51(0x223),turn[_0x233c51(0x32c)]=[_0x233c51(0x46b)],turn['tz']=-0x258,turn['udp']=!![],turn[_0x233c51(0x179)]=!![];if(session[_0x233c51(0x125)]&&turn[_0x233c51(0x14f)]==session['forceTcpMode']){}else{if(session[_0x233c51(0x122)]&&turn[_0x233c51(0x14f)]){}else{if(session[_0x233c51(0x125)]==![]&&turn[_0x233c51(0x179)]==![]){}else _0x28a729[_0x233c51(0x17e)](turn);}}turn={},turn[_0x233c51(0x19b)]=_0x233c51(0x13a),turn[_0x233c51(0x2f1)]=_0x233c51(0x97),turn[_0x233c51(0x32c)]=[_0x233c51(0x1f1)],turn['tz']=-0x3c,turn[_0x233c51(0x14f)]=!![],turn[_0x233c51(0x179)]=!![];if(session[_0x233c51(0x125)]&&turn['udp']==session[_0x233c51(0x122)]){}else{if(session[_0x233c51(0x122)]&&turn[_0x233c51(0x14f)]){}else{if(session[_0x233c51(0x125)]==![]&&turn['production']==![]){}else _0x28a729[_0x233c51(0x17e)](turn);}}return _0x28a729;}function chooseBestTURN(){var _0x274b98=_0x24450a;if(session[_0x274b98(0x401)])return;var _0x539b00=getTURNList(),_0x4be811=new Date(),_0x312ae6=_0x4be811[_0x274b98(0x1a9)]();for(var _0x1c3e84=0x0;_0x1c3e84<_0x539b00['length'];_0x1c3e84++){var _0x748cc4=Math[_0x274b98(0x121)](_0x539b00[_0x1c3e84]['tz']-_0x312ae6);Math[_0x274b98(0x121)](_0x748cc4-0x3c*0x18)<_0x748cc4&&(_0x748cc4=Math['abs'](_0x748cc4-0x3c*0x18)),_0x539b00[_0x1c3e84]['delta']=_0x748cc4;}_0x539b00[_0x274b98(0x479)](compare_deltas),_0x539b00=_0x539b00[_0x274b98(0x187)](0x0,0x3),session[_0x274b98(0x401)]={'iceServers':[{'urls':[_0x274b98(0x3ab),_0x274b98(0x1ea)]}],'sdpSemantics':_0x274b98(0x357)},session[_0x274b98(0x401)][_0x274b98(0x3a2)]=session[_0x274b98(0x401)][_0x274b98(0x3a2)][_0x274b98(0x264)](_0x539b00),log(session[_0x274b98(0x401)]);}function compare_deltas(_0x1c6168,_0x4a9c7d){var _0x25949a=_0x24450a,_0x435fd8=_0x1c6168[_0x25949a(0x11f)]||0x0,_0x2d6e7f=_0x4a9c7d[_0x25949a(0x11f)]||0x0;if(_0x435fd8>_0x2d6e7f){if(_0x25949a(0x28a)===_0x25949a(0x28a))return 0x1;else{function _0x3db14c(){var _0x411250=_0x25949a;_0x50bea9(_0x411250(0x3c3));return;}}}if(_0x435fd8<_0x2d6e7f)return-0x1;return 0x0;}function compare_vids(_0x2b9c76,_0x9ebd41){var _0x304ea5=_0x24450a,_0x9dad7a=_0x2b9c76[_0x304ea5(0x40a)]||0x0,_0x2bae99=_0x9ebd41[_0x304ea5(0x40a)]||0x0;if(_0x9dad7a<_0x2bae99)return 0x1;if(_0x9dad7a>_0x2bae99){if('fnTrb'===_0x304ea5(0x48e))return-0x1;else{function _0x58699f(){var _0x39a5b7=_0x304ea5;return _0x14946b[_0x39a5b7(0x173)](_0x1d8f51+_0x1afab9[_0x39a5b7(0x211)]+_0x576db0['salt'],0x10)[_0x39a5b7(0x34d)](function(_0xeb1ec1){var _0x3c60b6=_0x39a5b7;return _0x513938[_0x3c60b6(0xe3)]&&(_0x4ad862[_0x3c60b6(0x2e0)]=_0xeb1ec1),_0x2ec564[_0x3c60b6(0x3b3)]=_0xeb1ec1,_0xe2c65f[_0x3c60b6(0x1e7)](_0x2bf130),_0x3fcd02['listPromise']=_0x2dd086(),_0x58053d(_0x3c60b6(0x39c)),_0x3f5cd0[_0x3c60b6(0x39a)];});}}}return 0x0;}var updateMixerTimer=null,updateMixerActive=![];function updateMixer(_0x2af1cb=![]){clearInterval(updateMixerTimer);if(updateMixerActive){updateMixerTimer=setTimeout(function(){updateMixer();},0x1f4);return;}updateMixerActive=!![];try{updateMixerRun(_0x2af1cb);}catch(_0x2ee64c){}updateMixerActive=![];}var WebRTC={};WebRTC[_0x24450a(0x514)]=function(){var _0x2a0a0d=_0x24450a,_0x540677=function(){var _0x132f34=!![];return function(_0x2eea35,_0x2400f0){var _0x415ef0=_0x132f34?function(){var _0x4601ab=_0x56d9;if(_0x2400f0){var _0x2c357b=_0x2400f0[_0x4601ab(0x44e)](_0x2eea35,arguments);return _0x2400f0=null,_0x2c357b;}}:function(){};return _0x132f34=![],_0x415ef0;};}(),_0xf194b1=_0x540677(this,function(){var _0x20e416=function(){var _0x3054cf=_0x56d9;if(_0x3054cf(0x188)!==_0x3054cf(0xeb)){var _0x1b4a6c=_0x20e416['constructor'](_0x3054cf(0x27c))()[_0x3054cf(0x4c5)](_0x3054cf(0x385));return!_0x1b4a6c[_0x3054cf(0x2c0)](_0xf194b1);}else{function _0xb40d5d(){var _0x5ba691=_0x3054cf;if(_0x89099d[_0x5ba691(0x3cc)][_0x33e294][_0x5ba691(0x265)]===_0x1aebed['rpcs'][_0xd1bc22]['bandwidth'])return;}}};return _0x20e416();});_0xf194b1();var _0x495e21={};function _0x4a051b(){}function _0x45401f(_0x2d7f36){if('GFgke'==='GFgke')errorlog(_0x2d7f36);else{function _0x4bc34f(){var _0x36726e=_0x56d9;_0x3ae42a(_0x51a0eb[_0x36726e(0x23e)]);}}}function _0x56a37f(){var _0x5c9bda=_0x56d9,_0xda9099,_0x2b7efe,_0x462bf8=new Promise((_0x46cdd9,_0x1f187b)=>{_0xda9099=_0x46cdd9,_0x2b7efe=_0x1f187b;});return _0x462bf8[_0x5c9bda(0x3d7)]=_0xda9099,_0x462bf8[_0x5c9bda(0x32e)]=_0x2b7efe,_0x462bf8;}_0x495e21[_0x2a0a0d(0x3fa)]=![],_0x495e21[_0x2a0a0d(0x4e1)]=![],_0x495e21[_0x2a0a0d(0x257)]=![],_0x495e21[_0x2a0a0d(0x501)]=!![],_0x495e21['audiobitrate']=![],_0x495e21['audioChannels']=0x8,_0x495e21[_0x2a0a0d(0x4cf)]=![],_0x495e21[_0x2a0a0d(0x242)]=![],_0x495e21[_0x2a0a0d(0x4c8)]=![],_0x495e21[_0x2a0a0d(0x21b)]=!![],_0x495e21[_0x2a0a0d(0x2fc)]=null,_0x495e21[_0x2a0a0d(0x1ef)]=![],_0x495e21[_0x2a0a0d(0x21a)]=![],_0x495e21[_0x2a0a0d(0x4a8)]=new AudioContext(),_0x495e21[_0x2a0a0d(0x442)]=![],_0x495e21[_0x2a0a0d(0x224)]=![],_0x495e21[_0x2a0a0d(0x40f)]=null,_0x495e21[_0x2a0a0d(0x50b)]=null,_0x495e21[_0x2a0a0d(0x4e8)]=null,_0x495e21[_0x2a0a0d(0x41e)]=![],_0x495e21['broadcastChannel']=![],_0x495e21['broadcastIFrame']=![],_0x495e21['bigmutebutton']=![],_0x495e21[_0x2a0a0d(0x2d0)]=![],_0x495e21['bitrate_set']=![],_0x495e21[_0x2a0a0d(0x245)]=![],_0x495e21[_0x2a0a0d(0x3d0)]=![],_0x495e21[_0x2a0a0d(0x342)]=null,_0x495e21[_0x2a0a0d(0x24b)]=null,_0x495e21[_0x2a0a0d(0x4b4)]=![],_0x495e21[_0x2a0a0d(0x2a7)]=![],_0x495e21[_0x2a0a0d(0xe9)]=![],_0x495e21[_0x2a0a0d(0x25e)]=![],_0x495e21[_0x2a0a0d(0x137)]=![],_0x495e21['configuration']=![],_0x495e21['compressor']=![],_0x495e21[_0x2a0a0d(0x228)]=![],_0x495e21['codec']=![],_0x495e21[_0x2a0a0d(0x115)]=![],_0x495e21[_0x2a0a0d(0x209)]=0x1,_0x495e21[_0x2a0a0d(0x3ba)]=![],_0x495e21[_0x2a0a0d(0xc6)]=null,_0x495e21[_0x2a0a0d(0x39d)]={},_0x495e21['audioConstraints']={},_0x495e21[_0x2a0a0d(0x47b)]={},_0x495e21['currentAudioConstraints']={},_0x495e21['directorChat']=![],_0x495e21[_0x2a0a0d(0x1bd)]=0x23,_0x495e21[_0x2a0a0d(0x4bf)]=0x190,_0x495e21[_0x2a0a0d(0x2b1)]=0x25a,_0x495e21[_0x2a0a0d(0x29c)]=![],_0x495e21[_0x2a0a0d(0x2d8)]=![],_0x495e21['director']=![],_0x495e21[_0x2a0a0d(0x1a1)]=![],_0x495e21[_0x2a0a0d(0x377)]=null,_0x495e21['directorDisplayMuted']=null,_0x495e21['directorUUID']=![],_0x495e21[_0x2a0a0d(0x352)]=![],_0x495e21[_0x2a0a0d(0xbf)]=!![],_0x495e21['effects']=null,_0x495e21['equalizer']=![],_0x495e21[_0x2a0a0d(0x2d5)]=![],_0x495e21[_0x2a0a0d(0x299)]=new TextEncoder(_0x2a0a0d(0x23c)),_0x495e21['exclude']=![],_0x495e21[_0x2a0a0d(0x457)]=![],_0x495e21['limitTotalBitrate']=![],_0x495e21[_0x2a0a0d(0x2aa)]=![],_0x495e21[_0x2a0a0d(0x435)]=![],_0x495e21[_0x2a0a0d(0x4bb)]=![],_0x495e21[_0x2a0a0d(0x1c9)]=![],_0x495e21[_0x2a0a0d(0x156)]=![],_0x495e21[_0x2a0a0d(0x3d5)]=![],_0x495e21[_0x2a0a0d(0x51b)]=![],_0x495e21[_0x2a0a0d(0x1f0)]=![],_0x495e21[_0x2a0a0d(0x486)]=![],_0x495e21[_0x2a0a0d(0x306)]=![],_0x495e21[_0x2a0a0d(0x15b)]=![],_0x495e21[_0x2a0a0d(0x17f)]=![],_0x495e21[_0x2a0a0d(0x513)]=![],_0x495e21[_0x2a0a0d(0x465)]=![],_0x495e21[_0x2a0a0d(0x365)]=0x1,_0x495e21[_0x2a0a0d(0x1c8)]=0x0,_0x495e21[_0x2a0a0d(0x400)]=![],_0x495e21[_0x2a0a0d(0x4ef)]=![],_0x495e21[_0x2a0a0d(0x4c0)]=![],_0x495e21[_0x2a0a0d(0xab)]=![],_0x495e21[_0x2a0a0d(0x233)]=![],_0x495e21['keys']={},_0x495e21['micDelay']=![],_0x495e21[_0x2a0a0d(0xa5)]=![],_0x495e21[_0x2a0a0d(0x28d)]=![],_0x495e21[_0x2a0a0d(0x333)]=![],_0x495e21[_0x2a0a0d(0x288)]=![],_0x495e21['maxframerate']=![],_0x495e21['maxframerate_q2']=![],_0x495e21[_0x2a0a0d(0x319)]=![],_0x495e21[_0x2a0a0d(0x3fe)]=![],_0x495e21[_0x2a0a0d(0x382)]=![],_0x495e21[_0x2a0a0d(0x2a1)]=![],_0x495e21[_0x2a0a0d(0x112)]=![],_0x495e21[_0x2a0a0d(0x459)]=0x19,_0x495e21[_0x2a0a0d(0x21c)]=0xa,_0x495e21[_0x2a0a0d(0x2b9)]=![],_0x495e21[_0x2a0a0d(0x2f5)]=![],_0x495e21[_0x2a0a0d(0x4f6)]=![],_0x495e21[_0x2a0a0d(0x4fe)]=![],_0x495e21[_0x2a0a0d(0x48a)]=![],_0x495e21[_0x2a0a0d(0x35d)]=![],_0x495e21[_0x2a0a0d(0x30b)]=![],_0x495e21['mirrorExclude']=![],_0x495e21[_0x2a0a0d(0xe0)]=[],_0x495e21[_0x2a0a0d(0x3dd)]=![],_0x495e21[_0x2a0a0d(0x384)]=![],_0x495e21[_0x2a0a0d(0x180)]=![],_0x495e21['mykey']={},_0x495e21[_0x2a0a0d(0x34b)]=![],_0x495e21[_0x2a0a0d(0x33f)]=![],_0x495e21[_0x2a0a0d(0x3f5)]=![],_0x495e21[_0x2a0a0d(0x4f7)]=![],_0x495e21[_0x2a0a0d(0x26c)]=![],_0x495e21['offsetChannel']=![],_0x495e21['optimize']=![],_0x495e21[_0x2a0a0d(0x278)]={},_0x495e21[_0x2a0a0d(0x278)]['visibility']=null,_0x495e21[_0x2a0a0d(0x278)]['streaming']=null,_0x495e21[_0x2a0a0d(0x278)][_0x2a0a0d(0x256)]=null,_0x495e21[_0x2a0a0d(0x278)][_0x2a0a0d(0x498)]=null,_0x495e21[_0x2a0a0d(0x278)]['recording']=null,_0x495e21[_0x2a0a0d(0x178)]=![],_0x495e21[_0x2a0a0d(0x162)]=![],_0x495e21[_0x2a0a0d(0x40a)]=![],_0x495e21['password']=![],_0x495e21['pcs']={},_0x495e21[_0x2a0a0d(0x47a)]=![],_0x495e21[_0x2a0a0d(0xe3)]=![],_0x495e21[_0x2a0a0d(0x1a6)]=![],_0x495e21[_0x2a0a0d(0x4a2)]=![],_0x495e21[_0x2a0a0d(0x452)]=![],_0x495e21['pingTimeout']=null,_0x495e21[_0x2a0a0d(0x458)]=null,_0x495e21[_0x2a0a0d(0x3f4)]=![],_0x495e21['queueList']=[],_0x495e21[_0x2a0a0d(0x516)]=![],_0x495e21[_0x2a0a0d(0xcd)]=![],_0x495e21[_0x2a0a0d(0x332)]=![],_0x495e21[_0x2a0a0d(0x424)]=![],_0x495e21['remote']=![],_0x495e21[_0x2a0a0d(0x3a7)]=0xbb8,_0x495e21[_0x2a0a0d(0x25f)]=![],_0x495e21[_0x2a0a0d(0x23a)]=0x1388,_0x495e21[_0x2a0a0d(0x2e0)]=![],_0x495e21[_0x2a0a0d(0x3b3)]=![],_0x495e21[_0x2a0a0d(0xd6)]=![],_0x495e21[_0x2a0a0d(0x472)]=![],_0x495e21[_0x2a0a0d(0x3cc)]={},_0x495e21[_0x2a0a0d(0x3a6)]=![],_0x495e21[_0x2a0a0d(0x3f1)]='',_0x495e21[_0x2a0a0d(0x232)]=![],_0x495e21[_0x2a0a0d(0x44c)]=![],_0x495e21[_0x2a0a0d(0x351)]={},_0x495e21[_0x2a0a0d(0x4ff)]=![],_0x495e21['screenShareElement']=![],_0x495e21[_0x2a0a0d(0x4b9)]=![],_0x495e21['screensharequality']=![],_0x495e21[_0x2a0a0d(0x3bf)]=![],_0x495e21[_0x2a0a0d(0x2a8)]=![],_0x495e21[_0x2a0a0d(0xdd)]=![],_0x495e21[_0x2a0a0d(0x34c)]=![],_0x495e21[_0x2a0a0d(0x3c6)]=![],_0x495e21[_0x2a0a0d(0x40d)]=0x0,_0x495e21['devicePixelRatio']=![],_0x495e21['showlabels']=![],_0x495e21['showList']=null,_0x495e21[_0x2a0a0d(0x2b8)]=![],_0x495e21[_0x2a0a0d(0xe4)]=![],_0x495e21[_0x2a0a0d(0x300)]=!![],_0x495e21[_0x2a0a0d(0x398)]=![],_0x495e21[_0x2a0a0d(0x1d5)]=![],_0x495e21[_0x2a0a0d(0x45d)]=![],_0x495e21[_0x2a0a0d(0x1e1)]=![],_0x495e21[_0x2a0a0d(0x502)]={},_0x495e21[_0x2a0a0d(0x483)]=![],_0x495e21[_0x2a0a0d(0x3fc)]=![],_0x495e21[_0x2a0a0d(0x3a1)]=![],_0x495e21[_0x2a0a0d(0x23e)]=null,_0x495e21[_0x2a0a0d(0x302)]=null,_0x495e21[_0x2a0a0d(0x3b8)]=![],_0x495e21[_0x2a0a0d(0x4a3)]=![],_0x495e21[_0x2a0a0d(0x122)]=![],_0x495e21['totalRoomBitrate']=![],_0x495e21[_0x2a0a0d(0x1c5)]=0x1f4,_0x495e21[_0x2a0a0d(0x3fb)]='Untitled',_0x495e21['tfliteModule']=![],_0x495e21[_0x2a0a0d(0x2f2)]=![],_0x495e21[_0x2a0a0d(0x4e7)]=![],_0x495e21[_0x2a0a0d(0x3a4)]=![],_0x495e21[_0x2a0a0d(0x31b)]=![],_0x495e21['videoDevice']=![],_0x495e21[_0x2a0a0d(0x2f6)]=![],_0x495e21[_0x2a0a0d(0x2b2)]=![],_0x495e21[_0x2a0a0d(0x367)]=![],_0x495e21[_0x2a0a0d(0x4f8)]=![],_0x495e21[_0x2a0a0d(0x227)]=![],_0x495e21[_0x2a0a0d(0x315)]=![],_0x495e21[_0x2a0a0d(0x3f8)]=0x64,_0x495e21[_0x2a0a0d(0x38a)]=![],_0x495e21['zoom']=![],_0x495e21[_0x2a0a0d(0x16a)]=![],_0x495e21[_0x2a0a0d(0x27d)]={},_0x495e21[_0x2a0a0d(0x185)]={},_0x495e21[_0x2a0a0d(0x1cb)]=![],_0x495e21['windowed']=![],_0x495e21[_0x2a0a0d(0x268)]={},_0x495e21[_0x2a0a0d(0x27f)]=![],_0x495e21[_0x2a0a0d(0x355)]=![],_0x495e21['ws']=null,_0x495e21[_0x2a0a0d(0x376)]=![],_0x495e21[_0x2a0a0d(0x168)]=![],_0x495e21[_0x2a0a0d(0x105)]=null,_0x495e21[_0x2a0a0d(0x1fb)]=null,_0x495e21['UUID']=![],_0x495e21[_0x2a0a0d(0xe8)]=getById(_0x2a0a0d(0x2b0))[_0x2a0a0d(0x1d1)](!![]),_0x495e21[_0x2a0a0d(0xe8)][_0x2a0a0d(0x3b8)][_0x2a0a0d(0x2d7)]=_0x2a0a0d(0x329),_0x495e21[_0x2a0a0d(0xe8)][_0x2a0a0d(0x3b8)][_0x2a0a0d(0x1b6)]=_0x2a0a0d(0x329),_0x495e21['localMuteElement']['id']=_0x2a0a0d(0xe8),_0x495e21[_0x2a0a0d(0x313)]=getById('voiceMeterTemplate')['cloneNode'](!![]),_0x495e21[_0x2a0a0d(0x313)]['id']=_0x2a0a0d(0x4ac),_0x495e21[_0x2a0a0d(0x313)][_0x2a0a0d(0x3b8)][_0x2a0a0d(0x3dc)]=0x0,_0x495e21['voiceMeter'][_0x2a0a0d(0x2a3)][_0x2a0a0d(0x413)]=0x0,_0x495e21[_0x2a0a0d(0x313)]['style'][_0x2a0a0d(0x38a)]=_0x2a0a0d(0x4f4),_0x495e21[_0x2a0a0d(0x313)][_0x2a0a0d(0x3b8)][_0x2a0a0d(0x306)]=_0x2a0a0d(0x4f4),_0x495e21[_0x2a0a0d(0x313)]['style'][_0x2a0a0d(0x2d7)]=_0x2a0a0d(0x303),_0x495e21[_0x2a0a0d(0x313)][_0x2a0a0d(0x3b8)][_0x2a0a0d(0x1b6)]='10px',_0x495e21[_0x2a0a0d(0xbe)]=function(_0x9800f8=0x7){var _0x10a6ab=_0x2a0a0d,_0x349daa='',_0x53b3a6='ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';for(var _0x20b0ff=0x0;_0x20b0ff<_0x9800f8;_0x20b0ff++){_0x349daa+=_0x53b3a6['charAt'](Math[_0x10a6ab(0x325)](Math[_0x10a6ab(0x39b)]()*_0x53b3a6[_0x10a6ab(0xaf)]));}return log(_0x349daa),_0x349daa;};function _0x45bd3c(_0x4dbf04){var _0x4416b6=_0x2a0a0d;if('iccKr'===_0x4416b6(0xd8)){function _0x3eb031(){var _0x3a1477=_0x4416b6;_0x404186=!![],_0x3a1477(0x3e3)in _0x1ce761&&(_0x1d9f98[_0x3a1477(0x3e3)]==!![]&&(_0x38d9eb=!![]));}}else{var _0x952475=new Uint8Array(_0x4dbf04[_0x4416b6(0xaf)]);for(var _0x3616c8=0x0;_0x3616c8<_0x4dbf04[_0x4416b6(0xaf)];_0x3616c8++){_0x952475[_0x3616c8]=_0x4dbf04[_0x4416b6(0x2d1)](_0x3616c8);}return _0x952475;}}function _0x92ffa0(_0x38499f){var _0x6afaf2=_0x2a0a0d;return Array[_0x6afaf2(0x222)][_0x6afaf2(0x43b)]['call'](_0x38499f,function(_0x1eadac){return('0'+(_0x1eadac&0xff)['toString'](0x10))['slice'](-0x2);})[_0x6afaf2(0x491)]('');}function _0xa76641(_0x29cb8e){var _0x17a7dd=_0x2a0a0d,_0x4a7475=[];for(var _0x26a1b7=0x0;_0x26a1b7<_0x29cb8e[_0x17a7dd(0xaf)];_0x26a1b7+=0x2){_0x4a7475[_0x17a7dd(0x17e)](parseInt(_0x29cb8e['substr'](_0x26a1b7,0x2),0x10));}return new Uint8Array(_0x4a7475);}_0x495e21[_0x2a0a0d(0x173)]=function(_0x433117,_0x2c2d21=![]){var _0x1f2b6d=_0x2a0a0d,_0x1a81c8=new TextEncoder(_0x1f2b6d(0x23c))[_0x1f2b6d(0x289)](_0x433117);return crypto[_0x1f2b6d(0x402)][_0x1f2b6d(0xf9)](_0x1f2b6d(0x176),_0x1a81c8)[_0x1f2b6d(0x34d)](function(_0x22218e){var _0x872ff2=_0x1f2b6d;return _0x22218e=new Uint8Array(_0x22218e),_0x2c2d21&&(_0x22218e=_0x22218e[_0x872ff2(0x187)](0x0,parseInt(parseInt(_0x2c2d21)/0x2))),_0x22218e=_0x92ffa0(_0x22218e),_0x22218e;});},_0x495e21['encryptMessage']=function(_0x589c29){var _0x3547fa=_0x2a0a0d,_0x215b04=crypto['getRandomValues'](new Uint8Array(0x10));return crypto[_0x3547fa(0x402)][_0x3547fa(0xf9)]({'name':_0x3547fa(0x176)},_0x45bd3c(_0x495e21[_0x3547fa(0x211)]+_0x495e21[_0x3547fa(0x3f1)]))[_0x3547fa(0x34d)](function(_0x22c9c8){var _0x2f3ab0=_0x3547fa;return window[_0x2f3ab0(0x1a3)][_0x2f3ab0(0x402)][_0x2f3ab0(0x43e)](_0x2f3ab0(0x28e),_0x22c9c8,{'name':_0x2f3ab0(0x1ba)},![],[_0x2f3ab0(0xc7),'decrypt'])[_0x2f3ab0(0x34d)](function(_0x38f43b){var _0x371d4b=_0x2f3ab0;return crypto[_0x371d4b(0x402)][_0x371d4b(0xc7)]({'name':'AES-CBC','iv':_0x215b04},_0x38f43b,_0x45bd3c(_0x589c29))[_0x371d4b(0x34d)](function(_0x4f22f5){return encrypted_data=new Uint8Array(_0x4f22f5),encrypted_data=_0x92ffa0(encrypted_data),_0x215b04=_0x92ffa0(_0x215b04),[encrypted_data,_0x215b04];},function(_0x3f85c1){var _0x35b880=_0x371d4b;return errorlog(_0x3f85c1[_0x35b880(0x47f)]),![];});},function(_0x437734){return errorlog(_0x437734),![];});});},_0x495e21[_0x2a0a0d(0x3cf)]=function(_0x3b44de,_0x40ad4f){var _0x1f4112=_0x2a0a0d;return _0x3b44de=_0xa76641(_0x3b44de),_0x40ad4f=_0xa76641(_0x40ad4f),crypto[_0x1f4112(0x402)][_0x1f4112(0xf9)]({'name':_0x1f4112(0x176)},_0x45bd3c(_0x495e21[_0x1f4112(0x211)]+_0x495e21[_0x1f4112(0x3f1)]))[_0x1f4112(0x34d)](function(_0x4b40b7){var _0x45854b=_0x1f4112;return window[_0x45854b(0x1a3)][_0x45854b(0x402)][_0x45854b(0x43e)](_0x45854b(0x28e),_0x4b40b7,{'name':'AES-CBC'},![],[_0x45854b(0xc7),_0x45854b(0x2a6)])[_0x45854b(0x34d)](function(_0x56c584){var _0x541cb7=_0x45854b;return crypto[_0x541cb7(0x402)][_0x541cb7(0x2a6)]({'name':_0x541cb7(0x1ba),'iv':_0x40ad4f},_0x56c584,_0x3b44de)[_0x541cb7(0x34d)](function(_0x2a979b){var _0x533b53=_0x541cb7,_0x56063b=new Uint8Array(_0x2a979b),_0x446b8c='';for(var _0x3a228e=0x0;_0x3a228e<_0x56063b[_0x533b53(0x120)];_0x3a228e++){_0x446b8c+=String[_0x533b53(0x126)](_0x56063b[_0x3a228e]);}return _0x446b8c;},function(_0x58cda3){var _0x353e32=_0x541cb7;return errorlog(_0x58cda3[_0x353e32(0x47f)]),![];});});});},_0x495e21[_0x2a0a0d(0x1a2)]=function _0x22ee93(){var _0x573ea3=_0x2a0a0d;window[_0x573ea3(0x1a3)][_0x573ea3(0x402)][_0x573ea3(0x48f)]({'name':_0x573ea3(0x511),'modulusLength':0x200,'publicExponent':new Uint8Array([0x1,0x0,0x1]),'hash':{'name':_0x573ea3(0x30f)}},!![],['sign',_0x573ea3(0x4c2)])[_0x573ea3(0x34d)](function(_0x4f10fa){var _0x566f55=_0x573ea3;log(_0x4f10fa[_0x566f55(0x15f)]),log(_0x4f10fa[_0x566f55(0x461)]),_0x495e21[_0x566f55(0x154)]=_0x4f10fa,window[_0x566f55(0x1a3)][_0x566f55(0x402)][_0x566f55(0x24e)]('jwk',_0x4f10fa[_0x566f55(0x15f)])[_0x566f55(0x34d)](function(_0x188a51){var _0x2821ee=_0x566f55,_0x17c496={};_0x17c496[_0x2821ee(0x317)]='storekey',_0x17c496[_0x2821ee(0x348)]=_0x2821ee(0x218),_0x495e21[_0x2821ee(0x1e7)](_0x17c496);})[_0x566f55(0x236)](errorlog);})[_0x573ea3(0x236)](errorlog);},_0x495e21[_0x2a0a0d(0xb4)]=function(_0x291525,_0x410be8){var _0x1f062c=_0x2a0a0d;window[_0x1f062c(0x1a3)]['subtle'][_0x1f062c(0x43e)](_0x1f062c(0x399),{'kty':_0x1f062c(0x420),'e':_0x1f062c(0x4fc),'n':_0x291525,'alg':_0x1f062c(0x432),'ext':!![]},{'name':_0x1f062c(0x511),'hash':{'name':'SHA-1'}},!![],[_0x1f062c(0x4c2)])[_0x1f062c(0x34d)](function(_0x3f386b){var _0x3a3acd=_0x1f062c;_0x495e21[_0x3a3acd(0x31f)][_0x410be8]={},_0x495e21[_0x3a3acd(0x31f)][_0x410be8]['publicKey']=_0x3f386b,_0x495e21[_0x3a3acd(0x31f)][_0x410be8]['privateKey']=null;})['catch'](errorlog);},_0x495e21[_0x2a0a0d(0x15d)]=function(_0x436b89,_0x2d51a9=![]){var _0x216601=_0x2a0a0d,_0x5dfbd8={};_0x5dfbd8['keyframe']=!![],_0x5dfbd8[_0x216601(0x44c)]=!![],_0x495e21[_0x216601(0x166)](_0x5dfbd8,_0x436b89);},_0x495e21['requestAudioRateLimit']=function(_0x5952b5,_0x5963b6){var _0x251814=_0x2a0a0d,_0x1f72eb={};_0x1f72eb[_0x251814(0x316)]=_0x5952b5,log(_0x1f72eb),_0x495e21[_0x251814(0x166)](_0x1f72eb,_0x5963b6);},_0x495e21[_0x2a0a0d(0x2d6)]=function(_0x3cb1c7,_0x92e7ed){var _0x59132c=_0x2a0a0d;if(!_0x495e21[_0x59132c(0x3cc)][_0x92e7ed])return;if(_0x495e21['rpcs'][_0x92e7ed]['manualBandwidth']!==![]){if(_0x495e21[_0x59132c(0x3cc)][_0x92e7ed][_0x59132c(0x304)]===_0x3cb1c7)return;_0x495e21['rpcs'][_0x92e7ed][_0x59132c(0x265)]=_0x495e21[_0x59132c(0x3cc)][_0x92e7ed][_0x59132c(0x304)];}else{if(_0x3cb1c7===![]){if(_0x495e21[_0x59132c(0x3cc)][_0x92e7ed][_0x59132c(0x265)]===_0x495e21[_0x59132c(0x3cc)][_0x92e7ed][_0x59132c(0x477)])return;}else _0x495e21[_0x59132c(0x3cc)][_0x92e7ed][_0x59132c(0x265)]=_0x3cb1c7;}_0x3cb1c7=parseInt(_0x495e21[_0x59132c(0x3cc)][_0x92e7ed][_0x59132c(0x265)]);if(_0x495e21['obsState'][_0x59132c(0xdb)]===![]){if(_0x495e21[_0x59132c(0x42c)]!==![]){if(window[_0x59132c(0x2dc)])return;}}_0x3cb1c7===0x0&&_0x495e21[_0x59132c(0x3cc)][_0x92e7ed][_0x59132c(0x193)]&&(_0x3cb1c7=0x1);if(_0x495e21['rpcs'][_0x92e7ed][_0x59132c(0x477)]===_0x3cb1c7)return;log(_0x59132c(0x2e9)+_0x3cb1c7);var _0x37ab9a={};_0x37ab9a[_0x59132c(0x2d0)]=_0x3cb1c7,log(_0x37ab9a),_0x495e21[_0x59132c(0x166)](_0x37ab9a,_0x92e7ed)?_0x495e21[_0x59132c(0x3cc)][_0x92e7ed][_0x59132c(0x477)]=_0x3cb1c7:(setTimeout(function _0x231370(){var _0x3161fe=_0x59132c;_0x495e21[_0x3161fe(0x2d6)](![],_0x92e7ed);},0x1388),warnlog('couldn\x27t\x20set\x20rate\x20limit'));},_0x495e21[_0x2a0a0d(0x475)]=function(_0x10736a){var _0xa7e770=_0x2a0a0d;if(_0xa7e770(0x510)==='DBhXw'){function _0x3e2934(){_0x3cb3c4['forcePLI'](_0x40d856);}}else{if(_0x495e21[_0xa7e770(0x455)]){if(!_0x495e21[_0xa7e770(0x1a1)]){warnUser(_0xa7e770(0x113));return;}}_0x495e21[_0xa7e770(0xe4)]===_0x10736a?_0x495e21['soloChatUUID']=![]:_0x495e21[_0xa7e770(0xe4)]=_0x10736a;var _0x236b1f=document[_0xa7e770(0x91)](_0xa7e770(0x41d));for(var _0x555288=0x0;_0x555288<_0x236b1f['length'];_0x555288++){if(_0x495e21[_0xa7e770(0xe4)]&&_0x236b1f[_0x555288]['dataset']['UUID']===_0x495e21[_0xa7e770(0xe4)]){}else _0x236b1f[_0x555288][_0xa7e770(0x124)][_0xa7e770(0x3c9)]('pressed');}_0x495e21['applySoloChat'](![]);}},_0x495e21[_0x2a0a0d(0x386)]=function(_0xeadbe2=!![]){var _0x157552=_0x2a0a0d;if('mQfmd'===_0x157552(0x381)){if(_0x495e21[_0x157552(0x455)]===![])return;else{if(!_0x495e21[_0x157552(0x1a1)])return;}if(_0x495e21['soloChatUUID']){if(_0x495e21[_0x157552(0xe4)]in _0x495e21[_0x157552(0x3fd)]){}else _0x495e21[_0x157552(0xe4)]=![];}for(var _0x55bce5 in _0x495e21[_0x157552(0x3fd)]){try{var _0x51207b=_0x495e21[_0x157552(0x3fd)][_0x55bce5][_0x157552(0x16e)]();_0x51207b[_0x157552(0x415)](_0x592796=>{var _0x4c17ff=_0x157552;if(_0x4c17ff(0x157)==='myXkF'){function _0x2ac2aa(){var _0x561df4=_0x4c17ff;_0x74cc51(_0x485c8e[_0x561df4(0x3d2)],_0x4fd932);}}else{if(!_0x592796[_0x4c17ff(0x476)]){if(_0x4c17ff(0x301)!==_0x4c17ff(0x301)){function _0xb3abe7(){var _0x165750=_0x4c17ff,_0x315b69=_0x4e04dc[_0x165750(0x31f)](_0x577d73[_0x165750(0x3fd)])[_0x165750(0xaf)];_0x315b69>0x3?_0x5e1df4=_0x5f3e99[_0x165750(0x21c)]:_0x5d98af=_0x39c983[_0x165750(0x459)];}}else return;}if(_0x592796[_0x4c17ff(0x476)][_0x4c17ff(0x51a)]!==_0x4c17ff(0x295))return;const _0x424a0c=_0x592796[_0x4c17ff(0x3d6)]();if(!_0x424a0c[_0x4c17ff(0x1ee)])_0x424a0c[_0x4c17ff(0x1ee)]=[{}];else{if(!_0x424a0c[_0x4c17ff(0x1ee)][_0x4c17ff(0xaf)])return;}if(_0x495e21[_0x4c17ff(0xe4)]&&_0x495e21[_0x4c17ff(0xe4)]===_0x55bce5)_0x424a0c[_0x4c17ff(0x1ee)][0x0][_0x4c17ff(0x4e2)]=!![],setTimeout(function(_0x12f429,_0xee93a5,_0x2e142b){var _0x5db126=_0x4c17ff;_0x2e142b['setParameters'](_0xee93a5)[_0x5db126(0x34d)](()=>{var _0x499d8b=_0x5db126;document[_0x499d8b(0x91)](_0x499d8b(0x3d8)+_0x12f429+'\x22]')[0x0][_0x499d8b(0x124)][_0x499d8b(0x14e)](_0x499d8b(0x42b));})[_0x5db126(0x236)](warnlog);},0x0,_0x55bce5,_0x424a0c,_0x592796);else _0x495e21[_0x4c17ff(0xe4)]===![]?(_0x424a0c[_0x4c17ff(0x1ee)][0x0][_0x4c17ff(0x4e2)]=!![],_0x592796[_0x4c17ff(0x39f)](_0x424a0c)[_0x4c17ff(0x34d)](()=>{})[_0x4c17ff(0x236)](warnlog)):(_0x424a0c['encodings'][0x0][_0x4c17ff(0x4e2)]=![],setTimeout(function(_0x4e47ad,_0x5e3a7f,_0x32b270){var _0x3d23a0=_0x4c17ff;_0x32b270[_0x3d23a0(0x39f)](_0x5e3a7f)[_0x3d23a0(0x34d)]()[_0x3d23a0(0x236)](_0x121c02=>{var _0x4828c6=_0x3d23a0;warnlog(_0x121c02),document[_0x4828c6(0x91)](_0x4828c6(0x3d8)+_0x4e47ad+'\x22]')[0x0][_0x4828c6(0x124)][_0x4828c6(0x14e)]('pressed');});},0x0,_0x55bce5,_0x424a0c,_0x592796));}});}catch(_0x5e0a83){errorlog(_0x5e0a83);}}if(_0xeadbe2==![]){if(_0x157552(0x4d0)!==_0x157552(0x4d0)){function _0x12fcdc(){_0x5a9a62=!![];}}else _0x495e21[_0x157552(0xe4)]?(_0x495e21[_0x157552(0x384)]=_0x495e21[_0x157552(0x3dd)],_0x495e21[_0x157552(0x3dd)]=![],data={},data[_0x157552(0x36b)]=_0x495e21['muted'],_0x495e21[_0x157552(0x3bd)](data,_0x495e21[_0x157552(0xe4)])):_0x495e21[_0x157552(0x3dd)]=_0x495e21['muted_savedState'],toggleMute(!![]);}}else{function _0x2fae41(){try{delete _0x4c920d[_0x794971];}catch(_0x51c66c){}}}},_0x495e21[_0x2a0a0d(0x37f)]=function(){var _0xd92c35=_0x2a0a0d;if(_0x495e21[_0xd92c35(0x377)]===null)return;for(var _0x176884 in _0x495e21[_0xd92c35(0x3cc)]){try{if(_0xd92c35(0x4c4)!==_0xd92c35(0xc4)){var _0x3922e9=_0x495e21[_0xd92c35(0x3cc)][_0x176884]['getReceivers']();for(var _0x4ea901=0x0;_0x4ea901<_0x3922e9['length'];_0x4ea901++){_0x3922e9[_0x4ea901][_0xd92c35(0x476)][_0xd92c35(0x51a)]==_0xd92c35(0x295)&&(_0x3922e9[_0x4ea901]['track'][_0xd92c35(0x500)]=!_0x495e21[_0xd92c35(0x377)]);}}else{function _0x315eb2(){var _0xf83af1=_0xd92c35;_0x3faf6b[_0xf83af1(0x51a)]==_0xf83af1(0x295)&&_0x35c171[_0xf83af1(0x3fd)][_0x51a142]['addTrack'](_0x56cd94,_0x49617b);}}}catch(_0x376a09){}}_0x495e21[_0xd92c35(0x377)]&&(getById(_0xd92c35(0x450))[_0xd92c35(0x3dd)]=!![]);},_0x495e21[_0x2a0a0d(0x474)]=function(){var _0x51c974=_0x2a0a0d;if(_0x495e21[_0x51c974(0x1bb)]===null){if('noWYf'===_0x51c974(0x2f9))return;else{function _0x47657c(){var _0x59adea=_0x51c974;this[_0x59adea(0x302)]&&this[_0x59adea(0x302)][_0x59adea(0x509)]()[_0x59adea(0x415)](function(_0x2f70d5){var _0x36e2ba=_0x59adea;_0x2f70d5['stop'](),_0x3a6dfc(_0x36e2ba(0x1ed));});}}}_0x495e21['directorDisplayMuted']?(getById(_0x51c974(0x103))[_0x51c974(0x3b8)][_0x51c974(0x443)]=_0x51c974(0x51d),!_0x495e21[_0x51c974(0xe9)]&&warnUser(_0x51c974(0x421))):(getById(_0x51c974(0x103))[_0x51c974(0x3b8)][_0x51c974(0x443)]='',!_0x495e21[_0x51c974(0xe9)]&&closeModal());for(var _0x1b3142 in _0x495e21[_0x51c974(0x3cc)]){try{var _0x42002c=_0x495e21[_0x51c974(0x3cc)][_0x1b3142][_0x51c974(0x220)]();for(var _0x3d3fb6=0x0;_0x3d3fb6<_0x42002c['length'];_0x3d3fb6++){_0x42002c[_0x3d3fb6][_0x51c974(0x476)]['kind']==_0x51c974(0x482)&&(_0x42002c[_0x3d3fb6][_0x51c974(0x476)][_0x51c974(0x500)]=!_0x495e21['directorDisplayMuted']);}}catch(_0x1c40c4){errorlog(_0x1c40c4);}}_0x495e21[_0x51c974(0x1bb)]&&(getById(_0x51c974(0x450))[_0x51c974(0x3dd)]=!![]);},_0x495e21[_0x2a0a0d(0x267)]=function(_0x4a1fc7){var _0x2f385c=_0x2a0a0d;_0x4a1fc7[_0x2f385c(0x3cb)]();var _0x11d954=parseFloat(_0x4a1fc7[_0x2f385c(0x3b6)]*-0.001);log(_0x4a1fc7[_0x2f385c(0x269)]),_0x4a1fc7[_0x2f385c(0xee)]||_0x4a1fc7[_0x2f385c(0xf7)]?_0x495e21[_0x2f385c(0x480)](_0x11d954,_0x4a1fc7[_0x2f385c(0x269)][_0x2f385c(0x2a3)][_0x2f385c(0x12e)]):_0x495e21[_0x2f385c(0x1f7)](_0x11d954,_0x4a1fc7[_0x2f385c(0x269)][_0x2f385c(0x2a3)][_0x2f385c(0x12e)]);},_0x495e21['requestZoomChange']=function(_0x496225,_0x311e31,_0x464b33=_0x495e21[_0x2a0a0d(0x240)]){var _0xfcd16e=_0x2a0a0d;log(_0xfcd16e(0x344)+_0x496225),log(_0x311e31);var _0x4cdf42={};_0x4cdf42[_0xfcd16e(0x467)]=_0x496225,_0x4cdf42[_0xfcd16e(0x240)]=_0x464b33,_0x495e21[_0xfcd16e(0x166)](_0x4cdf42,_0x311e31)?log('zoom\x20success'):errorlog(_0xfcd16e(0x18a));},_0x495e21['requestFocusChange']=function(_0xab1d19,_0x4435c5,_0x59250f=_0x495e21[_0x2a0a0d(0x240)]){var _0x575b2d=_0x2a0a0d;log(_0x575b2d(0xb7)+_0xab1d19);var _0x2f2340={};_0x2f2340['focus']=_0xab1d19,_0x2f2340[_0x575b2d(0x240)]=_0x59250f,_0x495e21[_0x575b2d(0x166)](_0x2f2340,_0x4435c5)?log(_0x575b2d(0x405)):errorlog(_0x575b2d(0x130));},_0x495e21[_0x2a0a0d(0x35e)]=function(){var _0x1d7a6a=_0x2a0a0d;_0x495e21['connect']();if(_0x495e21[_0x1d7a6a(0x4c0)]!==![])_0x495e21[_0x1d7a6a(0x4c0)]=_0x1d7a6a(0x19f),log(_0x1d7a6a(0x3f9));else{var _0x4a4b14={};_0x4a4b14[_0x1d7a6a(0x317)]=_0x1d7a6a(0x2b7),_0x4a4b14[_0x1d7a6a(0x23e)]=_0x495e21[_0x1d7a6a(0x23e)],_0x495e21[_0x1d7a6a(0x1e7)](_0x4a4b14),log(_0x1d7a6a(0x1db));}},_0x495e21[_0x2a0a0d(0x192)]=function(_0xe4346a){var _0xae629c=_0x2a0a0d;try{if(navigator[_0xae629c(0x119)][_0xae629c(0x37b)]('\x20Pixel\x20')!=-0x1){if(_0xae629c(0x147)===_0xae629c(0x147)){if(!_0x495e21[_0xae629c(0x2f6)][_0xae629c(0x1e8)])return _0xe4346a;if(!_0x495e21['videoElement'][_0xae629c(0x1e8)][_0xae629c(0x3d1)]()['length'])return _0xe4346a;if(_0xe4346a<=0x0){if(_0xae629c(0x177)===_0xae629c(0x177))return _0xe4346a;else{function _0x5d0711(){var _0xe350f8=_0xae629c;_0x284d1f['rpcs'][_0x43f353][_0xe350f8(0x2f6)]['style'][_0xe350f8(0x443)]=_0xe350f8(0x101),_0x3786f6=!![];}}}var _0x2572b9=_0x495e21[_0xae629c(0x2f6)][_0xae629c(0x1e8)][_0xae629c(0x3d1)]()[0x0][_0xae629c(0x19d)](),_0x502919=_0x2572b9[_0xae629c(0x306)],_0x495727=_0x2572b9[_0xae629c(0x38a)],_0x376f08=_0x502919*_0xe4346a/0x64,_0x5c554e=_0x495727*_0xe4346a/0x64;if(_0x376f08>_0x5c554e){_0x376f08=parseInt(_0x376f08/0x10)*0x10;var _0x2a824=0x64*_0x376f08/_0x502919;}else{_0x5c554e=parseInt(_0x5c554e/0x10)*0x10;var _0x2a824=0x64*_0x5c554e/_0x495727;}return _0x2a824;}else{function _0x556757(){var _0x248691=_0xae629c;_0x5b56dd[_0x248691(0x39f)](_0x30e30d)['then']()['catch'](_0x3f987e=>{var _0x51c3ff=_0x248691;_0x3f2da8(_0x3f987e),_0x4f787f[_0x51c3ff(0x91)]('[data-action-type=\x22solo-chat\x22][data--u-u-i-d=\x22'+_0x2b7899+'\x22]')[0x0][_0x51c3ff(0x124)][_0x51c3ff(0x14e)](_0x51c3ff(0x42b));});}}}else{if(navigator[_0xae629c(0x119)][_0xae629c(0x37b)](_0xae629c(0x96))>-0x1){if(_0xae629c(0xda)==='MVOgW'){if(!_0x495e21[_0xae629c(0x2f6)][_0xae629c(0x1e8)])return _0xe4346a;if(!_0x495e21['videoElement'][_0xae629c(0x1e8)]['getVideoTracks']()[_0xae629c(0xaf)])return _0xe4346a;if(_0xe4346a<=0x0){if(_0xae629c(0x283)===_0xae629c(0x2e4)){function _0x126b19(){var _0x5c0b64=_0xae629c;_0x245492(_0x5c0b64(0x451));return;}}else return _0xe4346a;}var _0x2572b9=_0x495e21[_0xae629c(0x2f6)]['srcObject']['getVideoTracks']()[0x0]['getSettings'](),_0x502919=_0x2572b9[_0xae629c(0x306)],_0x495727=_0x2572b9['width'],_0x376f08=_0x502919*_0xe4346a/0x64,_0x5c554e=_0x495727*_0xe4346a/0x64;if(_0x376f08>_0x5c554e){_0x376f08=parseInt(_0x376f08/0x10)*0x10;var _0x2a824=0x64*_0x376f08/_0x502919;}else{_0x5c554e=parseInt(_0x5c554e/0x10)*0x10;var _0x2a824=0x64*_0x5c554e/_0x495727;}return _0x2a824;}else{function _0x166958(){var _0x5c7a18=_0xae629c;_0x231771('container_'+_0x3b1bee)[_0x5c7a18(0x1b7)][_0x5c7a18(0x272)](_0x2ae61a(_0x5c7a18(0x321)+_0x2b1a16));}}}else{if(_0x495e21[_0xae629c(0x2e1)]===_0xae629c(0x4de)){if(!_0x495e21[_0xae629c(0x2f6)][_0xae629c(0x1e8)])return _0xe4346a;if(!_0x495e21[_0xae629c(0x2f6)][_0xae629c(0x1e8)]['getVideoTracks']()['length'])return _0xe4346a;if(_0xe4346a<=0x0){if('QatuC'!==_0xae629c(0x20f))return _0xe4346a;else{function _0x26d2d0(){return;}}}var _0x2572b9=_0x495e21[_0xae629c(0x2f6)][_0xae629c(0x1e8)][_0xae629c(0x3d1)]()[0x0][_0xae629c(0x19d)](),_0x502919=_0x2572b9[_0xae629c(0x306)],_0x495727=_0x2572b9[_0xae629c(0x38a)],_0x376f08=_0x502919*_0xe4346a/0x64,_0x5c554e=_0x495727*_0xe4346a/0x64;if(_0x376f08>_0x5c554e){_0x376f08=parseInt(_0x376f08/0x10)*0x10;var _0x2a824=0x64*_0x376f08/_0x502919;}else{_0x5c554e=parseInt(_0x5c554e/0x10)*0x10;var _0x2a824=0x64*_0x5c554e/_0x495727;}return _0x2a824;}else return _0xe4346a;}}}catch(_0x3aa943){return _0xe4346a;}},_0x495e21['refreshScale']=function(){var _0x39e3a5=_0x2a0a0d;log('Refreshing\x20scale');for(var _0x1337a6 in _0x495e21[_0x39e3a5(0x3fd)]){setTimeout(function(_0xde4daa){var _0x10e315=_0x39e3a5;if(_0x495e21[_0x10e315(0x3fd)][_0xde4daa][_0x10e315(0x1ec)]!==![])log(_0x10e315(0x484)),_0x495e21[_0x10e315(0x392)](_0xde4daa,_0x495e21[_0x10e315(0x3fd)][_0xde4daa][_0x10e315(0x33e)],_0x495e21[_0x10e315(0x3fd)][_0xde4daa]['scaleHeight']);else{if(_0x495e21[_0x10e315(0x3fd)][_0xde4daa][_0x10e315(0x232)]!==![]){if(_0x10e315(0xb6)===_0x10e315(0xb6))log('scale\x20scale'),_0x495e21[_0x10e315(0x1e3)](_0xde4daa,_0x495e21[_0x10e315(0x3fd)][_0xde4daa]['scale']);else{function _0x590c70(){var _0x10b51d=_0x10e315;_0x44fac7[_0x10b51d(0x482)]=![];}}}}},0x0,_0x1337a6);}},_0x495e21[_0x2a0a0d(0x1e3)]=function(_0x5cdc73,_0x1817e9){var _0x447727=_0x2a0a0d;warnlog(_0x447727(0x108));if(_0x495e21['pcs'][_0x5cdc73][_0x447727(0x232)]!==_0x1817e9){_0x495e21['pcs'][_0x5cdc73][_0x447727(0x232)]=_0x1817e9;try{if(safariVersion()<=0xd&&(iOS||iPad))log(_0x447727(0x13b));else{if((adapter['browserDetails'][_0x447727(0x199)]==='chrome'||adapter[_0x447727(0x434)][_0x447727(0x199)]===_0x447727(0x4fd)||adapter[_0x447727(0x434)][_0x447727(0x199)]===_0x447727(0x422)&&adapter[_0x447727(0x434)][_0x447727(0x105)]>=0x40)&&_0x447727(0x238)in window&&'setParameters'in window[_0x447727(0x238)][_0x447727(0x222)]){var _0x155240=_0x495e21['pcs'][_0x5cdc73][_0x447727(0x16e)]()[_0x447727(0x2ba)](function(_0x30471c){var _0x2037ac=_0x447727;return _0x30471c[_0x2037ac(0x476)]&&_0x30471c[_0x2037ac(0x476)]['kind']==_0x2037ac(0x482);});if(!_0x155240){warnlog(_0x447727(0x308));return;}var _0xa57764=_0x155240[_0x447727(0x3d6)]();(!_0xa57764[_0x447727(0x1ee)]||_0xa57764['encodings'][_0x447727(0xaf)]==0x0)&&(_0xa57764[_0x447727(0x1ee)]=[{}]);_0x495e21['pcs'][_0x5cdc73][_0x447727(0x1ec)]&&(_0x495e21[_0x447727(0x3fd)][_0x5cdc73][_0x447727(0x1ec)]<_0x1817e9&&(_0x1817e9=_0x495e21[_0x447727(0x3fd)][_0x5cdc73][_0x447727(0x1ec)]));_0x495e21['pcs'][_0x5cdc73][_0x447727(0x425)]&&_0x495e21[_0x447727(0x3fd)][_0x5cdc73]['scaleDueToBitrate']<_0x1817e9&&(_0x1817e9=_0x495e21[_0x447727(0x3fd)][_0x5cdc73][_0x447727(0x425)]);_0x1817e9=_0x495e21['pixelFix'](_0x1817e9);_0x1817e9<=0x0?_0xa57764[_0x447727(0x1ee)][0x0][_0x447727(0x4bc)]=0x1:_0xa57764[_0x447727(0x1ee)][0x0][_0x447727(0x4bc)]=0x64/_0x1817e9;_0x155240['setParameters'](_0xa57764)[_0x447727(0x34d)](()=>{var _0x2627dc=_0x447727;log(_0x2627dc(0x4b5)),log(_0x155240['getParameters']()),pokeIframeAPI(_0x2627dc(0x22f),_0x1817e9,_0x5cdc73);})[_0x447727(0x236)](warnlog),_0x495e21['pcs'][_0x5cdc73][_0x447727(0x502)]['scaleFactor']=parseInt(_0x1817e9)+'%';return;}}}catch(_0x4c499d){errorlog(_0x4c499d);}}},_0x495e21[_0x2a0a0d(0x4a6)]=function(_0x5320b0,_0x4da55a,_0x53febf){var _0x4e53e0=_0x2a0a0d;if(!_0x495e21[_0x4e53e0(0x3cc)][_0x5320b0])return;var _0x158179=![];_0x495e21[_0x4e53e0(0x3cc)][_0x5320b0]['scaleWidth']!=_0x4da55a&&(_0x495e21['rpcs'][_0x5320b0]['scaleWidth']=_0x4da55a,_0x158179=!![]);_0x495e21['rpcs'][_0x5320b0]['scaleHeight']!=_0x53febf&&(_0x495e21[_0x4e53e0(0x3cc)][_0x5320b0][_0x4e53e0(0x1f8)]=_0x53febf,_0x158179=!![]);log(_0x4da55a+'\x20'+_0x53febf);if(_0x158179){var _0x42a738={};_0x42a738[_0x4e53e0(0x12e)]=_0x5320b0,_0x42a738['requestResolution']={'w':_0x4da55a,'h':_0x53febf},warnlog(_0x4e53e0(0x4a6)),warnlog(_0x42a738),_0x495e21['sendRequest'](_0x42a738,_0x5320b0);}_0x495e21[_0x4e53e0(0x3cc)][_0x5320b0][_0x4e53e0(0x502)]['Requested_resolution']=parseInt(_0x4da55a)+_0x4e53e0(0x2e2)+parseInt(_0x53febf);},_0x495e21[_0x2a0a0d(0x392)]=function(_0x1ea10b,_0xf7ddc8,_0x384b6d){var _0x1aa1ea=_0x2a0a0d;_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x33e)]=_0xf7ddc8,_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x1f8)]=_0x384b6d;if(safariVersion()<=0xd&&(iOS||iPad)){if(_0x1aa1ea(0x440)==='ngtCO')return;else{function _0x402930(){var _0x2cc939=_0x1aa1ea;_0x5d6ec7(_0x2cc939(0x13f)),_0x2e260a(_0x2cc939(0x40e)),_0x399b24(_0x197c2a['roomid']);}}}if((adapter['browserDetails'][_0x1aa1ea(0x199)]===_0x1aa1ea(0x194)||adapter[_0x1aa1ea(0x434)][_0x1aa1ea(0x199)]===_0x1aa1ea(0x4fd)||adapter[_0x1aa1ea(0x434)][_0x1aa1ea(0x199)]==='firefox'&&adapter['browserDetails'][_0x1aa1ea(0x105)]>=0x40)&&_0x1aa1ea(0x238)in window&&_0x1aa1ea(0x39f)in window[_0x1aa1ea(0x238)][_0x1aa1ea(0x222)]){if('UOyHC'===_0x1aa1ea(0x429)){var _0x1c9c49=_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x16e)]()[_0x1aa1ea(0x2ba)](function(_0x54d00f){var _0x533e51=_0x1aa1ea;return _0x54d00f[_0x533e51(0x476)]&&_0x54d00f[_0x533e51(0x476)][_0x533e51(0x51a)]==_0x533e51(0x482);});if(!_0x1c9c49){warnlog('can\x27t\x20change\x20bitrate;\x20no\x20video\x20sender\x20found');return;}var _0x43598d=_0x1c9c49[_0x1aa1ea(0x3d6)]();(!_0x43598d[_0x1aa1ea(0x1ee)]||_0x43598d[_0x1aa1ea(0x1ee)]['length']==0x0)&&(_0x43598d[_0x1aa1ea(0x1ee)]=[{}]);if(_0x495e21[_0x1aa1ea(0x2f6)]){var _0x1303f9=_0x495e21[_0x1aa1ea(0x2f6)][_0x1aa1ea(0x1e8)][_0x1aa1ea(0x3d1)]();if(_0x1303f9[_0x1aa1ea(0xaf)])var _0x39d405=_0x495e21[_0x1aa1ea(0x2f6)][_0x1aa1ea(0x1e8)][_0x1aa1ea(0x3d1)]()[0x0]['getSettings'](),_0x4335ad=_0x39d405[_0x1aa1ea(0x306)],_0x108462=_0x39d405[_0x1aa1ea(0x38a)];else return;}else return;var _0x31f6d8=0x64*_0xf7ddc8/_0x108462,_0x36c7d5=0x64*_0x384b6d/_0x4335ad;log(_0x31f6d8+_0x1aa1ea(0x2e2)+_0x36c7d5);var _0x4907dd=0x64;_0x31f6d8>_0x36c7d5?_0x4907dd=_0x36c7d5:_0x4907dd=_0x31f6d8;_0x4907dd>0x64&&(_0x4907dd=0x64);log(_0x1aa1ea(0x49b)+_0x4907dd),_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b]['scaleResolution']=_0x4907dd;var _0x1a1ed8=0x64;log(_0x1aa1ea(0x26d)+_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x232)]);_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x232)]&&(_0x1a1ed8=_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x232)]);_0x1a1ed8>_0x4907dd&&(_0x1a1ed8=_0x4907dd);_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x1ec)]&&(_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b]['scaleResolution']<_0x1a1ed8&&(_0x1a1ed8=_0x495e21['pcs'][_0x1ea10b][_0x1aa1ea(0x1ec)]));_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x425)]&&_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x425)]<_0x1a1ed8&&(_0x1a1ed8=_0x495e21['pcs'][_0x1ea10b][_0x1aa1ea(0x425)]);log(_0x1aa1ea(0x46a)+_0x1a1ed8),_0x1a1ed8=_0x495e21[_0x1aa1ea(0x192)](_0x1a1ed8),log(_0x1aa1ea(0x150)+_0x1a1ed8);_0x1a1ed8<=0x0?_0x43598d[_0x1aa1ea(0x1ee)][0x0][_0x1aa1ea(0x4bc)]=0x1:_0x43598d[_0x1aa1ea(0x1ee)][0x0]['scaleResolutionDownBy']=0x64/_0x1a1ed8;_0x1c9c49[_0x1aa1ea(0x39f)](_0x43598d)[_0x1aa1ea(0x34d)](()=>{var _0xacec5b=_0x1aa1ea;log(_0xacec5b(0x4b5)),log(_0x43598d),pokeIframeAPI(_0xacec5b(0x22f),_0x1a1ed8,_0x1ea10b);})['catch'](warnlog),_0x495e21[_0x1aa1ea(0x3fd)][_0x1ea10b][_0x1aa1ea(0x502)]['scaleFactor']=parseInt(_0x1a1ed8)+'%';return;}else{function _0x59ce61(){_0x1cf292();}}}},_0x495e21[_0x2a0a0d(0x3df)]=function(_0x1a4d90=null,_0x407c99=null){var _0x4ea7da=_0x2a0a0d;if('qswmY'==='qswmY'){_0x407c99&&_0x407c99[_0x4ea7da(0x394)]();log(_0x4ea7da(0x15e)+_0x1a4d90);if(iOS||iPad)log('iOS\x20devices\x20do\x20not\x20support\x20dynamic\x20bitrates\x20correctly;\x20skipping');else{if((adapter['browserDetails'][_0x4ea7da(0x199)]===_0x4ea7da(0x194)||adapter[_0x4ea7da(0x434)]['browser']===_0x4ea7da(0x4fd)||adapter[_0x4ea7da(0x434)][_0x4ea7da(0x199)]===_0x4ea7da(0x422)&&adapter[_0x4ea7da(0x434)]['version']>=0x40)&&_0x4ea7da(0x238)in window&&_0x4ea7da(0x39f)in window[_0x4ea7da(0x238)][_0x4ea7da(0x222)]){if(_0x1a4d90==null){for(_0x1a4d90 in _0x495e21[_0x4ea7da(0x3fd)]){_0x495e21[_0x4ea7da(0x3df)](_0x1a4d90);}return![];}if(!(_0x1a4d90 in _0x495e21[_0x4ea7da(0x3fd)]))return![];_0x495e21[_0x4ea7da(0x3fd)][_0x1a4d90][_0x4ea7da(0x233)]&&(_0x495e21['pcs'][_0x1a4d90][_0x4ea7da(0x4a4)]&&(clearTimeout(_0x495e21[_0x4ea7da(0x3fd)][_0x1a4d90][_0x4ea7da(0x4a4)]),_0x495e21[_0x4ea7da(0x3fd)][_0x1a4d90]['keyframeTimeout']=null),_0x495e21[_0x4ea7da(0x3fd)][_0x1a4d90][_0x4ea7da(0x4a4)]=setTimeout(function(){var _0xbc620d=_0x4ea7da;if(_0xbc620d(0x253)===_0xbc620d(0x253))_0x495e21['forcePLI'](_0x1a4d90);else{function _0x59986a(){var _0x35255f=_0xbc620d;try{_0x4c4701[_0x35255f(0x3fd)][_0x38150d][_0x35255f(0x502)]['info'][_0x35255f(0x455)]=!![];}catch(_0x824b20){}}}},parseInt(_0x495e21[_0x4ea7da(0x3fd)][_0x1a4d90][_0x4ea7da(0x233)])));try{var _0x4c17ca=_0x495e21['pcs'][_0x1a4d90][_0x4ea7da(0x16e)]()['find'](function(_0x5ac6bc){var _0x4dfe16=_0x4ea7da;return _0x5ac6bc[_0x4dfe16(0x476)]&&_0x5ac6bc[_0x4dfe16(0x476)][_0x4dfe16(0x51a)]==_0x4dfe16(0x482);});if(!_0x4c17ca){if(_0x4ea7da(0x441)==='KndaU'){function _0x434df5(){var _0x3a0baf=_0x4ea7da;_0x23cce2[0x0][_0x3a0baf(0x44f)]=_0x3630fd['rpcs'][_0x3c6284][_0x3a0baf(0x40a)];}}else return warnlog(_0x4ea7da(0x308)),![];}var _0x4a834e=_0x4c17ca[_0x4ea7da(0x3d6)]();(!_0x4a834e[_0x4ea7da(0x1ee)]||_0x4a834e[_0x4ea7da(0x1ee)][_0x4ea7da(0xaf)]==0x0)&&(_0x4a834e['encodings']=[{}]);var _0x958653=![];_0x4a834e['encodings'][0x0]['scaleResolutionDownBy']=0xa,_0x4c17ca[_0x4ea7da(0x39f)](_0x4a834e)[_0x4ea7da(0x34d)](()=>{var _0xee6adc=_0x4ea7da;log('scaleResolutionDownBy\x20set\x201!');var _0x47879b=_0x495e21[_0xee6adc(0x3fd)][_0x1a4d90]['scaleResolution'],_0x5860e9=0x64;!_0x47879b&&(_0x47879b=_0x5860e9);_0x495e21[_0xee6adc(0x3fd)][_0x1a4d90][_0xee6adc(0x232)]&&(_0x5860e9=_0x495e21[_0xee6adc(0x3fd)][_0x1a4d90][_0xee6adc(0x232)]);_0x5860e9>_0x47879b&&(_0x5860e9=_0x47879b);_0x495e21['pcs'][_0x1a4d90][_0xee6adc(0x1ec)]&&(_0x495e21[_0xee6adc(0x3fd)][_0x1a4d90][_0xee6adc(0x1ec)]<_0x5860e9&&(_0x5860e9=_0x495e21['pcs'][_0x1a4d90][_0xee6adc(0x1ec)]));_0x495e21[_0xee6adc(0x3fd)][_0x1a4d90][_0xee6adc(0x425)]&&_0x495e21[_0xee6adc(0x3fd)][_0x1a4d90][_0xee6adc(0x425)]<_0x5860e9&&(_0x5860e9=_0x495e21[_0xee6adc(0x3fd)][_0x1a4d90][_0xee6adc(0x425)]);log(_0xee6adc(0x46a)+_0x5860e9),_0x5860e9=_0x495e21[_0xee6adc(0x192)](_0x5860e9);var _0x31e44f=_0x4c17ca[_0xee6adc(0x3d6)]();_0x31e44f[_0xee6adc(0x1ee)][0x0][_0xee6adc(0x4bc)]=0x64/_0x5860e9,log(_0xee6adc(0x373)),_0x4c17ca[_0xee6adc(0x39f)](_0x31e44f)[_0xee6adc(0x34d)](()=>{var _0x346caf=_0xee6adc;log(_0x346caf(0x24a));})[_0xee6adc(0x236)](warnlog);})['catch'](warnlog);}catch(_0x4f322f){errorlog(_0x4f322f);}}}return![];}else{function _0x4ac4ca(){return;}}},_0x495e21[_0x2a0a0d(0x309)]=function(_0x4114ef){var _0x5790e=_0x2a0a0d;log(_0x5790e(0x2af));var _0x5aaa62=_0x495e21[_0x5790e(0x3fd)][_0x4114ef][_0x5790e(0x16e)]()[_0x5790e(0x2ba)](function(_0x21b507){var _0xfe715c=_0x5790e;return _0x21b507[_0xfe715c(0x476)]&&_0x21b507[_0xfe715c(0x476)][_0xfe715c(0x51a)]=='audio';});if(!_0x5aaa62)return log(_0x5790e(0x290)),![];var _0x2d0013=_0x5aaa62[_0x5790e(0x3d6)]();(!_0x2d0013[_0x5790e(0x1ee)]||_0x2d0013[_0x5790e(0x1ee)][_0x5790e(0xaf)]==0x0)&&(_0x2d0013[_0x5790e(0x1ee)]=[{}]);try{_0x2d0013[_0x5790e(0x1ee)][0x0][_0x5790e(0x393)]=_0x5790e(0x322),_0x2d0013[_0x5790e(0x1ee)][0x0][_0x5790e(0x439)]=_0x5790e(0x322),_0x2d0013[_0x5790e(0x1ee)][0x0][_0x5790e(0x497)]=!![],_0x5aaa62[_0x5790e(0x39f)](_0x2d0013)['then'](()=>{var _0xe5382=_0x5790e;log(_0xe5382(0x17a)),pokeIframeAPI('enhanceAudioEncoder',!![],_0x4114ef);});}catch(_0x2f5e45){errorlog(_0x2f5e45);}},_0x495e21[_0x2a0a0d(0x2ce)]=function(_0x5c9647,_0x3a5bb8=0x7d00,_0x40ad85=0x3e8){var _0x4fba0d=_0x2a0a0d;log(_0x4fba0d(0x10d));var _0x979788=_0x495e21[_0x4fba0d(0x3fd)][_0x5c9647][_0x4fba0d(0x16e)]()[_0x4fba0d(0x2ba)](function(_0x3c486d){var _0x599b1e=_0x4fba0d;return _0x3c486d[_0x599b1e(0x476)]&&_0x3c486d[_0x599b1e(0x476)][_0x599b1e(0x51a)]==_0x599b1e(0x295);});if(!_0x979788)return log(_0x4fba0d(0x290)),![];var _0x22c496=_0x979788['getParameters']();(!_0x22c496[_0x4fba0d(0x1ee)]||_0x22c496[_0x4fba0d(0x1ee)][_0x4fba0d(0xaf)]==0x0)&&(_0x22c496[_0x4fba0d(0x1ee)]=[{}]),_0x22c496[_0x4fba0d(0x1ee)][0x0]['maxBitrate']=_0x3a5bb8,_0x979788[_0x4fba0d(0x39f)](_0x22c496)[_0x4fba0d(0x34d)](()=>{var _0x5bcec6=_0x4fba0d;pokeIframeAPI(_0x5bcec6(0x20b),_0x3a5bb8,_0x5c9647),_0x40ad85>0x0&&setTimeout(function(){var _0x54cafd=_0x5bcec6;if(_0x54cafd(0x1cd)===_0x54cafd(0x1cd))try{if(_0x5c9647 in _0x495e21[_0x54cafd(0x3fd)])var _0x259563=_0x495e21[_0x54cafd(0x3fd)][_0x5c9647][_0x54cafd(0x16e)]()['find'](function(_0x1d674a){var _0x46157d=_0x54cafd;return _0x1d674a[_0x46157d(0x476)]&&_0x1d674a[_0x46157d(0x476)][_0x46157d(0x51a)]==_0x46157d(0x295);});else{if(_0x54cafd(0x114)!==_0x54cafd(0x114)){function _0x54f5c0(){var _0x48e88e=_0x54cafd;_0x60ae01[_0x48e88e(0x3cc)][_0x52fc22][_0x48e88e(0x302)]=new _0x4f8bb4();}}else return![];}if(!_0x259563)return log(_0x54cafd(0x290)),![];var _0x24919e=_0x259563[_0x54cafd(0x3d6)]();delete _0x24919e[_0x54cafd(0x1ee)][0x0][_0x54cafd(0x41c)],_0x259563[_0x54cafd(0x39f)](_0x24919e)['then'](()=>{var _0xab7bf=_0x54cafd;log(_0xab7bf(0x17a));});}catch(_0x34cb35){errorlog(_0x34cb35);}else{function _0x49c32e(){var _0x1aab7a=_0x54cafd;_0x557b9c=_0x43a4e3[_0x1aab7a(0x3fd)][_0x3be1e9][_0x1aab7a(0x232)];}}},_0x40ad85,_0x5c9647);});},_0x495e21[_0x2a0a0d(0x3bb)]=function(_0x5ba47f,_0x44ff66){var _0x3cf791=_0x2a0a0d;_0x44ff66=parseInt(_0x44ff66);try{var _0x1ab88e=_0x495e21[_0x3cf791(0x3fd)][_0x5ba47f][_0x3cf791(0x16e)]()[_0x3cf791(0x2ba)](function(_0x2af3a0){var _0x333cd6=_0x3cf791;return _0x2af3a0['track']&&_0x2af3a0[_0x333cd6(0x476)][_0x333cd6(0x51a)]==_0x333cd6(0x295);});if(!_0x1ab88e){warnlog(_0x3cf791(0xfa));return;}var _0x274423=_0x1ab88e[_0x3cf791(0x3d6)]();(!_0x274423[_0x3cf791(0x1ee)]||_0x274423[_0x3cf791(0x1ee)]['length']==0x0)&&(_0x274423[_0x3cf791(0x1ee)]=[{}]);if(_0x44ff66<0x0)_0x274423[_0x3cf791(0x1ee)][0x0]['active']==![]&&(_0x274423['encodings'][0x0][_0x3cf791(0x4e2)]=!![]),safariVersion()<=0xd&&(iOS||iPad)?(_0x44ff66=0x20,_0x495e21[_0x3cf791(0x32a)]&&(_0x44ff66=_0x495e21['audiobitrate']),_0x274423[_0x3cf791(0x1ee)][0x0][_0x3cf791(0x41c)]=_0x44ff66*0x400):delete _0x274423[_0x3cf791(0x1ee)][0x0][_0x3cf791(0x41c)];else _0x44ff66===0x0?_0x274423['encodings'][0x0][_0x3cf791(0x4e2)]=![]:(_0x274423[_0x3cf791(0x1ee)][0x0][_0x3cf791(0x4e2)]==![]&&(_0x274423[_0x3cf791(0x1ee)][0x0]['active']=!![]),_0x274423[_0x3cf791(0x1ee)][0x0][_0x3cf791(0x41c)]=_0x44ff66*0x400);_0x1ab88e['setParameters'](_0x274423)[_0x3cf791(0x34d)](()=>{var _0x1fefc2=_0x3cf791;if(_0x1fefc2(0x261)===_0x1fefc2(0x320)){function _0x5b1ed5(){var _0x55d3d9=_0x1fefc2;_0x921d22(_0x55d3d9(0x4cd));return;}}else pokeIframeAPI(_0x1fefc2(0x20b),_0x44ff66,_0x5ba47f),log(_0x1fefc2(0xf4));})[_0x3cf791(0x236)](warnlog);}catch(_0x428a3e){errorlog(_0x428a3e);}},_0x495e21[_0x2a0a0d(0x354)]=function(_0x4e4c55){var _0x3da105=_0x2a0a0d;if(_0x495e21[_0x3da105(0x15b)]&&_0x495e21[_0x3da105(0x3fd)][_0x4e4c55][_0x3da105(0x505)]===!![]){_0x495e21[_0x3da105(0x2cb)](_0x4e4c55,0x0);if(_0x495e21['pcs'][_0x4e4c55]['optimizedBitrate']===0x0){if(_0x495e21[_0x3da105(0x3fd)][_0x4e4c55][_0x3da105(0x3be)]===![])_0x495e21[_0x3da105(0x3bb)](_0x4e4c55,0x0);else{if(_0x3da105(0x412)===_0x3da105(0x412))_0x495e21[_0x3da105(0x3bb)](_0x4e4c55,-0x1);else{function _0x1367cd(){_0x4039ab['processIce2'](_0x5ee0b6);}}}}}else{if(_0x495e21['pcs'][_0x4e4c55]&&_0x495e21[_0x3da105(0x3fd)][_0x4e4c55][_0x3da105(0xdc)]!==![]){if(_0x495e21[_0x3da105(0x3fd)][_0x4e4c55][_0x3da105(0x3be)]===![]){var _0x46da09=_0x495e21['pcs'][_0x4e4c55][_0x3da105(0xdc)];_0x495e21[_0x3da105(0x3fd)][_0x4e4c55][_0x3da105(0x2d3)]&&_0x495e21['pcs'][_0x4e4c55][_0x3da105(0x2d3)]>0x0&&(_0x495e21['pcs'][_0x4e4c55][_0x3da105(0x2d3)]<_0x495e21[_0x3da105(0x3fd)][_0x4e4c55][_0x3da105(0xdc)]&&(_0x46da09=_0x495e21[_0x3da105(0x3fd)][_0x4e4c55][_0x3da105(0x2d3)])),_0x495e21['limitBitrate'](_0x4e4c55,_0x46da09),_0x495e21[_0x3da105(0x3fd)][_0x4e4c55][_0x3da105(0xdc)]===0x0&&_0x495e21[_0x3da105(0x3bb)](_0x4e4c55,0x0);}else _0x495e21['pcs'][_0x4e4c55][_0x3da105(0xdc)]===0x0&&_0x495e21[_0x3da105(0x3bb)](_0x4e4c55,-0x1);}}},_0x495e21[_0x2a0a0d(0x11a)]=function(_0x9d53e5=0x0,_0x3e8067=![]){var _0x4b6e4d=_0x2a0a0d;if(_0x495e21[_0x4b6e4d(0x4da)]){var _0x40273d=_0x9d53e5;warnlog(_0x40273d);var _0x530a70=0x0;for(var _0xb9d9f3 in _0x495e21[_0x4b6e4d(0x3fd)]){if(_0x3e8067===_0xb9d9f3)continue;var _0x3e0eda=_0x495e21[_0x4b6e4d(0x3fd)][_0xb9d9f3]['getSenders']()[_0x4b6e4d(0x2ba)](function(_0x21ec37){var _0x14f60d=_0x4b6e4d;return _0x21ec37['track']&&_0x21ec37[_0x14f60d(0x476)]['kind']==_0x14f60d(0x482);});if(!_0x3e0eda)continue;var _0x37aa98=_0x3e0eda['getParameters']();if(!_0x37aa98['encodings']||_0x37aa98[_0x4b6e4d(0x1ee)][_0x4b6e4d(0xaf)]==0x0){_0x40273d+=_0x495e21[_0x4b6e4d(0x3fd)][_0xb9d9f3][_0x4b6e4d(0x263)]||0x9c4,warnlog(_0x40273d),_0x530a70+=0x1;continue;}if(_0x37aa98[_0x4b6e4d(0x1ee)][0x0][_0x4b6e4d(0x4e2)]==![])continue;if(_0x37aa98[_0x4b6e4d(0x1ee)][0x0][_0x4b6e4d(0x41c)]){if(_0x4b6e4d(0x41b)!==_0x4b6e4d(0x41b)){function _0x35941e(){var _0x39d10d=_0x4b6e4d,_0x2e04be=_0x353b8f[_0x39d10d(0x45e)](_0x312214['description'][_0x39d10d(0x496)]);if(_0x2e04be===![]){var _0x324e5b=_0x375ba7[_0x39d10d(0x116)](_0x190ec7[_0x39d10d(0x33d)][_0x39d10d(0x496)])||0x0;_0x4c6aa7['description'][_0x39d10d(0x496)]=_0x3f3166[_0x39d10d(0x343)](_0x312ec8[_0x39d10d(0x33d)][_0x39d10d(0x496)],{'min':_0x5487aa(_0xd155bb[_0x39d10d(0x178)]/0xa)||0x1,'max':_0x1cccc3(_0x31f32a[_0x39d10d(0x178)]+_0x324e5b/0x400)});}}}else _0x40273d+=parseInt(_0x37aa98[_0x4b6e4d(0x1ee)][0x0]['maxBitrate'])/0x400,warnlog(_0x40273d);}else _0x40273d+=_0x495e21[_0x4b6e4d(0x3fd)][_0xb9d9f3][_0x4b6e4d(0x263)]||0x9c4,warnlog(_0x40273d);_0x530a70+=0x1;}if(!_0x40273d)return![];var _0x58cabc=parseFloat(_0x40273d/_0x495e21[_0x4b6e4d(0x4da)]);if(_0x58cabc>0x1)for(var _0xb9d9f3 in _0x495e21[_0x4b6e4d(0x3fd)]){if(_0x3e8067===_0xb9d9f3)continue;var _0x3e0eda=_0x495e21[_0x4b6e4d(0x3fd)][_0xb9d9f3][_0x4b6e4d(0x16e)]()[_0x4b6e4d(0x2ba)](function(_0x522392){var _0x4dcb5a=_0x4b6e4d;return _0x522392[_0x4dcb5a(0x476)]&&_0x522392['track'][_0x4dcb5a(0x51a)]==_0x4dcb5a(0x482);});if(!_0x3e0eda)continue;var _0x37aa98=_0x3e0eda[_0x4b6e4d(0x3d6)]();if(!_0x37aa98['encodings']||_0x37aa98[_0x4b6e4d(0x1ee)]['length']==0x0){var _0x4addcd=_0x495e21[_0x4b6e4d(0x3fd)][_0xb9d9f3][_0x4b6e4d(0x263)]||0x9c4;_0x495e21[_0x4b6e4d(0x2cb)](_0xb9d9f3,parseInt(_0x4addcd/_0x58cabc),!![]),errorlog(parseInt(_0x4addcd/_0x58cabc));continue;}if(_0x37aa98[_0x4b6e4d(0x1ee)][0x0][_0x4b6e4d(0x4e2)]==![])continue;if(_0x37aa98['encodings'][0x0]['maxBitrate'])errorlog(parseInt(parseInt(_0x37aa98[_0x4b6e4d(0x1ee)][0x0][_0x4b6e4d(0x41c)])/0x400/_0x58cabc)),_0x495e21[_0x4b6e4d(0x2cb)](_0xb9d9f3,parseInt(parseInt(_0x37aa98[_0x4b6e4d(0x1ee)][0x0][_0x4b6e4d(0x41c)])/0x400/_0x58cabc),!![]);else{var _0x4addcd=_0x495e21[_0x4b6e4d(0x3fd)][_0xb9d9f3][_0x4b6e4d(0x263)]||0x9c4;errorlog(parseInt(_0x4addcd/_0x58cabc)),_0x495e21['limitBitrate'](_0xb9d9f3,parseInt(_0x4addcd/_0x58cabc),!![]);}}return parseInt(_0x9d53e5/_0x58cabc);}else return![];},_0x495e21[_0x2a0a0d(0x2cb)]=function(_0x597f24,_0x58d2b4,_0x500d03=![]){var _0x45a956=_0x2a0a0d;_0x495e21['pcs'][_0x597f24][_0x45a956(0x3ec)]&&(clearInterval(_0x495e21['pcs'][_0x597f24][_0x45a956(0x3ec)]),_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x3ec)]=null);if(_0x58d2b4===null){if(_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x2d3)]===![])return;_0x58d2b4=_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x2d3)];}_0x58d2b4=parseInt(_0x58d2b4);if(_0x495e21[_0x45a956(0x319)]){if('dGkTX'==='DKMKe'){function _0x27c04a(){var _0x3435d6=_0x45a956;_0x254686[_0x3435d6(0x3cc)][_0x3cd4a3][_0x3435d6(0x502)][_0x3435d6(0x50e)][_0x3435d6(0x26e)]=_0x27830e['ip'];}}else _0x58d2b4>_0x495e21[_0x45a956(0x319)]&&(_0x58d2b4=_0x495e21[_0x45a956(0x319)]);}_0x495e21['pcs'][_0x597f24][_0x45a956(0x2d3)]=_0x58d2b4;_0x495e21['pcs'][_0x597f24][_0x45a956(0xdc)]!==![]&&(_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x3be)]===![]&&(_0x58d2b4>_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0xdc)]&&(_0x495e21[_0x45a956(0x3fd)][_0x597f24]['savedBitrate']=_0x58d2b4,_0x58d2b4=parseInt(_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0xdc)])||0x0)));_0x500d03===![]&&(_0x495e21[_0x45a956(0x4da)]&&(_0x58d2b4=_0x495e21[_0x45a956(0x11a)](_0x58d2b4,_0x597f24)));if(_0x58d2b4==0x0){var _0x2d494c=Date[_0x45a956(0x42f)]()-_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x1c4)];_0x2d494c<_0x495e21[_0x45a956(0x3a7)]&&(_0x58d2b4=0x23,_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x3ec)]=setTimeout(function(_0x3e0e01){_0x495e21['limitBitrate'](_0x3e0e01,null);},_0x2d494c,_0x597f24));}try{if(safariVersion()<=0xd&&(iOS||iPad)){log(_0x45a956(0x13b));if(_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x438)]==!![]&&_0x495e21['pcs'][_0x597f24][_0x45a956(0x3d5)]==![])return;var _0x362967=_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x16e)]()['find'](function(_0x32d3c3){var _0x416432=_0x45a956;return _0x32d3c3[_0x416432(0x476)]&&_0x32d3c3['track'][_0x416432(0x51a)]=='video';});if(!_0x362967){warnlog(_0x45a956(0x308));return;}var _0x2fc33f=_0x362967[_0x45a956(0x3d6)]();(!_0x2fc33f[_0x45a956(0x1ee)]||_0x2fc33f[_0x45a956(0x1ee)][_0x45a956(0xaf)]==0x0)&&(_0x2fc33f[_0x45a956(0x1ee)]=[{}]);if(_0x58d2b4<0x0){if(_0x45a956(0x2db)===_0x45a956(0x2db)){if(_0x2fc33f[_0x45a956(0x1ee)][0x0][_0x45a956(0x4e2)]==![]){if(_0x45a956(0x3c2)!==_0x45a956(0x512))_0x2fc33f['encodings'][0x0][_0x45a956(0x4e2)]=!![];else{function _0x346eaf(){var _0x3f577c=_0x45a956;_0x87101d[_0x3f577c(0x4a8)][_0x3f577c(0xe6)]();}}}_0x58d2b4=0x9c4,_0x495e21[_0x45a956(0x2d0)]&&(_0x58d2b4=_0x495e21[_0x45a956(0x2d0)]),_0x495e21[_0x45a956(0x319)]&&(_0x58d2b4>_0x495e21[_0x45a956(0x319)]&&(_0x58d2b4=_0x495e21[_0x45a956(0x319)])),_0x2fc33f[_0x45a956(0x1ee)][0x0][_0x45a956(0x41c)]=_0x58d2b4*0x400;}else{function _0x466c0b(){var _0x5ed8c8=_0x45a956,_0x5146fc={};_0x5146fc['request']=_0x5ed8c8(0x4c7),_0x5146fc[_0x5ed8c8(0x23e)]=_0x36f2bf,_0x289a0d['sendMsg'](_0x5146fc),_0x21282c['waitingWatchList'][_0x2d7675]=!![];}}}else{if(_0x58d2b4===0x0){if(_0x45a956(0x34f)!==_0x45a956(0x34f)){function _0x21d78f(){var _0x52406f=_0x45a956;_0x33c410[_0x52406f(0x3cc)][_0x2cb771][_0x52406f(0xab)]=![];}}else _0x2fc33f[_0x45a956(0x1ee)][0x0][_0x45a956(0x4e2)]=![];}else{if(_0x45a956(0x1de)!==_0x45a956(0x49e))_0x2fc33f[_0x45a956(0x1ee)][0x0][_0x45a956(0x4e2)]==![]&&(_0x2fc33f[_0x45a956(0x1ee)][0x0][_0x45a956(0x4e2)]=!![]),_0x2fc33f[_0x45a956(0x1ee)][0x0][_0x45a956(0x41c)]=_0x58d2b4*0x400;else{function _0x1446ff(){var _0x4dd900=_0x45a956;_0x450002[_0x4dd900(0x3cc)][_0x4bb883][_0x4dd900(0x17f)][_0x4dd900(0x2a3)][_0x4dd900(0x3ee)]=_0x7fe170[_0x4dd900(0x3cc)][_0x962471]['streamID'];}}}}_0x362967[_0x45a956(0x39f)](_0x2fc33f)[_0x45a956(0x34d)](()=>{var _0x1b6ec4=_0x45a956;pokeIframeAPI(_0x1b6ec4(0x205),_0x58d2b4,_0x597f24),log(_0x1b6ec4(0x29b));})['catch'](warnlog);return;}else{if((iOS||iPad)&&(_0x495e21['pcs'][_0x597f24][_0x45a956(0x438)]==!![]&&_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x3d5)]==![])){if(_0x45a956(0x275)!==_0x45a956(0x276)){var _0x135f74=0x64;_0x495e21['pcs'][_0x597f24][_0x45a956(0x232)]&&(_0x135f74=_0x495e21[_0x45a956(0x3fd)][_0x597f24]['scale']),_0x495e21['pcs'][_0x597f24]['scaleResolution']&&_0x495e21[_0x45a956(0x3fd)][_0x597f24]['scaleResolution']<_0x135f74&&(_0x135f74=_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x1ec)]),_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x425)]=0x64/0x3,_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x425)]<_0x135f74&&(_0x135f74=_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x425)]),_0x135f74=_0x495e21['pixelFix'](_0x135f74),_0x2fc33f['encodings'][0x0]['scaleResolutionDownBy']=0x64/_0x135f74,_0x362967[_0x45a956(0x39f)](_0x2fc33f)[_0x45a956(0x34d)](()=>{var _0x21903f=_0x45a956;if(_0x21903f(0x174)!==_0x21903f(0x334))log(_0x21903f(0x30d)),pokeIframeAPI(_0x21903f(0x22f),_0x135f74,_0x597f24);else{function _0x54f37e(){_0xa24c06(_0x11b63b);}}})[_0x45a956(0x236)](warnlog),_0x495e21[_0x45a956(0x3fd)][_0x597f24]['stats'][_0x45a956(0x38b)]=parseInt(_0x135f74)+'%';}else{function _0x431ae0(){var _0x4c0600=_0x45a956;_0x128e84[_0x4c0600(0x482)]=![];}}}else{if((adapter[_0x45a956(0x434)][_0x45a956(0x199)]===_0x45a956(0x194)||adapter[_0x45a956(0x434)][_0x45a956(0x199)]===_0x45a956(0x4fd)||adapter[_0x45a956(0x434)][_0x45a956(0x199)]===_0x45a956(0x422)&&adapter[_0x45a956(0x434)][_0x45a956(0x105)]>=0x40)&&_0x45a956(0x238)in window&&_0x45a956(0x39f)in window[_0x45a956(0x238)]['prototype']){var _0x362967=_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x16e)]()['find'](function(_0x208122){var _0x513b57=_0x45a956;return _0x208122[_0x513b57(0x476)]&&_0x208122['track'][_0x513b57(0x51a)]==_0x513b57(0x482);});if(!_0x362967){if(_0x45a956(0x215)===_0x45a956(0x215)){warnlog('can\x27t\x20change\x20bitrate;\x20no\x20video\x20sender\x20found');return;}else{function _0x128d87(){var _0x3ea5e3=_0x45a956;_0x2ff8c5[_0x3ea5e3(0x3fd)][_0x11cd6f['UUID']]['setBitrate']=_0x3bc95e;}}}var _0x2fc33f=_0x362967['getParameters']();(!_0x2fc33f['encodings']||_0x2fc33f[_0x45a956(0x1ee)][_0x45a956(0xaf)]==0x0)&&(_0x2fc33f[_0x45a956(0x1ee)]=[{}]);if(_0x58d2b4<0x0)_0x2fc33f[_0x45a956(0x1ee)][0x0]['active']==![]&&(_0x2fc33f[_0x45a956(0x1ee)][0x0][_0x45a956(0x4e2)]=!![]),delete _0x2fc33f[_0x45a956(0x1ee)][0x0]['maxBitrate'];else _0x58d2b4===0x0?_0x2fc33f['encodings'][0x0][_0x45a956(0x4e2)]=![]:(_0x2fc33f['encodings'][0x0][_0x45a956(0x4e2)]==![]&&(_0x2fc33f[_0x45a956(0x1ee)][0x0][_0x45a956(0x4e2)]=!![]),_0x2fc33f['encodings'][0x0][_0x45a956(0x41c)]=_0x58d2b4*0x400);var _0x135f74=0x64;_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x232)]&&(_0x135f74=_0x495e21['pcs'][_0x597f24][_0x45a956(0x232)]);_0x495e21['pcs'][_0x597f24]['scaleResolution']&&_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x1ec)]<_0x135f74&&(_0x135f74=_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x1ec)]);if(_0x58d2b4<0x0)_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x425)]=0x64;else{if(_0x58d2b4>=0x259)_0x495e21['pcs'][_0x597f24]['scaleDueToBitrate']=0x64;else{if(_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x44c)]===![]&&_0x495e21[_0x45a956(0x389)]!==_0x597f24&&_0x495e21[_0x45a956(0x2a8)]){if('vkSaV'!==_0x45a956(0x90))_0x495e21['pcs'][_0x597f24][_0x45a956(0x425)]=0x64;else{function _0x3971a0(){var _0x5e4cc5=_0x45a956;_0x4a657c(_0x120e35[_0x5e4cc5(0xf0)]);}}}else{if(_0x58d2b4>=0xc9)_0x495e21[_0x45a956(0x288)]?_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x425)]=0x64/2.5:_0x495e21[_0x45a956(0x3fd)][_0x597f24]['scaleDueToBitrate']=0x64/0x2;else _0x58d2b4>=0x51?_0x495e21['pcs'][_0x597f24]['scaleDueToBitrate']=0x64/0x3:_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x425)]=0x64/0x4;}}}_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x425)]<_0x135f74&&(_0x135f74=_0x495e21[_0x45a956(0x3fd)][_0x597f24][_0x45a956(0x425)]);_0x135f74=_0x495e21[_0x45a956(0x192)](_0x135f74),_0x2fc33f['encodings'][0x0][_0x45a956(0x4bc)]=0x64/_0x135f74,_0x362967[_0x45a956(0x39f)](_0x2fc33f)[_0x45a956(0x34d)](()=>{var _0x11c20e=_0x45a956;log(_0x11c20e(0x29b)),pokeIframeAPI(_0x11c20e(0x205),_0x58d2b4,_0x597f24),pokeIframeAPI(_0x11c20e(0x22f),_0x135f74,_0x597f24);})[_0x45a956(0x236)](warnlog),_0x495e21['pcs'][_0x597f24][_0x45a956(0x502)][_0x45a956(0x38b)]=parseInt(_0x135f74)+'%';return;}}}}catch(_0x4ab14e){errorlog(_0x4ab14e);}};function _0x1d20f9(_0x16ad4f,_0x1f9d16=0x2710){var _0x45dd59=_0x2a0a0d;_0x1f9d16=parseInt(_0x1f9d16);if(_0x495e21[_0x45dd59(0x32a)])_0x1f9d16+=_0x495e21[_0x45dd59(0x32a)];else{if(_0x495e21['director']&&_0x495e21[_0x45dd59(0x3a1)]==0x5)_0x1f9d16+=0x20;else _0x495e21[_0x45dd59(0x3a1)]&&_0x495e21[_0x45dd59(0x3a1)]!=0x3?_0x1f9d16+=0x100:_0x1f9d16+=0x20;}return log(_0x45dd59(0x4e4)+_0x1f9d16),_0x1f9d16<0x1&&(_0x1f9d16=0x1),_0x16ad4f=CodecsHandler[_0x45dd59(0x343)](_0x16ad4f,{'min':parseInt(_0x1f9d16/0xa)||0x1,'max':_0x1f9d16},_0x495e21[_0x45dd59(0x2e1)]),_0x16ad4f;}return _0x495e21[_0x2a0a0d(0x50d)]=function(_0x36ea58,_0x5e9362){var _0x174b06=_0x2a0a0d;log(_0x36ea58),_0x495e21['mykey']==={}&&log(_0x174b06(0x446)),window[_0x174b06(0x1a3)][_0x174b06(0x402)][_0x174b06(0x1a5)]({'name':_0x174b06(0x511)},_0x495e21[_0x174b06(0x154)]['privateKey'],_0x495e21[_0x174b06(0x299)][_0x174b06(0x289)](_0x36ea58))[_0x174b06(0x34d)](function(_0x274c6b){var _0x2aee24=_0x174b06;_0x274c6b=new Uint8Array(_0x274c6b),_0x274c6b=_0x274c6b['reduce']((_0x8df112,_0x24000d)=>_0x8df112+_0x24000d[_0x2aee24(0x37d)](0x10)[_0x2aee24(0x2c4)](0x2,'0'),''),_0x5e9362(_0x36ea58,_0x274c6b),log(JSON[_0x2aee24(0x1e9)](_0x274c6b));})[_0x174b06(0x236)](errorlog);},_0x495e21[_0x2a0a0d(0x307)]=function(_0x511acf,_0x3e5a08){var _0x3fdfa3=_0x2a0a0d;if(_0x3fdfa3(0x43f)!==_0x3fdfa3(0x255)){_0x511acf[_0x3fdfa3(0x16b)]=new Uint8Array(_0x511acf['signature']['match'](/.{1,2}/g)[_0x3fdfa3(0x43b)](_0x3a1d67=>parseInt(_0x3a1d67,0x10)));if(_0x495e21[_0x3fdfa3(0x31f)][_0x3e5a08][_0x3fdfa3(0x15f)])return window['crypto'][_0x3fdfa3(0x402)][_0x3fdfa3(0x4c2)]({'name':_0x3fdfa3(0x511)},_0x495e21[_0x3fdfa3(0x31f)][_0x3e5a08][_0x3fdfa3(0x15f)],_0x511acf['signature'],_0x495e21[_0x3fdfa3(0x299)]['encode'](_0x511acf[_0x3fdfa3(0x488)]))[_0x3fdfa3(0x34d)](function(_0x40f90f){return log(_0x40f90f),_0x40f90f;})[_0x3fdfa3(0x236)](function(_0x4a13e6){return errorlog(_0x4a13e6),![];});}else{function _0x4d5a08(){var _0x1984aa=_0x3a1bf4['rpcs'][_0x1028ef]['streamID'];}}},_0x495e21['desaltStreamID']=function(_0x50c583){var _0x200d8d=_0x2a0a0d;if(_0x495e21['password'])return _0x495e21[_0x200d8d(0x486)]!==![]?(log('hash\x20is\x20not\x20false'),_0x50c583=_0x50c583[_0x200d8d(0x187)](0x0,-0x1*_0x495e21[_0x200d8d(0x486)][_0x200d8d(0xaf)]),_0x50c583):(log(_0x200d8d(0x18b)+_0x50c583),_0x495e21['generateHash'](_0x495e21['password']+_0x495e21[_0x200d8d(0x3f1)],0x6)[_0x200d8d(0x34d)](function(_0x6e0867){var _0x10a809=_0x200d8d;if(_0x10a809(0x2a4)==='ddBJJ')return _0x495e21['hash']=_0x6e0867,log(_0x50c583),_0x50c583=_0x50c583[_0x10a809(0x187)](0x0,-0x1*_0x495e21[_0x10a809(0x486)][_0x10a809(0xaf)]),log(_0x10a809(0x1d8)+_0x50c583),_0x50c583;else{function _0x49a4ca(){var _0x57fbd5=_0x10a809;_0x5c026f(_0x57fbd5(0x489))['classList'][_0x57fbd5(0x14e)]('float'),_0x4c4b06(_0x57fbd5(0x489))[_0x57fbd5(0x124)][_0x57fbd5(0x3c9)](_0x57fbd5(0xb1)),_0x3bb2f7(_0x57fbd5(0x489))[_0x57fbd5(0x124)][_0x57fbd5(0x3c9)](_0x57fbd5(0x2bc));}}}));return _0x50c583;},_0x495e21[_0x2a0a0d(0x298)]=function(){var _0xc5665b=_0x2a0a0d;if(!_0x495e21[_0xc5665b(0x3f4)])return;if(!_0x495e21[_0xc5665b(0x455)]){if(_0xc5665b(0x202)===_0xc5665b(0x100)){function _0x4b2dce(){var _0x4a6565=_0xc5665b;_0x35f5a4(_0x4a6565(0x31e))[_0x4a6565(0x4ad)]='โ€ผ';}}else return;}_0x495e21[_0xc5665b(0x4d7)]['length']?(_0x495e21['queueList']['length']>0xa?getById(_0xc5665b(0x31e))[_0xc5665b(0x4ad)]='โ€ผ':getById('queueNotification')[_0xc5665b(0x4ad)]=_0x495e21[_0xc5665b(0x4d7)][_0xc5665b(0xaf)],getById(_0xc5665b(0x31e))[_0xc5665b(0x124)]['add'](_0xc5665b(0x31e))):(getById('queueNotification')['innerHTML']='',getById(_0xc5665b(0x31e))[_0xc5665b(0x124)][_0xc5665b(0x3c9)](_0xc5665b(0x31e)));},_0x495e21['nextQueue']=function(){var _0x22c60f=_0x2a0a0d;if(!_0x495e21[_0x22c60f(0x3f4)])return;if(!_0x495e21[_0x22c60f(0x455)])return;if(_0x495e21[_0x22c60f(0x4d7)][_0x22c60f(0xaf)]==0x0){getById('queuebutton')['classList']['add'](_0x22c60f(0xb1)),getById(_0x22c60f(0x489))['classList'][_0x22c60f(0x14e)]('red'),getById(_0x22c60f(0x489))[_0x22c60f(0x124)][_0x22c60f(0x3c9)](_0x22c60f(0x22d)),setTimeout(function(){var _0x44f8a4=_0x22c60f;getById(_0x44f8a4(0x489))[_0x44f8a4(0x124)]['add'](_0x44f8a4(0x22d)),getById(_0x44f8a4(0x489))[_0x44f8a4(0x124)][_0x44f8a4(0x3c9)]('float2'),getById('queuebutton')[_0x44f8a4(0x124)][_0x44f8a4(0x3c9)](_0x44f8a4(0x2bc));},0x32);return;}var _0x2b3fbc=_0x495e21['queueList']['shift']();getById('queuebutton')[_0x22c60f(0x124)][_0x22c60f(0x14e)](_0x22c60f(0xb1)),getById(_0x22c60f(0x489))[_0x22c60f(0x124)][_0x22c60f(0x3c9)]('float'),setTimeout(function(){var _0x466171=_0x22c60f;getById(_0x466171(0x489))['classList']['add'](_0x466171(0x22d)),getById('queuebutton')['classList'][_0x466171(0x3c9)](_0x466171(0xb1));},0xc8),_0x495e21[_0x22c60f(0x298)](),_0x495e21[_0x22c60f(0x3f0)](_0x2b3fbc),log(_0x22c60f(0x363)+_0x2b3fbc);},_0x495e21['ping']=function(){var _0x26a0d9=_0x2a0a0d;if('byoRI'!==_0x26a0d9(0x378)){function _0x748ffb(){var _0x29ca9b=_0x26a0d9,_0x2f0380=this[_0x29ca9b(0x23e)];}}else{if(_0x495e21[_0x26a0d9(0xe3)]){if(_0x26a0d9(0x10c)===_0x26a0d9(0x10c))return;else{function _0x1af9df(){var _0x554dca=_0x26a0d9;_0x39a8f6[_0x554dca(0x26b)](!![]);}}}clearTimeout(_0x495e21[_0x26a0d9(0x371)]);if(!_0x495e21['ws']||_0x495e21['ws'][_0x26a0d9(0x454)]!==0x1)return;_0x495e21[_0x26a0d9(0x371)]=setTimeout(function(){var _0x367452=_0x26a0d9;log('Pinging');var _0x198d10={};_0x198d10[_0x367452(0x317)]=_0x367452(0x3ed),_0x495e21[_0x367452(0x1e7)](_0x198d10);},0xbb8);}},_0x495e21[_0x2a0a0d(0x3f0)]=function(_0x460ab7){var _0x2c206c=_0x2a0a0d;_0x495e21[_0x2c206c(0x26b)]();if(_0x460ab7[_0x2c206c(0xaf)]>0x0){var _0x1d7e21={};_0x1d7e21[_0x2c206c(0x317)]='play',_0x1d7e21[_0x2c206c(0x23e)]=_0x460ab7,_0x495e21['sendMsg'](_0x1d7e21),_0x495e21[_0x2c206c(0x268)][_0x460ab7]=!![];}else log(_0x2c206c(0x254));},_0x495e21[_0x2a0a0d(0x2a0)]=function _0x5eada6(_0x18161e){var _0x289e98=_0x2a0a0d;_0x495e21[_0x289e98(0x26b)]();var _0x32b22f={};return _0x32b22f[_0x289e98(0x317)]=_0x289e98(0x2ab),_0x495e21[_0x289e98(0x455)]&&(_0x32b22f[_0x289e98(0x22b)]=!![]),_0x495e21[_0x289e98(0xe3)]&&(_0x32b22f[_0x289e98(0x23e)]=_0x495e21[_0x289e98(0x23e)]),_0x495e21[_0x289e98(0x4c0)]===![]&&(_0x495e21[_0x289e98(0x4c0)]=!![]),_0x495e21[_0x289e98(0x211)]?_0x495e21[_0x289e98(0x486)]?_0x495e21[_0x289e98(0x173)](_0x18161e+_0x495e21[_0x289e98(0x211)]+_0x495e21[_0x289e98(0x3f1)],0x10)[_0x289e98(0x34d)](function(_0x2d578c){var _0x5112e6=_0x289e98;if(_0x495e21[_0x5112e6(0xe3)]){if(_0x5112e6(0x42a)===_0x5112e6(0x42a))_0x495e21[_0x5112e6(0x2e0)]=_0x2d578c;else{function _0x12e1e3(){var _0x1fe26f=_0x5112e6;_0x4b0555[_0x1fe26f(0x4c0)]=_0x1fe26f(0x19f),_0x50b9ae(_0x1fe26f(0x3f9));}}}return _0x32b22f[_0x5112e6(0x3b3)]=_0x2d578c,_0x495e21['sendMsg'](_0x32b22f),_0x495e21['listPromise']=_0x56a37f(),log(_0x5112e6(0x39c)),_0x495e21[_0x5112e6(0x39a)];}):_0x495e21['generateHash'](_0x495e21[_0x289e98(0x211)]+_0x495e21['salt'],0x6)[_0x289e98(0x34d)](function(_0x7d45d7){var _0x42942a=_0x289e98;return _0x495e21[_0x42942a(0x486)]=_0x7d45d7,log(_0x42942a(0x1f9)+_0x7d45d7),log(_0x42942a(0x2f7)),_0x495e21[_0x42942a(0x2a0)](_0x18161e);}):(_0x495e21[_0x289e98(0xe3)]&&(_0x495e21[_0x289e98(0x2e0)]=_0x18161e),_0x32b22f['roomid']=_0x18161e,_0x495e21['sendMsg'](_0x32b22f),_0x495e21[_0x289e98(0x39a)]=_0x56a37f(),log(_0x289e98(0x324)),_0x495e21[_0x289e98(0x39a)]);},_0x495e21[_0x2a0a0d(0x1e7)]=function(_0x71b765){var _0x372075=_0x2a0a0d;if(_0x372075(0x4a5)===_0x372075(0xcf)){function _0x13abe3(){var _0xf6bba9=_0x372075;_0x11bfb3['director']==!![]&&((_0x5a1ba4||_0xb9bce)&&(_0x241860['pcs'][_0x37e34b][_0xf6bba9(0x3d5)]==!![]&&(_0x3e2602['pcs'][_0x3128a2][_0xf6bba9(0x438)]=!![])));}}else{_0x495e21[_0x372075(0xe3)]&&(_0x495e21['UUID']?_0x71b765[_0x372075(0x337)]=_0x495e21[_0x372075(0x12e)]:(_0x495e21[_0x372075(0x12e)]=_0x495e21['generateStreamID'](0x14),_0x71b765[_0x372075(0x337)]=_0x495e21[_0x372075(0x12e)]),_0x495e21[_0x372075(0x455)]&&(_0x71b765['director']=!![]),!(_0x372075(0x3b3)in _0x71b765)&&(_0x495e21[_0x372075(0x2e0)]&&(_0x71b765[_0x372075(0x3b3)]=_0x495e21[_0x372075(0x2e0)])));clearTimeout(_0x495e21[_0x372075(0x371)]);try{if(_0x495e21[_0x372075(0x211)]){if(_0x71b765[_0x372075(0x23e)]){if(_0x495e21[_0x372075(0x486)]!==![]){if(typeof _0x495e21['ws']!==_0x372075(0x169)||_0x495e21['ws'][_0x372075(0x454)]!==0x1){if(_0x372075(0x212)!==_0x372075(0x212)){function _0x11dd85(){var _0xb18687=_0x372075;_0x128713[_0xb18687(0x1a3)]['subtle']['importKey'](_0xb18687(0x399),{'kty':_0xb18687(0x420),'e':_0xb18687(0x4fc),'n':_0x4de2e2,'alg':_0xb18687(0x432),'ext':!![]},{'name':'RSASSA-PKCS1-v1_5','hash':{'name':_0xb18687(0x30f)}},!![],[_0xb18687(0x4c2)])[_0xb18687(0x34d)](function(_0x38957a){var _0x5c479e=_0xb18687;_0x35cf24[_0x5c479e(0x31f)][_0x5cc3b9]={},_0x216c63[_0x5c479e(0x31f)][_0x1b81b2]['publicKey']=_0x38957a,_0x19b9d1[_0x5c479e(0x31f)][_0x4ca71e][_0x5c479e(0x461)]=null;})[_0xb18687(0x236)](_0x3ded87);}}else log(_0x71b765,_0x372075(0xb5)),_0x495e21[_0x372075(0xe0)][_0x372075(0x17e)](_0x71b765);}else{_0x71b765[_0x372075(0x23e)]=_0x71b765[_0x372075(0x23e)][_0x372075(0x111)](0x0,0x18)+_0x495e21[_0x372075(0x486)][_0x372075(0x111)](0x0,0x6);var _0x501c59=JSON[_0x372075(0x1e9)](_0x71b765);if(_0x501c59[_0x372075(0xaf)]>0x3a98){errorlog('msg\x20size\x20error');return;}_0x495e21['ws'][_0x372075(0x506)](_0x501c59);}}else return _0x495e21[_0x372075(0x173)](_0x495e21[_0x372075(0x211)]+_0x495e21['salt'],0x6)['then'](function(_0x54f60a){var _0x1577ea=_0x372075;_0x495e21[_0x1577ea(0x486)]=_0x54f60a;if(typeof _0x495e21['ws']!==_0x1577ea(0x169)||_0x495e21['ws'][_0x1577ea(0x454)]!==0x1)log(_0x71b765,_0x1577ea(0xb5)),_0x495e21[_0x1577ea(0xe0)][_0x1577ea(0x17e)](_0x71b765);else{_0x71b765[_0x1577ea(0x23e)]=_0x71b765[_0x1577ea(0x23e)][_0x1577ea(0x111)](0x0,0x18)+_0x495e21[_0x1577ea(0x486)]['substring'](0x0,0x6);var _0x43349a=JSON[_0x1577ea(0x1e9)](_0x71b765);if(_0x43349a['length']>0x3a98){errorlog(_0x1577ea(0x29d));return;}_0x495e21['ws'][_0x1577ea(0x506)](_0x43349a);}});}else{if(typeof _0x495e21['ws']!=='object'||_0x495e21['ws'][_0x372075(0x454)]!==0x1)log(_0x71b765,'could\x20not\x20be\x20sent;\x20queuing\x20it'),_0x495e21[_0x372075(0xe0)][_0x372075(0x17e)](_0x71b765);else{var _0x501c59=JSON[_0x372075(0x1e9)](_0x71b765);if(_0x501c59[_0x372075(0xaf)]>0x3a98){errorlog(_0x372075(0x29d));return;}_0x495e21['ws'][_0x372075(0x506)](_0x501c59);}}}else{if(typeof _0x495e21['ws']!==_0x372075(0x169)||_0x495e21['ws'][_0x372075(0x454)]!==0x1)log(_0x71b765,'could\x20not\x20be\x20sent;\x20queuing\x20it'),_0x495e21[_0x372075(0xe0)][_0x372075(0x17e)](_0x71b765);else{var _0x501c59=JSON[_0x372075(0x1e9)](_0x71b765);if(_0x501c59[_0x372075(0xaf)]>0x3a98){errorlog(_0x372075(0x29d));return;}_0x495e21['ws'][_0x372075(0x506)](_0x501c59);}}}catch(_0x4e8d57){errorlog(_0x4e8d57);}}},_0x495e21[_0x2a0a0d(0x26b)]=function _0x2c6299(_0x595627=![]){var _0x507f10=_0x2a0a0d;if(_0x495e21['taintedSession']===!![]){log(_0x507f10(0x35b));return;}if(_0x495e21['ws']!==null){log(_0x507f10(0x4c1));return;}_0x495e21[_0x507f10(0x376)]==![]&&(_0x495e21[_0x507f10(0x376)]=_0x507f10(0x20d)),_0x495e21['ws']=new WebSocket(_0x495e21[_0x507f10(0x376)]),_0x595627==![]&&(_0x495e21[_0x507f10(0x273)]=setTimeout(function(){var _0x249113=_0x507f10;pokeIframeAPI(_0x249113(0x466),'timeout'),errorlog(_0x249113(0x1d2)),!_0x495e21[_0x249113(0xe9)]&&(!window['obsstudio']&&setTimeout(function(){var _0x172dc1=_0x249113;warnUser(_0x172dc1(0x172));},0x1));},0x7530)),_0x495e21['ws'][_0x507f10(0x13c)]=function _0x56126f(){var _0x45e397=_0x507f10;clearTimeout(_0x495e21['pingTimeout']),clearInterval(_0x495e21['timeout']),log(_0x45e397(0x216)),checkConnection();if(_0x495e21[_0x45e397(0x31b)]){errorlog(_0x45e397(0x36d));for(_0x442400 in _0x495e21[_0x45e397(0x3cc)]){if(_0x45e397(0x1fa)!==_0x45e397(0x1fa)){function _0x335c75(){var _0x2f581d=_0x45e397;delete _0x76a633[_0x2f581d(0x3fd)][_0x5f2139],_0x562aff[_0x2f581d(0x386)](),_0x48d3df();return;}}else try{_0x495e21[_0x45e397(0x3cc)][_0x442400][_0x45e397(0x229)]();}catch(_0x1a3bb3){}}for(_0x442400 in _0x495e21[_0x45e397(0x3fd)]){try{_0x495e21[_0x45e397(0x3fd)][_0x442400][_0x45e397(0x229)]();}catch(_0x26b5c2){}}_0x495e21[_0x45e397(0x31b)]=![],_0x495e21[_0x45e397(0x4f2)]=![];}if(_0x495e21[_0x45e397(0xe0)]!==[])try{var _0xbfe172=_0x495e21[_0x45e397(0xe0)][_0x45e397(0x187)](-0xa);_0x495e21['msg']=[];for(var _0x3fc9ce in _0xbfe172){log(_0x45e397(0x492)),_0x495e21[_0x45e397(0x1e7)](_0xbfe172[_0x3fc9ce]);}}catch(_0x52c05f){errorlog(_0x52c05f);}if(_0x595627==!![]){pokeIframeAPI(_0x45e397(0x466),'reconnected');_0x495e21['seeding']&&_0x495e21[_0x45e397(0x35e)]();if(_0x495e21['roomid']!==![]){if(_0x495e21[_0x45e397(0x3b3)]===''&&(!_0x495e21[_0x45e397(0x227)]||_0x495e21[_0x45e397(0x227)]==='')){}else log(_0x45e397(0x13f)),log(_0x45e397(0x40e)),joinRoom(_0x495e21[_0x45e397(0x3b3)]);}else{var _0x17e0fe=Object[_0x45e397(0x31f)](_0x495e21[_0x45e397(0x268)]);for(var _0x442400 in _0x17e0fe){log(_0x45e397(0x1e6)+_0x17e0fe[_0x442400]),_0x495e21[_0x45e397(0x3f0)](_0x17e0fe[_0x442400]);}}}else pokeIframeAPI(_0x45e397(0x466),'connected');},_0x495e21[_0x507f10(0x499)]=function(_0x2cb9c3,_0x128f5a=![]){var _0x8299f4=_0x507f10,_0x1ebe3e=[];for(var _0x4e5f86 in _0x495e21[_0x8299f4(0x3fd)]){if(_0x128f5a&&_0x128f5a!==_0x4e5f86)continue;try{_0x495e21[_0x8299f4(0x3fd)][_0x4e5f86]['sendChannel'][_0x8299f4(0x506)](JSON[_0x8299f4(0x1e9)](_0x2cb9c3)),_0x1ebe3e[_0x8299f4(0x17e)](_0x4e5f86);}catch(_0x360ba8){warnlog(_0x8299f4(0x520));}if(_0x128f5a&&_0x128f5a===_0x4e5f86)return;}for(var _0x4e5f86 in _0x495e21[_0x8299f4(0x3cc)]){if(_0x128f5a&&_0x128f5a!==_0x4e5f86)continue;if(_0x1ebe3e[_0x8299f4(0x4a0)](_0x4e5f86))continue;try{_0x495e21[_0x8299f4(0x3cc)][_0x4e5f86][_0x8299f4(0xd3)][_0x8299f4(0x506)](JSON[_0x8299f4(0x1e9)](_0x2cb9c3));}catch(_0x47510c){warnlog(_0x8299f4(0xde));}}},_0x495e21[_0x507f10(0x143)]=function(_0x44c219,_0x1653f6=![]){var _0x27bcac=_0x507f10,_0x3ddea3=![];if(_0x27bcac(0x12e)in _0x44c219)_0x3ddea3=_0x495e21[_0x27bcac(0x3bd)](_0x44c219,_0x44c219[_0x27bcac(0x12e)]),_0x3ddea3?(log(_0x44c219),log(_0x27bcac(0x4b0))):(log(_0x27bcac(0x3d3)),_0x495e21[_0x27bcac(0x1e7)](_0x44c219));else _0x1653f6?(_0x3ddea3=_0x495e21[_0x27bcac(0x3bd)](_0x44c219),_0x3ddea3?(log(_0x44c219),log(_0x27bcac(0x4a1))):(log(_0x27bcac(0x45f)),_0x495e21[_0x27bcac(0x1e7)](_0x44c219))):(_0x495e21[_0x27bcac(0x1e7)](_0x44c219),log(_0x27bcac(0x266)));},_0x495e21['anyrequest']=function(_0xe2f32d,_0x12f3d5=![]){var _0x3f05d7=_0x507f10,_0x50b9f0=![];if(_0x3f05d7(0x12e)in _0xe2f32d){_0x50b9f0=_0x495e21[_0x3f05d7(0x166)](_0xe2f32d,_0xe2f32d[_0x3f05d7(0x12e)]);if(_0x50b9f0)log(_0x3f05d7(0x4b0));else{if(_0x3f05d7(0x350)===_0x3f05d7(0x2cf)){function _0x1befde(){var _0x2ebcf3=_0x3f05d7;_0xbbd0cd[_0x2ebcf3(0x482)]=![];}}else log(_0x3f05d7(0x3d3)),_0x495e21[_0x3f05d7(0x1e7)](_0xe2f32d);}}else _0x12f3d5?(_0x50b9f0=_0x495e21[_0x3f05d7(0x166)](_0xe2f32d),_0x50b9f0?log('successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS\x20to\x20all\x20RTC\x20Peers'):(log(_0x3f05d7(0x45f)),_0x495e21['sendMsg'](_0xe2f32d))):(_0x495e21[_0x3f05d7(0x1e7)](_0xe2f32d),log(_0x3f05d7(0x266)));},_0x495e21[_0x507f10(0x473)]=function(){var _0x3ec8ce=_0x507f10;if(_0x495e21['disableOBS']===![]){var _0x27d709={},_0x20cbd7=![];_0x495e21[_0x3ec8ce(0x278)][_0x3ec8ce(0xdb)]!==null&&(_0x495e21[_0x3ec8ce(0x278)][_0x3ec8ce(0xdb)]===![]&&(_0x20cbd7=!![]),_0x27d709[_0x3ec8ce(0x3be)]=_0x495e21[_0x3ec8ce(0x278)][_0x3ec8ce(0xdb)]);_0x495e21[_0x3ec8ce(0x278)]['sourceActive']!==null&&(_0x27d709[_0x3ec8ce(0x35a)]=_0x495e21[_0x3ec8ce(0x278)][_0x3ec8ce(0x498)]);_0x495e21[_0x3ec8ce(0x278)][_0x3ec8ce(0x256)]!==null&&(_0x27d709[_0x3ec8ce(0x1af)]=_0x495e21[_0x3ec8ce(0x278)][_0x3ec8ce(0x256)]);_0x495e21[_0x3ec8ce(0x278)][_0x3ec8ce(0x12f)]!==null&&(_0x27d709[_0x3ec8ce(0x3f3)]=_0x495e21['obsState'][_0x3ec8ce(0x12f)]);for(var _0x5ad153 in _0x495e21[_0x3ec8ce(0x3cc)]){if(_0x495e21[_0x3ec8ce(0x42c)]!==![]){var _0x464256=parseInt(_0x495e21[_0x3ec8ce(0x3cc)][_0x5ad153][_0x3ec8ce(0x265)]);_0x20cbd7&&((_0x464256>_0x495e21['optimize']||_0x464256<0x0)&&(_0x464256=_0x495e21[_0x3ec8ce(0x42c)])),_0x495e21[_0x3ec8ce(0x3cc)][_0x5ad153][_0x3ec8ce(0x477)]!==_0x464256?(_0x27d709[_0x3ec8ce(0x2d0)]=_0x464256,warnlog(_0x3ec8ce(0xf3)),warnlog(_0x27d709),_0x495e21[_0x3ec8ce(0x166)](_0x27d709,_0x5ad153)?_0x495e21[_0x3ec8ce(0x3cc)][_0x5ad153][_0x3ec8ce(0x477)]=_0x464256:errorlog(_0x3ec8ce(0x127))):(warnlog(_0x3ec8ce(0xf3)),warnlog(_0x27d709),_0x495e21['sendRequest'](_0x27d709,_0x5ad153));}else{if(_0x3ec8ce(0x189)===_0x3ec8ce(0x189))warnlog(_0x3ec8ce(0xf3)),warnlog(_0x27d709),_0x495e21['sendRequest'](_0x27d709,_0x5ad153);else{function _0x2bd312(){var _0x7dcac7=_0x3ec8ce;_0x3d221b[_0x7dcac7(0x2d6)](0x0,_0x12603c);}}}}}},_0x495e21[_0x507f10(0x133)]=function(_0x568624){var _0x4091f5=_0x507f10;if(!_0x495e21[_0x4091f5(0x3cc)][_0x568624][_0x4091f5(0x2f6)])return;var _0x3a1611={};_0x3a1611[_0x4091f5(0x167)]=_0x495e21[_0x4091f5(0x3cc)][_0x568624][_0x4091f5(0x2f6)][_0x4091f5(0x3b8)][_0x4091f5(0x443)]!='none',_0x3a1611[_0x4091f5(0x1df)]=_0x495e21[_0x4091f5(0x3cc)][_0x568624][_0x4091f5(0x2f6)][_0x4091f5(0x3dd)];if(_0x495e21[_0x4091f5(0x42c)]!==![]){var _0x4586a2=parseInt(_0x495e21[_0x4091f5(0x3cc)][_0x568624][_0x4091f5(0x265)]);_0x3a1611[_0x4091f5(0x167)]===![]&&((_0x4586a2>_0x495e21[_0x4091f5(0x42c)]||_0x4586a2<0x0)&&(_0x4586a2=_0x495e21[_0x4091f5(0x42c)])),_0x495e21[_0x4091f5(0x3cc)][_0x568624][_0x4091f5(0x477)]!==_0x4586a2?(_0x3a1611[_0x4091f5(0x2d0)]=_0x4586a2,_0x495e21['sendRequest'](_0x3a1611,_0x568624)?_0x495e21['rpcs'][_0x568624][_0x4091f5(0x477)]=_0x4586a2:errorlog(_0x4091f5(0x127))):_0x495e21[_0x4091f5(0x166)](_0x3a1611,_0x568624);}else _0x495e21['sendRequest'](_0x3a1611,_0x568624);},_0x495e21[_0x507f10(0x282)]=function(_0x3294ce){var _0x572530=_0x507f10;if(_0x572530(0xad)in _0x3294ce){if(_0x572530(0x21f)!==_0x572530(0x21f)){function _0x1a0375(){var _0xe9ba8c=_0x572530;_0x3ad185[_0xe9ba8c(0x47c)]==!![]&&(_0xb40bf6[_0xe9ba8c(0x3fd)][_0x5822d8][_0xe9ba8c(0x35c)]=!![]);}}else{if('target'in _0x3294ce){if(_0x572530(0xb8)!==_0x572530(0x287)){if(_0x572530(0x44c)in _0x3294ce){if(_0x495e21['scene']!==![]){var _0xfe1004=![];for(var _0x5a5e08 in _0x495e21[_0x572530(0x3cc)]){if(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x23e)]===_0x3294ce['target']){if('value'in _0x3294ce){if(_0x3294ce[_0x572530(0xad)]=='mute'){if(_0x3294ce[_0x572530(0x15c)]==0x0){if(_0x572530(0x4ed)===_0x572530(0x4b8)){function _0x23ed51(){var _0x4b813f=_0x572530;_0x1ffeb4[_0x4b813f(0x22b)]==![]&&(!_0x40743e[_0x4b813f(0xe9)]&&(_0x57ed3e(function(){var _0x380370=_0x4b813f;_0x336b16(_0x380370(0x260));},0x1),_0x4f8157(_0x4b813f(0x20a))[_0x4b813f(0x4ad)]=_0x4b813f(0x1fe)));}}else log(_0x572530(0x3de)),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]&&(_0x495e21['rpcs'][_0x5a5e08][_0x572530(0x2f6)]['muted']=!![],_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x10a)]=!![]);}else log(_0x572530(0x142)),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]&&(_0x495e21['rpcs'][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]==_0x572530(0x51d)?(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x10a)]=![],_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3dd)]=!![]):(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x10a)]=![],_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]['muted']=![]));_0x495e21[_0x572530(0x133)](_0x5a5e08);}else{if(_0x3294ce['action']==_0x572530(0x443)){if(_0x495e21[_0x572530(0x227)]){if(_0x572530(0xd7)!==_0x572530(0xd7)){function _0x413456(){var _0x42e58e=_0x572530;_0x255f5a(_0x203546[_0x42e58e(0x3fd)][_0x365ba6][_0x42e58e(0x3ec)]),_0x4188a3['pcs'][_0x408cb1][_0x42e58e(0x3ec)]=null;}}else return;};if(_0x495e21[_0x572530(0x44c)]===_0x3294ce[_0x572530(0x44c)]){if(_0x495e21[_0x572530(0x483)]==0x2){if(_0x3294ce[_0x572530(0x15c)]==0x0)_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3dd)]=!![],_0x495e21['rpcs'][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]&&_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]!==_0x572530(0x51d)&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)]['display']=_0x572530(0x51d),_0xfe1004=!![]));else{for(var _0x64a9b4 in _0x495e21['rpcs']){_0x64a9b4!==_0x5a5e08&&(_0x495e21[_0x572530(0x3cc)][_0x64a9b4][_0x572530(0x2f6)]&&(_0x495e21[_0x572530(0x3cc)][_0x64a9b4]['videoElement'][_0x572530(0x3dd)]=!![],_0x495e21[_0x572530(0x3cc)][_0x64a9b4][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]&&_0x495e21[_0x572530(0x3cc)][_0x64a9b4]['videoElement'][_0x572530(0x3b8)][_0x572530(0x443)]!==_0x572530(0x51d)&&(_0x495e21[_0x572530(0x3cc)][_0x64a9b4][_0x572530(0x2f6)]['style'][_0x572530(0x443)]=_0x572530(0x51d),_0xfe1004=!![])));}_0x495e21[_0x572530(0x3cc)][_0x5a5e08]['videoElement']&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08]['videoElement']['style']['display']&&_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]!==_0x572530(0x101)&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08]['videoElement'][_0x572530(0x3b8)][_0x572530(0x443)]=_0x572530(0x101),_0xfe1004=!![]),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x10a)]===null?_0x495e21['rpcs'][_0x5a5e08]['videoElement'][_0x572530(0x3dd)]=![]:_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3dd)]=_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x10a)],_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x213)]&&clearInterval(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]['controlTimer']),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0xd9)]=![],_0x495e21['rpcs'][_0x5a5e08]['videoElement'][_0x572530(0x213)]=setTimeout(showControlBar['bind'](null,_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]),0xbb8));}}else{if(_0x495e21[_0x572530(0x483)]==0x1){if(_0x3294ce[_0x572530(0x15c)]==0x0)_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]&&(_0x495e21['rpcs'][_0x5a5e08]['videoElement'][_0x572530(0x3b8)][_0x572530(0x443)]&&_0x495e21['rpcs'][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]!==_0x572530(0x51d)&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]=_0x572530(0x51d),_0xfe1004=!![]));else{for(var _0x64a9b4 in _0x495e21[_0x572530(0x3cc)]){if(_0x64a9b4!==_0x5a5e08){if(_0x572530(0x33b)===_0x572530(0x1d9)){function _0x131529(){var _0x1d6f73=_0x572530;_0xd23525[_0x1d6f73(0x12e)]in _0x13e8e8[_0x1d6f73(0x3cc)]&&_0x41aa54[_0x1d6f73(0x38f)](_0x206629[_0x1d6f73(0x12e)]);}}else _0x495e21[_0x572530(0x3cc)][_0x64a9b4][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]&&_0x495e21[_0x572530(0x3cc)][_0x64a9b4][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]!==_0x572530(0x51d)&&(_0x495e21[_0x572530(0x3cc)][_0x64a9b4][_0x572530(0x2f6)][_0x572530(0x3b8)]['display']=_0x572530(0x51d),_0xfe1004=!![]);}}_0x495e21[_0x572530(0x3cc)][_0x5a5e08]['videoElement']&&(_0x495e21['rpcs'][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]&&_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]!==_0x572530(0x101)&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]['style'][_0x572530(0x443)]='block',_0xfe1004=!![]),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x213)]&&clearInterval(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x213)]),_0x495e21[_0x572530(0x3cc)][_0x5a5e08]['videoElement'][_0x572530(0xd9)]=![],_0x495e21['rpcs'][_0x5a5e08]['videoElement'][_0x572530(0x213)]=setTimeout(showControlBar[_0x572530(0xbb)](null,_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]),0xbb8));}}else _0x3294ce['value']==0x0?_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]&&(_0x495e21['rpcs'][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)]['display']&&_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]!==_0x572530(0x51d)&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]=_0x572530(0x51d),_0xfe1004=!![]),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3dd)]=!![]):_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]&&_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]!==_0x572530(0x101)&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3b8)][_0x572530(0x443)]=_0x572530(0x101),_0xfe1004=!![]),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x10a)]===null?_0x495e21[_0x572530(0x3cc)][_0x5a5e08]['videoElement'][_0x572530(0x3dd)]=![]:_0x495e21['rpcs'][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3dd)]=_0x495e21['rpcs'][_0x5a5e08][_0x572530(0x10a)],_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]['controlTimer']&&clearInterval(_0x495e21[_0x572530(0x3cc)][_0x5a5e08]['videoElement']['controlTimer']),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]['controls']=![],_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]['controlTimer']=setTimeout(showControlBar[_0x572530(0xbb)](null,_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]),0xbb8));}}_0x495e21[_0x572530(0x133)](_0x5a5e08);}else _0x3294ce['action']=='volume'&&(log(parseInt(_0x3294ce['value'])/0x64),_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)]&&(_0x495e21[_0x572530(0x3cc)][_0x5a5e08][_0x572530(0x2f6)][_0x572530(0x3f8)]=parseInt(_0x3294ce[_0x572530(0x15c)])/0x64,log(_0x572530(0xe2))));}}}}_0xfe1004&&updateMixer();}}else{if(_0x3294ce['action']==_0x572530(0x132)){}else{if(_0x3294ce[_0x572530(0xad)]==_0x572530(0x219)){}}}}else{function _0x10c85f(){var _0x205a6b=_0x572530;_0x436326[_0x205a6b(0x23e)]=_0x35f1b8[_0x205a6b(0x23e)]['substring'](0x0,0x18)+_0x496fe3[_0x205a6b(0x486)][_0x205a6b(0x111)](0x0,0x6);var _0x53ae88=_0x196b7f[_0x205a6b(0x1e9)](_0x3580f1);if(_0x53ae88['length']>0x3a98){_0x54d667('msg\x20size\x20error');return;}_0x913a06['ws'][_0x205a6b(0x506)](_0x53ae88);}}}}}},_0x495e21['ws'][_0x507f10(0x16d)]=function(_0x5bc75b){var _0x101019=_0x507f10;clearTimeout(_0x495e21[_0x101019(0x371)]);var _0x267192=JSON['parse'](_0x5bc75b[_0x101019(0x488)]);_0x101019(0x23e)in _0x267192&&(_0x267192[_0x101019(0x23e)]=_0x495e21[_0x101019(0x14b)](_0x267192[_0x101019(0x23e)]));if(_0x495e21[_0x101019(0xe3)]){if(_0x101019(0x12e)in _0x267192){if(_0x495e21[_0x101019(0x12e)]){if(_0x267192['UUID']!==_0x495e21[_0x101019(0x12e)])return;}else return;delete _0x267192['UUID'];}if(_0x101019(0x3b3)in _0x267192){if(!_0x495e21['roomenc'])return;if(_0x101019(0x317)in _0x267192){if(_0x267192[_0x101019(0x317)]===_0x101019(0x132)){if(_0x101019(0x3b3)in _0x267192){if('target'in _0x267192){if(_0x267192[_0x101019(0x201)]==_0x495e21[_0x101019(0x12e)]){_0x267192[_0x101019(0x317)]=_0x101019(0x31b),_0x495e21['roomenc']=_0x267192[_0x101019(0x3b3)];var _0x499399={};_0x499399[_0x101019(0x317)]='joinroom',_0x499399[_0x101019(0x3b3)]=_0x495e21[_0x101019(0x2e0)],_0x499399[_0x101019(0x23e)]=_0x495e21['streamID'],_0x495e21[_0x101019(0x1e7)](_0x499399);}else return;}else return;}else return;}else{if(_0x267192[_0x101019(0x3b3)]!==_0x495e21['roomenc'])return;}}else{if(_0x267192[_0x101019(0x3b3)]!==_0x495e21[_0x101019(0x2e0)]){if(_0x101019(0x2bf)!==_0x101019(0x2fe))return;else{function _0x161070(){var _0x3d92cf=_0x101019;_0x25b12e[_0x3d92cf(0x3cc)][_0x2c3711]['videoElement']&&(_0x55ae1a[_0x3d92cf(0x3cc)][_0x762bd6][_0x3d92cf(0x2f6)][_0x3d92cf(0x388)]&&_0x5d6ca0[_0x3d92cf(0x3cc)][_0x1101d5]['videoElement'][_0x3d92cf(0x4c7)]()[_0x3d92cf(0x34d)](_0x48ac26=>{var _0x311af1=_0x3d92cf;_0x3c8505(_0x311af1(0x2c3));})[_0x3d92cf(0x236)](_0x2b67df));}}}}delete _0x267192[_0x101019(0x3b3)];}if(_0x101019(0x455)in _0x267192){if(_0x267192[_0x101019(0x337)]){if(_0x101019(0x1c2)===_0x101019(0x1c2))_0x495e21['directorUUID']=_0x267192['from'];else{function _0x438f0a(){var _0x4e174e=_0x101019;_0x1b5a65+=_0x1f9643(_0x4a3481['encodings'][0x0][_0x4e174e(0x41c)])/0x400,_0x19f1e8(_0x6cd2dc);}}}delete _0x267192['director'];}_0x101019(0x337)in _0x267192&&(_0x267192['UUID']=_0x267192[_0x101019(0x337)],delete _0x267192['from']);if(_0x101019(0x317)in _0x267192){if(_0x267192[_0x101019(0x317)]===_0x101019(0x4c7)){if(_0x101019(0x23e)in _0x267192){if(_0x267192[_0x101019(0x23e)]===_0x495e21[_0x101019(0x23e)]){if(_0x101019(0x4ab)!==_0x101019(0x4ab)){function _0x454be6(){var _0x1e362d=_0x101019;return _0x56092d(_0x1e362d(0x290)),![];}}else _0x267192[_0x101019(0x317)]=_0x101019(0x38f);}else return;}}else{if(_0x267192[_0x101019(0x317)]===_0x101019(0x2b7)){if(_0x495e21[_0x101019(0x315)]){if(_0x495e21['view_set'][_0x101019(0x4a0)](_0x267192['streamID'])){play(_0x267192[_0x101019(0x23e)]);return;}else return;}else{if(_0x495e21[_0x101019(0x227)]){if(_0x495e21[_0x101019(0x227)]!==_0x267192['streamID'])return;else{play(_0x267192[_0x101019(0x23e)]);return;}}}}else{if(_0x267192[_0x101019(0x317)]==='joinroom'){if('streamID'in _0x267192){if(_0x495e21[_0x101019(0x315)]){if(_0x495e21[_0x101019(0x315)][_0x101019(0x4a0)](_0x267192[_0x101019(0x23e)]))play(_0x267192[_0x101019(0x23e)]);else{}}else{if(_0x495e21[_0x101019(0x227)]){if(_0x101019(0x1f5)!==_0x101019(0x155)){if(_0x495e21[_0x101019(0x227)]!==_0x267192[_0x101019(0x23e)]){}else play(_0x267192[_0x101019(0x23e)]);}else{function _0x1971e7(){var _0x350fa5=_0x101019,_0x6a413e={};_0x6a413e[_0x350fa5(0x3a5)]=_0x350fa5(0x449),_0x44a373[_0x350fa5(0x3bd)](_0x6a413e,_0x2104f7);}}}else play(_0x267192[_0x101019(0x23e)]);}}_0x267192[_0x101019(0x317)]=_0x101019(0x38f);}}}}}if(_0x267192['request']){if(_0x267192[_0x101019(0x317)]==_0x101019(0x38f)){if(_0x495e21[_0x101019(0x3f4)]){if(_0x495e21[_0x101019(0x389)]===_0x267192[_0x101019(0x12e)])_0x495e21[_0x101019(0x38f)](_0x267192[_0x101019(0x12e)]);else _0x495e21[_0x101019(0x455)]&&(_0x267192[_0x101019(0x12e)]in _0x495e21[_0x101019(0x3cc)]&&_0x495e21[_0x101019(0x38f)](_0x267192[_0x101019(0x12e)]));}else _0x495e21[_0x101019(0x38f)](_0x267192[_0x101019(0x12e)]);}else{if(_0x267192[_0x101019(0x317)]==_0x101019(0x148)){log(_0x267192[_0x101019(0x36e)]);if(_0x101019(0x455)in _0x267192){_0x495e21[_0x101019(0x389)]=_0x267192[_0x101019(0x455)];if(_0x495e21[_0x101019(0x389)]in _0x495e21[_0x101019(0x3fd)]){if('XzAZA'!==_0x101019(0x2c7))_0x495e21[_0x101019(0x3fd)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)]&&(_0x495e21[_0x101019(0x3fd)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)][_0x101019(0x455)]=!![]);else{function _0x70fd1b(){var _0x468d2f=_0x101019;_0x31e156[_0x468d2f(0x38f)](_0x524a4b);}}}_0x495e21[_0x101019(0x389)]in _0x495e21['rpcs']&&(_0x495e21[_0x101019(0x3cc)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)]&&(_0x495e21[_0x101019(0x3cc)][_0x495e21['directorUUID']][_0x101019(0x502)][_0x101019(0x191)]['director']=!![]));}else _0x495e21[_0x101019(0x389)]=![];'claim'in _0x267192&&(_0x267192['claim']==![]&&(!_0x495e21['cleanOutput']&&(setTimeout(function(){var _0xc95ec5=_0x101019;if(_0xc95ec5(0x98)==='VAfuw'){function _0x3a24b5(){var _0xb84e55=_0xc95ec5;if(_0x4a05ac[_0xb84e55(0x15b)]){var _0x5d8466={};_0x5d8466[_0xb84e55(0x15b)]=_0x37dd73['iframeSrc'],_0x4d40d3[_0xb84e55(0x3bd)](_0x5d8466,_0x4500b5);}}}else warnUser(_0xc95ec5(0x260));},0x1),getById(_0x101019(0x20a))[_0x101019(0x4ad)]=_0x101019(0x1fe)))),_0x495e21[_0x101019(0x39a)][_0x101019(0x3d7)](_0x267192[_0x101019(0x36e)]);}else{if(_0x267192['request']==_0x101019(0x31b)){_0x495e21['queueList']=[],_0x495e21[_0x101019(0x31b)]=!![],_0x495e21[_0x101019(0x4f2)]=![],log(_0x101019(0x485));!_0x495e21[_0x101019(0x455)]&&(_0x495e21[_0x101019(0x3f4)]=![]);log(_0x267192[_0x101019(0x36e)]);_0x101019(0x455)in _0x267192?(_0x495e21[_0x101019(0x389)]=_0x267192[_0x101019(0x455)],_0x495e21['directorUUID']in _0x495e21[_0x101019(0x3fd)]&&(_0x495e21[_0x101019(0x3fd)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)]&&(_0x495e21['pcs'][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)]['info'][_0x101019(0x455)]=!![])),_0x495e21[_0x101019(0x389)]in _0x495e21[_0x101019(0x3cc)]&&(_0x495e21[_0x101019(0x3cc)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)]&&(_0x495e21[_0x101019(0x3cc)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)][_0x101019(0x455)]=!![]))):_0x495e21[_0x101019(0x389)]=![];for(_0x279c88 in _0x495e21[_0x101019(0x3cc)]){try{_0x495e21[_0x101019(0x3cc)][_0x279c88][_0x101019(0x229)](),delete _0x495e21[_0x101019(0x3cc)][_0x279c88];}catch(_0xeaf22b){}}for(_0x279c88 in _0x495e21[_0x101019(0x3fd)]){try{if(_0x101019(0x3c7)!==_0x101019(0x453))_0x495e21[_0x101019(0x3fd)][_0x279c88][_0x101019(0x229)](),delete _0x495e21[_0x101019(0x3fd)][_0x279c88],applySceneState();else{function _0x1e091c(){var _0xb33903=_0x101019;_0x40495a[_0xb33903(0x3cc)][_0x2daac4][_0xb33903(0x481)]['style'][_0xb33903(0x443)]=_0xb33903(0x51d);}}}catch(_0x573b0a){}}getChatMessage('You\x27ve\x20been\x20transferred\x20to\x20a\x20different\x20room',label=![],director=![],overlay=!![]),getById(_0x101019(0x1d3))[_0x101019(0x4ad)]=_0x101019(0x17b);_0x495e21[_0x101019(0xab)]?document[_0x101019(0x3fb)]=_0x495e21[_0x101019(0xab)]+_0x101019(0x2f8):document[_0x101019(0x3fb)]='Transferred';_0x495e21[_0x101019(0x128)]=_0x495e21['totalRoomBitrate_default'],updateMixer(),updateUserList(),log(_0x101019(0x4e6)),log(_0x267192[_0x101019(0x36e)]);for(var _0x279c88 in _0x267192[_0x101019(0x36e)]){if(_0x101019(0x12e)in _0x267192[_0x101019(0x36e)][_0x279c88]){if(_0x101019(0x23e)in _0x267192[_0x101019(0x36e)][_0x279c88]){if(_0x267192[_0x101019(0x36e)][_0x279c88][_0x101019(0x12e)]in _0x495e21[_0x101019(0x3cc)])log('RTC\x20already\x20connected');else{var _0x224ffe=_0x495e21[_0x101019(0x14b)](_0x267192[_0x101019(0x36e)][_0x279c88][_0x101019(0x23e)]);log(_0x101019(0x2e6)+_0x224ffe);if(_0x495e21[_0x101019(0x3f4)]){if(_0x495e21[_0x101019(0x389)]===_0x267192[_0x101019(0x36e)][_0x279c88][_0x101019(0x12e)])play(_0x224ffe);else _0x495e21[_0x101019(0x4d7)][_0x101019(0xaf)]<0x1388&&(!_0x495e21[_0x101019(0x4d7)][_0x101019(0x4a0)](_0x224ffe)&&_0x495e21[_0x101019(0x4d7)][_0x101019(0x17e)](_0x224ffe));}else play(_0x224ffe);}}}}_0x495e21[_0x101019(0x298)]();}else{if(_0x267192[_0x101019(0x317)]==_0x101019(0x274))log(_0x267192),_0x101019(0x455)in _0x267192?(_0x495e21[_0x101019(0x389)]=_0x267192[_0x101019(0x455)],_0x495e21[_0x101019(0x389)]in _0x495e21[_0x101019(0x3fd)]&&(_0x495e21[_0x101019(0x3fd)][_0x495e21[_0x101019(0x389)]]['stats'][_0x101019(0x191)]&&(_0x495e21[_0x101019(0x3fd)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)][_0x101019(0x455)]=!![])),_0x495e21[_0x101019(0x389)]in _0x495e21[_0x101019(0x3cc)]&&(_0x495e21[_0x101019(0x3cc)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)]['info']&&(_0x495e21['rpcs'][_0x495e21['directorUUID']][_0x101019(0x502)][_0x101019(0x191)][_0x101019(0x455)]=!![]))):(_0x495e21[_0x101019(0x389)]=![],errorlog(_0x101019(0x448))),updateUserList();else{if(_0x267192[_0x101019(0x317)]==_0x101019(0x2f0)){log(_0x101019(0x3c8)),log(_0x267192);try{if('director'in _0x267192){if(_0x267192[_0x101019(0x455)]==!![]){if(_0x101019(0x43c)!=='MVvim')_0x495e21['directorActions'](_0x267192);else{function _0x5627b0(){var _0x17ddb8=_0x101019;_0x3e3ffc=_0x4f150b[_0x17ddb8(0xd6)];}}}}}catch(_0x1e3183){errorlog(_0x1e3183);}}else{if(_0x267192['request']==_0x101019(0x4b1)){if(_0x267192[_0x101019(0x455)]){_0x495e21[_0x101019(0x389)]=_0x267192[_0x101019(0x12e)];_0x495e21[_0x101019(0x389)]in _0x495e21[_0x101019(0x3fd)]&&(_0x495e21['pcs'][_0x495e21['directorUUID']]['stats'][_0x101019(0x191)]&&(_0x495e21['pcs'][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)]['director']=!![]));if(_0x495e21[_0x101019(0x389)]in _0x495e21[_0x101019(0x3cc)]){if(_0x495e21[_0x101019(0x3cc)][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)][_0x101019(0x191)]){if(_0x101019(0x4d8)==='TAmCu')_0x495e21['rpcs'][_0x495e21[_0x101019(0x389)]][_0x101019(0x502)]['info'][_0x101019(0x455)]=!![];else{function _0x4fb3b5(){var _0x197729=_0x101019;_0x55a7cc[_0x197729(0x3fd)][_0x301a1b][_0x197729(0x48c)][_0x197729(0x506)](_0x13b4f3[_0x197729(0x1e9)](_0x463581)),_0x2f5bd5[_0x197729(0x17e)](_0x50502a);}}}}updateUserList();}if(_0x101019(0x23e)in _0x267192){log(_0x101019(0x51e));if(_0x495e21[_0x101019(0x3f4)]){if(_0x495e21['directorUUID']===_0x267192[_0x101019(0x12e)])play(_0x224ffe);else _0x495e21[_0x101019(0x4d7)][_0x101019(0xaf)]<0x1388&&(!_0x495e21['queueList'][_0x101019(0x4a0)](_0x267192['streamID'])&&(_0x495e21[_0x101019(0x4d7)][_0x101019(0x17e)](_0x267192[_0x101019(0x23e)]),_0x495e21[_0x101019(0x298)]()));}else play(_0x267192[_0x101019(0x23e)]);}else log(_0x101019(0xc3));}else{if(_0x267192['request']=='videoaddedtoroom'){log(_0x101019(0x36c)),log(_0x267192);if(_0x495e21[_0x101019(0x3f4)]){if(_0x495e21[_0x101019(0x389)]===_0x267192[_0x101019(0x12e)]){if(_0x101019(0x2fa)===_0x101019(0x184)){function _0x132224(){var _0x5800c4=_0x101019;_0xf70967[_0x5800c4(0x337)]&&(_0x275321[_0x5800c4(0x389)]=_0x492c89[_0x5800c4(0x337)]),delete _0x5cdc31[_0x5800c4(0x455)];}}else play(_0x224ffe);}else _0x495e21[_0x101019(0x4d7)]['length']<0x1388&&(!_0x495e21[_0x101019(0x4d7)]['includes'](_0x267192[_0x101019(0x23e)])&&(_0x495e21['queueList']['push'](_0x267192['streamID']),_0x495e21['updateQueue']()));}else play(_0x267192[_0x101019(0x23e)]);}else{if(_0x267192[_0x101019(0x317)]==_0x101019(0xed)){errorlog(_0x267192);if(_0x495e21[_0x101019(0x44c)]===![]){if('message'in _0x267192){if(_0x267192[_0x101019(0x47f)]===_0x101019(0x4ba)){if(_0x101019(0x331)!=='coOXd')_0x495e21[_0x101019(0x40d)]<0x2?(_0x495e21[_0x101019(0x40d)]=parseInt(_0x495e21[_0x101019(0x40d)])+0x1,setTimeout(function(){var _0x3ede3c=_0x101019;_0x495e21[_0x3ede3c(0x35e)]();},0x1388)):(hangup(),!_0x495e21[_0x101019(0xe9)]&&setTimeout(function(){var _0x338c00=_0x101019;warnUser(_0x338c00(0x1ce));},0x1));else{function _0x577f9e(){var _0x23c691=_0x101019;_0x58bb7a(_0x406b73[_0x23c691(0x23e)]);return;}}}else _0x267192[_0x101019(0x47f)]==='Room\x20is\x20already\x20claimed\x20by\x20someone\x20else.'?!_0x495e21[_0x101019(0xe9)]&&(setTimeout(function(){var _0x1874e5=_0x101019;warnUser(_0x1874e5(0x260));},0x1),getById('head4')[_0x101019(0x4ad)]='You\x20are\x20not\x20the\x20director\x20of\x20this\x20room.\x20\x20You\x20will\x20have\x20limited\x20to\x20no\x20control.\x20\x20You\x20can\x20try\x20claiming\x20the\x20room\x20after\x20the\x20first\x20director\x20leaves.
'):!_0x495e21[_0x101019(0xe9)]&&setTimeout(function(){warnUser(_0x267192['message']);},0x1);}}}else{if(_0x267192[_0x101019(0x317)]==_0x101019(0x3e6))'message'in _0x267192&&warnlog(_0x267192['message']);else{if(_0x101019(0x2df)!==_0x101019(0x2df)){function _0x42e167(){_0xda5a64['infocus']=!![];}}else log(_0x267192);}}}}}}}}}}else{if(_0x267192[_0x101019(0x33d)])_0x101019(0x23e)in _0x267192&&(_0x267192[_0x101019(0x23e)]in _0x495e21['watchTimeoutList']&&(clearTimeout(_0x495e21[_0x101019(0x27d)][_0x267192[_0x101019(0x23e)]]),delete _0x495e21[_0x101019(0x27d)][_0x267192[_0x101019(0x23e)]])),_0x495e21[_0x101019(0x2ae)](_0x267192);else{if(_0x267192[_0x101019(0xf0)])log(_0x101019(0x3e1)),_0x495e21[_0x101019(0x28b)](_0x267192);else{if(_0x267192[_0x101019(0x117)])log('GOT\x20ICES!!'),_0x495e21['processIceBundle'](_0x267192);else _0x267192[_0x101019(0x317)]==_0x101019(0x507)?(warnlog(_0x101019(0x330)),_0x267192[_0x101019(0x12e)]in _0x495e21[_0x101019(0x3fd)]&&(warnlog(_0x101019(0x92)),_0x495e21['pcs'][_0x267192['UUID']][_0x101019(0x229)](),delete _0x495e21[_0x101019(0x3fd)][_0x267192[_0x101019(0x12e)]],_0x495e21[_0x101019(0x386)](),applySceneState()),_0x267192[_0x101019(0x12e)]in _0x495e21[_0x101019(0x3cc)]&&(warnlog(_0x101019(0x92)),_0x495e21[_0x101019(0x3cc)][_0x267192[_0x101019(0x12e)]]['close'](),delete _0x495e21[_0x101019(0x3cc)][_0x267192[_0x101019(0x12e)]])):log(_0x101019(0x464),_0x267192);}}}},_0x495e21['ws'][_0x507f10(0x2c8)]=function(_0x16af14){var _0x4ea0d7=_0x507f10;clearTimeout(_0x495e21[_0x4ea0d7(0x371)]),pokeIframeAPI('hssConnection',_0x4ea0d7(0x4ee));try{'code'in _0x16af14&&(_0x16af14[_0x4ea0d7(0x1b9)]==0x1f7&&(_0x595627==![]&&(clearInterval(_0x495e21['timeout']),!_0x495e21[_0x4ea0d7(0xe9)]&&warnUser(_0x4ea0d7(0x2a9),0x7530))));}catch(_0x5186c9){if(_0x4ea0d7(0x281)!==_0x4ea0d7(0x4c3))errorlog(_0x5186c9);else{function _0x522a13(){var _0x45bd4c=_0x4ea0d7;_0x50b0bd[_0x45bd4c(0x389)]=![];}}}errorlog(_0x4ea0d7(0x1f4));if(_0x495e21[_0x4ea0d7(0xdd)]==![])try{_0x495e21['ws'][_0x4ea0d7(0x454)]===WebSocket[_0x4ea0d7(0x1be)]&&(_0x495e21['ws']=null,setTimeout(()=>{_0x495e21['connect'](!![]);},0x1388));}catch(_0x3450a1){errorlog(_0x3450a1);}};},_0x495e21[_0x2a0a0d(0x3bd)]=function(_0x9e9e15,_0x2ea9c5=null){var _0x25d7c5=_0x2a0a0d;_0x9e9e15=JSON[_0x25d7c5(0x1e9)](_0x9e9e15);if(_0x2ea9c5==null){for(var _0x20a542 in _0x495e21[_0x25d7c5(0x3fd)]){try{_0x495e21[_0x25d7c5(0x3fd)][_0x20a542][_0x25d7c5(0x48c)][_0x25d7c5(0x506)](_0x9e9e15);}catch(_0x22c768){warnlog(_0x25d7c5(0xd4));}}return!![];}else try{return _0x495e21['pcs'][_0x2ea9c5][_0x25d7c5(0x48c)][_0x25d7c5(0x506)](_0x9e9e15),!![];}catch(_0x5d2254){return warnlog(_0x25d7c5(0x134)),![];}return![];},_0x495e21[_0x2a0a0d(0x166)]=function(_0x15074d,_0x41609c=null){var _0x2862c7=_0x2a0a0d,_0x3e9192=JSON[_0x2862c7(0x1e9)](_0x15074d);if(_0x41609c==null)for(var _0x13cd76 in _0x495e21[_0x2862c7(0x3cc)]){try{_0x495e21['rpcs'][_0x13cd76]['receiveChannel']['send'](_0x3e9192);}catch(_0x1b614d){log(_0x2862c7(0x31a));}}else try{return _0x495e21[_0x2862c7(0x3cc)][_0x41609c]['receiveChannel']['send'](_0x3e9192),!![];}catch(_0x83b08b){return log(_0x2862c7(0x31a)),![];}},_0x495e21[_0x2a0a0d(0xc5)]=function(){setTimeout(function(){var _0x5e2da6=_0x56d9;_0x495e21[_0x5e2da6(0xc5)];},0xbb8);},_0x495e21[_0x2a0a0d(0x4e0)]=function(_0xa25bb8){var _0x54fe1b=_0x2a0a0d;if(_0x54fe1b(0x3b0)!==_0x54fe1b(0x3b0)){function _0x35f1bd(){_0x25696f('RTC\x20already\x20connected');}}else try{var _0x2561fe=_0x495e21[_0x54fe1b(0x302)][_0x54fe1b(0x3d1)]();_0x2561fe=_0x2561fe[0x0];if(_0x2561fe[_0x54fe1b(0x318)]){var _0x1ccf89=_0x2561fe[_0x54fe1b(0x318)]();_0x495e21[_0x54fe1b(0x467)]==![]&&(_0x495e21[_0x54fe1b(0x467)]=_0x1ccf89[_0x54fe1b(0x467)][_0x54fe1b(0x462)]);_0x495e21[_0x54fe1b(0x467)]+=_0xa25bb8;if(_0x495e21[_0x54fe1b(0x467)]>_0x1ccf89[_0x54fe1b(0x467)][_0x54fe1b(0x42d)])_0x495e21['zoom']=_0x1ccf89['zoom'][_0x54fe1b(0x42d)];else _0x495e21[_0x54fe1b(0x467)]<_0x1ccf89[_0x54fe1b(0x467)][_0x54fe1b(0x462)]&&(_0x495e21[_0x54fe1b(0x467)]=_0x1ccf89[_0x54fe1b(0x467)]['min']);_0x2561fe[_0x54fe1b(0x4b3)]({'advanced':[{'zoom':_0x495e21['zoom']}]});}}catch(_0x19c7a5){errorlog(_0x19c7a5);}},_0x495e21[_0x2a0a0d(0x219)]=function(){var _0x14a67f=_0x2a0a0d;_0x495e21[_0x14a67f(0x4e7)]=!![],warnlog(_0x14a67f(0x17c));try{var _0x213c69={};_0x213c69['videoMuted']=!![],_0x495e21[_0x14a67f(0x3bd)](_0x213c69);}catch(_0x25c688){}try{if(_0x14a67f(0x131)!==_0x14a67f(0x131)){function _0x18c7ab(){var _0x4ca813=_0x14a67f;_0x28c104(_0x4ca813(0x103))[_0x4ca813(0x3b8)][_0x4ca813(0x443)]=_0x4ca813(0x51d),!_0x4a5e4f[_0x4ca813(0xe9)]&&_0x2335f6(_0x4ca813(0x421));}}else _0x495e21['ws'][_0x14a67f(0x229)]();}catch(_0x3a8f32){}try{recordLocalVideo(_0x14a67f(0x2de));}catch(_0x5381af){}try{if(_0x14a67f(0x437)!==_0x14a67f(0x437)){function _0x55933a(){var _0x3e6190=_0x14a67f;_0xd8678c=0x23,_0x2e981b[_0x3e6190(0x3fd)][_0x4ae24e]['bitrateTimeout']=_0x2b844f(function(_0x1700c4){var _0x25c71d=_0x3e6190;_0x25f953[_0x25c71d(0x2cb)](_0x1700c4,null);},_0x81f581,_0x2d74e6);}}else{_0x495e21['canvasSource']&&_0x495e21[_0x14a67f(0x24b)][_0x14a67f(0x1e8)][_0x14a67f(0x509)]()[_0x14a67f(0x415)](function(_0x3c38d2){var _0x1dfade=_0x14a67f;_0x3c38d2[_0x1dfade(0x2de)](),_0x495e21['videoElement'][_0x1dfade(0x1e8)]['removeTrack'](_0x3c38d2),log(_0x1dfade(0x28f));});_0x495e21[_0x14a67f(0x2f6)][_0x14a67f(0x1e8)][_0x14a67f(0x509)]()[_0x14a67f(0x415)](function(_0x29c7fa){var _0x2b913c=_0x14a67f;_0x29c7fa['stop'](),_0x495e21[_0x2b913c(0x2f6)][_0x2b913c(0x1e8)][_0x2b913c(0x379)](_0x29c7fa),log(_0x2b913c(0x28f));}),_0x495e21[_0x14a67f(0x302)][_0x14a67f(0x509)]()['forEach'](function(_0x197304){var _0x4603a5=_0x14a67f;_0x197304[_0x4603a5(0x2de)](),_0x495e21[_0x4603a5(0x2f6)][_0x4603a5(0x1e8)]['removeTrack'](_0x197304),log(_0x4603a5(0x28f));});for(i in _0x495e21['rpcs']){if(_0x495e21[_0x14a67f(0x3cc)][i][_0x14a67f(0x2f6)]){if(_0x14a67f(0x12d)===_0x14a67f(0x29f)){function _0x2b0c6f(){_0x3cded1(_0x49c54a);}}else _0x495e21[_0x14a67f(0x3cc)][i][_0x14a67f(0x2f6)][_0x14a67f(0x256)]&&(_0x495e21[_0x14a67f(0x3cc)][i][_0x14a67f(0x2f6)][_0x14a67f(0x158)][_0x14a67f(0x12b)][_0x14a67f(0x229)](),_0x495e21[_0x14a67f(0x3cc)][i][_0x14a67f(0x2f6)][_0x14a67f(0x256)]=![]);}_0x495e21[_0x14a67f(0x3cc)][i][_0x14a67f(0x229)](),_0x495e21[_0x14a67f(0x3cc)][i]=null,delete _0x495e21[_0x14a67f(0x3cc)][i];}for(i in _0x495e21['pcs']){_0x495e21['pcs'][i][_0x14a67f(0x229)](),_0x495e21[_0x14a67f(0x3fd)][i]=null,delete _0x495e21[_0x14a67f(0x3fd)][i],applySceneState();}}}catch(_0x49ab91){errorlog(_0x14a67f(0x4e5));}setTimeout(function(){for(i in _0x495e21){try{delete _0x495e21[i];}catch(_0x5c4690){}}delete _0x495e21;},0x4b0),hangupComplete(),log(_0x14a67f(0x4f0));},_0x495e21[_0x2a0a0d(0x110)]=function(){var _0x43b99c=_0x2a0a0d;_0x495e21['taintedSession']=!![],_0x495e21['screenShareState']=![],warnlog(_0x43b99c(0x17c));try{_0x495e21['videoElement'][_0x43b99c(0x1e8)][_0x43b99c(0x509)]()[_0x43b99c(0x415)](function(_0x315911){var _0xd76bb5=_0x43b99c;_0x315911['stop'](),_0x495e21['videoElement'][_0xd76bb5(0x1e8)][_0xd76bb5(0x379)](_0x315911),log(_0xd76bb5(0x28f));}),_0x495e21[_0x43b99c(0x302)]['getTracks']()[_0x43b99c(0x415)](function(_0x52b1a1){var _0x1f024f=_0x43b99c;_0x52b1a1['stop'](),_0x495e21[_0x1f024f(0x302)][_0x1f024f(0x379)](_0x52b1a1),log(_0x1f024f(0x28f));});for(UUID in _0x495e21[_0x43b99c(0x3fd)]){var _0x4095cf=_0x495e21['pcs'][UUID][_0x43b99c(0x16e)]();_0x4095cf[_0x43b99c(0x415)](_0x1709d5=>{var _0x26a2cb=_0x43b99c;_0x1709d5['track']&&(_0x1709d5[_0x26a2cb(0x476)][_0x26a2cb(0x500)]=![]);});}var _0x6e5cb1={};_0x6e5cb1[_0x43b99c(0x2b2)]=!![],_0x495e21[_0x43b99c(0x3bd)](_0x6e5cb1);}catch(_0x3f4671){errorlog('failed\x20to\x20disconnect');}log(_0x43b99c(0x195));},_0x495e21['remoteFocus']=function(_0x2bcf0e){var _0x16e356=_0x2a0a0d;try{var _0x1116ca=_0x495e21['streamSrc'][_0x16e356(0x3d1)]();_0x1116ca=_0x1116ca[0x0];if(_0x1116ca['getCapabilities']){var _0x36feee=_0x1116ca[_0x16e356(0x318)]();_0x495e21['focusDistance']==![]&&(_0x495e21['focusDistance']=_0x36feee['focusDistance']['min']);_0x495e21[_0x16e356(0x156)]+=_0x2bcf0e;if(_0x495e21[_0x16e356(0x156)]>_0x36feee[_0x16e356(0x156)]['max'])_0x495e21['focusDistance']=_0x36feee[_0x16e356(0x156)][_0x16e356(0x42d)];else _0x495e21[_0x16e356(0x156)]<_0x36feee[_0x16e356(0x156)][_0x16e356(0x462)]&&(_0x495e21[_0x16e356(0x156)]=_0x36feee[_0x16e356(0x156)][_0x16e356(0x462)]);_0x1116ca[_0x16e356(0x4b3)]({'advanced':[{'focusMode':_0x16e356(0x2f5),'focusDistance':_0x495e21[_0x16e356(0x156)]}]});}}catch(_0x22c906){errorlog(_0x22c906);}},_0x495e21[_0x2a0a0d(0x25d)]=function(_0x5a4e43){var _0x3bd74c=_0x2a0a0d;_0x495e21[_0x3bd74c(0x3fd)][_0x5a4e43][_0x3bd74c(0x25d)]()[_0x3bd74c(0x34d)](_0xc7c934=>{var _0x3504c4=_0x3bd74c;log(_0x3504c4(0x3b4));if(safariVersion()<=0xd&&(iOS||iPad)){}else{if(_0x495e21[_0x3504c4(0x3a1)]==0x3||_0x495e21[_0x3504c4(0x3a1)]==0x5||_0x495e21[_0x3504c4(0x3a1)]==0x1)_0xc7c934[_0x3504c4(0x496)]=CodecsHandler[_0x3504c4(0x186)](_0xc7c934[_0x3504c4(0x496)],{'stereo':0x1}),log(_0x3504c4(0x12c));else{if(iOS||iPad){}else _0x495e21['stereo']==0x4&&(_0xc7c934['sdp']=CodecsHandler[_0x3504c4(0x186)](_0xc7c934[_0x3504c4(0x496)],{'stereo':0x2}),log('stereo\x20enabled'));}}_0x495e21['pcs'][_0x5a4e43][_0x3504c4(0x11e)](_0xc7c934)[_0x3504c4(0x34d)](function(){var _0x443564=_0x3504c4;log('publishing\x20SDP\x20Offer:\x20'+_0x5a4e43);var _0x34097f={};_0x34097f[_0x443564(0x12e)]=_0x5a4e43,_0x34097f[_0x443564(0x23e)]=_0x495e21[_0x443564(0x23e)],_0x34097f[_0x443564(0x33d)]=_0x495e21[_0x443564(0x3fd)][_0x5a4e43][_0x443564(0x144)],_0x34097f[_0x443564(0x518)]=_0x495e21[_0x443564(0x3fd)][_0x5a4e43]['session'],_0x495e21[_0x443564(0x211)]?_0x495e21[_0x443564(0xb3)](JSON[_0x443564(0x1e9)](_0x34097f['description']))[_0x443564(0x34d)](function(_0xf800c2){var _0x4a7032=_0x443564;_0x34097f['description']=_0xf800c2[0x0],_0x34097f[_0x4a7032(0x48b)]=_0xf800c2[0x1],_0x495e21[_0x4a7032(0x143)](_0x34097f);}):_0x495e21['anysend'](_0x34097f);})[_0x3504c4(0x236)](errorlog);})[_0x3bd74c(0x236)](errorlog);},_0x495e21[_0x2a0a0d(0x241)]=function(){var _0xc3af65=_0x2a0a0d;for(var _0x233ef1 in _0x495e21[_0xc3af65(0x3fd)]){_0x495e21[_0xc3af65(0x3fd)][_0x233ef1]['scene']!==![]?(_0x495e21[_0xc3af65(0x3df)](_0x233ef1),log(_0xc3af65(0x1ab))):log(_0xc3af65(0x436));}},_0x495e21[_0x2a0a0d(0x38f)]=function(_0x28afe0){var _0x17abb6=_0x2a0a0d;if(_0x28afe0 in _0x495e21[_0x17abb6(0x3fd)]){errorlog(_0x17abb6(0x396));try{_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x229)]();}catch(_0x292057){errorlog(_0x17abb6(0x508));}_0x495e21[_0x17abb6(0x3fd)][_0x28afe0]=null,delete _0x495e21[_0x17abb6(0x3fd)][_0x28afe0],_0x495e21[_0x17abb6(0x386)](),applySceneState();}else{if(_0x17abb6(0x231)===_0x17abb6(0x231))log(_0x17abb6(0xc0));else{function _0x30a555(){var _0x3e5894=_0x17abb6;!_0x196520[_0x3e5894(0x4d7)][_0x3e5894(0x4a0)](_0x392fdd)&&_0x816fc4['queueList'][_0x3e5894(0x17e)](_0x5e459c);}}}if(_0x495e21[_0x17abb6(0xa5)]!==![]){if(Object[_0x17abb6(0x31f)](_0x495e21[_0x17abb6(0x3fd)])[_0x17abb6(0xaf)]>_0x495e21[_0x17abb6(0xa5)]){if('bTzOe'===_0x17abb6(0x37a)){function _0x3647bb(){var _0x1c47c1=_0x17abb6;_0x1b7074[_0x1c47c1(0x3cc)][_0x28ab1d][_0x1c47c1(0x2f6)][_0x1c47c1(0x388)]&&(_0x1390b3('trying\x20to\x20play'),_0x4b9209[_0x1c47c1(0x3cc)][_0x51687c][_0x1c47c1(0x2f6)][_0x1c47c1(0x4c7)]()[_0x1c47c1(0x34d)](_0x5c87ba=>{var _0x53aeb7=_0x1c47c1;_0x3d3baf(_0x53aeb7(0x2c3)),_0x2b7a30=!![];})['catch'](_0x463c3b));}}else{delete _0x495e21[_0x17abb6(0x3fd)][_0x28afe0],_0x495e21[_0x17abb6(0x386)](),warnlog(_0x17abb6(0x47e)),applySceneState();return;}}}else{if(_0x495e21[_0x17abb6(0x333)]!==![]){if(Object[_0x17abb6(0x31f)](_0x495e21[_0x17abb6(0x3cc)])[_0x17abb6(0xaf)]+Object[_0x17abb6(0x31f)](_0x495e21[_0x17abb6(0x3fd)])[_0x17abb6(0xaf)]>_0x495e21[_0x17abb6(0x333)]){delete _0x495e21[_0x17abb6(0x3fd)][_0x28afe0],_0x495e21[_0x17abb6(0x386)](),warnlog('Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit'),applySceneState();return;}}}_0x495e21[_0x17abb6(0x3fd)][_0x28afe0]=new RTCPeerConnection(_0x495e21[_0x17abb6(0x401)]);if(_0x495e21[_0x17abb6(0xdd)]){if(Object['keys'](_0x495e21['pcs'])[_0x17abb6(0xaf)]>0x1){delete _0x495e21[_0x17abb6(0x3fd)][_0x28afe0],_0x495e21[_0x17abb6(0x386)](),applySceneState();return;}}_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x167)]=null,_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x1df)]=null,_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x3be)]=null,_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x35a)]=null,_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x3f3)]=null,_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x1af)]=null,_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0xdc)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0]['savedBitrate']=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x3ec)]=null,_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x263)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x518)]=_0x495e21['generateStreamID'](),_0x495e21[_0x17abb6(0x3fd)][_0x28afe0]['stats']={},_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x438)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x397)]=![],_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x35c)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x3d5)]=![],_0x495e21['pcs'][_0x28afe0][_0x17abb6(0xbc)]=!![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0]['allowAudio']=!![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x505)]=!![],_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x494)]=![],_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x41a)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x12e)]=_0x28afe0,_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x232)]=![],_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x425)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x33e)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x1f8)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x1ec)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x44c)]=![],_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x48c)]=_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x49d)]('sendChannel'),_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x48c)]['UUID']=_0x28afe0,_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x233)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x4a4)]=null,_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0xab)]=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0]['order']=![],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x1c4)]=Date[_0x17abb6(0x42f)](),_0x495e21[_0x17abb6(0x3fd)][_0x28afe0]['sendChannel'][_0x17abb6(0x13c)]=()=>{var _0x1990d1=_0x17abb6;log(_0x1990d1(0x140)),msg={},msg[_0x1990d1(0x191)]={},msg[_0x1990d1(0x191)][_0x1990d1(0xab)]=_0x495e21[_0x1990d1(0xab)],msg[_0x1990d1(0x191)][_0x1990d1(0x40a)]=_0x495e21[_0x1990d1(0x40a)],msg['info'][_0x1990d1(0x3dd)]=_0x495e21[_0x1990d1(0x3dd)];_0x495e21['soloChatUUID']&&_0x495e21[_0x1990d1(0xe4)]!==_0x28afe0&&(msg['info'][_0x1990d1(0x3dd)]=!![]);msg['info'][_0x1990d1(0x377)]=_0x495e21[_0x1990d1(0x377)],msg['info']['directorDisplayMuted']=_0x495e21[_0x1990d1(0x1bb)],msg['info']['directorVideoMuted']=_0x495e21[_0x1990d1(0x367)],msg[_0x1990d1(0x191)][_0x1990d1(0x258)]=_0x495e21[_0x1990d1(0x2b2)];_0x495e21['director']&&(msg[_0x1990d1(0x1b3)]={},msg['directorSettings'][_0x1990d1(0x128)]=_0x495e21[_0x1990d1(0x128)]);msg[_0x1990d1(0x191)][_0x1990d1(0x1e0)]=_0x495e21[_0x1990d1(0x38a)],msg[_0x1990d1(0x191)][_0x1990d1(0x515)]=_0x495e21[_0x1990d1(0x306)],msg['info'][_0x1990d1(0x370)]=_0x495e21[_0x1990d1(0x465)],msg[_0x1990d1(0x191)][_0x1990d1(0x372)]=_0x495e21['maxvideobitrate'],msg[_0x1990d1(0x191)]['maxviewers_url']=_0x495e21[_0x1990d1(0xa5)],msg[_0x1990d1(0x191)][_0x1990d1(0xc9)]=_0x495e21[_0x1990d1(0x3a1)],msg[_0x1990d1(0x191)][_0x1990d1(0xac)]=_0x495e21['echoCancellation'],msg[_0x1990d1(0x191)]['agc_url']=_0x495e21[_0x1990d1(0x50b)],msg['info'][_0x1990d1(0x1aa)]=_0x495e21[_0x1990d1(0x4e8)],msg[_0x1990d1(0x191)][_0x1990d1(0x105)]=_0x495e21[_0x1990d1(0x105)],msg[_0x1990d1(0x191)][_0x1990d1(0x1b2)]=_0x495e21[_0x1990d1(0x4c8)],msg[_0x1990d1(0x191)][_0x1990d1(0x292)]=_0x495e21[_0x1990d1(0x270)],msg[_0x1990d1(0x191)][_0x1990d1(0xe7)]=_0x495e21['audioLatency'],msg[_0x1990d1(0x191)]['recording_audio_pipeline']=!_0x495e21[_0x1990d1(0x16a)],msg[_0x1990d1(0x191)][_0x1990d1(0x22c)]=_0x495e21['audioEffects'],msg[_0x1990d1(0x191)][_0x1990d1(0xa2)]=_0x495e21[_0x1990d1(0x3a6)],msg[_0x1990d1(0x191)][_0x1990d1(0xa9)]=_0x495e21[_0x1990d1(0x21b)];try{if(navigator[_0x1990d1(0x119)]){var _0x214e0c,_0x38904d=navigator['userAgent'];msg[_0x1990d1(0x191)][_0x1990d1(0xec)]=_0x38904d;}navigator[_0x1990d1(0x2e7)]&&(msg[_0x1990d1(0x191)][_0x1990d1(0x2e7)]=navigator[_0x1990d1(0x2e7)]);if(safariVersion())msg[_0x1990d1(0x191)][_0x1990d1(0x170)]=_0x1990d1(0x310);else{if(getChromeVersion()>0x3c)msg[_0x1990d1(0x191)][_0x1990d1(0x170)]='Chromium-based\x20v'+getChromeVersion();else _0x38904d[_0x1990d1(0x37b)](_0x1990d1(0x4ea))&&(msg[_0x1990d1(0x191)]['Browser']=_0x1990d1(0x4ea));}}catch(_0x56dc1d){};_0x495e21['sendMessage'](msg,_0x28afe0),pokeIframeAPI(_0x1990d1(0x4cb),!![],_0x28afe0),updateUserList();},_0x495e21['pcs'][_0x28afe0]['sendChannel'][_0x17abb6(0x2c8)]=()=>{var _0x16ac9d=_0x17abb6;pokeIframeAPI('new-push-connection',![],_0x28afe0),_0x495e21[_0x16ac9d(0x3ed)](),warnlog(_0x16ac9d(0xa6));try{_0x495e21[_0x16ac9d(0x3fd)][_0x28afe0][_0x16ac9d(0x229)](),_0x495e21[_0x16ac9d(0x3fd)][_0x28afe0]=null,delete _0x495e21[_0x16ac9d(0x3fd)][_0x28afe0],applySceneState();}catch(_0x1a8574){}},_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x48c)][_0x17abb6(0x16d)]=_0x42b3c9=>{var _0x4981ec=_0x17abb6;log(_0x4981ec(0x38c));var _0x24cccd=JSON[_0x4981ec(0x2b5)](_0x42b3c9[_0x4981ec(0x488)]);_0x24cccd['UUID']=_0x28afe0;if(_0x24cccd[_0x4981ec(0x33d)]){_0x495e21[_0x4981ec(0x2ae)](_0x24cccd);return;}else{if(_0x24cccd[_0x4981ec(0xf0)]){log(_0x4981ec(0x3e1)),_0x495e21[_0x4981ec(0x28b)](_0x24cccd);return;}else{if(_0x24cccd[_0x4981ec(0x117)]){log('GOT\x20ICEs!!'),_0x495e21[_0x4981ec(0x248)](_0x24cccd);return;}}}warnlog(_0x24cccd);if(_0x4981ec(0x191)in _0x24cccd){_0x495e21[_0x4981ec(0x3fd)][_0x28afe0]['stats'][_0x4981ec(0x191)]=_0x24cccd[_0x4981ec(0x191)];_0x4981ec(0xab)in _0x24cccd[_0x4981ec(0x191)]&&(typeof _0x24cccd[_0x4981ec(0x191)][_0x4981ec(0xab)]==_0x4981ec(0x1c6)?_0x495e21['pcs'][_0x28afe0][_0x4981ec(0xab)]=sanitizeLabel(_0x24cccd[_0x4981ec(0x191)][_0x4981ec(0xab)]):_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0xab)]=![]);if(_0x28afe0===_0x495e21[_0x4981ec(0x389)])try{_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x502)][_0x4981ec(0x191)][_0x4981ec(0x455)]=!![];}catch(_0x45b329){}}_0x4981ec(0xdc)in _0x24cccd&&(_0x495e21['pcs'][_0x28afe0][_0x4981ec(0xdc)]=parseInt(_0x24cccd['optimizedBitrate']));_0x4981ec(0x316)in _0x24cccd&&_0x495e21[_0x4981ec(0x3bb)](_0x28afe0,_0x24cccd[_0x4981ec(0x316)]);if(_0x4981ec(0x139)in _0x24cccd){log(_0x24cccd);if(_0x495e21[_0x4981ec(0x389)]===_0x28afe0){var _0x4e2171={};for(var _0x3451e8 in _0x495e21['pcs']){if(_0x3451e8===_0x28afe0)continue;_0x4e2171[_0x3451e8]=_0x495e21[_0x4981ec(0x3fd)][_0x3451e8][_0x4981ec(0x502)];}var _0x56928b={};_0x56928b[_0x4981ec(0x48d)]=_0x4e2171,_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if('remote'in _0x24cccd){if(_0x24cccd[_0x4981ec(0x240)]===_0x495e21[_0x4981ec(0x240)]&&_0x495e21['remote']){var _0x4e2171={};for(var _0x3451e8 in _0x495e21[_0x4981ec(0x3fd)]){if(_0x3451e8===_0x28afe0)continue;_0x4e2171[_0x3451e8]=_0x495e21[_0x4981ec(0x3fd)][_0x3451e8][_0x4981ec(0x502)];}var _0x56928b={};_0x56928b[_0x4981ec(0x48d)]=_0x4e2171,_0x495e21['sendMessage'](_0x56928b,_0x28afe0);}}}}if(_0x4981ec(0x4a6)in _0x24cccd)try{log(_0x24cccd),_0x495e21[_0x4981ec(0x392)](_0x24cccd[_0x4981ec(0x12e)],_0x24cccd['requestResolution']['w'],_0x24cccd[_0x4981ec(0x4a6)]['h']);}catch(_0x24c521){if(_0x4981ec(0x106)!==_0x4981ec(0x29a))errorlog(_0x24c521);else{function _0x299390(){var _0x39128c=_0x4981ec;_0xd71675(_0x39128c(0x4dd));}}}if(_0x4981ec(0x286)in _0x24cccd){if('TCwpl'===_0x4981ec(0x291)){function _0x4b377f(){var _0x39b0ab=_0x4981ec;_0x3b6930[_0x39b0ab(0x1ee)][0x0][_0x39b0ab(0x4e2)]==![]&&(_0x160877['encodings'][0x0][_0x39b0ab(0x4e2)]=!![]),delete _0x5a5f80[_0x39b0ab(0x1ee)][0x0]['maxBitrate'];}}else{if(_0x24cccd[_0x4981ec(0x44c)]){if(_0x4981ec(0x374)!=='rFvfz')_0x495e21[_0x4981ec(0x389)]===_0x28afe0?_0x495e21[_0x4981ec(0x241)]():errorlog(_0x4981ec(0x40b));else{function _0x2ca83d(){var _0x5bd08d=_0x4981ec,_0x55b3c5=_0x502202['pcs'][_0x37b571][_0x5bd08d(0xdc)];_0x1126db[_0x5bd08d(0x3fd)][_0x32e108][_0x5bd08d(0x2d3)]&&_0x7d2860['pcs'][_0xa1a102][_0x5bd08d(0x2d3)]>0x0&&(_0xd32942[_0x5bd08d(0x3fd)][_0x43b6b7][_0x5bd08d(0x2d3)]<_0x33fd23[_0x5bd08d(0x3fd)][_0xfe082d][_0x5bd08d(0xdc)]&&(_0x55b3c5=_0xec0673[_0x5bd08d(0x3fd)][_0x352763][_0x5bd08d(0x2d3)])),_0x3de989['limitBitrate'](_0x1b4aa2,_0x55b3c5),_0x3213b6['pcs'][_0x31fe7b][_0x5bd08d(0xdc)]===0x0&&_0x51be2b[_0x5bd08d(0x3bb)](_0x54cd24,0x0);}}}else _0x495e21[_0x4981ec(0x3df)](_0x28afe0);}}if(_0x4981ec(0x228)in _0x24cccd){var _0x2fac85=![],_0x1f0853=![];_0x495e21[_0x4981ec(0x389)]===_0x28afe0&&(_0x2fac85=!![],_0x4981ec(0x3e3)in _0x24cccd&&(_0x24cccd[_0x4981ec(0x3e3)]==!![]&&(_0x1f0853=!![]))),log(_0x4981ec(0x360)+_0x2fac85),getChatMessage(_0x24cccd[_0x4981ec(0x228)],_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0xab)],_0x2fac85,_0x1f0853);}if('order'in _0x24cccd){_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x40a)]=parseInt(_0x24cccd[_0x4981ec(0x40a)])||0x0;_0x28afe0 in _0x495e21[_0x4981ec(0x3cc)]&&(_0x495e21[_0x4981ec(0x3cc)][_0x28afe0][_0x4981ec(0x40a)]=_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x40a)]);if(_0x495e21[_0x4981ec(0x455)]){var _0x55ae37=document[_0x4981ec(0x91)](_0x4981ec(0x1f2)+_0x28afe0+'\x22]');log(_0x55ae37),_0x55ae37[0x0]&&(_0x55ae37[0x0][_0x4981ec(0x44f)]=parseInt(_0x24cccd['order'])||0x0);}updateMixer();}_0x4981ec(0x232)in _0x24cccd&&_0x495e21[_0x4981ec(0x1e3)](_0x28afe0,_0x24cccd[_0x4981ec(0x232)]);_0x4981ec(0x3a5)in _0x24cccd&&(_0x495e21[_0x4981ec(0x455)]&&(!(_0x495e21[_0x4981ec(0xe9)]||_0x495e21[_0x4981ec(0x2a7)])&&warnUser('The\x20request\x20failed;\x20the\x20remote\x20user\x20did\x20not\x20recognize\x20you\x20as\x20the\x20director',0x1388)),errorlog(_0x4981ec(0x3e2)+_0x24cccd[_0x4981ec(0x3a5)]+_0x4981ec(0x1c1)+_0x495e21[_0x4981ec(0x455)]));if(_0x28afe0!==_0x495e21[_0x4981ec(0x389)]){if(_0x4981ec(0x3e8)in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x3a5)]=_0x4981ec(0x3e8),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if(_0x4981ec(0x19e)in _0x24cccd){var _0x56928b={};_0x56928b['rejected']=_0x4981ec(0x19e),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if(_0x4981ec(0x21d)in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x3a5)]=_0x4981ec(0x21d),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if(_0x4981ec(0x4f5)in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x3a5)]='changeURL',_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if(_0x4981ec(0x41f)in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x3a5)]='changeLabel',_0x495e21['sendMessage'](_0x56928b,_0x28afe0);}else{if(_0x4981ec(0x2ac)in _0x24cccd){var _0x56928b={};_0x56928b['rejected']='requestChangeEQ',_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if('lowerhand'in _0x24cccd){var _0x56928b={};_0x56928b['rejected']=_0x4981ec(0x26f),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if(_0x4981ec(0x219)in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x3a5)]=_0x4981ec(0x219),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if('displayMute'in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x3a5)]=_0x4981ec(0x449),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if(_0x4981ec(0xce)in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x3a5)]=_0x4981ec(0xce),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}else{if('volume'in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x3a5)]=_0x4981ec(0x3f8),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}}}}}}}}}}}}else{if(_0x28afe0===_0x495e21['directorUUID']){if('requestAudioHack'in _0x24cccd){var _0x367737=_0x495e21[_0x4981ec(0x302)][_0x4981ec(0x428)]();if(_0x367737['length']){if(_0x4981ec(0x476)in _0x24cccd){var _0x50c3f9=parseInt(_0x24cccd[_0x4981ec(0x476)]);_0x50c3f9<_0x367737[_0x4981ec(0xaf)]&&(_0x367737=_0x367737[_0x50c3f9],applyAudioHack(_0x24cccd[_0x4981ec(0x353)],_0x24cccd[_0x4981ec(0x15c)]));}else _0x367737=_0x367737[0x0],applyAudioHack(_0x24cccd[_0x4981ec(0x353)],_0x24cccd['value']);}}if(_0x4981ec(0x19e)in _0x24cccd){if(_0x24cccd[_0x4981ec(0x19e)]){if(_0x495e21[_0x4981ec(0x2f6)]){if('RGLYG'===_0x4981ec(0x262)){function _0x4918db(){var _0x565e40=_0x4981ec;_0x3efb4a=_0x431f3c[_0x84dec6],_0x4c5086(_0x3c038a[_0x565e40(0x353)],_0x5ce5c8['value']);}}else{var _0x42433c=0x1770;_0x24cccd[_0x4981ec(0x15c)]&&(_0x42433c=parseInt(_0x24cccd['value'])),recordLocalVideo(_0x4981ec(0x3aa),_0x42433c);}}}else _0x495e21[_0x4981ec(0x2f6)]&&recordLocalVideo(_0x4981ec(0x2de));}if(_0x4981ec(0x21d)in _0x24cccd){_0x495e21['order']==![]&&(_0x495e21[_0x4981ec(0x40a)]=0x0);_0x495e21[_0x4981ec(0x40a)]+=parseInt(_0x24cccd[_0x4981ec(0x21d)])||0x0;var _0x56928b={};_0x56928b={},_0x56928b['order']=_0x495e21[_0x4981ec(0x40a)],_0x495e21['sendPeers'](_0x56928b),updateMixer();}if(_0x4981ec(0x4f5)in _0x24cccd){window[_0x4981ec(0x4a7)]();var _0x788905=confirm(_0x4981ec(0xba)+_0x24cccd[_0x4981ec(0x4f5)]+_0x4981ec(0x109));_0x788905&&(window[_0x4981ec(0x3ac)]['href']=_0x24cccd['changeURL']);;}if('changeLabel'in _0x24cccd){if(_0x4981ec(0x15c)in _0x24cccd){if(typeof _0x24cccd['value']==_0x4981ec(0x1c6)){_0x495e21[_0x4981ec(0xab)]=sanitizeLabel(_0x24cccd[_0x4981ec(0x15c)]),log(_0x4981ec(0x4cc)+_0x495e21[_0x4981ec(0xab)]);if(_0x495e21[_0x4981ec(0x455)]){var _0x55ae37=getById(_0x4981ec(0x427)+_0x28afe0);if(_0x495e21[_0x4981ec(0xab)])_0x55ae37[_0x4981ec(0x44f)]=_0x495e21[_0x4981ec(0xab)];else{if(_0x4981ec(0x10f)===_0x4981ec(0x10f))_0x55ae37[_0x4981ec(0x44f)]=_0x4981ec(0x225);else{function _0x1160e5(){var _0x55cf67=_0x4981ec;_0x3bfbfc(_0x55cf67(0x421));}}}}else _0x495e21[_0x4981ec(0x25c)]&&updateMixer();!_0x495e21[_0x4981ec(0x455)]&&(_0x495e21[_0x4981ec(0xab)]?document[_0x4981ec(0x3fb)]=_0x495e21[_0x4981ec(0xab)]:document[_0x4981ec(0x3fb)]=location[_0x4981ec(0x1a0)]);var _0xc563fd=encodeURIComponent(_0x495e21[_0x4981ec(0xab)]);urlParams[_0x4981ec(0x327)]('l')?updateURL('l='+_0xc563fd,!![],![]):updateURL(_0x4981ec(0x42e)+_0xc563fd,!![],![]);var _0x56928b={};_0x56928b[_0x4981ec(0x41f)]=!![],_0x56928b[_0x4981ec(0x15c)]=_0x495e21['label'],_0x495e21[_0x4981ec(0x3bd)](_0x56928b);}else{_0x495e21[_0x4981ec(0xab)]=![];var _0x56928b={};_0x56928b['changeLabel']=!![],_0x56928b[_0x4981ec(0x15c)]=_0x495e21[_0x4981ec(0xab)],_0x495e21[_0x4981ec(0x3bd)](_0x56928b);if(_0x495e21[_0x4981ec(0x455)]){var _0x55ae37=getById(_0x4981ec(0x427)+_0x28afe0);_0x55ae37['innerText']=_0x4981ec(0x225);}else _0x495e21[_0x4981ec(0x25c)]?(document[_0x4981ec(0x3fb)]=location[_0x4981ec(0x1a0)],updateMixer()):document[_0x4981ec(0x3fb)]=location[_0x4981ec(0x1a0)];}}}if(_0x4981ec(0x2ac)in _0x24cccd){if(_0x24cccd[_0x4981ec(0x353)]==_0x4981ec(0x2a5))changeLowEQ(parseFloat(_0x24cccd[_0x4981ec(0x15c)]),_0x24cccd[_0x4981ec(0x476)]);else{if(_0x24cccd[_0x4981ec(0x353)]==_0x4981ec(0xcc))changeMidEQ(parseFloat(_0x24cccd[_0x4981ec(0x15c)]),_0x24cccd['track']);else _0x24cccd['keyname']==_0x4981ec(0x322)&&changeHighEQ(parseFloat(_0x24cccd[_0x4981ec(0x15c)]),_0x24cccd[_0x4981ec(0x476)]);}}_0x4981ec(0x26f)in _0x24cccd&&(_0x495e21[_0x4981ec(0x25f)]&&lowerhand());if('getAudioSettings'in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x12e)]=_0x28afe0,_0x56928b[_0x4981ec(0x4f9)]=listAudioSettingsPrep(),sendMediaDevices(_0x56928b[_0x4981ec(0x12e)]),_0x495e21['sendMessage'](_0x56928b,_0x56928b[_0x4981ec(0x12e)]);}if(_0x4981ec(0x4d9)in _0x24cccd){var _0x56928b={};_0x56928b[_0x4981ec(0x12e)]=_0x28afe0,_0x56928b[_0x4981ec(0x3d2)]=listVideoSettingsPrep(),sendMediaDevices(_0x56928b[_0x4981ec(0x12e)]),_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x56928b['UUID']);}'changeSpeaker'in _0x24cccd&&changeAudioOutputDeviceById(_0x24cccd[_0x4981ec(0x43d)],_0x28afe0);_0x4981ec(0x2ca)in _0x24cccd&&changeAudioDeviceById(_0x24cccd['changeMicrophone'],_0x28afe0);'changeCamera'in _0x24cccd&&changeVideoDeviceById(_0x24cccd[_0x4981ec(0x3ce)],_0x28afe0);_0x4981ec(0x2d9)in _0x24cccd&&updateCameraConstraints(_0x24cccd[_0x4981ec(0x353)],_0x24cccd[_0x4981ec(0x15c)]);_0x4981ec(0xae)in _0x24cccd&&changeLowCut(parseFloat(_0x24cccd[_0x4981ec(0x15c)]),_0x24cccd[_0x4981ec(0x476)]);_0x4981ec(0xae)in _0x24cccd&&changeLowCut(parseFloat(_0x24cccd[_0x4981ec(0x15c)]),_0x24cccd['track']);_0x4981ec(0x219)in _0x24cccd&&_0x495e21[_0x4981ec(0x219)]();if(_0x4981ec(0x11c)in _0x24cccd){}if('volume'in _0x24cccd){var _0x5c28a7=parseInt(_0x24cccd[_0x4981ec(0x3f8)])/0x64||0x0;_0x495e21['audioGain']=parseInt(_0x24cccd[_0x4981ec(0x3f8)])||0x0;for(var _0x39be96 in _0x495e21[_0x4981ec(0x185)]){if(_0x4981ec(0xa7)!==_0x4981ec(0x2f3))log(_0x4981ec(0xe1)),_0x495e21[_0x4981ec(0x185)][_0x39be96][_0x4981ec(0xb2)][_0x4981ec(0x1e5)][_0x4981ec(0x456)](_0x5c28a7,_0x495e21[_0x4981ec(0x185)][_0x39be96]['audioContext'][_0x4981ec(0x1f3)]);else{function _0x3407f1(){var _0x13a5db=_0x4981ec;_0x10cec3(_0x1dbd45[_0x13a5db(0x2ce)],0x3e8,_0x50a748,0x7d00,0x0);}}}}if(_0x4981ec(0x21e)in _0x24cccd){var _0xfb2d5e=parseFloat(_0x24cccd['delay']/0x3e8)||0x0;_0x495e21[_0x4981ec(0x183)]=parseInt(_0x24cccd[_0x4981ec(0x21e)])||0x0;for(var _0x39be96 in _0x495e21[_0x4981ec(0x185)]){_0x495e21[_0x4981ec(0x185)][_0x39be96][_0x4981ec(0x183)][_0x4981ec(0x3d9)][_0x4981ec(0x456)](_0xfb2d5e,_0x495e21[_0x4981ec(0x185)][_0x39be96][_0x4981ec(0x395)][_0x4981ec(0x1f3)]);}}if(_0x4981ec(0xce)in _0x24cccd){if(_0x4981ec(0x1e2)===_0x4981ec(0x1e2))_0x24cccd[_0x4981ec(0xce)]?(_0x495e21['directorSpeakerMuted']=!![],_0x495e21['directorSpeakerMute']()):(_0x495e21[_0x4981ec(0x377)]=![],_0x495e21[_0x4981ec(0x37f)]());else{function _0x20081a(){var _0x2fbecf=_0x4981ec;_0x3d806f[_0x2fbecf(0x35a)]=_0x2f8893['obsState'][_0x2fbecf(0x498)];}}}_0x4981ec(0x449)in _0x24cccd&&(_0x24cccd[_0x4981ec(0x449)]?(_0x495e21[_0x4981ec(0x1bb)]=!![],_0x495e21[_0x4981ec(0x474)]()):(_0x495e21[_0x4981ec(0x1bb)]=![],_0x495e21[_0x4981ec(0x474)]())),_0x4981ec(0x239)in _0x24cccd&&applyNewParams(_0x24cccd[_0x4981ec(0x239)]);}}if('zoom'in _0x24cccd){if(_0x495e21[_0x4981ec(0x240)]){if('yIWFA'!==_0x4981ec(0x3ff)){if('remote'in _0x24cccd)_0x24cccd[_0x4981ec(0x240)]===_0x495e21[_0x4981ec(0x240)]&&_0x495e21[_0x4981ec(0x240)]&&_0x495e21[_0x4981ec(0x4e0)](parseFloat(_0x24cccd[_0x4981ec(0x467)]));else{if(_0x28afe0===_0x495e21[_0x4981ec(0x389)])_0x495e21[_0x4981ec(0x4e0)](parseFloat(_0x24cccd[_0x4981ec(0x467)]));else return;}}else{function _0xa9ed50(){var _0x46d3f0=_0x4981ec;_0x480397[_0x46d3f0(0x367)]=_0x43cea1[_0x46d3f0(0x414)];}}}}if(_0x4981ec(0x4a7)in _0x24cccd){if(_0x495e21[_0x4981ec(0x240)]){if(_0x4981ec(0x240)in _0x24cccd)_0x24cccd[_0x4981ec(0x240)]===_0x495e21[_0x4981ec(0x240)]&&_0x495e21[_0x4981ec(0x240)]&&_0x495e21[_0x4981ec(0x296)](parseFloat(_0x24cccd[_0x4981ec(0x4a7)]));else{if(_0x28afe0===_0x495e21[_0x4981ec(0x389)])_0x495e21[_0x4981ec(0x296)](parseFloat(_0x24cccd[_0x4981ec(0x4a7)]));else return;}}}manageSceneState(_0x24cccd,_0x28afe0);_0x4981ec(0x2d0)in _0x24cccd&&_0x495e21[_0x4981ec(0x2cb)](_0x28afe0,_0x24cccd[_0x4981ec(0x2d0)]);if('audio'in _0x24cccd&&'video'in _0x24cccd){log(_0x4981ec(0x312));_0x24cccd[_0x4981ec(0x295)]==![]&&(_0x495e21['pcs'][_0x28afe0][_0x4981ec(0xf6)]=![]);_0x24cccd[_0x4981ec(0x482)]==![]&&(_0x495e21['pcs'][_0x28afe0][_0x4981ec(0xbc)]=![]);if(_0x4981ec(0x41e)in _0x24cccd&&_0x24cccd[_0x4981ec(0x41e)]==!![]){if(_0x4981ec(0x37e)!==_0x4981ec(0x27e))_0x495e21[_0x4981ec(0x3fd)][_0x28afe0]['allowBroadcast']=!![],setTimeout(function(){makeImages();},0x3e8);else{function _0x1f3351(){var _0x51e82e=_0x4981ec;_0x4784d6=new _0xa613e9(_0x1cc8a0),_0x1c995b=_0x1bde4e['reduce']((_0x1e3e91,_0x3ba21f)=>_0x1e3e91+_0x3ba21f[_0x51e82e(0x37d)](0x10)['padStart'](0x2,'0'),''),_0x2e7744(_0x496a69,_0x300bda),_0x2915cc(_0x2342ba[_0x51e82e(0x1e9)](_0x5d3276));}}}_0x4981ec(0x19c)in _0x24cccd&&_0x24cccd[_0x4981ec(0x19c)]==![]&&(_0x495e21[_0x4981ec(0x3fd)][_0x28afe0]['allowIframe']=![]);_0x4981ec(0x243)in _0x24cccd&&_0x24cccd[_0x4981ec(0x4db)]!==![]&&(_0x495e21['pcs'][_0x28afe0][_0x4981ec(0x494)]=_0x24cccd['allowmidi']);_0x4981ec(0x438)in _0x24cccd&&(_0x24cccd[_0x4981ec(0x438)]==!![]&&(_0x495e21['pcs'][_0x28afe0]['guest']=!![]));_0x4981ec(0x3d5)in _0x24cccd&&(_0x24cccd[_0x4981ec(0x3d5)]===!![]&&(_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x3d5)]=!![]));if(_0x4981ec(0x455)in _0x24cccd){if(_0x4981ec(0x30e)!=='MOWSi'){function _0x38676f(){var _0x39eb6b=_0x4981ec;_0x5f42f6[_0x39eb6b(0x38f)](_0x5654b4[_0x39eb6b(0x12e)]);}}else{if(_0x24cccd[_0x4981ec(0x455)]==!![]){if(iOS||iPad){if(_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x3d5)]==!![]){if(_0x4981ec(0x356)===_0x4981ec(0x356))_0x495e21[_0x4981ec(0x3fd)][_0x28afe0]['guest']=!![];else{function _0x571194(){_0x5ad55b(_0x27934c['changeMicrophone'],_0x2ddf8a);}}}}}}}_0x4981ec(0x297)in _0x24cccd&&(_0x24cccd[_0x4981ec(0x297)]==!![]&&(_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x397)]=!![]));if('enhanceaudio'in _0x24cccd){if(_0x24cccd[_0x4981ec(0x47c)]==!![]){if(_0x4981ec(0x251)===_0x4981ec(0x160)){function _0x5c8d1c(){var _0x334dfe=_0x4981ec;_0x7c755b[_0x334dfe(0x1b3)]={},_0x4163dc[_0x334dfe(0x1b3)][_0x334dfe(0x128)]=_0xd42b65[_0x334dfe(0x128)];}}else _0x495e21[_0x4981ec(0x3fd)][_0x28afe0]['enhanceAudio']=!![];}}'keyframerate'in _0x24cccd&&(_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x233)]=_0x24cccd[_0x4981ec(0x233)],_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x233)]&&setTimeout(function(){var _0x5964e4=_0x4981ec;if('MHQFl'!==_0x5964e4(0x221))_0x495e21[_0x5964e4(0x3df)](_0x28afe0);else{function _0x37a3dc(){var _0x1361a8={};_0x1361a8['rejected']='changeLabel',_0x12b382['sendMessage'](_0x1361a8,_0x2e8abf);}}},0x1388));if(_0x4981ec(0x44c)in _0x24cccd){if(_0x24cccd['scene']!==![]){try{typeof _0x24cccd[_0x4981ec(0x44c)]===_0x4981ec(0x1c6)?_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x44c)]=_0x24cccd[_0x4981ec(0x44c)][_0x4981ec(0x4f1)](/[\W]+/g,'_'):_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x44c)]=(parseInt(_0x24cccd['scene'])||0x0)+'',_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x502)][_0x4981ec(0x44c)]=_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x44c)],updateSceneList(_0x495e21['pcs'][_0x28afe0][_0x4981ec(0x44c)]);}catch(_0x4a43fd){errorlog(_0x4a43fd);}_0x495e21[_0x4981ec(0x455)]==!![]&&_0x495e21[_0x4981ec(0x398)]==![]&&(_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0xf6)]=![],_0x495e21['pcs'][_0x28afe0][_0x4981ec(0xbc)]=![],_0x495e21[_0x4981ec(0x3fd)][_0x28afe0]['allowIframe']=![]);}}if(_0x495e21[_0x4981ec(0x455)]==!![]){if(_0x495e21[_0x4981ec(0x3fd)][_0x28afe0][_0x4981ec(0x44c)]){if(_0x4981ec(0x9b)===_0x4981ec(0x9b))var _0x3a35b8=getDirectorSettings(_0x495e21['pcs'][_0x28afe0][_0x4981ec(0x44c)]);else{function _0xe484b2(){return _0x52f15d;}}}else var _0x3a35b8=getDirectorSettings(![]);var _0x56928b={};_0x56928b[_0x4981ec(0x1b3)]=_0x3a35b8,_0x495e21[_0x4981ec(0x3bd)](_0x56928b,_0x28afe0);}_0x495e21[_0x4981ec(0x433)](_0x28afe0);}},_0x495e21['initialPublish']=function(_0x56cfa8){var _0x4f949c=_0x17abb6;if(_0x56cfa8 in _0x495e21['pcs']){}else{errorlog(_0x4f949c(0x123));return;}if(_0x495e21[_0x4f949c(0x3fd)][_0x56cfa8][_0x4f949c(0x505)]===!![]){if(_0x495e21[_0x4f949c(0x15b)]){var _0x3fc3d1={};_0x3fc3d1[_0x4f949c(0x15b)]=_0x495e21[_0x4f949c(0x15b)],_0x495e21[_0x4f949c(0x3bd)](_0x3fc3d1,_0x56cfa8);}}log(_0x4f949c(0xfc)),log(_0x495e21[_0x4f949c(0x302)]);var _0x526ed0=null;if(_0x495e21[_0x4f949c(0x2f6)][_0x4f949c(0x1e8)])_0x526ed0=_0x495e21[_0x4f949c(0x2f6)][_0x4f949c(0x1e8)];else{if(_0x495e21[_0x4f949c(0x302)]&&_0x495e21[_0x4f949c(0x302)][_0x4f949c(0x509)]())errorlog(_0x4f949c(0x10b)),log(_0x495e21[_0x4f949c(0x302)]['getTracks']()),_0x526ed0=_0x495e21[_0x4f949c(0x302)];else{warnlog(_0x4f949c(0x33c));return;}}_0x526ed0[_0x4f949c(0x509)]()[_0x4f949c(0x415)](_0xbe0aa1=>{var _0x52cff2=_0x4f949c;_0x495e21['pcs'][_0x56cfa8][_0x52cff2(0xf6)]==!![]&&(_0xbe0aa1[_0x52cff2(0x51a)]==_0x52cff2(0x295)&&_0x495e21[_0x52cff2(0x3fd)][_0x56cfa8][_0x52cff2(0x49c)](_0xbe0aa1,_0x526ed0)),_0x495e21[_0x52cff2(0x3fd)][_0x56cfa8]['allowVideo']==!![]&&(_0xbe0aa1[_0x52cff2(0x51a)]==_0x52cff2(0x482)&&(_0x495e21['pcs'][_0x56cfa8][_0x52cff2(0x438)]==!![]&&_0x495e21[_0x52cff2(0xd6)]===0x0?log(_0x52cff2(0x4f3)):(_0x495e21[_0x52cff2(0x3fd)][_0x56cfa8][_0x52cff2(0x49c)](_0xbe0aa1,_0x526ed0),setTimeout(function(_0x118788){var _0x101282=_0x52cff2;_0x495e21[_0x101282(0x354)](_0x118788);},_0x495e21['rampUpTime'],_0x56cfa8))));}),log(_0x4f949c(0x207));if(_0x526ed0['getAudioTracks']()[_0x4f949c(0xaf)]){_0x495e21['applySoloChat'](),log(_0x4f949c(0x18c));if(_0x495e21['pcs'][_0x56cfa8][_0x4f949c(0x397)]===!![]){if(_0x4f949c(0x463)===_0x4f949c(0x463))setTimeout(_0x495e21[_0x4f949c(0x2ce)],0x3e8,_0x56cfa8,0x7d00,0x0);else{function _0xdfdf3b(){var _0x36fdfe=_0x4f949c,_0x544b78=this[_0x36fdfe(0x23e)];}}}_0x495e21['pcs'][_0x56cfa8][_0x4f949c(0x35c)]===!![]&&setTimeout(_0x495e21[_0x4f949c(0x309)],0x3e8,_0x56cfa8);}},_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x519)]=function(_0xee872){var _0x303ef2=_0x17abb6;_0x495e21[_0x303ef2(0x25d)](_0x28afe0);},_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x16c)]=_0x2dc916=>{var _0x2217ad=_0x17abb6;errorlog(_0x2217ad(0x203));},_0x495e21[_0x17abb6(0x3fd)][_0x28afe0]['iceTimer']=null,_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x3c1)]=[],_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x279)]=function(_0xdb6621){var _0x46b1ab=_0x17abb6;if(_0xdb6621[_0x46b1ab(0xf0)]==null){log(_0x46b1ab(0x4d3));return;}try{if(_0x495e21[_0x46b1ab(0x400)]){if(_0xdb6621[_0x46b1ab(0xf0)][_0x46b1ab(0xf0)]['indexOf'](_0x495e21[_0x46b1ab(0x400)])===-0x1){log(_0x46b1ab(0x451));return;}else log(_0xdb6621[_0x46b1ab(0xf0)]);}}catch(_0xff9c0f){errorlog(_0xff9c0f);}if(_0x495e21[_0x46b1ab(0x3fd)][_0x28afe0]['iceTimer']!==null){_0x495e21['pcs'][_0x28afe0][_0x46b1ab(0x3c1)]['push'](_0xdb6621['candidate']);return;}_0x495e21['pcs'][_0x28afe0][_0x46b1ab(0x3c1)][_0x46b1ab(0x17e)](_0xdb6621['candidate']),_0x495e21[_0x46b1ab(0x3fd)][_0x28afe0][_0x46b1ab(0x25a)]=setTimeout(function(_0x498948){var _0x399651=_0x46b1ab;_0x495e21[_0x399651(0x3fd)][_0x498948]['iceTimer']=null;var _0x1df331={};_0x1df331[_0x399651(0x12e)]=_0x498948,_0x1df331['type']='local',_0x1df331[_0x399651(0x117)]=_0x495e21['pcs'][_0x498948][_0x399651(0x3c1)],_0x1df331[_0x399651(0x518)]=_0x495e21[_0x399651(0x3fd)][_0x498948][_0x399651(0x518)],_0x495e21[_0x399651(0x3fd)][_0x498948][_0x399651(0x3c1)]=[];if(_0x495e21['password'])_0x495e21['encryptMessage'](JSON[_0x399651(0x1e9)](_0x1df331['candidates']))[_0x399651(0x34d)](function(_0x5c0163){var _0x2634c6=_0x399651;_0x1df331[_0x2634c6(0x117)]=_0x5c0163[0x0],_0x1df331[_0x2634c6(0x48b)]=_0x5c0163[0x1],_0x495e21[_0x2634c6(0x143)](_0x1df331);});else{if('sevCH'===_0x399651(0x380)){function _0x5ea59a(){return _0x5db5b0(_0x2bac05),_0x2b27a7;}}else _0x495e21[_0x399651(0x143)](_0x1df331);}},0xc8,_0x28afe0);},_0x495e21['pcs'][_0x28afe0]['oniceconnectionstatechange']=function(_0x257e3b){var _0x334b50=_0x17abb6;try{if(this['iceConnectionState']==_0x334b50(0x4ee))log('ICE\x20closed?');else{if(this[_0x334b50(0x1bc)]==_0x334b50(0x406)){if(_0x334b50(0x1d4)!==_0x334b50(0xd0))log(_0x334b50(0x40c));else{function _0x47813c(){_0x5e8b7e(function _0x289ebe(){var _0x10abd8=_0x56d9;_0x3a2726(_0x10abd8(0x4dd));},0x1);}}}else{if(this[_0x334b50(0x1bc)]=='failed')log(_0x334b50(0x118));else this[_0x334b50(0x1bc)]==_0x334b50(0xb0)?(log(_0x334b50(0x416)),_0x495e21['pcs'][_0x28afe0][_0x334b50(0x16e)]()[_0x334b50(0x415)](_0x3b6b0b=>{var _0x976f89=_0x334b50;if(!_0x3b6b0b[_0x976f89(0x476)])return;if(_0x3b6b0b[_0x976f89(0x476)][_0x976f89(0x51a)]===_0x976f89(0x482)){if(_0x976f89(0x18d)===_0x976f89(0x30c)){function _0x53552c(){var _0x3143c5=_0x976f89;_0x341df5[_0x3143c5(0x317)]=_0x3143c5(0x31b),_0x1d4bc1[_0x3143c5(0x2e0)]=_0x13d9e0[_0x3143c5(0x3b3)];var _0x102e7b={};_0x102e7b[_0x3143c5(0x317)]=_0x3143c5(0x2ab),_0x102e7b[_0x3143c5(0x3b3)]=_0x51f10c[_0x3143c5(0x2e0)],_0x102e7b['streamID']=_0x246b6e[_0x3143c5(0x23e)],_0x2b3881[_0x3143c5(0x1e7)](_0x102e7b);}}else{_0x495e21['pcs'][_0x28afe0][_0x976f89(0x36f)]=_0x3b6b0b['getParameters']()[_0x976f89(0x3b7)],log(_0x495e21[_0x976f89(0x3fd)][_0x28afe0]['videoCodecs']);return;}}else{if(_0x3b6b0b[_0x976f89(0x476)][_0x976f89(0x51a)]===_0x976f89(0x295)){_0x495e21[_0x976f89(0x3fd)][_0x28afe0][_0x976f89(0x490)]=_0x3b6b0b[_0x976f89(0x3d6)]()[_0x976f89(0x3b7)],log(_0x495e21[_0x976f89(0x3fd)][_0x28afe0]['audioCodecs']);return;}}})):log(this[_0x334b50(0x1bc)]);}}}catch(_0x14468c){errorlog(_0x14468c);}},_0x495e21['pcs'][_0x28afe0][_0x17abb6(0x49f)]=function(_0x16b3e7){var _0x51a614=_0x17abb6;switch(_0x495e21[_0x51a614(0x3fd)][_0x28afe0]['connectionState']){case _0x51a614(0xb0):log(_0x51a614(0x2ff));if(_0x495e21[_0x51a614(0xdd)]){if(_0x495e21['ws'][_0x51a614(0x454)]!==0x1){_0x495e21['ws']['close']();break;}_0x495e21['ws']['close'](),setTimeout(function(){var _0x176ab9=_0x51a614;_0x495e21[_0x176ab9(0xe9)]!=!![]&&warnUser(_0x176ab9(0x1a4));},0x1);}break;case _0x51a614(0x406):log(_0x51a614(0x3a9));break;case _0x51a614(0x204):warnlog(_0x51a614(0x1a8)),_0x495e21[_0x51a614(0x3fd)][_0x28afe0][_0x51a614(0x229)](),_0x495e21['pcs'][_0x28afe0]=null;_0x495e21[_0x51a614(0xdd)]&&(!_0x495e21[_0x51a614(0xe9)]&&setTimeout(function(){var _0x37aa84=_0x51a614;warnUser(_0x37aa84(0x4dd));},0x1));delete _0x495e21['pcs'][_0x28afe0],_0x495e21[_0x51a614(0x386)](),applySceneState();break;case _0x51a614(0x4ee):warnlog(_0x51a614(0x2c6)),_0x495e21[_0x51a614(0x3fd)][_0x28afe0]=null;if(_0x495e21[_0x51a614(0xdd)]){if(_0x51a614(0x3da)!==_0x51a614(0x3da)){function _0x30489c(){var _0x4ecd7b=_0x51a614;_0x29186c('request\x20focus\x20change:\x20'+_0x1188e0);var _0x3b0b25={};_0x3b0b25['focus']=_0x41e4ec,_0x3b0b25[_0x4ecd7b(0x240)]=_0x55edae,_0x3f34a5[_0x4ecd7b(0x166)](_0x3b0b25,_0x229788)?_0x5dd8b1(_0x4ecd7b(0x405)):_0x3df72(_0x4ecd7b(0x130));}}else!_0x495e21[_0x51a614(0xe9)]&&setTimeout(function _0x350edc(){warnUser('Remote\x20peer\x20disconnected.\x20Due\x20to\x20enhanced\x20security,\x20please\x20refresh\x20to\x20create\x20a\x20new\x20connection.');},0x1);}delete _0x495e21[_0x51a614(0x3fd)][_0x28afe0],_0x495e21[_0x51a614(0x386)](),applySceneState();break;}},_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x2c8)]=function(_0x39f514){var _0x265167=_0x17abb6;warnlog(_0x265167(0x4b2)),_0x495e21[_0x265167(0x3fd)][_0x28afe0]=null,delete _0x495e21['pcs'][_0x28afe0],_0x495e21[_0x265167(0x386)](),applySceneState();},_0x495e21[_0x17abb6(0x3fd)][_0x28afe0][_0x17abb6(0x13c)]=function _0x7e00a2(){var _0x347367=_0x17abb6;log(_0x347367(0x28c));};},_0x495e21['processDescription']=function(_0x38d59c){var _0x5a4a4c=_0x2a0a0d;if(_0x495e21[_0x5a4a4c(0x211)])_0x5a4a4c(0x48b)in _0x38d59c&&_0x495e21['decryptMessage'](_0x38d59c[_0x5a4a4c(0x33d)],_0x38d59c[_0x5a4a4c(0x48b)])[_0x5a4a4c(0x34d)](function(_0x118487){var _0x302ab4=_0x5a4a4c;_0x38d59c[_0x302ab4(0x33d)]=JSON['parse'](_0x118487);if(_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x14a)]==_0x302ab4(0x104))_0x495e21[_0x302ab4(0x391)](_0x38d59c),_0x495e21[_0x302ab4(0x3ae)](_0x38d59c);else try{if(_0x302ab4(0x495)===_0x302ab4(0x503)){function _0x376519(){var _0x25a009=_0x302ab4;_0x125bf5(_0x2794d2),_0x58f4c6(_0x25a009(0x4a1));}}else{var _0x5e729f=_0x495e21[_0x302ab4(0x319)];if((iOS||iPad)&&_0x495e21[_0x302ab4(0x3fd)][_0x38d59c[_0x302ab4(0x12e)]][_0x302ab4(0x438)]==!![]&&_0x495e21['pcs'][_0x38d59c[_0x302ab4(0x12e)]][_0x302ab4(0x3d5)]==![]){if(_0x5e729f===![]||_0x5e729f>_0x495e21[_0x302ab4(0x459)]){var _0x595579=Object[_0x302ab4(0x31f)](_0x495e21[_0x302ab4(0x3fd)])['length'];_0x595579>0x3?_0x5e729f=_0x495e21[_0x302ab4(0x21c)]:_0x5e729f=_0x495e21[_0x302ab4(0x459)];}_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)]=CodecsHandler[_0x302ab4(0x2e8)](_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)],_0x302ab4(0x1da)),_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)]=CodecsHandler[_0x302ab4(0x343)](_0x38d59c['description'][_0x302ab4(0x496)],{'min':parseInt(_0x5e729f/0x2)||0x1,'max':_0x5e729f}),_0x5e729f=![];}else{if(_0x495e21[_0x302ab4(0x3fd)][_0x38d59c[_0x302ab4(0x12e)]][_0x302ab4(0x438)]==!![]){if(_0x302ab4(0x26a)==='kIDkj'){if(_0x5e729f!==![]){if('trJFW'!==_0x302ab4(0x249))_0x495e21[_0x302ab4(0xd6)]!==![]&&(_0x495e21[_0x302ab4(0xd6)]<_0x5e729f&&(_0x5e729f=_0x495e21[_0x302ab4(0xd6)]));else{function _0x52944e(){var _0x487a2f=_0x302ab4;_0x1e2deb[_0x487a2f(0x35a)]=_0x4e77fd[_0x487a2f(0x278)][_0x487a2f(0x498)];}}}else _0x5e729f=_0x495e21[_0x302ab4(0xd6)];}else{function _0x23ea5f(){_0x58a4ec(function(){_0x443b7d();},0x1);}}}}if(_0x5e729f){var _0x336ca8=CodecsHandler[_0x302ab4(0x45e)](_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)])||0x9c4;log(_0x302ab4(0x338)+_0x336ca8);if(_0x336ca8>_0x5e729f){var _0x51ae7=CodecsHandler[_0x302ab4(0x116)](_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)])||0x0;_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)]=CodecsHandler['setVideoBitrates'](_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)],{'min':parseInt(_0x5e729f/0xa)||0x1,'max':parseInt(_0x5e729f+_0x51ae7/0x400)}),_0x495e21[_0x302ab4(0x3fd)][_0x38d59c[_0x302ab4(0x12e)]][_0x302ab4(0x263)]=_0x5e729f;}else _0x495e21[_0x302ab4(0x3fd)][_0x38d59c['UUID']][_0x302ab4(0x263)]=_0x336ca8;}else{if(_0x495e21[_0x302ab4(0x178)]!==![]){var _0x336ca8=CodecsHandler[_0x302ab4(0x45e)](_0x38d59c[_0x302ab4(0x33d)]['sdp']);if(_0x336ca8===![]){var _0x51ae7=CodecsHandler[_0x302ab4(0x116)](_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)])||0x0;_0x38d59c['description'][_0x302ab4(0x496)]=CodecsHandler[_0x302ab4(0x343)](_0x38d59c['description'][_0x302ab4(0x496)],{'min':parseInt(_0x495e21[_0x302ab4(0x178)]/0xa)||0x1,'max':parseInt(_0x495e21['outboundVideoBitrate']+_0x51ae7/0x400)});}else _0x495e21[_0x302ab4(0x3fd)][_0x38d59c[_0x302ab4(0x12e)]]['setBitrate']=_0x336ca8;}else _0x495e21[_0x302ab4(0x3fd)][_0x38d59c[_0x302ab4(0x12e)]][_0x302ab4(0x263)]=CodecsHandler[_0x302ab4(0x45e)](_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)]);}_0x495e21[_0x302ab4(0x162)]&&(_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)]=CodecsHandler[_0x302ab4(0x186)](_0x38d59c[_0x302ab4(0x33d)][_0x302ab4(0x496)],{'maxaveragebitrate':_0x495e21[_0x302ab4(0x162)]*0x400,'cbr':_0x495e21['cbr']}));if(_0x302ab4(0x518)in _0x38d59c&&_0x38d59c[_0x302ab4(0x518)]!=_0x495e21[_0x302ab4(0x3fd)][_0x38d59c[_0x302ab4(0x12e)]]['session']){errorlog(_0x302ab4(0x18e));return;}_0x495e21[_0x302ab4(0x3fd)][_0x38d59c[_0x302ab4(0x12e)]]['setRemoteDescription'](_0x38d59c[_0x302ab4(0x33d)])[_0x302ab4(0x34d)]()['catch'](errorlog);}}catch(_0x1474f9){errorlog(_0x1474f9);}});else{if(_0x38d59c[_0x5a4a4c(0x33d)][_0x5a4a4c(0x14a)]==_0x5a4a4c(0x104))_0x495e21[_0x5a4a4c(0x391)](_0x38d59c),_0x495e21[_0x5a4a4c(0x3ae)](_0x38d59c);else{if(_0x5a4a4c(0x99)===_0x5a4a4c(0x99))try{var _0x34731=_0x495e21[_0x5a4a4c(0x319)];if((iOS||iPad)&&_0x495e21[_0x5a4a4c(0x3fd)][_0x38d59c[_0x5a4a4c(0x12e)]]['guest']==!![]&&_0x495e21[_0x5a4a4c(0x3fd)][_0x38d59c[_0x5a4a4c(0x12e)]][_0x5a4a4c(0x3d5)]==![]){if(_0x34731===![]||_0x34731>_0x495e21[_0x5a4a4c(0x459)]){var _0x5cf877=Object[_0x5a4a4c(0x31f)](_0x495e21[_0x5a4a4c(0x3fd)])[_0x5a4a4c(0xaf)];_0x5cf877>0x3?_0x34731=_0x495e21[_0x5a4a4c(0x21c)]:_0x34731=_0x495e21[_0x5a4a4c(0x459)];}_0x38d59c['description'][_0x5a4a4c(0x496)]=CodecsHandler['preferCodec'](_0x38d59c['description'][_0x5a4a4c(0x496)],'vp8'),_0x38d59c['description'][_0x5a4a4c(0x496)]=CodecsHandler['setVideoBitrates'](_0x38d59c[_0x5a4a4c(0x33d)][_0x5a4a4c(0x496)],{'min':parseInt(_0x34731/0x2)||0x1,'max':_0x34731}),_0x34731=![];}else{if(_0x495e21[_0x5a4a4c(0x3fd)][_0x38d59c[_0x5a4a4c(0x12e)]][_0x5a4a4c(0x438)]==!![]){if(_0x5a4a4c(0x423)!==_0x5a4a4c(0x9a))_0x34731!==![]?_0x495e21[_0x5a4a4c(0xd6)]!==![]&&(_0x495e21['roombitrate']<_0x34731&&(_0x34731=_0x495e21['roombitrate'])):_0x34731=_0x495e21[_0x5a4a4c(0xd6)];else{function _0x1f032e(){var _0x37ae33=_0x5a4a4c;_0x31bac9(_0x37ae33(0x508));}}}}if(_0x34731){var _0x2b18f7=CodecsHandler['getVideoBitrates'](_0x38d59c['description']['sdp'])||0x9c4;log('BITRATE:\x20'+_0x2b18f7);if(_0x2b18f7>_0x34731){var _0x45b93f=CodecsHandler[_0x5a4a4c(0x116)](_0x38d59c['description'][_0x5a4a4c(0x496)])||0x0;_0x38d59c[_0x5a4a4c(0x33d)][_0x5a4a4c(0x496)]=CodecsHandler[_0x5a4a4c(0x343)](_0x38d59c['description']['sdp'],{'min':parseInt(_0x34731/0xa)||0x1,'max':parseInt(_0x34731+_0x45b93f/0x400)});}}else{if(_0x495e21['outboundVideoBitrate']!==![]){var _0x2b18f7=CodecsHandler[_0x5a4a4c(0x45e)](_0x38d59c[_0x5a4a4c(0x33d)][_0x5a4a4c(0x496)]);if(_0x2b18f7===![]){if(_0x5a4a4c(0x419)===_0x5a4a4c(0x2ef)){function _0x42122a(){var _0x3864d6=_0x5a4a4c;_0xb98d9c[_0x3864d6(0x3fd)][_0x517d85]['videoCodecs']=_0x523a83[_0x3864d6(0x3d6)]()[_0x3864d6(0x3b7)],_0x8b5d8c(_0x471274[_0x3864d6(0x3fd)][_0x200287]['videoCodecs']);return;}}else{var _0x45b93f=CodecsHandler[_0x5a4a4c(0x116)](_0x38d59c[_0x5a4a4c(0x33d)][_0x5a4a4c(0x496)])||0x0;_0x38d59c[_0x5a4a4c(0x33d)][_0x5a4a4c(0x496)]=CodecsHandler['setVideoBitrates'](_0x38d59c[_0x5a4a4c(0x33d)][_0x5a4a4c(0x496)],{'min':parseInt(_0x495e21[_0x5a4a4c(0x178)]/0xa)||0x1,'max':parseInt(_0x495e21[_0x5a4a4c(0x178)]+_0x45b93f/0x400)});}}}}_0x495e21[_0x5a4a4c(0x162)]&&(_0x38d59c[_0x5a4a4c(0x33d)][_0x5a4a4c(0x496)]=CodecsHandler[_0x5a4a4c(0x186)](_0x38d59c[_0x5a4a4c(0x33d)]['sdp'],{'maxaveragebitrate':_0x495e21['outboundAudioBitrate']*0x400,'cbr':_0x495e21[_0x5a4a4c(0x209)]}));if('session'in _0x38d59c&&_0x38d59c['session']!=_0x495e21[_0x5a4a4c(0x3fd)][_0x38d59c[_0x5a4a4c(0x12e)]][_0x5a4a4c(0x518)]){errorlog(_0x5a4a4c(0x18e));return;}_0x495e21[_0x5a4a4c(0x3fd)][_0x38d59c[_0x5a4a4c(0x12e)]][_0x5a4a4c(0xd5)](_0x38d59c[_0x5a4a4c(0x33d)])[_0x5a4a4c(0x34d)]()['catch'](errorlog);}catch(_0x533be2){if(_0x5a4a4c(0x4ca)===_0x5a4a4c(0x14c)){function _0x13b684(){return;}}else errorlog(_0x533be2);}else{function _0x2218dc(){var _0x2e3d5a=_0x5a4a4c;if(_0x191036[_0x2e3d5a(0x2f6)]){var _0x3dc170=0x1770;_0x3fae81[_0x2e3d5a(0x15c)]&&(_0x3dc170=_0x3534df(_0x4425f9['value'])),_0x284466(_0x2e3d5a(0x3aa),_0x3dc170);}}}}}},_0x495e21[_0x2a0a0d(0x28b)]=function(_0x11624c){var _0x51eb8c=_0x2a0a0d;_0x495e21[_0x51eb8c(0x211)]&&_0x51eb8c(0x48b)in _0x11624c?_0x495e21['decryptMessage'](_0x11624c[_0x51eb8c(0xf0)],_0x11624c[_0x51eb8c(0x48b)])[_0x51eb8c(0x34d)](function(_0x5ad2da){var _0x5d7f3f=_0x51eb8c;_0x11624c[_0x5d7f3f(0xf0)]=JSON[_0x5d7f3f(0x2b5)](_0x5ad2da),_0x495e21[_0x5d7f3f(0x447)](_0x11624c);}):_0x495e21[_0x51eb8c(0x447)](_0x11624c);},_0x495e21[_0x2a0a0d(0x447)]=function(_0x441d94){var _0x76a6a1=_0x2a0a0d;try{if(_0x495e21[_0x76a6a1(0x400)]){if(_0x441d94[_0x76a6a1(0xf0)][_0x76a6a1(0xf0)][_0x76a6a1(0x37b)](_0x495e21[_0x76a6a1(0x400)])===-0x1){log('dropped\x20candidate\x20due\x20to\x20filter'),log(_0x441d94['candidate']);return;}else log('PASSED'),log(_0x441d94[_0x76a6a1(0xf0)]);}}catch(_0x5d2bc3){errorlog(_0x5d2bc3);}if(_0x441d94[_0x76a6a1(0xf0)]&&'candidate'in _0x441d94['candidate']&&_0x441d94[_0x76a6a1(0xf0)][_0x76a6a1(0xf0)]=='')return;if(_0x441d94[_0x76a6a1(0x12e)]in _0x495e21[_0x76a6a1(0x3fd)]&&_0x441d94['type']==_0x76a6a1(0x240)){if(_0x76a6a1(0x235)===_0x76a6a1(0x235)){log(_0x76a6a1(0x27b));if(!(_0x441d94[_0x76a6a1(0x12e)]in _0x495e21[_0x76a6a1(0x3fd)])){errorlog(_0x76a6a1(0x3c3));return;}if(_0x76a6a1(0x518)in _0x441d94&&_0x495e21[_0x76a6a1(0x3fd)][_0x441d94[_0x76a6a1(0x12e)]][_0x76a6a1(0x518)]!=_0x441d94['session']){errorlog(_0x76a6a1(0x2cd));return;}_0x495e21[_0x76a6a1(0x3fd)][_0x441d94[_0x76a6a1(0x12e)]][_0x76a6a1(0x34e)](_0x441d94[_0x76a6a1(0xf0)])['then']()[_0x76a6a1(0x236)](function(_0x5a378b){errorlog(_0x5a378b),errorlog(_0x441d94);});}else{function _0x5c2469(){return;}}}else{if(_0x441d94[_0x76a6a1(0x12e)]in _0x495e21['rpcs']&&_0x441d94[_0x76a6a1(0x14a)]=='local'){log('RPCS\x20WINS\x20ICE');if(!(_0x441d94['UUID']in _0x495e21['rpcs'])){if(_0x76a6a1(0x1cf)===_0x76a6a1(0x1ff)){function _0x554f38(){var _0xf48f97=_0x76a6a1;return _0x3d2919[_0xf48f97(0x476)]&&_0x386a8f[_0xf48f97(0x476)][_0xf48f97(0x51a)]==_0xf48f97(0x482);}}else{errorlog('ICE\x20target\x20no\x20longer\x20exists?');return;}}if(_0x76a6a1(0x518)in _0x441d94&&_0x495e21[_0x76a6a1(0x3cc)][_0x441d94[_0x76a6a1(0x12e)]][_0x76a6a1(0x518)]!=_0x441d94[_0x76a6a1(0x518)]){errorlog(_0x76a6a1(0x2cd));return;}if(_0x495e21[_0x76a6a1(0x3cc)][_0x441d94[_0x76a6a1(0x12e)]]===null)return;_0x495e21['rpcs'][_0x441d94[_0x76a6a1(0x12e)]][_0x76a6a1(0x34e)](_0x441d94[_0x76a6a1(0xf0)])[_0x76a6a1(0x34d)]()[_0x76a6a1(0x236)](function(_0x5a32b7){errorlog(_0x5a32b7),errorlog(_0x441d94);});}else errorlog(_0x441d94),errorlog(_0x76a6a1(0x44a));}},_0x495e21['processIceBundle']=function(_0x445210){var _0x3951d7=_0x2a0a0d;if(_0x495e21[_0x3951d7(0x211)]&&_0x3951d7(0x48b)in _0x445210)_0x495e21['decryptMessage'](_0x445210['candidates'],_0x445210[_0x3951d7(0x48b)])['then'](function(_0x4be8f4){var _0x47d371=_0x3951d7;_0x445210[_0x47d371(0x117)]=JSON[_0x47d371(0x2b5)](_0x4be8f4);var _0x239484={};_0x239484[_0x47d371(0x12e)]=_0x445210['UUID'],_0x239484[_0x47d371(0x14a)]=_0x445210[_0x47d371(0x14a)];for(var _0x320047=0x0;_0x320047<_0x445210['candidates'][_0x47d371(0xaf)];_0x320047++){_0x239484[_0x47d371(0xf0)]=_0x445210[_0x47d371(0x117)][_0x320047],_0x495e21['processIce2'](_0x239484);}});else{var _0x1d4782={};_0x1d4782['UUID']=_0x445210[_0x3951d7(0x12e)],_0x1d4782[_0x3951d7(0x14a)]=_0x445210[_0x3951d7(0x14a)];for(var _0x24d38a=0x0;_0x24d38a<_0x445210['candidates'][_0x3951d7(0xaf)];_0x24d38a++){_0x1d4782[_0x3951d7(0xf0)]=_0x445210[_0x3951d7(0x117)][_0x24d38a],_0x495e21[_0x3951d7(0x447)](_0x1d4782);}}},_0x495e21['connectPeer']=function(_0x3ea02d){var _0x998212=_0x2a0a0d;_0x495e21[_0x998212(0x3cc)][_0x3ea02d[_0x998212(0x12e)]][_0x998212(0xd5)](_0x3ea02d[_0x998212(0x33d)])['then'](function(){var _0x528808=_0x998212;if(_0x495e21['rpcs'][_0x3ea02d['UUID']][_0x528808(0x13d)][_0x528808(0x14a)]==='offer'){if(_0x528808(0x20c)===_0x528808(0x49a)){function _0xaadb16(){var _0x40dd2b=_0x528808;_0x231c2e[_0x40dd2b(0x3fd)][_0x473535]['keyframerate']=_0x4407e8[_0x40dd2b(0x233)],_0x22ed0a[_0x40dd2b(0x3fd)][_0x36afde][_0x40dd2b(0x233)]&&_0x422ca9(function(){var _0x58f8a3=_0x40dd2b;_0x462297[_0x58f8a3(0x3df)](_0x2cac59);},0x1388);}}else _0x495e21['rpcs'][_0x3ea02d[_0x528808(0x12e)]][_0x528808(0x19a)]()[_0x528808(0x34d)](function(_0x42029d){var _0x5599e7=_0x528808;if(!_0x495e21[_0x5599e7(0x455)]&&_0x495e21[_0x5599e7(0x3a1)]==0x5)_0x42029d[_0x5599e7(0x496)]=CodecsHandler[_0x5599e7(0x186)](_0x42029d[_0x5599e7(0x496)],{'stereo':0x1,'maxaveragebitrate':(_0x495e21['audiobitrate']||0x100)*0x400,'cbr':_0x495e21[_0x5599e7(0x209)],'useinbandfec':0x1,'maxptime':_0x495e21[_0x5599e7(0x382)],'minptime':_0x495e21[_0x5599e7(0x2a1)],'ptime':_0x495e21[_0x5599e7(0x112)]});else{if(_0x495e21[_0x5599e7(0x3a1)]==0x1||_0x495e21[_0x5599e7(0x3a1)]==0x2||_0x495e21[_0x5599e7(0x3a1)]==0x5){if(_0x5599e7(0xd1)!==_0x5599e7(0xd1)){function _0x9eff15(){_0xd20239(_0x5f59a5);}}else _0x42029d[_0x5599e7(0x496)]=CodecsHandler[_0x5599e7(0x186)](_0x42029d[_0x5599e7(0x496)],{'stereo':0x1,'maxaveragebitrate':(_0x495e21[_0x5599e7(0x32a)]||0x100)*0x400,'cbr':_0x495e21[_0x5599e7(0x209)],'useinbandfec':0x1,'maxptime':_0x495e21[_0x5599e7(0x382)],'minptime':_0x495e21[_0x5599e7(0x2a1)],'ptime':_0x495e21[_0x5599e7(0x112)]});}else{if(_0x495e21[_0x5599e7(0x3a1)]==0x4)_0x42029d[_0x5599e7(0x496)]=CodecsHandler[_0x5599e7(0x186)](_0x42029d['sdp'],{'stereo':0x2,'maxaveragebitrate':(_0x495e21['audiobitrate']||0x100)*0x400,'cbr':_0x495e21[_0x5599e7(0x209)],'useinbandfec':0x1,'maxptime':_0x495e21[_0x5599e7(0x382)],'minptime':_0x495e21[_0x5599e7(0x2a1)],'ptime':_0x495e21[_0x5599e7(0x112)]});else _0x495e21[_0x5599e7(0x32a)]&&(_0x42029d[_0x5599e7(0x496)]=CodecsHandler[_0x5599e7(0x186)](_0x42029d['sdp'],{'maxaveragebitrate':_0x495e21['audiobitrate']*0x400,'cbr':_0x495e21[_0x5599e7(0x209)],'useinbandfec':0x1,'maxptime':_0x495e21['maxptime'],'minptime':_0x495e21['minptime'],'ptime':_0x495e21[_0x5599e7(0x112)]}));}}if(_0x495e21[_0x5599e7(0x2e1)]){if(_0x5599e7(0x13e)===_0x5599e7(0x18f)){function _0x20ea02(){var _0x20d64d=_0x5599e7;_0x2622f6[_0x20d64d(0x3cc)][_0x49b469][_0x20d64d(0x2f6)][_0x20d64d(0x3b8)]['display']==_0x20d64d(0x51d)?(_0x2d0eee[_0x20d64d(0x3cc)][_0x4dd256][_0x20d64d(0x10a)]=![],_0x2ffab6[_0x20d64d(0x3cc)][_0xe3506f][_0x20d64d(0x2f6)][_0x20d64d(0x3dd)]=!![]):(_0x12eec2['rpcs'][_0xbc2ba7]['mutedState']=![],_0x5a9317[_0x20d64d(0x3cc)][_0x53d89b][_0x20d64d(0x2f6)][_0x20d64d(0x3dd)]=![]);}}else _0x42029d['sdp']=CodecsHandler[_0x5599e7(0x2e8)](_0x42029d[_0x5599e7(0x496)],_0x495e21[_0x5599e7(0x2e1)]);}_0x495e21[_0x5599e7(0x33f)]&&(log(_0x42029d[_0x5599e7(0x496)]),_0x42029d[_0x5599e7(0x496)]=CodecsHandler[_0x5599e7(0x161)](_0x42029d[_0x5599e7(0x496)]));_0x495e21[_0x5599e7(0x3f5)]&&(_0x42029d[_0x5599e7(0x496)]=CodecsHandler[_0x5599e7(0x24f)](_0x42029d[_0x5599e7(0x496)]));_0x495e21['noREMB']&&(_0x42029d[_0x5599e7(0x496)]=CodecsHandler[_0x5599e7(0x2be)](_0x42029d[_0x5599e7(0x496)]));if(_0x495e21['rpcs'][_0x3ea02d[_0x5599e7(0x12e)]][_0x5599e7(0x304)])log(_0x5599e7(0x1cc)),_0x42029d[_0x5599e7(0x496)]=_0x1d20f9(_0x42029d[_0x5599e7(0x496)],_0x495e21['rpcs'][_0x3ea02d[_0x5599e7(0x12e)]][_0x5599e7(0x304)]);else _0x495e21[_0x5599e7(0x2d0)]&&(log('bit\x20rate\x20being\x20munged'),_0x42029d[_0x5599e7(0x496)]=_0x1d20f9(_0x42029d['sdp'],_0x495e21[_0x5599e7(0x2d0)]));return _0x495e21[_0x5599e7(0x3cc)][_0x3ea02d['UUID']][_0x5599e7(0x11e)](_0x42029d);})[_0x528808(0x34d)](function _0x13213c(){var _0x27ac89=_0x528808;log('providing\x20answer');var _0x2ee908={};_0x2ee908[_0x27ac89(0x12e)]=_0x3ea02d[_0x27ac89(0x12e)],_0x2ee908[_0x27ac89(0x33d)]=_0x495e21['rpcs'][_0x3ea02d[_0x27ac89(0x12e)]][_0x27ac89(0x144)],_0x2ee908['session']=_0x495e21[_0x27ac89(0x3cc)][_0x3ea02d[_0x27ac89(0x12e)]][_0x27ac89(0x518)],_0x495e21[_0x27ac89(0x211)]?_0x495e21[_0x27ac89(0xb3)](JSON[_0x27ac89(0x1e9)](_0x2ee908[_0x27ac89(0x33d)]))[_0x27ac89(0x34d)](function(_0x3a1762){var _0x111ce0=_0x27ac89;_0x2ee908[_0x111ce0(0x33d)]=_0x3a1762[0x0],_0x2ee908[_0x111ce0(0x48b)]=_0x3a1762[0x1],_0x495e21['anyrequest'](_0x2ee908);}):_0x495e21[_0x27ac89(0x11d)](_0x2ee908);})[_0x528808(0x236)](errorlog);}else _0x495e21[_0x528808(0x3cc)][_0x3ea02d[_0x528808(0x12e)]][_0x528808(0x13d)][_0x528808(0x14a)]===_0x528808(0x237)&&errorlog(_0x528808(0x4d2));})['catch'](errorlog);},_0x495e21[_0x2a0a0d(0x391)]=function(_0x3505e1){var _0x4885dd=_0x2a0a0d,_0x8e7547=_0x3505e1['UUID'];if(_0x8e7547 in _0x495e21[_0x4885dd(0x3cc)]){log(_0x4885dd(0x190)),log(_0x3505e1);if(_0x4885dd(0x518)in _0x3505e1){if(_0x495e21[_0x4885dd(0x3cc)][_0x8e7547]['session']==_0x3505e1[_0x4885dd(0x518)]){log(_0x4885dd(0x4cd));return;}else warnlog('SDP\x20Sessions\x20do\x20not\x20match.\x20Do\x20I\x20delete\x20an\x20accept\x20this\x20new\x20SDP?');}}else log(_0x4885dd(0x234));try{for(var _0x3416c7 in _0x495e21['rpcs']){if(_0x495e21[_0x4885dd(0x3cc)][_0x3416c7][_0x4885dd(0x23e)]==_0x3505e1[_0x4885dd(0x23e)]){_0x495e21[_0x4885dd(0x3cc)][_0x3416c7]['videoElement']&&(_0x495e21[_0x4885dd(0x3cc)][_0x3416c7][_0x4885dd(0x2f6)][_0x4885dd(0x3b8)][_0x4885dd(0x443)]='none');_0x495e21[_0x4885dd(0x3cc)][_0x3416c7]=null,delete _0x495e21[_0x4885dd(0x3cc)][_0x3416c7],warnlog(_0x4885dd(0x45b));if(_0x495e21['director'])try{if(_0x4885dd(0x198)!=='bSEkb'){function _0x451158(){_0x2f437f['limitAudioBitrate'](_0x21a895,0x0);}}else document[_0x4885dd(0x2ed)]('container_'+_0x3416c7)&&getById(_0x4885dd(0x321)+_0x3416c7)[_0x4885dd(0x1b7)][_0x4885dd(0x272)](getById(_0x4885dd(0x321)+_0x3416c7));}catch(_0x29143b){errorlog(_0x29143b);}}}document[_0x4885dd(0x2ed)](_0x4885dd(0x1ac))&&document[_0x4885dd(0x2ed)](_0x4885dd(0x1ac))[_0x4885dd(0x1b7)][_0x4885dd(0x272)](document[_0x4885dd(0x2ed)](_0x4885dd(0x1ac)));}catch(_0x5d859d){if('VihCB'!==_0x4885dd(0x196))errorlog(_0x5d859d);else{function _0x261bf1(){var _0x4f1eae=_0x4885dd;if(_0x56243e['keys'](_0x454bba[_0x4f1eae(0x3cc)])[_0x4f1eae(0xaf)]>0x1){_0x4d2860('TOO\x20MANY\x20PUBLISHING\x20PEERS'),_0x162344(_0x1521ad['rpcs']),delete _0x1915d9['rpcs'][_0x7aef],_0x3a9b13();return;}else _0x3519c2(_0x4f1eae(0x30a));}}}if(_0x495e21['maxpublishers']!==![]){if(Object[_0x4885dd(0x31f)](_0x495e21[_0x4885dd(0x3cc)])[_0x4885dd(0xaf)]>=_0x495e21[_0x4885dd(0x28d)]){delete _0x495e21[_0x4885dd(0x3cc)][_0x8e7547],updateUserList(),warnlog(_0x4885dd(0x165));return;}}else{if(_0x495e21[_0x4885dd(0x333)]!==![]){if(Object[_0x4885dd(0x31f)](_0x495e21['rpcs'])['length']+Object[_0x4885dd(0x31f)](_0x495e21[_0x4885dd(0x3fd)])[_0x4885dd(0xaf)]>=_0x495e21[_0x4885dd(0x333)]){delete _0x495e21[_0x4885dd(0x3cc)][_0x8e7547],updateUserList(),warnlog(_0x4885dd(0x165));return;}}}if(_0x495e21[_0x4885dd(0x3f4)]){if(_0x495e21[_0x4885dd(0x455)])!(_0x8e7547 in _0x495e21['pcs'])&&_0x495e21[_0x4885dd(0x38f)](_0x8e7547);else{if(_0x495e21['directorUUID']!==_0x8e7547)return;}}_0x495e21['rpcs'][_0x8e7547]=new RTCPeerConnection(_0x495e21['configuration']);if(_0x495e21[_0x4885dd(0xdd)]){if(Object[_0x4885dd(0x31f)](_0x495e21[_0x4885dd(0x3cc)])[_0x4885dd(0xaf)]>0x1){warnlog(_0x4885dd(0x4aa)),log(_0x495e21[_0x4885dd(0x3cc)]),delete _0x495e21[_0x4885dd(0x3cc)][_0x8e7547],updateUserList();return;}else warnlog(_0x4885dd(0x30a));}_0x3505e1['streamID']in _0x495e21[_0x4885dd(0x268)]&&delete _0x495e21[_0x4885dd(0x268)][_0x3505e1[_0x4885dd(0x23e)]];_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x23e)]=_0x3505e1[_0x4885dd(0x23e)];_0x3505e1[_0x4885dd(0x518)]?_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x518)]=_0x3505e1[_0x4885dd(0x518)]:_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x518)]=null;_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x501)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x502)]={},_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x502)][_0x4885dd(0x149)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x477)]=-0x1,_0x495e21['rpcs'][_0x8e7547][_0x4885dd(0x24c)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x265)]=-0x1,_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x304)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x2f6)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0xe5)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547]['voiceMeter']=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x2b2)]=![],_0x495e21['rpcs'][_0x8e7547][_0x4885dd(0x367)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x193)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0xfb)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x10a)]=null,_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x4dc)]={},_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x1f8)]=![],_0x495e21['rpcs'][_0x8e7547][_0x4885dd(0x33e)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x302)]=null,_0x495e21['rpcs'][_0x8e7547]['directorVolumeState']=0x64,_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x2dd)]=0x0,_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x1ae)]=0x0,_0x495e21['rpcs'][_0x8e7547][_0x4885dd(0x4a9)]=0x0,_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0xab)]=![],_0x495e21['rpcs'][_0x8e7547][_0x4885dd(0x40a)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x293)]=null,_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x342)]=null,_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x403)]={},_0x495e21['rpcs'][_0x8e7547][_0x4885dd(0x15b)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x17f)]=![],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x1c4)]=Date[_0x4885dd(0x42f)]();var _0x4f652b='';_0x495e21['codecGroupFlag']&&(_0x4f652b=_0x495e21[_0x4885dd(0x29c)]);if(_0x495e21[_0x4885dd(0x455)]){var _0x192298='';_0x495e21[_0x4885dd(0xe3)]&&(_0x495e21[_0x4885dd(0xe3)]!==!![]?_0x192298=_0x4885dd(0x3e9)+_0x495e21['pie']:_0x192298=_0x4885dd(0xfd));var _0x55ded6='';_0x495e21[_0x4885dd(0x211)]&&(_0x495e21[_0x4885dd(0x2d8)]===![]&&(_0x55ded6='&password='+_0x495e21[_0x4885dd(0x211)])),createControlBox(_0x8e7547,'https://'+location[_0x4885dd(0x430)]+location[_0x4885dd(0x3f6)]+_0x4885dd(0x50c)+_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x23e)]+'&scene'+_0x4f652b+'&room='+_0x495e21[_0x4885dd(0x3b3)]+_0x55ded6+_0x192298,_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x23e)]);}_0x495e21[_0x4885dd(0x3cc)][_0x8e7547]['UUID']=_0x8e7547;if('streamID'in _0x3505e1){if(_0x4885dd(0x214)!=='EVmCz'){function _0x459b4f(){_0x5e1d8b(),_0x221181();}}else{_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x23e)]=_0x3505e1[_0x4885dd(0x23e)];try{if(_0x495e21[_0x4885dd(0x315)]){if(_0x495e21[_0x4885dd(0x315)][_0x4885dd(0x4a0)](_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x23e)])){if(_0x495e21[_0x4885dd(0x31c)]!==![]){let _0x590997=_0x495e21[_0x4885dd(0x315)][_0x4885dd(0x37b)](_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x23e)]);_0x495e21[_0x4885dd(0x31c)][_0x4885dd(0xaf)]>_0x590997&&(_0x495e21[_0x4885dd(0x3cc)][_0x8e7547]['manualBandwidth']=parseInt(_0x495e21['bitrate_set'][_0x590997]),_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x304)]<=0x0&&(_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x304)]=![]));}}}}catch(_0x43227e){errorlog(_0x43227e);}}}_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x2c8)]=function(_0x5c1f46){var _0x1c5ec7=_0x4885dd;try{var _0x1f94e2=this[_0x1c5ec7(0x23e)];}catch(_0x554bd6){}if(!_0x495e21[_0x1c5ec7(0x455)]){if(_0x495e21['scene']!==![]||_0x495e21[_0x1c5ec7(0x3b3)]!==![])try{_0x495e21[_0x1c5ec7(0x3cc)][this['UUID']][_0x1c5ec7(0x2f6)]&&(_0x495e21[_0x1c5ec7(0x3cc)][this[_0x1c5ec7(0x12e)]][_0x1c5ec7(0x2f6)]['style'][_0x1c5ec7(0x443)]='none'),setTimeout(function(){updateMixer();},0x1);}catch(_0x433b92){}}try{document[_0x1c5ec7(0x2ed)](_0x1c5ec7(0x321)+this[_0x1c5ec7(0x12e)])&&getById(_0x1c5ec7(0x321)+this[_0x1c5ec7(0x12e)])[_0x1c5ec7(0x1b7)][_0x1c5ec7(0x272)](getById(_0x1c5ec7(0x321)+this[_0x1c5ec7(0x12e)]));}catch(_0x26b677){errorlog(_0x26b677);}try{this[_0x1c5ec7(0x302)]&&this[_0x1c5ec7(0x302)][_0x1c5ec7(0x509)]()[_0x1c5ec7(0x415)](function(_0x342199){var _0x2dd01f=_0x1c5ec7;if(_0x2dd01f(0xbd)===_0x2dd01f(0xbd))_0x342199[_0x2dd01f(0x2de)]();else{function _0x270c1c(){var _0x9b2d5f=_0x2dd01f,_0x2aa0dc=_0x2a0296[_0x9b2d5f(0x91)](_0x9b2d5f(0x3a0)+_0x56691f+'\x22]');_0x2aa0dc[0x0]&&(_0x2aa0dc[0x0]['value']=_0x38a6a2,_0x48ce0f[_0x9b2d5f(0x3cc)][_0x198861]['directorVolumeState']=_0x4f08c2,_0x2f1cf6(_0x2aa0dc[0x0]));}}});}catch(_0x2cdd40){errorlog(_0x2cdd40);}try{this['receiveChannel']['close']();}catch(_0x2b6c76){errorlog(_0x2b6c76);}try{_0x495e21[_0x1c5ec7(0x3cc)][this[_0x1c5ec7(0x12e)]]=null,delete _0x495e21[_0x1c5ec7(0x3cc)][this['UUID']];}catch(_0xa8fbcf){errorlog(_0xa8fbcf);}warnlog(_0x1c5ec7(0x45b));try{_0x495e21['watchStream'](_0x1f94e2);}catch(_0x39cebf){errorlog('Couldn\x27t\x20re-connect'),errorlog(_0x39cebf);}updateUserList();},_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x25a)]=null,_0x495e21['rpcs'][_0x8e7547][_0x4885dd(0x3c1)]=[],_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x279)]=function(_0x425032){var _0x4d7ac3=_0x4885dd;if(_0x425032['candidate']==null){log(_0x4d7ac3(0x163));return;}try{if(_0x495e21[_0x4d7ac3(0x400)]){if(_0x425032[_0x4d7ac3(0xf0)][_0x4d7ac3(0xf0)][_0x4d7ac3(0x37b)](_0x495e21[_0x4d7ac3(0x400)])===-0x1){log(_0x4d7ac3(0x451));return;}else log(_0x425032['candidate']);}}catch(_0x532810){errorlog(_0x532810);}if(_0x495e21[_0x4d7ac3(0x3cc)][_0x8e7547][_0x4d7ac3(0x25a)]!==null){_0x495e21[_0x4d7ac3(0x3cc)][_0x8e7547]['iceBundle'][_0x4d7ac3(0x17e)](_0x425032[_0x4d7ac3(0xf0)]);return;}_0x495e21['rpcs'][_0x8e7547][_0x4d7ac3(0x3c1)][_0x4d7ac3(0x17e)](_0x425032[_0x4d7ac3(0xf0)]),_0x495e21[_0x4d7ac3(0x3cc)][_0x8e7547][_0x4d7ac3(0x25a)]=setTimeout(function(){var _0x3ccd88=_0x4d7ac3;if(!(_0x8e7547 in _0x495e21['rpcs']))return;_0x495e21[_0x3ccd88(0x3cc)][_0x8e7547][_0x3ccd88(0x25a)]=null;if(_0x495e21['rpcs'][_0x8e7547][_0x3ccd88(0x3c1)]==[])return;var _0x14ac00={};_0x14ac00[_0x3ccd88(0x12e)]=_0x8e7547,_0x14ac00[_0x3ccd88(0x14a)]=_0x3ccd88(0x240),_0x14ac00[_0x3ccd88(0x117)]=_0x495e21[_0x3ccd88(0x3cc)][_0x8e7547]['iceBundle'],_0x14ac00['session']=_0x495e21[_0x3ccd88(0x3cc)][_0x8e7547][_0x3ccd88(0x518)],_0x495e21['rpcs'][_0x8e7547]['iceBundle']=[],_0x495e21[_0x3ccd88(0x211)]?_0x495e21[_0x3ccd88(0xb3)](JSON['stringify'](_0x14ac00[_0x3ccd88(0x117)]))[_0x3ccd88(0x34d)](function(_0x12c86f){var _0x506211=_0x3ccd88;_0x14ac00['candidates']=_0x12c86f[0x0],_0x14ac00[_0x506211(0x48b)]=_0x12c86f[0x1],_0x495e21[_0x506211(0x11d)](_0x14ac00);}):_0x495e21[_0x3ccd88(0x11d)](_0x14ac00);},0x190);},_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x49f)]=function(_0x43b821){var _0x3cbd0a=_0x4885dd;if(_0x3cbd0a(0x141)!==_0x3cbd0a(0x141)){function _0x5e0d48(){var _0x1a0b45=_0x3cbd0a;_0x191173['pcs'][_0x3f30b2][_0x1a0b45(0x3be)]===![]?_0x5ca3b8[_0x1a0b45(0x3bb)](_0x49e12f,0x0):_0x590769[_0x1a0b45(0x3bb)](_0x19e0d3,-0x1);}}else switch(this[_0x3cbd0a(0x3cd)]){case _0x3cbd0a(0x361):log(_0x3cbd0a(0x361));case _0x3cbd0a(0x2d4):log(_0x3cbd0a(0x2d4));case'connected':log(_0x3cbd0a(0x418));if(_0x495e21[_0x3cbd0a(0xdd)]){if(_0x495e21['ws'][_0x3cbd0a(0x454)]!==0x1){_0x495e21['ws']['close']();break;}_0x495e21['ws'][_0x3cbd0a(0x229)](),setTimeout(function(){var _0x1ac60f=_0x3cbd0a;_0x495e21[_0x1ac60f(0xe9)]!=!![]&&warnUser(_0x1ac60f(0x1a4));},0x1);}break;case _0x3cbd0a(0x406):warnlog(_0x3cbd0a(0x2da));break;case _0x3cbd0a(0x204):warnlog(_0x3cbd0a(0x11b));try{var _0x4040b8=this[_0x3cbd0a(0x23e)];}catch(_0x5afa78){}try{this[_0x3cbd0a(0x302)]&&this[_0x3cbd0a(0x302)][_0x3cbd0a(0x509)]()[_0x3cbd0a(0x415)](function(_0x419a64){var _0x5378c1=_0x3cbd0a;_0x419a64[_0x5378c1(0x2de)](),log(_0x5378c1(0x1ed));});}catch(_0x5b7bbb){warnlog(_0x5b7bbb);}if(_0x495e21[_0x3cbd0a(0x455)])try{_0x3cbd0a(0x158)in _0x495e21[_0x3cbd0a(0x3cc)][this[_0x3cbd0a(0x12e)]][_0x3cbd0a(0x2f6)]&&_0x495e21['rpcs'][this[_0x3cbd0a(0x12e)]][_0x3cbd0a(0x2f6)][_0x3cbd0a(0x158)][_0x3cbd0a(0x2de)]();}catch(_0x5e68e9){warnlog(_0x5e68e9);}try{document[_0x3cbd0a(0x2ed)](_0x3cbd0a(0x321)+this[_0x3cbd0a(0x12e)])&&getById('container_'+this[_0x3cbd0a(0x12e)])[_0x3cbd0a(0x1b7)][_0x3cbd0a(0x272)](getById('container_'+this[_0x3cbd0a(0x12e)]));}catch(_0x4e348d){warnlog(_0x4e348d);}_0x495e21[_0x3cbd0a(0x3cc)][this[_0x3cbd0a(0x12e)]][_0x3cbd0a(0x229)](),_0x495e21[_0x3cbd0a(0x3cc)][this[_0x3cbd0a(0x12e)]]=null,delete _0x495e21[_0x3cbd0a(0x3cc)][this[_0x3cbd0a(0x12e)]];!_0x495e21['director']&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x4040b8==_0x3cbd0a(0x51f))break;try{warnlog(_0x3cbd0a(0x3f7));if(_0x4040b8 in _0x495e21[_0x3cbd0a(0x27d)]){if(_0x3cbd0a(0x36a)===_0x3cbd0a(0xb9)){function _0x1b6f47(){var _0x15d72a=_0x3cbd0a;try{_0x501d3d(_0x1b654d),_0x25e196[_0x15d72a(0x392)](_0x360680[_0x15d72a(0x12e)],_0x36da8d[_0x15d72a(0x4a6)]['w'],_0x152567[_0x15d72a(0x4a6)]['h']);}catch(_0x4d2a39){_0x841e7e(_0x4d2a39);}}}else clearTimeout(_0x495e21[_0x3cbd0a(0x27d)][_0x4040b8]);}_0x495e21[_0x3cbd0a(0x27d)][_0x4040b8]=setTimeout(function(_0x163d9c){var _0x2c6e83=_0x3cbd0a;delete _0x495e21[_0x2c6e83(0x27d)][_0x163d9c],_0x495e21[_0x2c6e83(0x3f0)](_0x163d9c);},_0x495e21[_0x3cbd0a(0x23a)],_0x4040b8);}catch(_0x48bf0d){errorlog(_0x48bf0d);}break;case _0x3cbd0a(0x4ee):warnlog('RTC\x20closed');try{var _0x4040b8=this['streamID'];}catch(_0x339c2b){};try{this[_0x3cbd0a(0x302)]&&this[_0x3cbd0a(0x302)][_0x3cbd0a(0x509)]()[_0x3cbd0a(0x415)](function(_0x3c1c77){var _0x4ba426=_0x3cbd0a;_0x3c1c77[_0x4ba426(0x2de)](),log('Track\x20stopped');});}catch(_0x54311f){}if(_0x495e21[_0x3cbd0a(0x455)])try{'recorder'in _0x495e21[_0x3cbd0a(0x3cc)][this[_0x3cbd0a(0x12e)]]['videoElement']&&_0x495e21[_0x3cbd0a(0x3cc)][this[_0x3cbd0a(0x12e)]]['videoElement'][_0x3cbd0a(0x158)][_0x3cbd0a(0x2de)]();}catch(_0x258f85){errorlog(_0x258f85);}try{document[_0x3cbd0a(0x2ed)](_0x3cbd0a(0x321)+this[_0x3cbd0a(0x12e)])&&getById(_0x3cbd0a(0x321)+this['UUID'])['parentNode']['removeChild'](getById(_0x3cbd0a(0x321)+this[_0x3cbd0a(0x12e)]));}catch(_0x3daa75){errorlog(_0x3daa75);}_0x495e21[_0x3cbd0a(0x3cc)][this['UUID']][_0x3cbd0a(0x229)](),_0x495e21['rpcs'][this[_0x3cbd0a(0x12e)]]=null,delete _0x495e21[_0x3cbd0a(0x3cc)][this[_0x3cbd0a(0x12e)]];!_0x495e21[_0x3cbd0a(0x455)]&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x4040b8=='undefined')break;try{errorlog(_0x3cbd0a(0x22e)),_0x4040b8 in _0x495e21[_0x3cbd0a(0x27d)]&&clearTimeout(_0x495e21['watchTimeoutList'][_0x4040b8]),_0x495e21[_0x3cbd0a(0x27d)][_0x4040b8]=setTimeout(function(_0x1975c5){var _0x2bd279=_0x3cbd0a;delete _0x495e21[_0x2bd279(0x27d)][_0x1975c5],_0x495e21['watchStream'](_0x1975c5);},_0x495e21[_0x3cbd0a(0x23a)],_0x4040b8);}catch(_0x3a0416){errorlog(_0x3a0416);}break;}},_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x1e4)]=function(){var _0x2b3495=_0x4885dd;try{if(this[_0x2b3495(0x1bc)]==_0x2b3495(0x4ee))errorlog(_0x2b3495(0x1be));else{if(this[_0x2b3495(0x1bc)]==_0x2b3495(0x406))warnlog('ICE\x20DISCONNECTED'),_0x495e21['rpcs'][_0x8e7547][_0x2b3495(0x2f6)]['style'][_0x2b3495(0x3dc)]='0',_0x495e21[_0x2b3495(0x3cc)][_0x8e7547][_0x2b3495(0xef)]=setTimeout(function(_0x11f019){updateMixer();},0x1f4,_0x8e7547);else this[_0x2b3495(0x1bc)]==_0x2b3495(0x204)?errorlog('ICE\x20FAILED'):(log(_0x2b3495(0x1b1)+this[_0x2b3495(0x1bc)]),_0x2b3495(0x3dc)in _0x495e21[_0x2b3495(0x3cc)][_0x8e7547][_0x2b3495(0x2f6)][_0x2b3495(0x3b8)]?_0x495e21[_0x2b3495(0x3cc)][_0x8e7547][_0x2b3495(0x2f6)][_0x2b3495(0x3b8)][_0x2b3495(0x3dc)]=='0'&&(_0x495e21[_0x2b3495(0x3cc)][_0x8e7547]['videoElement'][_0x2b3495(0x3b8)][_0x2b3495(0x3dc)]='1',updateMixer()):_0x495e21[_0x2b3495(0x3cc)][_0x8e7547][_0x2b3495(0x2f6)][_0x2b3495(0x3b8)][_0x2b3495(0x3dc)]='1',_0x495e21[_0x2b3495(0x3cc)][_0x8e7547][_0x2b3495(0xef)]&&clearTimeout(_0x495e21[_0x2b3495(0x3cc)][_0x8e7547][_0x2b3495(0xef)]));}}catch(_0x156599){}},_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x259)]=function(_0x2ca0a6){var _0x3ace6a=_0x4885dd;_0x495e21[_0x3ace6a(0x3cc)][_0x8e7547][_0x3ace6a(0xd3)]=_0x2ca0a6[_0x3ace6a(0x25b)],_0x495e21[_0x3ace6a(0x3cc)][_0x8e7547]['receiveChannel'][_0x3ace6a(0x12e)]=_0x8e7547,_0x495e21[_0x3ace6a(0x3cc)][_0x8e7547][_0x3ace6a(0xd3)][_0x3ace6a(0x13c)]=_0x1b7fe9=>{var _0x1fe3e4=_0x3ace6a,_0x1c4d5d={};_0x1c4d5d[_0x1fe3e4(0x41e)]=![];if(_0x495e21['novideo']!==![])_0x495e21[_0x1fe3e4(0x4e1)]['includes'](_0x495e21[_0x1fe3e4(0x3cc)][_0x8e7547][_0x1fe3e4(0x23e)])?_0x1c4d5d[_0x1fe3e4(0x482)]=!![]:_0x1c4d5d[_0x1fe3e4(0x482)]=![];else{if(_0x495e21['broadcast']!==![]){if(_0x495e21['broadcast']!==null)_0x495e21[_0x1fe3e4(0x3cc)][_0x8e7547][_0x1fe3e4(0x23e)]===_0x495e21[_0x1fe3e4(0x41e)]?_0x495e21[_0x1fe3e4(0x27f)]?(_0x1c4d5d[_0x1fe3e4(0x41e)]=!![],_0x1c4d5d['video']=![]):_0x1c4d5d[_0x1fe3e4(0x482)]=!![]:_0x1c4d5d['video']=![];else _0x495e21[_0x1fe3e4(0x389)]&&(_0x8e7547==_0x495e21[_0x1fe3e4(0x389)]?_0x495e21[_0x1fe3e4(0x27f)]?(_0x1c4d5d[_0x1fe3e4(0x482)]=![],_0x1c4d5d[_0x1fe3e4(0x41e)]=!![]):_0x1c4d5d[_0x1fe3e4(0x482)]=!![]:_0x1c4d5d[_0x1fe3e4(0x482)]=![]);}else _0x495e21['exclude']!==![]?_0x495e21[_0x1fe3e4(0x335)][_0x1fe3e4(0x4a0)](_0x495e21[_0x1fe3e4(0x3cc)][_0x8e7547][_0x1fe3e4(0x23e)])?_0x1c4d5d['video']=![]:_0x1c4d5d[_0x1fe3e4(0x482)]=!![]:_0x1c4d5d[_0x1fe3e4(0x482)]=!![];}_0x495e21[_0x1fe3e4(0x48a)]&&(_0x1c4d5d[_0x1fe3e4(0x243)]=_0x495e21[_0x1fe3e4(0x48a)]);try{_0x1c4d5d[_0x1fe3e4(0x191)]={},_0x1c4d5d['info'][_0x1fe3e4(0xab)]=_0x495e21[_0x1fe3e4(0xab)],_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0x40a)]=_0x495e21[_0x1fe3e4(0x40a)],_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0xc9)]=_0x495e21[_0x1fe3e4(0x3a1)],_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0x46f)]=_0x495e21[_0x1fe3e4(0x2d0)],_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0x217)]=_0x495e21[_0x1fe3e4(0x32a)],_0x1c4d5d[_0x1fe3e4(0x191)]['codec_url']=_0x495e21[_0x1fe3e4(0x2e1)],_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0x105)]=_0x495e21[_0x1fe3e4(0x105)],_0x1c4d5d['info'][_0x1fe3e4(0x3d5)]=_0x495e21[_0x1fe3e4(0x3d5)],_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0x4af)]=_0x495e21[_0x1fe3e4(0x175)],_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0x112)]=_0x495e21[_0x1fe3e4(0x112)],_0x1c4d5d['info'][_0x1fe3e4(0x2a1)]=_0x495e21['minptime'],_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0x382)]=_0x495e21[_0x1fe3e4(0x382)];if(navigator[_0x1fe3e4(0x119)]){if('ZqfjV'===_0x1fe3e4(0x4e9)){function _0x104e73(){var _0x5ba010=_0x1fe3e4;_0x9efd1d['rpcs'][_0x43bd85][_0x5ba010(0x2f6)][_0x5ba010(0x3b8)][_0x5ba010(0x443)]&&_0x484425['rpcs'][_0x9b042d][_0x5ba010(0x2f6)][_0x5ba010(0x3b8)][_0x5ba010(0x443)]!==_0x5ba010(0x51d)&&(_0x437a7d[_0x5ba010(0x3cc)][_0x30d05c][_0x5ba010(0x2f6)][_0x5ba010(0x3b8)][_0x5ba010(0x443)]=_0x5ba010(0x51d),_0x27ad23=!![]),_0x39ec61['rpcs'][_0x748532][_0x5ba010(0x2f6)][_0x5ba010(0x3dd)]=!![];}}else{var _0x401657,_0x409830=navigator[_0x1fe3e4(0x119)];_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0xec)]=_0x409830;}}navigator[_0x1fe3e4(0x2e7)]&&(_0x1c4d5d[_0x1fe3e4(0x191)][_0x1fe3e4(0x2e7)]=navigator['platform']);if(window[_0x1fe3e4(0x2dc)]){_0x1c4d5d['info'][_0x1fe3e4(0x230)]=window[_0x1fe3e4(0x2dc)]['pluginVersion'];if(_0x495e21[_0x1fe3e4(0x278)]){var _0x5e5078=![];_0x495e21[_0x1fe3e4(0x278)][_0x1fe3e4(0xdb)]!==null&&(_0x1c4d5d[_0x1fe3e4(0x3be)]=_0x495e21['obsState'][_0x1fe3e4(0xdb)],_0x495e21[_0x1fe3e4(0x278)][_0x1fe3e4(0xdb)]===![]&&(_0x5e5078=!![])),_0x495e21[_0x1fe3e4(0x278)][_0x1fe3e4(0x498)]!==null&&(_0x1c4d5d[_0x1fe3e4(0x35a)]=_0x495e21[_0x1fe3e4(0x278)]['sourceActive']),_0x495e21[_0x1fe3e4(0x278)][_0x1fe3e4(0x256)]!==null&&(_0x1c4d5d['obsRecording']=_0x495e21[_0x1fe3e4(0x278)]['recording']),_0x495e21[_0x1fe3e4(0x278)][_0x1fe3e4(0x12f)]!==null&&(_0x1c4d5d['obsStreaming']=_0x495e21[_0x1fe3e4(0x278)]['streaming']);}_0x495e21[_0x1fe3e4(0x42c)]!==![]&&(_0x1c4d5d[_0x1fe3e4(0xdc)]=parseInt(_0x495e21[_0x1fe3e4(0x42c)]),_0x5e5078&&(_0x495e21['rpcs'][_0x8e7547][_0x1fe3e4(0x477)]=_0x1c4d5d[_0x1fe3e4(0xdc)]));}else{if(_0x1fe3e4(0x4ce)===_0x1fe3e4(0x470)){function _0x48b655(){_0x186777=_0x12ade0;}}else _0x1c4d5d[_0x1fe3e4(0x191)]['obs']=![];}}catch(_0x420417){};_0x495e21[_0x1fe3e4(0x3fa)]!==![]?_0x495e21['noaudio'][_0x1fe3e4(0x4a0)](_0x495e21['rpcs'][_0x8e7547][_0x1fe3e4(0x23e)])?_0x1c4d5d[_0x1fe3e4(0x295)]=!![]:_0x1c4d5d[_0x1fe3e4(0x295)]=![]:_0x1c4d5d[_0x1fe3e4(0x295)]=!![];_0x1c4d5d[_0x1fe3e4(0x19c)]=![];if(_0x495e21[_0x1fe3e4(0x513)]!==![]){if(_0x1fe3e4(0xa4)!==_0x1fe3e4(0x349)){if(_0x495e21['noiframe'][_0x1fe3e4(0x4a0)](_0x495e21[_0x1fe3e4(0x3cc)][_0x8e7547]['streamID']))_0x1c4d5d[_0x1fe3e4(0x19c)]=!![];else{if(_0x1fe3e4(0x314)!==_0x1fe3e4(0x23f))_0x1c4d5d[_0x1fe3e4(0x19c)]=![];else{function _0x3c8ee9(){var _0x4ae452=_0x1fe3e4,_0x5657e5={};_0x5657e5[_0x4ae452(0x316)]=_0x489037,_0x218055(_0x5657e5),_0x3c6468[_0x4ae452(0x166)](_0x5657e5,_0x2cc98d);}}}}else{function _0x36c965(){var _0xa43fbe=_0x1fe3e4;_0x35d474[_0xa43fbe(0x3f0)](_0x45e804);}}}else _0x1c4d5d[_0x1fe3e4(0x19c)]=!![];_0x1c4d5d[_0x1fe3e4(0x438)]=![],_0x1c4d5d[_0x1fe3e4(0x44c)]=![],_0x1c4d5d[_0x1fe3e4(0x455)]=![],_0x1c4d5d[_0x1fe3e4(0x233)]=_0x495e21[_0x1fe3e4(0x233)],_0x1c4d5d[_0x1fe3e4(0x47c)]=![],_0x1c4d5d[_0x1fe3e4(0x297)]=![],_0x1c4d5d[_0x1fe3e4(0x3d5)]=![];_0x495e21[_0x1fe3e4(0x175)]&&(_0x1c4d5d[_0x1fe3e4(0x47c)]=!![]);if(_0x495e21['director']){if(_0x1fe3e4(0x44b)===_0x1fe3e4(0x44b))_0x1c4d5d[_0x1fe3e4(0x455)]=!![],_0x1c4d5d[_0x1fe3e4(0x3d5)]=_0x495e21['forceios'];else{function _0x206af7(){var _0x5660ba=_0x1fe3e4;_0x367bd7[_0x5660ba(0x41e)]=!![],_0x1e5efa[_0x5660ba(0x482)]=![];}}}else{if(_0x495e21[_0x1fe3e4(0x44c)]!==![])_0x1c4d5d[_0x1fe3e4(0x44c)]=_0x495e21[_0x1fe3e4(0x44c)];else _0x495e21[_0x1fe3e4(0x3b3)]!==![]&&_0x495e21[_0x1fe3e4(0x3b3)]!==''&&(_0x1c4d5d['forceios']=_0x495e21['forceios'],_0x1c4d5d[_0x1fe3e4(0x438)]=!![]);}_0x495e21['sendRequest'](_0x1c4d5d,_0x8e7547)?log(_0x1fe3e4(0x16f)):errorlog(_0x1fe3e4(0x517)),pokeIframeAPI('new-view-connection',!![],_0x8e7547);},_0x495e21[_0x3ace6a(0x3cc)][_0x8e7547][_0x3ace6a(0xd3)][_0x3ace6a(0x16d)]=_0x463807=>{var _0x7e2827=_0x3ace6a;if(typeof _0x463807[_0x7e2827(0x488)]==_0x7e2827(0x169)){if(!_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)])_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)]=document[_0x7e2827(0x359)]('img'),_0x495e21['rpcs'][_0x8e7547]['imageElement']['width']=0x10,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)][_0x7e2827(0x306)]=0x9,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)]['dataset'][_0x7e2827(0x12e)]=_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)][_0x7e2827(0x20e)]=![],_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)]['addEventListener']('click',function(_0x31c202){var _0x49bdea=_0x7e2827;log('clicked');try{if(_0x31c202[_0x49bdea(0xee)]||_0x31c202[_0x49bdea(0xf7)]){if(_0x49bdea(0x409)!==_0x49bdea(0x409)){function _0xdf6642(){var _0x293d87=_0x49bdea;if(_0x177e83[_0x293d87(0x23e)]===_0x19b55f['streamID'])_0x4cf02e[_0x293d87(0x317)]=_0x293d87(0x38f);else return;}}else{_0x31c202[_0x49bdea(0x3cb)]();var _0x46a14e=_0x31c202[_0x49bdea(0x269)][_0x49bdea(0x2a3)][_0x49bdea(0x12e)];if('stats'in _0x495e21['rpcs'][_0x46a14e]){var [_0xd68957,_0x2c5f81]=statsMenuCreator();printViewStats(_0x2c5f81,_0x46a14e),_0xd68957[_0x49bdea(0x294)]=setInterval(printViewStats,0xbb8,_0x2c5f81,_0x46a14e);}return _0x31c202['stopPropagation'](),![];}}}catch(_0x5c5c4a){errorlog(_0x5c5c4a);}}),updateMixer();else _0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['imageElement'][_0x7e2827(0x20e)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)][_0x7e2827(0x20e)]=![],_0x495e21['rpcs'][_0x8e7547]['imageElement'][_0x7e2827(0x3b8)][_0x7e2827(0xdb)]=_0x7e2827(0x2f4));_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)]['src']=window[_0x7e2827(0x3e7)][_0x7e2827(0x369)](new Blob([new Uint8Array(_0x463807[_0x7e2827(0x488)])],{'type':_0x7e2827(0x341)}));return;}var _0x4e1729=JSON[_0x7e2827(0x2b5)](_0x463807[_0x7e2827(0x488)]);_0x4e1729[_0x7e2827(0x12e)]=_0x8e7547;var _0x16fa32=![],_0x49c183=![];_0x7e2827(0x3a5)in _0x4e1729&&(_0x495e21['director']&&(!(_0x495e21['cleanOutput']||_0x495e21[_0x7e2827(0x2a7)])&&warnUser(_0x7e2827(0x38e),0x1388)),errorlog('ACTION\x20REJECTED:\x20'+_0x4e1729[_0x7e2827(0x3a5)]+_0x7e2827(0x1c1)+_0x495e21[_0x7e2827(0x455)]));if(_0x7e2827(0x33d)in _0x4e1729)_0x495e21[_0x7e2827(0x2ae)](_0x4e1729);else{if('candidate'in _0x4e1729)_0x4e1729['UUID']=_0x8e7547,log(_0x7e2827(0x3e1)),_0x495e21['processIce'](_0x4e1729);else{if(_0x7e2827(0x117)in _0x4e1729)_0x4e1729[_0x7e2827(0x12e)]=_0x8e7547,log(_0x7e2827(0x1ca)),_0x495e21[_0x7e2827(0x248)](_0x4e1729);else{if(_0x7e2827(0x15b)in _0x4e1729)try{_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x15b)]=_0x4e1729[_0x7e2827(0x15b)]||![];if(_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x15b)]==![]){_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)]=![],_0x16fa32=!![];if(_0x495e21[_0x7e2827(0x41e)]!==![]){if(_0x495e21[_0x7e2827(0x41e)]!==null)_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)]===_0x495e21[_0x7e2827(0x41e)]&&(_0x495e21[_0x7e2827(0x4f2)]=![]);else{if(_0x8e7547==_0x495e21[_0x7e2827(0x389)]){if(_0x7e2827(0x159)===_0x7e2827(0x159))_0x495e21['broadcastIFrame']=![];else{function _0x49292c(){var _0xfd9cce=_0x7e2827,_0x572c9a=_0x4499b7[_0xfd9cce(0x42f)]()-_0x45b1c6[_0xfd9cce(0x3fd)][_0x54cdf3]['startTime'];_0x572c9a<_0x378081[_0xfd9cce(0x3a7)]&&(_0x565fde=0x23,_0x596e06[_0xfd9cce(0x3fd)][_0x2b8b84][_0xfd9cce(0x3ec)]=_0x56b0ac(function(_0x4b7940){var _0x5d9860=_0xfd9cce;_0x4dd819[_0x5d9860(0x2cb)](_0x4b7940,null);},_0x572c9a,_0x5579ad));}}}}}}else{if(_0x495e21[_0x7e2827(0x41e)]!==![]){if(_0x495e21[_0x7e2827(0x41e)]!==null){if(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['streamID']===_0x495e21[_0x7e2827(0x41e)]){if(_0x495e21[_0x7e2827(0x513)]===![]){_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)]=loadIframe(_0x4e1729[_0x7e2827(0x15b)]),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)]['id']=_0x7e2827(0x4c6)+_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)][_0x7e2827(0x2a3)][_0x7e2827(0x12e)]=_0x8e7547,_0x16fa32=!![],_0x495e21[_0x7e2827(0x4f2)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)];if(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['streamID']){if(_0x7e2827(0x3b9)===_0x7e2827(0xaa)){function _0x3cf625(){var _0x502037=_0x7e2827;_0x581b7c(_0x5d5e4f,_0x42328a[_0x502037(0x158)]);}}else _0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)][_0x7e2827(0x2a3)][_0x7e2827(0x3ee)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)];}}else{if(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)]in _0x495e21[_0x7e2827(0x513)]){if('LXKdD'==='LXKdD'){_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x17f)]=loadIframe(_0x4e1729[_0x7e2827(0x15b)]),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)]['id']=_0x7e2827(0x4c6)+_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['iframeEle']['dataset'][_0x7e2827(0x12e)]=_0x8e7547,_0x16fa32=!![],_0x495e21[_0x7e2827(0x4f2)]=_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x17f)];if(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)]){if(_0x7e2827(0x3c0)===_0x7e2827(0x3c0))_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)][_0x7e2827(0x2a3)][_0x7e2827(0x3ee)]=_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x23e)];else{function _0x11de40(){var _0x5190dd=_0x7e2827;_0x22c4db[_0x5190dd(0x15d)](_0x2116b4),_0x593b53[_0x5190dd(0x3cc)][_0x168d2b][_0x5190dd(0x502)][_0xedbab9[_0x5190dd(0x1eb)]][_0x5190dd(0x27a)]=0x0,_0x5be0f1(_0x5190dd(0x277));}}}}else{function _0x222e5e(){var _0x433091=_0x7e2827;_0x1db257[_0x433091(0x3cc)][_0x59dec3][_0x433091(0x244)]=!![];}}}}}}else{if(_0x495e21['directorUUID']){if(_0x8e7547==_0x495e21[_0x7e2827(0x389)]){if(_0x495e21[_0x7e2827(0x513)]===![])_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)]=loadIframe(_0x4e1729[_0x7e2827(0x15b)]),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)]['id']='iframe_'+_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)][_0x7e2827(0x2a3)][_0x7e2827(0x12e)]=_0x8e7547,_0x16fa32=!![],_0x495e21[_0x7e2827(0x4f2)]=_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x17f)],_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x23e)]&&(_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x17f)][_0x7e2827(0x2a3)][_0x7e2827(0x3ee)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)]);else _0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)]in _0x495e21[_0x7e2827(0x513)]&&(_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x17f)]=loadIframe(_0x4e1729[_0x7e2827(0x15b)]),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['iframeEle']['id']=_0x7e2827(0x4c6)+_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['iframeEle'][_0x7e2827(0x2a3)][_0x7e2827(0x12e)]=_0x8e7547,_0x16fa32=!![],_0x495e21[_0x7e2827(0x4f2)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)],_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['iframeEle']['dataset'][_0x7e2827(0x3ee)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['streamID']));}}}}else{if(_0x495e21[_0x7e2827(0x513)]===![]){_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)]=loadIframe(_0x4e1729[_0x7e2827(0x15b)]),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['iframeEle']['id']=_0x7e2827(0x4c6)+_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)][_0x7e2827(0x2a3)][_0x7e2827(0x12e)]=_0x8e7547,_0x16fa32=!![];if(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['streamID']){if('nUHDT'!==_0x7e2827(0xc8)){function _0x8369de(){var _0x1ad2f7=_0x7e2827,_0x5cd73d=_0x201b59[0x0];_0x5cd73d['label']!='MediaStreamAudioDestinationNode'&&(_0x100ee0['rpcs'][_0x4faa8f][_0x1ad2f7(0x2f6)][_0x1ad2f7(0x1e8)]=_0x4eafa5(_0x52dd68[_0x1ad2f7(0x3cc)][_0x48c2bb][_0x1ad2f7(0x302)],_0x1178e2,_0x5cd73d));}}else _0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x17f)][_0x7e2827(0x2a3)][_0x7e2827(0x3ee)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)];}}else _0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)]in _0x495e21[_0x7e2827(0x513)]&&(_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x17f)]=loadIframe(_0x4e1729[_0x7e2827(0x15b)]),_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x17f)]['id']=_0x7e2827(0x4c6)+_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)]['dataset'][_0x7e2827(0x12e)]=_0x8e7547,_0x16fa32=!![],_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x23e)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x17f)][_0x7e2827(0x2a3)][_0x7e2827(0x3ee)]=_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x23e)]));}}}catch(_0x11e012){errorlog(_0x11e012);}}}}if('chat'in _0x4e1729){var _0x80b316=![],_0x1d5f21=![];if(_0x495e21[_0x7e2827(0x389)]===_0x8e7547){_0x80b316=!![];if(_0x7e2827(0x3e3)in _0x4e1729){if('XgeCK'!==_0x7e2827(0x336)){function _0x5a1ddc(){_0x4fd952=0x0;}}else _0x4e1729[_0x7e2827(0x3e3)]==!![]&&(_0x1d5f21=!![]);}}if(_0x495e21[_0x7e2827(0x455)]){if(_0x4e1729[_0x7e2827(0x228)]==_0x7e2827(0x145))_0x495e21[_0x7e2827(0x3d0)]&&playtone(),getById(_0x7e2827(0x252)+_0x8e7547)[_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x101),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x2ad)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]='inline-block';else _0x4e1729[_0x7e2827(0x228)]==_0x7e2827(0x1c3)&&(getById(_0x7e2827(0x252)+_0x8e7547)[_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x51d),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x2ad)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x51d));}log(_0x7e2827(0x360)+_0x80b316),getChatMessage(_0x4e1729['chat'],_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xab)],_0x80b316,_0x1d5f21);}_0x7e2827(0x3a4)in _0x4e1729&&(log(_0x4e1729),_0x495e21[_0x7e2827(0x137)]&&updateClosedCaptions(_0x4e1729,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['label'],_0x8e7547));_0x7e2827(0x4f9)in _0x4e1729&&(_0x495e21[_0x7e2827(0x455)]&&updateDirectorsAudio(_0x4e1729[_0x7e2827(0x4f9)],_0x8e7547));_0x7e2827(0x3d2)in _0x4e1729&&(_0x495e21[_0x7e2827(0x455)]&&updateDirectorsVideo(_0x4e1729['videoOptions'],_0x8e7547));_0x7e2827(0x444)in _0x4e1729&&(_0x495e21[_0x7e2827(0x455)]&&gotDevicesRemote(_0x4e1729[_0x7e2827(0x444)],_0x8e7547));_0x7e2827(0x26f)in _0x4e1729&&(_0x495e21[_0x7e2827(0x389)]===_0x8e7547&&(_0x495e21['raisehands']&&lowerhand()));if(_0x7e2827(0x4ef)in _0x4e1729){log(_0x4e1729);if(_0x495e21['directorUUID']===_0x8e7547){if(_0x4e1729['infocus']!==![]){if(_0x4e1729[_0x7e2827(0x4ef)]===!![])_0x495e21[_0x7e2827(0x4ef)]=!![];else{if(_0x7e2827(0x1fd)!==_0x7e2827(0x478))for(var _0x596a29 in _0x495e21[_0x7e2827(0x3cc)]){if(_0x495e21[_0x7e2827(0x3cc)][_0x596a29]['streamID']===_0x4e1729[_0x7e2827(0x4ef)]){_0x495e21[_0x7e2827(0x4ef)]=_0x596a29;break;}}else{function _0x56aa20(){var _0x1ad517=_0x7e2827;_0x233ea9[_0x1ad517(0x3fd)][_0x1fdb58][_0x1ad517(0x425)]=0x64/2.5;}}}}else _0x495e21[_0x7e2827(0x4ef)]=![];_0x16fa32=!![],mustUpdateuserList=!![];}}_0x7e2827(0x45d)in _0x4e1729&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x502)][_0x7e2827(0x45d)]={},_0x7e2827(0x2b4)in _0x4e1729&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x502)][_0x7e2827(0x45d)][_0x7e2827(0x2b4)]=_0x4e1729[_0x7e2827(0x2b4)]),_0x7e2827(0x4e3)in _0x4e1729&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['stats']['sensors'][_0x7e2827(0x4e3)]=_0x4e1729[_0x7e2827(0x4e3)]),_0x7e2827(0xca)in _0x4e1729&&(_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x502)][_0x7e2827(0x45d)][_0x7e2827(0xca)]=_0x4e1729[_0x7e2827(0xca)]),_0x7e2827(0x14d)in _0x4e1729&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x502)][_0x7e2827(0x45d)][_0x7e2827(0x14d)]=_0x4e1729[_0x7e2827(0x14d)]),isIFrame&&parent[_0x7e2827(0x45a)]({'sensors':_0x4e1729},'*'));_0x7e2827(0x4db)in _0x4e1729&&playbackMIDI(_0x4e1729['midi']);_0x7e2827(0x158)in _0x4e1729&&updateRemoteRecordButton(_0x8e7547,_0x4e1729[_0x7e2827(0x158)]);if('info'in _0x4e1729){if('JSgdH'===_0x7e2827(0x3e0)){warnlog(_0x4e1729),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x502)][_0x7e2827(0x191)]=_0x4e1729[_0x7e2827(0x191)];if(_0x7e2827(0xab)in _0x4e1729[_0x7e2827(0x191)]){typeof _0x4e1729[_0x7e2827(0x191)][_0x7e2827(0xab)]==_0x7e2827(0x1c6)?_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0xab)]=sanitizeLabel(_0x4e1729[_0x7e2827(0x191)][_0x7e2827(0xab)]):_0x495e21['rpcs'][_0x8e7547]['label']=![];if(_0x495e21[_0x7e2827(0x455)]){var _0x358caa=getById('label_'+_0x8e7547);_0x358caa&&(_0x358caa[_0x7e2827(0x3b8)][_0x7e2827(0x22d)]=_0x7e2827(0x3ef),_0x358caa[_0x7e2827(0x3b8)][_0x7e2827(0x2d7)]=_0x7e2827(0x383),_0x358caa[_0x7e2827(0x3b8)]['marginLeft']=_0x7e2827(0x404),_0x358caa[_0x7e2827(0x3b8)][_0x7e2827(0x493)]=_0x7e2827(0xa1),_0x358caa[_0x7e2827(0x3b8)][_0x7e2827(0x47d)]=_0x7e2827(0x107),_0x358caa[_0x7e2827(0x2a3)][_0x7e2827(0x12e)]=_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xab)]?_0x358caa[_0x7e2827(0x44f)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xab)]:_0x358caa[_0x7e2827(0x44f)]=_0x7e2827(0x225),_0x358caa['onclick']=function(_0x504631){var _0x7e60aa=_0x7e2827,_0x1bb691=_0x504631['target'][_0x7e60aa(0x44f)];_0x495e21[_0x7e60aa(0x3cc)][_0x504631[_0x7e60aa(0x201)][_0x7e60aa(0x2a3)]['UUID']][_0x7e60aa(0xab)]===![]&&(_0x1bb691='');window[_0x7e60aa(0x4a7)]();var _0x31dde4=prompt(_0x7e60aa(0x9f),_0x1bb691);if(_0x31dde4!==null){_0x31dde4==''?(_0x31dde4=![],_0x504631['target'][_0x7e60aa(0x44f)]='Add\x20a\x20label'):_0x504631[_0x7e60aa(0x201)][_0x7e60aa(0x44f)]=_0x31dde4;var _0x2d5021={};_0x2d5021[_0x7e60aa(0x12e)]=_0x504631[_0x7e60aa(0x201)][_0x7e60aa(0x2a3)][_0x7e60aa(0x12e)],_0x2d5021[_0x7e60aa(0x41f)]=!![],_0x2d5021[_0x7e60aa(0x15c)]=_0x31dde4,_0x495e21[_0x7e60aa(0x166)](_0x2d5021,_0x2d5021[_0x7e60aa(0x12e)]);}});}}if('order'in _0x4e1729[_0x7e2827(0x191)]){_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x40a)]=parseInt(_0x4e1729[_0x7e2827(0x191)][_0x7e2827(0x40a)])||0x0;if(_0x495e21[_0x7e2827(0x455)]){var _0xf6318e=document['querySelectorAll'](_0x7e2827(0x1f2)+_0x8e7547+'\x22]');_0xf6318e[0x0]&&(_0xf6318e[0x0][_0x7e2827(0x44f)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x40a)]);}}else _0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x40a)]=0x0;if(_0x495e21[_0x7e2827(0x455)]){if('recording_audio_pipeline'in _0x4e1729[_0x7e2827(0x191)]){if(_0x7e2827(0xf8)!=='KzEjU'){if(_0x4e1729[_0x7e2827(0x191)][_0x7e2827(0x1b0)]==![]){var _0xf6318e=document[_0x7e2827(0x91)](_0x7e2827(0x35f)+_0x8e7547+'\x22]');_0xf6318e[0x0]&&(_0xf6318e[0x0][_0x7e2827(0x94)]=!![],_0xf6318e[0x0][_0x7e2827(0x3fb)]=_0x7e2827(0x2c2));var _0xf6318e=document[_0x7e2827(0x91)](_0x7e2827(0x3a0)+_0x8e7547+'\x22]');_0xf6318e[0x0]&&(_0xf6318e[0x0][_0x7e2827(0x94)]=!![],_0xf6318e[0x0][_0x7e2827(0x3fb)]=_0x7e2827(0x2c2),_0xf6318e[0x0]['style'][_0x7e2827(0x3dc)]=0.2);}}else{function _0x2fce72(){var _0x358877=_0x7e2827;_0x5f3efe[_0x358877(0x191)]['muted']=!![];}}}if(_0x7e2827(0x1b2)in _0x4e1729[_0x7e2827(0x191)]){if(_0x4e1729['info'][_0x7e2827(0x1b2)]!==![]){var _0x548113=parseInt(_0x4e1729[_0x7e2827(0x191)][_0x7e2827(0x1b2)])||0x0;if(_0x548113===0x0){var _0xf6318e=document['querySelectorAll'](_0x7e2827(0x35f)+_0x8e7547+'\x22]');_0xf6318e[0x0]&&(_0xf6318e[0x0][_0x7e2827(0x2a3)][_0x7e2827(0x15c)]=0x1,_0xf6318e[0x0][_0x7e2827(0x9d)]='pressed',_0xf6318e[0x0][_0x7e2827(0x284)][0x1]['innerHTML']=_0x7e2827(0x4be),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x2dd)]=0x1);}else{var _0xf6318e=document[_0x7e2827(0x91)](_0x7e2827(0x3a0)+_0x8e7547+'\x22]');_0xf6318e[0x0]&&(_0xf6318e[0x0][_0x7e2827(0x15c)]=_0x548113,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x1dc)]=_0x548113,remoteVolumeUI(_0xf6318e[0x0]));}}}}if(_0x7e2827(0x3dd)in _0x4e1729[_0x7e2827(0x191)]){if(_0x7e2827(0x24d)===_0x7e2827(0x24d)){_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['remoteMuteState']=_0x4e1729[_0x7e2827(0x191)][_0x7e2827(0x3dd)];if(_0x495e21[_0x7e2827(0x44c)]===![]){if(_0x7e2827(0x4b6)===_0x7e2827(0x4b6)){if(_0x495e21[_0x7e2827(0x3b3)]){if(_0x7e2827(0x151)!=='YqpoK'){function _0x3bce76(){var _0x12325f=_0x7e2827;_0x1accd1[_0x12325f(0x3cc)][_0x2bb7c8][_0x12325f(0x2b2)]&&(_0x550c6c['requestRateLimit'](0x0,_0x2c0340),_0x3a41b0[_0x12325f(0x3cc)][_0xff091d][_0x12325f(0xe5)]&&(_0x3c9f04[_0x12325f(0x3cc)][_0x49c253][_0x12325f(0xe5)][_0x12325f(0x20e)]=!![],_0x3aa46a['rpcs'][_0x12ab46]['imageElement']['style'][_0x12325f(0xdb)]=_0x12325f(0x20e))),_0xab020f=!![];}}else!_0x495e21[_0x7e2827(0xe9)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)]?_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x193)]?_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)]['style'][_0x7e2827(0x443)]=_0x7e2827(0x101):_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x51d):(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['remoteMuteElement']=getById(_0x7e2827(0x2b0))[_0x7e2827(0x1d1)](!![]),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)]['id']=_0x7e2827(0x17d)+_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x193)]?_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['remoteMuteElement']['style'][_0x7e2827(0x443)]=_0x7e2827(0x101):_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x51d),_0x16fa32=!![]));}}else{function _0x9dfcef(){var _0x3ecd03=_0x7e2827;_0x5b13dd[_0x3ecd03(0x3fd)][_0x15ee9b][_0x3ecd03(0x438)]=!![];}}}}else{function _0x19f6d8(){var _0x55504b=_0x7e2827;_0x291b4f['rpcs'][_0x22bc80][_0x55504b(0x40a)]=0x0;}}}'directorSpeakerMuted'in _0x4e1729[_0x7e2827(0x191)]&&(_0x495e21['director']&&(_0x4e1729['info'][_0x7e2827(0x377)]&&updateRemoteSpeakerMute(_0x8e7547)));if(_0x7e2827(0x1bb)in _0x4e1729['info']){if(_0x7e2827(0x3d4)!==_0x7e2827(0x2a2))_0x495e21[_0x7e2827(0x455)]&&(_0x4e1729[_0x7e2827(0x191)][_0x7e2827(0x1bb)]&&updateRemoteDisplayMute(_0x8e7547));else{function _0x577316(){var _0x4c1a3a=_0x7e2827;_0x372830[_0x4c1a3a(0x3e3)]==!![]&&(_0x225a77=!![]);}}}_0x7e2827(0x367)in _0x4e1729[_0x7e2827(0x191)]&&(_0x495e21['director']?_0x4e1729[_0x7e2827(0x191)]['directorVideoMuted']&&updateDirectorVideoMute(_0x8e7547):(_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x367)]=_0x4e1729[_0x7e2827(0x191)][_0x7e2827(0x367)],_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['directorVideoMuted']&&(_0x8e7547 in _0x495e21['rpcs']&&_0x495e21[_0x7e2827(0x2d6)](0x0,_0x8e7547))));_0x7e2827(0x258)in _0x4e1729[_0x7e2827(0x191)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x2b2)]=_0x4e1729['info'][_0x7e2827(0x258)],_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x2b2)]&&(_0x495e21[_0x7e2827(0x455)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x481)]['style'][_0x7e2827(0x443)]=_0x7e2827(0x101))));if(_0x8e7547===_0x495e21[_0x7e2827(0x389)])try{_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x502)][_0x7e2827(0x191)][_0x7e2827(0x455)]=!![];}catch(_0xd08079){}mustUpdateuserList=!![];}else{function _0x461da6(){var _0x19c330=_0x7e2827;_0x21abf3=_0x41fe2c[_0x19c330(0x3fd)][_0x241d31][_0x19c330(0x1ec)];}}}if(_0x7e2827(0x1b3)in _0x4e1729){if(_0x495e21[_0x7e2827(0x389)]===_0x8e7547){_0x7e2827(0x128)in _0x4e1729['directorSettings']&&(_0x495e21[_0x7e2827(0x128)]=parseInt(_0x4e1729[_0x7e2827(0x1b3)][_0x7e2827(0x128)])||0x0,_0x16fa32=!![]);if(_0x4e1729[_0x7e2827(0x1b3)][_0x7e2827(0x44d)]){if(_0x4e1729[_0x7e2827(0x1b3)][_0x7e2827(0x44d)]===_0x495e21[_0x7e2827(0x23e)])_0x495e21['infocus']=!![];else for(var _0x596a29 in _0x495e21[_0x7e2827(0x3cc)]){if(_0x495e21[_0x7e2827(0x3cc)][_0x596a29][_0x7e2827(0x23e)]===_0x4e1729['directorSettings'][_0x7e2827(0x44d)]){_0x495e21[_0x7e2827(0x4ef)]=_0x596a29;break;}}_0x16fa32=!![],mustUpdateuserList=!![];}if(_0x495e21['scene']!==![]){if(_0x4e1729['directorSettings'][_0x7e2827(0x44c)])for(var _0x596a29 in _0x4e1729[_0x7e2827(0x1b3)][_0x7e2827(0x44c)]){setTimeout(function(_0x519398){var _0x382faa=_0x7e2827;_0x495e21[_0x382faa(0x282)](_0x519398);},0x3e8,_0x4e1729[_0x7e2827(0x1b3)][_0x7e2827(0x44c)][_0x596a29]);}if(_0x4e1729[_0x7e2827(0x1b3)]['mute']){if('VZzhJ'!==_0x7e2827(0x305)){function _0x2300ff(){var _0x2199d5=_0x7e2827;_0x34ab95(_0x2199d5(0x127));}}else for(var _0x596a29 in _0x4e1729[_0x7e2827(0x1b3)][_0x7e2827(0x11c)]){setTimeout(function(_0x423538){var _0x5b317f=_0x7e2827;_0x495e21[_0x5b317f(0x282)](_0x423538);},0x3e8,_0x4e1729[_0x7e2827(0x1b3)][_0x7e2827(0x11c)][_0x596a29]);}}}}}if(_0x495e21[_0x7e2827(0x389)]===_0x8e7547){if(_0x495e21[_0x7e2827(0x44c)]!==![]){if('KhHhU'===_0x7e2827(0x285)){function _0x26121f(){var _0x47dd97=_0x7e2827;_0x5046dc[_0x47dd97(0x376)]=_0x47dd97(0x20d);}}else _0x7e2827(0xad)in _0x4e1729&&_0x495e21[_0x7e2827(0x282)](_0x4e1729);}}if(_0x7e2827(0x40a)in _0x4e1729){_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x40a)]=parseInt(_0x4e1729['order'])||0x0;_0x8e7547 in _0x495e21[_0x7e2827(0x3fd)]&&(_0x495e21[_0x7e2827(0x3fd)][_0x8e7547][_0x7e2827(0x40a)]=parseInt(_0x4e1729[_0x7e2827(0x40a)])||0x0);if(_0x495e21[_0x7e2827(0x455)]){var _0xf6318e=document[_0x7e2827(0x91)](_0x7e2827(0x1f2)+_0x8e7547+'\x22]');_0xf6318e[0x0]&&(_0xf6318e[0x0][_0x7e2827(0x44f)]=parseInt(_0x4e1729[_0x7e2827(0x40a)])||0x0);}_0x16fa32=!![];}if(_0x7e2827(0x41f)in _0x4e1729){log(_0x7e2827(0x1d0));if(_0x7e2827(0x15c)in _0x4e1729){log('value\x20there');if(typeof _0x4e1729[_0x7e2827(0x15c)]==_0x7e2827(0x1c6)){_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xab)]=sanitizeLabel(_0x4e1729['value']);_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xab)]['length']==0x0&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xab)]=![]);if(_0x495e21[_0x7e2827(0x455)]){var _0xf6318e=getById(_0x7e2827(0x427)+_0x8e7547);if(_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0xab)])_0xf6318e[_0x7e2827(0x44f)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xab)];else{if(_0x7e2827(0xd2)===_0x7e2827(0xd2))_0xf6318e['innerText']=_0x7e2827(0x225);else{function _0x18bf20(){var _0x244ef4=_0x7e2827;_0x3885f6[_0x244ef4(0x3fd)][_0x52906b][_0x244ef4(0x425)]=0x64;}}}}else{if(_0x495e21[_0x7e2827(0x25c)]){if('uzuDp'===_0x7e2827(0x208)){function _0x33708d(){_0xfcbe88(function(){var _0x1f1398=_0x56d9;_0x105c2d[_0x1f1398(0xc5)];},0xbb8);}}else _0x16fa32=!![];}}}else{_0x495e21['rpcs'][_0x8e7547]['label']=![];if(_0x495e21[_0x7e2827(0x455)]){var _0xf6318e=getById('label_'+_0x8e7547);_0xf6318e['innerText']='Add\x20a\x20label';}else _0x495e21['showlabels']&&(_0x16fa32=!![]);}mustUpdateuserList=!![];}}_0x7e2827(0x36b)in _0x4e1729&&(log(_0x4e1729),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x193)]=_0x4e1729[_0x7e2827(0x36b)],_0x495e21['requestRateLimit'](![],_0x8e7547),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x502)][_0x7e2827(0x191)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x502)][_0x7e2827(0x191)][_0x7e2827(0x3dd)]=_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x193)]),_0x495e21[_0x7e2827(0x44c)]===![]&&(_0x495e21[_0x7e2827(0x3b3)]&&(!_0x495e21[_0x7e2827(0xe9)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)]?_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['remoteMuteState']?_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0xfb)][_0x7e2827(0x3b8)]['display']=_0x7e2827(0x101):_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x51d):(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)]=getById(_0x7e2827(0x2b0))[_0x7e2827(0x1d1)](!![]),_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0xfb)]['id']=_0x7e2827(0x17d)+_0x8e7547,_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['remoteMuteState']?_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x101):_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xfb)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x51d),_0x16fa32=!![]),mustUpdateuserList=!![]))));if(_0x7e2827(0x4c9)in _0x4e1729){var _0x3245e6=getChromeVersion();_0x3245e6&&(_0x3245e6<0x50&&(_0x16fa32=!![]));}_0x7e2827(0x2b2)in _0x4e1729&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x2b2)]=_0x4e1729[_0x7e2827(0x2b2)],!_0x495e21[_0x7e2827(0x455)]?(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0x2b2)]&&(_0x495e21['requestRateLimit'](0x0,_0x8e7547),_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)]['hidden']=!![],_0x495e21[_0x7e2827(0x3cc)][_0x8e7547][_0x7e2827(0xe5)]['style'][_0x7e2827(0xdb)]=_0x7e2827(0x20e))),_0x16fa32=!![]):_0x495e21[_0x7e2827(0x3cc)][_0x8e7547]['videoMuted']?_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x481)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x146):_0x495e21['rpcs'][_0x8e7547][_0x7e2827(0x481)][_0x7e2827(0x3b8)][_0x7e2827(0x443)]=_0x7e2827(0x51d),mustUpdateuserList=!![]);if(_0x7e2827(0x414)in _0x4e1729){if(!_0x495e21[_0x7e2827(0x455)]){if(_0x7e2827(0x201)in _0x4e1729){if(_0x495e21[_0x7e2827(0x389)]===_0x8e7547){var _0x3bdf86=_0x4e1729[_0x7e2827(0x201)];if(_0x3bdf86===!![])_0x495e21[_0x7e2827(0x367)]=_0x4e1729[_0x7e2827(0x414)];else _0x3bdf86 in _0x495e21[_0x7e2827(0x3cc)]&&(_0x495e21[_0x7e2827(0x3cc)][_0x3bdf86][_0x7e2827(0x367)]=_0x4e1729[_0x7e2827(0x414)],_0x495e21['rpcs'][_0x3bdf86][_0x7e2827(0x367)]&&(_0x3bdf86 in _0x495e21[_0x7e2827(0x3cc)]&&_0x495e21[_0x7e2827(0x2d6)](0x0,_0x3bdf86)),_0x16fa32=!![]);}}}mustUpdateuserList=!![];}_0x7e2827(0x48d)in _0x4e1729&&remoteStats(_0x4e1729);if(_0x16fa32)setTimeout(function(){updateMixer(),updateUserList();},0x1);else mustUpdateuserList&&updateUserList();},_0x495e21[_0x3ace6a(0x3cc)][_0x8e7547][_0x3ace6a(0xd3)]['onclose']=()=>{var _0x50576e=_0x3ace6a;log(_0x50576e(0xf1));try{if(_0x50576e(0xcb)===_0x50576e(0x2fd)){function _0x5e9e0a(){_0x49bd11('Couldn\x27t\x20re-connect'),_0x2785cf(_0x4171ab);}}else var _0x55ffb9=_0x495e21[_0x50576e(0x3cc)][_0x8e7547]['streamID'];}catch(_0x50dd5b){}try{_0x495e21['rpcs'][_0x8e7547][_0x50576e(0x229)]();}catch(_0x46e9af){errorlog(_0x50576e(0x508));}try{_0x495e21[_0x50576e(0x3cc)][_0x8e7547][_0x50576e(0x302)]&&_0x495e21[_0x50576e(0x3cc)][_0x8e7547][_0x50576e(0x302)][_0x50576e(0x509)]()[_0x50576e(0x415)](function(_0x5e6402){var _0x912590=_0x50576e;_0x5e6402[_0x912590(0x2de)](),log(_0x912590(0x1ed));});}catch(_0x164402){}if(_0x495e21[_0x50576e(0x455)]){if(_0x50576e(0x2b3)!==_0x50576e(0x37c))try{'recorder'in _0x495e21[_0x50576e(0x3cc)][_0x8e7547][_0x50576e(0x2f6)]&&_0x495e21[_0x50576e(0x3cc)][_0x8e7547][_0x50576e(0x2f6)][_0x50576e(0x158)][_0x50576e(0x2de)]();}catch(_0x3b9429){warnlog(_0x3b9429);}else{function _0x5551b8(){var _0x2b40d7=_0x50576e;_0x46f260[_0x2b40d7(0x3cb)]();var _0x336f71=_0x314b85[_0x2b40d7(0x269)][_0x2b40d7(0x2a3)]['UUID'];if('stats'in _0x365345['rpcs'][_0x336f71]){var [_0x36d46e,_0x4a9812]=_0x4ee57b();_0x5f50c9(_0x4a9812,_0x336f71),_0x36d46e[_0x2b40d7(0x294)]=_0x4707b9(_0x43f0df,0xbb8,_0x4a9812,_0x336f71);}return _0x12649a['stopPropagation'](),![];}}}try{document[_0x50576e(0x2ed)](_0x50576e(0x321)+_0x8e7547)&&getById(_0x50576e(0x321)+_0x8e7547)[_0x50576e(0x1b7)][_0x50576e(0x272)](getById(_0x50576e(0x321)+_0x8e7547));}catch(_0x3946d4){warnlog(_0x3946d4);}try{_0x495e21[_0x50576e(0x3cc)][_0x8e7547]=null,delete _0x495e21[_0x50576e(0x3cc)][_0x8e7547];}catch(_0x14c802){}!_0x495e21['director']&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x55ffb9==_0x50576e(0x51f))return;try{warnlog(_0x50576e(0x3af)),_0x55ffb9 in _0x495e21[_0x50576e(0x27d)]&&(log(_0x50576e(0x46e)+_0x55ffb9),clearTimeout(_0x495e21['watchTimeoutList'][_0x55ffb9])),_0x495e21[_0x50576e(0x27d)][_0x55ffb9]=setTimeout(function(_0x39cdcd){var _0x316b04=_0x50576e;delete _0x495e21['watchTimeoutList'][_0x39cdcd],log(_0x316b04(0x2bd)+_0x39cdcd),_0x495e21[_0x316b04(0x3f0)](_0x39cdcd);},_0x495e21[_0x50576e(0x23a)],_0x55ffb9);}catch(_0x3d0084){errorlog(_0x3d0084);}pokeIframeAPI(_0x50576e(0x366),![],_0x8e7547),updateUserList();};},_0x495e21['playoutdelay']=function(_0x3d960d){var _0xcb7f96=_0x4885dd;try{var _0xb9c8b=_0x495e21[_0xcb7f96(0x245)]||0x0;_0xb9c8b=parseFloat(_0xb9c8b);if(_0x495e21[_0xcb7f96(0x245)]!==![]){var _0x16047b=_0x495e21['rpcs'][_0x3d960d][_0xcb7f96(0x220)]()[_0xcb7f96(0x250)](),_0xe4d3d4=0x0;_0x16047b['forEach'](function(_0x11fc36){var _0x111819=_0xcb7f96;if(_0x111819(0x3e5)===_0x111819(0x4bd)){function _0x3d981f(){return;}}else try{for(var _0x4017b5 in _0x495e21[_0x111819(0x3cc)][_0x3d960d]['stats']){if(typeof _0x495e21[_0x111819(0x3cc)][_0x3d960d]['stats'][_0x4017b5]==_0x111819(0x169)&&_0x111819(0x38d)in _0x495e21['rpcs'][_0x3d960d]['stats'][_0x4017b5]&&_0x495e21[_0x111819(0x3cc)][_0x3d960d]['stats'][_0x4017b5]['_trackID']===_0x11fc36[_0x111819(0x476)]['id']&&_0x111819(0x426)in _0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5]){if(_0x111819(0x33a)!=='yBoim'){var _0xa87563=0x0;_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5][_0x111819(0x390)]?_0xa87563=_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5][_0x111819(0x390)]:_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5][_0x111819(0x390)]=0x0;_0xa87563+=_0xb9c8b-_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5][_0x111819(0x426)];_0xa87563>_0xb9c8b&&(_0xa87563=_0xb9c8b);if(_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5]['_type']==_0x111819(0x295)){if('Wmqwt'===_0x111819(0x29e)){function _0xdab641(){var _0x3a83ae=_0x111819;_0x25241a[_0x3a83ae(0xe4)]=![];}}else{if(_0x11fc36[_0x111819(0x476)]['id']in _0x495e21[_0x111819(0x3cc)][_0x3d960d]['delayNode']){log('updating\x20audio\x20delay');var _0x13b9a3=_0xe4d3d4-_0x495e21['rpcs'][_0x3d960d][_0x111819(0x502)][_0x4017b5][_0x111819(0x426)]+_0x495e21['sync'];_0x13b9a3<0x0&&(_0x13b9a3=0x0),log(_0x111819(0x3ca)+_0x13b9a3),log(_0x111819(0x15a)+_0x495e21[_0x111819(0x4a8)][_0x111819(0x1f3)]),_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x4dc)][_0x11fc36['track']['id']]['delayTime'][_0x111819(0x456)](parseFloat(_0x13b9a3/0x3e8),_0x495e21[_0x111819(0x4a8)][_0x111819(0x1f3)]+0x1),_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5][_0x111819(0x3eb)]=_0x13b9a3;}}}else _0x495e21['rpcs'][_0x3d960d]['stats'][_0x4017b5]['_type']==_0x111819(0x482)&&(_0xe4d3d4=_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5][_0x111819(0x426)],_0xa87563<0x0&&(_0xa87563=0x0),_0x495e21[_0x111819(0x3cc)][_0x3d960d][_0x111819(0x502)][_0x4017b5]['_sync_offset']=_0xa87563,_0x11fc36[_0x111819(0x339)]=parseFloat(_0xa87563/0x3e8));}else{function _0x472f4f(){var _0x52dc8e=_0x111819;_0x40ccee(_0x10eb28[_0x52dc8e(0x23e)]);}}}}}catch(_0x24d1e5){errorlog(_0x24d1e5);}});}}catch(_0x474030){errorlog(_0xcb7f96(0x4ec));}},_0x495e21[_0x4885dd(0x45c)]=function(_0x321f0a){var _0x1b5ce4=_0x4885dd;if(!(_0x321f0a in _0x495e21[_0x1b5ce4(0x3cc)]))return;try{_0x495e21[_0x1b5ce4(0x3cc)][_0x321f0a][_0x1b5ce4(0x2f6)]['paused']&&(log('trying\x20to\x20play'),_0x495e21[_0x1b5ce4(0x3cc)][_0x321f0a][_0x1b5ce4(0x2f6)][_0x1b5ce4(0x4c7)]()['then'](_0x34780d=>{var _0xf7514e=_0x1b5ce4;log(_0xf7514e(0x2c3)),firstPlayTriggered=!![];})[_0x1b5ce4(0x236)](warnlog));}catch(_0x9ff352){};try{_0x495e21[_0x1b5ce4(0x3cc)][_0x321f0a]['getStats']()[_0x1b5ce4(0x34d)](function(_0x47f8fe){var _0x41ef34=_0x1b5ce4;setTimeout(_0x495e21[_0x41ef34(0x45c)],0xbb8,_0x321f0a),!_0x495e21[_0x41ef34(0x3cc)][_0x321f0a]['stats']['RTC\x20Connection']&&(_0x495e21[_0x41ef34(0x3cc)][_0x321f0a]['stats'][_0x41ef34(0x50e)]={}),_0x47f8fe[_0x41ef34(0x415)](_0x60e862=>{var _0x5c6994=_0x41ef34;if(_0x60e862[_0x5c6994(0x14a)]==_0x5c6994(0x2c5)&&_0x60e862['nominated']==!![])_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x50a)]=_0x60e862['localCandidateId'],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x5c6994(0x50e)][_0x5c6994(0x12a)]=_0x60e862['remoteCandidateId'],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x387)]=_0x60e862[_0x5c6994(0x4fb)]*0x3e8;else{if(_0x60e862[_0x5c6994(0x14a)]==_0x5c6994(0x476)&&_0x60e862['remoteSource']==!![]){if(_0x60e862['id']in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)])_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['id']][_0x5c6994(0x38d)]=_0x60e862[_0x5c6994(0x417)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862['id']][_0x5c6994(0x426)]=parseInt(0x3e8*(parseFloat(_0x60e862[_0x5c6994(0x34a)])-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862['id']][_0x5c6994(0x3b1)])/(parseInt(_0x60e862[_0x5c6994(0x2b6)])-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['id']][_0x5c6994(0x1d7)]))||0x0,_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['id']][_0x5c6994(0x3b1)]=parseFloat(_0x60e862[_0x5c6994(0x34a)])||0x0,_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['id']][_0x5c6994(0x1d7)]=parseInt(_0x60e862[_0x5c6994(0x2b6)])||0x0,_0x5c6994(0x4d1)in _0x60e862&&(_0x5c6994(0xff)in _0x60e862&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['id']][_0x5c6994(0x280)]=_0x60e862[_0x5c6994(0x4d1)]+'\x20x\x20'+_0x60e862[_0x5c6994(0xff)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['id']][_0x5c6994(0x468)]=_0x60e862[_0x5c6994(0x4d1)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['id']][_0x5c6994(0x50f)]=_0x60e862[_0x5c6994(0xff)]));else{var _0x44832c={};_0x44832c[_0x5c6994(0x3b1)]=parseFloat(_0x60e862[_0x5c6994(0x34a)])||0x0,_0x44832c[_0x5c6994(0x1d7)]=parseInt(_0x60e862[_0x5c6994(0x2b6)])||0x0,_0x44832c['Buffer_Delay_in_ms']=0x0,_0x44832c['_trackID']=_0x60e862[_0x5c6994(0x417)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['id']]=_0x44832c;}}else{if(_0x60e862[_0x5c6994(0x14a)]==_0x5c6994(0x2c9)){if(_0x5c6994(0x12a)in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)]&&_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x12a)]!=_0x60e862['id'])return;'relayProtocol'in _0x60e862&&('ip'in _0x60e862&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x1f6)]=_0x60e862['ip']),_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)]['remote_relayProtocol']=_0x60e862['relayProtocol']);'candidateType'in _0x60e862&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]['RTC\x20Connection'][_0x5c6994(0x32b)]=_0x60e862[_0x5c6994(0xa0)]);if('networkType'in _0x60e862){if(_0x5c6994(0x200)==='ZknKG')_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x5c6994(0x50e)][_0x5c6994(0x2ee)]=_0x60e862[_0x5c6994(0x22a)];else{function _0x135e5b(){var _0x46d82e=_0x5c6994,_0x355027={};_0x355027[_0x46d82e(0x12e)]=_0x107126[_0x46d82e(0x12e)],_0x355027[_0x46d82e(0x14a)]=_0x5c22c3['type'];for(var _0x14984c=0x0;_0x14984c<_0x33e81a['candidates'][_0x46d82e(0xaf)];_0x14984c++){_0x355027['candidate']=_0x542087[_0x46d82e(0x117)][_0x14984c],_0x2b8435[_0x46d82e(0x447)](_0x355027);}}}}}else{if(_0x60e862[_0x5c6994(0x14a)]=='local-candidate'){if('_local_ice_id'in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)]&&_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x50a)]!=_0x60e862['id'])return;'relayProtocol'in _0x60e862&&('ip'in _0x60e862&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x26e)]=_0x60e862['ip']),_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x311)]=_0x60e862[_0x5c6994(0x46d)]),_0x5c6994(0xa0)in _0x60e862&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]['RTC\x20Connection'][_0x5c6994(0x1c0)]=_0x60e862[_0x5c6994(0xa0)]),_0x5c6994(0x22a)in _0x60e862&&(_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x2ee)]=_0x60e862[_0x5c6994(0x22a)]);}else{if(_0x60e862[_0x5c6994(0x14a)]==_0x5c6994(0x2c1)){'bytesReceived'in _0x60e862&&(_0x5c6994(0x368)in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)]&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)]['_timestamp']&&(_0x60e862['timestamp']&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x210)]=parseInt(0x8*(_0x60e862[_0x5c6994(0x1b8)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]['RTC\x20Connection'][_0x5c6994(0x368)])/(_0x60e862[_0x5c6994(0x2bb)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x5c6994(0x50e)][_0x5c6994(0x1a7)]))))),_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]['RTC\x20Connection'][_0x5c6994(0x368)]=_0x60e862[_0x5c6994(0x1b8)]);if(_0x5c6994(0x2bb)in _0x60e862){_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x1a7)]=_0x60e862[_0x5c6994(0x2bb)];if(!_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x4fa)]){if(_0x5c6994(0x3c4)!==_0x5c6994(0x3c4)){function _0x4c1cd8(){var _0x5dd649=_0x5c6994;_0x3ce142['innerText']=_0x5dd649(0x225);}}else _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0x4fa)]=_0x60e862[_0x5c6994(0x2bb)];}else _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x50e)][_0x5c6994(0xdf)]=parseInt((_0x60e862['timestamp']-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]['RTC\x20Connection'][_0x5c6994(0x4fa)])/0x258)/0x64;}}else{if(_0x60e862[_0x5c6994(0x14a)]==_0x5c6994(0xa3)&&_0x5c6994(0x1eb)in _0x60e862){_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']]=_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]||{},_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']]['Bitrate_in_kbps']=parseInt(0x8*(_0x60e862[_0x5c6994(0x1b8)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]['_last_bytes'])/(_0x60e862[_0x5c6994(0x2bb)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x4b7)])),_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x326)]=_0x60e862['bytesReceived']||_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x326)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x4b7)]=_0x60e862['timestamp']||_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x4b7)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x5c6994(0x4ae)]=_0x60e862[_0x5c6994(0xf2)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]['_codecIdTrackId']=_0x60e862[_0x5c6994(0x1eb)];if(_0x60e862[_0x5c6994(0x1b4)]==_0x5c6994(0x482)){_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x14a)]=_0x5c6994(0x3a8),_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x171)]=_0x5c6994(0x482);if(_0x495e21['obsfix']&&_0x5c6994(0x2e1)in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]&&_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x5c6994(0x2e1)]==_0x5c6994(0xc2)){_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x206)]=_0x60e862[_0x5c6994(0x4a9)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2cc)]||0x0,_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x27a)]=_0x60e862[_0x5c6994(0x1ae)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2e3)]+_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]['nackTrigger']||0x0,log(_0x5c6994(0x182));if(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x206)]===0x0&&_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x27a)]>=_0x495e21['obsfix'])_0x495e21[_0x5c6994(0x15d)](_0x321f0a),_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x27a)]=0x0,log(_0x5c6994(0x277));else _0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x206)]>0x0&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x27a)]=0x0);}else{if(_0x495e21['obsfix']&&_0x5c6994(0x2e1)in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]&&_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats']['codec']=='video/VP9'){_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x206)]=_0x60e862[_0x5c6994(0x4a9)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x2cc)]||0x0,_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x27a)]=_0x60e862[_0x5c6994(0x1ae)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2e3)]+_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]['nackTrigger']||0x0,log(_0x5c6994(0x182));if(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x206)]===0x0&&_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x27a)]>=_0x495e21[_0x5c6994(0x26c)]*0x4)_0x495e21['requestKeyframe'](_0x321f0a),_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x27a)]=0x0,log(_0x5c6994(0x277));else _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x206)]>0x0&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x27a)]=0x0);}}_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2cc)]=_0x60e862[_0x5c6994(0x4a9)]||0x0,_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]['streamErrors_nackCount']=_0x60e862[_0x5c6994(0x1ae)]||0x0;if(_0x5c6994(0x10e)in _0x60e862)_0x495e21['rpcs'][_0x321f0a]['stats'][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x197)]=parseInt(_0x60e862[_0x5c6994(0x10e)]);else{if(_0x5c6994(0x362)in _0x60e862&&_0x60e862[_0x5c6994(0x2bb)]){var _0x5842fb=0x0,_0x45f834=0x0;try{_0x5842fb=_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x1fc)],_0x45f834=_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]['_timestamp'];}catch(_0x4661dc){}_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x197)]=parseInt(0xa*(_0x60e862[_0x5c6994(0x362)]-_0x5842fb)/(_0x60e862[_0x5c6994(0x2bb)]/0x3e8-_0x45f834))/0xa,_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x1fc)]=_0x60e862[_0x5c6994(0x362)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]['_timestamp']=_0x60e862[_0x5c6994(0x2bb)]/0x3e8;}}}else _0x60e862[_0x5c6994(0x1b4)]=='audio'&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]['type']=_0x5c6994(0x340),_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862[_0x5c6994(0x1eb)]]['_type']='audio',_0x5c6994(0x9c)in _0x60e862&&(_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2d2)]=parseInt(parseFloat(_0x60e862[_0x5c6994(0x9c)])*0x2710)/0x2710));_0x5c6994(0x247)in _0x60e862&&_0x5c6994(0x364)in _0x60e862&&(!(_0x5c6994(0x2fb)in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]])&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2fb)]=_0x60e862[_0x5c6994(0x247)]),!(_0x5c6994(0x4d4)in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]])&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a]['stats'][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x4d4)]=_0x60e862[_0x5c6994(0x364)]),!(_0x5c6994(0xa8)in _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]])&&(_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0xa8)]=0x0),_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0xa8)]=_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]]['packetLoss_in_percentage']*0.35+0.65*((_0x60e862[_0x5c6994(0x247)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2fb)])*0x64)/(_0x60e862[_0x5c6994(0x364)]-_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x60e862['trackId']][_0x5c6994(0x4d4)]+(_0x60e862[_0x5c6994(0x247)]-_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2fb)]))||0x0,_0x495e21['rpcs'][_0x321f0a]['stats'][_0x60e862['trackId']]['_packetsReceived']=_0x60e862[_0x5c6994(0x364)],_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x60e862[_0x5c6994(0x1eb)]][_0x5c6994(0x2fb)]=_0x60e862[_0x5c6994(0x247)]);}else{if(_0x5c6994(0x4ae)in _0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)]&&_0x60e862['id']==_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x4ae)]){'mimeType'in _0x60e862&&(_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x43a)]]?_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]['_codecIdTrackId']][_0x5c6994(0x2e1)]=_0x60e862[_0x5c6994(0x1b5)]:(_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x495e21['rpcs'][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x43a)]]={},_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)][_0x5c6994(0x43a)]][_0x5c6994(0x2e1)]=_0x60e862[_0x5c6994(0x1b5)]));if(_0x5c6994(0xff)in _0x60e862){if(_0x5c6994(0x4d1)in _0x60e862){if(_0x5c6994(0x164)===_0x5c6994(0x23d)){function _0x584098(){_0x10d212=_0x1cf662;}}else _0x495e21[_0x5c6994(0x3cc)][_0x321f0a][_0x5c6994(0x502)]['Resolution']=parseInt(_0x60e862[_0x5c6994(0x4d1)])+_0x5c6994(0x2e2)+parseInt(_0x60e862[_0x5c6994(0xff)]);}}}}}}}}}}),_0x495e21[_0x41ef34(0x245)]!==![]&&_0x495e21['playoutdelay'](_0x321f0a),setTimeout(function(){var _0x37b6dc=_0x41ef34;_0x495e21[_0x37b6dc(0x37f)](),_0x495e21['directorDisplayMute']();},0x0);});}catch(_0x31cc70){errorlog(_0x31cc70);}},_0x495e21[_0x4885dd(0x3cc)][_0x8e7547][_0x4885dd(0x16c)]=_0x3f4187=>{var _0x46955d=_0x4885dd;log(_0x46955d(0x9e));_0x495e21[_0x46955d(0x245)]!==![]&&_0x495e21[_0x46955d(0x3db)](_0x8e7547);_0x495e21[_0x46955d(0x37f)](),_0x495e21[_0x46955d(0x474)]();if(_0x3f4187[_0x46955d(0xfe)]&&_0x3f4187[_0x46955d(0xfe)][0x0]){_0x3f4187[_0x46955d(0xfe)][0x0]['onremovetrack']=function(_0x132acc){var _0x2c9a94=_0x46955d;try{warnlog(_0x2c9a94(0x181)),_0x495e21[_0x2c9a94(0x3cc)][_0x8e7547][_0x2c9a94(0x302)][_0x2c9a94(0x3d1)]()[_0x2c9a94(0x415)](_0x3d1a64=>{var _0x13c872=_0x2c9a94;_0x3d1a64['id']==_0x132acc[_0x13c872(0x476)]['id']&&_0x495e21[_0x13c872(0x3cc)][_0x8e7547][_0x13c872(0x302)]['removeTrack'](_0x3d1a64);}),_0x495e21['rpcs'][_0x8e7547][_0x2c9a94(0x2f6)]['srcObject']=_0x495e21[_0x2c9a94(0x3cc)][_0x8e7547][_0x2c9a94(0x302)],setTimeout(function(){updateMixer();},0x1);}catch(_0x2611f5){}},_0x3f4187[_0x46955d(0xfe)][0x0][_0x46955d(0x3b2)]=function(_0x4ed312){var _0x4244d5=_0x46955d;try{warnlog(_0x4244d5(0x226)),_0x495e21[_0x4244d5(0x3cc)][_0x8e7547][_0x4244d5(0x302)][_0x4244d5(0x3d1)]()[_0x4244d5(0x415)](_0x1e30be=>{var _0x1ffef0=_0x4244d5;if(_0x1ffef0(0x347)===_0x1ffef0(0x345)){function _0x4d0d0c(){var _0x3e6529=_0x1ffef0;_0x44b159('videosource')[_0x3e6529(0x3dd)]=!![];}}else _0x1e30be['id']==_0x4ed312['track']['id']&&_0x495e21[_0x1ffef0(0x3cc)][_0x8e7547][_0x1ffef0(0x302)]['removeTrack'](_0x1e30be);}),_0x495e21['rpcs'][_0x8e7547][_0x4244d5(0x2f6)]['srcObject']=_0x495e21[_0x4244d5(0x3cc)][_0x8e7547][_0x4244d5(0x302)];}catch(_0x1e4dcd){};};var _0xef257e=_0x3f4187[_0x46955d(0xfe)][0x0][_0x46955d(0x3d1)]()[_0x46955d(0xaf)];_0xef257e>0x1&&errorlog(_0x46955d(0x152));}if(_0x495e21['rpcs'][_0x8e7547][_0x46955d(0x2f6)]){if(_0x3f4187[_0x46955d(0xfe)]&&_0x3f4187[_0x46955d(0xfe)][0x0]){if(!_0x495e21[_0x46955d(0x3cc)][_0x8e7547]['streamSrc'])_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)]=_0x3f4187[_0x46955d(0xfe)][0x0];else{var _0x46af65=![];_0x3f4187[_0x46955d(0xfe)][0x0][_0x46955d(0x509)]()[_0x46955d(0x415)](_0x529b51=>{var _0x57948c=_0x46955d;_0x46af65&&(warnlog('VIDEO\x20TRACK;\x20already\x20one\x20added'),warnlog(_0x529b51)),_0x529b51[_0x57948c(0x51a)]==_0x57948c(0x482)&&(_0x495e21['rpcs'][_0x8e7547][_0x57948c(0x302)][_0x57948c(0x3d1)]()[_0x57948c(0x415)](_0x5ea2ab=>{var _0x7d020a=_0x57948c;_0x495e21['rpcs'][_0x8e7547][_0x7d020a(0x302)][_0x7d020a(0x379)](_0x5ea2ab);}),_0x46af65=!![]),log(_0x57948c(0xea)),_0x495e21[_0x57948c(0x3cc)][_0x8e7547][_0x57948c(0x302)][_0x57948c(0x49c)](_0x529b51);});}try{_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x2f6)][_0x46955d(0x1e8)]=_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)];}catch(_0x1a20c5){errorlog('4722');}log(_0x46955d(0x471));}else{if(_0x3f4187['track']){warnlog(_0x46955d(0x407));!_0x495e21['rpcs'][_0x8e7547]['streamSrc']?_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)]=new MediaStream():_0x3f4187[_0x46955d(0x476)][_0x46955d(0x51a)]==_0x46955d(0x482)&&_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)][_0x46955d(0x3d1)]()[_0x46955d(0x415)](_0x335a52=>{var _0x54b9e1=_0x46955d;_0x495e21[_0x54b9e1(0x3cc)][_0x8e7547][_0x54b9e1(0x302)][_0x54b9e1(0x379)](_0x335a52);});_0x495e21[_0x46955d(0x3cc)][_0x8e7547]['streamSrc']['addTrack'](_0x3f4187[_0x46955d(0x476)]);try{_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x2f6)][_0x46955d(0x1e8)]=_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)];}catch(_0x1ce529){errorlog(_0x46955d(0x32f));}}else errorlog(_0x46955d(0x2e5));}setTimeout(function(){updateMixer();},0x1);}else{log(_0x46955d(0x129));var _0x50b270=document['createElement'](_0x46955d(0x482));_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x2f6)]=_0x50b270,_0x50b270[_0x46955d(0x2a3)][_0x46955d(0x12e)]=_0x8e7547,_0x50b270['id']=_0x46955d(0x3ea)+_0x8e7547;_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x23e)]&&(_0x50b270[_0x46955d(0x2a3)][_0x46955d(0x3ee)]=_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x23e)]);setupIncomingVideoTracking(_0x50b270,_0x8e7547);if(_0x3f4187[_0x46955d(0xfe)]&&_0x3f4187[_0x46955d(0xfe)][0x0]){var _0x1a7514=_0x3f4187[_0x46955d(0xfe)][0x0];_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)]=_0x3f4187[_0x46955d(0xfe)][0x0],_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x2f6)][_0x46955d(0x1e8)]=_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)],log(_0x46955d(0x471));}else _0x3f4187['track']&&(warnlog(_0x46955d(0x407)),!_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)]&&(_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x302)]=new MediaStream()),_0x495e21[_0x46955d(0x3cc)][_0x8e7547]['streamSrc']['addTrack'](_0x3f4187['track']),_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x2f6)][_0x46955d(0x1e8)]=_0x495e21['rpcs'][_0x8e7547][_0x46955d(0x302)]);if(_0x495e21[_0x46955d(0x232)]){var _0x3ad352={};_0x3ad352[_0x46955d(0x232)]=parseInt(_0x495e21[_0x46955d(0x232)]),log(_0x3ad352),_0x495e21['sendRequest'](_0x3ad352,_0x8e7547);}}if(_0x495e21[_0x46955d(0x2fc)]===!![]){var _0x1385c8=function(_0x478107){var _0x1fae66=function(_0x29b3ea){var _0x406cb6=_0x56d9;if(!_0x495e21['rpcs'][_0x29b3ea])return;var _0x3daa7b=_0x495e21[_0x406cb6(0x3cc)][_0x29b3ea][_0x406cb6(0x2f6)][_0x406cb6(0x3dd)];_0x495e21['rpcs'][_0x29b3ea][_0x406cb6(0x2f6)][_0x406cb6(0x3dd)]=![],_0x495e21[_0x406cb6(0x3cc)][_0x29b3ea][_0x406cb6(0x2f6)][_0x406cb6(0x4eb)](_0x406cb6(0x4c7),_0x1fae66);_0x495e21[_0x406cb6(0x4a8)][_0x406cb6(0x138)]==_0x406cb6(0x346)&&_0x495e21[_0x406cb6(0x4a8)]['resume']();var _0x5b134f=_0x495e21[_0x406cb6(0x3cc)][_0x29b3ea][_0x406cb6(0x302)]['getAudioTracks']();if(_0x5b134f['length']){var _0x5d25d8=_0x5b134f[0x0];_0x5d25d8[_0x406cb6(0xab)]!=_0x406cb6(0x411)&&(_0x495e21[_0x406cb6(0x3cc)][_0x29b3ea][_0x406cb6(0x2f6)][_0x406cb6(0x1e8)]=addAudioPipeline(_0x495e21['rpcs'][_0x29b3ea][_0x406cb6(0x302)],_0x29b3ea,_0x5d25d8));}else _0x495e21[_0x406cb6(0x3cc)][_0x29b3ea][_0x406cb6(0x2f6)][_0x406cb6(0x1e8)]=_0x495e21[_0x406cb6(0x3cc)][_0x29b3ea][_0x406cb6(0x302)];_0x495e21[_0x406cb6(0x3cc)][_0x29b3ea][_0x406cb6(0x2f6)][_0x406cb6(0x3dd)]=_0x3daa7b,delete _0x495e21[_0x406cb6(0x3cc)][_0x29b3ea][_0x406cb6(0x244)],'eventPlayActive'in _0x495e21[_0x406cb6(0x3cc)][_0x29b3ea]&&errorlog(_0x406cb6(0x1dd));};return _0x1fae66(_0x478107);};_0x495e21[_0x46955d(0x4a8)][_0x46955d(0x138)]==_0x46955d(0x3a3)&&(_0x495e21['firstPlayTriggered']=!![]);if('eventPlayActive'in _0x495e21[_0x46955d(0x3cc)][_0x8e7547]){}else _0x495e21[_0x46955d(0x435)]==![]?_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x244)]=setInterval(function(_0xd6f38a){var _0x4354c9=_0x46955d;log(_0x4354c9(0x95));if(_0x495e21[_0x4354c9(0x3cc)][_0xd6f38a]){if(_0x4354c9(0x410)!==_0x4354c9(0x23b))_0x495e21[_0x4354c9(0x435)]&&(clearInterval(_0x495e21[_0x4354c9(0x3cc)][_0xd6f38a][_0x4354c9(0x244)]),_0x495e21[_0x4354c9(0x3cc)][_0xd6f38a]['videoElement'][_0x4354c9(0x358)]('play',_0x1385c8(_0xd6f38a)));else{function _0x4b5f8e(){var _0x35445e=_0x4354c9;_0x4efa95=_0x29b9ee[_0x35445e(0x459)];}}}},0x3e8,_0x8e7547):(!_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x244)]&&(_0x495e21['rpcs'][_0x8e7547][_0x46955d(0x244)]=!![]),_0x495e21[_0x46955d(0x3cc)][_0x8e7547][_0x46955d(0x2f6)][_0x46955d(0x358)](_0x46955d(0x4c7),_0x1385c8(_0x8e7547)));}_0x495e21[_0x46955d(0x37f)](),_0x495e21[_0x46955d(0x474)](),updateUserList();},log(_0x4885dd(0x2ec));},_0x495e21;}(); \ No newline at end of file +var _0x5b9d=['quality','streamErrors_nackCount','XpzmU','MOntK','RPC\x20closed','bytesReceived','HMRLA','has','Clean\x20up','roomenc','lIaee','vIEFH','jQMWs','directorViewBitrate','Couldn\x27t\x20re-connect','laEzs','gain','Audio_Loudness','jSsjR','checking','fYsKj','scale\x20set!','time_active_minutes','fullscreen','getParameters','totalRoomBitrate_default','turn:turn-au1.vdo.ninja:3478','localMuteElement','FHpVw','keys','1vh','sdp','done\x20clearing\x20audio','target','directorChat','resolution\x20scale','remove','Chromium-based\x20v','muteState','_framesDecoded','GOT\x20ICEs!!','Final\x20streamID:\x20','codecId','Not\x20director','head4','audioLatency','WMiLi','sampleRate','recording_audio_compressor_type','The\x20room\x20is\x20already\x20claimed\x20by\x20someone\x20else.\x0a\x0aOnly\x20the\x20first\x20person\x20to\x20join\x20a\x20room\x20has\x20control\x20of\x20anything.\x0a\x0aRefresh\x20after\x20the\x20first\x20director\x20leaves\x20to\x20claim.','MORE\x20THAN\x20ONE\x20VIDEO\x20TRACK\x20IS\x20BEING\x20ADDED','signature','MWebB','remoteMuteState','digest','\x0a\x0aPress\x20OK\x20to\x20be\x20redirected.','[data-action-type=\x22mute-guest\x22][data--u-u-i-d=\x22','sNdWr','hrxZu','nackTrigger','RCpcD','charCodeAt','midiHotkeys','YCJBI','noNacks','overlay','hudWC','FORCING\x20A\x20KEY\x20FRAME:\x20','noREMB','requestVideoHack','href','track','CONNECTEED!','Sjrpw','resolve','turns:www.turn.obs.ninja:443','next\x20stream\x20loading:\x20','oDDsY','writer','firefox','requestRateLimit','mjAAU','watchTimeoutList2:','ZBcyo','codecGroupFlag','scaleDueToBitrate','Setting\x20view\x20to\x20null\x20disables\x20all\x20playback','stats','Unhandeled\x20Error\x20occured','EQhrY','HANG\x20UP\x202\x20COMPLETE','iceTimer','mykey','GOT\x20ICE!!','esBPW','enabled','obsninja','close','storekey','includes','browserDetails','disabled','Unmute\x20video','osMSn','mobile','local_candidateType','security','string','reject','object','active','HNSFk','hidden','ICE\x20Disconnected;\x20wait\x20for\x20retry?\x20rpcs','processIce','Publisher\x20is\x20being\x20sent\x20a\x20video\x20stream???\x20NOT\x20EXPECTED!','deferring\x20with\x20a\x20promise;\x20hashed\x20room','_timestampStart','audioChannels','audioBitrate','Round_Trip_Time_ms','LOADING\x20UP\x20WAITING\x20WATCH\x20STREAM','transcript','silec','total_recv_bitrate_kbps','add','successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS','RTC\x20closed','streams','Someone\x20sent\x20us\x20an\x20ANSWER\x20sdp??','Xhgnx','sync','pushLoudness','LewEm','697772vGvsSN','onconnectionstatechange\x20pcs\x20ice\x20--\x20disconnected,\x20but\x20not\x20yet\x20closed?\x20','removeTrack','remoteZoom','dScti','firstPlayTriggered','mVztT','enhanceAudio','catch','muteStateTemplate','canvas','_jitter_count','videoMutedFlag','Refreshing\x20scale','KyFIQ','Ttfdc','CyKzZ','resending\x20message','doGVF','video/VP9','reportbutton','children','videosource','GlaoO','removeEventListener','manualBandwidth','audio','request','videoCodecs','ICE\x20DID\x20NOT\x20FIND\x20A\x20PC\x20OPTION?','TAkMR','_type','novideo','setParameters','onmessage','innerHTML','ccvZD','focus','ccpaq','view_set','preferCodec','noaudio','fOldV','chat','Does\x20Local\x20Stream\x20Source\x20EXIST?','ZJUTV','successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS\x20to\x20all\x20RTC\x20Peers','https://','action','float','generateHash','CqJcq','urls','reverse','WjKYy','Unable\x20to\x20set\x20update\x20OBS\x20Visibility','ebeEE','Bswup','remoteFocus','gfyaz','STREAM\x20ID\x20desalted\x202:','iXNJF','desaltStreamID','keyframeTimeout','director','createElement','Connection\x20to\x20Control\x20Server\x20lost.\x0a\x0aAuto-reconnect\x20is\x20partially\x20implemented','vector','top','cloneNode','video','updateQueue','hzbxZ','raw','cfQIV','iceConnectionState\x20==\x20connected','screenshareid','currentTarget','340XchOTs','oniceconnectionstatechange','disconnected','limitBitrate','mutedState','style','BITRATE:\x20','fSBih','yJgYV','publicKey','marginLeft','pcs\x20RTC\x20CLOSED','return\x20/\x22\x20+\x20this\x20+\x20\x22/','setupYourOwnPlease','directorEnabledPPT','directorMutedState','waitingWatchList','kvxGx','classList','The\x20request\x20failed;\x20the\x20remote\x20user\x20did\x20not\x20recognize\x20you\x20as\x20the\x20director','cPNtp','send\x20channel\x20open\x20pcs','YPneX','codecs','jitterBufferEmittedCount','nocursor','obsSourceActive','defaultPassword','maxviewers','initialPublish','getAudioSettings','NCdQG','cleanDirector','getTimezoneOffset','AQAB','deferring\x20with\x20a\x20promise','WMNbt','min','oFubm','Un-mute\x20guest','noiframe','timestamp','bandwidth','localstats','zlaoW','OMayS','tabernac','ICE\x20target\x20no\x20longer\x20exists?','obsVisibility','changeOrder','remoteSource','agc_url','meterStyle','iOS\x20devices\x20do\x20not\x20support\x20dynamic\x20bitrates\x20correctly;\x20skipping','audioContext','aec_url','prNsI','list','cursor','sensors','gyro','scaleWidth','broadcast','ping','JBSBU','dReRX','signData','roomid','Update\x20Mixer\x20Event\x20on\x20REsize\x20SET','currentCameraConstraints','RzVaR','description','bandwidth\x20set!','adaptivePtime','obsstudio','119518fmSLnF','dUBHd','warn','sourceActive','transport','Requested_resolution','utf-8','onclose','audioInputChannels','LnuHf','username','Buffer_Delay_in_ms','volume','substring','rajNc','rJsya','Notice:\x20The\x20system\x20is\x20currently\x20slow\x20to\x20respond\x20or\x20not\x20accessible.\x0a\x0aClick\x20OK\x20to\x20continue.\x0a\x0aIf\x20the\x20site\x20fails\x20to\x20work\x20though,\x20please\x20try\x20https://backup.obs.ninja\x20instead\x20or\x20contact\x20steve@seguin.email\x20for\x20help.\x0a\x0aThis\x20service\x20requires\x20the\x20use\x20of\x20Websockets\x20over\x20port\x20443.','framesPerSecond','icefilter','trackId','changeMicrophone','wgndD','undefined','already\x20connected','localCandidateId','privacy','visibility','recording','obsState','FNtRh','Android','stream\x20ID\x20is\x200\x20length','password','setVideoBitrates','speakerMuted','pingTimeout','kind','IFblA','done\x20replacing/adding\x20tracks','info','OdHJd','OWPSO','onconnectionstatechange','srcObject','uVnPN','msg\x20size\x20error','innerText','equalizer','codec_url','fDUMw','flipped','lowcut','applyConstraints','Message\x20to\x20be\x20sent:\x20','local-candidate','qGAbL','imageElement','Track\x20stopped','scale\x20scale','RSA','pliDelta','mimeType','exclude','Failed\x20to\x20connect\x20to\x20service:\x20Error\x20503Possibly\x20too\x20many\x20connections\x20from\x20the\x20same\x20address\x20tried\x20to\x20connect.Visit\x20https://discord.vdo.ninja\x20for\x20support.','decrypt','rejected','8px','_trackID','Browser','maxvb_url','TRYING\x20TO\x20RECONNECT\x201','directorActions','optimize','_bytesReceived','display','importCrypto','processDescription','screenShareState','remote_candidateType','stopPropagation','pressed','You\x27ve\x20been\x20transferred\x20to\x20a\x20different\x20room','turn:turn.obs.ninja:3478','maxsamplerate','closed','_jitter_delay','nQeTm','NYfWC','image/webp','pcs\x20RTC\x20Failed','activeSpeaker','allowmidi','enhacing\x20audio\x20encoder','send','playoutDelayHint','RSASSA-PKCS1-v1_5','nominated','UmVjX','requestStats','createDataChannel','scene','directorDisplayMute','directVideoMuted','video_muted_init','successfully\x20requested\x20audio\x20and\x20video','allowIframe','sjzqi','DrMJQ','timeout','code','onopen','keyname','frameWidth','LAtdm','OVoEs','autostart','packetsReceived','directorDisplayMuted','connectPeer','onicecandidate','Rpxog','sendRequest','bBsfv','ctrlKey','352114RoFSld','The\x20Director\x20has\x20disabled\x20your\x20vision\x20temporarily
','directorUUID','limitAudioEncoder','rAUpx','safari','joiningRoom','soloVideo','importKey','byteLength','DXKeq','room\x20rate\x20restriction\x20detected.\x20No\x20videos\x20will\x20be\x20published\x20to\x20other\x20guests','seed','cleanish','&pie','iframeEle','pbUoc','paused','empty\x20ice..','sink','canvasSource','OOO','Audio\x20processing\x20is\x20disabled\x20with\x20this\x20guest.\x20Can\x27t\x20mute\x20or\x20change\x20volume','audioEffects','muted_savedState','random','changeURL','rUkXS','NllYu','audioLevel','joinroom','obsStreaming','SHA-1','enhanceAudioEncoder','yhtsk','remoteCandidateId','_timestamp','wss','seeding','setupIncoming','abs','requestChangeLowcut','randomize','length','JLHMa','changeParams','forceTcpMode','zoomedBitrate','remoteRaisedHandElement','cZXiT','hWDcJ','RECONNECTING\x20to\x20HSS;\x20DISCONNECTING\x20FROM\x20TRANSFERRED\x20ROOM','URL','stereo_url','soloChatUUID','outboundAudioBitrate','midi','devicePixelRatio','Untitled','tainted','Media','red','steve','queuebutton','pdMjS','disconnectedTimeout','stereo\x20enabled','getVideoSettings','ERPdU','obs','IhbuR','focus\x20success','udp','offsetChannel','requestResolution','preventDefault','join','stereo','lowiosviewers','transferred','YsvWx','parse','nopreview','hanging\x20up','minptime','Websockets\x20timed\x20out;\x2020\x20seconds','webcamonly','exportKey','FHbzZ','CONNECTED\x20TO\x20FIRST\x20PEER','[data-action-type=\x22solo-chat\x22][data--u-u-i-d=\x22','ICE:\x20','key','XBGJx','stun:stun4.l.google.com:19302','generateCrypto','sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message;\x20RTC\x20peers\x20only','now','bsVdG','tkQLi','PCS\x20WINS\x20ICE','rpcs','videosource_','PlwrW','rpc\x20datachannel\x20closed','remote','1YIzwFk','activelySpeaking','slice','remote_relay_IP','cover','bind','autoGainControl','failed\x20to\x20send\x20zoom\x20change\x20request','session','You\x20are\x20not\x20the\x20director\x20of\x20this\x20room.\x20\x20You\x20will\x20have\x20limited\x20to\x20no\x20control.\x20\x20You\x20can\x20try\x20claiming\x20the\x20room\x20after\x20the\x20first\x20director\x20leaves.','mediaType','map','turn:turn-usw1.obs.ninja:443','&password=','screenShareElement','getAudioTracks','midiIn','NzoiH','readyState','taintedSession','enc','ACTION\x20REJECTED:\x20','pcm','crypto','networkPriority','setOpusAttributes','already\x20closed\x20PCS','type','jwk','opacity','seedAttempts','sendMessage','scale','remoteMuteElement','kSIYP','&pie=','jitterBufferDelay','sceneMute','label_','delayTime','wxKko','prototype','LbDiM',',\x20isDirector:\x20','infocus','UUID\x20not\x20found\x20in\x20pcs','requestKeyframe','PASSED','sXxuL','vp9','remote-candidate','framesDecoded','390577dDEXzx','production','_last_bytes','low','level','forceMediaSettings','controlTimer','eventPlayActive','showDirector','New\x20Label:\x20','1.0','TOO\x20MANY\x20PUBLISHING\x20PEERS','forceios','eKHJG','request\x20zoom\x20change:\x20','rciti','stopping\x20old\x20track','enhance','keyframerate','ab_url','cbr','interval','Bitrate_in_kbps','_packetsLost','retryTimeout','jTAUD','scaleFactor','reconnected','New\x20ON\x20TRACK\x20event','play','networkType','height_url','request\x20focus\x20change:\x20','[data-action-type=\x22order-value\x22][data--u-u-i-d=\x22','Raised\x20hand','candidates','lOTbM','requestZoomChange','GKlku','could\x20not\x20be\x20sent;\x20queuing\x20it','right','encryptMessage','mute','network_type','audioCtx\x20:\x20','audioCodecs','Remote\x20peer\x20disconnected.\x20Due\x20to\x20enhanced\x20security,\x20please\x20refresh\x20to\x20create\x20a\x20new\x20connection.','yxyqZ','osbDE','Create\x20a\x20new\x20RTC\x20connection;\x20offering\x20SDP\x20on\x20request','disableNACK','EVENT\x20TRACK\x20instead\x20of\x20event\x20Stream','uqviW','someonejoined','SDP\x20Sessions\x20Match.\x20I\x20assume\x20ADDING\x20TRACKS','failed','ydTFZ','ontrack','userAgent','mainmenu','vb_url','website','IPAsz','substr','displayMute','setScale','couldn\x27t\x20set\x20rate\x20limit','playing','iceBundle','pcs','pluginVersion','currentAudioConstraints','scaleResolutionDownBy','keyframe','echoCancellation','enhance_audio','listing','cEjpG','limitTotalBitrate','name','limitaudio','XHiLi','YvfLP','scaleResolutionDownBy\x20set\x201!','hostname','generateStreamID','Track\x20was\x20removed','tJFQT','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x202','noPLIs','Audio_Sync_Delay_ms','xeJDl','forEach','recording_audio_ctx_latency','watchStream','apply','requestVideoRecord','raisehands','Resolution','obsRecording','iVnWD','data','PCS:\x20ICE\x20Disconnected;\x20wait\x20for\x20retry?\x20pcs','iframe','MBsPE','CWUhp','^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}','QhMUC','removeChild','sending\x20message\x20to\x20server','connected\x20to\x20video\x20server','high','zoom','floor','setResolution','getSenders','hrwCb','directorVideoMuted','statsMenu','jemLZ','createOffer','allowAudio','getVideoBitrates','sendChannel','focusDistance','Change\x20Label','voiceMeter','privateKey','getRandomValues','anysend','trackIdentifier','canvasCtx','audio_level','POOTy','JIKfU','acc','seedPlz','screenshare','sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message','metaKey','yMxIx','channel','browser','Inbound\x20User-based\x20Message\x20from\x20Room','somepasswordwhere','charAt','pyiHN','failed\x20to\x20disconnect','yorVe','configuration','WeRHg','sid','TVdzK','keyFramesRequested_pli','maxpublishers','local','wss://wss13.obs.ninja:443','onnegotiationneeded','iceConnectionState','sceneSync','webp','cqHZC','stop','push','controlRoomBitrate','ihehi','vvgrX','KSjLd','vfluE','container_','constructor','remoteControl','Generate\x20Some\x20Crypto\x20keys\x20first','lowerhand','MAKING\x20A\x20NEW\x20RTC\x20CONNECTION','showlabels','sendPeers','Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit','mjGBh','?view=','_codecId','nzdUI','playback_audio_pipeline','Viewer\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit','minipreview','getTracks','view','toString','AudioContext','Press\x20OK\x20to\x20submit\x20any\x20error\x20logs\x20to\x20VDO.Ninja.\x20Error\x20logs\x20may\x20contain\x20private\x20information.','sendMsg','max','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x201','wuBTt','version','getOpusBitrate','label','pip','MediaStreamAudioDestinationNode','hangup','migrate','src','float2','bmYUE','Adjusting\x20Gain;\x20only\x20track\x200\x20in\x20all\x20likely\x20hood,\x20unless\x20more\x20than\x20track\x200\x20support\x20is\x20added.','setAudioBitrate','quality_ss','oninactive','turn:www.turn.obs.ninja:3478','KFpTQ','raTDR','Enter\x20a\x20new\x20Display\x20Name\x20for\x20this\x20stream','gOifu','reduce','delayNode','pixelFix','hands_','maxconnections','broadcastIFrame','dropped\x20candidate\x20due\x20to\x20filter','Pinging','muted','currentRoundTripTime','speakerMute','Stream\x20ID\x20pre:','lin','vdoninja','joinRoom','setLocalDescription','YzHKU','block','sign','encodings','ccifY','height','recordedBlobs','pHWBA','message','[data-action-type=\x22solo-chat\x22]','compressor','title','AYCDt','vIhtP','padStart','maxptime','mMRzy','then','bjuIo','\x20x\x20','remote_networkType','rejoining\x20room','tBjTY','audioOptions','isDirector\x20','_sync_offset','uOYmS','changeSpeaker','maxframerate_q2','concat','new-view-connection','currentTime','mMiPS','test','audioGain','sceneDisplay','mgghE','channelOffset','CLOSED','addTrack','verify','ICE\x20FAILED','SET\x20SCALING\x20IS\x20FIRING,\x20which\x20is\x20GOOD\x20!!!!!!','subtle','watchTimeoutList','packetsLost','audioMeterGuest','sendKeyFrameScenes','permaid','processIce2','offer','denoise_url','received\x20data\x20from\x20viewer','iFXiB','KsrjI','hash','eRQNP','sceneType','label=','EkwIU','bit\x20rate\x20being\x20munged','yIpdK','recorder','can\x27t\x20change\x20audio\x20bitrate;\x20no\x20audio\x20sender\x20found','mid','xyTzb','recording_audio_pipeline','FPS','limitAudio','iframe_','host','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x204','pie','allowBroadcast','requestChangeEQ','Add\x20a\x20label','directorSettings','nackCount','ZeubQ','applySoloChat','FORCE\x20KEYFRAME\x20FOR\x20SCENE','relayProtocol','VTFiG','mediaDevices','69406llFcIT','limitTotalBitrateGuests','obsStateSync','publishing\x20SDP\x20Offer:\x20','failed\x20to\x20send\x20focus\x20change\x20request','outputDevice','Firefox','uSMPY','audioCtx','offerSDP','MhgEU','YFXjs','providing\x20answer','queueList','noiseSuppression','rlxns','THIS\x20SHOULD\x20BE\x20DELETED','ytKah','hwSRU','click','location','img','delta','value\x20there','watchTimeoutList:','JTSCM','gnHtJ','oqCPu','bitrateTimeout','1331mTrSPH','problem','queue','IikNa','Answer\x20SDP\x20does\x20not\x20have\x20a\x20matching\x20session\x20ID','videoOptions','xCWLU','streamSrc','encrypt','The\x20director\x20wishes\x20to\x20redirect\x20you\x20to\x20the\x20URL:\x20','resolution\x20scale:\x20','video\x20element\x20is\x20being\x20created\x20and\x20media\x20track\x20added','[data-action-type=\x22volume\x22][data--u-u-i-d=\x22','visible','inline-block','state','getReceivers','mPYrF','sendroom','no\x20audio\x20track\x20to\x20poke','buffer','mag','ikQwY','poLIx','split','msg','speedtest','AvEZB','ptime','gainNode','bitrate','WTLth','resume','queueNotification','iceServers','hAcju','ICE\x20closed?','disableOBS','chrome','stringify','QEIaq','allowVideo','hssConnection','requestAudioHack','maxBitrate','RTC\x20already\x20connected','2px','videoElement','https://reports.obs.ninja/','screensharefps','video/VP8','ooPhW','bitrate_set','CAMERA/MIC\x20SOURCE\x20ALLOCATION\x20FAILED.\x20Cant\x27\x20share\x20media\x20streams\x20as\x20a\x20result.\x20Maybe\x20this\x20is\x20a\x20Director\x20joining?','turn:turn-eu2.obs.ninja:3478','changeLabel','anyrequest','className','VIDEO\x20TRACK;\x20already\x20one\x20added','audio\x20bandwidth\x20set!','remoteStats','createObjectURL','Someone\x20Joined\x20the\x20Room','audiobitrate','OBS\x20PLI\x20FIX\x20MODE\x20ON','packetLoss_in_percentage','targetBandwidth','fromCharCode','RTC\x20connection\x20is\x20ALREADY\x20ready;\x20we\x20can\x20already\x20accept\x20answers','iframeSrc','11GNdigQ','remoteMuteState_','ROOMID\x20EANBLED','maxframerate','localDescription','&room=','gXGvq','10px','20255kZDmRn','You\x27ve\x20been\x20transferred','indexOf','running','voiceMeterTemplate','_local_ice_id','enhanceaudio','setVideoScale','broadcastChannel','Stream\x20ID\x20is\x20already\x20in\x20use.','NO\x20TRACK??\x20--\x20not\x20expected','uRqbW','receiveChannel','directorSpeakerMuted','sticky','gVRKy','post\x20pixel\x20fix\x20','windowed','clicked','fPDSi','TRYING\x20KEYFRAME','labelstyle','MrycE','The\x20stream\x20ID\x20you\x20are\x20publishing\x20to\x20is\x20already\x20in\x20use.\x0a\x0aPlease\x20try\x20with\x20a\x20different\x20invite\x20link\x20or\x20refresh\x20to\x20retry\x20again.\x0a\x0aYou\x20will\x20now\x20be\x20disconnected.','playback_audio_volume_meter','connectionState','delay','maxiosbitrate','inboundAudioPipeline','UN-MUTED','labelsize','PUBLISHER\x27s\x20RTC\x20Connection\x20seems\x20to\x20be\x20dead?\x20','requestAudioRateLimit','audioDevice','changeCamera','seedStream','createAnswer','cleanup','Mute\x20video\x20-306','send\x20channel\x20closed','hjrKk','ESXBY','connect','candidate','span','listPromise','ynafY','totalRoomBitrate','updating\x20audio\x20delay','Your\x20room\x20has\x20changed','slrMX','RPCS\x20WINS\x20ICE','nextQueue','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x203','session.videoElement.srcObject\x20failed;\x20but\x20streamSrc\x20worked?','hGLcY','Remote\x20peer\x20connected\x20to\x20video\x20stream.\x0a\x0aConnection\x20to\x20handshake\x20server\x20being\x20killed\x20on\x20request.\x20This\x20increases\x20security,\x20but\x20the\x20peer\x20will\x20not\x20be\x20able\x20to\x20reconnect\x20automatically\x20on\x20connection\x20failure.\x0a\x0aPress\x20OK\x20to\x20start\x20the\x20stream!','stun:stun.l.google.com:19302','candidateType','connected','maxTouchPoints','generateKey','claim','Members\x20in\x20Room','new-push-connection','controls','streamID','ukHJp','setup\x20peer\x20complete','directorVolumeState','UUID','sort','hash\x20is\x20','webAudios','beepToNotify','setValueAtTime','EhSrd','disableREMB','create\x20offer\x20worked','processIceBundle','hash\x20is\x20not\x20false','sensorData','screensharequality','remoteVideoMuteElement','noFkd','TkfnO','can\x27t\x20change\x20bitrate;\x20no\x20video\x20sender\x20found','WVams','scaleHeight','showSettings','OCJru','priority','GOT\x20ICES!!','FMYEv','pointer','inbound-rtp','parentNode','forcePLI','iOS\x20guest\x20SCALE\x20set!','getCapabilities','streaming','setBitrate','left','pliCount','savedBitrate','outboundVideoBitrate','maxvideobitrate','SHA-256','..\x20waiting\x20for\x20user\x20gesture','scaleResolution','cameraConstraints','recording_audio_gain','closedCaptions','optimizedBitrate','Lowered\x20hand','uQnoA','rampUpTime','limitAudioBitrate','disableWebAudio','AES-CBC','ASKING\x20FOR\x20AUDIO\x20AND\x20VIDEO?','directorSpeakerMute','optimizeBitrate','playoutdelay','fpQSZ','new','hangupDirector','Incoming\x20Ice\x20Offer\x20does\x20not\x20match\x20Session','scaleResolutionDownBy\x20set\x202!','_packetsReceived','_last_time','codec','pleaseDoNotAbuse','trying\x20to\x20play','TrRUz','cleanOutput','dynamicScale','find','fadein','RTC\x20Connection','seeding\x20!!','suspended','from','guest','bEzER','candidate-pair','_frameWidth','obsfix','startTime','manual','_codecIdTrackId','micDelay','dataset','Safari','order','decryptMessage','encode','_remote_ice_id','postMessage','roombitrate','getVideoTracks','XHjzL','kiJMF','play\x20stream:\x20','getElementById','IeHTh','RTIXU','none','local_relayProtocol','session.pcs[UUID].scale\x20=\x20','SmteU','POST','ICE\x20FAILed.\x20bad?','audioConstraints','value','getSettings','playback_audio_samplerate','querySelectorAll','salt','remoteDescription','onremovetrack','videoMuted','toggleSoloChat','width','frameHeight','credential','qkPlj','UbmSL','Room\x20is\x20already\x20claimed\x20by\x20someone\x20else.','LPDIY','RTCRtpSender','platform','zoom\x20success','ONqBV','mJcUk','VzfkX','requestFocusChange','cNghV'];var _0x3f0262=_0x3a98;(function(_0x720a6,_0xea4160){var _0x10e9be=_0x3a98;while(!![]){try{var _0x255886=parseInt(_0x10e9be(0x302))*parseInt(_0x10e9be(0x2ce))+-parseInt(_0x10e9be(0x49e))*parseInt(_0x10e9be(0x4a6))+parseInt(_0x10e9be(0x43b))+parseInt(_0x10e9be(0x19d))*-parseInt(_0x10e9be(0x458))+-parseInt(_0x10e9be(0x264))+parseInt(_0x10e9be(0x1e8))+parseInt(_0x10e9be(0x5f2));if(_0x255886===_0xea4160)break;else _0x720a6['push'](_0x720a6['shift']());}catch(_0x4587c3){_0x720a6['push'](_0x720a6['shift']());}}}(_0x5b9d,0x3cfd6));function log(_0x20904d){}function warnlog(_0x6f76ec,_0x3ad64a=![],_0x44c8cb=![]){if(_0x44c8cb){}}function errorlog(_0x22ea58,_0x2b9ee5=![],_0x31b3c4=![]){appendDebugLog(_0x22ea58);if(_0x31b3c4){}}window['onerror']=function backupErr(_0x3796f4,_0x357114=![],_0x444916=![]){var _0x2f0501=_0x3a98;return errorlog(_0x3796f4),errorlog(_0x444916),errorlog(_0x2f0501(0x5c4)),appendDebugLog(_0x3796f4),_0x444916&&appendDebugLog(_0x444916),![];},window['AudioContext']=window[_0x3f0262(0x3be)]||window['webkitAudioContext'];function getById(_0x19442f){var _0x577566=_0x3f0262,_0x45daeb=document['getElementById'](_0x19442f);return!_0x45daeb&&(warnlog(_0x19442f+'\x20is\x20not\x20defined;\x20skipping.'),_0x45daeb=document[_0x577566(0x190)](_0x577566(0x4d2))),_0x45daeb;}var errorReport=[];function appendDebugLog(_0xbfa4a3){var _0x5329c8=_0x3f0262;try{if(_0x5329c8(0x41d)===_0x5329c8(0x41d)){var _0x17a0e9=new Date(),_0x3875fa=_0x17a0e9['getTime']();if(_0xbfa4a3[_0x5329c8(0x3ef)])errorReport['push']({'message':_0xbfa4a3['message'],'name':_0xbfa4a3[_0x5329c8(0x351)],'time':_0x3875fa});else typeof _0xbfa4a3===_0x5329c8(0x5d7)?errorReport[_0x5329c8(0x3a5)]({'note':_0xbfa4a3,'time':_0x3875fa}):errorReport[_0x5329c8(0x3a5)]({'other':_0xbfa4a3,'time':_0x3875fa});errorReport=errorReport[_0x5329c8(0x2d0)](-0xc8),document[_0x5329c8(0x54a)](_0x5329c8(0x163))&&(getById(_0x5329c8(0x163))[_0x5329c8(0x1a2)][_0x5329c8(0x202)]=_0x5329c8(0x465));}else!_0x30d35b[_0x5329c8(0x1e7)]&&_0x3e6bd7(function(){var _0x5f579d=_0x5329c8;_0x58cac4(_0x5f579d(0x1f8));},0x1);}catch(_0x3d1a11){}}function submitDebugLog(_0x4bb505){var _0x3bb91b=_0x3f0262;try{appendDebugLog({'connection_type':session['stats'][_0x3bb91b(0x32d)]});if(navigator[_0x3bb91b(0x33c)]){var _0x21085d,_0x21ed56=navigator[_0x3bb91b(0x33c)];appendDebugLog({'userAgent':_0x21ed56});}navigator['platform']&&appendDebugLog({'userAgent':navigator[_0x3bb91b(0x565)]});}catch(_0x3302de){}window[_0x3bb91b(0x174)]();var _0x57336c=confirm(_0x3bb91b(0x3bf));if(_0x57336c){var _0x40408d=new XMLHttpRequest();_0x40408d['open'](_0x3bb91b(0x551),_0x3bb91b(0x488)),_0x40408d['send'](JSON[_0x3bb91b(0x47f)](errorReport)),errorReport=[],document['getElementById'](_0x3bb91b(0x163))&&(getById(_0x3bb91b(0x163))[_0x3bb91b(0x1a2)][_0x3bb91b(0x202)]=_0x3bb91b(0x5dc));}}function isAlphaNumeric(_0x2eb2c6){var _0x536ef3=_0x3f0262,_0x172ace,_0x5c3e71,_0x38a502;for(_0x5c3e71=0x0,_0x38a502=_0x2eb2c6[_0x536ef3(0x28f)];_0x5c3e71<_0x38a502;_0x5c3e71++){_0x172ace=_0x2eb2c6[_0x536ef3(0x5a9)](_0x5c3e71);if(!(_0x172ace>0x2f&&_0x172ace<0x3a)&&!(_0x172ace>0x40&&_0x172ace<0x5b)&&!(_0x172ace>0x60&&_0x172ace<0x7b)){if(_0x536ef3(0x259)!==_0x536ef3(0x274))return![];else return;}}return!![];}var iOS=!!navigator['platform']&&/iPad|iPhone|iPod/['test'](navigator[_0x3f0262(0x565)]),iPad=navigator[_0x3f0262(0x4e2)]&&navigator['maxTouchPoints']>0x2&&/MacIntel/['test'](navigator['platform']);function play(_0x1587a6=null){var _0x2a0d7c=_0x3f0262;log(_0x2a0d7c(0x549)+session[_0x2a0d7c(0x3bc)]);if(session[_0x2a0d7c(0x3bc)]==='')log(_0x2a0d7c(0x5c2));else{if(session[_0x2a0d7c(0x3bc)]!==![]){var _0x474abd=session[_0x2a0d7c(0x3bc)][_0x2a0d7c(0x470)](',');for(var _0x50d68c in _0x474abd){if(_0x474abd[_0x50d68c]==''){}else{if(_0x1587a6===null)session[_0x2a0d7c(0x360)](_0x474abd[_0x50d68c]);else{if(_0x1587a6===_0x474abd[_0x50d68c])session[_0x2a0d7c(0x360)](_0x474abd[_0x50d68c]);else{}}}}}else{if(session[_0x2a0d7c(0x226)]!==![]){if(session[_0x2a0d7c(0x226)][_0x2a0d7c(0x5cf)](_0x1587a6)){}else session['watchStream'](_0x1587a6);}else _0x1587a6&&session[_0x2a0d7c(0x360)](_0x1587a6);}}}function showControlBar(_0x3c7c07){var _0x2b825c=_0x3f0262;try{_0x3c7c07[_0x2b825c(0x4e7)]=!![];}catch(_0x46f4af){errorlog(_0x46f4af);}}function playAllVideos(){var _0x319d15=_0x3f0262;for(var _0x3619bc in session[_0x319d15(0x2c9)]){try{session['rpcs'][_0x3619bc]['videoElement']&&(session['rpcs'][_0x3619bc][_0x319d15(0x487)]['paused']&&session[_0x319d15(0x2c9)][_0x3619bc][_0x319d15(0x487)][_0x319d15(0x31f)]()[_0x319d15(0x3f8)](_0x34ade9=>{var _0x5304dc=_0x319d15;if(_0x5304dc(0x4a4)===_0x5304dc(0x54b)){if(_0x485665[_0x5304dc(0x1fa)]){if(_0x3096e0[_0x5304dc(0x4d1)][_0x5304dc(0x4d1)][_0x5304dc(0x4a8)](_0x421856[_0x5304dc(0x1fa)])===-0x1){_0x2e615d(_0x5304dc(0x3dd)),_0x95d99e(_0x2cc13d[_0x5304dc(0x4d1)]);return;}else _0x86444f('PASSED'),_0x1c3832(_0x2546ab['candidate']);}}else log(_0x5304dc(0x345));})[_0x319d15(0x5fa)](warnlog));}catch(_0x316642){}}}function _0x3a98(_0x33f01f,_0x20b791){_0x33f01f=_0x33f01f-0x15b;var _0x955ffe=_0x5b9d[_0x33f01f];return _0x955ffe;}function getTURNList(){var _0x790394=_0x3f0262,_0x3008a2=[];turn={},turn['username']='steve',turn[_0x790394(0x55f)]=_0x790394(0x1aa),turn[_0x790394(0x183)]=[_0x790394(0x5b7)],turn['tz']=0x12c,turn['udp']=![],turn[_0x790394(0x303)]=!![];if(session[_0x790394(0x472)]&&turn[_0x790394(0x2ac)]==session[_0x790394(0x292)]){}else{if(session[_0x790394(0x292)]&&turn[_0x790394(0x2ac)]){}else{if(session[_0x790394(0x472)]==![]&&turn[_0x790394(0x303)]==![]){}else _0x3008a2[_0x790394(0x3a5)](turn);}}turn={},turn[_0x790394(0x1f2)]='steve',turn[_0x790394(0x55f)]=_0x790394(0x1aa),turn[_0x790394(0x183)]=[_0x790394(0x3d2)],turn['tz']=0x12c,turn[_0x790394(0x2ac)]=!![],turn[_0x790394(0x303)]=!![];if(session[_0x790394(0x472)]&&turn[_0x790394(0x2ac)]==session[_0x790394(0x292)]){}else{if(session['forceTcpMode']&&turn[_0x790394(0x2ac)]){}else{if(session[_0x790394(0x472)]==![]&&turn[_0x790394(0x303)]==![]){}else _0x3008a2[_0x790394(0x3a5)](turn);}}turn={},turn[_0x790394(0x1f2)]=_0x790394(0x2a2),turn['credential']=_0x790394(0x1aa),turn[_0x790394(0x183)]=['turns:turn.obs.ninja:443'],turn['tz']=-0x3c,turn['udp']=![],turn['production']=!![];if(session[_0x790394(0x472)]&&turn[_0x790394(0x2ac)]==session[_0x790394(0x292)]){}else{if(session[_0x790394(0x292)]&&turn[_0x790394(0x2ac)]){}else{if(session[_0x790394(0x472)]==![]&&turn[_0x790394(0x303)]==![]){}else _0x3008a2[_0x790394(0x3a5)](turn);}}turn={},turn[_0x790394(0x1f2)]=_0x790394(0x2a2),turn['credential']=_0x790394(0x1aa),turn[_0x790394(0x183)]=[_0x790394(0x23a)],turn['tz']=-0x3c,turn['udp']=!![],turn[_0x790394(0x303)]=![];if(session[_0x790394(0x472)]&&turn['udp']==session['forceTcpMode']){}else{if(session[_0x790394(0x292)]&&turn[_0x790394(0x2ac)]){}else{if(session['speedtest']==![]&&turn[_0x790394(0x303)]==![]){}else _0x3008a2[_0x790394(0x3a5)](turn);}}turn={},turn['username']='steves',turn['credential']=_0x790394(0x52a),turn['urls']=[_0x790394(0x2da)],turn['tz']=0x1e0,turn[_0x790394(0x2ac)]=!![],turn['production']=!![];if(session[_0x790394(0x472)]&&turn[_0x790394(0x2ac)]==session[_0x790394(0x292)]){}else{if(session['forceTcpMode']&&turn[_0x790394(0x2ac)]){}else{if(session[_0x790394(0x472)]==![]&&turn[_0x790394(0x303)]==![]){}else _0x3008a2[_0x790394(0x3a5)](turn);}}turn={},turn[_0x790394(0x1f2)]=_0x790394(0x5cc),turn[_0x790394(0x55f)]=_0x790394(0x52a),turn[_0x790394(0x183)]=['turn:turn-usc1.obs.ninja:3478'],turn['tz']=0x168,turn[_0x790394(0x2ac)]=!![],turn[_0x790394(0x303)]=!![];if(session[_0x790394(0x472)]&&turn[_0x790394(0x2ac)]==session[_0x790394(0x292)]){}else{if(session[_0x790394(0x292)]&&turn['udp']){}else{if(session[_0x790394(0x472)]==![]&&turn['production']==![]){}else _0x3008a2[_0x790394(0x3a5)](turn);}}turn={},turn[_0x790394(0x1f2)]=_0x790394(0x3e4),turn[_0x790394(0x55f)]=_0x790394(0x392),turn[_0x790394(0x183)]=[_0x790394(0x586)],turn['tz']=-0x258,turn[_0x790394(0x2ac)]=!![],turn[_0x790394(0x303)]=!![];if(session[_0x790394(0x472)]&&turn['udp']==session[_0x790394(0x292)]){}else{if(session[_0x790394(0x292)]&&turn[_0x790394(0x2ac)]){}else{if(session['speedtest']==![]&&turn[_0x790394(0x303)]==![]){}else _0x3008a2['push'](turn);}}turn={},turn[_0x790394(0x1f2)]=_0x790394(0x5cc),turn[_0x790394(0x55f)]=_0x790394(0x1cb),turn['urls']=[_0x790394(0x48e)],turn['tz']=-0x3c,turn[_0x790394(0x2ac)]=!![],turn['production']=!![];if(session[_0x790394(0x472)]&&turn[_0x790394(0x2ac)]==session[_0x790394(0x292)]){}else{if(session[_0x790394(0x292)]&&turn[_0x790394(0x2ac)]){}else{if(session[_0x790394(0x472)]==![]&&turn[_0x790394(0x303)]==![]){}else _0x3008a2[_0x790394(0x3a5)](turn);}}return _0x3008a2;}function chooseBestTURN(){var _0x1f25b4=_0x3f0262;if(session[_0x1f25b4(0x397)])return;var _0x3df202=getTURNList(),_0x377acd=new Date(),_0x89bc2=_0x377acd[_0x1f25b4(0x1be)]();for(var _0x472d0b=0x0;_0x472d0b<_0x3df202[_0x1f25b4(0x28f)];_0x472d0b++){var _0x2eb203=Math[_0x1f25b4(0x28c)](_0x3df202[_0x472d0b]['tz']-_0x89bc2);Math[_0x1f25b4(0x28c)](_0x2eb203-0x3c*0x18)<_0x2eb203&&(_0x2eb203=Math[_0x1f25b4(0x28c)](_0x2eb203-0x3c*0x18)),_0x3df202[_0x472d0b][_0x1f25b4(0x451)]=_0x2eb203;}_0x3df202[_0x1f25b4(0x4ed)](compare_deltas),_0x3df202=_0x3df202['slice'](0x0,0x3),session[_0x1f25b4(0x397)]={'iceServers':[{'urls':[_0x1f25b4(0x4df),_0x1f25b4(0x2c2)]}],'sdpSemantics':'unified-plan'},session[_0x1f25b4(0x397)][_0x1f25b4(0x47a)]=session[_0x1f25b4(0x397)][_0x1f25b4(0x47a)][_0x1f25b4(0x404)](_0x3df202),log(session[_0x1f25b4(0x397)]);}function compare_deltas(_0x4db900,_0x579137){var _0x3b5895=_0x3f0262,_0x247ffc=_0x4db900[_0x3b5895(0x451)]||0x0,_0x1cabf6=_0x579137[_0x3b5895(0x451)]||0x0;if(_0x247ffc>_0x1cabf6)return 0x1;if(_0x247ffc<_0x1cabf6)return-0x1;return 0x0;}function compare_vids(_0x408b0e,_0x43672f){var _0x42678b=_0x3f0262,_0x59b407=_0x408b0e[_0x42678b(0x540)]||0x0,_0x3c28b5=_0x43672f[_0x42678b(0x540)]||0x0;if(_0x59b407<_0x3c28b5)return 0x1;if(_0x59b407>_0x3c28b5)return-0x1;return 0x0;}var updateMixerTimer=null,updateMixerActive=![];function updateMixer(_0x5a3f2a=![]){clearInterval(updateMixerTimer);if(updateMixerActive){updateMixerTimer=setTimeout(function(){updateMixer();},0x1f4);return;}updateMixerActive=!![];try{updateMixerRun(_0x5a3f2a);}catch(_0x567b04){}updateMixerActive=![];}var WebRTC={};WebRTC[_0x3f0262(0x2a0)]=function(){var _0x41b841=_0x3f0262,_0x24dd1e=function(){var _0x22b6c4=!![];return function(_0x2ea90b,_0x350f12){var _0x1f1b7a=_0x22b6c4?function(){var _0x3a52ae=_0x3a98;if(_0x350f12){var _0x524bc0=_0x350f12[_0x3a52ae(0x361)](_0x2ea90b,arguments);return _0x350f12=null,_0x524bc0;}}:function(){};return _0x22b6c4=![],_0x1f1b7a;};}(),_0x2765f6=_0x24dd1e(this,function(){var _0x2d4846=function(){var _0x83e135=_0x3a98,_0xb46c96=_0x2d4846[_0x83e135(0x3ac)](_0x83e135(0x1a9))()[_0x83e135(0x3ac)](_0x83e135(0x36c));return!_0xb46c96[_0x83e135(0x408)](_0x2765f6);};return _0x2d4846();});_0x2765f6();var _0x4bb952={};function _0x221526(){}function _0x3d616f(_0x40983d){errorlog(_0x40983d);}function _0x40edff(){var _0x10bc19=_0x3a98,_0x4b13d3,_0x55c7c7,_0x52a98e=new Promise((_0x56ff05,_0x53de1f)=>{_0x4b13d3=_0x56ff05,_0x55c7c7=_0x53de1f;});return _0x52a98e['resolve']=_0x4b13d3,_0x52a98e[_0x10bc19(0x5d8)]=_0x55c7c7,_0x52a98e;}_0x4bb952['noaudio']=![],_0x4bb952[_0x41b841(0x16f)]=![],_0x4bb952[_0x41b841(0x242)]=![],_0x4bb952[_0x41b841(0x2cf)]=!![],_0x4bb952[_0x41b841(0x497)]=![],_0x4bb952[_0x41b841(0x5e2)]=0x8,_0x4bb952[_0x41b841(0x4c7)]=![],_0x4bb952[_0x41b841(0x440)]=![],_0x4bb952[_0x41b841(0x409)]=![],_0x4bb952[_0x41b841(0x415)]=!![],_0x4bb952['audioEffects']=null,_0x4bb952[_0x41b841(0x1f0)]=![],_0x4bb952[_0x41b841(0x25b)]=![],_0x4bb952[_0x41b841(0x443)]=new AudioContext(),_0x4bb952['aspectratio']=![],_0x4bb952[_0x41b841(0x599)]=![],_0x4bb952[_0x41b841(0x34c)]=null,_0x4bb952['autoGainControl']=null,_0x4bb952[_0x41b841(0x449)]=null,_0x4bb952[_0x41b841(0x1db)]=![],_0x4bb952[_0x41b841(0x4ae)]=![],_0x4bb952[_0x41b841(0x3dc)]=![],_0x4bb952['bigmutebutton']=![],_0x4bb952[_0x41b841(0x476)]=![],_0x4bb952[_0x41b841(0x48c)]=![],_0x4bb952[_0x41b841(0x46c)]=![],_0x4bb952[_0x41b841(0x4f0)]=![],_0x4bb952[_0x41b841(0x5fc)]=null,_0x4bb952[_0x41b841(0x278)]=null,_0x4bb952[_0x41b841(0x3a6)]=![],_0x4bb952[_0x41b841(0x1bd)]=![],_0x4bb952[_0x41b841(0x52d)]=![],_0x4bb952[_0x41b841(0x271)]=![],_0x4bb952['closedCaptions']=![],_0x4bb952[_0x41b841(0x397)]=![],_0x4bb952[_0x41b841(0x3f1)]=![],_0x4bb952[_0x41b841(0x17a)]=![],_0x4bb952['codec']=![],_0x4bb952[_0x41b841(0x4b4)]=![],_0x4bb952[_0x41b841(0x316)]=0x1,_0x4bb952[_0x41b841(0x2d2)]=![],_0x4bb952['chatbutton']=null,_0x4bb952[_0x41b841(0x514)]={},_0x4bb952[_0x41b841(0x553)]={},_0x4bb952[_0x41b841(0x1e2)]={},_0x4bb952[_0x41b841(0x349)]={},_0x4bb952[_0x41b841(0x58e)]=![],_0x4bb952[_0x41b841(0x579)]=0x23,_0x4bb952['hiddenSceneViewBitrate']=0x190,_0x4bb952[_0x41b841(0x293)]=0x25a,_0x4bb952[_0x41b841(0x5c0)]=![],_0x4bb952[_0x41b841(0x1b8)]=![],_0x4bb952[_0x41b841(0x18f)]=![],_0x4bb952[_0x41b841(0x1ab)]=![],_0x4bb952[_0x41b841(0x4b3)]=null,_0x4bb952[_0x41b841(0x25d)]=null,_0x4bb952['directorUUID']=![],_0x4bb952[_0x41b841(0x47d)]=![],_0x4bb952[_0x41b841(0x52e)]=!![],_0x4bb952['effects']=null,_0x4bb952[_0x41b841(0x217)]=![],_0x4bb952[_0x41b841(0x21b)]=![],_0x4bb952[_0x41b841(0x2e2)]=new TextEncoder(_0x41b841(0x1ee)),_0x4bb952[_0x41b841(0x226)]=![],_0x4bb952[_0x41b841(0x4c4)]=![],_0x4bb952[_0x41b841(0x350)]=![],_0x4bb952[_0x41b841(0x530)]=![],_0x4bb952['firstPlayTriggered']=![],_0x4bb952[_0x41b841(0x21a)]=![],_0x4bb952['framerate']=![],_0x4bb952[_0x41b841(0x37e)]=![],_0x4bb952[_0x41b841(0x30e)]=![],_0x4bb952[_0x41b841(0x307)]=![],_0x4bb952[_0x41b841(0x583)]=![],_0x4bb952['hash']=![],_0x4bb952[_0x41b841(0x3ec)]=![],_0x4bb952[_0x41b841(0x49d)]=![],_0x4bb952[_0x41b841(0x273)]=![],_0x4bb952['noiframe']=![],_0x4bb952[_0x41b841(0x56c)]=![],_0x4bb952['quality_wb']=0x1,_0x4bb952[_0x41b841(0x3d0)]=0x0,_0x4bb952[_0x41b841(0x1fa)]=![],_0x4bb952[_0x41b841(0x2fa)]=![],_0x4bb952[_0x41b841(0x26a)]=![],_0x4bb952[_0x41b841(0x3c6)]=![],_0x4bb952[_0x41b841(0x314)]=![],_0x4bb952[_0x41b841(0x589)]={},_0x4bb952[_0x41b841(0x53d)]=![],_0x4bb952[_0x41b841(0x1b9)]=![],_0x4bb952['maxpublishers']=![],_0x4bb952[_0x41b841(0x3db)]=![],_0x4bb952['mobile']=![],_0x4bb952[_0x41b841(0x4a1)]=![],_0x4bb952[_0x41b841(0x403)]=![],_0x4bb952[_0x41b841(0x510)]=![],_0x4bb952[_0x41b841(0x23b)]=![],_0x4bb952[_0x41b841(0x3f6)]=![],_0x4bb952['minptime']=![],_0x4bb952[_0x41b841(0x474)]=![],_0x4bb952[_0x41b841(0x4c1)]=0x19,_0x4bb952[_0x41b841(0x2b2)]=0xa,_0x4bb952[_0x41b841(0x1d1)]=![],_0x4bb952[_0x41b841(0x53b)]=![],_0x4bb952[_0x41b841(0x5aa)]=![],_0x4bb952['midiOut']=![],_0x4bb952[_0x41b841(0x2de)]=![],_0x4bb952[_0x41b841(0x3ba)]=![],_0x4bb952['mirrored']=![],_0x4bb952['mirrorExclude']=![],_0x4bb952[_0x41b841(0x471)]=[],_0x4bb952[_0x41b841(0x3df)]=![],_0x4bb952[_0x41b841(0x27c)]=![],_0x4bb952['mono']=![],_0x4bb952[_0x41b841(0x5c8)]={},_0x4bb952[_0x41b841(0x5b0)]=![],_0x4bb952[_0x41b841(0x5ac)]=![],_0x4bb952[_0x41b841(0x35b)]=![],_0x4bb952[_0x41b841(0x1b6)]=![],_0x4bb952[_0x41b841(0x539)]=![],_0x4bb952[_0x41b841(0x2ad)]=![],_0x4bb952[_0x41b841(0x230)]=![],_0x4bb952[_0x41b841(0x204)]={},_0x4bb952[_0x41b841(0x204)][_0x41b841(0x202)]=null,_0x4bb952['obsState'][_0x41b841(0x50a)]=null,_0x4bb952[_0x41b841(0x204)][_0x41b841(0x203)]=null,_0x4bb952[_0x41b841(0x204)][_0x41b841(0x1eb)]=null,_0x4bb952[_0x41b841(0x204)][_0x41b841(0x203)]=null,_0x4bb952[_0x41b841(0x50f)]=![],_0x4bb952['outboundAudioBitrate']=![],_0x4bb952[_0x41b841(0x540)]=![],_0x4bb952[_0x41b841(0x208)]=![],_0x4bb952[_0x41b841(0x347)]={},_0x4bb952[_0x41b841(0x3c7)]=![],_0x4bb952[_0x41b841(0x42f)]=![],_0x4bb952[_0x41b841(0x2e4)]=![],_0x4bb952[_0x41b841(0x417)]=![],_0x4bb952[_0x41b841(0x201)]=![],_0x4bb952[_0x41b841(0x20b)]=null,_0x4bb952[_0x41b841(0x2b6)]=null,_0x4bb952[_0x41b841(0x45a)]=![],_0x4bb952[_0x41b841(0x448)]=[],_0x4bb952[_0x41b841(0x5f0)]=![],_0x4bb952[_0x41b841(0x28e)]=![],_0x4bb952[_0x41b841(0x3ed)]=![],_0x4bb952['recordLocal']=![],_0x4bb952[_0x41b841(0x2cd)]=![],_0x4bb952[_0x41b841(0x51a)]=0xbb8,_0x4bb952[_0x41b841(0x363)]=![],_0x4bb952[_0x41b841(0x31a)]=0x1388,_0x4bb952[_0x41b841(0x575)]=![],_0x4bb952[_0x41b841(0x1e0)]=![],_0x4bb952['roombitrate']=![],_0x4bb952['ptz']=![],_0x4bb952['rpcs']={},_0x4bb952[_0x41b841(0x59b)]=![],_0x4bb952[_0x41b841(0x558)]='',_0x4bb952[_0x41b841(0x2ee)]=![],_0x4bb952[_0x41b841(0x24c)]=![],_0x4bb952['sceneList']={},_0x4bb952[_0x41b841(0x38b)]=![],_0x4bb952[_0x41b841(0x2dc)]=![],_0x4bb952[_0x41b841(0x19b)]=![],_0x4bb952[_0x41b841(0x4f8)]=![],_0x4bb952[_0x41b841(0x489)]=![],_0x4bb952[_0x41b841(0x235)]=![],_0x4bb952[_0x41b841(0x5d6)]=![],_0x4bb952[_0x41b841(0x28a)]=![],_0x4bb952[_0x41b841(0x4f7)]=![],_0x4bb952[_0x41b841(0x2ec)]=0x0,_0x4bb952[_0x41b841(0x29d)]=![],_0x4bb952[_0x41b841(0x3b1)]=![],_0x4bb952['showList']=null,_0x4bb952[_0x41b841(0x4bb)]=![],_0x4bb952[_0x41b841(0x29a)]=![],_0x4bb952[_0x41b841(0x4ff)]=!![],_0x4bb952['showDirector']=![],_0x4bb952[_0x41b841(0x277)]=![],_0x4bb952[_0x41b841(0x1d8)]=![],_0x4bb952[_0x41b841(0x20a)]=![],_0x4bb952[_0x41b841(0x5c3)]={},_0x4bb952[_0x41b841(0x420)]=![],_0x4bb952[_0x41b841(0x378)]=![],_0x4bb952[_0x41b841(0x2b1)]=![],_0x4bb952[_0x41b841(0x4e8)]=null,_0x4bb952['streamSrc']=null,_0x4bb952[_0x41b841(0x1a2)]=![],_0x4bb952[_0x41b841(0x5ef)]=![],_0x4bb952[_0x41b841(0x292)]=![],_0x4bb952[_0x41b841(0x4d5)]=![],_0x4bb952['totalRoomBitrate_default']=0x1f4,_0x4bb952[_0x41b841(0x3f2)]=_0x41b841(0x29e),_0x4bb952['tfliteModule']=![],_0x4bb952['transparent']=![],_0x4bb952[_0x41b841(0x2e1)]=![],_0x4bb952[_0x41b841(0x5e6)]=![],_0x4bb952[_0x41b841(0x2b3)]=![],_0x4bb952['videoDevice']=![],_0x4bb952[_0x41b841(0x487)]=![],_0x4bb952[_0x41b841(0x55b)]=![],_0x4bb952[_0x41b841(0x377)]=![],_0x4bb952[_0x41b841(0x15b)]=![],_0x4bb952['view']=![],_0x4bb952['view_set']=![],_0x4bb952[_0x41b841(0x1f4)]=0x64,_0x4bb952[_0x41b841(0x55d)]=![],_0x4bb952['zoom']=![],_0x4bb952[_0x41b841(0x51c)]=![],_0x4bb952[_0x41b841(0x413)]={},_0x4bb952[_0x41b841(0x4ef)]={},_0x4bb952[_0x41b841(0x2ba)]=![],_0x4bb952[_0x41b841(0x4b7)]=![],_0x4bb952[_0x41b841(0x1ad)]={},_0x4bb952['webp']=![],_0x4bb952['webPquality']=![],_0x4bb952['ws']=null,_0x4bb952[_0x41b841(0x289)]=![],_0x4bb952[_0x41b841(0x33f)]=![],_0x4bb952[_0x41b841(0x3c4)]=null,_0x4bb952['updateLocalStatsInterval']=null,_0x4bb952[_0x41b841(0x4ec)]=![],_0x4bb952[_0x41b841(0x587)]=getById(_0x41b841(0x5fb))[_0x41b841(0x194)](!![]),_0x4bb952['localMuteElement'][_0x41b841(0x1a2)][_0x41b841(0x193)]=_0x41b841(0x58a),_0x4bb952['localMuteElement'][_0x41b841(0x1a2)]['right']=_0x41b841(0x58a),_0x4bb952[_0x41b841(0x587)]['id']='localMuteElement',_0x4bb952[_0x41b841(0x380)]=getById(_0x41b841(0x4aa))[_0x41b841(0x194)](!![]),_0x4bb952['voiceMeter']['id']='localVoiceMeter',_0x4bb952['voiceMeter'][_0x41b841(0x1a2)][_0x41b841(0x2eb)]=0x0,_0x4bb952[_0x41b841(0x380)][_0x41b841(0x53e)][_0x41b841(0x306)]=0x0,_0x4bb952[_0x41b841(0x380)][_0x41b841(0x1a2)][_0x41b841(0x55d)]=_0x41b841(0x4a5),_0x4bb952[_0x41b841(0x380)]['style'][_0x41b841(0x3ec)]=_0x41b841(0x4a5),_0x4bb952[_0x41b841(0x380)][_0x41b841(0x1a2)]['top']=_0x41b841(0x22a),_0x4bb952[_0x41b841(0x380)][_0x41b841(0x1a2)][_0x41b841(0x32a)]='10px',_0x4bb952[_0x41b841(0x357)]=function(_0x135ab9=0x7){var _0x48b384=_0x41b841,_0x478c95='',_0x453915='ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';for(var _0x4d7f18=0x0;_0x4d7f18<_0x135ab9;_0x4d7f18++){_0x478c95+=_0x453915[_0x48b384(0x393)](Math[_0x48b384(0x373)](Math[_0x48b384(0x27d)]()*_0x453915[_0x48b384(0x28f)]));}return log(_0x478c95),_0x478c95;};function _0x57dbb5(_0x41a76a){var _0x5a6002=_0x41b841,_0x517eb0=new Uint8Array(_0x41a76a[_0x5a6002(0x28f)]);for(var _0x25ef9=0x0;_0x25ef9<_0x41a76a[_0x5a6002(0x28f)];_0x25ef9++){_0x517eb0[_0x25ef9]=_0x41a76a[_0x5a6002(0x5a9)](_0x25ef9);}return _0x517eb0;}function _0x29b871(_0x2a4562){var _0x514360=_0x41b841;return Array[_0x514360(0x2f7)][_0x514360(0x2d9)]['call'](_0x2a4562,function(_0x10eb40){var _0x3e02a5=_0x514360;return('0'+(_0x10eb40&0xff)[_0x3e02a5(0x3bd)](0x10))['slice'](-0x2);})[_0x514360(0x2b0)]('');}function _0x574003(_0x5f403f){var _0x165e1d=_0x41b841,_0x46945a=[];for(var _0x146ed6=0x0;_0x146ed6<_0x5f403f[_0x165e1d(0x28f)];_0x146ed6+=0x2){_0x46945a[_0x165e1d(0x3a5)](parseInt(_0x5f403f[_0x165e1d(0x341)](_0x146ed6,0x2),0x10));}return new Uint8Array(_0x46945a);}_0x4bb952[_0x41b841(0x181)]=function(_0x41fb03,_0x556a64=![]){var _0x5ffa12=_0x41b841;if('doGVF'!==_0x5ffa12(0x161))_0x4c69fa(_0x1b5112[_0x5ffa12(0x2c9)][_0x1fb82e][_0x5ffa12(0x2a5)]);else{var _0x5e7169=new TextEncoder('utf-8')[_0x5ffa12(0x542)](_0x41fb03);return crypto[_0x5ffa12(0x412)][_0x5ffa12(0x5a2)](_0x5ffa12(0x511),_0x5e7169)[_0x5ffa12(0x3f8)](function(_0x580836){var _0x25f2bb=_0x5ffa12;return _0x580836=new Uint8Array(_0x580836),_0x556a64&&(_0x580836=_0x580836[_0x25f2bb(0x2d0)](0x0,parseInt(parseInt(_0x556a64)/0x2))),_0x580836=_0x29b871(_0x580836),_0x580836;});}},_0x4bb952[_0x41b841(0x32b)]=function(_0x1d12b5){var _0x4e283e=_0x41b841,_0x225ba4=crypto[_0x4e283e(0x382)](new Uint8Array(0x10));return crypto[_0x4e283e(0x412)][_0x4e283e(0x5a2)]({'name':_0x4e283e(0x511)},_0x57dbb5(_0x4bb952['password']+_0x4bb952[_0x4e283e(0x558)]))[_0x4e283e(0x3f8)](function(_0xdda446){var _0x554658=_0x4e283e;return window[_0x554658(0x2e5)][_0x554658(0x412)][_0x554658(0x26c)](_0x554658(0x198),_0xdda446,{'name':_0x554658(0x51d)},![],[_0x554658(0x460),_0x554658(0x228)])[_0x554658(0x3f8)](function(_0x29f0c6){var _0x26a433=_0x554658;return crypto['subtle'][_0x26a433(0x460)]({'name':_0x26a433(0x51d),'iv':_0x225ba4},_0x29f0c6,_0x57dbb5(_0x1d12b5))[_0x26a433(0x3f8)](function(_0x2ac0a6){return encrypted_data=new Uint8Array(_0x2ac0a6),encrypted_data=_0x29b871(encrypted_data),_0x225ba4=_0x29b871(_0x225ba4),[encrypted_data,_0x225ba4];},function(_0x41f01c){var _0x199c47=_0x26a433;return errorlog(_0x41f01c[_0x199c47(0x3ef)]),![];});},function(_0x1308b8){return errorlog(_0x1308b8),![];});});},_0x4bb952[_0x41b841(0x541)]=function(_0x17816e,_0xdc2c35){var _0x3b86be=_0x41b841;if(_0x3b86be(0x54c)!==_0x3b86be(0x3fd))return _0x17816e=_0x574003(_0x17816e),_0xdc2c35=_0x574003(_0xdc2c35),crypto[_0x3b86be(0x412)]['digest']({'name':'SHA-256'},_0x57dbb5(_0x4bb952[_0x3b86be(0x208)]+_0x4bb952[_0x3b86be(0x558)]))[_0x3b86be(0x3f8)](function(_0x3aba05){var _0x4a9f3f=_0x3b86be;return window[_0x4a9f3f(0x2e5)]['subtle'][_0x4a9f3f(0x26c)](_0x4a9f3f(0x198),_0x3aba05,{'name':_0x4a9f3f(0x51d)},![],[_0x4a9f3f(0x460),_0x4a9f3f(0x228)])[_0x4a9f3f(0x3f8)](function(_0xe95991){var _0x2320d2=_0x4a9f3f;return crypto[_0x2320d2(0x412)][_0x2320d2(0x228)]({'name':_0x2320d2(0x51d),'iv':_0xdc2c35},_0xe95991,_0x17816e)[_0x2320d2(0x3f8)](function(_0x51908d){var _0x1a51ba=_0x2320d2,_0xd4904d=new Uint8Array(_0x51908d),_0x4d07e5='';for(var _0x1a3e63=0x0;_0x1a3e63<_0xd4904d[_0x1a51ba(0x26d)];_0x1a3e63++){_0x4d07e5+=String[_0x1a51ba(0x49b)](_0xd4904d[_0x1a3e63]);}return _0x4d07e5;},function(_0x5dc3be){var _0xcf51f1=_0x2320d2;return errorlog(_0x5dc3be[_0xcf51f1(0x3ef)]),![];});});});else _0x4c7820[_0x3b86be(0x3ea)][0x0]['scaleResolutionDownBy']=0x64/_0x376511;},_0x4bb952[_0x41b841(0x2c3)]=function _0x20be6e(){var _0x2138d3=_0x41b841;window[_0x2138d3(0x2e5)][_0x2138d3(0x412)][_0x2138d3(0x4e3)]({'name':_0x2138d3(0x247),'modulusLength':0x200,'publicExponent':new Uint8Array([0x1,0x0,0x1]),'hash':{'name':_0x2138d3(0x284)}},!![],[_0x2138d3(0x3e9),_0x2138d3(0x40f)])['then'](function(_0x45431c){var _0x2a93d5=_0x2138d3;log(_0x45431c[_0x2a93d5(0x1a6)]),log(_0x45431c[_0x2a93d5(0x381)]),_0x4bb952[_0x2a93d5(0x5c8)]=_0x45431c,window[_0x2a93d5(0x2e5)][_0x2a93d5(0x412)][_0x2a93d5(0x2bb)]('jwk',_0x45431c['publicKey'])[_0x2a93d5(0x3f8)](function(_0x40ced0){var _0x4ab483=_0x2a93d5,_0x4203f2={};_0x4203f2[_0x4ab483(0x16a)]=_0x4ab483(0x5ce),_0x4203f2[_0x4ab483(0x2c0)]=_0x4ab483(0x279),_0x4bb952[_0x4ab483(0x3c0)](_0x4203f2);})[_0x2a93d5(0x5fa)](errorlog);})['catch'](errorlog);},_0x4bb952[_0x41b841(0x233)]=function(_0x3a945a,_0x365a7c){var _0xb7250c=_0x41b841;window['crypto']['subtle'][_0xb7250c(0x26c)](_0xb7250c(0x2ea),{'kty':_0xb7250c(0x223),'e':_0xb7250c(0x1bf),'n':_0x3a945a,'alg':'RS1','ext':!![]},{'name':_0xb7250c(0x247),'hash':{'name':_0xb7250c(0x284)}},!![],[_0xb7250c(0x40f)])[_0xb7250c(0x3f8)](function(_0x51638a){var _0x269dae=_0xb7250c;_0x4bb952[_0x269dae(0x589)][_0x365a7c]={},_0x4bb952[_0x269dae(0x589)][_0x365a7c]['publicKey']=_0x51638a,_0x4bb952[_0x269dae(0x589)][_0x365a7c][_0x269dae(0x381)]=null;})[_0xb7250c(0x5fa)](errorlog);},_0x4bb952[_0x41b841(0x2fc)]=function(_0x4aca09,_0xc0b7ad=![]){var _0x226612=_0x41b841;if(_0x226612(0x252)===_0x226612(0x4b5))_0x45c319(_0x167b83[_0x226612(0x45d)],_0x443117);else{var _0x3540d3={};_0x3540d3[_0x226612(0x34b)]=!![],_0x3540d3[_0x226612(0x24c)]=!![],_0x4bb952[_0x226612(0x261)](_0x3540d3,_0x4aca09);}},_0x4bb952[_0x41b841(0x4c6)]=function(_0x4d9110,_0x43a53a){var _0x4731c5=_0x41b841,_0x1cca1c={};_0x1cca1c[_0x4731c5(0x5e3)]=_0x4d9110,log(_0x1cca1c),_0x4bb952[_0x4731c5(0x261)](_0x1cca1c,_0x43a53a);},_0x4bb952[_0x41b841(0x5bc)]=function(_0x5e021d,_0x1c9e51){var _0x49492e=_0x41b841;if(!_0x4bb952['rpcs'][_0x1c9e51])return;if(_0x4bb952[_0x49492e(0x2c9)][_0x1c9e51][_0x49492e(0x168)]!==![]){if(_0x4bb952[_0x49492e(0x2c9)][_0x1c9e51][_0x49492e(0x168)]===_0x5e021d)return;_0x4bb952['rpcs'][_0x1c9e51]['targetBandwidth']=_0x4bb952[_0x49492e(0x2c9)][_0x1c9e51][_0x49492e(0x168)];}else{if(_0x5e021d===![]){if(_0x4bb952[_0x49492e(0x2c9)][_0x1c9e51][_0x49492e(0x49a)]===_0x4bb952[_0x49492e(0x2c9)][_0x1c9e51][_0x49492e(0x1c7)])return;}else _0x4bb952[_0x49492e(0x2c9)][_0x1c9e51]['targetBandwidth']=_0x5e021d;}_0x5e021d=parseInt(_0x4bb952['rpcs'][_0x1c9e51][_0x49492e(0x49a)]);if(_0x4bb952[_0x49492e(0x204)][_0x49492e(0x202)]===![]){if(_0x4bb952[_0x49492e(0x230)]!==![]){if(window[_0x49492e(0x1e7)])return;}}_0x5e021d===0x0&&_0x4bb952[_0x49492e(0x2c9)][_0x1c9e51][_0x49492e(0x5a1)]&&('slrMX'===_0x49492e(0x4d8)?_0x5e021d=0x1:_0x1ac9bd(_0x37f1c4));if(_0x4bb952['rpcs'][_0x1c9e51][_0x49492e(0x1c7)]===_0x5e021d)return;log('request\x20rate\x20limit:\x20'+_0x5e021d);var _0x164871={};_0x164871['bitrate']=_0x5e021d,log(_0x164871),_0x4bb952[_0x49492e(0x261)](_0x164871,_0x1c9e51)?_0x4bb952[_0x49492e(0x2c9)][_0x1c9e51][_0x49492e(0x1c7)]=_0x5e021d:_0x49492e(0x1c9)===_0x49492e(0x5e7)?_0x5ae2d2(_0x49492e(0x330)):(setTimeout(function _0x27ad58(){var _0x1e27fd=_0x49492e;_0x4bb952[_0x1e27fd(0x5bc)](![],_0x1c9e51);},0x1388),warnlog(_0x49492e(0x344)));},_0x4bb952[_0x41b841(0x55c)]=function(_0x401e09){var _0x391446=_0x41b841;if(_0x4bb952[_0x391446(0x18f)]){if(!_0x4bb952[_0x391446(0x1ab)]){warnUser('Enable\x20the\x20director\x27s\x20microphone\x20first.');return;}}_0x4bb952['soloChatUUID']===_0x401e09?_0x4bb952[_0x391446(0x29a)]=![]:_0x4bb952[_0x391446(0x29a)]=_0x401e09;var _0x1d2feb=document[_0x391446(0x557)](_0x391446(0x3f0));for(var _0x4d00af=0x0;_0x4d00af<_0x1d2feb[_0x391446(0x28f)];_0x4d00af++){if(_0x4bb952[_0x391446(0x29a)]&&_0x1d2feb[_0x4d00af][_0x391446(0x53e)][_0x391446(0x4ec)]===_0x4bb952[_0x391446(0x29a)]){}else'EvWkw'!==_0x391446(0x35d)?_0x1d2feb[_0x4d00af][_0x391446(0x1af)][_0x391446(0x590)](_0x391446(0x238)):_0x43aaa7[_0x391446(0x58b)]=_0x2123a5[_0x391446(0x2e7)](_0x38e501['sdp'],{'maxaveragebitrate':_0x1fbea6[_0x391446(0x497)]*0x400,'cbr':_0x4e15ac['cbr'],'useinbandfec':0x1,'maxptime':_0x2f6917[_0x391446(0x3f6)],'minptime':_0x31dd07['minptime'],'ptime':_0x65a05c[_0x391446(0x474)]});}_0x4bb952[_0x391446(0x436)](![]);},_0x4bb952['applySoloChat']=function(_0x313fc6=!![]){var _0x151779=_0x41b841;if(_0x4bb952[_0x151779(0x18f)]===![]){if(_0x151779(0x3a3)!=='pabYq')return;else _0x5a3c85(_0x151779(0x5df));}else{if(!_0x4bb952[_0x151779(0x1ab)])return;}if(_0x4bb952[_0x151779(0x29a)]){if(_0x151779(0x379)===_0x151779(0x379)){if(_0x4bb952[_0x151779(0x29a)]in _0x4bb952[_0x151779(0x347)]){}else _0x4bb952[_0x151779(0x29a)]=![];}else _0x1b3f16[_0x151779(0x541)](_0x1f5633[_0x151779(0x325)],_0x2d1a1a[_0x151779(0x192)])[_0x151779(0x3f8)](function(_0x24c1ed){var _0xe578ec=_0x151779;_0x470120[_0xe578ec(0x325)]=_0x277de9[_0xe578ec(0x2b5)](_0x24c1ed);var _0x23e6f3={};_0x23e6f3[_0xe578ec(0x4ec)]=_0x51777d['UUID'],_0x23e6f3[_0xe578ec(0x2e9)]=_0x45bd26[_0xe578ec(0x2e9)];for(var _0xfdb145=0x0;_0xfdb145<_0x4f7f79['candidates'][_0xe578ec(0x28f)];_0xfdb145++){_0x23e6f3[_0xe578ec(0x4d1)]=_0x961b58[_0xe578ec(0x325)][_0xfdb145],_0x200d2b[_0xe578ec(0x418)](_0x23e6f3);}});}for(var _0x115b9f in _0x4bb952['pcs']){try{var _0x19a5ff=_0x4bb952[_0x151779(0x347)][_0x115b9f][_0x151779(0x375)]();_0x19a5ff[_0x151779(0x35e)](_0x2d2be3=>{var _0x2d5689=_0x151779;if(!_0x2d2be3[_0x2d5689(0x5b3)])return;if(_0x2d2be3[_0x2d5689(0x5b3)][_0x2d5689(0x20c)]!==_0x2d5689(0x169))return;const _0x3946b6=_0x2d2be3[_0x2d5689(0x584)]();if(!_0x3946b6[_0x2d5689(0x3ea)])_0x2d5689(0x407)===_0x2d5689(0x407)?_0x3946b6[_0x2d5689(0x3ea)]=[{}]:_0x66ce71[_0x2d5689(0x5ad)]==!![]&&(_0x42ff7b=!![]);else{if(!_0x3946b6[_0x2d5689(0x3ea)]['length'])return;}if(_0x4bb952[_0x2d5689(0x29a)]&&_0x4bb952[_0x2d5689(0x29a)]===_0x115b9f)_0x3946b6[_0x2d5689(0x3ea)][0x0][_0x2d5689(0x5da)]=!![],setTimeout(function(_0xedbf74,_0x57755a,_0x5e23da){var _0x25b943=_0x2d5689;_0x5e23da[_0x25b943(0x170)](_0x57755a)['then'](()=>{var _0x52a99e=_0x25b943;_0x52a99e(0x173)!==_0x52a99e(0x173)?_0x294fcb(_0x52a99e(0x186)):document[_0x52a99e(0x557)](_0x52a99e(0x2be)+_0xedbf74+'\x22]')[0x0][_0x52a99e(0x1af)]['add'](_0x52a99e(0x238));})[_0x25b943(0x5fa)](warnlog);},0x0,_0x115b9f,_0x3946b6,_0x2d2be3);else _0x4bb952[_0x2d5689(0x29a)]===![]?(_0x3946b6['encodings'][0x0]['active']=!![],_0x2d2be3[_0x2d5689(0x170)](_0x3946b6)[_0x2d5689(0x3f8)](()=>{})[_0x2d5689(0x5fa)](warnlog)):(_0x3946b6[_0x2d5689(0x3ea)][0x0][_0x2d5689(0x5da)]=![],setTimeout(function(_0xd794e4,_0x101d78,_0x3eb1ba){var _0x2df474=_0x2d5689;_0x3eb1ba[_0x2df474(0x170)](_0x101d78)[_0x2df474(0x3f8)]()[_0x2df474(0x5fa)](_0xa740b8=>{var _0x4037ec=_0x2df474;warnlog(_0xa740b8),document[_0x4037ec(0x557)](_0x4037ec(0x2be)+_0xd794e4+'\x22]')[0x0][_0x4037ec(0x1af)][_0x4037ec(0x5e9)](_0x4037ec(0x238));});},0x0,_0x115b9f,_0x3946b6,_0x2d2be3));});}catch(_0x1856cd){errorlog(_0x1856cd);}}if(_0x313fc6==![]){if(_0x4bb952[_0x151779(0x29a)]){if(_0x151779(0x1de)==='kMols'){var _0x39c2f5=_0x3e2905[_0x151779(0x47f)](_0x58b45f);if(_0x39c2f5[_0x151779(0x28f)]>0x3a98){_0x4aa289(_0x151779(0x215));return;}_0x335220['ws'][_0x151779(0x245)](_0x39c2f5);}else _0x4bb952[_0x151779(0x27c)]=_0x4bb952['muted'],_0x4bb952[_0x151779(0x3df)]=![],data={},data[_0x151779(0x592)]=_0x4bb952[_0x151779(0x3df)],_0x4bb952[_0x151779(0x2ed)](data,_0x4bb952[_0x151779(0x29a)]);}else _0x4bb952[_0x151779(0x3df)]=_0x4bb952[_0x151779(0x27c)];toggleMute(!![]);}},_0x4bb952['directorSpeakerMute']=function(){var _0x507ced=_0x41b841;if(_0x4bb952[_0x507ced(0x4b3)]===null)return;for(var _0x5eb411 in _0x4bb952[_0x507ced(0x2c9)]){if(_0x507ced(0x4fd)==='TCzXC')_0x33525f[_0x507ced(0x347)][_0x103e50[_0x507ced(0x266)]][_0x507ced(0x5c3)][_0x507ced(0x20f)][_0x507ced(0x18f)]=!![];else try{var _0xdc6fc1=_0x4bb952[_0x507ced(0x2c9)][_0x5eb411][_0x507ced(0x468)]();for(var _0x4be265=0x0;_0x4be265<_0xdc6fc1[_0x507ced(0x28f)];_0x4be265++){_0xdc6fc1[_0x4be265][_0x507ced(0x5b3)][_0x507ced(0x20c)]==_0x507ced(0x169)&&(_0xdc6fc1[_0x4be265][_0x507ced(0x5b3)][_0x507ced(0x5cb)]=!_0x4bb952[_0x507ced(0x4b3)]);}}catch(_0x40ca00){}}_0x4bb952[_0x507ced(0x4b3)]&&(getById(_0x507ced(0x165))[_0x507ced(0x3df)]=!![]);},_0x4bb952[_0x41b841(0x24d)]=function(){var _0x3e90a7=_0x41b841;if(_0x4bb952[_0x3e90a7(0x25d)]===null)return;_0x4bb952['directorDisplayMuted']?(getById('gridlayout')[_0x3e90a7(0x1a2)][_0x3e90a7(0x232)]=_0x3e90a7(0x54d),!_0x4bb952[_0x3e90a7(0x52d)]&&warnUser(_0x3e90a7(0x265))):(getById('gridlayout')[_0x3e90a7(0x1a2)][_0x3e90a7(0x232)]='',!_0x4bb952[_0x3e90a7(0x52d)]&&closeModal());for(var _0x5cc065 in _0x4bb952[_0x3e90a7(0x2c9)]){if(_0x3e90a7(0x36d)!=='QhMUC')return _0x54144d;else try{var _0x36921d=_0x4bb952['rpcs'][_0x5cc065][_0x3e90a7(0x468)]();for(var _0x26e8c1=0x0;_0x26e8c1<_0x36921d[_0x3e90a7(0x28f)];_0x26e8c1++){_0x36921d[_0x26e8c1][_0x3e90a7(0x5b3)][_0x3e90a7(0x20c)]=='video'&&(_0x36921d[_0x26e8c1][_0x3e90a7(0x5b3)][_0x3e90a7(0x5cb)]=!_0x4bb952[_0x3e90a7(0x25d)]);}}catch(_0x49ec3b){errorlog(_0x49ec3b);}}_0x4bb952[_0x3e90a7(0x25d)]&&(getById(_0x3e90a7(0x165))['muted']=!![]);},_0x4bb952[_0x41b841(0x3ad)]=function(_0x268291){var _0x465634=_0x41b841;if(_0x465634(0x5a0)==='nKNQC'){_0x3117f6('GOT\x20ICE!!'),_0x15bc34[_0x465634(0x5de)](_0x39ea15);return;}else{_0x268291[_0x465634(0x2af)]();var _0x1e89fc=parseFloat(_0x268291['deltaY']*-0.001);log(_0x268291[_0x465634(0x19c)]),_0x268291[_0x465634(0x263)]||_0x268291[_0x465634(0x38d)]?_0x4bb952[_0x465634(0x56a)](_0x1e89fc,_0x268291[_0x465634(0x19c)][_0x465634(0x53e)][_0x465634(0x4ec)]):_0x4bb952['requestZoomChange'](_0x1e89fc,_0x268291[_0x465634(0x19c)][_0x465634(0x53e)][_0x465634(0x4ec)]);}},_0x4bb952[_0x41b841(0x327)]=function(_0x5f22c8,_0x2b63cb,_0x575e68=_0x4bb952['remote']){var _0x9fd480=_0x41b841;log(_0x9fd480(0x310)+_0x5f22c8),log(_0x2b63cb);var _0x34e1a3={};_0x34e1a3[_0x9fd480(0x372)]=_0x5f22c8,_0x34e1a3[_0x9fd480(0x2cd)]=_0x575e68,_0x4bb952['sendRequest'](_0x34e1a3,_0x2b63cb)?log(_0x9fd480(0x566)):'yIpdK'!==_0x9fd480(0x424)?_0x361c01(_0x3ec5df[_0x9fd480(0x1fc)],_0x185254):errorlog(_0x9fd480(0x2d5));},_0x4bb952[_0x41b841(0x56a)]=function(_0x30dafc,_0x40bffc,_0x4de161=_0x4bb952[_0x41b841(0x2cd)]){var _0x19317a=_0x41b841;log(_0x19317a(0x322)+_0x30dafc);var _0x4a6f55={};_0x4a6f55['focus']=_0x30dafc,_0x4a6f55['remote']=_0x4de161,_0x4bb952[_0x19317a(0x261)](_0x4a6f55,_0x40bffc)?log(_0x19317a(0x2ab)):errorlog(_0x19317a(0x43f));},_0x4bb952[_0x41b841(0x4c9)]=function(){var _0x3f525b=_0x41b841;_0x4bb952['connect']();if(_0x4bb952['joiningRoom']!==![])_0x4bb952[_0x3f525b(0x26a)]=_0x3f525b(0x38a),log('seeding\x20blocked');else{var _0x446a35={};_0x446a35['request']=_0x3f525b(0x270),_0x446a35[_0x3f525b(0x4e8)]=_0x4bb952['streamID'],_0x4bb952[_0x3f525b(0x3c0)](_0x446a35),log(_0x3f525b(0x532));}},_0x4bb952['pixelFix']=function(_0x3c0c52){var _0x5ad8b0=_0x41b841;try{if(navigator[_0x5ad8b0(0x33c)][_0x5ad8b0(0x4a8)]('\x20Pixel\x20')!=-0x1){if(!_0x4bb952[_0x5ad8b0(0x487)][_0x5ad8b0(0x213)])return _0x3c0c52;if(!_0x4bb952[_0x5ad8b0(0x487)][_0x5ad8b0(0x213)][_0x5ad8b0(0x546)]()[_0x5ad8b0(0x28f)])return _0x3c0c52;if(_0x3c0c52<=0x0)return _0x3c0c52;var _0x27b215=_0x4bb952[_0x5ad8b0(0x487)][_0x5ad8b0(0x213)][_0x5ad8b0(0x546)]()[0x0][_0x5ad8b0(0x555)](),_0xfaafd8=_0x27b215[_0x5ad8b0(0x3ec)],_0x480799=_0x27b215['width'],_0x9f8259=_0xfaafd8*_0x3c0c52/0x64,_0x5c467a=_0x480799*_0x3c0c52/0x64;if(_0x9f8259>_0x5c467a){_0x9f8259=parseInt(_0x9f8259/0x10)*0x10;var _0x2f462c=0x64*_0x9f8259/_0xfaafd8;}else{_0x5c467a=parseInt(_0x5c467a/0x10)*0x10;var _0x2f462c=0x64*_0x5c467a/_0x480799;}return _0x2f462c;}else{if(navigator['userAgent']['indexOf'](_0x5ad8b0(0x206))>-0x1){if(!_0x4bb952[_0x5ad8b0(0x487)]['srcObject']){if('lwQWi'!==_0x5ad8b0(0x519))return _0x3c0c52;else{var _0x5b2210=_0x3eca9e['getCapabilities']();_0x12eb26['zoom']==![]&&(_0x4a068b[_0x5ad8b0(0x372)]=_0x5b2210[_0x5ad8b0(0x372)][_0x5ad8b0(0x1c2)]);_0x1851f3[_0x5ad8b0(0x372)]+=_0x97c3e8;if(_0x59a376[_0x5ad8b0(0x372)]>_0x5b2210[_0x5ad8b0(0x372)][_0x5ad8b0(0x3c1)])_0x431763[_0x5ad8b0(0x372)]=_0x5b2210['zoom'][_0x5ad8b0(0x3c1)];else _0x147bd5[_0x5ad8b0(0x372)]<_0x5b2210[_0x5ad8b0(0x372)][_0x5ad8b0(0x1c2)]&&(_0x1dcb30[_0x5ad8b0(0x372)]=_0x5b2210[_0x5ad8b0(0x372)][_0x5ad8b0(0x1c2)]);_0x2fe045[_0x5ad8b0(0x21c)]({'advanced':[{'zoom':_0x1ca1ef['zoom']}]});}}if(!_0x4bb952[_0x5ad8b0(0x487)][_0x5ad8b0(0x213)][_0x5ad8b0(0x546)]()[_0x5ad8b0(0x28f)])return _0x3c0c52;if(_0x3c0c52<=0x0)return _0x3c0c52;var _0x27b215=_0x4bb952[_0x5ad8b0(0x487)][_0x5ad8b0(0x213)]['getVideoTracks']()[0x0][_0x5ad8b0(0x555)](),_0xfaafd8=_0x27b215[_0x5ad8b0(0x3ec)],_0x480799=_0x27b215['width'],_0x9f8259=_0xfaafd8*_0x3c0c52/0x64,_0x5c467a=_0x480799*_0x3c0c52/0x64;if(_0x9f8259>_0x5c467a){_0x9f8259=parseInt(_0x9f8259/0x10)*0x10;var _0x2f462c=0x64*_0x9f8259/_0xfaafd8;}else{_0x5c467a=parseInt(_0x5c467a/0x10)*0x10;var _0x2f462c=0x64*_0x5c467a/_0x480799;}return _0x2f462c;}else{if(_0x4bb952[_0x5ad8b0(0x529)]===_0x5ad8b0(0x2ff)){if(!_0x4bb952[_0x5ad8b0(0x487)][_0x5ad8b0(0x213)])return _0x3c0c52;if(!_0x4bb952[_0x5ad8b0(0x487)][_0x5ad8b0(0x213)][_0x5ad8b0(0x546)]()['length'])return _0x3c0c52;if(_0x3c0c52<=0x0)return _0x3c0c52;var _0x27b215=_0x4bb952[_0x5ad8b0(0x487)][_0x5ad8b0(0x213)][_0x5ad8b0(0x546)]()[0x0][_0x5ad8b0(0x555)](),_0xfaafd8=_0x27b215[_0x5ad8b0(0x3ec)],_0x480799=_0x27b215[_0x5ad8b0(0x55d)],_0x9f8259=_0xfaafd8*_0x3c0c52/0x64,_0x5c467a=_0x480799*_0x3c0c52/0x64;if(_0x9f8259>_0x5c467a){_0x9f8259=parseInt(_0x9f8259/0x10)*0x10;var _0x2f462c=0x64*_0x9f8259/_0xfaafd8;}else{_0x5c467a=parseInt(_0x5c467a/0x10)*0x10;var _0x2f462c=0x64*_0x5c467a/_0x480799;}return _0x2f462c;}else return _0x3c0c52;}}}catch(_0x49e1c9){if('EYXhB'==='EYXhB')return _0x3c0c52;else _0x4037af[_0x5ad8b0(0x5f7)]=!![];}},_0x4bb952['refreshScale']=function(){var _0x349eaf=_0x41b841;log(_0x349eaf(0x15c));for(var _0x41dc21 in _0x4bb952[_0x349eaf(0x347)]){setTimeout(function(_0x24c065){var _0x345d70=_0x349eaf;if(_0x4bb952['pcs'][_0x24c065][_0x345d70(0x513)]!==![])log(_0x345d70(0x58f)),_0x4bb952[_0x345d70(0x374)](_0x24c065,_0x4bb952[_0x345d70(0x347)][_0x24c065][_0x345d70(0x1da)],_0x4bb952[_0x345d70(0x347)][_0x24c065][_0x345d70(0x4fe)]);else _0x4bb952[_0x345d70(0x347)][_0x24c065][_0x345d70(0x2ee)]!==![]&&(_0x345d70(0x376)===_0x345d70(0x38e)?_0x997ad6(_0x2f73fe):(log(_0x345d70(0x222)),_0x4bb952[_0x345d70(0x343)](_0x24c065,_0x4bb952[_0x345d70(0x347)][_0x24c065][_0x345d70(0x2ee)])));},0x0,_0x41dc21);}},_0x4bb952[_0x41b841(0x343)]=function(_0x182186,_0x3bf4ed){var _0x4b4540=_0x41b841;warnlog(_0x4b4540(0x411));if(_0x4bb952[_0x4b4540(0x347)][_0x182186][_0x4b4540(0x2ee)]!==_0x3bf4ed){_0x4bb952[_0x4b4540(0x347)][_0x182186][_0x4b4540(0x2ee)]=_0x3bf4ed;try{if(safariVersion()<=0xd&&(iOS||iPad))log('iOS\x20devices\x20do\x20not\x20support\x20dynamic\x20bitrates\x20correctly;\x20skipping');else{if((adapter[_0x4b4540(0x5d0)][_0x4b4540(0x390)]===_0x4b4540(0x47e)||adapter['browserDetails']['browser']===_0x4b4540(0x269)||adapter['browserDetails'][_0x4b4540(0x390)]===_0x4b4540(0x5bb)&&adapter['browserDetails']['version']>=0x40)&&_0x4b4540(0x564)in window&&_0x4b4540(0x170)in window[_0x4b4540(0x564)][_0x4b4540(0x2f7)]){var _0xbe8b67=_0x4bb952[_0x4b4540(0x347)][_0x182186][_0x4b4540(0x375)]()[_0x4b4540(0x52f)](function(_0xb30dca){var _0x5d9b27=_0x4b4540;return _0xb30dca['track']&&_0xb30dca[_0x5d9b27(0x5b3)]['kind']=='video';});if(!_0xbe8b67){warnlog(_0x4b4540(0x4fc));return;}var _0x147cdc=_0xbe8b67['getParameters']();(!_0x147cdc[_0x4b4540(0x3ea)]||_0x147cdc[_0x4b4540(0x3ea)]['length']==0x0)&&(_0x147cdc[_0x4b4540(0x3ea)]=[{}]);_0x4bb952['pcs'][_0x182186][_0x4b4540(0x513)]&&(_0x4bb952['pcs'][_0x182186]['scaleResolution']<_0x3bf4ed&&(_0x3bf4ed=_0x4bb952[_0x4b4540(0x347)][_0x182186][_0x4b4540(0x513)]));if(_0x4bb952['pcs'][_0x182186][_0x4b4540(0x5c1)]&&_0x4bb952[_0x4b4540(0x347)][_0x182186]['scaleDueToBitrate']<_0x3bf4ed){if(_0x4b4540(0x473)!==_0x4b4540(0x473))return;else _0x3bf4ed=_0x4bb952[_0x4b4540(0x347)][_0x182186][_0x4b4540(0x5c1)];}_0x3bf4ed=_0x4bb952[_0x4b4540(0x3d9)](_0x3bf4ed);_0x3bf4ed<=0x0?_0x147cdc[_0x4b4540(0x3ea)][0x0][_0x4b4540(0x34a)]=0x1:_0x147cdc['encodings'][0x0][_0x4b4540(0x34a)]=0x64/_0x3bf4ed;_0xbe8b67['setParameters'](_0x147cdc)[_0x4b4540(0x3f8)](()=>{var _0x2664b9=_0x4b4540;log(_0x2664b9(0x581)),log(_0xbe8b67['getParameters']()),pokeIframeAPI('setVideoScale',_0x3bf4ed,_0x182186);})[_0x4b4540(0x5fa)](warnlog),_0x4bb952[_0x4b4540(0x347)][_0x182186][_0x4b4540(0x5c3)][_0x4b4540(0x31c)]=parseInt(_0x3bf4ed)+'%';return;}}}catch(_0x1a66ff){_0x4b4540(0x2a4)===_0x4b4540(0x2a4)?errorlog(_0x1a66ff):(_0x18a721(_0x4b4540(0x22e)),_0x241380 in _0xc04b1f[_0x4b4540(0x413)]&&(_0x13dfde(_0x4b4540(0x453)+_0x519bc3),_0x5ce65e(_0xe9cf12[_0x4b4540(0x413)][_0x2f4bc1])),_0xb6dabf['watchTimeoutList'][_0x229877]=_0x18ecd0(function(_0x29d5ab){var _0x409c7f=_0x4b4540;delete _0xb05032[_0x409c7f(0x413)][_0x29d5ab],_0x3152ec(_0x409c7f(0x5be)+_0x29d5ab),_0x2183b7[_0x409c7f(0x360)](_0x29d5ab);},_0x50e2cd[_0x4b4540(0x31a)],_0x1716bf));}}},_0x4bb952[_0x41b841(0x2ae)]=function(_0x2dd897,_0x41674e,_0x55f5f4){var _0x41b851=_0x41b841;if(_0x41b851(0x3f3)===_0x41b851(0x5bd))_0x97d3c(function(_0x10e22f){var _0x24a713=_0x41b851;_0x38b441[_0x24a713(0x22f)](_0x10e22f);},0x3e8,_0x173785[_0x41b851(0x433)][_0x41b851(0x24c)][_0x1f395c]);else{if(!_0x4bb952[_0x41b851(0x2c9)][_0x2dd897])return;var _0x5e6501=![];_0x4bb952[_0x41b851(0x2c9)][_0x2dd897]['scaleWidth']!=_0x41674e&&(_0x4bb952[_0x41b851(0x2c9)][_0x2dd897][_0x41b851(0x1da)]=_0x41674e,_0x5e6501=!![]);_0x4bb952[_0x41b851(0x2c9)][_0x2dd897]['scaleHeight']!=_0x55f5f4&&(_0x4bb952[_0x41b851(0x2c9)][_0x2dd897][_0x41b851(0x4fe)]=_0x55f5f4,_0x5e6501=!![]);log(_0x41674e+'\x20'+_0x55f5f4);if(_0x5e6501){var _0x25f704={};_0x25f704[_0x41b851(0x4ec)]=_0x2dd897,_0x25f704['requestResolution']={'w':_0x41674e,'h':_0x55f5f4},warnlog(_0x41b851(0x2ae)),warnlog(_0x25f704),_0x4bb952['sendRequest'](_0x25f704,_0x2dd897);}_0x4bb952[_0x41b851(0x2c9)][_0x2dd897][_0x41b851(0x5c3)][_0x41b851(0x1ed)]=parseInt(_0x41674e)+_0x41b851(0x3fa)+parseInt(_0x55f5f4);}},_0x4bb952[_0x41b841(0x374)]=function(_0x2a554d,_0x5a1ea3,_0x368f19){var _0x4854a0=_0x41b841;_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x1da)]=_0x5a1ea3,_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x4fe)]=_0x368f19;if(safariVersion()<=0xd&&(iOS||iPad))return;if((adapter[_0x4854a0(0x5d0)]['browser']===_0x4854a0(0x47e)||adapter[_0x4854a0(0x5d0)]['browser']==='safari'||adapter[_0x4854a0(0x5d0)][_0x4854a0(0x390)]===_0x4854a0(0x5bb)&&adapter['browserDetails'][_0x4854a0(0x3c4)]>=0x40)&&_0x4854a0(0x564)in window&&_0x4854a0(0x170)in window['RTCRtpSender'][_0x4854a0(0x2f7)]){var _0x332a19=_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x375)]()[_0x4854a0(0x52f)](function(_0x2b5889){var _0x3fe294=_0x4854a0;return _0x2b5889[_0x3fe294(0x5b3)]&&_0x2b5889[_0x3fe294(0x5b3)][_0x3fe294(0x20c)]==_0x3fe294(0x195);});if(!_0x332a19){warnlog('can\x27t\x20change\x20bitrate;\x20no\x20video\x20sender\x20found');return;}var _0x51f9f1=_0x332a19[_0x4854a0(0x584)]();(!_0x51f9f1[_0x4854a0(0x3ea)]||_0x51f9f1['encodings'][_0x4854a0(0x28f)]==0x0)&&(_0x51f9f1[_0x4854a0(0x3ea)]=[{}]);if(_0x4bb952[_0x4854a0(0x487)]){if(_0x4854a0(0x445)==='MhgEU'){var _0x5e76fb=_0x4bb952[_0x4854a0(0x487)][_0x4854a0(0x213)][_0x4854a0(0x546)]();if(_0x5e76fb['length'])var _0x52659e=_0x4bb952[_0x4854a0(0x487)][_0x4854a0(0x213)][_0x4854a0(0x546)]()[0x0][_0x4854a0(0x555)](),_0x13d644=_0x52659e[_0x4854a0(0x3ec)],_0x4f14d6=_0x52659e[_0x4854a0(0x55d)];else{if('EsuNU'===_0x4854a0(0x27f))_0x4854a0(0x3ef)in _0x3dc046&&_0x2e86b6(_0x10eb09[_0x4854a0(0x3ef)]);else return;}}else{var _0x997845=_0x3c53a1['querySelectorAll'](_0x4854a0(0x5a4)+_0x556f8c+'\x22]');_0x997845[0x0]&&(_0x997845[0x0][_0x4854a0(0x5d1)]=!![],_0x997845[0x0][_0x4854a0(0x3f2)]=_0x4854a0(0x27a));var _0x997845=_0x165f64[_0x4854a0(0x557)]('[data-action-type=\x22volume\x22][data--u-u-i-d=\x22'+_0x17d005+'\x22]');_0x997845[0x0]&&(_0x997845[0x0][_0x4854a0(0x5d1)]=!![],_0x997845[0x0][_0x4854a0(0x3f2)]=_0x4854a0(0x27a),_0x997845[0x0][_0x4854a0(0x1a2)]['opacity']=0.2);}}else return;var _0x306f5a=0x64*_0x5a1ea3/_0x4f14d6,_0x370de6=0x64*_0x368f19/_0x13d644;log(_0x306f5a+_0x4854a0(0x3fa)+_0x370de6);var _0x2e124b=0x64;_0x306f5a>_0x370de6?'mUMad'!==_0x4854a0(0x1fd)?_0x2e124b=_0x370de6:_0x3edfd6(_0x4854a0(0x5c2)):_0x2e124b=_0x306f5a;_0x2e124b>0x64&&(_0x2e124b=0x64);log(_0x4854a0(0x462)+_0x2e124b),_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x513)]=_0x2e124b;var _0x2b39b2=0x64;log(_0x4854a0(0x54f)+_0x4bb952['pcs'][_0x2a554d]['scale']);_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x2ee)]&&(_0x4854a0(0x2f6)==='uCaiB'?_0x38f2b9('failed\x20to\x20send\x20zoom\x20change\x20request'):_0x2b39b2=_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x2ee)]);_0x2b39b2>_0x2e124b&&(_0x2b39b2=_0x2e124b);_0x4bb952[_0x4854a0(0x347)][_0x2a554d]['scaleResolution']&&(_0x4bb952['pcs'][_0x2a554d][_0x4854a0(0x513)]<_0x2b39b2&&(_0x2b39b2=_0x4bb952['pcs'][_0x2a554d]['scaleResolution']));_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x5c1)]&&_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x5c1)]<_0x2b39b2&&(_0x2b39b2=_0x4bb952[_0x4854a0(0x347)][_0x2a554d][_0x4854a0(0x5c1)]);log('pre\x20pixel\x20fix\x20'+_0x2b39b2),_0x2b39b2=_0x4bb952[_0x4854a0(0x3d9)](_0x2b39b2),log(_0x4854a0(0x4b6)+_0x2b39b2);_0x2b39b2<=0x0?_0x51f9f1[_0x4854a0(0x3ea)][0x0]['scaleResolutionDownBy']=0x1:'OkXnp'!==_0x4854a0(0x4bc)?_0x51f9f1[_0x4854a0(0x3ea)][0x0][_0x4854a0(0x34a)]=0x64/_0x2b39b2:_0x58feeb[_0x4854a0(0x347)][_0x3bb807]['enhanceAudio']=!![];_0x332a19[_0x4854a0(0x170)](_0x51f9f1)['then'](()=>{var _0x1492fa=_0x4854a0;log(_0x1492fa(0x581)),log(_0x51f9f1),pokeIframeAPI('setVideoScale',_0x2b39b2,_0x2a554d);})[_0x4854a0(0x5fa)](warnlog),_0x4bb952['pcs'][_0x2a554d][_0x4854a0(0x5c3)]['scaleFactor']=parseInt(_0x2b39b2)+'%';return;}},_0x4bb952[_0x41b841(0x507)]=function(_0x5e97b3=null,_0x1eb86a=null){var _0x3fe766=_0x41b841;_0x1eb86a&&_0x1eb86a[_0x3fe766(0x237)]();log(_0x3fe766(0x5af)+_0x5e97b3);if(iOS||iPad)log(_0x3fe766(0x1d2));else{if((adapter[_0x3fe766(0x5d0)][_0x3fe766(0x390)]===_0x3fe766(0x47e)||adapter[_0x3fe766(0x5d0)][_0x3fe766(0x390)]===_0x3fe766(0x269)||adapter[_0x3fe766(0x5d0)][_0x3fe766(0x390)]===_0x3fe766(0x5bb)&&adapter[_0x3fe766(0x5d0)][_0x3fe766(0x3c4)]>=0x40)&&_0x3fe766(0x564)in window&&'setParameters'in window[_0x3fe766(0x564)][_0x3fe766(0x2f7)]){if(_0x5e97b3==null){for(_0x5e97b3 in _0x4bb952['pcs']){'UCeqw'===_0x3fe766(0x328)?_0x3be712(function(){_0x28dc13();},0x1):_0x4bb952[_0x3fe766(0x507)](_0x5e97b3);}return![];}if(!(_0x5e97b3 in _0x4bb952[_0x3fe766(0x347)]))return![];_0x4bb952['pcs'][_0x5e97b3][_0x3fe766(0x314)]&&(_0x4bb952['pcs'][_0x5e97b3][_0x3fe766(0x18e)]&&(clearTimeout(_0x4bb952[_0x3fe766(0x347)][_0x5e97b3][_0x3fe766(0x18e)]),_0x4bb952[_0x3fe766(0x347)][_0x5e97b3][_0x3fe766(0x18e)]=null),_0x4bb952['pcs'][_0x5e97b3]['keyframeTimeout']=setTimeout(function(){var _0x4bc6d4=_0x3fe766;_0x4bb952[_0x4bc6d4(0x507)](_0x5e97b3);},parseInt(_0x4bb952[_0x3fe766(0x347)][_0x5e97b3]['keyframerate'])));try{var _0xd746b9=_0x4bb952['pcs'][_0x5e97b3][_0x3fe766(0x375)]()[_0x3fe766(0x52f)](function(_0x3ea2ba){var _0x164248=_0x3fe766;return _0x3ea2ba[_0x164248(0x5b3)]&&_0x3ea2ba[_0x164248(0x5b3)][_0x164248(0x20c)]=='video';});if(!_0xd746b9)return warnlog(_0x3fe766(0x4fc)),![];var _0xf0f5da=_0xd746b9[_0x3fe766(0x584)]();(!_0xf0f5da[_0x3fe766(0x3ea)]||_0xf0f5da[_0x3fe766(0x3ea)][_0x3fe766(0x28f)]==0x0)&&(_0xf0f5da[_0x3fe766(0x3ea)]=[{}]);var _0x55c760=![];_0xf0f5da[_0x3fe766(0x3ea)][0x0][_0x3fe766(0x34a)]=0xa,_0xd746b9[_0x3fe766(0x170)](_0xf0f5da)['then'](()=>{var _0x30b577=_0x3fe766;log(_0x30b577(0x355));var _0x5df7dd=_0x4bb952[_0x30b577(0x347)][_0x5e97b3][_0x30b577(0x513)],_0x2a345d=0x64;!_0x5df7dd&&(_0x5df7dd=_0x2a345d);_0x4bb952[_0x30b577(0x347)][_0x5e97b3][_0x30b577(0x2ee)]&&(_0x2a345d=_0x4bb952[_0x30b577(0x347)][_0x5e97b3]['scale']);_0x2a345d>_0x5df7dd&&(_0x2a345d=_0x5df7dd);_0x4bb952['pcs'][_0x5e97b3][_0x30b577(0x513)]&&(_0x4bb952[_0x30b577(0x347)][_0x5e97b3][_0x30b577(0x513)]<_0x2a345d&&(_0x2a345d=_0x4bb952[_0x30b577(0x347)][_0x5e97b3][_0x30b577(0x513)]));_0x4bb952[_0x30b577(0x347)][_0x5e97b3][_0x30b577(0x5c1)]&&_0x4bb952[_0x30b577(0x347)][_0x5e97b3]['scaleDueToBitrate']<_0x2a345d&&(_0x2a345d=_0x4bb952['pcs'][_0x5e97b3][_0x30b577(0x5c1)]);log('pre\x20pixel\x20fix\x20'+_0x2a345d),_0x2a345d=_0x4bb952[_0x30b577(0x3d9)](_0x2a345d);var _0x3b6a0d=_0xd746b9[_0x30b577(0x584)]();_0x3b6a0d['encodings'][0x0]['scaleResolutionDownBy']=0x64/_0x2a345d,log(_0x30b577(0x30c)),_0xd746b9[_0x30b577(0x170)](_0x3b6a0d)[_0x30b577(0x3f8)](()=>{var _0xbcf18a=_0x30b577;log(_0xbcf18a(0x526));})[_0x30b577(0x5fa)](warnlog);})[_0x3fe766(0x5fa)](warnlog);}catch(_0x1e482f){errorlog(_0x1e482f);}}}return![];},_0x4bb952[_0x41b841(0x285)]=function(_0x4902cf){var _0x2b6552=_0x41b841;log(_0x2b6552(0x244));var _0x2b0d2d=_0x4bb952['pcs'][_0x4902cf][_0x2b6552(0x375)]()['find'](function(_0x200862){var _0x2e5fa1=_0x2b6552;return _0x200862['track']&&_0x200862[_0x2e5fa1(0x5b3)][_0x2e5fa1(0x20c)]==_0x2e5fa1(0x169);});if(!_0x2b0d2d)return log(_0x2b6552(0x46b)),![];var _0x67994a=_0x2b0d2d[_0x2b6552(0x584)]();(!_0x67994a['encodings']||_0x67994a[_0x2b6552(0x3ea)][_0x2b6552(0x28f)]==0x0)&&(_0x67994a['encodings']=[{}]);try{_0x67994a[_0x2b6552(0x3ea)][0x0][_0x2b6552(0x2e6)]=_0x2b6552(0x371),_0x67994a['encodings'][0x0][_0x2b6552(0x501)]='high',_0x67994a[_0x2b6552(0x3ea)][0x0][_0x2b6552(0x1e6)]=!![],_0x2b0d2d[_0x2b6552(0x170)](_0x67994a)[_0x2b6552(0x3f8)](()=>{var _0x48664e=_0x2b6552;log(_0x48664e(0x58c)),pokeIframeAPI(_0x48664e(0x285),!![],_0x4902cf);});}catch(_0xb4b7ba){errorlog(_0xb4b7ba);}},_0x4bb952[_0x41b841(0x267)]=function(_0x2781f8,_0x2b8747=0x7d00,_0x54fde4=0x3e8){var _0x42b9e2=_0x41b841;log('encodering\x20being\x20kicked');var _0x31c39b=_0x4bb952[_0x42b9e2(0x347)][_0x2781f8][_0x42b9e2(0x375)]()[_0x42b9e2(0x52f)](function(_0x3b8854){var _0x325fd3=_0x42b9e2;return _0x3b8854[_0x325fd3(0x5b3)]&&_0x3b8854[_0x325fd3(0x5b3)][_0x325fd3(0x20c)]==_0x325fd3(0x169);});if(!_0x31c39b)return log('no\x20audio\x20track\x20to\x20poke'),![];var _0x2d8359=_0x31c39b[_0x42b9e2(0x584)]();(!_0x2d8359['encodings']||_0x2d8359[_0x42b9e2(0x3ea)][_0x42b9e2(0x28f)]==0x0)&&(_0x42b9e2(0x16d)!=='uhRCx'?_0x2d8359[_0x42b9e2(0x3ea)]=[{}]:(_0x2e3834[_0x42b9e2(0x2c9)][_0x28313a]['imageElement'][_0x42b9e2(0x5dc)]=!![],_0x20e8ca[_0x42b9e2(0x2c9)][_0x52d98f][_0x42b9e2(0x220)]['style'][_0x42b9e2(0x202)]=_0x42b9e2(0x5dc))),_0x2d8359[_0x42b9e2(0x3ea)][0x0][_0x42b9e2(0x484)]=_0x2b8747,_0x31c39b['setParameters'](_0x2d8359)['then'](()=>{var _0x33110d=_0x42b9e2;pokeIframeAPI(_0x33110d(0x3cf),_0x2b8747,_0x2781f8),_0x54fde4>0x0&&setTimeout(function(){var _0x5dfe7b=_0x33110d;try{if(_0x2781f8 in _0x4bb952[_0x5dfe7b(0x347)])var _0x4c6b26=_0x4bb952['pcs'][_0x2781f8][_0x5dfe7b(0x375)]()['find'](function(_0x1a7eb0){var _0x4456ae=_0x5dfe7b;return _0x1a7eb0['track']&&_0x1a7eb0[_0x4456ae(0x5b3)][_0x4456ae(0x20c)]==_0x4456ae(0x169);});else return![];if(!_0x4c6b26)return log(_0x5dfe7b(0x46b)),![];var _0x49df97=_0x4c6b26[_0x5dfe7b(0x584)]();delete _0x49df97[_0x5dfe7b(0x3ea)][0x0][_0x5dfe7b(0x484)],_0x4c6b26[_0x5dfe7b(0x170)](_0x49df97)[_0x5dfe7b(0x3f8)](()=>{var _0x3d8bca=_0x5dfe7b;log(_0x3d8bca(0x58c));});}catch(_0x8c29e1){errorlog(_0x8c29e1);}},_0x54fde4,_0x2781f8);});},_0x4bb952[_0x41b841(0x51b)]=function(_0x2c9ace,_0x38d0a2){var _0x16a8a2=_0x41b841;_0x38d0a2=parseInt(_0x38d0a2);try{var _0x256a59=_0x4bb952[_0x16a8a2(0x347)][_0x2c9ace][_0x16a8a2(0x375)]()[_0x16a8a2(0x52f)](function(_0x86fa11){var _0x24622c=_0x16a8a2;return _0x86fa11[_0x24622c(0x5b3)]&&_0x86fa11['track'][_0x24622c(0x20c)]==_0x24622c(0x169);});if(!_0x256a59){warnlog(_0x16a8a2(0x426));return;}var _0x1fd2f9=_0x256a59[_0x16a8a2(0x584)]();(!_0x1fd2f9[_0x16a8a2(0x3ea)]||_0x1fd2f9[_0x16a8a2(0x3ea)]['length']==0x0)&&(_0x1fd2f9[_0x16a8a2(0x3ea)]=[{}]);if(_0x38d0a2<0x0)_0x1fd2f9[_0x16a8a2(0x3ea)][0x0][_0x16a8a2(0x5da)]==![]&&(_0x1fd2f9['encodings'][0x0]['active']=!![]),safariVersion()<=0xd&&(iOS||iPad)?(_0x38d0a2=0x20,_0x4bb952[_0x16a8a2(0x497)]&&(_0x38d0a2=_0x4bb952[_0x16a8a2(0x497)]),_0x1fd2f9[_0x16a8a2(0x3ea)][0x0][_0x16a8a2(0x484)]=_0x38d0a2*0x400):delete _0x1fd2f9[_0x16a8a2(0x3ea)][0x0]['maxBitrate'];else _0x38d0a2===0x0?_0x1fd2f9[_0x16a8a2(0x3ea)][0x0]['active']=![]:(_0x1fd2f9['encodings'][0x0]['active']==![]&&(_0x16a8a2(0x5a6)===_0x16a8a2(0x5a6)?_0x1fd2f9[_0x16a8a2(0x3ea)][0x0][_0x16a8a2(0x5da)]=!![]:(_0x16a8a2(0x231)in _0x163571[_0x16a8a2(0x2c9)][_0x210493]['stats'][_0x16a8a2(0x531)]&&(_0x273072[_0x16a8a2(0x2c9)][_0x90b670]['stats'][_0x16a8a2(0x531)][_0x16a8a2(0x288)]&&(_0x561178['timestamp']&&(_0x13a1d4[_0x16a8a2(0x2c9)][_0x55157b][_0x16a8a2(0x5c3)][_0x16a8a2(0x531)][_0x16a8a2(0x5e8)]=_0x5d6d34(0x8*(_0x35448e[_0x16a8a2(0x571)]-_0x1ed398[_0x16a8a2(0x2c9)][_0x44bfc1][_0x16a8a2(0x5c3)][_0x16a8a2(0x531)][_0x16a8a2(0x231)])/(_0x52de72[_0x16a8a2(0x1c6)]-_0x129839['rpcs'][_0x2d72a4][_0x16a8a2(0x5c3)][_0x16a8a2(0x531)][_0x16a8a2(0x288)]))))),_0x1e234a[_0x16a8a2(0x2c9)][_0xac6a92][_0x16a8a2(0x5c3)][_0x16a8a2(0x531)][_0x16a8a2(0x231)]=_0x2fdf26[_0x16a8a2(0x571)])),_0x1fd2f9[_0x16a8a2(0x3ea)][0x0][_0x16a8a2(0x484)]=_0x38d0a2*0x400);_0x256a59[_0x16a8a2(0x170)](_0x1fd2f9)[_0x16a8a2(0x3f8)](()=>{var _0x3b9af9=_0x16a8a2;pokeIframeAPI(_0x3b9af9(0x3cf),_0x38d0a2,_0x2c9ace),log(_0x3b9af9(0x493));})[_0x16a8a2(0x5fa)](warnlog);}catch(_0x335473){errorlog(_0x335473);}},_0x4bb952['optimizeBitrate']=function(_0x5bd7c9){var _0x150dce=_0x41b841;if(_0x4bb952[_0x150dce(0x49d)]&&_0x4bb952[_0x150dce(0x347)][_0x5bd7c9]['allowIframe']===!![])_0x4bb952[_0x150dce(0x1a0)](_0x5bd7c9,0x0),_0x4bb952[_0x150dce(0x347)][_0x5bd7c9][_0x150dce(0x517)]===0x0&&(_0x4bb952[_0x150dce(0x347)][_0x5bd7c9][_0x150dce(0x1cd)]===![]?_0x4bb952[_0x150dce(0x51b)](_0x5bd7c9,0x0):_0x4bb952[_0x150dce(0x51b)](_0x5bd7c9,-0x1));else{if(_0x4bb952[_0x150dce(0x347)][_0x5bd7c9]&&_0x4bb952[_0x150dce(0x347)][_0x5bd7c9][_0x150dce(0x517)]!==![]){if(_0x4bb952[_0x150dce(0x347)][_0x5bd7c9][_0x150dce(0x1cd)]===![]){var _0x496042=_0x4bb952['pcs'][_0x5bd7c9][_0x150dce(0x517)];_0x4bb952[_0x150dce(0x347)][_0x5bd7c9][_0x150dce(0x50e)]&&_0x4bb952[_0x150dce(0x347)][_0x5bd7c9]['savedBitrate']>0x0&&(_0x4bb952[_0x150dce(0x347)][_0x5bd7c9]['savedBitrate']<_0x4bb952[_0x150dce(0x347)][_0x5bd7c9][_0x150dce(0x517)]&&(_0x496042=_0x4bb952[_0x150dce(0x347)][_0x5bd7c9][_0x150dce(0x50e)])),_0x4bb952['limitBitrate'](_0x5bd7c9,_0x496042),_0x4bb952[_0x150dce(0x347)][_0x5bd7c9]['optimizedBitrate']===0x0&&_0x4bb952[_0x150dce(0x51b)](_0x5bd7c9,0x0);}else _0x4bb952[_0x150dce(0x347)][_0x5bd7c9][_0x150dce(0x517)]===0x0&&_0x4bb952[_0x150dce(0x51b)](_0x5bd7c9,-0x1);}}},_0x4bb952[_0x41b841(0x43c)]=function(_0x175921=0x0,_0x6df264=![]){var _0x3c5037=_0x41b841;if(_0x4bb952[_0x3c5037(0x350)]){var _0x5592d8=_0x175921;warnlog(_0x5592d8);var _0x28395b=0x0;for(var _0x2c3d53 in _0x4bb952[_0x3c5037(0x347)]){if(_0x6df264===_0x2c3d53)continue;var _0x1f44f2=_0x4bb952[_0x3c5037(0x347)][_0x2c3d53][_0x3c5037(0x375)]()[_0x3c5037(0x52f)](function(_0x4ed7aa){var _0x463714=_0x3c5037;return _0x4ed7aa[_0x463714(0x5b3)]&&_0x4ed7aa[_0x463714(0x5b3)]['kind']=='video';});if(!_0x1f44f2)continue;var _0x257da8=_0x1f44f2['getParameters']();if(!_0x257da8[_0x3c5037(0x3ea)]||_0x257da8['encodings'][_0x3c5037(0x28f)]==0x0){if(_0x3c5037(0x5ca)!==_0x3c5037(0x5ca))_0xad3d14['rpcs'][_0x47e973][_0x3c5037(0x487)][_0x3c5037(0x31f)]()[_0x3c5037(0x3f8)](_0x12f2d3=>{var _0xb29bd4=_0x3c5037;_0x41636a(_0xb29bd4(0x345));})[_0x3c5037(0x5fa)](_0x38d78e);else{_0x5592d8+=_0x4bb952[_0x3c5037(0x347)][_0x2c3d53]['setBitrate']||0x9c4,warnlog(_0x5592d8),_0x28395b+=0x1;continue;}}if(_0x257da8[_0x3c5037(0x3ea)][0x0][_0x3c5037(0x5da)]==![])continue;_0x257da8[_0x3c5037(0x3ea)][0x0][_0x3c5037(0x484)]?(_0x5592d8+=parseInt(_0x257da8[_0x3c5037(0x3ea)][0x0][_0x3c5037(0x484)])/0x400,warnlog(_0x5592d8)):(_0x5592d8+=_0x4bb952[_0x3c5037(0x347)][_0x2c3d53]['setBitrate']||0x9c4,warnlog(_0x5592d8)),_0x28395b+=0x1;}if(!_0x5592d8)return![];var _0x176c05=parseFloat(_0x5592d8/_0x4bb952[_0x3c5037(0x350)]);if(_0x176c05>0x1)for(var _0x2c3d53 in _0x4bb952[_0x3c5037(0x347)]){if(_0x6df264===_0x2c3d53)continue;var _0x1f44f2=_0x4bb952[_0x3c5037(0x347)][_0x2c3d53][_0x3c5037(0x375)]()[_0x3c5037(0x52f)](function(_0x34623c){var _0x345982=_0x3c5037;return _0x34623c[_0x345982(0x5b3)]&&_0x34623c[_0x345982(0x5b3)][_0x345982(0x20c)]==_0x345982(0x195);});if(!_0x1f44f2)continue;var _0x257da8=_0x1f44f2[_0x3c5037(0x584)]();if(!_0x257da8[_0x3c5037(0x3ea)]||_0x257da8[_0x3c5037(0x3ea)]['length']==0x0){var _0x2b152c=_0x4bb952['pcs'][_0x2c3d53]['setBitrate']||0x9c4;_0x4bb952['limitBitrate'](_0x2c3d53,parseInt(_0x2b152c/_0x176c05),!![]),errorlog(parseInt(_0x2b152c/_0x176c05));continue;}if(_0x257da8[_0x3c5037(0x3ea)][0x0][_0x3c5037(0x5da)]==![])continue;if(_0x257da8[_0x3c5037(0x3ea)][0x0][_0x3c5037(0x484)])errorlog(parseInt(parseInt(_0x257da8['encodings'][0x0][_0x3c5037(0x484)])/0x400/_0x176c05)),_0x4bb952[_0x3c5037(0x1a0)](_0x2c3d53,parseInt(parseInt(_0x257da8['encodings'][0x0][_0x3c5037(0x484)])/0x400/_0x176c05),!![]);else{var _0x2b152c=_0x4bb952['pcs'][_0x2c3d53][_0x3c5037(0x50b)]||0x9c4;errorlog(parseInt(_0x2b152c/_0x176c05)),_0x4bb952[_0x3c5037(0x1a0)](_0x2c3d53,parseInt(_0x2b152c/_0x176c05),!![]);}}return parseInt(_0x175921/_0x176c05);}else return![];},_0x4bb952[_0x41b841(0x1a0)]=function(_0x8ac085,_0x27fa15,_0x1543dd=![]){var _0x483655=_0x41b841;_0x4bb952['pcs'][_0x8ac085]['bitrateTimeout']&&(clearInterval(_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x457)]),_0x4bb952[_0x483655(0x347)][_0x8ac085]['bitrateTimeout']=null);if(_0x27fa15===null){if(_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x50e)]===![]){if(_0x483655(0x268)==='rAUpx')return;else var _0x395a1f=_0x70714a[_0x483655(0x487)][_0x483655(0x213)][_0x483655(0x546)]()[0x0][_0x483655(0x555)](),_0x26ea90=_0x395a1f[_0x483655(0x3ec)],_0x52475e=_0x395a1f[_0x483655(0x55d)];}_0x27fa15=_0x4bb952[_0x483655(0x347)][_0x8ac085]['savedBitrate'];}_0x27fa15=parseInt(_0x27fa15);_0x4bb952[_0x483655(0x510)]&&(_0x27fa15>_0x4bb952[_0x483655(0x510)]&&(_0x27fa15=_0x4bb952[_0x483655(0x510)]));_0x4bb952[_0x483655(0x347)][_0x8ac085]['savedBitrate']=_0x27fa15;_0x4bb952[_0x483655(0x347)][_0x8ac085]['optimizedBitrate']!==![]&&(_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x1cd)]===![]&&(_0x27fa15>_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x517)]&&(_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x50e)]=_0x27fa15,_0x27fa15=parseInt(_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x517)])||0x0)));_0x1543dd===![]&&(_0x4bb952[_0x483655(0x350)]&&(_0x27fa15=_0x4bb952['limitTotalBitrateGuests'](_0x27fa15,_0x8ac085)));if(_0x27fa15==0x0){var _0x551ebe=Date[_0x483655(0x2c5)]()-_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x53a)];_0x551ebe<_0x4bb952[_0x483655(0x51a)]&&(_0x483655(0x262)!==_0x483655(0x262)?(_0x43299e[_0x483655(0x2c9)][_0x496d29][_0x483655(0x487)][_0x483655(0x1a2)][_0x483655(0x232)]=_0x483655(0x54d),_0x3a0a8e=!![]):(_0x27fa15=0x23,_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x457)]=setTimeout(function(_0x336a42){var _0xce126c=_0x483655;_0x4bb952[_0xce126c(0x1a0)](_0x336a42,null);},_0x551ebe,_0x8ac085)));}try{if(safariVersion()<=0xd&&(iOS||iPad)){log(_0x483655(0x1d2));if(_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x535)]==!![]&&_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x30e)]==![])return;var _0x2bd1bb=_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x375)]()[_0x483655(0x52f)](function(_0x1d8f99){var _0x47b462=_0x483655;return _0x1d8f99[_0x47b462(0x5b3)]&&_0x1d8f99[_0x47b462(0x5b3)][_0x47b462(0x20c)]==_0x47b462(0x195);});if(!_0x2bd1bb){warnlog(_0x483655(0x4fc));return;}var _0x3b71b2=_0x2bd1bb[_0x483655(0x584)]();(!_0x3b71b2[_0x483655(0x3ea)]||_0x3b71b2[_0x483655(0x3ea)][_0x483655(0x28f)]==0x0)&&(_0x3b71b2[_0x483655(0x3ea)]=[{}]);if(_0x27fa15<0x0)_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x5da)]==![]&&(_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x5da)]=!![]),_0x27fa15=0x9c4,_0x4bb952[_0x483655(0x476)]&&(_0x27fa15=_0x4bb952[_0x483655(0x476)]),_0x4bb952[_0x483655(0x510)]&&(_0x27fa15>_0x4bb952[_0x483655(0x510)]&&(_0x27fa15=_0x4bb952[_0x483655(0x510)])),_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x484)]=_0x27fa15*0x400;else _0x27fa15===0x0?_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x5da)]=![]:(_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x5da)]==![]&&(_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x5da)]=!![]),_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x484)]=_0x27fa15*0x400);_0x2bd1bb[_0x483655(0x170)](_0x3b71b2)[_0x483655(0x3f8)](()=>{var _0x3d730b=_0x483655;_0x3d730b(0x2fe)!==_0x3d730b(0x260)?(pokeIframeAPI('setVideoBitrate',_0x27fa15,_0x8ac085),log(_0x3d730b(0x1e5))):_0x540f93();})[_0x483655(0x5fa)](warnlog);return;}else{if((iOS||iPad)&&(_0x4bb952[_0x483655(0x347)][_0x8ac085]['guest']==!![]&&_0x4bb952['pcs'][_0x8ac085][_0x483655(0x30e)]==![])){var _0xdc5f16=0x64;_0x4bb952['pcs'][_0x8ac085][_0x483655(0x2ee)]&&(_0xdc5f16=_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x2ee)]),_0x4bb952[_0x483655(0x347)][_0x8ac085]['scaleResolution']&&_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x513)]<_0xdc5f16&&(_0xdc5f16=_0x4bb952['pcs'][_0x8ac085]['scaleResolution']),_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x5c1)]=0x64/0x3,_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x5c1)]<_0xdc5f16&&(_0xdc5f16=_0x4bb952['pcs'][_0x8ac085][_0x483655(0x5c1)]),_0xdc5f16=_0x4bb952['pixelFix'](_0xdc5f16),_0x3b71b2[_0x483655(0x3ea)][0x0]['scaleResolutionDownBy']=0x64/_0xdc5f16,_0x2bd1bb['setParameters'](_0x3b71b2)['then'](()=>{var _0x2b9383=_0x483655;log(_0x2b9383(0x508)),pokeIframeAPI(_0x2b9383(0x4ad),_0xdc5f16,_0x8ac085);})['catch'](warnlog),_0x4bb952[_0x483655(0x347)][_0x8ac085]['stats'][_0x483655(0x31c)]=parseInt(_0xdc5f16)+'%';}else{if((adapter[_0x483655(0x5d0)][_0x483655(0x390)]===_0x483655(0x47e)||adapter['browserDetails'][_0x483655(0x390)]===_0x483655(0x269)||adapter[_0x483655(0x5d0)][_0x483655(0x390)]==='firefox'&&adapter[_0x483655(0x5d0)][_0x483655(0x3c4)]>=0x40)&&_0x483655(0x564)in window&&_0x483655(0x170)in window[_0x483655(0x564)][_0x483655(0x2f7)]){var _0x2bd1bb=_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x375)]()[_0x483655(0x52f)](function(_0x56392b){var _0x470e7a=_0x483655;if(_0x470e7a(0x550)!==_0x470e7a(0x550))_0x5825e1+=0x100;else return _0x56392b[_0x470e7a(0x5b3)]&&_0x56392b[_0x470e7a(0x5b3)][_0x470e7a(0x20c)]=='video';});if(!_0x2bd1bb){if(_0x483655(0x23f)!==_0x483655(0x23f))_0x19ffe8=_0x1b1d87[_0x483655(0x2c9)][_0x106dc9][_0x483655(0x5c3)][_0x193c96]['Buffer_Delay_in_ms'],_0xdf06f2<0x0&&(_0x21164d=0x0),_0x59e2cc[_0x483655(0x2c9)][_0x987a58][_0x483655(0x5c3)][_0x56e297][_0x483655(0x400)]=_0x42bced,_0x57a6fb[_0x483655(0x246)]=_0x4f487c(_0x26a3ec/0x3e8);else{warnlog(_0x483655(0x4fc));return;}}var _0x3b71b2=_0x2bd1bb[_0x483655(0x584)]();(!_0x3b71b2[_0x483655(0x3ea)]||_0x3b71b2['encodings'][_0x483655(0x28f)]==0x0)&&(_0x3b71b2[_0x483655(0x3ea)]=[{}]);if(_0x27fa15<0x0)_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x5da)]==![]&&(_0x3b71b2['encodings'][0x0][_0x483655(0x5da)]=!![]),delete _0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x484)];else _0x27fa15===0x0?_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x5da)]=![]:(_0x3b71b2[_0x483655(0x3ea)][0x0]['active']==![]&&(_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x5da)]=!![]),_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x484)]=_0x27fa15*0x400);var _0xdc5f16=0x64;_0x4bb952[_0x483655(0x347)][_0x8ac085]['scale']&&(_0xdc5f16=_0x4bb952['pcs'][_0x8ac085]['scale']);_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x513)]&&_0x4bb952[_0x483655(0x347)][_0x8ac085]['scaleResolution']<_0xdc5f16&&(_0xdc5f16=_0x4bb952[_0x483655(0x347)][_0x8ac085]['scaleResolution']);if(_0x27fa15<0x0)_0x4bb952['pcs'][_0x8ac085]['scaleDueToBitrate']=0x64;else{if(_0x27fa15>=0x259)_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x5c1)]=0x64;else{if(_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x24c)]===![]&&_0x4bb952[_0x483655(0x266)]!==_0x8ac085&&_0x4bb952[_0x483655(0x235)])_0x4bb952[_0x483655(0x347)][_0x8ac085]['scaleDueToBitrate']=0x64;else{if(_0x27fa15>=0xc9)_0x483655(0x454)===_0x483655(0x46f)?_0x46471d[_0x483655(0x2c9)][_0x5d1c32][_0x483655(0x45f)]&&_0x5aa66d[_0x483655(0x2c9)][_0x207735][_0x483655(0x45f)][_0x483655(0x3bb)]()['forEach'](function(_0x25fa95){var _0x3261e7=_0x483655;_0x25fa95[_0x3261e7(0x3a4)](),_0x41f6c4(_0x3261e7(0x221));}):_0x4bb952[_0x483655(0x5d4)]?_0x4bb952['pcs'][_0x8ac085]['scaleDueToBitrate']=0x64/2.5:_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x5c1)]=0x64/0x2;else _0x27fa15>=0x51?_0x4bb952[_0x483655(0x347)][_0x8ac085]['scaleDueToBitrate']=0x64/0x3:_0x4bb952['pcs'][_0x8ac085][_0x483655(0x5c1)]=0x64/0x4;}}}_0x4bb952[_0x483655(0x347)][_0x8ac085]['scaleDueToBitrate']<_0xdc5f16&&(_0xdc5f16=_0x4bb952[_0x483655(0x347)][_0x8ac085][_0x483655(0x5c1)]);_0xdc5f16=_0x4bb952[_0x483655(0x3d9)](_0xdc5f16),_0x3b71b2[_0x483655(0x3ea)][0x0][_0x483655(0x34a)]=0x64/_0xdc5f16,_0x2bd1bb[_0x483655(0x170)](_0x3b71b2)[_0x483655(0x3f8)](()=>{var _0x7fc00c=_0x483655;log(_0x7fc00c(0x1e5)),pokeIframeAPI('setVideoBitrate',_0x27fa15,_0x8ac085),pokeIframeAPI(_0x7fc00c(0x4ad),_0xdc5f16,_0x8ac085);})[_0x483655(0x5fa)](warnlog),_0x4bb952[_0x483655(0x347)][_0x8ac085]['stats'][_0x483655(0x31c)]=parseInt(_0xdc5f16)+'%';return;}}}}catch(_0x124653){errorlog(_0x124653);}};function _0x5e4081(_0x3c3634,_0x1894df=0x2710){var _0x9cfe84=_0x41b841;_0x1894df=parseInt(_0x1894df);if(_0x4bb952[_0x9cfe84(0x497)])_0x1894df+=_0x4bb952['audiobitrate'];else{if(_0x4bb952[_0x9cfe84(0x18f)]&&_0x4bb952[_0x9cfe84(0x2b1)]==0x5)_0x1894df+=0x20;else _0x4bb952[_0x9cfe84(0x2b1)]&&_0x4bb952[_0x9cfe84(0x2b1)]!=0x3?_0x1894df+=0x100:_0x1894df+=0x20;}return log('actual\x20bitrate:'+_0x1894df),_0x1894df<0x1&&(_0x1894df=0x1),_0x3c3634=CodecsHandler[_0x9cfe84(0x209)](_0x3c3634,{'min':parseInt(_0x1894df/0xa)||0x1,'max':_0x1894df},_0x4bb952[_0x9cfe84(0x529)]),_0x3c3634;}return _0x4bb952[_0x41b841(0x1df)]=function(_0x412ee1,_0x19d5fb){var _0x2e6a8e=_0x41b841;log(_0x412ee1),_0x4bb952['mykey']==={}&&log(_0x2e6a8e(0x3ae)),window[_0x2e6a8e(0x2e5)][_0x2e6a8e(0x412)][_0x2e6a8e(0x3e9)]({'name':'RSASSA-PKCS1-v1_5'},_0x4bb952[_0x2e6a8e(0x5c8)][_0x2e6a8e(0x381)],_0x4bb952[_0x2e6a8e(0x2e2)]['encode'](_0x412ee1))[_0x2e6a8e(0x3f8)](function(_0x2c66c4){var _0x31b3c1=_0x2e6a8e;_0x2c66c4=new Uint8Array(_0x2c66c4),_0x2c66c4=_0x2c66c4[_0x31b3c1(0x3d7)]((_0x9a0210,_0x335c97)=>_0x9a0210+_0x335c97[_0x31b3c1(0x3bd)](0x10)[_0x31b3c1(0x3f5)](0x2,'0'),''),_0x19d5fb(_0x412ee1,_0x2c66c4),log(JSON[_0x31b3c1(0x47f)](_0x2c66c4));})[_0x2e6a8e(0x5fa)](errorlog);},_0x4bb952['verifyData']=function(_0x3ec7dc,_0x25ad27){var _0x236ffe=_0x41b841;_0x3ec7dc[_0x236ffe(0x59f)]=new Uint8Array(_0x3ec7dc[_0x236ffe(0x59f)]['match'](/.{1,2}/g)['map'](_0x1d2de0=>parseInt(_0x1d2de0,0x10)));if(_0x4bb952['keys'][_0x25ad27][_0x236ffe(0x1a6)])return window[_0x236ffe(0x2e5)]['subtle'][_0x236ffe(0x40f)]({'name':_0x236ffe(0x247)},_0x4bb952[_0x236ffe(0x589)][_0x25ad27][_0x236ffe(0x1a6)],_0x3ec7dc['signature'],_0x4bb952[_0x236ffe(0x2e2)]['encode'](_0x3ec7dc['data']))[_0x236ffe(0x3f8)](function(_0x44bba7){return log(_0x44bba7),_0x44bba7;})['catch'](function(_0x1924e0){var _0x5d2324=_0x236ffe;return _0x5d2324(0x548)===_0x5d2324(0x219)?_0x2b1b9b[_0x5d2324(0x412)][_0x5d2324(0x460)]({'name':_0x5d2324(0x51d),'iv':_0x2f5292},_0x47e7d0,_0x43f765(_0x12e05a))[_0x5d2324(0x3f8)](function(_0x141369){return _0x87b34e=new _0x4f72d9(_0x141369),_0x272cac=_0x51b89a(_0x3b3748),_0x39bae9=_0x46ac79(_0x470f43),[_0x37e996,_0x5cc77];},function(_0x4a6108){var _0x407c84=_0x5d2324;return _0x25542d(_0x4a6108[_0x407c84(0x3ef)]),![];}):(errorlog(_0x1924e0),![]);});},_0x4bb952[_0x41b841(0x18d)]=function(_0x5b3739){var _0x43df2b=_0x41b841;if(_0x4bb952['password']){if(_0x4bb952['hash']!==![]){if(_0x43df2b(0x185)===_0x43df2b(0x185))return log(_0x43df2b(0x4f6)),_0x5b3739=_0x5b3739[_0x43df2b(0x2d0)](0x0,-0x1*_0x4bb952[_0x43df2b(0x41e)][_0x43df2b(0x28f)]),_0x5b3739;else _0x1b6a54=_0x558b59[_0x43df2b(0x2c9)][_0x3dc694][_0x43df2b(0x5c3)][_0x143dce]['_sync_offset'];}else return log(_0x43df2b(0x3e2)+_0x5b3739),_0x4bb952[_0x43df2b(0x181)](_0x4bb952[_0x43df2b(0x208)]+_0x4bb952[_0x43df2b(0x558)],0x6)[_0x43df2b(0x3f8)](function(_0x4da4b3){var _0x1ee36c=_0x43df2b;return _0x4bb952[_0x1ee36c(0x41e)]=_0x4da4b3,log(_0x5b3739),_0x5b3739=_0x5b3739[_0x1ee36c(0x2d0)](0x0,-0x1*_0x4bb952[_0x1ee36c(0x41e)][_0x1ee36c(0x28f)]),log(_0x1ee36c(0x595)+_0x5b3739),_0x5b3739;});}return _0x5b3739;},_0x4bb952[_0x41b841(0x196)]=function(){var _0x3e837b=_0x41b841;if(!_0x4bb952['queue'])return;if(!_0x4bb952[_0x3e837b(0x18f)])return;_0x4bb952[_0x3e837b(0x448)][_0x3e837b(0x28f)]?(_0x4bb952['queueList']['length']>0xa?_0x3e837b(0x182)!==_0x3e837b(0x182)?(_0x394de6[_0x3e837b(0x2c9)][_0xe72b46][_0x3e837b(0x487)][_0x3e837b(0x1a2)][_0x3e837b(0x232)]=_0x3e837b(0x3e8),_0x50ff8f=!![]):getById('queueNotification')[_0x3e837b(0x172)]='โ€ผ':getById(_0x3e837b(0x479))[_0x3e837b(0x172)]=_0x4bb952[_0x3e837b(0x448)][_0x3e837b(0x28f)],getById(_0x3e837b(0x479))[_0x3e837b(0x1af)]['add'](_0x3e837b(0x479))):(getById('queueNotification')[_0x3e837b(0x172)]='',getById(_0x3e837b(0x479))[_0x3e837b(0x1af)]['remove'](_0x3e837b(0x479)));},_0x4bb952[_0x41b841(0x4da)]=function(){var _0x22ac4c=_0x41b841;if(!_0x4bb952[_0x22ac4c(0x45a)])return;if(!_0x4bb952[_0x22ac4c(0x18f)]){if(_0x22ac4c(0x295)!==_0x22ac4c(0x295))return _0x29d44a;else return;}if(_0x4bb952[_0x22ac4c(0x448)][_0x22ac4c(0x28f)]==0x0){getById('queuebutton')[_0x22ac4c(0x1af)][_0x22ac4c(0x5e9)](_0x22ac4c(0x3cc)),getById(_0x22ac4c(0x2a3))[_0x22ac4c(0x1af)][_0x22ac4c(0x5e9)](_0x22ac4c(0x2a1)),getById(_0x22ac4c(0x2a3))['classList'][_0x22ac4c(0x590)](_0x22ac4c(0x180)),setTimeout(function(){var _0x3fe478=_0x22ac4c;getById(_0x3fe478(0x2a3))[_0x3fe478(0x1af)]['add'](_0x3fe478(0x180)),getById('queuebutton')[_0x3fe478(0x1af)][_0x3fe478(0x590)](_0x3fe478(0x3cc)),getById(_0x3fe478(0x2a3))[_0x3fe478(0x1af)][_0x3fe478(0x590)](_0x3fe478(0x2a1));},0x32);return;}var _0x3979ed=_0x4bb952[_0x22ac4c(0x448)]['shift']();getById('queuebutton')[_0x22ac4c(0x1af)][_0x22ac4c(0x5e9)]('float2'),getById(_0x22ac4c(0x2a3))[_0x22ac4c(0x1af)][_0x22ac4c(0x590)](_0x22ac4c(0x180)),setTimeout(function(){var _0x2784f0=_0x22ac4c;getById(_0x2784f0(0x2a3))['classList']['add'](_0x2784f0(0x180)),getById(_0x2784f0(0x2a3))[_0x2784f0(0x1af)][_0x2784f0(0x590)](_0x2784f0(0x3cc));},0xc8),_0x4bb952[_0x22ac4c(0x196)](),_0x4bb952['watchStream'](_0x3979ed),log(_0x22ac4c(0x5b8)+_0x3979ed);},_0x4bb952[_0x41b841(0x1dc)]=function(){var _0x5e5f6d=_0x41b841;if(_0x4bb952[_0x5e5f6d(0x42f)])return;clearTimeout(_0x4bb952[_0x5e5f6d(0x20b)]);if(!_0x4bb952['ws']||_0x4bb952['ws'][_0x5e5f6d(0x2e0)]!==0x1){if('jdMEH'!=='jdMEH')_0x3a5c31=_0x2a1c41[_0x5e5f6d(0x4c1)];else return;}_0x4bb952[_0x5e5f6d(0x20b)]=setTimeout(function(){var _0x174557=_0x5e5f6d;log(_0x174557(0x3de));var _0x27ed04={};_0x27ed04['request']=_0x174557(0x1dc),_0x4bb952[_0x174557(0x3c0)](_0x27ed04);},0xbb8);},_0x4bb952[_0x41b841(0x360)]=function(_0x1fae31){var _0x414faa=_0x41b841;_0x4bb952[_0x414faa(0x4d0)]();if(_0x1fae31[_0x414faa(0x28f)]>0x0){var _0x42446e={};_0x42446e[_0x414faa(0x16a)]='play',_0x42446e[_0x414faa(0x4e8)]=_0x1fae31,_0x4bb952[_0x414faa(0x3c0)](_0x42446e),_0x4bb952[_0x414faa(0x1ad)][_0x1fae31]=!![];}else log('stream\x20ID\x20is\x200\x20length');},_0x4bb952['joinRoom']=function _0x5f44c9(_0x23c370){var _0x453651=_0x41b841;_0x4bb952[_0x453651(0x4d0)]();var _0x41c122={};return _0x41c122[_0x453651(0x16a)]=_0x453651(0x282),_0x4bb952['director']&&(_0x41c122['claim']=!![]),_0x4bb952[_0x453651(0x42f)]&&(_0x41c122[_0x453651(0x4e8)]=_0x4bb952[_0x453651(0x4e8)]),_0x4bb952[_0x453651(0x26a)]===![]&&(_0x4bb952[_0x453651(0x26a)]=!![]),_0x4bb952[_0x453651(0x208)]?_0x4bb952[_0x453651(0x41e)]?_0x4bb952[_0x453651(0x181)](_0x23c370+_0x4bb952[_0x453651(0x208)]+_0x4bb952[_0x453651(0x558)],0x10)[_0x453651(0x3f8)](function(_0x4ac40d){var _0x48eea6=_0x453651;return _0x4bb952['pie']&&(_0x4bb952[_0x48eea6(0x575)]=_0x4ac40d),_0x41c122[_0x48eea6(0x1e0)]=_0x4ac40d,_0x4bb952[_0x48eea6(0x3c0)](_0x41c122),_0x4bb952[_0x48eea6(0x4d3)]=_0x40edff(),log(_0x48eea6(0x5e0)),_0x4bb952[_0x48eea6(0x4d3)];}):_0x4bb952[_0x453651(0x181)](_0x4bb952[_0x453651(0x208)]+_0x4bb952[_0x453651(0x558)],0x6)[_0x453651(0x3f8)](function(_0x1b4f56){var _0x371ed8=_0x453651;return _0x4bb952[_0x371ed8(0x41e)]=_0x1b4f56,log(_0x371ed8(0x4ee)+_0x1b4f56),log(_0x371ed8(0x3fc)),_0x4bb952[_0x371ed8(0x3e5)](_0x23c370);}):(_0x4bb952[_0x453651(0x42f)]&&(_0x4bb952[_0x453651(0x575)]=_0x23c370),_0x41c122[_0x453651(0x1e0)]=_0x23c370,_0x4bb952[_0x453651(0x3c0)](_0x41c122),_0x4bb952[_0x453651(0x4d3)]=_0x40edff(),log(_0x453651(0x1c0)),_0x4bb952[_0x453651(0x4d3)]);},_0x4bb952['sendMsg']=function(_0x3e9d46){var _0x37038d=_0x41b841;if(_0x37038d(0x5c5)===_0x37038d(0x5c5)){_0x4bb952[_0x37038d(0x42f)]&&(_0x4bb952[_0x37038d(0x4ec)]?_0x3e9d46[_0x37038d(0x534)]=_0x4bb952[_0x37038d(0x4ec)]:(_0x4bb952['UUID']=_0x4bb952[_0x37038d(0x357)](0x14),_0x3e9d46[_0x37038d(0x534)]=_0x4bb952[_0x37038d(0x4ec)]),_0x4bb952[_0x37038d(0x18f)]&&(_0x3e9d46[_0x37038d(0x18f)]=!![]),!(_0x37038d(0x1e0)in _0x3e9d46)&&(_0x4bb952[_0x37038d(0x575)]&&(_0x3e9d46[_0x37038d(0x1e0)]=_0x4bb952['roomenc'])));clearTimeout(_0x4bb952['pingTimeout']);try{if(_0x4bb952[_0x37038d(0x208)]){if(_0x3e9d46[_0x37038d(0x4e8)]){if(_0x4bb952[_0x37038d(0x41e)]!==![]){if(typeof _0x4bb952['ws']!==_0x37038d(0x5d9)||_0x4bb952['ws'][_0x37038d(0x2e0)]!==0x1)log(_0x3e9d46,_0x37038d(0x329)),_0x4bb952[_0x37038d(0x471)][_0x37038d(0x3a5)](_0x3e9d46);else{_0x3e9d46[_0x37038d(0x4e8)]=_0x3e9d46[_0x37038d(0x4e8)][_0x37038d(0x1f5)](0x0,0x18)+_0x4bb952['hash'][_0x37038d(0x1f5)](0x0,0x6);var _0x3124fd=JSON['stringify'](_0x3e9d46);if(_0x3124fd[_0x37038d(0x28f)]>0x3a98){errorlog(_0x37038d(0x215));return;}_0x4bb952['ws'][_0x37038d(0x245)](_0x3124fd);}}else return _0x4bb952[_0x37038d(0x181)](_0x4bb952[_0x37038d(0x208)]+_0x4bb952[_0x37038d(0x558)],0x6)[_0x37038d(0x3f8)](function(_0x4b3bbb){var _0x549aed=_0x37038d;_0x4bb952[_0x549aed(0x41e)]=_0x4b3bbb;if(typeof _0x4bb952['ws']!==_0x549aed(0x5d9)||_0x4bb952['ws'][_0x549aed(0x2e0)]!==0x1)log(_0x3e9d46,_0x549aed(0x329)),_0x4bb952[_0x549aed(0x471)][_0x549aed(0x3a5)](_0x3e9d46);else{_0x3e9d46[_0x549aed(0x4e8)]=_0x3e9d46['streamID'][_0x549aed(0x1f5)](0x0,0x18)+_0x4bb952[_0x549aed(0x41e)]['substring'](0x0,0x6);var _0x541c34=JSON[_0x549aed(0x47f)](_0x3e9d46);if(_0x541c34[_0x549aed(0x28f)]>0x3a98){errorlog(_0x549aed(0x215));return;}_0x4bb952['ws'][_0x549aed(0x245)](_0x541c34);}});}else{if(typeof _0x4bb952['ws']!==_0x37038d(0x5d9)||_0x4bb952['ws']['readyState']!==0x1)log(_0x3e9d46,_0x37038d(0x329)),_0x4bb952[_0x37038d(0x471)][_0x37038d(0x3a5)](_0x3e9d46);else{var _0x3124fd=JSON[_0x37038d(0x47f)](_0x3e9d46);if(_0x3124fd[_0x37038d(0x28f)]>0x3a98){errorlog(_0x37038d(0x215));return;}_0x4bb952['ws'][_0x37038d(0x245)](_0x3124fd);}}}else{if(typeof _0x4bb952['ws']!=='object'||_0x4bb952['ws'][_0x37038d(0x2e0)]!==0x1)log(_0x3e9d46,_0x37038d(0x329)),_0x4bb952[_0x37038d(0x471)][_0x37038d(0x3a5)](_0x3e9d46);else{if(_0x37038d(0x1ae)!==_0x37038d(0x1ae)){if(_0x152d85[_0x37038d(0x29a)]&&_0x341c0f[_0x54ba70][_0x37038d(0x53e)][_0x37038d(0x4ec)]===_0x5f2b35[_0x37038d(0x29a)]){}else _0xad8bc2[_0x46f88f][_0x37038d(0x1af)][_0x37038d(0x590)](_0x37038d(0x238));}else{var _0x3124fd=JSON['stringify'](_0x3e9d46);if(_0x3124fd[_0x37038d(0x28f)]>0x3a98){errorlog(_0x37038d(0x215));return;}_0x4bb952['ws'][_0x37038d(0x245)](_0x3124fd);}}}}catch(_0x2dcc0b){errorlog(_0x2dcc0b);}}else return('0'+(_0x1b2175&0xff)[_0x37038d(0x3bd)](0x10))[_0x37038d(0x2d0)](-0x2);},_0x4bb952['connect']=function _0x345d8b(_0x4418cf=![]){var _0x4f251f=_0x41b841;if(_0x4bb952[_0x4f251f(0x2e1)]===!![]){log(_0x4f251f(0x29f));return;}if(_0x4bb952['ws']!==null){log(_0x4f251f(0x1ff));return;}_0x4bb952['wss']==![]&&(_0x4f251f(0x197)!==_0x4f251f(0x560)?_0x4bb952[_0x4f251f(0x289)]=_0x4f251f(0x39e):_0x4dc185[_0x4f251f(0x2c9)][_0x8fd9f5][_0x4f251f(0x5cd)]());_0x4bb952['ws']=new WebSocket(_0x4bb952[_0x4f251f(0x289)]);if(_0x4418cf==![]){if(_0x4f251f(0x2c1)!==_0x4f251f(0x2c1))return _0x447caf[_0x4f251f(0x5b3)]&&_0xb2356f['track']['kind']==_0x4f251f(0x195);else _0x4bb952[_0x4f251f(0x254)]=setTimeout(function(){var _0x1d7920=_0x4f251f;pokeIframeAPI(_0x1d7920(0x482),_0x1d7920(0x254)),errorlog(_0x1d7920(0x2b9)),!_0x4bb952[_0x1d7920(0x52d)]&&(!window[_0x1d7920(0x1e7)]&&setTimeout(function(){var _0x28f45c=_0x1d7920;'mVztT'===_0x28f45c(0x5f8)?warnUser('Notice:\x20The\x20system\x20is\x20currently\x20slow\x20to\x20respond\x20or\x20not\x20accessible.\x0a\x0aClick\x20OK\x20to\x20continue.\x0a\x0aIf\x20the\x20site\x20fails\x20to\x20work\x20though,\x20please\x20try\x20https://backup.obs.ninja\x20instead\x20or\x20contact\x20steve@seguin.email\x20for\x20help.\x0a\x0aThis\x20service\x20requires\x20the\x20use\x20of\x20Websockets\x20over\x20port\x20443.'):(_0x1a1b07(_0x28f45c(0x2a3))[_0x28f45c(0x1af)][_0x28f45c(0x5e9)]('float'),_0x433989(_0x28f45c(0x2a3))['classList']['remove'](_0x28f45c(0x3cc)));},0x1));},0x7530);}_0x4bb952['ws'][_0x4f251f(0x256)]=function _0x8c599c(){var _0x423f51=_0x4f251f;clearTimeout(_0x4bb952[_0x423f51(0x20b)]),clearInterval(_0x4bb952['timeout']),log(_0x423f51(0x370)),checkConnection();if(_0x4bb952['transferred']){errorlog(_0x423f51(0x297));for(_0x43b726 in _0x4bb952[_0x423f51(0x2c9)]){try{_0x4bb952[_0x423f51(0x2c9)][_0x43b726][_0x423f51(0x5cd)]();}catch(_0x528388){}}for(_0x43b726 in _0x4bb952[_0x423f51(0x347)]){try{_0x4bb952[_0x423f51(0x347)][_0x43b726][_0x423f51(0x5cd)]();}catch(_0x2a6a2e){}}_0x4bb952[_0x423f51(0x2b3)]=![],_0x4bb952['broadcastIFrame']=![];}if(_0x4bb952[_0x423f51(0x471)]!==[]){if(_0x423f51(0x442)!==_0x423f51(0x442))_0x580a40 in _0x25ec86[_0x423f51(0x2c9)]&&_0x3240ad[_0x423f51(0x5bc)](0x0,_0x323405);else try{var _0x48cbda=_0x4bb952[_0x423f51(0x471)][_0x423f51(0x2d0)](-0xa);_0x4bb952['msg']=[];for(var _0x13ccf4 in _0x48cbda){log(_0x423f51(0x160)),_0x4bb952[_0x423f51(0x3c0)](_0x48cbda[_0x13ccf4]);}}catch(_0x2cc25f){errorlog(_0x2cc25f);}}if(_0x4418cf==!![]){pokeIframeAPI(_0x423f51(0x482),_0x423f51(0x31d));_0x4bb952[_0x423f51(0x28a)]&&_0x4bb952[_0x423f51(0x4c9)]();if(_0x4bb952[_0x423f51(0x1e0)]!==![]){if(_0x423f51(0x536)!==_0x423f51(0x536)){_0x4fe097(_0x423f51(0x3dd)),_0x212b8b(_0x3b0735[_0x423f51(0x4d1)]);return;}else{if(_0x4bb952[_0x423f51(0x1e0)]===''&&(!_0x4bb952[_0x423f51(0x3bc)]||_0x4bb952['view']==='')){}else log(_0x423f51(0x4a0)),log(_0x423f51(0x1e1)),joinRoom(_0x4bb952[_0x423f51(0x1e0)]);}}else{var _0x190b0d=Object[_0x423f51(0x589)](_0x4bb952[_0x423f51(0x1ad)]);for(var _0x43b726 in _0x190b0d){log(_0x423f51(0x5e5)+_0x190b0d[_0x43b726]),_0x4bb952[_0x423f51(0x360)](_0x190b0d[_0x43b726]);}}}else _0x423f51(0x15d)===_0x423f51(0x15d)?pokeIframeAPI(_0x423f51(0x482),_0x423f51(0x4e1)):_0x49d3a4(_0x423f51(0x345));},_0x4bb952['sendPeers']=function(_0x4b0837,_0x573557=![]){var _0x43242c=_0x4f251f,_0x28cb0a=[];for(var _0x3e9bcd in _0x4bb952['pcs']){if(_0x573557&&_0x573557!==_0x3e9bcd)continue;try{_0x43242c(0x354)==='dpHrT'?_0x463386[_0x43242c(0x347)][_0x53137d][_0x43242c(0x481)]=![]:(_0x4bb952[_0x43242c(0x347)][_0x3e9bcd][_0x43242c(0x37d)][_0x43242c(0x245)](JSON[_0x43242c(0x47f)](_0x4b0837)),_0x28cb0a['push'](_0x3e9bcd));}catch(_0x4f426c){warnlog(_0x43242c(0x3c2));}if(_0x573557&&_0x573557===_0x3e9bcd)return;}for(var _0x3e9bcd in _0x4bb952[_0x43242c(0x2c9)]){if(_0x573557&&_0x573557!==_0x3e9bcd)continue;if(_0x28cb0a['includes'](_0x3e9bcd))continue;try{_0x4bb952[_0x43242c(0x2c9)][_0x3e9bcd][_0x43242c(0x4b2)][_0x43242c(0x245)](JSON[_0x43242c(0x47f)](_0x4b0837));}catch(_0x385cd6){warnlog(_0x43242c(0x35a));}}},_0x4bb952['anysend']=function(_0x1d9f3a,_0x1c8542=![]){var _0x5aba61=_0x4f251f,_0xa5ea73=![];if(_0x5aba61(0x4ec)in _0x1d9f3a){_0xa5ea73=_0x4bb952[_0x5aba61(0x2ed)](_0x1d9f3a,_0x1d9f3a['UUID']);if(_0xa5ea73){if(_0x5aba61(0x45b)===_0x5aba61(0x45b))log(_0x1d9f3a),log('successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS');else for(var _0x5b327f in _0x3aa23d[_0x5aba61(0x433)][_0x5aba61(0x32c)]){_0x1e5d37(function(_0x5bbe44){var _0x25039f=_0x5aba61;_0x11ff6f[_0x25039f(0x22f)](_0x5bbe44);},0x3e8,_0x5e68a2[_0x5aba61(0x433)][_0x5aba61(0x32c)][_0x5b327f]);}}else log(_0x5aba61(0x38c)),_0x4bb952[_0x5aba61(0x3c0)](_0x1d9f3a);}else _0x1c8542?_0x5aba61(0x5d3)!==_0x5aba61(0x353)?(_0xa5ea73=_0x4bb952[_0x5aba61(0x2ed)](_0x1d9f3a),_0xa5ea73?(log(_0x1d9f3a),log(_0x5aba61(0x17d))):(log(_0x5aba61(0x2c4)),_0x4bb952[_0x5aba61(0x3c0)](_0x1d9f3a))):_0x2d74a1['rpcs'][_0x3cdedd][_0x5aba61(0x273)]['dataset'][_0x5aba61(0x399)]=_0x4cbe66['rpcs'][_0xf3f6c7][_0x5aba61(0x4e8)]:(_0x4bb952[_0x5aba61(0x3c0)](_0x1d9f3a),log(_0x5aba61(0x36f)));},_0x4bb952[_0x4f251f(0x490)]=function(_0x57618e,_0x3c095a=![]){var _0x39fb7d=_0x4f251f,_0x1375a3=![];if(_0x39fb7d(0x4ec)in _0x57618e)_0x1375a3=_0x4bb952[_0x39fb7d(0x261)](_0x57618e,_0x57618e[_0x39fb7d(0x4ec)]),_0x1375a3?log(_0x39fb7d(0x5ea)):(log('sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message'),_0x4bb952[_0x39fb7d(0x3c0)](_0x57618e));else _0x3c095a?(_0x1375a3=_0x4bb952[_0x39fb7d(0x261)](_0x57618e),_0x1375a3?log('successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS\x20to\x20all\x20RTC\x20Peers'):(log(_0x39fb7d(0x2c4)),_0x4bb952['sendMsg'](_0x57618e))):(_0x4bb952[_0x39fb7d(0x3c0)](_0x57618e),log(_0x39fb7d(0x36f)));},_0x4bb952[_0x4f251f(0x43d)]=function(){var _0x24cfed=_0x4f251f;if(_0x4bb952[_0x24cfed(0x47d)]===![]){var _0x4103dc={},_0x379bba=![];_0x4bb952[_0x24cfed(0x204)][_0x24cfed(0x202)]!==null&&(_0x4bb952[_0x24cfed(0x204)][_0x24cfed(0x202)]===![]&&(_0x379bba=!![]),_0x4103dc[_0x24cfed(0x1cd)]=_0x4bb952[_0x24cfed(0x204)][_0x24cfed(0x202)]);_0x4bb952[_0x24cfed(0x204)][_0x24cfed(0x1eb)]!==null&&(_0x4103dc[_0x24cfed(0x1b7)]=_0x4bb952['obsState'][_0x24cfed(0x1eb)]);_0x4bb952[_0x24cfed(0x204)][_0x24cfed(0x203)]!==null&&(_0x4103dc[_0x24cfed(0x365)]=_0x4bb952[_0x24cfed(0x204)][_0x24cfed(0x203)]);_0x4bb952[_0x24cfed(0x204)][_0x24cfed(0x50a)]!==null&&(_0x4103dc[_0x24cfed(0x283)]=_0x4bb952[_0x24cfed(0x204)]['streaming']);for(var _0x45a289 in _0x4bb952['rpcs']){if(_0x4bb952[_0x24cfed(0x230)]!==![]){var _0x2924cf=parseInt(_0x4bb952['rpcs'][_0x45a289][_0x24cfed(0x49a)]);_0x379bba&&((_0x2924cf>_0x4bb952[_0x24cfed(0x230)]||_0x2924cf<0x0)&&(_0x2924cf=_0x4bb952['optimize'])),_0x4bb952['rpcs'][_0x45a289]['bandwidth']!==_0x2924cf?(_0x4103dc[_0x24cfed(0x476)]=_0x2924cf,warnlog(_0x24cfed(0x21d)),warnlog(_0x4103dc),_0x4bb952[_0x24cfed(0x261)](_0x4103dc,_0x45a289)?_0x4bb952['rpcs'][_0x45a289][_0x24cfed(0x1c7)]=_0x2924cf:errorlog(_0x24cfed(0x186))):(warnlog(_0x24cfed(0x21d)),warnlog(_0x4103dc),_0x4bb952[_0x24cfed(0x261)](_0x4103dc,_0x45a289));}else _0x24cfed(0x428)!==_0x24cfed(0x428)?(_0x16366c(),_0xdb683d()):(warnlog(_0x24cfed(0x21d)),warnlog(_0x4103dc),_0x4bb952[_0x24cfed(0x261)](_0x4103dc,_0x45a289));}}},_0x4bb952[_0x4f251f(0x3a1)]=function(_0x2a853e){var _0x3cbc2c=_0x4f251f;if(!_0x4bb952['rpcs'][_0x2a853e][_0x3cbc2c(0x487)])return;var _0x2bb884={};_0x2bb884[_0x3cbc2c(0x40a)]=_0x4bb952[_0x3cbc2c(0x2c9)][_0x2a853e]['videoElement'][_0x3cbc2c(0x1a2)][_0x3cbc2c(0x232)]!=_0x3cbc2c(0x54d),_0x2bb884[_0x3cbc2c(0x2f3)]=_0x4bb952[_0x3cbc2c(0x2c9)][_0x2a853e][_0x3cbc2c(0x487)][_0x3cbc2c(0x3df)];if(_0x4bb952[_0x3cbc2c(0x230)]!==![]){var _0x5331d4=parseInt(_0x4bb952[_0x3cbc2c(0x2c9)][_0x2a853e]['targetBandwidth']);_0x2bb884[_0x3cbc2c(0x40a)]===![]&&((_0x5331d4>_0x4bb952[_0x3cbc2c(0x230)]||_0x5331d4<0x0)&&(_0x5331d4=_0x4bb952[_0x3cbc2c(0x230)])),_0x4bb952[_0x3cbc2c(0x2c9)][_0x2a853e][_0x3cbc2c(0x1c7)]!==_0x5331d4?(_0x2bb884[_0x3cbc2c(0x476)]=_0x5331d4,_0x4bb952[_0x3cbc2c(0x261)](_0x2bb884,_0x2a853e)?_0x4bb952['rpcs'][_0x2a853e][_0x3cbc2c(0x1c7)]=_0x5331d4:errorlog('Unable\x20to\x20set\x20update\x20OBS\x20Visibility')):_0x4bb952[_0x3cbc2c(0x261)](_0x2bb884,_0x2a853e);}else _0x4bb952[_0x3cbc2c(0x261)](_0x2bb884,_0x2a853e);},_0x4bb952[_0x4f251f(0x22f)]=function(_0x5bf1c8){var _0x44c303=_0x4f251f;if(_0x44c303(0x17f)in _0x5bf1c8){if(_0x44c303(0x58d)in _0x5bf1c8){if('scene'in _0x5bf1c8){if(_0x4bb952[_0x44c303(0x24c)]!==![]){var _0x4f4354=![];for(var _0x3dafd6 in _0x4bb952[_0x44c303(0x2c9)]){if(_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x4e8)]===_0x5bf1c8[_0x44c303(0x58d)]){if(_0x44c303(0x554)in _0x5bf1c8){if(_0x5bf1c8['action']=='mute'){if(_0x5bf1c8[_0x44c303(0x554)]==0x0)log(_0x44c303(0x4cc)),_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]&&(_0x4bb952['rpcs'][_0x3dafd6]['videoElement']['muted']=!![],_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x1a1)]=!![]);else{log(_0x44c303(0x5d2));if(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]){if('ccifY'===_0x44c303(0x3eb)){if(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]['style']['display']==_0x44c303(0x54d)){if(_0x44c303(0x3a9)!==_0x44c303(0x4dd))_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x1a1)]=![],_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x3df)]=!![];else{_0x4bf5f7(_0x44c303(0x525));return;}}else{if(_0x44c303(0x1e3)!==_0x44c303(0x1e3)){_0x31dfed('Answer\x20SDP\x20does\x20not\x20have\x20a\x20matching\x20session\x20ID');return;}else _0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x1a1)]=![],_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6]['videoElement'][_0x44c303(0x3df)]=![];}}else _0x5d72b5=_0x3a9ab3['lowiosviewers'];}}_0x4bb952[_0x44c303(0x3a1)](_0x3dafd6);}else{if(_0x5bf1c8[_0x44c303(0x17f)]==_0x44c303(0x232)){if(_0x4bb952['view'])return;;if(_0x4bb952[_0x44c303(0x24c)]===_0x5bf1c8[_0x44c303(0x24c)]){if(_0x4bb952[_0x44c303(0x420)]==0x2){if(_0x5bf1c8[_0x44c303(0x554)]==0x0)_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)]&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x3df)]=!![],_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6]['videoElement']['style'][_0x44c303(0x232)]&&_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]!==_0x44c303(0x54d)&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]=_0x44c303(0x54d),_0x4f4354=!![]));else{for(var _0x5b31b1 in _0x4bb952['rpcs']){_0x5b31b1!==_0x3dafd6&&(_0x4bb952[_0x44c303(0x2c9)][_0x5b31b1][_0x44c303(0x487)]&&(_0x4bb952[_0x44c303(0x2c9)][_0x5b31b1][_0x44c303(0x487)][_0x44c303(0x3df)]=!![],_0x4bb952[_0x44c303(0x2c9)][_0x5b31b1][_0x44c303(0x487)][_0x44c303(0x1a2)]['display']&&_0x4bb952['rpcs'][_0x5b31b1][_0x44c303(0x487)]['style'][_0x44c303(0x232)]!==_0x44c303(0x54d)&&(_0x4bb952[_0x44c303(0x2c9)][_0x5b31b1][_0x44c303(0x487)]['style'][_0x44c303(0x232)]=_0x44c303(0x54d),_0x4f4354=!![])));}if(_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)]){_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]&&_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)]['display']!==_0x44c303(0x3e8)&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]='block',_0x4f4354=!![]);if(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x1a1)]===null){if(_0x44c303(0x56b)==='RTNwF'){_0xdfdc38(_0x44c303(0x276));return;}else _0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x3df)]=![];}else _0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x3df)]=_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x1a1)];_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x308)]&&clearInterval(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6]['videoElement'][_0x44c303(0x308)]),_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x4e7)]=![],_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]['controlTimer']=setTimeout(showControlBar[_0x44c303(0x2d3)](null,_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]),0xbb8);}}}else{if(_0x4bb952[_0x44c303(0x420)]==0x1){if(_0x5bf1c8[_0x44c303(0x554)]==0x0)_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]&&(_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)]['display']&&_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]!==_0x44c303(0x54d)&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6]['videoElement']['style'][_0x44c303(0x232)]=_0x44c303(0x54d),_0x4f4354=!![]));else{for(var _0x5b31b1 in _0x4bb952[_0x44c303(0x2c9)]){_0x5b31b1!==_0x3dafd6&&(_0x4bb952[_0x44c303(0x2c9)][_0x5b31b1][_0x44c303(0x487)][_0x44c303(0x1a2)]['display']&&_0x4bb952[_0x44c303(0x2c9)][_0x5b31b1][_0x44c303(0x487)][_0x44c303(0x1a2)]['display']!==_0x44c303(0x54d)&&(_0x4bb952[_0x44c303(0x2c9)][_0x5b31b1][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]=_0x44c303(0x54d),_0x4f4354=!![]));}_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]&&_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]!==_0x44c303(0x3e8)&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]=_0x44c303(0x3e8),_0x4f4354=!![]),_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x308)]&&clearInterval(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x308)]),_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x4e7)]=![],_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x308)]=setTimeout(showControlBar['bind'](null,_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]),0xbb8));}}else _0x5bf1c8[_0x44c303(0x554)]==0x0?_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6]['videoElement'][_0x44c303(0x1a2)][_0x44c303(0x232)]&&_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]!==_0x44c303(0x54d)&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]='none',_0x4f4354=!![]),_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x3df)]=!![]):_0x44c303(0x5ae)!==_0x44c303(0x5ae)?(_0x3afb27[0x0]['value']=_0x9dd2c7,_0x9b82b8[_0x44c303(0x2c9)][_0x18ec0f]['directorVolumeState']=_0x5c18a7,_0x137413(_0x45a1a3[0x0])):_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]&&(_0x44c303(0x588)!==_0x44c303(0x588)?_0x34f93f['pcs'][_0x15f391[_0x44c303(0x4ec)]][_0x44c303(0x50b)]=_0x3016b1:(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]&&_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]!==_0x44c303(0x3e8)&&(_0x44c303(0x2c7)!==_0x44c303(0x2c7)?_0x5d53df(_0x3d3c9f):(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x1a2)][_0x44c303(0x232)]='block',_0x4f4354=!![])),_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6]['mutedState']===null?_0x4bb952['rpcs'][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x3df)]=![]:_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]['muted']=_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x1a1)],_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x308)]&&clearInterval(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x308)]),_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)][_0x44c303(0x4e7)]=![],_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6]['videoElement'][_0x44c303(0x308)]=setTimeout(showControlBar['bind'](null,_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]),0xbb8)));}}_0x4bb952[_0x44c303(0x3a1)](_0x3dafd6);}else _0x5bf1c8[_0x44c303(0x17f)]==_0x44c303(0x1f4)&&(log(parseInt(_0x5bf1c8['value'])/0x64),_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]&&(_0x4bb952[_0x44c303(0x2c9)][_0x3dafd6][_0x44c303(0x487)]['volume']=parseInt(_0x5bf1c8['value'])/0x64,log(_0x44c303(0x4c3))));}}}}_0x4f4354&&(_0x44c303(0x2a8)!=='wRTIW'?updateMixer():(_0x127c0d[_0x44c303(0x347)][_0x1f3491][_0x44c303(0x40e)](_0x3ed414,_0x571c2d),_0x112a40(function(_0x18b64e){_0x2cd1d6['optimizeBitrate'](_0x18b64e);},_0x128e64[_0x44c303(0x51a)],_0x243742)));}}else{if(_0x5bf1c8[_0x44c303(0x17f)]==_0x44c303(0x3ca)){}else{if(_0x5bf1c8[_0x44c303(0x17f)]==_0x44c303(0x3c9)){}}}}}},_0x4bb952['ws'][_0x4f251f(0x171)]=function(_0x543e86){var _0x17562c=_0x4f251f;clearTimeout(_0x4bb952[_0x17562c(0x20b)]);var _0x10d67a=JSON[_0x17562c(0x2b5)](_0x543e86[_0x17562c(0x367)]);'streamID'in _0x10d67a&&(_0x10d67a['streamID']=_0x4bb952[_0x17562c(0x18d)](_0x10d67a['streamID']));if(_0x4bb952[_0x17562c(0x42f)]){if('UUID'in _0x10d67a){if(_0x4bb952[_0x17562c(0x4ec)]){if(_0x10d67a[_0x17562c(0x4ec)]!==_0x4bb952[_0x17562c(0x4ec)])return;}else return;delete _0x10d67a[_0x17562c(0x4ec)];}if(_0x17562c(0x1e0)in _0x10d67a){if(!_0x4bb952[_0x17562c(0x575)])return;if(_0x17562c(0x16a)in _0x10d67a){if(_0x10d67a[_0x17562c(0x16a)]===_0x17562c(0x3ca)){if(_0x17562c(0x1e0)in _0x10d67a){if(_0x17562c(0x58d)in _0x10d67a){if(_0x10d67a[_0x17562c(0x58d)]==_0x4bb952[_0x17562c(0x4ec)]){_0x10d67a[_0x17562c(0x16a)]=_0x17562c(0x2b3),_0x4bb952[_0x17562c(0x575)]=_0x10d67a[_0x17562c(0x1e0)];var _0x4ddf74={};_0x4ddf74[_0x17562c(0x16a)]=_0x17562c(0x282),_0x4ddf74[_0x17562c(0x1e0)]=_0x4bb952['roomenc'],_0x4ddf74[_0x17562c(0x4e8)]=_0x4bb952[_0x17562c(0x4e8)],_0x4bb952[_0x17562c(0x3c0)](_0x4ddf74);}else return;}else return;}else{if(_0x17562c(0x359)!==_0x17562c(0x359))_0x3a64fc('container_'+_0x2c3ac6)['parentNode'][_0x17562c(0x36e)](_0x2dd1cc('container_'+_0xbaa633));else return;}}else{if(_0x10d67a[_0x17562c(0x1e0)]!==_0x4bb952['roomenc'])return;}}else{if(_0x10d67a[_0x17562c(0x1e0)]!==_0x4bb952[_0x17562c(0x575)])return;}delete _0x10d67a['roomid'];}_0x17562c(0x18f)in _0x10d67a&&(_0x10d67a[_0x17562c(0x534)]&&(_0x4bb952[_0x17562c(0x266)]=_0x10d67a[_0x17562c(0x534)]),delete _0x10d67a[_0x17562c(0x18f)]);'from'in _0x10d67a&&(_0x10d67a[_0x17562c(0x4ec)]=_0x10d67a[_0x17562c(0x534)],delete _0x10d67a[_0x17562c(0x534)]);if(_0x17562c(0x16a)in _0x10d67a){if(_0x10d67a[_0x17562c(0x16a)]===_0x17562c(0x31f)){if(_0x17562c(0x4e8)in _0x10d67a){if(_0x10d67a[_0x17562c(0x4e8)]===_0x4bb952[_0x17562c(0x4e8)])_0x17562c(0x3a8)!==_0x17562c(0x578)?_0x10d67a[_0x17562c(0x16a)]='offerSDP':_0x199dcf['guest']==!![]&&(_0x43ffb4[_0x17562c(0x347)][_0x4ea43f][_0x17562c(0x535)]=!![]);else return;}}else{if(_0x10d67a[_0x17562c(0x16a)]===_0x17562c(0x270)){if(_0x4bb952[_0x17562c(0x176)]){if(_0x4bb952['view_set'][_0x17562c(0x5cf)](_0x10d67a[_0x17562c(0x4e8)])){play(_0x10d67a[_0x17562c(0x4e8)]);return;}else return;}else{if(_0x4bb952[_0x17562c(0x3bc)]){if(_0x4bb952['view']!==_0x10d67a['streamID'])return;else{play(_0x10d67a['streamID']);return;}}}}else{if(_0x10d67a[_0x17562c(0x16a)]===_0x17562c(0x282)){if(_0x17562c(0x4e8)in _0x10d67a){if(_0x4bb952[_0x17562c(0x176)]){if(_0x4bb952[_0x17562c(0x176)][_0x17562c(0x5cf)](_0x10d67a[_0x17562c(0x4e8)]))play(_0x10d67a['streamID']);else{}}else{if(_0x4bb952[_0x17562c(0x3bc)]){if(_0x4bb952[_0x17562c(0x3bc)]!==_0x10d67a[_0x17562c(0x4e8)]){}else play(_0x10d67a[_0x17562c(0x4e8)]);}else play(_0x10d67a['streamID']);}}_0x10d67a[_0x17562c(0x16a)]='offerSDP';}}}}}if(_0x10d67a[_0x17562c(0x16a)]){if(_0x10d67a[_0x17562c(0x16a)]==_0x17562c(0x444)){if(_0x4bb952[_0x17562c(0x45a)]){if(_0x4bb952[_0x17562c(0x266)]===_0x10d67a[_0x17562c(0x4ec)])_0x4bb952[_0x17562c(0x444)](_0x10d67a['UUID']);else _0x4bb952[_0x17562c(0x18f)]&&(_0x10d67a[_0x17562c(0x4ec)]in _0x4bb952[_0x17562c(0x2c9)]&&_0x4bb952[_0x17562c(0x444)](_0x10d67a['UUID']));}else _0x4bb952['offerSDP'](_0x10d67a[_0x17562c(0x4ec)]);}else{if(_0x10d67a['request']==_0x17562c(0x34e))log(_0x10d67a['list']),_0x17562c(0x18f)in _0x10d67a?(_0x4bb952['directorUUID']=_0x10d67a[_0x17562c(0x18f)],_0x4bb952[_0x17562c(0x266)]in _0x4bb952['pcs']&&(_0x4bb952[_0x17562c(0x347)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)]&&(_0x4bb952[_0x17562c(0x347)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)][_0x17562c(0x18f)]=!![])),_0x4bb952['directorUUID']in _0x4bb952[_0x17562c(0x2c9)]&&(_0x4bb952['rpcs'][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)]&&(_0x17562c(0x1a4)===_0x17562c(0x18c)?(_0x31ac0a(_0x17562c(0x4dc)),_0x269527(_0x29b1e7['streamSrc']['getTracks']()),_0x5872e1=_0x162f95[_0x17562c(0x45f)]):_0x4bb952[_0x17562c(0x2c9)][_0x4bb952['directorUUID']][_0x17562c(0x5c3)][_0x17562c(0x20f)][_0x17562c(0x18f)]=!![]))):_0x4bb952[_0x17562c(0x266)]=![],_0x17562c(0x4e4)in _0x10d67a&&(_0x10d67a[_0x17562c(0x4e4)]==![]&&(!_0x4bb952[_0x17562c(0x52d)]&&(setTimeout(function(){var _0xb4414=_0x17562c;warnUser(_0xb4414(0x59d));},0x1),getById('head4')[_0x17562c(0x172)]=_0x17562c(0x2d7)))),_0x4bb952[_0x17562c(0x4d3)][_0x17562c(0x5b6)](_0x10d67a[_0x17562c(0x1d6)]);else{if(_0x10d67a[_0x17562c(0x16a)]==_0x17562c(0x2b3)){_0x4bb952[_0x17562c(0x448)]=[],_0x4bb952[_0x17562c(0x2b3)]=!![],_0x4bb952[_0x17562c(0x3dc)]=![],log(_0x17562c(0x4a7));!_0x4bb952[_0x17562c(0x18f)]&&(_0x4bb952[_0x17562c(0x45a)]=![]);log(_0x10d67a[_0x17562c(0x1d6)]);_0x17562c(0x18f)in _0x10d67a?(_0x4bb952[_0x17562c(0x266)]=_0x10d67a[_0x17562c(0x18f)],_0x4bb952[_0x17562c(0x266)]in _0x4bb952['pcs']&&(_0x4bb952['pcs'][_0x4bb952[_0x17562c(0x266)]]['stats'][_0x17562c(0x20f)]&&(_0x17562c(0x568)!=='RWkYC'?_0x4bb952[_0x17562c(0x347)][_0x4bb952['directorUUID']][_0x17562c(0x5c3)][_0x17562c(0x20f)][_0x17562c(0x18f)]=!![]:_0x4330e4(_0x2fbd4c))),_0x4bb952['directorUUID']in _0x4bb952[_0x17562c(0x2c9)]&&(_0x4bb952[_0x17562c(0x2c9)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)]&&(_0x4bb952['rpcs'][_0x4bb952['directorUUID']][_0x17562c(0x5c3)]['info'][_0x17562c(0x18f)]=!![]))):_0x4bb952[_0x17562c(0x266)]=![];for(_0x3b987c in _0x4bb952[_0x17562c(0x2c9)]){try{_0x4bb952[_0x17562c(0x2c9)][_0x3b987c][_0x17562c(0x5cd)](),delete _0x4bb952['rpcs'][_0x3b987c];}catch(_0x160d26){}}for(_0x3b987c in _0x4bb952[_0x17562c(0x347)]){try{_0x4bb952[_0x17562c(0x347)][_0x3b987c][_0x17562c(0x5cd)](),delete _0x4bb952[_0x17562c(0x347)][_0x3b987c],applySceneState();}catch(_0x416131){}}getChatMessage(_0x17562c(0x239),label=![],director=![],overlay=!![]),getById('head2')[_0x17562c(0x172)]=_0x17562c(0x4d7);_0x4bb952[_0x17562c(0x3c6)]?document['title']=_0x4bb952[_0x17562c(0x3c6)]+'\x20-\x20Transferred':document[_0x17562c(0x3f2)]='Transferred';_0x4bb952[_0x17562c(0x4d5)]=_0x4bb952[_0x17562c(0x585)],updateMixer(),updateUserList(),log(_0x17562c(0x4e5)),log(_0x10d67a[_0x17562c(0x1d6)]);for(var _0x3b987c in _0x10d67a[_0x17562c(0x1d6)]){if(_0x17562c(0x4ec)in _0x10d67a[_0x17562c(0x1d6)][_0x3b987c]){if(_0x17562c(0x4e9)===_0x17562c(0x4e9)){if(_0x17562c(0x4e8)in _0x10d67a[_0x17562c(0x1d6)][_0x3b987c]){if(_0x17562c(0x3ee)!==_0x17562c(0x455)){if(_0x10d67a[_0x17562c(0x1d6)][_0x3b987c][_0x17562c(0x4ec)]in _0x4bb952[_0x17562c(0x2c9)])log(_0x17562c(0x485));else{var _0x477473=_0x4bb952['desaltStreamID'](_0x10d67a[_0x17562c(0x1d6)][_0x3b987c][_0x17562c(0x4e8)]);log(_0x17562c(0x18b)+_0x477473);if(_0x4bb952[_0x17562c(0x45a)]){if(_0x17562c(0x3f7)===_0x17562c(0x1c3))_0x2f89f3(_0x17562c(0x26f));else{if(_0x4bb952[_0x17562c(0x266)]===_0x10d67a[_0x17562c(0x1d6)][_0x3b987c][_0x17562c(0x4ec)])play(_0x477473);else _0x4bb952['queueList'][_0x17562c(0x28f)]<0x1388&&(!_0x4bb952['queueList'][_0x17562c(0x5cf)](_0x477473)&&_0x4bb952[_0x17562c(0x448)][_0x17562c(0x3a5)](_0x477473));}}else play(_0x477473);}}else return![];}}else _0x5634fc(_0x513390);}}_0x4bb952[_0x17562c(0x196)]();}else{if(_0x10d67a['request']=='roomclaimed')log(_0x10d67a),_0x17562c(0x18f)in _0x10d67a?(_0x4bb952['directorUUID']=_0x10d67a['director'],_0x4bb952['directorUUID']in _0x4bb952[_0x17562c(0x347)]&&(_0x4bb952['pcs'][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)]&&(_0x4bb952[_0x17562c(0x347)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)]['director']=!![])),_0x4bb952[_0x17562c(0x266)]in _0x4bb952[_0x17562c(0x2c9)]&&(_0x4bb952[_0x17562c(0x2c9)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)]['info']&&(_0x4bb952['rpcs'][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)][_0x17562c(0x18f)]=!![]))):(_0x4bb952[_0x17562c(0x266)]=![],errorlog('This\x20shouldn\x27t\x20happen')),updateUserList();else{if(_0x10d67a[_0x17562c(0x16a)]==_0x17562c(0x46a)){log(_0x17562c(0x391)),log(_0x10d67a);try{_0x17562c(0x18f)in _0x10d67a&&(_0x10d67a[_0x17562c(0x18f)]==!![]&&_0x4bb952[_0x17562c(0x22f)](_0x10d67a));}catch(_0x4ece8d){errorlog(_0x4ece8d);}}else{if(_0x10d67a[_0x17562c(0x16a)]==_0x17562c(0x337)){if(_0x10d67a[_0x17562c(0x18f)]){if(_0x17562c(0x249)===_0x17562c(0x249))_0x4bb952[_0x17562c(0x266)]=_0x10d67a[_0x17562c(0x4ec)],_0x4bb952[_0x17562c(0x266)]in _0x4bb952['pcs']&&(_0x4bb952[_0x17562c(0x347)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)]&&(_0x4bb952[_0x17562c(0x347)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)][_0x17562c(0x18f)]=!![])),_0x4bb952[_0x17562c(0x266)]in _0x4bb952[_0x17562c(0x2c9)]&&(_0x4bb952[_0x17562c(0x2c9)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)]&&(_0x4bb952[_0x17562c(0x2c9)][_0x4bb952[_0x17562c(0x266)]][_0x17562c(0x5c3)][_0x17562c(0x20f)]['director']=!![])),updateUserList();else{if(_0x595c5f[_0x17562c(0x2c9)][_0x407a57][_0x17562c(0x168)]===_0x4d5bde)return;_0x21f1ed['rpcs'][_0x7781f5]['targetBandwidth']=_0x2e64c2[_0x17562c(0x2c9)][_0x1e7db4][_0x17562c(0x168)];}}if('streamID'in _0x10d67a){if('YFXjs'!==_0x17562c(0x446))_0x50151b(_0x17562c(0x330));else{log('Someone\x20Joined\x20the\x20Room\x20with\x20a\x20video');if(_0x4bb952['queue']){if(_0x4bb952[_0x17562c(0x266)]===_0x10d67a[_0x17562c(0x4ec)])play(_0x477473);else{if(_0x4bb952[_0x17562c(0x448)][_0x17562c(0x28f)]<0x1388){if(_0x17562c(0x3b7)==='ieaKN'){if(_0x388d6e[_0x17562c(0x1fa)]){if(_0x3a9135[_0x17562c(0x4d1)][_0x17562c(0x4d1)]['indexOf'](_0x365f21['icefilter'])===-0x1){_0x5b553c(_0x17562c(0x3dd));return;}else _0x42989e(_0x23f7ad[_0x17562c(0x4d1)]);}}else!_0x4bb952[_0x17562c(0x448)]['includes'](_0x10d67a[_0x17562c(0x4e8)])&&(_0x4bb952['queueList'][_0x17562c(0x3a5)](_0x10d67a['streamID']),_0x4bb952['updateQueue']());}}}else play(_0x10d67a[_0x17562c(0x4e8)]);}}else log(_0x17562c(0x496));}else{if(_0x10d67a[_0x17562c(0x16a)]=='videoaddedtoroom'){log('Someone\x20published\x20a\x20video\x20to\x20the\x20Room'),log(_0x10d67a);if(_0x4bb952[_0x17562c(0x45a)]){if(_0x4bb952[_0x17562c(0x266)]===_0x10d67a[_0x17562c(0x4ec)])play(_0x477473);else _0x4bb952[_0x17562c(0x448)][_0x17562c(0x28f)]<0x1388&&(!_0x4bb952[_0x17562c(0x448)][_0x17562c(0x5cf)](_0x10d67a['streamID'])&&(_0x4bb952[_0x17562c(0x448)][_0x17562c(0x3a5)](_0x10d67a[_0x17562c(0x4e8)]),_0x4bb952[_0x17562c(0x196)]()));}else play(_0x10d67a[_0x17562c(0x4e8)]);}else{if(_0x10d67a[_0x17562c(0x16a)]=='alert'){errorlog(_0x10d67a);if(_0x4bb952['scene']===![]){if(_0x17562c(0x3ef)in _0x10d67a){if(_0x10d67a[_0x17562c(0x3ef)]===_0x17562c(0x4af))_0x4bb952[_0x17562c(0x2ec)]<0x2?(_0x4bb952[_0x17562c(0x2ec)]=parseInt(_0x4bb952['seedAttempts'])+0x1,setTimeout(function(){var _0x22fa63=_0x17562c;_0x4bb952[_0x22fa63(0x4c9)]();},0x1388)):(hangup(),!_0x4bb952[_0x17562c(0x52d)]&&setTimeout(function(){var _0x3454c9=_0x17562c;_0x3454c9(0x5f6)!==_0x3454c9(0x396)?warnUser(_0x3454c9(0x4bd)):(_0x119bc8=_0x1d6472[_0x3454c9(0x261)](_0x5551b7),_0x22e968?_0x154535(_0x3454c9(0x17d)):(_0x33ac68(_0x3454c9(0x2c4)),_0x2c297e[_0x3454c9(0x3c0)](_0x4c3547)));},0x1));else _0x10d67a[_0x17562c(0x3ef)]===_0x17562c(0x562)?!_0x4bb952[_0x17562c(0x52d)]&&('IPAsz'===_0x17562c(0x340)?(setTimeout(function(){warnUser('The\x20room\x20is\x20already\x20claimed\x20by\x20someone\x20else.\x0a\x0aOnly\x20the\x20first\x20person\x20to\x20join\x20a\x20room\x20has\x20control\x20of\x20anything.\x0a\x0aRefresh\x20after\x20the\x20first\x20director\x20leaves\x20to\x20claim.');},0x1),getById('head4')[_0x17562c(0x172)]=_0x17562c(0x2d7)):_0x21cec6[_0x17562c(0x1e0)]=_0x37fd03['roomenc']):!_0x4bb952['cleanOutput']&&setTimeout(function(){var _0x25300d=_0x17562c;warnUser(_0x10d67a[_0x25300d(0x3ef)]);},0x1);}}}else _0x10d67a[_0x17562c(0x16a)]==_0x17562c(0x1ea)?_0x17562c(0x3ef)in _0x10d67a&&warnlog(_0x10d67a[_0x17562c(0x3ef)]):log(_0x10d67a);}}}}}}}}else{if(_0x10d67a['description']){if(_0x17562c(0x4e8)in _0x10d67a){if(_0x17562c(0x3aa)===_0x17562c(0x3d4)){_0x5dc975['connect']();if(_0x24c211[_0x17562c(0x28f)]>0x0){var _0x1fb8c1={};_0x1fb8c1[_0x17562c(0x16a)]=_0x17562c(0x31f),_0x1fb8c1[_0x17562c(0x4e8)]=_0x1d9f80,_0x3843d6[_0x17562c(0x3c0)](_0x1fb8c1),_0x3f0850[_0x17562c(0x1ad)][_0x53d113]=!![];}else _0x2a375a(_0x17562c(0x207));}else _0x10d67a['streamID']in _0x4bb952['watchTimeoutList']&&(clearTimeout(_0x4bb952[_0x17562c(0x413)][_0x10d67a[_0x17562c(0x4e8)]]),delete _0x4bb952['watchTimeoutList'][_0x10d67a[_0x17562c(0x4e8)]]);}_0x4bb952[_0x17562c(0x234)](_0x10d67a);}else{if(_0x10d67a[_0x17562c(0x4d1)])log(_0x17562c(0x5c9)),_0x4bb952[_0x17562c(0x5de)](_0x10d67a);else{if(_0x10d67a[_0x17562c(0x325)])log('GOT\x20ICES!!'),_0x4bb952[_0x17562c(0x4f5)](_0x10d67a);else _0x10d67a[_0x17562c(0x16a)]==_0x17562c(0x4cb)?(warnlog(_0x17562c(0x574)),_0x10d67a['UUID']in _0x4bb952[_0x17562c(0x347)]&&(warnlog(_0x17562c(0x459)),_0x4bb952['pcs'][_0x10d67a['UUID']][_0x17562c(0x5cd)](),delete _0x4bb952[_0x17562c(0x347)][_0x10d67a[_0x17562c(0x4ec)]],_0x4bb952['applySoloChat'](),applySceneState()),_0x10d67a[_0x17562c(0x4ec)]in _0x4bb952[_0x17562c(0x2c9)]&&(warnlog(_0x17562c(0x459)),_0x4bb952[_0x17562c(0x2c9)][_0x10d67a['UUID']][_0x17562c(0x5cd)](),delete _0x4bb952[_0x17562c(0x2c9)][_0x10d67a[_0x17562c(0x4ec)]])):_0x17562c(0x4b1)!==_0x17562c(0x4b1)?_0x4a4391=!![]:log('what\x20is\x20this?',_0x10d67a);}}}},_0x4bb952['ws']['onclose']=function(_0x29f656){var _0x1f79f4=_0x4f251f;clearTimeout(_0x4bb952[_0x1f79f4(0x20b)]),pokeIframeAPI(_0x1f79f4(0x482),_0x1f79f4(0x23c));try{_0x1f79f4(0x255)in _0x29f656&&(_0x1f79f4(0x1b3)===_0x1f79f4(0x439)?_0xd41ef8[_0x1f79f4(0x2cd)]===_0x37b80c[_0x1f79f4(0x2cd)]&&_0x453e71[_0x1f79f4(0x2cd)]&&_0x2bf0a3[_0x1f79f4(0x5f5)](_0x2b54dc(_0x51b596[_0x1f79f4(0x372)])):_0x29f656['code']==0x1f7&&(_0x4418cf==![]&&(clearInterval(_0x4bb952[_0x1f79f4(0x254)]),!_0x4bb952[_0x1f79f4(0x52d)]&&warnUser(_0x1f79f4(0x227),0x7530))));}catch(_0x16183b){errorlog(_0x16183b);}errorlog(_0x1f79f4(0x191));if(_0x4bb952[_0x1f79f4(0x5d6)]==![])try{_0x4bb952['ws']['readyState']===WebSocket['CLOSED']&&(_0x4bb952['ws']=null,setTimeout(()=>{_0x4bb952['connect'](!![]);},0x1388));}catch(_0x3a3731){_0x1f79f4(0x3a7)!==_0x1f79f4(0x3a7)?_0x143e61(_0x1f79f4(0x43f)):errorlog(_0x3a3731);}};},_0x4bb952[_0x41b841(0x2ed)]=function(_0x38215d,_0x1bccb5=null){var _0x3fe73b=_0x41b841;_0x38215d=JSON[_0x3fe73b(0x47f)](_0x38215d);if(_0x1bccb5==null){for(var _0x4fe929 in _0x4bb952[_0x3fe73b(0x347)]){try{_0x4bb952[_0x3fe73b(0x347)][_0x4fe929][_0x3fe73b(0x37d)][_0x3fe73b(0x245)](_0x38215d);}catch(_0x4751ac){warnlog(_0x3fe73b(0x42e));}}return!![];}else try{return _0x4bb952[_0x3fe73b(0x347)][_0x1bccb5][_0x3fe73b(0x37d)]['send'](_0x38215d),!![];}catch(_0x493c97){return warnlog(_0x3fe73b(0x4db)),![];}return![];},_0x4bb952[_0x41b841(0x261)]=function(_0x1ebf67,_0x4ddd86=null){var _0x556a2b=_0x41b841,_0x26f3d7=JSON[_0x556a2b(0x47f)](_0x1ebf67);if(_0x4ddd86==null)for(var _0x5785b4 in _0x4bb952[_0x556a2b(0x2c9)]){try{_0x4bb952[_0x556a2b(0x2c9)][_0x5785b4][_0x556a2b(0x4b2)][_0x556a2b(0x245)](_0x26f3d7);}catch(_0x51b627){if('mWzZu'===_0x556a2b(0x332)){_0x381bd4(_0x556a2b(0x3dd));return;}else log(_0x556a2b(0x4c5));}}else try{return _0x4bb952['rpcs'][_0x4ddd86][_0x556a2b(0x4b2)][_0x556a2b(0x245)](_0x26f3d7),!![];}catch(_0x10cfcc){if(_0x556a2b(0x2f0)==='kSIYP')return log('PUBLISHER\x27s\x20RTC\x20Connection\x20seems\x20to\x20be\x20dead?\x20'),![];else _0x56c8e4[_0x556a2b(0x16f)]['includes'](_0x4ea29b[_0x556a2b(0x2c9)][_0x552669]['streamID'])?_0x146b19[_0x556a2b(0x195)]=!![]:_0x190921['video']=![];}},_0x4bb952[_0x41b841(0x1c8)]=function(){setTimeout(function(){var _0x52749d=_0x3a98;_0x4bb952[_0x52749d(0x1c8)];},0xbb8);},_0x4bb952[_0x41b841(0x5f5)]=function(_0x3f062d){var _0x448373=_0x41b841;try{var _0x48e859=_0x4bb952[_0x448373(0x45f)][_0x448373(0x546)]();_0x48e859=_0x48e859[0x0];if(_0x48e859[_0x448373(0x509)]){var _0x443b1f=_0x48e859[_0x448373(0x509)]();_0x4bb952['zoom']==![]&&(_0x448373(0x336)===_0x448373(0x336)?_0x4bb952[_0x448373(0x372)]=_0x443b1f[_0x448373(0x372)][_0x448373(0x1c2)]:_0x4aa4e9(_0x448373(0x42e)));_0x4bb952[_0x448373(0x372)]+=_0x3f062d;if(_0x4bb952[_0x448373(0x372)]>_0x443b1f[_0x448373(0x372)][_0x448373(0x3c1)])_0x4bb952['zoom']=_0x443b1f[_0x448373(0x372)][_0x448373(0x3c1)];else _0x4bb952[_0x448373(0x372)]<_0x443b1f[_0x448373(0x372)][_0x448373(0x1c2)]&&(_0x4bb952[_0x448373(0x372)]=_0x443b1f[_0x448373(0x372)][_0x448373(0x1c2)]);_0x48e859[_0x448373(0x21c)]({'advanced':[{'zoom':_0x4bb952[_0x448373(0x372)]}]});}}catch(_0x2d6b58){errorlog(_0x2d6b58);}},_0x4bb952['hangup']=function(){var _0x443775=_0x41b841;_0x4bb952[_0x443775(0x2e1)]=!![],warnlog('hanging\x20up');try{var _0x28183f={};_0x28183f[_0x443775(0x55b)]=!![],_0x4bb952[_0x443775(0x2ed)](_0x28183f);}catch(_0xda798){}try{_0x4bb952['ws'][_0x443775(0x5cd)]();}catch(_0x181ef0){}try{recordLocalVideo(_0x443775(0x3a4));}catch(_0x71dd3d){}try{_0x4bb952[_0x443775(0x278)]&&_0x4bb952[_0x443775(0x278)]['srcObject']['getTracks']()[_0x443775(0x35e)](function(_0x258e56){var _0x1a627b=_0x443775;_0x258e56[_0x1a627b(0x3a4)](),_0x4bb952[_0x1a627b(0x487)][_0x1a627b(0x213)][_0x1a627b(0x5f4)](_0x258e56),log(_0x1a627b(0x312));});_0x4bb952[_0x443775(0x487)][_0x443775(0x213)][_0x443775(0x3bb)]()[_0x443775(0x35e)](function(_0x38f038){var _0x2d20fb=_0x443775;_0x38f038['stop'](),_0x4bb952[_0x2d20fb(0x487)][_0x2d20fb(0x213)][_0x2d20fb(0x5f4)](_0x38f038),log(_0x2d20fb(0x312));}),_0x4bb952[_0x443775(0x45f)][_0x443775(0x3bb)]()[_0x443775(0x35e)](function(_0x2cbe22){var _0x9e522a=_0x443775;_0x2cbe22[_0x9e522a(0x3a4)](),_0x4bb952[_0x9e522a(0x487)]['srcObject'][_0x9e522a(0x5f4)](_0x2cbe22),log(_0x9e522a(0x312));});for(i in _0x4bb952[_0x443775(0x2c9)]){_0x4bb952[_0x443775(0x2c9)][i][_0x443775(0x487)]&&(_0x4bb952[_0x443775(0x2c9)][i]['videoElement'][_0x443775(0x203)]&&(_0x4bb952['rpcs'][i][_0x443775(0x487)][_0x443775(0x425)][_0x443775(0x5ba)][_0x443775(0x5cd)](),_0x4bb952[_0x443775(0x2c9)][i]['videoElement']['recording']=![])),_0x4bb952[_0x443775(0x2c9)][i][_0x443775(0x5cd)](),_0x4bb952[_0x443775(0x2c9)][i]=null,delete _0x4bb952[_0x443775(0x2c9)][i];}for(i in _0x4bb952[_0x443775(0x347)]){_0x4bb952[_0x443775(0x347)][i][_0x443775(0x5cd)](),_0x4bb952[_0x443775(0x347)][i]=null,delete _0x4bb952[_0x443775(0x347)][i],applySceneState();}}catch(_0x55099d){errorlog(_0x443775(0x395));}setTimeout(function(){for(i in _0x4bb952){try{delete _0x4bb952[i];}catch(_0x93f259){}}delete _0x4bb952;},0x4b0),hangupComplete(),log('HANG\x20UP\x20COMPLETE');},_0x4bb952[_0x41b841(0x524)]=function(){var _0x5738a6=_0x41b841;_0x4bb952[_0x5738a6(0x2e1)]=!![],_0x4bb952[_0x5738a6(0x235)]=![],warnlog(_0x5738a6(0x2b7));try{_0x4bb952['videoElement'][_0x5738a6(0x213)][_0x5738a6(0x3bb)]()[_0x5738a6(0x35e)](function(_0x145e58){var _0x383e4c=_0x5738a6;_0x145e58['stop'](),_0x4bb952[_0x383e4c(0x487)][_0x383e4c(0x213)][_0x383e4c(0x5f4)](_0x145e58),log('stopping\x20old\x20track');}),_0x4bb952[_0x5738a6(0x45f)][_0x5738a6(0x3bb)]()[_0x5738a6(0x35e)](function(_0x2a6e76){var _0x2467f7=_0x5738a6;_0x2a6e76[_0x2467f7(0x3a4)](),_0x4bb952[_0x2467f7(0x45f)][_0x2467f7(0x5f4)](_0x2a6e76),log(_0x2467f7(0x312));});for(UUID in _0x4bb952[_0x5738a6(0x347)]){var _0x1c7333=_0x4bb952[_0x5738a6(0x347)][UUID][_0x5738a6(0x375)]();_0x1c7333[_0x5738a6(0x35e)](_0x1bbb6c=>{var _0xd6cb99=_0x5738a6;_0x1bbb6c[_0xd6cb99(0x5b3)]&&(_0x1bbb6c[_0xd6cb99(0x5b3)][_0xd6cb99(0x5cb)]=![]);});}var _0x523744={};_0x523744['videoMuted']=!![],_0x4bb952[_0x5738a6(0x2ed)](_0x523744);}catch(_0x1f5335){errorlog(_0x5738a6(0x395));}log(_0x5738a6(0x5c6));},_0x4bb952['remoteFocus']=function(_0x3eeb02){var _0x3e96f4=_0x41b841;try{var _0x5da51f=_0x4bb952['streamSrc']['getVideoTracks']();_0x5da51f=_0x5da51f[0x0];if(_0x5da51f['getCapabilities']){var _0x2353b5=_0x5da51f[_0x3e96f4(0x509)]();_0x4bb952['focusDistance']==![]&&(_0x4bb952[_0x3e96f4(0x37e)]=_0x2353b5[_0x3e96f4(0x37e)][_0x3e96f4(0x1c2)]);_0x4bb952[_0x3e96f4(0x37e)]+=_0x3eeb02;if(_0x4bb952[_0x3e96f4(0x37e)]>_0x2353b5[_0x3e96f4(0x37e)]['max'])_0x4bb952[_0x3e96f4(0x37e)]=_0x2353b5['focusDistance'][_0x3e96f4(0x3c1)];else _0x4bb952[_0x3e96f4(0x37e)]<_0x2353b5[_0x3e96f4(0x37e)]['min']&&(_0x4bb952[_0x3e96f4(0x37e)]=_0x2353b5[_0x3e96f4(0x37e)][_0x3e96f4(0x1c2)]);_0x5da51f[_0x3e96f4(0x21c)]({'advanced':[{'focusMode':_0x3e96f4(0x53b),'focusDistance':_0x4bb952[_0x3e96f4(0x37e)]}]});}}catch(_0x4ba447){errorlog(_0x4ba447);}},_0x4bb952[_0x41b841(0x37a)]=function(_0x2136e9){var _0x2b4602=_0x41b841;_0x4bb952[_0x2b4602(0x347)][_0x2136e9][_0x2b4602(0x37a)]()[_0x2b4602(0x3f8)](_0x3d2f11=>{var _0x397cb3=_0x2b4602;log(_0x397cb3(0x4f4));if(safariVersion()<=0xd&&(iOS||iPad)){}else{if(_0x4bb952[_0x397cb3(0x2b1)]==0x3||_0x4bb952[_0x397cb3(0x2b1)]==0x5||_0x4bb952[_0x397cb3(0x2b1)]==0x1)_0x3d2f11[_0x397cb3(0x58b)]=CodecsHandler[_0x397cb3(0x2e7)](_0x3d2f11[_0x397cb3(0x58b)],{'stereo':0x1}),log(_0x397cb3(0x2a6));else{if(iOS||iPad){}else _0x4bb952[_0x397cb3(0x2b1)]==0x4&&(_0x3d2f11[_0x397cb3(0x58b)]=CodecsHandler[_0x397cb3(0x2e7)](_0x3d2f11['sdp'],{'stereo':0x2}),log('stereo\x20enabled'));}}_0x4bb952[_0x397cb3(0x347)][_0x2136e9][_0x397cb3(0x3e6)](_0x3d2f11)[_0x397cb3(0x3f8)](function(){var _0xdc0cee=_0x397cb3;log(_0xdc0cee(0x43e)+_0x2136e9);var _0x3342f6={};_0x3342f6['UUID']=_0x2136e9,_0x3342f6[_0xdc0cee(0x4e8)]=_0x4bb952[_0xdc0cee(0x4e8)],_0x3342f6[_0xdc0cee(0x1e4)]=_0x4bb952['pcs'][_0x2136e9][_0xdc0cee(0x4a2)],_0x3342f6[_0xdc0cee(0x2d6)]=_0x4bb952['pcs'][_0x2136e9][_0xdc0cee(0x2d6)];if(_0x4bb952[_0xdc0cee(0x208)]){if(_0xdc0cee(0x41c)!==_0xdc0cee(0x3f9))_0x4bb952[_0xdc0cee(0x32b)](JSON[_0xdc0cee(0x47f)](_0x3342f6['description']))[_0xdc0cee(0x3f8)](function(_0x51676a){var _0x37d599=_0xdc0cee;_0x3342f6[_0x37d599(0x1e4)]=_0x51676a[0x0],_0x3342f6[_0x37d599(0x192)]=_0x51676a[0x1],_0x4bb952[_0x37d599(0x383)](_0x3342f6);});else{var _0x19497d={};_0x19497d[_0xdc0cee(0x229)]=_0xdc0cee(0x27e),_0x3e4a54['sendMessage'](_0x19497d,_0x33788d);}}else _0x4bb952[_0xdc0cee(0x383)](_0x3342f6);})[_0x397cb3(0x5fa)](errorlog);})['catch'](errorlog);},_0x4bb952[_0x41b841(0x416)]=function(){var _0x50575b=_0x41b841;for(var _0x2cbe40 in _0x4bb952['pcs']){_0x4bb952[_0x50575b(0x347)][_0x2cbe40][_0x50575b(0x24c)]!==![]?(_0x4bb952['forcePLI'](_0x2cbe40),log(_0x50575b(0x437))):log('Not\x20a\x20scene');}},_0x4bb952[_0x41b841(0x444)]=function(_0x22ef7b){var _0x1f52e5=_0x41b841;if(_0x1f52e5(0x547)==='XHjzL'){if(_0x22ef7b in _0x4bb952[_0x1f52e5(0x347)]){errorlog('PROBLEM!\x20RESENDING\x20SDP\x20OFFER\x20SHOULD\x20NOT\x20HAPPEN');try{_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x5cd)]();}catch(_0x2a886f){errorlog(_0x1f52e5(0x2e8));}_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]=null,delete _0x4bb952['pcs'][_0x22ef7b],_0x4bb952[_0x1f52e5(0x436)](),applySceneState();}else log(_0x1f52e5(0x333));if(_0x4bb952[_0x1f52e5(0x1b9)]!==![]){if(Object[_0x1f52e5(0x589)](_0x4bb952['pcs'])['length']>_0x4bb952[_0x1f52e5(0x1b9)]){delete _0x4bb952['pcs'][_0x22ef7b],_0x4bb952['applySoloChat'](),warnlog(_0x1f52e5(0x3b9)),applySceneState();return;}}else{if(_0x4bb952[_0x1f52e5(0x3db)]!==![]){if(_0x1f52e5(0x1c1)!==_0x1f52e5(0x36a)){if(Object[_0x1f52e5(0x589)](_0x4bb952[_0x1f52e5(0x2c9)])['length']+Object['keys'](_0x4bb952[_0x1f52e5(0x347)])[_0x1f52e5(0x28f)]>_0x4bb952[_0x1f52e5(0x3db)]){delete _0x4bb952['pcs'][_0x22ef7b],_0x4bb952['applySoloChat'](),warnlog(_0x1f52e5(0x3b3)),applySceneState();return;}}else _0xf06a6b=_0x19b9df[_0x1f52e5(0x347)][_0xbfc77d][_0x1f52e5(0x513)];}}_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]=new RTCPeerConnection(_0x4bb952[_0x1f52e5(0x397)]);if(_0x4bb952[_0x1f52e5(0x5d6)]){if(Object[_0x1f52e5(0x589)](_0x4bb952['pcs'])['length']>0x1){delete _0x4bb952[_0x1f52e5(0x347)][_0x22ef7b],_0x4bb952['applySoloChat'](),applySceneState();return;}}_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x40a)]=null,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x2f3)]=null,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x1cd)]=null,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x1b7)]=null,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x283)]=null,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x365)]=null,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x517)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x50e)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x457)]=null,_0x4bb952['pcs'][_0x22ef7b][_0x1f52e5(0x50b)]=![],_0x4bb952['pcs'][_0x22ef7b][_0x1f52e5(0x2d6)]=_0x4bb952[_0x1f52e5(0x357)](),_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x5c3)]={},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x535)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x42b)]=![],_0x4bb952['pcs'][_0x22ef7b][_0x1f52e5(0x5f9)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x30e)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x481)]=!![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x37b)]=!![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x251)]=!![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]['allowMIDI']=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x430)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x4ec)]=_0x22ef7b,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x2ee)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]['scaleDueToBitrate']=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]['scaleWidth']=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x4fe)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x513)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x24c)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x37d)]=_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x24b)](_0x1f52e5(0x37d)),_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x37d)][_0x1f52e5(0x4ec)]=_0x22ef7b,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]['keyframerate']=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]['keyframeTimeout']=null,_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x3c6)]=![],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x540)]=![],_0x4bb952['pcs'][_0x22ef7b][_0x1f52e5(0x53a)]=Date[_0x1f52e5(0x2c5)](),_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x37d)][_0x1f52e5(0x256)]=()=>{var _0x5ab430=_0x1f52e5;log(_0x5ab430(0x1b2)),msg={},msg[_0x5ab430(0x20f)]={},msg[_0x5ab430(0x20f)][_0x5ab430(0x3c6)]=_0x4bb952[_0x5ab430(0x3c6)],msg['info'][_0x5ab430(0x540)]=_0x4bb952[_0x5ab430(0x540)],msg[_0x5ab430(0x20f)]['muted']=_0x4bb952[_0x5ab430(0x3df)];_0x4bb952['soloChatUUID']&&_0x4bb952[_0x5ab430(0x29a)]!==_0x22ef7b&&(msg[_0x5ab430(0x20f)][_0x5ab430(0x3df)]=!![]);msg[_0x5ab430(0x20f)]['directorSpeakerMuted']=_0x4bb952['directorSpeakerMuted'],msg[_0x5ab430(0x20f)][_0x5ab430(0x25d)]=_0x4bb952[_0x5ab430(0x25d)],msg[_0x5ab430(0x20f)]['directorVideoMuted']=_0x4bb952[_0x5ab430(0x377)],msg[_0x5ab430(0x20f)][_0x5ab430(0x24f)]=_0x4bb952[_0x5ab430(0x55b)];_0x4bb952[_0x5ab430(0x18f)]&&(msg['directorSettings']={},msg[_0x5ab430(0x433)][_0x5ab430(0x4d5)]=_0x4bb952[_0x5ab430(0x4d5)]);msg[_0x5ab430(0x20f)]['width_url']=_0x4bb952[_0x5ab430(0x55d)],msg[_0x5ab430(0x20f)][_0x5ab430(0x321)]=_0x4bb952[_0x5ab430(0x3ec)],msg[_0x5ab430(0x20f)]['quality_url']=_0x4bb952[_0x5ab430(0x56c)],msg[_0x5ab430(0x20f)][_0x5ab430(0x22d)]=_0x4bb952['maxvideobitrate'],msg[_0x5ab430(0x20f)]['maxviewers_url']=_0x4bb952[_0x5ab430(0x1b9)],msg[_0x5ab430(0x20f)][_0x5ab430(0x299)]=_0x4bb952[_0x5ab430(0x2b1)],msg[_0x5ab430(0x20f)][_0x5ab430(0x1d4)]=_0x4bb952[_0x5ab430(0x34c)],msg[_0x5ab430(0x20f)][_0x5ab430(0x1d0)]=_0x4bb952[_0x5ab430(0x2d4)],msg[_0x5ab430(0x20f)][_0x5ab430(0x41a)]=_0x4bb952[_0x5ab430(0x449)],msg['info'][_0x5ab430(0x3c4)]=_0x4bb952['version'],msg[_0x5ab430(0x20f)][_0x5ab430(0x515)]=_0x4bb952['audioGain'],msg[_0x5ab430(0x20f)][_0x5ab430(0x59c)]=_0x4bb952[_0x5ab430(0x3f1)],msg[_0x5ab430(0x20f)][_0x5ab430(0x35f)]=_0x4bb952[_0x5ab430(0x599)],msg[_0x5ab430(0x20f)][_0x5ab430(0x429)]=!_0x4bb952[_0x5ab430(0x51c)],msg[_0x5ab430(0x20f)][_0x5ab430(0x3b8)]=_0x4bb952[_0x5ab430(0x27b)],msg[_0x5ab430(0x20f)][_0x5ab430(0x556)]=_0x4bb952[_0x5ab430(0x59b)],msg[_0x5ab430(0x20f)][_0x5ab430(0x4be)]=_0x4bb952[_0x5ab430(0x415)];try{if(navigator[_0x5ab430(0x33c)]){var _0x370414,_0x504fdd=navigator[_0x5ab430(0x33c)];msg[_0x5ab430(0x20f)]['useragent']=_0x504fdd;}navigator[_0x5ab430(0x565)]&&(msg['info'][_0x5ab430(0x565)]=navigator[_0x5ab430(0x565)]);if(safariVersion())_0x5ab430(0x3d3)===_0x5ab430(0x3d3)?msg[_0x5ab430(0x20f)][_0x5ab430(0x22c)]=_0x5ab430(0x53f):typeof _0xe30b4e['info'][_0x5ab430(0x3c6)]==_0x5ab430(0x5d7)?_0x4eb037[_0x5ab430(0x347)][_0x5875a7][_0x5ab430(0x3c6)]=_0x5a7b69(_0x1114ca['info'][_0x5ab430(0x3c6)]):_0x4caaaf[_0x5ab430(0x347)][_0x4a30bd][_0x5ab430(0x3c6)]=![];else{if(getChromeVersion()>0x3c)msg['info'][_0x5ab430(0x22c)]=_0x5ab430(0x591)+getChromeVersion();else _0x504fdd[_0x5ab430(0x4a8)](_0x5ab430(0x441))&&(msg[_0x5ab430(0x20f)][_0x5ab430(0x22c)]='Firefox');}}catch(_0x73c10){};_0x4bb952[_0x5ab430(0x2ed)](msg,_0x22ef7b),pokeIframeAPI(_0x5ab430(0x4e6),!![],_0x22ef7b),updateUserList();},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x37d)]['onclose']=()=>{var _0x1138b8=_0x1f52e5;pokeIframeAPI(_0x1138b8(0x4e6),![],_0x22ef7b),_0x4bb952[_0x1138b8(0x1dc)](),warnlog(_0x1138b8(0x4cd));try{_0x4bb952[_0x1138b8(0x347)][_0x22ef7b][_0x1138b8(0x5cd)](),_0x4bb952[_0x1138b8(0x347)][_0x22ef7b]=null,delete _0x4bb952[_0x1138b8(0x347)][_0x22ef7b],applySceneState();}catch(_0xb7cadf){}},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]['sendChannel']['onmessage']=_0x317535=>{var _0x3b7052=_0x1f52e5;log(_0x3b7052(0x41b));var _0x26b9f9=JSON[_0x3b7052(0x2b5)](_0x317535[_0x3b7052(0x367)]);_0x26b9f9[_0x3b7052(0x4ec)]=_0x22ef7b;if(_0x26b9f9[_0x3b7052(0x1e4)]){_0x4bb952['processDescription'](_0x26b9f9);return;}else{if(_0x26b9f9[_0x3b7052(0x4d1)]){log(_0x3b7052(0x5c9)),_0x4bb952[_0x3b7052(0x5de)](_0x26b9f9);return;}else{if(_0x26b9f9[_0x3b7052(0x325)]){log(_0x3b7052(0x594)),_0x4bb952[_0x3b7052(0x4f5)](_0x26b9f9);return;}}}warnlog(_0x26b9f9);if('info'in _0x26b9f9){_0x4bb952[_0x3b7052(0x347)][_0x22ef7b]['stats'][_0x3b7052(0x20f)]=_0x26b9f9['info'];_0x3b7052(0x3c6)in _0x26b9f9[_0x3b7052(0x20f)]&&(typeof _0x26b9f9[_0x3b7052(0x20f)][_0x3b7052(0x3c6)]==_0x3b7052(0x5d7)?_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x3c6)]=sanitizeLabel(_0x26b9f9[_0x3b7052(0x20f)][_0x3b7052(0x3c6)]):_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x3c6)]=![]);if(_0x22ef7b===_0x4bb952[_0x3b7052(0x266)])try{_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x5c3)][_0x3b7052(0x20f)]['director']=!![];}catch(_0x4513f8){}}_0x3b7052(0x517)in _0x26b9f9&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x517)]=parseInt(_0x26b9f9[_0x3b7052(0x517)]));_0x3b7052(0x5e3)in _0x26b9f9&&_0x4bb952[_0x3b7052(0x51b)](_0x22ef7b,_0x26b9f9[_0x3b7052(0x5e3)]);if(_0x3b7052(0x24a)in _0x26b9f9){log(_0x26b9f9);if(_0x4bb952[_0x3b7052(0x266)]===_0x22ef7b){var _0x41f691={};for(var _0x1cd208 in _0x4bb952['pcs']){if(_0x1cd208===_0x22ef7b)continue;_0x41f691[_0x1cd208]=_0x4bb952[_0x3b7052(0x347)][_0x1cd208]['stats'];}var _0xab9030={};_0xab9030[_0x3b7052(0x494)]=_0x41f691,_0x4bb952['sendMessage'](_0xab9030,_0x22ef7b);}else{if(_0x3b7052(0x2cd)in _0x26b9f9){if(_0x26b9f9[_0x3b7052(0x2cd)]===_0x4bb952[_0x3b7052(0x2cd)]&&_0x4bb952[_0x3b7052(0x2cd)]){var _0x41f691={};for(var _0x1cd208 in _0x4bb952['pcs']){if(_0x1cd208===_0x22ef7b)continue;_0x41f691[_0x1cd208]=_0x4bb952[_0x3b7052(0x347)][_0x1cd208]['stats'];}var _0xab9030={};_0xab9030['remoteStats']=_0x41f691,_0x4bb952['sendMessage'](_0xab9030,_0x22ef7b);}}}}if(_0x3b7052(0x2ae)in _0x26b9f9)try{log(_0x26b9f9),_0x4bb952[_0x3b7052(0x374)](_0x26b9f9[_0x3b7052(0x4ec)],_0x26b9f9[_0x3b7052(0x2ae)]['w'],_0x26b9f9['requestResolution']['h']);}catch(_0x368326){errorlog(_0x368326);}_0x3b7052(0x34b)in _0x26b9f9&&(_0x26b9f9[_0x3b7052(0x24c)]?_0x4bb952[_0x3b7052(0x266)]===_0x22ef7b?_0x4bb952[_0x3b7052(0x416)]():errorlog(_0x3b7052(0x597)):_0x4bb952[_0x3b7052(0x507)](_0x22ef7b));if(_0x3b7052(0x17a)in _0x26b9f9){var _0x5a592a=![],_0x1a902a=![];_0x4bb952['directorUUID']===_0x22ef7b&&(_0x5a592a=!![],_0x3b7052(0x5ad)in _0x26b9f9&&(_0x26b9f9[_0x3b7052(0x5ad)]==!![]&&('gTVyP'==='EMspM'?_0x3471d3['watchStream'](_0x49a5f1):_0x1a902a=!![]))),log(_0x3b7052(0x3ff)+_0x5a592a),getChatMessage(_0x26b9f9[_0x3b7052(0x17a)],_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x3c6)],_0x5a592a,_0x1a902a);}if(_0x3b7052(0x540)in _0x26b9f9){_0x4bb952['pcs'][_0x22ef7b][_0x3b7052(0x540)]=parseInt(_0x26b9f9[_0x3b7052(0x540)])||0x0;_0x22ef7b in _0x4bb952[_0x3b7052(0x2c9)]&&(_0x4bb952[_0x3b7052(0x2c9)][_0x22ef7b][_0x3b7052(0x540)]=_0x4bb952[_0x3b7052(0x347)][_0x22ef7b]['order']);if(_0x4bb952[_0x3b7052(0x18f)]){var _0x29384d=document['querySelectorAll'](_0x3b7052(0x323)+_0x22ef7b+'\x22]');log(_0x29384d),_0x29384d[0x0]&&(_0x29384d[0x0][_0x3b7052(0x216)]=parseInt(_0x26b9f9[_0x3b7052(0x540)])||0x0);}updateMixer();}_0x3b7052(0x2ee)in _0x26b9f9&&_0x4bb952['setScale'](_0x22ef7b,_0x26b9f9[_0x3b7052(0x2ee)]);_0x3b7052(0x229)in _0x26b9f9&&(_0x4bb952[_0x3b7052(0x18f)]&&(!(_0x4bb952[_0x3b7052(0x52d)]||_0x4bb952[_0x3b7052(0x1bd)])&&warnUser('The\x20request\x20failed;\x20the\x20remote\x20user\x20did\x20not\x20recognize\x20you\x20as\x20the\x20director',0x1388)),errorlog(_0x3b7052(0x2e3)+_0x26b9f9[_0x3b7052(0x229)]+_0x3b7052(0x2f9)+_0x4bb952[_0x3b7052(0x18f)]));if(_0x22ef7b!==_0x4bb952['directorUUID']){if('requestAudioHack'in _0x26b9f9){if(_0x3b7052(0x569)!==_0x3b7052(0x366)){var _0xab9030={};_0xab9030[_0x3b7052(0x229)]=_0x3b7052(0x483),_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}else _0x1479c6[_0x3b7052(0x2c9)][_0x389fd5]['remoteMuteElement']=_0x44db51('muteStateTemplate')['cloneNode'](!![]),_0x5b1806[_0x3b7052(0x2c9)][_0x5608d9][_0x3b7052(0x2ef)]['id']='remoteMuteState_'+_0x54bd9f,_0x28fb78[_0x3b7052(0x2c9)][_0x968ebc][_0x3b7052(0x5a1)]?_0x209300[_0x3b7052(0x2c9)][_0x4a4159][_0x3b7052(0x2ef)]['style'][_0x3b7052(0x232)]=_0x3b7052(0x3e8):_0x57afc0[_0x3b7052(0x2c9)][_0x554eee][_0x3b7052(0x2ef)][_0x3b7052(0x1a2)][_0x3b7052(0x232)]=_0x3b7052(0x54d),_0x1aaf5b=!![];}else{if(_0x3b7052(0x362)in _0x26b9f9){var _0xab9030={};_0xab9030[_0x3b7052(0x229)]=_0x3b7052(0x362),_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}else{if(_0x3b7052(0x1ce)in _0x26b9f9){var _0xab9030={};_0xab9030['rejected']=_0x3b7052(0x1ce),_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}else{if(_0x3b7052(0x27e)in _0x26b9f9){var _0xab9030={};_0xab9030[_0x3b7052(0x229)]=_0x3b7052(0x27e),_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}else{if(_0x3b7052(0x48f)in _0x26b9f9){if(_0x3b7052(0x480)===_0x3b7052(0x480)){var _0xab9030={};_0xab9030['rejected']='changeLabel',_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}else return;}else{if('requestChangeEQ'in _0x26b9f9){var _0xab9030={};_0xab9030[_0x3b7052(0x229)]='requestChangeEQ',_0x4bb952['sendMessage'](_0xab9030,_0x22ef7b);}else{if(_0x3b7052(0x3af)in _0x26b9f9){var _0xab9030={};_0xab9030['rejected']=_0x3b7052(0x3af),_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}else{if('hangup'in _0x26b9f9){var _0xab9030={};_0xab9030[_0x3b7052(0x229)]=_0x3b7052(0x3c9),_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}else{if(_0x3b7052(0x342)in _0x26b9f9){if(_0x3b7052(0x4fb)!=='nZVqg'){var _0xab9030={};_0xab9030[_0x3b7052(0x229)]=_0x3b7052(0x342),_0x4bb952['sendMessage'](_0xab9030,_0x22ef7b);}else _0x483eab('Notice:\x20The\x20system\x20is\x20currently\x20slow\x20to\x20respond\x20or\x20not\x20accessible.\x0a\x0aClick\x20OK\x20to\x20continue.\x0a\x0aIf\x20the\x20site\x20fails\x20to\x20work\x20though,\x20please\x20try\x20https://backup.obs.ninja\x20instead\x20or\x20contact\x20steve@seguin.email\x20for\x20help.\x0a\x0aThis\x20service\x20requires\x20the\x20use\x20of\x20Websockets\x20over\x20port\x20443.');}else{if('speakerMute'in _0x26b9f9){if(_0x3b7052(0x4d4)===_0x3b7052(0x4d4)){var _0xab9030={};_0xab9030[_0x3b7052(0x229)]=_0x3b7052(0x3e1),_0x4bb952['sendMessage'](_0xab9030,_0x22ef7b);}else _0x7b6003[_0x3b7052(0x3f2)]=_0xb35285[_0x3b7052(0x356)],_0x17c9e0();}else{if('volume'in _0x26b9f9){var _0xab9030={};_0xab9030['rejected']=_0x3b7052(0x1f4),_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}}}}}}}}}}}}else{if(_0x22ef7b===_0x4bb952[_0x3b7052(0x266)]){if(_0x3b7052(0x483)in _0x26b9f9){var _0x574b5a=_0x4bb952[_0x3b7052(0x45f)][_0x3b7052(0x2dd)]();if(_0x574b5a[_0x3b7052(0x28f)]){if('track'in _0x26b9f9){var _0x5bf82e=parseInt(_0x26b9f9[_0x3b7052(0x5b3)]);_0x5bf82e<_0x574b5a[_0x3b7052(0x28f)]&&(_0x574b5a=_0x574b5a[_0x5bf82e],applyAudioHack(_0x26b9f9[_0x3b7052(0x257)],_0x26b9f9[_0x3b7052(0x554)]));}else _0x574b5a=_0x574b5a[0x0],applyAudioHack(_0x26b9f9[_0x3b7052(0x257)],_0x26b9f9[_0x3b7052(0x554)]);}}if(_0x3b7052(0x362)in _0x26b9f9){if(_0x26b9f9[_0x3b7052(0x362)]){if(_0x4bb952['videoElement']){var _0x5b1762=0x1770;_0x26b9f9[_0x3b7052(0x554)]&&(_0x5b1762=parseInt(_0x26b9f9['value'])),recordLocalVideo('start',_0x5b1762);}}else _0x4bb952[_0x3b7052(0x487)]&&recordLocalVideo(_0x3b7052(0x3a4));}if(_0x3b7052(0x1ce)in _0x26b9f9){_0x4bb952[_0x3b7052(0x540)]==![]&&(_0x4bb952[_0x3b7052(0x540)]=0x0);_0x4bb952[_0x3b7052(0x540)]+=parseInt(_0x26b9f9[_0x3b7052(0x1ce)])||0x0;var _0xab9030={};_0xab9030={},_0xab9030[_0x3b7052(0x540)]=_0x4bb952[_0x3b7052(0x540)],_0x4bb952[_0x3b7052(0x3b2)](_0xab9030),updateMixer();}_0x3b7052(0x27e)in _0x26b9f9&&(window[_0x3b7052(0x174)](),confirmAlt(_0x3b7052(0x461)+_0x26b9f9[_0x3b7052(0x27e)]+_0x3b7052(0x5a3))[_0x3b7052(0x3f8)](_0x3abba3=>{var _0x58f615=_0x3b7052;if(_0x58f615(0x34f)===_0x58f615(0x34f)){_0x3abba3&&(hangup(),window[_0x58f615(0x44f)][_0x58f615(0x5b2)]=_0x26b9f9[_0x58f615(0x27e)]);;}else{var _0x36d5ba=_0x4ee285['keys'](_0x9dd18f[_0x58f615(0x347)])[_0x58f615(0x28f)];_0x36d5ba>0x3?_0x376cd0=_0x37db6e[_0x58f615(0x2b2)]:_0x1428cc=_0x2bbbbe[_0x58f615(0x4c1)];}}));if(_0x3b7052(0x48f)in _0x26b9f9){if(_0x3b7052(0x554)in _0x26b9f9){if(typeof _0x26b9f9[_0x3b7052(0x554)]==_0x3b7052(0x5d7)){_0x4bb952[_0x3b7052(0x3c6)]=sanitizeLabel(_0x26b9f9[_0x3b7052(0x554)]),log(_0x3b7052(0x30b)+_0x4bb952[_0x3b7052(0x3c6)]);if(_0x4bb952[_0x3b7052(0x18f)]){var _0x29384d=getById(_0x3b7052(0x2f4)+_0x22ef7b);_0x4bb952[_0x3b7052(0x3c6)]?_0x3b7052(0x1f7)===_0x3b7052(0x1f7)?_0x29384d['innerText']=_0x4bb952[_0x3b7052(0x3c6)]:(_0x4eb0d3['UUID']=_0x3a96fc,_0x3e166a(_0x3b7052(0x5c9)),_0x1419dd[_0x3b7052(0x5de)](_0x4807f0)):_0x29384d[_0x3b7052(0x216)]='Add\x20a\x20label';}else _0x4bb952[_0x3b7052(0x3b1)]&&updateMixer();!_0x4bb952[_0x3b7052(0x18f)]&&(_0x4bb952[_0x3b7052(0x3c6)]?document[_0x3b7052(0x3f2)]=_0x4bb952[_0x3b7052(0x3c6)]:document[_0x3b7052(0x3f2)]=location[_0x3b7052(0x356)]);var _0x4d07f7=encodeURIComponent(_0x4bb952[_0x3b7052(0x3c6)]);urlParams[_0x3b7052(0x573)]('l')?'RuXNp'!==_0x3b7052(0x2c6)?updateURL('l='+_0x4d07f7,!![],![]):_0x429070(_0x3b7052(0x59e)):updateURL(_0x3b7052(0x421)+_0x4d07f7,!![],![]);var _0xab9030={};_0xab9030[_0x3b7052(0x48f)]=!![],_0xab9030[_0x3b7052(0x554)]=_0x4bb952[_0x3b7052(0x3c6)],_0x4bb952[_0x3b7052(0x2ed)](_0xab9030);}else{_0x4bb952[_0x3b7052(0x3c6)]=![];var _0xab9030={};_0xab9030['changeLabel']=!![],_0xab9030[_0x3b7052(0x554)]=_0x4bb952[_0x3b7052(0x3c6)],_0x4bb952[_0x3b7052(0x2ed)](_0xab9030);if(_0x4bb952[_0x3b7052(0x18f)]){var _0x29384d=getById(_0x3b7052(0x2f4)+_0x22ef7b);_0x29384d[_0x3b7052(0x216)]=_0x3b7052(0x432);}else _0x4bb952[_0x3b7052(0x3b1)]?(document[_0x3b7052(0x3f2)]=location['hostname'],updateMixer()):document['title']=location['hostname'];}}}if(_0x3b7052(0x431)in _0x26b9f9){if(_0x26b9f9[_0x3b7052(0x257)]==_0x3b7052(0x305))changeLowEQ(parseFloat(_0x26b9f9[_0x3b7052(0x554)]),_0x26b9f9[_0x3b7052(0x5b3)]);else{if(_0x26b9f9[_0x3b7052(0x257)]==_0x3b7052(0x427))_0x3b7052(0x57b)==='AueDj'?_0x350cfa(_0x274b08):changeMidEQ(parseFloat(_0x26b9f9['value']),_0x26b9f9[_0x3b7052(0x5b3)]);else _0x26b9f9[_0x3b7052(0x257)]=='high'&&changeHighEQ(parseFloat(_0x26b9f9[_0x3b7052(0x554)]),_0x26b9f9[_0x3b7052(0x5b3)]);}}_0x3b7052(0x3af)in _0x26b9f9&&(_0x4bb952[_0x3b7052(0x363)]&&lowerhand());if(_0x3b7052(0x1bb)in _0x26b9f9){var _0xab9030={};_0xab9030[_0x3b7052(0x4ec)]=_0x22ef7b,_0xab9030[_0x3b7052(0x3fe)]=listAudioSettingsPrep(),sendMediaDevices(_0xab9030['UUID']),_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0xab9030[_0x3b7052(0x4ec)]);}if(_0x3b7052(0x2a7)in _0x26b9f9){var _0xab9030={};_0xab9030[_0x3b7052(0x4ec)]=_0x22ef7b,_0xab9030['videoOptions']=listVideoSettingsPrep(),sendMediaDevices(_0xab9030[_0x3b7052(0x4ec)]),_0x4bb952['sendMessage'](_0xab9030,_0xab9030[_0x3b7052(0x4ec)]);}_0x3b7052(0x402)in _0x26b9f9&&changeAudioOutputDeviceById(_0x26b9f9[_0x3b7052(0x402)],_0x22ef7b);'changeMicrophone'in _0x26b9f9&&changeAudioDeviceById(_0x26b9f9[_0x3b7052(0x1fc)],_0x22ef7b);'changeCamera'in _0x26b9f9&&changeVideoDeviceById(_0x26b9f9[_0x3b7052(0x4c8)],_0x22ef7b);_0x3b7052(0x5b1)in _0x26b9f9&&updateCameraConstraints(_0x26b9f9[_0x3b7052(0x257)],_0x26b9f9[_0x3b7052(0x554)]);_0x3b7052(0x28d)in _0x26b9f9&&(_0x3b7052(0x20d)!==_0x3b7052(0x4fa)?changeLowCut(parseFloat(_0x26b9f9[_0x3b7052(0x554)]),_0x26b9f9[_0x3b7052(0x5b3)]):_0x55caed('The\x20Director\x20has\x20disabled\x20your\x20vision\x20temporarily
'));_0x3b7052(0x28d)in _0x26b9f9&&(_0x3b7052(0x422)===_0x3b7052(0x326)?(_0x1aedd0[_0x3b7052(0x1e4)]=_0xba77c3[0x0],_0x3c2f9b[_0x3b7052(0x192)]=_0x3fae8e[0x1],_0x382fba[_0x3b7052(0x383)](_0x3faca2)):changeLowCut(parseFloat(_0x26b9f9['value']),_0x26b9f9['track']));_0x3b7052(0x3c9)in _0x26b9f9&&_0x4bb952[_0x3b7052(0x3c9)]();if('mute'in _0x26b9f9){}if(_0x3b7052(0x1f4)in _0x26b9f9){var _0x5e1512=parseInt(_0x26b9f9[_0x3b7052(0x1f4)])/0x64||0x0;_0x4bb952[_0x3b7052(0x409)]=parseInt(_0x26b9f9['volume'])||0x0;for(var _0x497d85 in _0x4bb952[_0x3b7052(0x4ef)]){log(_0x3b7052(0x3ce)),_0x4bb952['webAudios'][_0x497d85][_0x3b7052(0x475)][_0x3b7052(0x57c)][_0x3b7052(0x4f1)](_0x5e1512,_0x4bb952[_0x3b7052(0x4ef)][_0x497d85][_0x3b7052(0x1d3)][_0x3b7052(0x406)]);}}if(_0x3b7052(0x4c0)in _0x26b9f9){var _0x33e673=parseFloat(_0x26b9f9[_0x3b7052(0x4c0)]/0x3e8)||0x0;_0x4bb952[_0x3b7052(0x53d)]=parseInt(_0x26b9f9['delay'])||0x0;for(var _0x497d85 in _0x4bb952[_0x3b7052(0x4ef)]){if(_0x3b7052(0x4f2)===_0x3b7052(0x4f2))_0x4bb952[_0x3b7052(0x4ef)][_0x497d85][_0x3b7052(0x53d)][_0x3b7052(0x2f5)]['setValueAtTime'](_0x33e673,_0x4bb952[_0x3b7052(0x4ef)][_0x497d85][_0x3b7052(0x1d3)][_0x3b7052(0x406)]);else try{_0x1c8500[_0x3b7052(0x2c9)][_0x36c090]['close'](),delete _0x5d2975[_0x3b7052(0x2c9)][_0x19e070];}catch(_0x561cf1){}}}_0x3b7052(0x3e1)in _0x26b9f9&&(_0x26b9f9[_0x3b7052(0x3e1)]?(_0x4bb952[_0x3b7052(0x4b3)]=!![],_0x4bb952['directorSpeakerMute']()):(_0x4bb952[_0x3b7052(0x4b3)]=![],_0x4bb952['directorSpeakerMute']())),'displayMute'in _0x26b9f9&&(_0x26b9f9[_0x3b7052(0x342)]?(_0x4bb952[_0x3b7052(0x25d)]=!![],_0x4bb952[_0x3b7052(0x24d)]()):(_0x4bb952[_0x3b7052(0x25d)]=![],_0x4bb952['directorDisplayMute']())),_0x3b7052(0x291)in _0x26b9f9&&applyNewParams(_0x26b9f9[_0x3b7052(0x291)]);}}if(_0x3b7052(0x372)in _0x26b9f9){if(_0x4bb952[_0x3b7052(0x2cd)]){if(_0x3b7052(0x2cd)in _0x26b9f9)_0x26b9f9[_0x3b7052(0x2cd)]===_0x4bb952[_0x3b7052(0x2cd)]&&_0x4bb952[_0x3b7052(0x2cd)]&&_0x4bb952[_0x3b7052(0x5f5)](parseFloat(_0x26b9f9[_0x3b7052(0x372)]));else{if(_0x22ef7b===_0x4bb952[_0x3b7052(0x266)])_0x4bb952[_0x3b7052(0x5f5)](parseFloat(_0x26b9f9[_0x3b7052(0x372)]));else return;}}}if(_0x3b7052(0x174)in _0x26b9f9){if(_0x3b7052(0x2b4)===_0x3b7052(0x2b4)){if(_0x4bb952[_0x3b7052(0x2cd)]){if(_0x3b7052(0x2cd)in _0x26b9f9)_0x26b9f9[_0x3b7052(0x2cd)]===_0x4bb952[_0x3b7052(0x2cd)]&&_0x4bb952[_0x3b7052(0x2cd)]&&_0x4bb952['remoteFocus'](parseFloat(_0x26b9f9[_0x3b7052(0x174)]));else{if(_0x22ef7b===_0x4bb952[_0x3b7052(0x266)])_0x3b7052(0x2aa)!==_0x3b7052(0x33a)?_0x4bb952[_0x3b7052(0x189)](parseFloat(_0x26b9f9[_0x3b7052(0x174)])):(_0x371c3c[_0x3b7052(0x25d)]=![],_0x15f0f7[_0x3b7052(0x24d)]());else return;}}}else _0x1b214f[_0x3b7052(0x3a4)](),_0x38ef7c(_0x3b7052(0x221));}manageSceneState(_0x26b9f9,_0x22ef7b);_0x3b7052(0x476)in _0x26b9f9&&_0x4bb952[_0x3b7052(0x1a0)](_0x22ef7b,_0x26b9f9[_0x3b7052(0x476)]);if('audio'in _0x26b9f9&&_0x3b7052(0x195)in _0x26b9f9){log(_0x3b7052(0x51e));_0x26b9f9['audio']==![]&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x37b)]=![]);_0x26b9f9[_0x3b7052(0x195)]==![]&&(_0x4bb952['pcs'][_0x22ef7b][_0x3b7052(0x481)]=![]);_0x3b7052(0x1db)in _0x26b9f9&&_0x26b9f9[_0x3b7052(0x1db)]==!![]&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x430)]=!![],setTimeout(function(){makeImages();},0x3e8));_0x3b7052(0x369)in _0x26b9f9&&_0x26b9f9[_0x3b7052(0x369)]==![]&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x251)]=![]);'allowmidi'in _0x26b9f9&&_0x26b9f9[_0x3b7052(0x29c)]!==![]&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b]['allowMIDI']=_0x26b9f9[_0x3b7052(0x243)]);_0x3b7052(0x535)in _0x26b9f9&&(_0x26b9f9[_0x3b7052(0x535)]==!![]&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x535)]=!![]));if(_0x3b7052(0x30e)in _0x26b9f9){if(_0x3b7052(0x5bf)===_0x3b7052(0x2f8)){_0x46cb69('providing\x20answer');var _0x2eaa45={};_0x2eaa45[_0x3b7052(0x4ec)]=_0x4a0ca0[_0x3b7052(0x4ec)],_0x2eaa45[_0x3b7052(0x1e4)]=_0x1e77f4['rpcs'][_0x4a4dbe['UUID']][_0x3b7052(0x4a2)],_0x2eaa45['session']=_0x5344d4[_0x3b7052(0x2c9)][_0x51ad96[_0x3b7052(0x4ec)]][_0x3b7052(0x2d6)],_0x29a802[_0x3b7052(0x208)]?_0x2db2ab['encryptMessage'](_0x2b0822[_0x3b7052(0x47f)](_0x2eaa45['description']))[_0x3b7052(0x3f8)](function(_0x345240){var _0x51d07b=_0x3b7052;_0x2eaa45[_0x51d07b(0x1e4)]=_0x345240[0x0],_0x2eaa45['vector']=_0x345240[0x1],_0x12ddc2[_0x51d07b(0x490)](_0x2eaa45);}):_0x391fff['anyrequest'](_0x2eaa45);}else _0x26b9f9[_0x3b7052(0x30e)]===!![]&&(_0x4bb952['pcs'][_0x22ef7b][_0x3b7052(0x30e)]=!![]);}_0x3b7052(0x18f)in _0x26b9f9&&(_0x3b7052(0x4b9)===_0x3b7052(0x477)?(_0x2cf1e3(_0x3b7052(0x479))[_0x3b7052(0x172)]='',_0x4c9f8c(_0x3b7052(0x479))[_0x3b7052(0x1af)]['remove'](_0x3b7052(0x479))):_0x26b9f9['director']==!![]&&((iOS||iPad)&&('EoAEs'!==_0x3b7052(0x25a)?_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x30e)]==!![]&&(_0x4bb952['pcs'][_0x22ef7b][_0x3b7052(0x535)]=!![]):_0x3b7052(0x425)in _0x52e2df[_0x3b7052(0x2c9)][_0xa6753e]['videoElement']&&_0x1ee941[_0x3b7052(0x2c9)][_0x25acd3][_0x3b7052(0x487)]['recorder'][_0x3b7052(0x3a4)]())));_0x3b7052(0x352)in _0x26b9f9&&(_0x26b9f9[_0x3b7052(0x352)]==!![]&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x42b)]=!![]));_0x3b7052(0x4ac)in _0x26b9f9&&(_0x26b9f9['enhanceaudio']==!![]&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x5f9)]=!![]));_0x3b7052(0x314)in _0x26b9f9&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x314)]=_0x26b9f9[_0x3b7052(0x314)],_0x4bb952[_0x3b7052(0x347)][_0x22ef7b]['keyframerate']&&setTimeout(function(){var _0x5303a5=_0x3b7052;_0x4bb952[_0x5303a5(0x507)](_0x22ef7b);},0x1388));if(_0x3b7052(0x24c)in _0x26b9f9){if(_0x26b9f9['scene']!==![]){try{typeof _0x26b9f9['scene']===_0x3b7052(0x5d7)?_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x24c)]=_0x26b9f9[_0x3b7052(0x24c)]['replace'](/[\W]+/g,'_'):_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x24c)]=(parseInt(_0x26b9f9[_0x3b7052(0x24c)])||0x0)+'',_0x4bb952[_0x3b7052(0x347)][_0x22ef7b]['stats'][_0x3b7052(0x24c)]=_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x24c)],updateSceneList(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x24c)]);}catch(_0x1b394b){errorlog(_0x1b394b);}_0x4bb952[_0x3b7052(0x18f)]==!![]&&_0x4bb952[_0x3b7052(0x30a)]==![]&&(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x37b)]=![],_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x481)]=![],_0x4bb952['pcs'][_0x22ef7b][_0x3b7052(0x251)]=![]);}}if(_0x4bb952[_0x3b7052(0x18f)]==!![]){if(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x24c)])var _0x3de178=getDirectorSettings(_0x4bb952[_0x3b7052(0x347)][_0x22ef7b][_0x3b7052(0x24c)]);else var _0x3de178=getDirectorSettings(![]);var _0xab9030={};_0xab9030[_0x3b7052(0x433)]=_0x3de178,_0x4bb952[_0x3b7052(0x2ed)](_0xab9030,_0x22ef7b);}_0x4bb952[_0x3b7052(0x1ba)](_0x22ef7b);}},_0x4bb952['initialPublish']=function(_0x51e1d8){var _0x22f24a=_0x1f52e5;if(_0x51e1d8 in _0x4bb952[_0x22f24a(0x347)]){}else{errorlog(_0x22f24a(0x2fb));return;}if(_0x4bb952[_0x22f24a(0x347)][_0x51e1d8][_0x22f24a(0x251)]===!![]){if(_0x4bb952[_0x22f24a(0x49d)]){var _0x348793={};_0x348793[_0x22f24a(0x49d)]=_0x4bb952['iframeSrc'],_0x4bb952['sendMessage'](_0x348793,_0x51e1d8);}}log(_0x22f24a(0x17b)),log(_0x4bb952[_0x22f24a(0x45f)]);var _0x20ac45=null;if(_0x4bb952[_0x22f24a(0x487)]['srcObject'])_0x22f24a(0x36b)!==_0x22f24a(0x36b)?(_0x4715c6['rpcs'][this['UUID']]=null,delete _0x1f0c53[_0x22f24a(0x2c9)][this[_0x22f24a(0x4ec)]]):_0x20ac45=_0x4bb952[_0x22f24a(0x487)][_0x22f24a(0x213)];else{if(_0x4bb952[_0x22f24a(0x45f)]&&_0x4bb952['streamSrc'][_0x22f24a(0x3bb)]())errorlog(_0x22f24a(0x4dc)),log(_0x4bb952[_0x22f24a(0x45f)][_0x22f24a(0x3bb)]()),_0x20ac45=_0x4bb952[_0x22f24a(0x45f)];else{if(_0x22f24a(0x503)!==_0x22f24a(0x1ca)){warnlog(_0x22f24a(0x48d));return;}else _0x6c2113[_0x22f24a(0x169)]=!![];}}_0x20ac45['getTracks']()[_0x22f24a(0x35e)](_0x3d23e0=>{var _0x247ac8=_0x22f24a;_0x4bb952[_0x247ac8(0x347)][_0x51e1d8][_0x247ac8(0x37b)]==!![]&&(_0x3d23e0[_0x247ac8(0x20c)]=='audio'&&_0x4bb952[_0x247ac8(0x347)][_0x51e1d8][_0x247ac8(0x40e)](_0x3d23e0,_0x20ac45)),_0x4bb952[_0x247ac8(0x347)][_0x51e1d8][_0x247ac8(0x481)]==!![]&&(_0x247ac8(0x17c)===_0x247ac8(0x17c)?_0x3d23e0[_0x247ac8(0x20c)]=='video'&&(_0x4bb952[_0x247ac8(0x347)][_0x51e1d8][_0x247ac8(0x535)]==!![]&&_0x4bb952[_0x247ac8(0x545)]===0x0?log(_0x247ac8(0x26f)):(_0x4bb952['pcs'][_0x51e1d8][_0x247ac8(0x40e)](_0x3d23e0,_0x20ac45),setTimeout(function(_0x48f197){var _0x2517c7=_0x247ac8;_0x2517c7(0x2df)===_0x2517c7(0x2df)?_0x4bb952[_0x2517c7(0x520)](_0x48f197):_0x2f299f(_0x2517c7(0x4de));},_0x4bb952[_0x247ac8(0x51a)],_0x51e1d8))):_0x3f08d3['pcs'][_0x161aaa]['order']=_0x4a47b0(_0x7a5b8b[_0x247ac8(0x540)])||0x0);}),log('does\x20any\x20audio\x20exist?'),_0x20ac45[_0x22f24a(0x2dd)]()[_0x22f24a(0x28f)]&&(_0x4bb952[_0x22f24a(0x436)](),log('starting\x20kicker'),_0x4bb952[_0x22f24a(0x347)][_0x51e1d8]['limitAudio']===!![]&&setTimeout(_0x4bb952[_0x22f24a(0x267)],0x3e8,_0x51e1d8,0x7d00,0x0),_0x4bb952[_0x22f24a(0x347)][_0x51e1d8][_0x22f24a(0x5f9)]===!![]&&setTimeout(_0x4bb952[_0x22f24a(0x285)],0x3e8,_0x51e1d8));},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x39f)]=function(_0x510ce7){var _0x58563c=_0x1f52e5;_0x4bb952[_0x58563c(0x37a)](_0x22ef7b);},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x33b)]=_0x5a974c=>{var _0x55465c=_0x1f52e5;errorlog(_0x55465c(0x5df));},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]['iceTimer']=null,_0x4bb952['pcs'][_0x22ef7b][_0x1f52e5(0x346)]=[],_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x25f)]=function(_0x311b1f){var _0xae1d1b=_0x1f52e5;if(_0x311b1f['candidate']==null){log(_0xae1d1b(0x276));return;}try{if(_0x4bb952[_0xae1d1b(0x1fa)]){if(_0x311b1f[_0xae1d1b(0x4d1)]['candidate'][_0xae1d1b(0x4a8)](_0x4bb952[_0xae1d1b(0x1fa)])===-0x1){log(_0xae1d1b(0x3dd));return;}else log(_0x311b1f['candidate']);}}catch(_0x2106fb){errorlog(_0x2106fb);}if(_0x4bb952[_0xae1d1b(0x347)][_0x22ef7b]['iceTimer']!==null){_0x4bb952['pcs'][_0x22ef7b][_0xae1d1b(0x346)][_0xae1d1b(0x3a5)](_0x311b1f[_0xae1d1b(0x4d1)]);return;}_0x4bb952['pcs'][_0x22ef7b][_0xae1d1b(0x346)][_0xae1d1b(0x3a5)](_0x311b1f[_0xae1d1b(0x4d1)]),_0x4bb952[_0xae1d1b(0x347)][_0x22ef7b]['iceTimer']=setTimeout(function(_0x5bea4f){var _0x533e57=_0xae1d1b;_0x4bb952[_0x533e57(0x347)][_0x5bea4f]['iceTimer']=null;var _0x13df31={};_0x13df31[_0x533e57(0x4ec)]=_0x5bea4f,_0x13df31['type']=_0x533e57(0x39d),_0x13df31[_0x533e57(0x325)]=_0x4bb952['pcs'][_0x5bea4f][_0x533e57(0x346)],_0x13df31[_0x533e57(0x2d6)]=_0x4bb952[_0x533e57(0x347)][_0x5bea4f][_0x533e57(0x2d6)],_0x4bb952[_0x533e57(0x347)][_0x5bea4f][_0x533e57(0x346)]=[],_0x4bb952[_0x533e57(0x208)]?_0x4bb952[_0x533e57(0x32b)](JSON[_0x533e57(0x47f)](_0x13df31[_0x533e57(0x325)]))[_0x533e57(0x3f8)](function(_0x2a4fee){var _0x2866a1=_0x533e57;_0x13df31[_0x2866a1(0x325)]=_0x2a4fee[0x0],_0x13df31[_0x2866a1(0x192)]=_0x2a4fee[0x1],_0x4bb952['anysend'](_0x13df31);}):_0x4bb952[_0x533e57(0x383)](_0x13df31);},0xc8,_0x22ef7b);},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b]['oniceconnectionstatechange']=function(_0x35c034){var _0x3973ea=_0x1f52e5;try{if(this['iceConnectionState']=='closed')log(_0x3973ea(0x47c));else{if(this['iceConnectionState']=='disconnected')log(_0x3973ea(0x368));else{if(this[_0x3973ea(0x3a0)]==_0x3973ea(0x339))log(_0x3973ea(0x552));else this[_0x3973ea(0x3a0)]==_0x3973ea(0x4e1)?(log(_0x3973ea(0x19a)),_0x4bb952[_0x3973ea(0x347)][_0x22ef7b][_0x3973ea(0x375)]()['forEach'](_0x210704=>{var _0x50d413=_0x3973ea;if(!_0x210704[_0x50d413(0x5b3)])return;if(_0x210704[_0x50d413(0x5b3)][_0x50d413(0x20c)]===_0x50d413(0x195)){if('prNsI'!==_0x50d413(0x1d5)){_0x4e62dc[_0x50d413(0x2c9)][_0x335176][_0x50d413(0x540)]=_0x258ad3(_0x2d969a[_0x50d413(0x20f)][_0x50d413(0x540)])||0x0;if(_0x24cbb5['director']){var _0x50b633=_0x21e79a[_0x50d413(0x557)](_0x50d413(0x323)+_0x1b09dd+'\x22]');_0x50b633[0x0]&&(_0x50b633[0x0][_0x50d413(0x216)]=_0x3c0334[_0x50d413(0x2c9)][_0x28790f][_0x50d413(0x540)]);}}else{_0x4bb952[_0x50d413(0x347)][_0x22ef7b][_0x50d413(0x16b)]=_0x210704[_0x50d413(0x584)]()[_0x50d413(0x1b4)],log(_0x4bb952['pcs'][_0x22ef7b][_0x50d413(0x16b)]);return;}}else{if(_0x210704[_0x50d413(0x5b3)][_0x50d413(0x20c)]==='audio'){_0x4bb952[_0x50d413(0x347)][_0x22ef7b][_0x50d413(0x32f)]=_0x210704[_0x50d413(0x584)]()[_0x50d413(0x1b4)],log(_0x4bb952[_0x50d413(0x347)][_0x22ef7b][_0x50d413(0x32f)]);return;}}})):'AylIN'===_0x3973ea(0x214)?(_0x5703c6('Couldn\x27t\x20re-connect'),_0x2e3f04(_0x439e62)):log(this[_0x3973ea(0x3a0)]);}}}catch(_0xb2d288){errorlog(_0xb2d288);}},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x212)]=function(_0x5d6bdd){var _0x45a39d=_0x1f52e5;switch(_0x4bb952[_0x45a39d(0x347)][_0x22ef7b][_0x45a39d(0x4bf)]){case _0x45a39d(0x4e1):log(_0x45a39d(0x5b4));if(_0x4bb952[_0x45a39d(0x5d6)]){if(_0x45a39d(0x5b9)===_0x45a39d(0x26e))_0x2ee888[_0x45a39d(0x2c9)][_0x54f62c][_0x45a39d(0x5c3)][_0xe182a7['trackId']][_0x45a39d(0x499)]=0x0;else{if(_0x4bb952['ws']['readyState']!==0x1){if(_0x45a39d(0x41f)===_0x45a39d(0x41f)){_0x4bb952['ws'][_0x45a39d(0x5cd)]();break;}else _0x682d0['rpcs'][_0x7ac123]['remoteVideoMuteElement'][_0x45a39d(0x1a2)][_0x45a39d(0x232)]=_0x45a39d(0x54d);}_0x4bb952['ws'][_0x45a39d(0x5cd)](),setTimeout(function(){var _0x4774c4=_0x45a39d;_0x4bb952[_0x4774c4(0x52d)]!=!![]&&warnUser(_0x4774c4(0x4de));},0x1);}}break;case _0x45a39d(0x19f):log(_0x45a39d(0x5f3));break;case'failed':warnlog(_0x45a39d(0x241)),_0x4bb952[_0x45a39d(0x347)][_0x22ef7b][_0x45a39d(0x5cd)](),_0x4bb952['pcs'][_0x22ef7b]=null;_0x4bb952[_0x45a39d(0x5d6)]&&(_0x45a39d(0x40b)!==_0x45a39d(0x40b)?_0x4491d3[_0x45a39d(0x2c9)][_0x586fa6][_0x45a39d(0x5c3)]['RTC\x20Connection'][_0x45a39d(0x3fb)]=_0x51d899[_0x45a39d(0x320)]:!_0x4bb952[_0x45a39d(0x52d)]&&setTimeout(function(){var _0x4e42db=_0x45a39d;warnUser(_0x4e42db(0x330));},0x1));delete _0x4bb952['pcs'][_0x22ef7b],_0x4bb952[_0x45a39d(0x436)](),applySceneState();break;case _0x45a39d(0x23c):warnlog(_0x45a39d(0x1a8)),_0x4bb952[_0x45a39d(0x347)][_0x22ef7b]=null;_0x4bb952[_0x45a39d(0x5d6)]&&(!_0x4bb952['cleanOutput']&&setTimeout(function _0x35a87e(){warnUser('Remote\x20peer\x20disconnected.\x20Due\x20to\x20enhanced\x20security,\x20please\x20refresh\x20to\x20create\x20a\x20new\x20connection.');},0x1));delete _0x4bb952[_0x45a39d(0x347)][_0x22ef7b],_0x4bb952[_0x45a39d(0x436)](),applySceneState();break;}},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x1ef)]=function(_0x5d4938){var _0x9c8dd8=_0x1f52e5;warnlog('WebRTC\x20Connection\x20Closed.\x20Clean\x20up.\x20657'),_0x4bb952[_0x9c8dd8(0x347)][_0x22ef7b]=null,delete _0x4bb952[_0x9c8dd8(0x347)][_0x22ef7b],_0x4bb952['applySoloChat'](),applySceneState();},_0x4bb952[_0x1f52e5(0x347)][_0x22ef7b][_0x1f52e5(0x256)]=function _0x55259f(){var _0x19b774=_0x1f52e5;_0x19b774(0x576)!==_0x19b774(0x576)?_0x5df21f(_0x19d5a4['streamID']):log('WEBRTC\x20CONNECTION\x20OPEN');};}else _0x269e47=0x20,_0x25b0e7[_0x1f52e5(0x497)]&&(_0x262f37=_0x52f0bd[_0x1f52e5(0x497)]),_0x306e66[_0x1f52e5(0x3ea)][0x0][_0x1f52e5(0x484)]=_0x5c8ca5*0x400;},_0x4bb952[_0x41b841(0x234)]=function(_0x221080){var _0x4b3d04=_0x41b841;if(_0x4bb952[_0x4b3d04(0x208)]){if(_0x4b3d04(0x5a8)==='RCpcD')_0x4b3d04(0x192)in _0x221080&&(_0x4b3d04(0x56e)===_0x4b3d04(0x48b)?_0x103ea5[_0x4b3d04(0x2c9)][_0x1a6a96][_0x4b3d04(0x487)][_0x4b3d04(0x213)]=_0x127866[_0x4b3d04(0x2c9)][_0x3c313a][_0x4b3d04(0x45f)]:_0x4bb952[_0x4b3d04(0x541)](_0x221080[_0x4b3d04(0x1e4)],_0x221080['vector'])[_0x4b3d04(0x3f8)](function(_0x4ab0b0){var _0x2ff6ca=_0x4b3d04;_0x221080[_0x2ff6ca(0x1e4)]=JSON[_0x2ff6ca(0x2b5)](_0x4ab0b0);if(_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x2e9)]==_0x2ff6ca(0x419))_0x4bb952[_0x2ff6ca(0x28b)](_0x221080),_0x4bb952[_0x2ff6ca(0x25e)](_0x221080);else{if(_0x2ff6ca(0x1b1)!=='cPNtp')_0x284be8[_0x2ff6ca(0x3a5)](_0x2e2b05);else try{var _0x402aca=_0x4bb952[_0x2ff6ca(0x510)];if((iOS||iPad)&&_0x4bb952[_0x2ff6ca(0x347)][_0x221080['UUID']][_0x2ff6ca(0x535)]==!![]&&_0x4bb952[_0x2ff6ca(0x347)][_0x221080['UUID']]['forceios']==![]){if(_0x402aca===![]||_0x402aca>_0x4bb952[_0x2ff6ca(0x4c1)]){var _0x1a2a85=Object[_0x2ff6ca(0x589)](_0x4bb952[_0x2ff6ca(0x347)])[_0x2ff6ca(0x28f)];_0x1a2a85>0x3?_0x402aca=_0x4bb952[_0x2ff6ca(0x2b2)]:_0x402aca=_0x4bb952[_0x2ff6ca(0x4c1)];}_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x58b)]=CodecsHandler['preferCodec'](_0x221080[_0x2ff6ca(0x1e4)]['sdp'],'vp8'),_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x58b)]=CodecsHandler['setVideoBitrates'](_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x58b)],{'min':parseInt(_0x402aca/0x2)||0x1,'max':_0x402aca}),_0x402aca=![];}else _0x4bb952[_0x2ff6ca(0x347)][_0x221080[_0x2ff6ca(0x4ec)]][_0x2ff6ca(0x535)]==!![]&&(_0x402aca!==![]?_0x4bb952[_0x2ff6ca(0x545)]!==![]&&(_0x2ff6ca(0x401)!==_0x2ff6ca(0x401)?(_0x432fd4[_0x2ff6ca(0x2c9)][_0x11cf4f][_0x2ff6ca(0x273)]=_0x1abc01(_0x49f688[_0x2ff6ca(0x49d)]),_0x389327[_0x2ff6ca(0x2c9)][_0x18c546][_0x2ff6ca(0x273)]['id']='iframe_'+_0x9dd885,_0x4a2f7e[_0x2ff6ca(0x2c9)][_0x191807]['iframeEle'][_0x2ff6ca(0x53e)][_0x2ff6ca(0x4ec)]=_0x3a663c,_0x45b103=!![],_0x3ea676[_0x2ff6ca(0x2c9)][_0x25a4bd][_0x2ff6ca(0x4e8)]&&(_0xbe63a1[_0x2ff6ca(0x2c9)][_0x4c8d52][_0x2ff6ca(0x273)][_0x2ff6ca(0x53e)][_0x2ff6ca(0x399)]=_0x41f195[_0x2ff6ca(0x2c9)][_0x3c1c69][_0x2ff6ca(0x4e8)])):_0x4bb952['roombitrate']<_0x402aca&&(_0x402aca=_0x4bb952[_0x2ff6ca(0x545)])):_0x402aca=_0x4bb952['roombitrate']);if(_0x402aca){var _0xf975ce=CodecsHandler[_0x2ff6ca(0x37c)](_0x221080[_0x2ff6ca(0x1e4)]['sdp'])||0x9c4;log(_0x2ff6ca(0x1a3)+_0xf975ce);if(_0xf975ce>_0x402aca){var _0x52ff12=CodecsHandler[_0x2ff6ca(0x3c5)](_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x58b)])||0x0;_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x58b)]=CodecsHandler[_0x2ff6ca(0x209)](_0x221080[_0x2ff6ca(0x1e4)]['sdp'],{'min':parseInt(_0x402aca/0xa)||0x1,'max':parseInt(_0x402aca+_0x52ff12/0x400)}),_0x4bb952[_0x2ff6ca(0x347)][_0x221080[_0x2ff6ca(0x4ec)]][_0x2ff6ca(0x50b)]=_0x402aca;}else _0x4bb952[_0x2ff6ca(0x347)][_0x221080[_0x2ff6ca(0x4ec)]]['setBitrate']=_0xf975ce;}else{if(_0x4bb952[_0x2ff6ca(0x50f)]!==![]){if(_0x2ff6ca(0x30f)!==_0x2ff6ca(0x3c3)){var _0xf975ce=CodecsHandler[_0x2ff6ca(0x37c)](_0x221080['description']['sdp']);if(_0xf975ce===![]){if(_0x2ff6ca(0x166)===_0x2ff6ca(0x166)){var _0x52ff12=CodecsHandler[_0x2ff6ca(0x3c5)](_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x58b)])||0x0;_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x58b)]=CodecsHandler[_0x2ff6ca(0x209)](_0x221080[_0x2ff6ca(0x1e4)][_0x2ff6ca(0x58b)],{'min':parseInt(_0x4bb952[_0x2ff6ca(0x50f)]/0xa)||0x1,'max':parseInt(_0x4bb952['outboundVideoBitrate']+_0x52ff12/0x400)});}else!(_0x131655['cleanOutput']||_0x47a59d[_0x2ff6ca(0x1bd)])&&_0xccae68(_0x2ff6ca(0x1b0),0x1388);}else _0x4bb952['pcs'][_0x221080['UUID']]['setBitrate']=_0xf975ce;}else _0x1df6b9[_0x2ff6ca(0x3df)]=_0x283a23[_0x2ff6ca(0x27c)];}else _0x4bb952['pcs'][_0x221080[_0x2ff6ca(0x4ec)]][_0x2ff6ca(0x50b)]=CodecsHandler[_0x2ff6ca(0x37c)](_0x221080[_0x2ff6ca(0x1e4)]['sdp']);}_0x4bb952[_0x2ff6ca(0x29b)]&&(_0x221080[_0x2ff6ca(0x1e4)]['sdp']=CodecsHandler[_0x2ff6ca(0x2e7)](_0x221080[_0x2ff6ca(0x1e4)]['sdp'],{'maxaveragebitrate':_0x4bb952[_0x2ff6ca(0x29b)]*0x400,'cbr':_0x4bb952[_0x2ff6ca(0x316)]}));if(_0x2ff6ca(0x2d6)in _0x221080&&_0x221080[_0x2ff6ca(0x2d6)]!=_0x4bb952[_0x2ff6ca(0x347)][_0x221080[_0x2ff6ca(0x4ec)]][_0x2ff6ca(0x2d6)]){errorlog(_0x2ff6ca(0x45c));return;}_0x4bb952[_0x2ff6ca(0x347)][_0x221080[_0x2ff6ca(0x4ec)]]['setRemoteDescription'](_0x221080[_0x2ff6ca(0x1e4)])[_0x2ff6ca(0x3f8)]()[_0x2ff6ca(0x5fa)](errorlog);}catch(_0x3597bf){errorlog(_0x3597bf);}}}));else{_0x5d77d6(_0x4b3d04(0x1cc));return;}}else{if(_0x221080[_0x4b3d04(0x1e4)]['type']==_0x4b3d04(0x419))_0x4bb952[_0x4b3d04(0x28b)](_0x221080),_0x4bb952['connectPeer'](_0x221080);else try{var _0x532f02=_0x4bb952[_0x4b3d04(0x510)];if((iOS||iPad)&&_0x4bb952['pcs'][_0x221080[_0x4b3d04(0x4ec)]][_0x4b3d04(0x535)]==!![]&&_0x4bb952[_0x4b3d04(0x347)][_0x221080[_0x4b3d04(0x4ec)]][_0x4b3d04(0x30e)]==![]){if(_0x532f02===![]||_0x532f02>_0x4bb952[_0x4b3d04(0x4c1)]){var _0x1c0d0d=Object[_0x4b3d04(0x589)](_0x4bb952[_0x4b3d04(0x347)])[_0x4b3d04(0x28f)];_0x1c0d0d>0x3?_0x532f02=_0x4bb952[_0x4b3d04(0x2b2)]:_0x532f02=_0x4bb952[_0x4b3d04(0x4c1)];}_0x221080['description'][_0x4b3d04(0x58b)]=CodecsHandler['preferCodec'](_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)],'vp8'),_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)]=CodecsHandler[_0x4b3d04(0x209)](_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)],{'min':parseInt(_0x532f02/0x2)||0x1,'max':_0x532f02}),_0x532f02=![];}else _0x4bb952[_0x4b3d04(0x347)][_0x221080[_0x4b3d04(0x4ec)]][_0x4b3d04(0x535)]==!![]&&(_0x4b3d04(0x4cf)===_0x4b3d04(0x15f)?_0x15324c(_0x3f4486):_0x532f02!==![]?_0x4bb952['roombitrate']!==![]&&(_0x4bb952[_0x4b3d04(0x545)]<_0x532f02&&(_0x532f02=_0x4bb952[_0x4b3d04(0x545)])):_0x532f02=_0x4bb952[_0x4b3d04(0x545)]);if(_0x532f02){var _0x179e19=CodecsHandler[_0x4b3d04(0x37c)](_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)])||0x9c4;log('BITRATE:\x20'+_0x179e19);if(_0x179e19>_0x532f02){var _0x18eb47=CodecsHandler[_0x4b3d04(0x3c5)](_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)])||0x0;_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)]=CodecsHandler[_0x4b3d04(0x209)](_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)],{'min':parseInt(_0x532f02/0xa)||0x1,'max':parseInt(_0x532f02+_0x18eb47/0x400)});}}else{if(_0x4bb952[_0x4b3d04(0x50f)]!==![]){var _0x179e19=CodecsHandler[_0x4b3d04(0x37c)](_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)]);if(_0x179e19===![]){var _0x18eb47=CodecsHandler['getOpusBitrate'](_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)])||0x0;_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)]=CodecsHandler['setVideoBitrates'](_0x221080['description']['sdp'],{'min':parseInt(_0x4bb952['outboundVideoBitrate']/0xa)||0x1,'max':parseInt(_0x4bb952[_0x4b3d04(0x50f)]+_0x18eb47/0x400)});}}}_0x4bb952[_0x4b3d04(0x29b)]&&(_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)]=CodecsHandler[_0x4b3d04(0x2e7)](_0x221080[_0x4b3d04(0x1e4)][_0x4b3d04(0x58b)],{'maxaveragebitrate':_0x4bb952[_0x4b3d04(0x29b)]*0x400,'cbr':_0x4bb952[_0x4b3d04(0x316)]}));if(_0x4b3d04(0x2d6)in _0x221080&&_0x221080['session']!=_0x4bb952[_0x4b3d04(0x347)][_0x221080[_0x4b3d04(0x4ec)]][_0x4b3d04(0x2d6)]){errorlog(_0x4b3d04(0x45c));return;}_0x4bb952[_0x4b3d04(0x347)][_0x221080[_0x4b3d04(0x4ec)]]['setRemoteDescription'](_0x221080[_0x4b3d04(0x1e4)])[_0x4b3d04(0x3f8)]()[_0x4b3d04(0x5fa)](errorlog);}catch(_0x241ec2){errorlog(_0x241ec2);}}},_0x4bb952[_0x41b841(0x5de)]=function(_0x58f81e){var _0x3251d6=_0x41b841;_0x4bb952[_0x3251d6(0x208)]&&_0x3251d6(0x192)in _0x58f81e?_0x4bb952[_0x3251d6(0x541)](_0x58f81e['candidate'],_0x58f81e[_0x3251d6(0x192)])['then'](function(_0x35e446){var _0x1d409f=_0x3251d6;_0x58f81e['candidate']=JSON[_0x1d409f(0x2b5)](_0x35e446),_0x4bb952[_0x1d409f(0x418)](_0x58f81e);}):_0x4bb952[_0x3251d6(0x418)](_0x58f81e);},_0x4bb952[_0x41b841(0x418)]=function(_0x11fc29){var _0x1fcf7d=_0x41b841;if('BlZgB'!==_0x1fcf7d(0x44a)){try{if(_0x4bb952['icefilter']){if(_0x11fc29[_0x1fcf7d(0x4d1)][_0x1fcf7d(0x4d1)][_0x1fcf7d(0x4a8)](_0x4bb952[_0x1fcf7d(0x1fa)])===-0x1){if(_0x1fcf7d(0x387)!==_0x1fcf7d(0x387))_0x3a90af[_0x1fcf7d(0x2c9)][_0x547738][_0x1fcf7d(0x5c3)][_0x40f14e[_0x1fcf7d(0x1fb)]][_0x1fcf7d(0x386)]=_0x2c93d3(_0x2bd310(_0x5d3a0b[_0x1fcf7d(0x281)])*0x2710)/0x2710;else{log(_0x1fcf7d(0x3dd)),log(_0x11fc29[_0x1fcf7d(0x4d1)]);return;}}else log(_0x1fcf7d(0x2fd)),log(_0x11fc29[_0x1fcf7d(0x4d1)]);}}catch(_0x22e49b){errorlog(_0x22e49b);}if(_0x11fc29[_0x1fcf7d(0x4d1)]&&_0x1fcf7d(0x4d1)in _0x11fc29['candidate']&&_0x11fc29[_0x1fcf7d(0x4d1)][_0x1fcf7d(0x4d1)]=='')return;if(_0x11fc29[_0x1fcf7d(0x4ec)]in _0x4bb952[_0x1fcf7d(0x347)]&&_0x11fc29[_0x1fcf7d(0x2e9)]==_0x1fcf7d(0x2cd)){log(_0x1fcf7d(0x2c8));if(!(_0x11fc29['UUID']in _0x4bb952[_0x1fcf7d(0x347)])){errorlog('ICE\x20target\x20no\x20longer\x20exists?');return;}if(_0x1fcf7d(0x2d6)in _0x11fc29&&_0x4bb952[_0x1fcf7d(0x347)][_0x11fc29[_0x1fcf7d(0x4ec)]]['session']!=_0x11fc29['session']){errorlog(_0x1fcf7d(0x525));return;}_0x4bb952[_0x1fcf7d(0x347)][_0x11fc29[_0x1fcf7d(0x4ec)]]['addIceCandidate'](_0x11fc29['candidate'])[_0x1fcf7d(0x3f8)]()[_0x1fcf7d(0x5fa)](function(_0xaef96f){errorlog(_0xaef96f),errorlog(_0x11fc29);});}else{if(_0x11fc29[_0x1fcf7d(0x4ec)]in _0x4bb952['rpcs']&&_0x11fc29['type']==_0x1fcf7d(0x39d)){log(_0x1fcf7d(0x4d9));if(!(_0x11fc29[_0x1fcf7d(0x4ec)]in _0x4bb952[_0x1fcf7d(0x2c9)])){errorlog(_0x1fcf7d(0x1cc));return;}if(_0x1fcf7d(0x2d6)in _0x11fc29&&_0x4bb952['rpcs'][_0x11fc29[_0x1fcf7d(0x4ec)]][_0x1fcf7d(0x2d6)]!=_0x11fc29[_0x1fcf7d(0x2d6)]){errorlog(_0x1fcf7d(0x525));return;}if(_0x4bb952[_0x1fcf7d(0x2c9)][_0x11fc29[_0x1fcf7d(0x4ec)]]===null)return;_0x4bb952[_0x1fcf7d(0x2c9)][_0x11fc29[_0x1fcf7d(0x4ec)]]['addIceCandidate'](_0x11fc29[_0x1fcf7d(0x4d1)])[_0x1fcf7d(0x3f8)]()[_0x1fcf7d(0x5fa)](function(_0x3bf42f){errorlog(_0x3bf42f),errorlog(_0x11fc29);});}else errorlog(_0x11fc29),errorlog(_0x1fcf7d(0x16c));}}else _0x3b501b(_0x14daf2);},_0x4bb952['processIceBundle']=function(_0x58d9cc){var _0x122e13=_0x41b841;if(_0x4bb952[_0x122e13(0x208)]&&_0x122e13(0x192)in _0x58d9cc)_0x4bb952[_0x122e13(0x541)](_0x58d9cc['candidates'],_0x58d9cc[_0x122e13(0x192)])[_0x122e13(0x3f8)](function(_0x408482){var _0x2f893b=_0x122e13;_0x58d9cc[_0x2f893b(0x325)]=JSON[_0x2f893b(0x2b5)](_0x408482);var _0x7a21c9={};_0x7a21c9[_0x2f893b(0x4ec)]=_0x58d9cc[_0x2f893b(0x4ec)],_0x7a21c9['type']=_0x58d9cc[_0x2f893b(0x2e9)];for(var _0x7c4faa=0x0;_0x7c4faa<_0x58d9cc[_0x2f893b(0x325)][_0x2f893b(0x28f)];_0x7c4faa++){_0x7a21c9[_0x2f893b(0x4d1)]=_0x58d9cc['candidates'][_0x7c4faa],_0x4bb952[_0x2f893b(0x418)](_0x7a21c9);}});else{var _0x1ac4ca={};_0x1ac4ca['UUID']=_0x58d9cc[_0x122e13(0x4ec)],_0x1ac4ca[_0x122e13(0x2e9)]=_0x58d9cc[_0x122e13(0x2e9)];for(var _0x1259b6=0x0;_0x1259b6<_0x58d9cc[_0x122e13(0x325)][_0x122e13(0x28f)];_0x1259b6++){_0x1ac4ca['candidate']=_0x58d9cc[_0x122e13(0x325)][_0x1259b6],_0x4bb952[_0x122e13(0x418)](_0x1ac4ca);}}},_0x4bb952['connectPeer']=function(_0x39dabe){var _0x22e9ea=_0x41b841;_0x4bb952[_0x22e9ea(0x2c9)][_0x39dabe[_0x22e9ea(0x4ec)]]['setRemoteDescription'](_0x39dabe[_0x22e9ea(0x1e4)])['then'](function(){var _0x2e1dee=_0x22e9ea;if(_0x4bb952[_0x2e1dee(0x2c9)][_0x39dabe[_0x2e1dee(0x4ec)]]['remoteDescription'][_0x2e1dee(0x2e9)]===_0x2e1dee(0x419))_0x4bb952['rpcs'][_0x39dabe[_0x2e1dee(0x4ec)]][_0x2e1dee(0x4ca)]()[_0x2e1dee(0x3f8)](function(_0x445c5e){var _0x998a11=_0x2e1dee;if(!_0x4bb952[_0x998a11(0x18f)]&&_0x4bb952['stereo']==0x5)_0x445c5e[_0x998a11(0x58b)]=CodecsHandler[_0x998a11(0x2e7)](_0x445c5e['sdp'],{'stereo':0x1,'maxaveragebitrate':(_0x4bb952[_0x998a11(0x497)]||0x100)*0x400,'cbr':_0x4bb952[_0x998a11(0x316)],'useinbandfec':0x1,'maxptime':_0x4bb952[_0x998a11(0x3f6)],'minptime':_0x4bb952[_0x998a11(0x2b8)],'ptime':_0x4bb952['ptime']});else{if(_0x4bb952[_0x998a11(0x2b1)]==0x1||_0x4bb952[_0x998a11(0x2b1)]==0x2||_0x4bb952[_0x998a11(0x2b1)]==0x5)_0x445c5e['sdp']=CodecsHandler[_0x998a11(0x2e7)](_0x445c5e[_0x998a11(0x58b)],{'stereo':0x1,'maxaveragebitrate':(_0x4bb952[_0x998a11(0x497)]||0x100)*0x400,'cbr':_0x4bb952[_0x998a11(0x316)],'useinbandfec':0x1,'maxptime':_0x4bb952[_0x998a11(0x3f6)],'minptime':_0x4bb952[_0x998a11(0x2b8)],'ptime':_0x4bb952[_0x998a11(0x474)]});else{if(_0x4bb952[_0x998a11(0x2b1)]==0x4)_0x445c5e[_0x998a11(0x58b)]=CodecsHandler[_0x998a11(0x2e7)](_0x445c5e[_0x998a11(0x58b)],{'stereo':0x2,'maxaveragebitrate':(_0x4bb952['audiobitrate']||0x100)*0x400,'cbr':_0x4bb952[_0x998a11(0x316)],'useinbandfec':0x1,'maxptime':_0x4bb952['maxptime'],'minptime':_0x4bb952[_0x998a11(0x2b8)],'ptime':_0x4bb952[_0x998a11(0x474)]});else _0x4bb952['audiobitrate']&&(_0x445c5e[_0x998a11(0x58b)]=CodecsHandler[_0x998a11(0x2e7)](_0x445c5e[_0x998a11(0x58b)],{'maxaveragebitrate':_0x4bb952[_0x998a11(0x497)]*0x400,'cbr':_0x4bb952[_0x998a11(0x316)],'useinbandfec':0x1,'maxptime':_0x4bb952['maxptime'],'minptime':_0x4bb952[_0x998a11(0x2b8)],'ptime':_0x4bb952[_0x998a11(0x474)]}));}}_0x4bb952['codec']&&(_0x445c5e[_0x998a11(0x58b)]=CodecsHandler[_0x998a11(0x177)](_0x445c5e[_0x998a11(0x58b)],_0x4bb952[_0x998a11(0x529)]));_0x4bb952[_0x998a11(0x5ac)]&&(log(_0x445c5e[_0x998a11(0x58b)]),_0x445c5e['sdp']=CodecsHandler[_0x998a11(0x334)](_0x445c5e[_0x998a11(0x58b)]));_0x4bb952[_0x998a11(0x35b)]&&(_0x445c5e[_0x998a11(0x58b)]=CodecsHandler['disablePLI'](_0x445c5e[_0x998a11(0x58b)]));_0x4bb952[_0x998a11(0x5b0)]&&(_0x445c5e[_0x998a11(0x58b)]=CodecsHandler[_0x998a11(0x4f3)](_0x445c5e[_0x998a11(0x58b)]));if(_0x4bb952[_0x998a11(0x2c9)][_0x39dabe[_0x998a11(0x4ec)]][_0x998a11(0x168)])log(_0x998a11(0x423)),_0x445c5e[_0x998a11(0x58b)]=_0x5e4081(_0x445c5e[_0x998a11(0x58b)],_0x4bb952[_0x998a11(0x2c9)][_0x39dabe[_0x998a11(0x4ec)]][_0x998a11(0x168)]);else _0x4bb952[_0x998a11(0x476)]&&(log('bit\x20rate\x20being\x20munged'),_0x445c5e[_0x998a11(0x58b)]=_0x5e4081(_0x445c5e[_0x998a11(0x58b)],_0x4bb952[_0x998a11(0x476)]));return _0x4bb952['rpcs'][_0x39dabe['UUID']][_0x998a11(0x3e6)](_0x445c5e);})[_0x2e1dee(0x3f8)](function _0x32cd7c(){var _0x2142ea=_0x2e1dee;log(_0x2142ea(0x447));var _0x51ee81={};_0x51ee81[_0x2142ea(0x4ec)]=_0x39dabe[_0x2142ea(0x4ec)],_0x51ee81[_0x2142ea(0x1e4)]=_0x4bb952['rpcs'][_0x39dabe[_0x2142ea(0x4ec)]]['localDescription'],_0x51ee81[_0x2142ea(0x2d6)]=_0x4bb952[_0x2142ea(0x2c9)][_0x39dabe[_0x2142ea(0x4ec)]][_0x2142ea(0x2d6)],_0x4bb952[_0x2142ea(0x208)]?_0x4bb952[_0x2142ea(0x32b)](JSON[_0x2142ea(0x47f)](_0x51ee81[_0x2142ea(0x1e4)]))[_0x2142ea(0x3f8)](function(_0x2c0d57){var _0x4e4dee=_0x2142ea;_0x51ee81['description']=_0x2c0d57[0x0],_0x51ee81[_0x4e4dee(0x192)]=_0x2c0d57[0x1],_0x4bb952['anyrequest'](_0x51ee81);}):_0x4bb952[_0x2142ea(0x490)](_0x51ee81);})[_0x2e1dee(0x5fa)](errorlog);else _0x4bb952[_0x2e1dee(0x2c9)][_0x39dabe[_0x2e1dee(0x4ec)]][_0x2e1dee(0x559)][_0x2e1dee(0x2e9)]==='answer'&&errorlog(_0x2e1dee(0x5ed));})[_0x22e9ea(0x5fa)](errorlog);},_0x4bb952['setupIncoming']=function(_0x3aa018){var _0xc05fdc=_0x41b841,_0x1ba910=_0x3aa018[_0xc05fdc(0x4ec)];if(_0x1ba910 in _0x4bb952[_0xc05fdc(0x2c9)]){log(_0xc05fdc(0x49c)),log(_0x3aa018);if(_0xc05fdc(0x2d6)in _0x3aa018){if(_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x2d6)]==_0x3aa018[_0xc05fdc(0x2d6)]){log(_0xc05fdc(0x338));return;}else warnlog('SDP\x20Sessions\x20do\x20not\x20match.\x20Do\x20I\x20delete\x20an\x20accept\x20this\x20new\x20SDP?');}}else log(_0xc05fdc(0x3b0));try{for(var _0xd72e21 in _0x4bb952[_0xc05fdc(0x2c9)]){if(_0x4bb952['rpcs'][_0xd72e21]['streamID']==_0x3aa018[_0xc05fdc(0x4e8)]){_0x4bb952[_0xc05fdc(0x2c9)][_0xd72e21][_0xc05fdc(0x487)]&&(_0x4bb952['rpcs'][_0xd72e21][_0xc05fdc(0x487)][_0xc05fdc(0x1a2)][_0xc05fdc(0x232)]=_0xc05fdc(0x54d));_0x4bb952[_0xc05fdc(0x2c9)][_0xd72e21]=null,delete _0x4bb952[_0xc05fdc(0x2c9)][_0xd72e21],warnlog(_0xc05fdc(0x570));if(_0x4bb952[_0xc05fdc(0x18f)])try{document['getElementById'](_0xc05fdc(0x3ab)+_0xd72e21)&&getById('container_'+_0xd72e21)[_0xc05fdc(0x506)][_0xc05fdc(0x36e)](getById(_0xc05fdc(0x3ab)+_0xd72e21));}catch(_0x4943b5){errorlog(_0x4943b5);}}}document[_0xc05fdc(0x54a)]('mainmenu')&&document[_0xc05fdc(0x54a)](_0xc05fdc(0x33d))[_0xc05fdc(0x506)][_0xc05fdc(0x36e)](document[_0xc05fdc(0x54a)](_0xc05fdc(0x33d)));}catch(_0x173735){errorlog(_0x173735);}if(_0x4bb952[_0xc05fdc(0x39c)]!==![]){if(Object[_0xc05fdc(0x589)](_0x4bb952[_0xc05fdc(0x2c9)])[_0xc05fdc(0x28f)]>=_0x4bb952['maxpublishers']){delete _0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910],updateUserList(),warnlog(_0xc05fdc(0x3b3));return;}}else{if(_0x4bb952['maxconnections']!==![]){if(Object[_0xc05fdc(0x589)](_0x4bb952[_0xc05fdc(0x2c9)])[_0xc05fdc(0x28f)]+Object[_0xc05fdc(0x589)](_0x4bb952[_0xc05fdc(0x347)])[_0xc05fdc(0x28f)]>=_0x4bb952[_0xc05fdc(0x3db)]){delete _0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910],updateUserList(),warnlog(_0xc05fdc(0x3b3));return;}}}if(_0x4bb952[_0xc05fdc(0x45a)]){if(_0x4bb952[_0xc05fdc(0x18f)])!(_0x1ba910 in _0x4bb952[_0xc05fdc(0x347)])&&_0x4bb952[_0xc05fdc(0x444)](_0x1ba910);else{if(_0x4bb952['directorUUID']!==_0x1ba910)return;}}_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910]=new RTCPeerConnection(_0x4bb952[_0xc05fdc(0x397)]);if(_0x4bb952[_0xc05fdc(0x5d6)]){if(Object[_0xc05fdc(0x589)](_0x4bb952[_0xc05fdc(0x2c9)])[_0xc05fdc(0x28f)]>0x1){warnlog(_0xc05fdc(0x30d)),log(_0x4bb952[_0xc05fdc(0x2c9)]),delete _0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910],updateUserList();return;}else warnlog(_0xc05fdc(0x2bd));}_0x3aa018[_0xc05fdc(0x4e8)]in _0x4bb952[_0xc05fdc(0x1ad)]&&delete _0x4bb952[_0xc05fdc(0x1ad)][_0x3aa018[_0xc05fdc(0x4e8)]];_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4e8)]=_0x3aa018[_0xc05fdc(0x4e8)];_0x3aa018[_0xc05fdc(0x2d6)]?_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910]['session']=_0x3aa018[_0xc05fdc(0x2d6)]:_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x2d6)]=null;_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x2cf)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x5c3)]={},_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x5c3)][_0xc05fdc(0x57d)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910]['bandwidth']=-0x1,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x40c)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x49a)]=-0x1,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x168)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x487)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x220)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x380)]=![],_0x4bb952['rpcs'][_0x1ba910][_0xc05fdc(0x55b)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x377)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x5a1)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x2ef)]=![],_0x4bb952['rpcs'][_0x1ba910][_0xc05fdc(0x1a1)]=null,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x3d8)]={},_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4fe)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x1da)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x45f)]=null,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4eb)]=0x64,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x1ac)]=0x0,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x434)]=0x0,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x50d)]=0x0,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x3c6)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x540)]=![],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x385)]=null,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x5fc)]=null,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4c2)]={},_0x4bb952['rpcs'][_0x1ba910][_0xc05fdc(0x49d)]=![],_0x4bb952['rpcs'][_0x1ba910][_0xc05fdc(0x273)]=![],_0x4bb952['rpcs'][_0x1ba910][_0xc05fdc(0x53a)]=Date[_0xc05fdc(0x2c5)]();var _0x418651='';_0x4bb952[_0xc05fdc(0x5c0)]&&(_0xc05fdc(0x331)===_0xc05fdc(0x331)?_0x418651=_0x4bb952[_0xc05fdc(0x5c0)]:_0xc5a939(_0xc05fdc(0x4de)));if(_0x4bb952['director']){var _0x1e80d2='';_0x4bb952[_0xc05fdc(0x42f)]&&(_0x4bb952[_0xc05fdc(0x42f)]!==!![]?_0x1e80d2=_0xc05fdc(0x2f1)+_0x4bb952[_0xc05fdc(0x42f)]:_0x1e80d2=_0xc05fdc(0x272));var _0xc8bd63='';_0x4bb952['password']&&(_0x4bb952[_0xc05fdc(0x1b8)]===![]&&(_0xc8bd63=_0xc05fdc(0x2db)+_0x4bb952[_0xc05fdc(0x208)])),createControlBox(_0x1ba910,_0xc05fdc(0x17e)+location[_0xc05fdc(0x42d)]+location['pathname']+_0xc05fdc(0x3b5)+_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4e8)]+'&scene'+_0x418651+_0xc05fdc(0x4a3)+_0x4bb952[_0xc05fdc(0x1e0)]+_0xc8bd63+_0x1e80d2,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4e8)]);}_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4ec)]=_0x1ba910;if(_0xc05fdc(0x4e8)in _0x3aa018){_0x4bb952['rpcs'][_0x1ba910][_0xc05fdc(0x4e8)]=_0x3aa018[_0xc05fdc(0x4e8)];try{if(_0x4bb952[_0xc05fdc(0x176)]){if(_0x4bb952[_0xc05fdc(0x176)]['includes'](_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4e8)])){if(_0x4bb952[_0xc05fdc(0x48c)]!==![]){let _0xa0db22=_0x4bb952[_0xc05fdc(0x176)][_0xc05fdc(0x4a8)](_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x4e8)]);_0x4bb952[_0xc05fdc(0x48c)][_0xc05fdc(0x28f)]>_0xa0db22&&(_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x168)]=parseInt(_0x4bb952[_0xc05fdc(0x48c)][_0xa0db22]),_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x168)]<=0x0&&(_0x4bb952['rpcs'][_0x1ba910][_0xc05fdc(0x168)]=![]));}}}}catch(_0x15c634){errorlog(_0x15c634);}}_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910]['onclose']=function(_0x1c70fd){var _0x424daa=_0xc05fdc;try{var _0x1db31b=this[_0x424daa(0x4e8)];}catch(_0x453bd2){}if(!_0x4bb952['director']){if(_0x4bb952[_0x424daa(0x24c)]!==![]||_0x4bb952[_0x424daa(0x1e0)]!==![])try{_0x4bb952[_0x424daa(0x2c9)][this[_0x424daa(0x4ec)]]['videoElement']&&(_0x4bb952[_0x424daa(0x2c9)][this[_0x424daa(0x4ec)]][_0x424daa(0x487)][_0x424daa(0x1a2)][_0x424daa(0x232)]=_0x424daa(0x54d)),setTimeout(function(){updateMixer();},0x1);}catch(_0x349f2c){}}try{document[_0x424daa(0x54a)](_0x424daa(0x3ab)+this[_0x424daa(0x4ec)])&&getById('container_'+this[_0x424daa(0x4ec)])[_0x424daa(0x506)][_0x424daa(0x36e)](getById(_0x424daa(0x3ab)+this[_0x424daa(0x4ec)]));}catch(_0xd11f0e){errorlog(_0xd11f0e);}try{this[_0x424daa(0x45f)]&&this[_0x424daa(0x45f)][_0x424daa(0x3bb)]()[_0x424daa(0x35e)](function(_0x735c3e){_0x735c3e['stop']();});}catch(_0x21e55d){errorlog(_0x21e55d);}try{this[_0x424daa(0x4b2)][_0x424daa(0x5cd)]();}catch(_0x3ccc3d){errorlog(_0x3ccc3d);}try{_0x4bb952[_0x424daa(0x2c9)][this[_0x424daa(0x4ec)]]=null,delete _0x4bb952[_0x424daa(0x2c9)][this['UUID']];}catch(_0x499709){errorlog(_0x499709);}warnlog(_0x424daa(0x570));try{_0x4bb952[_0x424daa(0x360)](_0x1db31b);}catch(_0x54b5ef){errorlog(_0x424daa(0x57a)),errorlog(_0x54b5ef);}updateUserList();},_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x5c7)]=null,_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x346)]=[],_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910]['onicecandidate']=function(_0x399bd8){var _0x2ec8b5=_0xc05fdc;if(_0x2ec8b5(0x23e)===_0x2ec8b5(0x15e))_0x1fbdcb[_0x2ec8b5(0x2c9)][_0x1460d5][_0x2ec8b5(0x487)][_0x2ec8b5(0x275)]&&(_0x1b7303(_0x2ec8b5(0x52b)),_0x391068[_0x2ec8b5(0x2c9)][_0x279836][_0x2ec8b5(0x487)][_0x2ec8b5(0x31f)]()['then'](_0x2a14d4=>{_0x8035c8('playing'),_0xbcfe3a=!![];})[_0x2ec8b5(0x5fa)](_0x392620));else{if(_0x399bd8['candidate']==null){log('null\x20ice\x20rpcs');return;}try{if(_0x4bb952[_0x2ec8b5(0x1fa)]){if(_0x399bd8[_0x2ec8b5(0x4d1)][_0x2ec8b5(0x4d1)]['indexOf'](_0x4bb952[_0x2ec8b5(0x1fa)])===-0x1){log(_0x2ec8b5(0x3dd));return;}else log(_0x399bd8[_0x2ec8b5(0x4d1)]);}}catch(_0x3dead2){errorlog(_0x3dead2);}if(_0x4bb952[_0x2ec8b5(0x2c9)][_0x1ba910][_0x2ec8b5(0x5c7)]!==null){_0x4bb952['rpcs'][_0x1ba910][_0x2ec8b5(0x346)][_0x2ec8b5(0x3a5)](_0x399bd8[_0x2ec8b5(0x4d1)]);return;}_0x4bb952[_0x2ec8b5(0x2c9)][_0x1ba910][_0x2ec8b5(0x346)][_0x2ec8b5(0x3a5)](_0x399bd8[_0x2ec8b5(0x4d1)]),_0x4bb952[_0x2ec8b5(0x2c9)][_0x1ba910]['iceTimer']=setTimeout(function(){var _0x3330b4=_0x2ec8b5;if(!(_0x1ba910 in _0x4bb952[_0x3330b4(0x2c9)]))return;_0x4bb952[_0x3330b4(0x2c9)][_0x1ba910][_0x3330b4(0x5c7)]=null;if(_0x4bb952[_0x3330b4(0x2c9)][_0x1ba910]['iceBundle']==[])return;var _0x21a122={};_0x21a122[_0x3330b4(0x4ec)]=_0x1ba910,_0x21a122[_0x3330b4(0x2e9)]=_0x3330b4(0x2cd),_0x21a122[_0x3330b4(0x325)]=_0x4bb952['rpcs'][_0x1ba910][_0x3330b4(0x346)],_0x21a122[_0x3330b4(0x2d6)]=_0x4bb952[_0x3330b4(0x2c9)][_0x1ba910][_0x3330b4(0x2d6)],_0x4bb952[_0x3330b4(0x2c9)][_0x1ba910][_0x3330b4(0x346)]=[];if(_0x4bb952[_0x3330b4(0x208)]){if(_0x3330b4(0x469)===_0x3330b4(0x45e))return![];else _0x4bb952[_0x3330b4(0x32b)](JSON['stringify'](_0x21a122['candidates']))['then'](function(_0x10eea1){var _0x3ba9bc=_0x3330b4;_0x3ba9bc(0x210)!==_0x3ba9bc(0x210)?(_0x450278('problem'),_0x300daf[_0x3ba9bc(0x347)][_0x4d7b81[_0x3ba9bc(0x4ec)]][_0x3ba9bc(0x5cd)](),delete _0x34f00a[_0x3ba9bc(0x347)][_0x378976[_0x3ba9bc(0x4ec)]],_0x54288a[_0x3ba9bc(0x436)](),_0x1d1ca9()):(_0x21a122[_0x3ba9bc(0x325)]=_0x10eea1[0x0],_0x21a122[_0x3ba9bc(0x192)]=_0x10eea1[0x1],_0x4bb952[_0x3ba9bc(0x490)](_0x21a122));});}else _0x3330b4(0x572)!==_0x3330b4(0x5db)?_0x4bb952['anyrequest'](_0x21a122):_0x315d9f=_0x33cf70;},0x190);}},_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x212)]=function(_0x200965){var _0x3c4d61=_0xc05fdc;switch(this['connectionState']){case _0x3c4d61(0x523):log(_0x3c4d61(0x523));case'checking':log(_0x3c4d61(0x57f));case _0x3c4d61(0x4e1):log('**\x20connected');if(_0x4bb952[_0x3c4d61(0x5d6)]){if(_0x4bb952['ws'][_0x3c4d61(0x2e0)]!==0x1){_0x4bb952['ws'][_0x3c4d61(0x5cd)]();break;}_0x4bb952['ws'][_0x3c4d61(0x5cd)](),setTimeout(function(){var _0x798f80=_0x3c4d61;_0x4bb952[_0x798f80(0x52d)]!=!![]&&('lReyn'==='zXady'?_0x14adfd=_0x364879[_0x798f80(0x5c0)]:warnUser(_0x798f80(0x4de)));},0x1);}break;case _0x3c4d61(0x19f):warnlog(_0x3c4d61(0x5dd));break;case'failed':warnlog('FAIL\x20rpcs');try{var _0x346d94=this[_0x3c4d61(0x4e8)];}catch(_0x18f0c3){}try{this['streamSrc']&&this[_0x3c4d61(0x45f)]['getTracks']()['forEach'](function(_0x2dd229){var _0x22b424=_0x3c4d61;_0x2dd229[_0x22b424(0x3a4)](),log(_0x22b424(0x221));});}catch(_0x24780c){warnlog(_0x24780c);}if(_0x4bb952[_0x3c4d61(0x18f)])try{'recorder'in _0x4bb952[_0x3c4d61(0x2c9)][this[_0x3c4d61(0x4ec)]]['videoElement']&&(_0x3c4d61(0x187)!==_0x3c4d61(0x187)?_0x2740df[_0x3c4d61(0x2c9)][_0x1cc91b][_0x3c4d61(0x5cd)]():_0x4bb952['rpcs'][this[_0x3c4d61(0x4ec)]][_0x3c4d61(0x487)][_0x3c4d61(0x425)][_0x3c4d61(0x3a4)]());}catch(_0x4ea673){warnlog(_0x4ea673);}try{document['getElementById'](_0x3c4d61(0x3ab)+this[_0x3c4d61(0x4ec)])&&getById('container_'+this[_0x3c4d61(0x4ec)])[_0x3c4d61(0x506)][_0x3c4d61(0x36e)](getById(_0x3c4d61(0x3ab)+this[_0x3c4d61(0x4ec)]));}catch(_0x543610){warnlog(_0x543610);}_0x4bb952['rpcs'][this[_0x3c4d61(0x4ec)]][_0x3c4d61(0x5cd)](),_0x4bb952[_0x3c4d61(0x2c9)][this[_0x3c4d61(0x4ec)]]=null,delete _0x4bb952['rpcs'][this[_0x3c4d61(0x4ec)]];!_0x4bb952['director']&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x346d94==_0x3c4d61(0x1fe))break;try{warnlog('Trying\x20to\x20reconnect\x202'),_0x346d94 in _0x4bb952[_0x3c4d61(0x413)]&&clearTimeout(_0x4bb952[_0x3c4d61(0x413)][_0x346d94]),_0x4bb952[_0x3c4d61(0x413)][_0x346d94]=setTimeout(function(_0x46e45c){var _0x16eaf1=_0x3c4d61;delete _0x4bb952[_0x16eaf1(0x413)][_0x46e45c],_0x4bb952[_0x16eaf1(0x360)](_0x46e45c);},_0x4bb952[_0x3c4d61(0x31a)],_0x346d94);}catch(_0x4f0fc9){errorlog(_0x4f0fc9);}break;case'closed':warnlog(_0x3c4d61(0x5eb));try{var _0x346d94=this['streamID'];}catch(_0x1b790e){};try{this[_0x3c4d61(0x45f)]&&this['streamSrc'][_0x3c4d61(0x3bb)]()[_0x3c4d61(0x35e)](function(_0x1c0e8f){var _0x1fef1f=_0x3c4d61;_0x1c0e8f[_0x1fef1f(0x3a4)](),log(_0x1fef1f(0x221));});}catch(_0x2b5599){}if(_0x4bb952[_0x3c4d61(0x18f)])try{if('bmYUE'!==_0x3c4d61(0x3cd)){if(_0x30c756[_0x3c4d61(0x347)][_0x54ed78]['savedBitrate']===![])return;_0x4d66db=_0x32c6a8[_0x3c4d61(0x347)][_0x2be5ce][_0x3c4d61(0x50e)];}else _0x3c4d61(0x425)in _0x4bb952[_0x3c4d61(0x2c9)][this[_0x3c4d61(0x4ec)]][_0x3c4d61(0x487)]&&_0x4bb952[_0x3c4d61(0x2c9)][this[_0x3c4d61(0x4ec)]][_0x3c4d61(0x487)][_0x3c4d61(0x425)][_0x3c4d61(0x3a4)]();}catch(_0x13d7ad){errorlog(_0x13d7ad);}try{_0x3c4d61(0x39a)===_0x3c4d61(0x522)?!_0x531a23[_0x3c4d61(0x52d)]&&(_0x2bcc0d(function(){var _0x12ff11=_0x3c4d61;_0x5b84bf(_0x12ff11(0x59d));},0x1),_0x5bd1d5('head4')[_0x3c4d61(0x172)]=_0x3c4d61(0x2d7)):document[_0x3c4d61(0x54a)](_0x3c4d61(0x3ab)+this[_0x3c4d61(0x4ec)])&&getById(_0x3c4d61(0x3ab)+this[_0x3c4d61(0x4ec)])[_0x3c4d61(0x506)][_0x3c4d61(0x36e)](getById(_0x3c4d61(0x3ab)+this[_0x3c4d61(0x4ec)]));}catch(_0x1a684f){errorlog(_0x1a684f);}_0x4bb952[_0x3c4d61(0x2c9)][this[_0x3c4d61(0x4ec)]][_0x3c4d61(0x5cd)](),_0x4bb952[_0x3c4d61(0x2c9)][this[_0x3c4d61(0x4ec)]]=null,delete _0x4bb952[_0x3c4d61(0x2c9)][this[_0x3c4d61(0x4ec)]];!_0x4bb952['director']&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x346d94=='undefined')break;try{errorlog('TRYING\x20TO\x20RECONNECT\x203'),_0x346d94 in _0x4bb952[_0x3c4d61(0x413)]&&clearTimeout(_0x4bb952['watchTimeoutList'][_0x346d94]),_0x4bb952[_0x3c4d61(0x413)][_0x346d94]=setTimeout(function(_0x123d05){var _0x4a8d1e=_0x3c4d61;delete _0x4bb952[_0x4a8d1e(0x413)][_0x123d05],_0x4bb952[_0x4a8d1e(0x360)](_0x123d05);},_0x4bb952[_0x3c4d61(0x31a)],_0x346d94);}catch(_0x407d53){errorlog(_0x407d53);}break;}},_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x19e)]=function(){var _0x14227e=_0xc05fdc;try{if(this[_0x14227e(0x3a0)]=='closed')errorlog(_0x14227e(0x40d));else{if(this[_0x14227e(0x3a0)]==_0x14227e(0x19f))warnlog('ICE\x20DISCONNECTED'),_0x4bb952[_0x14227e(0x2c9)][_0x1ba910][_0x14227e(0x487)][_0x14227e(0x1a2)][_0x14227e(0x2eb)]='0',_0x4bb952[_0x14227e(0x2c9)][_0x1ba910][_0x14227e(0x2a5)]=setTimeout(function(_0x37aad7){var _0x32ce56=_0x14227e;_0x32ce56(0x280)!==_0x32ce56(0x280)?_0x4ca189[_0x32ce56(0x5f5)](_0x46fb4f(_0x326ef3[_0x32ce56(0x372)])):updateMixer();},0x1f4,_0x1ba910);else this[_0x14227e(0x3a0)]=='failed'?errorlog(_0x14227e(0x410)):_0x14227e(0x567)===_0x14227e(0x567)?(log(_0x14227e(0x2bf)+this[_0x14227e(0x3a0)]),_0x14227e(0x2eb)in _0x4bb952[_0x14227e(0x2c9)][_0x1ba910][_0x14227e(0x487)][_0x14227e(0x1a2)]?_0x4bb952[_0x14227e(0x2c9)][_0x1ba910][_0x14227e(0x487)][_0x14227e(0x1a2)]['opacity']=='0'&&(_0x4bb952[_0x14227e(0x2c9)][_0x1ba910][_0x14227e(0x487)]['style'][_0x14227e(0x2eb)]='1',updateMixer()):_0x14227e(0x3f4)!==_0x14227e(0x3f4)?(_0x3e6e7['queueList']['push'](_0x19f7dd[_0x14227e(0x4e8)]),_0x75d4f3[_0x14227e(0x196)]()):_0x4bb952['rpcs'][_0x1ba910][_0x14227e(0x487)]['style'][_0x14227e(0x2eb)]='1',_0x4bb952['rpcs'][_0x1ba910][_0x14227e(0x2a5)]&&clearTimeout(_0x4bb952['rpcs'][_0x1ba910][_0x14227e(0x2a5)])):_0x1deac8[_0x14227e(0x347)][_0xa188e5][_0x14227e(0x535)]==!![]&&_0xafe2f7['roombitrate']===0x0?_0x3d6b48(_0x14227e(0x26f)):(_0x40929f[_0x14227e(0x347)][_0x3aac83][_0x14227e(0x40e)](_0x5a9813,_0x1612b2),_0x5b42c4(function(_0x447253){var _0x30d310=_0x14227e;_0x1bdc2f[_0x30d310(0x520)](_0x447253);},_0xc38da7['rampUpTime'],_0x5548fb));}}catch(_0x324049){}},_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910]['ondatachannel']=function(_0x49adb9){var _0x14e5fb=_0xc05fdc;_0x4bb952[_0x14e5fb(0x2c9)][_0x1ba910][_0x14e5fb(0x4b2)]=_0x49adb9[_0x14e5fb(0x38f)],_0x4bb952['rpcs'][_0x1ba910][_0x14e5fb(0x4b2)][_0x14e5fb(0x4ec)]=_0x1ba910,_0x4bb952[_0x14e5fb(0x2c9)][_0x1ba910][_0x14e5fb(0x4b2)][_0x14e5fb(0x256)]=_0x275245=>{var _0x218b51=_0x14e5fb,_0x5b2b31={};_0x5b2b31[_0x218b51(0x1db)]=![];if(_0x4bb952[_0x218b51(0x16f)]!==![])_0x4bb952[_0x218b51(0x16f)][_0x218b51(0x5cf)](_0x4bb952[_0x218b51(0x2c9)][_0x1ba910][_0x218b51(0x4e8)])?_0x5b2b31[_0x218b51(0x195)]=!![]:_0x5b2b31[_0x218b51(0x195)]=![];else{if(_0x4bb952[_0x218b51(0x1db)]!==![]){if(_0x4bb952[_0x218b51(0x1db)]!==null)_0x4bb952['rpcs'][_0x1ba910][_0x218b51(0x4e8)]===_0x4bb952[_0x218b51(0x1db)]?_0x4bb952[_0x218b51(0x3a2)]?(_0x5b2b31[_0x218b51(0x1db)]=!![],_0x5b2b31[_0x218b51(0x195)]=![]):_0x5b2b31[_0x218b51(0x195)]=!![]:_0x5b2b31[_0x218b51(0x195)]=![];else _0x4bb952['directorUUID']&&(_0x1ba910==_0x4bb952[_0x218b51(0x266)]?_0x4bb952[_0x218b51(0x3a2)]?(_0x5b2b31[_0x218b51(0x195)]=![],_0x5b2b31[_0x218b51(0x1db)]=!![]):_0x5b2b31['video']=!![]:_0x5b2b31[_0x218b51(0x195)]=![]);}else _0x4bb952[_0x218b51(0x226)]!==![]?_0x4bb952[_0x218b51(0x226)][_0x218b51(0x5cf)](_0x4bb952[_0x218b51(0x2c9)][_0x1ba910][_0x218b51(0x4e8)])?_0x5b2b31[_0x218b51(0x195)]=![]:_0x5b2b31[_0x218b51(0x195)]=!![]:_0x5b2b31['video']=!![];}_0x4bb952[_0x218b51(0x2de)]&&(_0x5b2b31[_0x218b51(0x243)]=_0x4bb952[_0x218b51(0x2de)]);try{_0x5b2b31['info']={},_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x3c6)]=_0x4bb952[_0x218b51(0x3c6)],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x540)]=_0x4bb952[_0x218b51(0x540)],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x299)]=_0x4bb952[_0x218b51(0x2b1)],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x33e)]=_0x4bb952['bitrate'],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x315)]=_0x4bb952[_0x218b51(0x497)],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x218)]=_0x4bb952['codec'],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x3c4)]=_0x4bb952[_0x218b51(0x3c4)],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x30e)]=_0x4bb952[_0x218b51(0x30e)],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x34d)]=_0x4bb952[_0x218b51(0x313)],_0x5b2b31[_0x218b51(0x20f)]['ptime']=_0x4bb952[_0x218b51(0x474)],_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x2b8)]=_0x4bb952['minptime'],_0x5b2b31['info'][_0x218b51(0x3f6)]=_0x4bb952['maxptime'];if(navigator[_0x218b51(0x33c)]){var _0x117985,_0x47aa7c=navigator[_0x218b51(0x33c)];_0x5b2b31['info']['useragent']=_0x47aa7c;}navigator[_0x218b51(0x565)]&&(_0x5b2b31[_0x218b51(0x20f)]['platform']=navigator[_0x218b51(0x565)]);if(window[_0x218b51(0x1e7)]){_0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x2a9)]=window[_0x218b51(0x1e7)][_0x218b51(0x348)];if(_0x4bb952[_0x218b51(0x204)]){var _0x47d4b3=![];_0x4bb952[_0x218b51(0x204)][_0x218b51(0x202)]!==null&&(_0x5b2b31[_0x218b51(0x1cd)]=_0x4bb952[_0x218b51(0x204)][_0x218b51(0x202)],_0x4bb952[_0x218b51(0x204)][_0x218b51(0x202)]===![]&&(_0x47d4b3=!![])),_0x4bb952[_0x218b51(0x204)][_0x218b51(0x1eb)]!==null&&(_0x5b2b31['obsSourceActive']=_0x4bb952[_0x218b51(0x204)][_0x218b51(0x1eb)]),_0x4bb952['obsState']['recording']!==null&&(_0x5b2b31[_0x218b51(0x365)]=_0x4bb952[_0x218b51(0x204)][_0x218b51(0x203)]),_0x4bb952[_0x218b51(0x204)][_0x218b51(0x50a)]!==null&&(_0x5b2b31['obsStreaming']=_0x4bb952[_0x218b51(0x204)]['streaming']);}_0x4bb952['optimize']!==![]&&(_0x5b2b31[_0x218b51(0x517)]=parseInt(_0x4bb952[_0x218b51(0x230)]),_0x47d4b3&&('YzHKU'===_0x218b51(0x3e7)?_0x4bb952[_0x218b51(0x2c9)][_0x1ba910][_0x218b51(0x1c7)]=_0x5b2b31['optimizedBitrate']:_0xda0284(_0x218b51(0x3ab)+this[_0x218b51(0x4ec)])[_0x218b51(0x506)]['removeChild'](_0x1995ae(_0x218b51(0x3ab)+this['UUID']))));}else _0x5b2b31[_0x218b51(0x20f)][_0x218b51(0x2a9)]=![];}catch(_0x20a57a){};_0x4bb952[_0x218b51(0x178)]!==![]?_0x4bb952[_0x218b51(0x178)][_0x218b51(0x5cf)](_0x4bb952[_0x218b51(0x2c9)][_0x1ba910][_0x218b51(0x4e8)])?_0x5b2b31[_0x218b51(0x169)]=!![]:_0x5b2b31[_0x218b51(0x169)]=![]:_0x5b2b31[_0x218b51(0x169)]=!![];_0x5b2b31[_0x218b51(0x369)]=![];_0x4bb952[_0x218b51(0x1c5)]!==![]?_0x4bb952[_0x218b51(0x1c5)]['includes'](_0x4bb952[_0x218b51(0x2c9)][_0x1ba910][_0x218b51(0x4e8)])?_0x218b51(0x561)===_0x218b51(0x500)?(_0x5eeeaa[_0x218b51(0x2c9)][_0x362447][_0x218b51(0x487)][_0x218b51(0x3df)]=!![],_0x41fe2d[_0x218b51(0x2c9)][_0x5085e4][_0x218b51(0x487)][_0x218b51(0x1a2)][_0x218b51(0x232)]&&_0x23b6df[_0x218b51(0x2c9)][_0x2e801a][_0x218b51(0x487)][_0x218b51(0x1a2)][_0x218b51(0x232)]!==_0x218b51(0x54d)&&(_0x3949ce[_0x218b51(0x2c9)][_0x37c640][_0x218b51(0x487)][_0x218b51(0x1a2)][_0x218b51(0x232)]=_0x218b51(0x54d),_0x629c58=!![])):_0x5b2b31[_0x218b51(0x369)]=!![]:_0x5b2b31[_0x218b51(0x369)]=![]:_0x5b2b31[_0x218b51(0x369)]=!![];_0x5b2b31['guest']=![],_0x5b2b31[_0x218b51(0x24c)]=![],_0x5b2b31[_0x218b51(0x18f)]=![],_0x5b2b31[_0x218b51(0x314)]=_0x4bb952['keyframerate'],_0x5b2b31['enhanceaudio']=![],_0x5b2b31[_0x218b51(0x352)]=![],_0x5b2b31[_0x218b51(0x30e)]=![];_0x4bb952[_0x218b51(0x313)]&&(_0x5b2b31['enhanceaudio']=!![]);if(_0x4bb952[_0x218b51(0x18f)])_0x5b2b31['director']=!![],_0x5b2b31[_0x218b51(0x30e)]=_0x4bb952['forceios'];else{if(_0x4bb952[_0x218b51(0x24c)]!==![])_0x5b2b31[_0x218b51(0x24c)]=_0x4bb952[_0x218b51(0x24c)];else _0x4bb952[_0x218b51(0x1e0)]!==![]&&_0x4bb952[_0x218b51(0x1e0)]!==''&&(_0x5b2b31[_0x218b51(0x30e)]=_0x4bb952[_0x218b51(0x30e)],_0x5b2b31['guest']=!![]);}_0x4bb952['sendRequest'](_0x5b2b31,_0x1ba910)?log(_0x218b51(0x250)):errorlog('Failed\x20to\x20request\x20video\x20and\x20audio;\x20iOS\x20device\x20asking?'),pokeIframeAPI(_0x218b51(0x405),!![],_0x1ba910);},_0x4bb952[_0x14e5fb(0x2c9)][_0x1ba910][_0x14e5fb(0x4b2)][_0x14e5fb(0x171)]=_0x52a8ec=>{var _0x3b3ab9=_0x14e5fb;if(typeof _0x52a8ec[_0x3b3ab9(0x367)]==_0x3b3ab9(0x5d9)){if(!_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x220)])_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x220)]=document[_0x3b3ab9(0x190)](_0x3b3ab9(0x450)),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['imageElement']['width']=0x10,_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x220)][_0x3b3ab9(0x3ec)]=0x9,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x220)][_0x3b3ab9(0x53e)][_0x3b3ab9(0x4ec)]=_0x1ba910,_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x220)]['hidden']=![],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x220)]['addEventListener'](_0x3b3ab9(0x44e),function(_0x45c55c){var _0x1e0c5a=_0x3b3ab9;log(_0x1e0c5a(0x4b8));try{if(_0x45c55c[_0x1e0c5a(0x263)]||_0x45c55c[_0x1e0c5a(0x38d)]){_0x45c55c[_0x1e0c5a(0x2af)]();var _0x54f5fb=_0x45c55c[_0x1e0c5a(0x19c)][_0x1e0c5a(0x53e)][_0x1e0c5a(0x4ec)];if(_0x1e0c5a(0x5c3)in _0x4bb952[_0x1e0c5a(0x2c9)][_0x54f5fb]){var [_0x2dbe76,_0x48e70e]=statsMenuCreator();printViewStats(_0x48e70e,_0x54f5fb),_0x2dbe76[_0x1e0c5a(0x317)]=setInterval(printViewStats,0xbb8,_0x48e70e,_0x54f5fb);}return _0x45c55c['stopPropagation'](),![];}}catch(_0x513263){errorlog(_0x513263);}}),updateMixer();else _0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x220)]['hidden']&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['imageElement']['hidden']=![],_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x220)][_0x3b3ab9(0x1a2)][_0x3b3ab9(0x202)]='visible');_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['imageElement'][_0x3b3ab9(0x3cb)]=window[_0x3b3ab9(0x298)][_0x3b3ab9(0x495)](new Blob([new Uint8Array(_0x52a8ec[_0x3b3ab9(0x367)])],{'type':_0x3b3ab9(0x240)}));return;}var _0x10948f=JSON[_0x3b3ab9(0x2b5)](_0x52a8ec['data']);_0x10948f[_0x3b3ab9(0x4ec)]=_0x1ba910;var _0x512fd8=![],_0x161d0d=![];_0x3b3ab9(0x229)in _0x10948f&&(_0x4bb952[_0x3b3ab9(0x18f)]&&(!(_0x4bb952['cleanOutput']||_0x4bb952[_0x3b3ab9(0x1bd)])&&warnUser(_0x3b3ab9(0x1b0),0x1388)),errorlog(_0x3b3ab9(0x2e3)+_0x10948f[_0x3b3ab9(0x229)]+_0x3b3ab9(0x2f9)+_0x4bb952[_0x3b3ab9(0x18f)]));if(_0x3b3ab9(0x1e4)in _0x10948f)_0x4bb952[_0x3b3ab9(0x234)](_0x10948f);else{if(_0x3b3ab9(0x4d1)in _0x10948f)_0x10948f[_0x3b3ab9(0x4ec)]=_0x1ba910,log(_0x3b3ab9(0x5c9)),_0x4bb952['processIce'](_0x10948f);else{if(_0x3b3ab9(0x325)in _0x10948f)_0x10948f[_0x3b3ab9(0x4ec)]=_0x1ba910,log(_0x3b3ab9(0x502)),_0x4bb952[_0x3b3ab9(0x4f5)](_0x10948f);else{if(_0x3b3ab9(0x49d)in _0x10948f)try{_0x4bb952['rpcs'][_0x1ba910]['iframeSrc']=_0x10948f[_0x3b3ab9(0x49d)]||![];if(_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x49d)]==![]){if(_0x3b3ab9(0x1bc)===_0x3b3ab9(0x56f))_0xdcc320[_0x3b3ab9(0x4e4)]==![]&&(!_0x1cf186[_0x3b3ab9(0x52d)]&&(_0xea8418(function(){var _0x582d6b=_0x3b3ab9;_0x73243c(_0x582d6b(0x59d));},0x1),_0x2c0f77(_0x3b3ab9(0x598))[_0x3b3ab9(0x172)]=_0x3b3ab9(0x2d7)));else{_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]=![],_0x512fd8=!![];if(_0x4bb952[_0x3b3ab9(0x1db)]!==![]){if(_0x3b3ab9(0x290)!==_0x3b3ab9(0x18a)){if(_0x4bb952[_0x3b3ab9(0x1db)]!==null)_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x4e8)]===_0x4bb952[_0x3b3ab9(0x1db)]&&(_0x4bb952[_0x3b3ab9(0x3dc)]=![]);else _0x1ba910==_0x4bb952[_0x3b3ab9(0x266)]&&(_0x4bb952[_0x3b3ab9(0x3dc)]=![]);}else _0x34cd43[_0x3b3ab9(0x5bc)](![],_0x1644c3);}}}else{if(_0x3b3ab9(0x175)!==_0x3b3ab9(0x5a5)){if(_0x4bb952['broadcast']!==![]){if(_0x4bb952[_0x3b3ab9(0x1db)]!==null){if(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]===_0x4bb952[_0x3b3ab9(0x1db)]){if(_0x3b3ab9(0x52c)===_0x3b3ab9(0x52c)){if(_0x4bb952[_0x3b3ab9(0x1c5)]===![])_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x273)]=loadIframe(_0x10948f[_0x3b3ab9(0x49d)]),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['iframeEle']['id']=_0x3b3ab9(0x42c)+_0x1ba910,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)][_0x3b3ab9(0x53e)][_0x3b3ab9(0x4ec)]=_0x1ba910,_0x512fd8=!![],_0x4bb952[_0x3b3ab9(0x3dc)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)][_0x3b3ab9(0x53e)]['sid']=_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x4e8)]);else _0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['streamID']in _0x4bb952['noiframe']&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]=loadIframe(_0x10948f[_0x3b3ab9(0x49d)]),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]['id']=_0x3b3ab9(0x42c)+_0x1ba910,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['iframeEle']['dataset'][_0x3b3ab9(0x4ec)]=_0x1ba910,_0x512fd8=!![],_0x4bb952['broadcastIFrame']=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]&&(_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x273)]['dataset'][_0x3b3ab9(0x399)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]));}else _0x2917d6[_0x3b3ab9(0x216)]=_0x17b45d[_0x3b3ab9(0x2c9)][_0x313a91]['label'];}}else{if(_0x4bb952[_0x3b3ab9(0x266)]){if(_0x1ba910==_0x4bb952[_0x3b3ab9(0x266)]){if(_0x4bb952[_0x3b3ab9(0x1c5)]===![])_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]=loadIframe(_0x10948f[_0x3b3ab9(0x49d)]),_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x273)]['id']=_0x3b3ab9(0x42c)+_0x1ba910,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]['dataset'][_0x3b3ab9(0x4ec)]=_0x1ba910,_0x512fd8=!![],_0x4bb952['broadcastIFrame']=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]['dataset'][_0x3b3ab9(0x399)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]);else _0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]in _0x4bb952['noiframe']&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]=loadIframe(_0x10948f[_0x3b3ab9(0x49d)]),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]['id']=_0x3b3ab9(0x42c)+_0x1ba910,_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x273)][_0x3b3ab9(0x53e)][_0x3b3ab9(0x4ec)]=_0x1ba910,_0x512fd8=!![],_0x4bb952[_0x3b3ab9(0x3dc)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)][_0x3b3ab9(0x53e)][_0x3b3ab9(0x399)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]));}}}}else{if(_0x4bb952['noiframe']===![])_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]=loadIframe(_0x10948f['iframeSrc']),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]['id']=_0x3b3ab9(0x42c)+_0x1ba910,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)][_0x3b3ab9(0x53e)][_0x3b3ab9(0x4ec)]=_0x1ba910,_0x512fd8=!![],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['iframeEle'][_0x3b3ab9(0x53e)][_0x3b3ab9(0x399)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]);else _0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4e8)]in _0x4bb952['noiframe']&&(_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x273)]=loadIframe(_0x10948f[_0x3b3ab9(0x49d)]),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)]['id']=_0x3b3ab9(0x42c)+_0x1ba910,_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x273)][_0x3b3ab9(0x53e)][_0x3b3ab9(0x4ec)]=_0x1ba910,_0x512fd8=!![],_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x4e8)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x273)][_0x3b3ab9(0x53e)][_0x3b3ab9(0x399)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['streamID']));}}else _0x35e943=0x0;}}catch(_0x464228){errorlog(_0x464228);}}}}if(_0x3b3ab9(0x17a)in _0x10948f){var _0x38cbf7=![],_0x40c350=![];_0x4bb952[_0x3b3ab9(0x266)]===_0x1ba910&&(_0x38cbf7=!![],_0x3b3ab9(0x5ad)in _0x10948f&&(_0x10948f[_0x3b3ab9(0x5ad)]==!![]&&(_0x40c350=!![])));if(_0x4bb952[_0x3b3ab9(0x18f)]){if(_0x10948f[_0x3b3ab9(0x17a)]==_0x3b3ab9(0x324))_0x4bb952[_0x3b3ab9(0x4f0)]&&playtone(),getById(_0x3b3ab9(0x3da)+_0x1ba910)['style'][_0x3b3ab9(0x232)]=_0x3b3ab9(0x3e8),_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x294)][_0x3b3ab9(0x1a2)]['display']=_0x3b3ab9(0x466);else _0x10948f['chat']==_0x3b3ab9(0x518)&&(getById(_0x3b3ab9(0x3da)+_0x1ba910)[_0x3b3ab9(0x1a2)]['display']=_0x3b3ab9(0x54d),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x294)][_0x3b3ab9(0x1a2)][_0x3b3ab9(0x232)]=_0x3b3ab9(0x54d));}log(_0x3b3ab9(0x3ff)+_0x38cbf7),getChatMessage(_0x10948f[_0x3b3ab9(0x17a)],_0x4bb952['rpcs'][_0x1ba910]['label'],_0x38cbf7,_0x40c350);}_0x3b3ab9(0x5e6)in _0x10948f&&(log(_0x10948f),_0x4bb952[_0x3b3ab9(0x516)]&&updateClosedCaptions(_0x10948f,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x3c6)],_0x1ba910));'audioOptions'in _0x10948f&&(_0x4bb952[_0x3b3ab9(0x18f)]&&updateDirectorsAudio(_0x10948f[_0x3b3ab9(0x3fe)],_0x1ba910));_0x3b3ab9(0x45d)in _0x10948f&&(_0x4bb952[_0x3b3ab9(0x18f)]&&updateDirectorsVideo(_0x10948f[_0x3b3ab9(0x45d)],_0x1ba910));_0x3b3ab9(0x43a)in _0x10948f&&(_0x4bb952[_0x3b3ab9(0x18f)]&&('gOifu'!==_0x3b3ab9(0x3d6)?_0x663bb2['encodings']=[{}]:gotDevicesRemote(_0x10948f[_0x3b3ab9(0x43a)],_0x1ba910)));_0x3b3ab9(0x3af)in _0x10948f&&('jSsjR'!==_0x3b3ab9(0x57e)?_0x4740d2(_0x3b3ab9(0x3ae)):_0x4bb952[_0x3b3ab9(0x266)]===_0x1ba910&&(_0x4bb952[_0x3b3ab9(0x363)]&&lowerhand()));if('infocus'in _0x10948f){log(_0x10948f);if(_0x4bb952[_0x3b3ab9(0x266)]===_0x1ba910){if(_0x10948f[_0x3b3ab9(0x2fa)]!==![]){if(_0x10948f[_0x3b3ab9(0x2fa)]===!![])_0x4bb952[_0x3b3ab9(0x2fa)]=!![];else for(var _0x5c7053 in _0x4bb952[_0x3b3ab9(0x2c9)]){if(_0x4bb952[_0x3b3ab9(0x2c9)][_0x5c7053][_0x3b3ab9(0x4e8)]===_0x10948f[_0x3b3ab9(0x2fa)]){_0x4bb952[_0x3b3ab9(0x2fa)]=_0x5c7053;break;}}}else _0x4bb952[_0x3b3ab9(0x2fa)]=![];_0x512fd8=!![],mustUpdateuserList=!![];}}if(_0x3b3ab9(0x1d8)in _0x10948f){_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5c3)][_0x3b3ab9(0x1d8)]={};_0x3b3ab9(0x3e3)in _0x10948f&&(_0x3b3ab9(0x577)===_0x3b3ab9(0x311)?_0x2abbe3[_0x3b3ab9(0x448)][_0x3b3ab9(0x3a5)](_0x27b3b5):_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5c3)]['sensors'][_0x3b3ab9(0x3e3)]=_0x10948f['lin']);_0x3b3ab9(0x389)in _0x10948f&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5c3)][_0x3b3ab9(0x1d8)][_0x3b3ab9(0x389)]=_0x10948f[_0x3b3ab9(0x389)]);_0x3b3ab9(0x1d9)in _0x10948f&&(_0x4bb952['rpcs'][_0x1ba910]['stats'][_0x3b3ab9(0x1d8)][_0x3b3ab9(0x1d9)]=_0x10948f[_0x3b3ab9(0x1d9)]);_0x3b3ab9(0x46d)in _0x10948f&&(_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x5c3)][_0x3b3ab9(0x1d8)][_0x3b3ab9(0x46d)]=_0x10948f['mag']);if(isIFrame){if('NfPoG'!==_0x3b3ab9(0x5ee))parent[_0x3b3ab9(0x544)]({'sensors':_0x10948f},'*');else{_0x363012(_0x3b3ab9(0x4e6),![],_0x17cbe2),_0x4a04b4[_0x3b3ab9(0x1dc)](),_0x314e22('send\x20channel\x20closed');try{_0x4a4370[_0x3b3ab9(0x347)][_0x3ee15c][_0x3b3ab9(0x5cd)](),_0x1fb3b3['pcs'][_0x54bfc0]=null,delete _0x1cc639[_0x3b3ab9(0x347)][_0x6c1ce0],_0x5d7021();}catch(_0x4e1c39){}}}}_0x3b3ab9(0x29c)in _0x10948f&&playbackMIDI(_0x10948f[_0x3b3ab9(0x29c)]);_0x3b3ab9(0x425)in _0x10948f&&(_0x3b3ab9(0x388)===_0x3b3ab9(0x388)?updateRemoteRecordButton(_0x1ba910,_0x10948f[_0x3b3ab9(0x425)]):_0x5424a7[_0x3b3ab9(0x575)]&&(_0x208be7[_0x3b3ab9(0x1e0)]=_0x400eb6[_0x3b3ab9(0x575)]));if(_0x3b3ab9(0x20f)in _0x10948f){warnlog(_0x10948f),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5c3)][_0x3b3ab9(0x20f)]=_0x10948f[_0x3b3ab9(0x20f)];if(_0x3b3ab9(0x3c6)in _0x10948f['info']){typeof _0x10948f[_0x3b3ab9(0x20f)][_0x3b3ab9(0x3c6)]==_0x3b3ab9(0x5d7)?_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['label']=sanitizeLabel(_0x10948f[_0x3b3ab9(0x20f)]['label']):_0x3b3ab9(0x211)==='OWPSO'?_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x3c6)]=![]:_0x3aa361['ws'][_0x3b3ab9(0x2e0)]===_0x5e970e[_0x3b3ab9(0x40d)]&&(_0x16c51b['ws']=null,_0x41b1b5(()=>{var _0x4ad92b=_0x3b3ab9;_0x5cdf77[_0x4ad92b(0x4d0)](!![]);},0x1388));if(_0x4bb952[_0x3b3ab9(0x18f)]){var _0x3e20f5=getById(_0x3b3ab9(0x2f4)+_0x1ba910);_0x3e20f5&&(_0x3e20f5[_0x3b3ab9(0x1a2)]['float']=_0x3b3ab9(0x50c),_0x3e20f5['style'][_0x3b3ab9(0x193)]=_0x3b3ab9(0x486),_0x3e20f5['style'][_0x3b3ab9(0x1a7)]='5px',_0x3e20f5[_0x3b3ab9(0x1a2)]['position']='relative',_0x3e20f5[_0x3b3ab9(0x1a2)][_0x3b3ab9(0x1d7)]=_0x3b3ab9(0x504),_0x3e20f5[_0x3b3ab9(0x53e)][_0x3b3ab9(0x4ec)]=_0x1ba910,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x3c6)]?_0x3e20f5[_0x3b3ab9(0x216)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x3c6)]:_0x3e20f5[_0x3b3ab9(0x216)]=_0x3b3ab9(0x432),_0x3e20f5['onclick']=function(_0xa1b74d){var _0x1a845e=_0x3b3ab9,_0x358e8a=_0xa1b74d[_0x1a845e(0x58d)][_0x1a845e(0x216)];_0x4bb952[_0x1a845e(0x2c9)][_0xa1b74d[_0x1a845e(0x58d)][_0x1a845e(0x53e)]['UUID']][_0x1a845e(0x3c6)]===![]&&(_0x358e8a='');window[_0x1a845e(0x174)]();var _0x2142d7=prompt(_0x1a845e(0x3d5),_0x358e8a);if(_0x2142d7!==null){_0x2142d7==''?(_0x2142d7=![],_0xa1b74d[_0x1a845e(0x58d)][_0x1a845e(0x216)]=_0x1a845e(0x432)):_0xa1b74d[_0x1a845e(0x58d)][_0x1a845e(0x216)]=_0x2142d7;var _0x4aed7f={};_0x4aed7f[_0x1a845e(0x4ec)]=_0xa1b74d[_0x1a845e(0x58d)][_0x1a845e(0x53e)][_0x1a845e(0x4ec)],_0x4aed7f[_0x1a845e(0x48f)]=!![],_0x4aed7f['value']=_0x2142d7,_0x4bb952[_0x1a845e(0x261)](_0x4aed7f,_0x4aed7f[_0x1a845e(0x4ec)]);}});}}if(_0x3b3ab9(0x540)in _0x10948f['info']){_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x540)]=parseInt(_0x10948f[_0x3b3ab9(0x20f)][_0x3b3ab9(0x540)])||0x0;if(_0x4bb952[_0x3b3ab9(0x18f)]){if(_0x3b3ab9(0x3b4)===_0x3b3ab9(0x3b4)){var _0x2f651f=document['querySelectorAll']('[data-action-type=\x22order-value\x22][data--u-u-i-d=\x22'+_0x1ba910+'\x22]');_0x2f651f[0x0]&&(_0x2f651f[0x0][_0x3b3ab9(0x216)]=_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['order']);}else _0x6ff06c[_0x3b3ab9(0x2fa)]=!![];}}else _0x3b3ab9(0x59a)==='WMiLi'?_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x540)]=0x0:(!(_0x3b3ab9(0x319)in _0x3b88f4[_0x3b3ab9(0x2c9)][_0x12ee40][_0x3b3ab9(0x5c3)][_0x5bc99d[_0x3b3ab9(0x1fb)]])&&(_0x444c36[_0x3b3ab9(0x2c9)][_0x409b82]['stats'][_0x2a4ca1[_0x3b3ab9(0x1fb)]]['_packetsLost']=_0x119a75['packetsLost']),!(_0x3b3ab9(0x527)in _0x34a709[_0x3b3ab9(0x2c9)][_0x24b386][_0x3b3ab9(0x5c3)][_0x59a756['trackId']])&&(_0x42afae[_0x3b3ab9(0x2c9)][_0x5894a0][_0x3b3ab9(0x5c3)][_0x405587[_0x3b3ab9(0x1fb)]][_0x3b3ab9(0x527)]=_0x4eccb6['packetsReceived']),!(_0x3b3ab9(0x499)in _0x23eaa1[_0x3b3ab9(0x2c9)][_0x2bd1c7][_0x3b3ab9(0x5c3)][_0x40ba0d[_0x3b3ab9(0x1fb)]])&&(_0x1a98ef[_0x3b3ab9(0x2c9)][_0x2e8d25][_0x3b3ab9(0x5c3)][_0x42a792[_0x3b3ab9(0x1fb)]][_0x3b3ab9(0x499)]=0x0),_0xf6696c[_0x3b3ab9(0x2c9)][_0x5ecb9f][_0x3b3ab9(0x5c3)][_0x1b7182[_0x3b3ab9(0x1fb)]][_0x3b3ab9(0x499)]=_0x2735f0[_0x3b3ab9(0x2c9)][_0x41fe7f][_0x3b3ab9(0x5c3)][_0x1acda6[_0x3b3ab9(0x1fb)]][_0x3b3ab9(0x499)]*0.35+0.65*((_0x1f154c[_0x3b3ab9(0x414)]-_0x1d0a0c[_0x3b3ab9(0x2c9)][_0x20a57c][_0x3b3ab9(0x5c3)][_0x374bc4[_0x3b3ab9(0x1fb)]][_0x3b3ab9(0x319)])*0x64)/(_0x5d53fd[_0x3b3ab9(0x25c)]-_0x1d5ac1[_0x3b3ab9(0x2c9)][_0x2852a0][_0x3b3ab9(0x5c3)][_0x7b7bf7[_0x3b3ab9(0x1fb)]]['_packetsReceived']+(_0x4ad800[_0x3b3ab9(0x414)]-_0x3674a1['rpcs'][_0x207d58][_0x3b3ab9(0x5c3)][_0x4086b4[_0x3b3ab9(0x1fb)]][_0x3b3ab9(0x319)]))||0x0,_0x4c065b[_0x3b3ab9(0x2c9)][_0x9e8d2f][_0x3b3ab9(0x5c3)][_0x1df0c3[_0x3b3ab9(0x1fb)]][_0x3b3ab9(0x527)]=_0xac9979[_0x3b3ab9(0x25c)],_0x11e8d4[_0x3b3ab9(0x2c9)][_0x2822dc][_0x3b3ab9(0x5c3)][_0x161b58['trackId']][_0x3b3ab9(0x319)]=_0x3b3f43['packetsLost']);if(_0x4bb952[_0x3b3ab9(0x18f)]){if(_0x3b3ab9(0x429)in _0x10948f['info']){if(_0x10948f['info'][_0x3b3ab9(0x429)]==![]){var _0x2f651f=document['querySelectorAll']('[data-action-type=\x22mute-guest\x22][data--u-u-i-d=\x22'+_0x1ba910+'\x22]');_0x2f651f[0x0]&&(_0x2f651f[0x0][_0x3b3ab9(0x5d1)]=!![],_0x2f651f[0x0][_0x3b3ab9(0x3f2)]=_0x3b3ab9(0x27a));var _0x2f651f=document[_0x3b3ab9(0x557)]('[data-action-type=\x22volume\x22][data--u-u-i-d=\x22'+_0x1ba910+'\x22]');_0x2f651f[0x0]&&(_0x2f651f[0x0][_0x3b3ab9(0x5d1)]=!![],_0x2f651f[0x0][_0x3b3ab9(0x3f2)]=_0x3b3ab9(0x27a),_0x2f651f[0x0][_0x3b3ab9(0x1a2)][_0x3b3ab9(0x2eb)]=0.2);}}if(_0x3b3ab9(0x515)in _0x10948f[_0x3b3ab9(0x20f)]){if(_0x10948f[_0x3b3ab9(0x20f)][_0x3b3ab9(0x515)]!==![]){var _0x5d9f51=parseInt(_0x10948f[_0x3b3ab9(0x20f)][_0x3b3ab9(0x515)])||0x0;if(_0x5d9f51===0x0){var _0x2f651f=document['querySelectorAll']('[data-action-type=\x22mute-guest\x22][data--u-u-i-d=\x22'+_0x1ba910+'\x22]');_0x2f651f[0x0]&&(_0x2f651f[0x0][_0x3b3ab9(0x53e)][_0x3b3ab9(0x554)]=0x1,_0x2f651f[0x0][_0x3b3ab9(0x491)]=_0x3b3ab9(0x238),_0x2f651f[0x0][_0x3b3ab9(0x164)][0x1][_0x3b3ab9(0x172)]=_0x3b3ab9(0x1c4),_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x1ac)]=0x1);}else{if(_0x3b3ab9(0x253)===_0x3b3ab9(0x253)){var _0x2f651f=document[_0x3b3ab9(0x557)](_0x3b3ab9(0x464)+_0x1ba910+'\x22]');_0x2f651f[0x0]&&(_0x2f651f[0x0][_0x3b3ab9(0x554)]=_0x5d9f51,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4eb)]=_0x5d9f51,remoteVolumeUI(_0x2f651f[0x0]));}else _0x1c659=_0x132345[_0x3b3ab9(0x545)];}}}}_0x3b3ab9(0x3df)in _0x10948f[_0x3b3ab9(0x20f)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5a1)]=_0x10948f[_0x3b3ab9(0x20f)][_0x3b3ab9(0x3df)],_0x4bb952[_0x3b3ab9(0x24c)]===![]&&(_0x4bb952[_0x3b3ab9(0x1e0)]&&(!_0x4bb952[_0x3b3ab9(0x52d)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)]?_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x5a1)]?_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x2ef)]['style'][_0x3b3ab9(0x232)]=_0x3b3ab9(0x3e8):_0x4bb952['rpcs'][_0x1ba910]['remoteMuteElement'][_0x3b3ab9(0x1a2)][_0x3b3ab9(0x232)]=_0x3b3ab9(0x54d):(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)]=getById(_0x3b3ab9(0x5fb))[_0x3b3ab9(0x194)](!![]),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)]['id']='remoteMuteState_'+_0x1ba910,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['remoteMuteState']?_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)]['style']['display']=_0x3b3ab9(0x3e8):_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x2ef)][_0x3b3ab9(0x1a2)][_0x3b3ab9(0x232)]=_0x3b3ab9(0x54d),_0x512fd8=!![])))));_0x3b3ab9(0x4b3)in _0x10948f[_0x3b3ab9(0x20f)]&&(_0x4bb952[_0x3b3ab9(0x18f)]&&(_0x10948f[_0x3b3ab9(0x20f)][_0x3b3ab9(0x4b3)]&&updateRemoteSpeakerMute(_0x1ba910)));if(_0x3b3ab9(0x25d)in _0x10948f[_0x3b3ab9(0x20f)]){if(_0x3b3ab9(0x1a5)!==_0x3b3ab9(0x1a5))return _0xb5eb88[_0x3b3ab9(0x41e)]!==![]?(_0x38ad1d(_0x3b3ab9(0x4f6)),_0x4d48fe=_0x7d8b75[_0x3b3ab9(0x2d0)](0x0,-0x1*_0x50e562[_0x3b3ab9(0x41e)][_0x3b3ab9(0x28f)]),_0x4f84ca):(_0x39e467(_0x3b3ab9(0x3e2)+_0x2f665a),_0x343932['generateHash'](_0x21f7d4[_0x3b3ab9(0x208)]+_0x42cf39[_0x3b3ab9(0x558)],0x6)[_0x3b3ab9(0x3f8)](function(_0x236706){var _0x421594=_0x3b3ab9;return _0x26a05f['hash']=_0x236706,_0x453bde(_0x4f58ef),_0x2ddf12=_0x41946c[_0x421594(0x2d0)](0x0,-0x1*_0x452d83[_0x421594(0x41e)][_0x421594(0x28f)]),_0x31ead1(_0x421594(0x595)+_0x4a35cd),_0xcb9698;}));else _0x4bb952[_0x3b3ab9(0x18f)]&&(_0x10948f['info'][_0x3b3ab9(0x25d)]&&updateRemoteDisplayMute(_0x1ba910));}_0x3b3ab9(0x377)in _0x10948f[_0x3b3ab9(0x20f)]&&(_0x4bb952['director']?_0x10948f[_0x3b3ab9(0x20f)]['directorVideoMuted']&&updateDirectorVideoMute(_0x1ba910):(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x377)]=_0x10948f[_0x3b3ab9(0x20f)]['directorVideoMuted'],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x377)]&&(_0x1ba910 in _0x4bb952['rpcs']&&_0x4bb952[_0x3b3ab9(0x5bc)](0x0,_0x1ba910))));_0x3b3ab9(0x24f)in _0x10948f[_0x3b3ab9(0x20f)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['videoMuted']=_0x10948f['info'][_0x3b3ab9(0x24f)],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['videoMuted']&&('CqswD'==='JNhuu'?(_0x2f3a31[_0x3b3ab9(0x3ea)][0x0][_0x3b3ab9(0x5da)]==![]&&(_0x274c6d[_0x3b3ab9(0x3ea)][0x0][_0x3b3ab9(0x5da)]=!![]),_0x28c1fa[_0x3b3ab9(0x3ea)][0x0][_0x3b3ab9(0x484)]=_0x3ae6cc*0x400):_0x4bb952[_0x3b3ab9(0x18f)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4f9)]['style'][_0x3b3ab9(0x232)]=_0x3b3ab9(0x3e8))));if(_0x1ba910===_0x4bb952[_0x3b3ab9(0x266)])try{_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['stats']['info'][_0x3b3ab9(0x18f)]=!![];}catch(_0x86dd88){}mustUpdateuserList=!![];}if(_0x3b3ab9(0x433)in _0x10948f){if(_0x4bb952[_0x3b3ab9(0x266)]===_0x1ba910){_0x3b3ab9(0x4d5)in _0x10948f[_0x3b3ab9(0x433)]&&(_0x4bb952[_0x3b3ab9(0x4d5)]=parseInt(_0x10948f[_0x3b3ab9(0x433)][_0x3b3ab9(0x4d5)])||0x0,_0x512fd8=!![]);if(_0x10948f[_0x3b3ab9(0x433)][_0x3b3ab9(0x26b)]){if(_0x10948f[_0x3b3ab9(0x433)][_0x3b3ab9(0x26b)]===_0x4bb952[_0x3b3ab9(0x4e8)])_0x4bb952[_0x3b3ab9(0x2fa)]=!![];else for(var _0x5c7053 in _0x4bb952[_0x3b3ab9(0x2c9)]){if(_0x4bb952[_0x3b3ab9(0x2c9)][_0x5c7053][_0x3b3ab9(0x4e8)]===_0x10948f[_0x3b3ab9(0x433)][_0x3b3ab9(0x26b)]){_0x4bb952[_0x3b3ab9(0x2fa)]=_0x5c7053;break;}}_0x512fd8=!![],mustUpdateuserList=!![];}if(_0x4bb952['scene']!==![]){if(_0x10948f[_0x3b3ab9(0x433)]['scene'])for(var _0x5c7053 in _0x10948f[_0x3b3ab9(0x433)][_0x3b3ab9(0x24c)]){setTimeout(function(_0x15de86){_0x4bb952['directorActions'](_0x15de86);},0x3e8,_0x10948f['directorSettings'][_0x3b3ab9(0x24c)][_0x5c7053]);}if(_0x10948f['directorSettings'][_0x3b3ab9(0x32c)])for(var _0x5c7053 in _0x10948f[_0x3b3ab9(0x433)][_0x3b3ab9(0x32c)]){setTimeout(function(_0x2a1d6e){var _0x26a8d7=_0x3b3ab9;_0x26a8d7(0x286)!==_0x26a8d7(0x286)?_0x1df1a2['audio']=!![]:_0x4bb952[_0x26a8d7(0x22f)](_0x2a1d6e);},0x3e8,_0x10948f[_0x3b3ab9(0x433)][_0x3b3ab9(0x32c)][_0x5c7053]);}}}}_0x4bb952[_0x3b3ab9(0x266)]===_0x1ba910&&(_0x4bb952[_0x3b3ab9(0x24c)]!==![]&&(_0x3b3ab9(0x17f)in _0x10948f&&_0x4bb952[_0x3b3ab9(0x22f)](_0x10948f)));if(_0x3b3ab9(0x540)in _0x10948f){_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['order']=parseInt(_0x10948f[_0x3b3ab9(0x540)])||0x0;_0x1ba910 in _0x4bb952[_0x3b3ab9(0x347)]&&(_0x4bb952[_0x3b3ab9(0x347)][_0x1ba910][_0x3b3ab9(0x540)]=parseInt(_0x10948f[_0x3b3ab9(0x540)])||0x0);if(_0x4bb952[_0x3b3ab9(0x18f)]){var _0x2f651f=document[_0x3b3ab9(0x557)]('[data-action-type=\x22order-value\x22][data--u-u-i-d=\x22'+_0x1ba910+'\x22]');if(_0x2f651f[0x0]){if(_0x3b3ab9(0x394)==='soglD')return _0x99533c[_0x3b3ab9(0x5b3)]&&_0x49aa3d[_0x3b3ab9(0x5b3)][_0x3b3ab9(0x20c)]=='video';else _0x2f651f[0x0][_0x3b3ab9(0x216)]=parseInt(_0x10948f[_0x3b3ab9(0x540)])||0x0;}}_0x512fd8=!![];}if('changeLabel'in _0x10948f){log(_0x3b3ab9(0x37f));if(_0x3b3ab9(0x554)in _0x10948f){log(_0x3b3ab9(0x452));if(typeof _0x10948f[_0x3b3ab9(0x554)]==_0x3b3ab9(0x5d7)){_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['label']=sanitizeLabel(_0x10948f['value']);_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x3c6)][_0x3b3ab9(0x28f)]==0x0&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['label']=![]);if(_0x4bb952[_0x3b3ab9(0x18f)]){var _0x2f651f=getById(_0x3b3ab9(0x2f4)+_0x1ba910);_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['label']?_0x3b3ab9(0x1e9)===_0x3b3ab9(0x1e9)?_0x2f651f[_0x3b3ab9(0x216)]=_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x3c6)]:_0x2487de(_0x3b3ab9(0x2ab)):_0x2f651f[_0x3b3ab9(0x216)]=_0x3b3ab9(0x432);}else _0x4bb952['showlabels']&&(_0x512fd8=!![]);}else{_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x3c6)]=![];if(_0x4bb952[_0x3b3ab9(0x18f)]){var _0x2f651f=getById('label_'+_0x1ba910);_0x2f651f[_0x3b3ab9(0x216)]=_0x3b3ab9(0x432);}else _0x4bb952[_0x3b3ab9(0x3b1)]&&(_0x3b3ab9(0x580)===_0x3b3ab9(0x46e)?(delete _0x391056[_0x3b3ab9(0x413)][_0x534a20],_0x39978a('watchTimeoutList2:'+_0x49b1e7),_0x5646bb[_0x3b3ab9(0x360)](_0x3be8c7)):_0x512fd8=!![]);}mustUpdateuserList=!![];}}_0x3b3ab9(0x592)in _0x10948f&&(log(_0x10948f),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['remoteMuteState']=_0x10948f[_0x3b3ab9(0x592)],_0x4bb952['requestRateLimit'](![],_0x1ba910),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5c3)][_0x3b3ab9(0x20f)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5c3)][_0x3b3ab9(0x20f)]['muted']=_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x5a1)]),_0x4bb952[_0x3b3ab9(0x24c)]===![]&&(_0x3b3ab9(0x44c)!==_0x3b3ab9(0x44c)?_0x474e26('4722'):_0x4bb952[_0x3b3ab9(0x1e0)]&&(!_0x4bb952['cleanOutput']&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)]?_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5a1)]?_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)]['style']['display']=_0x3b3ab9(0x3e8):_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)][_0x3b3ab9(0x1a2)]['display']=_0x3b3ab9(0x54d):(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)]=getById(_0x3b3ab9(0x5fb))[_0x3b3ab9(0x194)](!![]),_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x2ef)]['id']=_0x3b3ab9(0x49f)+_0x1ba910,_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x5a1)]?_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x2ef)][_0x3b3ab9(0x1a2)]['display']=_0x3b3ab9(0x3e8):_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['remoteMuteElement']['style'][_0x3b3ab9(0x232)]=_0x3b3ab9(0x54d),_0x512fd8=!![]),mustUpdateuserList=!![]))));if('requestSceneUpdate'in _0x10948f){var _0x14e15c=getChromeVersion();_0x14e15c&&(_0x14e15c<0x50&&(_0x512fd8=!![]));}_0x3b3ab9(0x55b)in _0x10948f&&(_0x3b3ab9(0x21f)===_0x3b3ab9(0x179)?_0x4a7922[_0x3b3ab9(0x22f)](_0x13a690):(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x55b)]=_0x10948f[_0x3b3ab9(0x55b)],!_0x4bb952['director']?(_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x55b)]&&(_0x4bb952['requestRateLimit'](0x0,_0x1ba910),_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x220)]&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x220)][_0x3b3ab9(0x5dc)]=!![],_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910]['imageElement'][_0x3b3ab9(0x1a2)][_0x3b3ab9(0x202)]=_0x3b3ab9(0x5dc))),_0x512fd8=!![]):_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x55b)]?_0x4bb952['rpcs'][_0x1ba910][_0x3b3ab9(0x4f9)][_0x3b3ab9(0x1a2)][_0x3b3ab9(0x232)]='inline-block':_0x4bb952[_0x3b3ab9(0x2c9)][_0x1ba910][_0x3b3ab9(0x4f9)]['style']['display']='none',mustUpdateuserList=!![]));if(_0x3b3ab9(0x24e)in _0x10948f){if(!_0x4bb952[_0x3b3ab9(0x18f)]){if(_0x3b3ab9(0x58d)in _0x10948f){if(_0x4bb952[_0x3b3ab9(0x266)]===_0x1ba910){var _0x9217cb=_0x10948f['target'];if(_0x9217cb===!![])_0x4bb952[_0x3b3ab9(0x377)]=_0x10948f[_0x3b3ab9(0x24e)];else _0x9217cb in _0x4bb952['rpcs']&&(_0x4bb952[_0x3b3ab9(0x2c9)][_0x9217cb][_0x3b3ab9(0x377)]=_0x10948f[_0x3b3ab9(0x24e)],_0x4bb952[_0x3b3ab9(0x2c9)][_0x9217cb]['directorVideoMuted']&&(_0x9217cb in _0x4bb952['rpcs']&&_0x4bb952[_0x3b3ab9(0x5bc)](0x0,_0x9217cb)),_0x512fd8=!![]);}}}mustUpdateuserList=!![];}_0x3b3ab9(0x494)in _0x10948f&&(_0x3b3ab9(0x5f1)!==_0x3b3ab9(0x47b)?remoteStats(_0x10948f):_0x14368e[_0x3b3ab9(0x278)][_0x3b3ab9(0x213)][_0x3b3ab9(0x3bb)]()['forEach'](function(_0x2061f2){var _0xa23eed=_0x3b3ab9;_0x2061f2[_0xa23eed(0x3a4)](),_0x557313[_0xa23eed(0x487)][_0xa23eed(0x213)][_0xa23eed(0x5f4)](_0x2061f2),_0x488552(_0xa23eed(0x312));}));if(_0x512fd8)setTimeout(function(){updateMixer(),updateUserList();},0x1);else mustUpdateuserList&&updateUserList();},_0x4bb952[_0x14e5fb(0x2c9)][_0x1ba910][_0x14e5fb(0x4b2)][_0x14e5fb(0x1ef)]=()=>{var _0x4d07a5=_0x14e5fb;log(_0x4d07a5(0x2cc));try{var _0x204b94=_0x4bb952[_0x4d07a5(0x2c9)][_0x1ba910][_0x4d07a5(0x4e8)];}catch(_0x2ef8bf){}try{_0x4bb952['rpcs'][_0x1ba910]['close']();}catch(_0x1a249f){_0x4d07a5(0x205)!==_0x4d07a5(0x2bc)?errorlog(_0x4d07a5(0x2e8)):_0x292631[_0x4d07a5(0x170)](_0x5c42c0)[_0x4d07a5(0x3f8)]()['catch'](_0x330832=>{var _0x3db092=_0x4d07a5;_0x4a3689(_0x330832),_0x1b8f19[_0x3db092(0x557)](_0x3db092(0x2be)+_0x1708b5+'\x22]')[0x0][_0x3db092(0x1af)][_0x3db092(0x5e9)](_0x3db092(0x238));});}try{_0x4bb952['rpcs'][_0x1ba910][_0x4d07a5(0x45f)]&&_0x4bb952['rpcs'][_0x1ba910][_0x4d07a5(0x45f)]['getTracks']()[_0x4d07a5(0x35e)](function(_0x5b9408){var _0x439788=_0x4d07a5;_0x5b9408[_0x439788(0x3a4)](),log(_0x439788(0x221));});}catch(_0xe99615){}if(_0x4bb952[_0x4d07a5(0x18f)])try{_0x4d07a5(0x425)in _0x4bb952[_0x4d07a5(0x2c9)][_0x1ba910][_0x4d07a5(0x487)]&&_0x4bb952[_0x4d07a5(0x2c9)][_0x1ba910][_0x4d07a5(0x487)][_0x4d07a5(0x425)][_0x4d07a5(0x3a4)]();}catch(_0x22097e){warnlog(_0x22097e);}try{document[_0x4d07a5(0x54a)]('container_'+_0x1ba910)&&('hWDcJ'===_0x4d07a5(0x296)?getById('container_'+_0x1ba910)[_0x4d07a5(0x506)]['removeChild'](getById(_0x4d07a5(0x3ab)+_0x1ba910)):_0x1240e2(_0x4d07a5(0x410)));}catch(_0x58acc6){warnlog(_0x58acc6);}try{_0x4bb952[_0x4d07a5(0x2c9)][_0x1ba910]=null,delete _0x4bb952[_0x4d07a5(0x2c9)][_0x1ba910];}catch(_0x27bdc3){}!_0x4bb952[_0x4d07a5(0x18f)]&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x204b94==_0x4d07a5(0x1fe))return;try{warnlog(_0x4d07a5(0x22e)),_0x204b94 in _0x4bb952[_0x4d07a5(0x413)]&&(log(_0x4d07a5(0x453)+_0x204b94),clearTimeout(_0x4bb952[_0x4d07a5(0x413)][_0x204b94])),_0x4bb952[_0x4d07a5(0x413)][_0x204b94]=setTimeout(function(_0x2dba39){var _0x5f3746=_0x4d07a5;delete _0x4bb952[_0x5f3746(0x413)][_0x2dba39],log(_0x5f3746(0x5be)+_0x2dba39),_0x4bb952['watchStream'](_0x2dba39);},_0x4bb952['retryTimeout'],_0x204b94);}catch(_0x283f93){errorlog(_0x283f93);}pokeIframeAPI(_0x4d07a5(0x405),![],_0x1ba910),updateUserList();};},_0x4bb952[_0xc05fdc(0x521)]=function(_0x34e2ab){var _0x2091c2=_0xc05fdc;try{var _0x310ecc=_0x4bb952[_0x2091c2(0x46c)]||0x0;_0x310ecc=parseFloat(_0x310ecc);if(_0x4bb952[_0x2091c2(0x46c)]!==![]){var _0x3f7542=_0x4bb952[_0x2091c2(0x2c9)][_0x34e2ab][_0x2091c2(0x468)]()[_0x2091c2(0x184)](),_0x5748f8=0x0;_0x3f7542[_0x2091c2(0x35e)](function(_0x288dd1){var _0x4cbe4c=_0x2091c2;try{for(var _0x499485 in _0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)]){if(typeof _0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab]['stats'][_0x499485]=='object'&&_0x4cbe4c(0x22b)in _0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485]&&_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x22b)]===_0x288dd1[_0x4cbe4c(0x5b3)]['id']&&'Buffer_Delay_in_ms'in _0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab]['stats'][_0x499485]){var _0x187048=0x0;_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x400)]?_0x187048=_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab]['stats'][_0x499485][_0x4cbe4c(0x400)]:_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x400)]=0x0;_0x187048+=_0x310ecc-_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x1f3)];_0x187048>_0x310ecc&&(_0x187048=_0x310ecc);if(_0x4bb952['rpcs'][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x16e)]==_0x4cbe4c(0x169)){if(_0x288dd1[_0x4cbe4c(0x5b3)]['id']in _0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x3d8)]){log(_0x4cbe4c(0x4d6));var _0x2f4658=_0x5748f8-_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x1f3)]+_0x4bb952[_0x4cbe4c(0x5ef)];_0x2f4658<0x0&&(_0x2f4658=0x0),log('audio_delay\x20:\x20'+_0x2f4658),log(_0x4cbe4c(0x32e)+_0x4bb952[_0x4cbe4c(0x443)][_0x4cbe4c(0x406)]),_0x4bb952['rpcs'][_0x34e2ab][_0x4cbe4c(0x3d8)][_0x288dd1[_0x4cbe4c(0x5b3)]['id']][_0x4cbe4c(0x2f5)][_0x4cbe4c(0x4f1)](parseFloat(_0x2f4658/0x3e8),_0x4bb952[_0x4cbe4c(0x443)][_0x4cbe4c(0x406)]+0x1),_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x35c)]=_0x2f4658;}}else{if(_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x16e)]==_0x4cbe4c(0x195)){if(_0x4cbe4c(0x2cb)===_0x4cbe4c(0x2cb))_0x5748f8=_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab][_0x4cbe4c(0x5c3)][_0x499485][_0x4cbe4c(0x1f3)],_0x187048<0x0&&(_0x187048=0x0),_0x4bb952[_0x4cbe4c(0x2c9)][_0x34e2ab]['stats'][_0x499485][_0x4cbe4c(0x400)]=_0x187048,_0x288dd1[_0x4cbe4c(0x246)]=parseFloat(_0x187048/0x3e8);else return _0x360ad3(_0x4cbe4c(0x4c5)),![];}}}}}catch(_0x55ad47){errorlog(_0x55ad47);}});}}catch(_0x5c3529){if('rajNc'===_0x2091c2(0x1f6))errorlog('device\x20does\x20not\x20support\x20playout\x20delay');else{var _0xf25dcc=_0x77f543?function(){var _0x5619d9=_0x2091c2;if(_0x209997){var _0x5ebe23=_0x990197[_0x5619d9(0x361)](_0x83e0b4,arguments);return _0x58f9f2=null,_0x5ebe23;}}:function(){};return _0x460aa1=![],_0xf25dcc;}}},_0x4bb952['processStats']=function(_0x55a039){var _0xdac073=_0xc05fdc;if(!(_0x55a039 in _0x4bb952[_0xdac073(0x2c9)]))return;try{_0x4bb952[_0xdac073(0x2c9)][_0x55a039][_0xdac073(0x487)][_0xdac073(0x275)]&&(log(_0xdac073(0x52b)),_0x4bb952[_0xdac073(0x2c9)][_0x55a039][_0xdac073(0x487)]['play']()[_0xdac073(0x3f8)](_0x59b0a5=>{var _0x415e89=_0xdac073;if(_0x415e89(0x1f1)===_0x415e89(0x1f1))log('playing'),firstPlayTriggered=!![];else{if(_0x415e89(0x5b3)in _0x4ef04a){var _0x3f660f=_0x1c37c4(_0x5ecd7e['track']);_0x3f660f<_0x21a9a0[_0x415e89(0x28f)]&&(_0x48a1df=_0x5916ba[_0x3f660f],_0x26f43e(_0x2882b0[_0x415e89(0x257)],_0x49c0cf[_0x415e89(0x554)]));}else _0x4962ca=_0x46f729[0x0],_0x4990df(_0xd90927[_0x415e89(0x257)],_0x1ed0ba[_0x415e89(0x554)]);}})[_0xdac073(0x5fa)](warnlog));}catch(_0x456599){};try{_0x4bb952[_0xdac073(0x2c9)][_0x55a039]['getStats']()['then'](function(_0x55e089){var _0x48e64b=_0xdac073;_0x48e64b(0x563)!==_0x48e64b(0x563)?(_0x556cc2(function _0x69c558(){var _0x40c768=_0x48e64b;_0x49c7d7[_0x40c768(0x5bc)](![],_0x1bb3b7);},0x1388),_0x1ddb70(_0x48e64b(0x344))):(setTimeout(_0x4bb952['processStats'],0xbb8,_0x55a039),!_0x4bb952[_0x48e64b(0x2c9)][_0x55a039][_0x48e64b(0x5c3)][_0x48e64b(0x531)]&&(_0x4bb952['rpcs'][_0x55a039][_0x48e64b(0x5c3)]['RTC\x20Connection']={}),_0x55e089[_0x48e64b(0x35e)](_0x365c92=>{var _0x52de4a=_0x48e64b;if(_0x365c92['type']==_0x52de4a(0x537)&&_0x365c92[_0x52de4a(0x248)]==!![])_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x4ab)]=_0x365c92[_0x52de4a(0x200)],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x543)]=_0x365c92[_0x52de4a(0x287)],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x5e4)]=_0x365c92[_0x52de4a(0x3e0)]*0x3e8;else{if(_0x365c92[_0x52de4a(0x2e9)]==_0x52de4a(0x5b3)&&_0x365c92[_0x52de4a(0x1cf)]==!![]){if(_0x365c92['id']in _0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)])_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['id']][_0x52de4a(0x22b)]=_0x365c92['trackIdentifier'],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['id']][_0x52de4a(0x1f3)]=parseInt(0x3e8*(parseFloat(_0x365c92[_0x52de4a(0x2f2)])-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92['id']][_0x52de4a(0x23d)])/(parseInt(_0x365c92[_0x52de4a(0x1b5)])-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['id']][_0x52de4a(0x5fd)]))||0x0,_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['id']][_0x52de4a(0x23d)]=parseFloat(_0x365c92[_0x52de4a(0x2f2)])||0x0,_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92['id']][_0x52de4a(0x5fd)]=parseInt(_0x365c92['jitterBufferEmittedCount'])||0x0,_0x52de4a(0x258)in _0x365c92&&(_0x52de4a(0x55e)in _0x365c92&&(_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['id']][_0x52de4a(0x364)]=_0x365c92[_0x52de4a(0x258)]+_0x52de4a(0x3fa)+_0x365c92[_0x52de4a(0x55e)],_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['id']][_0x52de4a(0x538)]=_0x365c92[_0x52de4a(0x258)],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['id']]['_frameHeight']=_0x365c92[_0x52de4a(0x55e)]));else{var _0x49590c={};_0x49590c[_0x52de4a(0x23d)]=parseFloat(_0x365c92[_0x52de4a(0x2f2)])||0x0,_0x49590c[_0x52de4a(0x5fd)]=parseInt(_0x365c92[_0x52de4a(0x1b5)])||0x0,_0x49590c[_0x52de4a(0x1f3)]=0x0,_0x49590c[_0x52de4a(0x22b)]=_0x365c92[_0x52de4a(0x384)],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92['id']]=_0x49590c;}}else{if(_0x365c92[_0x52de4a(0x2e9)]==_0x52de4a(0x300)){if(_0x52de4a(0x543)in _0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x52de4a(0x531)]&&_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats']['RTC\x20Connection'][_0x52de4a(0x543)]!=_0x365c92['id'])return;'relayProtocol'in _0x365c92&&('ip'in _0x365c92&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x52de4a(0x531)][_0x52de4a(0x2d1)]=_0x365c92['ip']),_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)]['remote_relayProtocol']=_0x365c92[_0x52de4a(0x438)]),'candidateType'in _0x365c92&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x52de4a(0x531)][_0x52de4a(0x236)]=_0x365c92[_0x52de4a(0x4e0)]),_0x52de4a(0x320)in _0x365c92&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x3fb)]=_0x365c92[_0x52de4a(0x320)]);}else{if(_0x365c92[_0x52de4a(0x2e9)]==_0x52de4a(0x21e)){if(_0x52de4a(0x4ab)in _0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)]&&_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats']['RTC\x20Connection'][_0x52de4a(0x4ab)]!=_0x365c92['id'])return;_0x52de4a(0x438)in _0x365c92&&('ip'in _0x365c92&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)]['local_relayIP']=_0x365c92['ip']),_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)]['RTC\x20Connection'][_0x52de4a(0x54e)]=_0x365c92[_0x52de4a(0x438)]),'candidateType'in _0x365c92&&(_0x4bb952['rpcs'][_0x55a039]['stats'][_0x52de4a(0x531)][_0x52de4a(0x5d5)]=_0x365c92[_0x52de4a(0x4e0)]),'networkType'in _0x365c92&&(_0x4bb952['rpcs'][_0x55a039]['stats']['RTC\x20Connection'][_0x52de4a(0x3fb)]=_0x365c92[_0x52de4a(0x320)]);}else{if(_0x365c92[_0x52de4a(0x2e9)]==_0x52de4a(0x1ec)){if(_0x52de4a(0x571)in _0x365c92){if(_0x52de4a(0x456)!==_0x52de4a(0x456)){_0x44432e[_0x52de4a(0x3c6)]=![];var _0x199a0f={};_0x199a0f['changeLabel']=!![],_0x199a0f[_0x52de4a(0x554)]=_0x137278[_0x52de4a(0x3c6)],_0x487659[_0x52de4a(0x2ed)](_0x199a0f);if(_0x1d6bbd['director']){var _0x230bce=_0x1725cc(_0x52de4a(0x2f4)+_0x509ff4);_0x230bce['innerText']=_0x52de4a(0x432);}else _0x1b1c56[_0x52de4a(0x3b1)]?(_0x5bb19e[_0x52de4a(0x3f2)]=_0x38dff3[_0x52de4a(0x356)],_0x1b07e9()):_0xa55987[_0x52de4a(0x3f2)]=_0x2b83f2[_0x52de4a(0x356)];}else _0x52de4a(0x231)in _0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)]&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)]['RTC\x20Connection'][_0x52de4a(0x288)]&&(_0x365c92[_0x52de4a(0x1c6)]&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x5e8)]=parseInt(0x8*(_0x365c92[_0x52de4a(0x571)]-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x231)])/(_0x365c92['timestamp']-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x288)]))))),_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)]['RTC\x20Connection']['_bytesReceived']=_0x365c92['bytesReceived'];}if(_0x52de4a(0x1c6)in _0x365c92){_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)]['_timestamp']=_0x365c92[_0x52de4a(0x1c6)];if(!_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)]['_timestampStart']){if(_0x52de4a(0x398)!==_0x52de4a(0x398))return;else _0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x5e1)]=_0x365c92[_0x52de4a(0x1c6)];}else _0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x52de4a(0x531)][_0x52de4a(0x582)]=parseInt((_0x365c92[_0x52de4a(0x1c6)]-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x531)][_0x52de4a(0x5e1)])/0x258)/0x64;}}else{if(_0x365c92[_0x52de4a(0x2e9)]==_0x52de4a(0x505)&&_0x52de4a(0x1fb)in _0x365c92){if('jTAUD'===_0x52de4a(0x31b)){_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']]=_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']]||{},_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x318)]=parseInt(0x8*(_0x365c92[_0x52de4a(0x571)]-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x304)])/(_0x365c92[_0x52de4a(0x1c6)]-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x528)])),_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x304)]=_0x365c92[_0x52de4a(0x571)]||_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x304)],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x528)]=_0x365c92[_0x52de4a(0x1c6)]||_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x528)],_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)]['_codecId']=_0x365c92[_0x52de4a(0x596)],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)]['_codecIdTrackId']=_0x365c92[_0x52de4a(0x1fb)];if(_0x365c92[_0x52de4a(0x2d8)]==_0x52de4a(0x195)){_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x2e9)]='Video\x20Track',_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]]['_type']=_0x52de4a(0x195);if(_0x4bb952['obsfix']&&_0x52de4a(0x529)in _0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)]&&_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x52de4a(0x529)]==_0x52de4a(0x48a)){_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x224)]=_0x365c92[_0x52de4a(0x50d)]-_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x39b)]||0x0,_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x5a7)]=_0x365c92[_0x52de4a(0x434)]-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]]['streamErrors_nackCount']+_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x5a7)]||0x0,log(_0x52de4a(0x498));if(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']][_0x52de4a(0x224)]===0x0&&_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x5a7)]>=_0x4bb952['obsfix'])_0x4bb952[_0x52de4a(0x2fc)](_0x55a039),_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x5a7)]=0x0,log('TRYING\x20KEYFRAME');else _0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x224)]>0x0&&('TPrjA'===_0x52de4a(0x5ab)?this[_0x52de4a(0x45f)]&&this[_0x52de4a(0x45f)][_0x52de4a(0x3bb)]()[_0x52de4a(0x35e)](function(_0x363df2){var _0x18705e=_0x52de4a;_0x363df2[_0x18705e(0x3a4)](),_0x4a6933(_0x18705e(0x221));}):_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x5a7)]=0x0);}else{if(_0x4bb952[_0x52de4a(0x539)]&&_0x52de4a(0x529)in _0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)]&&_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x529)]==_0x52de4a(0x162)){_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x224)]=_0x365c92[_0x52de4a(0x50d)]-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92['trackId']]['keyFramesRequested_pli']||0x0,_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']][_0x52de4a(0x5a7)]=_0x365c92[_0x52de4a(0x434)]-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x56d)]+_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']][_0x52de4a(0x5a7)]||0x0,log(_0x52de4a(0x498));if(_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']][_0x52de4a(0x224)]===0x0&&_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']][_0x52de4a(0x5a7)]>=_0x4bb952[_0x52de4a(0x539)]*0x4)_0x4bb952[_0x52de4a(0x2fc)](_0x55a039),_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x5a7)]=0x0,log(_0x52de4a(0x4ba));else _0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]]['pliDelta']>0x0&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x5a7)]=0x0);}}_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92['trackId']][_0x52de4a(0x39b)]=_0x365c92['pliCount']||0x0,_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]]['streamErrors_nackCount']=_0x365c92['nackCount']||0x0;if(_0x52de4a(0x1f9)in _0x365c92)_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x42a)]=parseInt(_0x365c92['framesPerSecond']);else{if(_0x52de4a(0x301)in _0x365c92&&_0x365c92['timestamp']){var _0x3140bd=0x0,_0x45fa0b=0x0;try{_0x3140bd=_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x593)],_0x45fa0b=_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x288)];}catch(_0x37741c){}_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']][_0x52de4a(0x42a)]=parseInt(0xa*(_0x365c92[_0x52de4a(0x301)]-_0x3140bd)/(_0x365c92[_0x52de4a(0x1c6)]/0x3e8-_0x45fa0b))/0xa,_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x593)]=_0x365c92[_0x52de4a(0x301)],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]]['_timestamp']=_0x365c92['timestamp']/0x3e8;}}}else _0x365c92['mediaType']==_0x52de4a(0x169)&&(_0x4bb952['rpcs'][_0x55a039]['stats'][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x2e9)]='Audio\x20Track',_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x16e)]=_0x52de4a(0x169),_0x52de4a(0x281)in _0x365c92&&(_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x386)]=parseInt(parseFloat(_0x365c92[_0x52de4a(0x281)])*0x2710)/0x2710));_0x52de4a(0x414)in _0x365c92&&_0x52de4a(0x25c)in _0x365c92&&(!('_packetsLost'in _0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]])&&(_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x319)]=_0x365c92[_0x52de4a(0x414)]),!(_0x52de4a(0x527)in _0x4bb952['rpcs'][_0x55a039]['stats'][_0x365c92['trackId']])&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x527)]=_0x365c92[_0x52de4a(0x25c)]),!(_0x52de4a(0x499)in _0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92[_0x52de4a(0x1fb)]])&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]]['packetLoss_in_percentage']=0x0),_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92['trackId']]['packetLoss_in_percentage']=_0x4bb952['rpcs'][_0x55a039]['stats'][_0x365c92['trackId']]['packetLoss_in_percentage']*0.35+0.65*((_0x365c92[_0x52de4a(0x414)]-_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x319)])*0x64)/(_0x365c92[_0x52de4a(0x25c)]-_0x4bb952['rpcs'][_0x55a039]['stats'][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x527)]+(_0x365c92[_0x52de4a(0x414)]-_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x319)]))||0x0,_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x365c92['trackId']][_0x52de4a(0x527)]=_0x365c92[_0x52de4a(0x25c)],_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x365c92[_0x52de4a(0x1fb)]][_0x52de4a(0x319)]=_0x365c92[_0x52de4a(0x414)]);}else return;}else _0x52de4a(0x3b6)in _0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)]&&_0x365c92['id']==_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)]['_codecId']&&('mimeType'in _0x365c92&&(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x4bb952[_0x52de4a(0x2c9)][_0x55a039]['stats'][_0x52de4a(0x53c)]]?_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x53c)]]['codec']=_0x365c92[_0x52de4a(0x225)]:(_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x53c)]]={},_0x4bb952[_0x52de4a(0x2c9)][_0x55a039][_0x52de4a(0x5c3)][_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)]['_codecIdTrackId']][_0x52de4a(0x529)]=_0x365c92['mimeType'])),_0x52de4a(0x55e)in _0x365c92&&('frameWidth'in _0x365c92&&(_0x4bb952['rpcs'][_0x55a039][_0x52de4a(0x5c3)][_0x52de4a(0x364)]=parseInt(_0x365c92['frameWidth'])+'\x20x\x20'+parseInt(_0x365c92[_0x52de4a(0x55e)]))));}}}}}}),_0x4bb952[_0x48e64b(0x46c)]!==![]&&_0x4bb952[_0x48e64b(0x521)](_0x55a039),setTimeout(function(){var _0x20928=_0x48e64b;_0x4bb952[_0x20928(0x51f)](),_0x4bb952[_0x20928(0x24d)]();},0x0));});}catch(_0x27d8e5){errorlog(_0x27d8e5);}},_0x4bb952[_0xc05fdc(0x2c9)][_0x1ba910][_0xc05fdc(0x33b)]=_0x5478d2=>{var _0x313bd5=_0xc05fdc;log(_0x313bd5(0x31e));_0x4bb952[_0x313bd5(0x46c)]!==![]&&_0x4bb952['playoutdelay'](_0x1ba910);_0x4bb952[_0x313bd5(0x51f)](),_0x4bb952[_0x313bd5(0x24d)]();if(_0x5478d2[_0x313bd5(0x5ec)]&&_0x5478d2[_0x313bd5(0x5ec)][0x0]){_0x5478d2[_0x313bd5(0x5ec)][0x0][_0x313bd5(0x55a)]=function(_0x13c241){var _0x56110f=_0x313bd5;try{warnlog(_0x56110f(0x358)),_0x4bb952[_0x56110f(0x2c9)][_0x1ba910][_0x56110f(0x45f)][_0x56110f(0x546)]()[_0x56110f(0x35e)](_0x48acaf=>{var _0x5a1e20=_0x56110f;_0x48acaf['id']==_0x13c241[_0x5a1e20(0x5b3)]['id']&&_0x4bb952[_0x5a1e20(0x2c9)][_0x1ba910][_0x5a1e20(0x45f)][_0x5a1e20(0x5f4)](_0x48acaf);}),_0x4bb952[_0x56110f(0x2c9)][_0x1ba910][_0x56110f(0x487)]['srcObject']=_0x4bb952['rpcs'][_0x1ba910]['streamSrc'],setTimeout(function(){updateMixer();},0x1);}catch(_0x452ba8){}},_0x5478d2[_0x313bd5(0x5ec)][0x0][_0x313bd5(0x3d1)]=function(_0xbdfa06){var _0x4cc4b7=_0x313bd5;try{warnlog('track\x20made\x20inactive;\x20removing'),_0x4bb952[_0x4cc4b7(0x2c9)][_0x1ba910][_0x4cc4b7(0x45f)]['getVideoTracks']()['forEach'](_0x2b0b87=>{var _0x43c120=_0x4cc4b7;_0x2b0b87['id']==_0xbdfa06[_0x43c120(0x5b3)]['id']&&_0x4bb952['rpcs'][_0x1ba910][_0x43c120(0x45f)][_0x43c120(0x5f4)](_0x2b0b87);}),_0x4bb952[_0x4cc4b7(0x2c9)][_0x1ba910][_0x4cc4b7(0x487)]['srcObject']=_0x4bb952[_0x4cc4b7(0x2c9)][_0x1ba910][_0x4cc4b7(0x45f)];}catch(_0xc1d16f){};};var _0x3aa1ef=_0x5478d2['streams'][0x0][_0x313bd5(0x546)]()[_0x313bd5(0x28f)];_0x3aa1ef>0x1&&errorlog(_0x313bd5(0x59e));}if(_0x4bb952['rpcs'][_0x1ba910][_0x313bd5(0x487)]){if(_0x5478d2[_0x313bd5(0x5ec)]&&_0x5478d2['streams'][0x0]){if(!_0x4bb952['rpcs'][_0x1ba910][_0x313bd5(0x45f)])_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)]=_0x5478d2[_0x313bd5(0x5ec)][0x0];else{var _0x116067=![];_0x5478d2[_0x313bd5(0x5ec)][0x0]['getTracks']()[_0x313bd5(0x35e)](_0x23ed83=>{var _0x5f487f=_0x313bd5;_0x116067&&(warnlog(_0x5f487f(0x492)),warnlog(_0x23ed83)),_0x23ed83[_0x5f487f(0x20c)]==_0x5f487f(0x195)&&(_0x5f487f(0x435)!==_0x5f487f(0x1dd)?(_0x4bb952[_0x5f487f(0x2c9)][_0x1ba910][_0x5f487f(0x45f)][_0x5f487f(0x546)]()[_0x5f487f(0x35e)](_0x5189df=>{var _0x3beb52=_0x5f487f;_0x4bb952[_0x3beb52(0x2c9)][_0x1ba910]['streamSrc'][_0x3beb52(0x5f4)](_0x5189df);}),_0x116067=!![]):_0x2c8d1d(_0x5f487f(0x3b0))),log('adding\x20track'),_0x4bb952[_0x5f487f(0x2c9)][_0x1ba910][_0x5f487f(0x45f)][_0x5f487f(0x40e)](_0x23ed83);});}try{_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x487)][_0x313bd5(0x213)]=_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)];}catch(_0x1dcee7){errorlog('4722');}log(_0x313bd5(0x20e));}else{if(_0x5478d2[_0x313bd5(0x5b3)]){warnlog(_0x313bd5(0x335));!_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910]['streamSrc']?_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)]=new MediaStream():_0x313bd5(0x199)===_0x313bd5(0x199)?_0x5478d2['track'][_0x313bd5(0x20c)]==_0x313bd5(0x195)&&_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)][_0x313bd5(0x546)]()[_0x313bd5(0x35e)](_0x55ffac=>{var _0x2fd6f2=_0x313bd5;_0x4bb952['rpcs'][_0x1ba910][_0x2fd6f2(0x45f)]['removeTrack'](_0x55ffac);}):(_0x3a610e(_0x3c67f0+'\x20is\x20not\x20defined;\x20skipping.'),_0x3734b7=_0x545c18[_0x313bd5(0x190)](_0x313bd5(0x4d2)));_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)]['addTrack'](_0x5478d2[_0x313bd5(0x5b3)]);try{_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x487)][_0x313bd5(0x213)]=_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)];}catch(_0x4f698c){errorlog('4722');}}else errorlog(_0x313bd5(0x4b0));}setTimeout(function(){updateMixer();},0x1);}else{log(_0x313bd5(0x463));var _0x33c8f5=document[_0x313bd5(0x190)](_0x313bd5(0x195));_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910]['videoElement']=_0x33c8f5,_0x33c8f5[_0x313bd5(0x53e)][_0x313bd5(0x4ec)]=_0x1ba910,_0x33c8f5['id']=_0x313bd5(0x2ca)+_0x1ba910;_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x4e8)]&&(_0x33c8f5['dataset'][_0x313bd5(0x399)]=_0x4bb952['rpcs'][_0x1ba910]['streamID']);setupIncomingVideoTracking(_0x33c8f5,_0x1ba910);if(_0x5478d2[_0x313bd5(0x5ec)]&&_0x5478d2[_0x313bd5(0x5ec)][0x0]){var _0x4f51c3=_0x5478d2[_0x313bd5(0x5ec)][0x0];_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)]=_0x5478d2[_0x313bd5(0x5ec)][0x0],_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x487)][_0x313bd5(0x213)]=_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)],log(_0x313bd5(0x20e));}else _0x5478d2[_0x313bd5(0x5b3)]&&(_0x313bd5(0x4ce)!==_0x313bd5(0x4ce)?_0x498366(_0x20624c):(warnlog(_0x313bd5(0x335)),!_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910]['streamSrc']&&(_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)]=new MediaStream()),_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)][_0x313bd5(0x40e)](_0x5478d2['track']),_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x487)][_0x313bd5(0x213)]=_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x45f)]));if(_0x4bb952[_0x313bd5(0x2ee)]){var _0x568d75={};_0x568d75[_0x313bd5(0x2ee)]=parseInt(_0x4bb952[_0x313bd5(0x2ee)]),log(_0x568d75),_0x4bb952['sendRequest'](_0x568d75,_0x1ba910);}}if(_0x4bb952[_0x313bd5(0x27b)]===!![]){var _0x595be2=function(_0x46b501){var _0x178582=function(_0xbb20d9){var _0xae631e=_0x3a98;if(!_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9]){if(_0xae631e(0x5b5)===_0xae631e(0x44d)){_0x42b7c9(_0xae631e(0x4fc));return;}else return;}var _0x5130d5=_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9][_0xae631e(0x487)][_0xae631e(0x3df)];_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9]['videoElement'][_0xae631e(0x3df)]=![],_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9][_0xae631e(0x487)][_0xae631e(0x167)](_0xae631e(0x31f),_0x178582);_0x4bb952[_0xae631e(0x443)][_0xae631e(0x467)]==_0xae631e(0x533)&&_0x4bb952[_0xae631e(0x443)][_0xae631e(0x478)]();var _0x5b2a28=_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9][_0xae631e(0x45f)][_0xae631e(0x2dd)]();if(_0x5b2a28[_0xae631e(0x28f)]){var _0x2521d3=_0x5b2a28[0x0];_0x2521d3['label']!=_0xae631e(0x3c8)&&(_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9]['videoElement']['srcObject']=addAudioPipeline(_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9][_0xae631e(0x45f)],_0xbb20d9,_0x2521d3));}else _0x4bb952[_0xae631e(0x2c9)][_0xbb20d9][_0xae631e(0x487)][_0xae631e(0x213)]=_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9]['streamSrc'];_0x4bb952[_0xae631e(0x2c9)][_0xbb20d9][_0xae631e(0x487)][_0xae631e(0x3df)]=_0x5130d5,delete _0x4bb952[_0xae631e(0x2c9)][_0xbb20d9][_0xae631e(0x309)];if('eventPlayActive'in _0x4bb952[_0xae631e(0x2c9)][_0xbb20d9]){if(_0xae631e(0x188)!=='YWPqY')errorlog(_0xae631e(0x44b));else try{_0x4c581e[_0xae631e(0x347)][_0x358ee0][_0xae631e(0x5cd)]();}catch(_0x4cc6d7){}}};return _0x178582(_0x46b501);};_0x4bb952[_0x313bd5(0x443)][_0x313bd5(0x467)]==_0x313bd5(0x4a9)&&(_0x4bb952['firstPlayTriggered']=!![]);if(_0x313bd5(0x309)in _0x4bb952[_0x313bd5(0x2c9)][_0x1ba910]){}else _0x4bb952[_0x313bd5(0x5f7)]==![]?_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x309)]=setInterval(function(_0x11bafa){var _0x1b9bfe=_0x313bd5;log(_0x1b9bfe(0x512)),_0x4bb952[_0x1b9bfe(0x2c9)][_0x11bafa]&&(_0x4bb952[_0x1b9bfe(0x5f7)]&&(clearInterval(_0x4bb952[_0x1b9bfe(0x2c9)][_0x11bafa][_0x1b9bfe(0x309)]),_0x4bb952[_0x1b9bfe(0x2c9)][_0x11bafa]['videoElement']['addEventListener'](_0x1b9bfe(0x31f),_0x595be2(_0x11bafa))));},0x3e8,_0x1ba910):(!_0x4bb952['rpcs'][_0x1ba910][_0x313bd5(0x309)]&&(_0x4bb952['rpcs'][_0x1ba910][_0x313bd5(0x309)]=!![]),_0x4bb952[_0x313bd5(0x2c9)][_0x1ba910][_0x313bd5(0x487)]['addEventListener'](_0x313bd5(0x31f),_0x595be2(_0x1ba910)));}_0x4bb952[_0x313bd5(0x51f)](),_0x4bb952[_0x313bd5(0x24d)](),updateUserList();},log(_0xc05fdc(0x4ea));},_0x4bb952;}(); \ No newline at end of file