\
-
\
-
" + soloLink + "\
-
copy Solo link\
-
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 = '
Scene: '+scene+'';
- 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 + "\
-
copy Solo link\
-
\
-
\
- \
- Lower Raised Hand \
- \
-
";
-
- 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://obs.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://obs.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://obs.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
- }
- getById("advanced_audio_director_" + UUID).appendChild(audioSelect);
- getById("advanced_audio_director_" + UUID).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 ((audioList[i].value == "default") && (session.echoCancellation !== false) && (session.autoGainControl !== false) && (session.noiseSuppression !== false)) {
- var constraint = {
- audio: true
- };
- } 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{
- session.rpcs[UUID].videoElement.pause().then(() => {
- setTimeout(function(uuid) {
- 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/', '');
- }
-
- 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 (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 {
- const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] });
-
- const selectionElem = document.createElement('div');
- selectionElem.classList = 'desktop-capturer-selection';
- selectionElem.innerHTML = `
-
- `;
- 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() {
- warnUser(err);
- }, 1); // 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();
- 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 ((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();},0);
- }
-
- 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();
-
-};
-
-
-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.obs.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==="")){
-
- if (session.fullscreen){
- session.windowed = false;
- } else {
- v.className = "myVideo";
- session.windowed = true;
- }
- getById("mutespeakerbutton").classList.add("advanced");
-
- 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 {
-
- if (session.fullscreen){
- session.windowed = false;
- } else {
- v.className = "myVideo";
- session.windowed = true;
- }
- getById("mutespeakerbutton").classList.add("advanced");
-
- 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();},0);
- }
-
- 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);
- window.addEventListener("orientationchange", updateMixer);
- 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";
- 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);
- } else if (session.roomid!==false){
- if (session.roomid===""){
- if (!(session.view) || (session.view==="")){
-
- if (session.fullscreen){
- session.windowed = false;
- } else {
- v.className = "myVideo clean";
- 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);
- }
- } 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);
- }
- } else {
-
-
- if (session.fullscreen){
- session.windowed = false;
- } else {
- v.className = "myVideo clean";
- 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";
- iframe.allowtransparency = "true";
- iframe.allowfullscreen = "true";
- 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";
- iframe.allowtransparency = "true";
- iframe.allowfullscreen = "true";
- 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://obs.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;
-
-function setupClosedCaptions() {
- 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");
- };
- Recognition.onerror = function(event) {
- errorlog(event);
- try {
- Recognition.stop();
- } catch (e) {}
- setTimeout(function() {
- setupClosedCaptions();
- }, 0); // restart it if it fails.
- };
- Recognition.onend = function(e) {
- warnlog(e);
- log("Stopped transcription");
- setTimeout(function() {
- setupClosedCaptions();
- }, 0); // restart it if it fails.
- };
-
- 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) && (session.audioDevice !== 1)) { // 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;
- session.iframeEle = null;
- 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;
-
- var iframe = document.createElement("iframe");
- iframe.allow="autoplay;camera;microphone;fullscreen;picture-in-picture";
- iframe.allowtransparency="true";
- iframe.allowfullscreen ="true";
- iframe.src = session.iframeSrc;
- iframe.id = "iframe_source"
- session.iframeEle = iframe;
-
- 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";
- 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(input.dataset.param);
- if (input.checked) {
-
- getById("director_block_" + arg).dataset.raw += input.dataset.param;
-
- var string = getById("director_block_" + arg).dataset.raw;
-
- if (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 (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(input.dataset.param);
- if (!(input.checked)) {
-
- getById("director_block_" + arg).dataset.raw += input.dataset.param;
-
- var string = getById("director_block_" + arg).dataset.raw;
-
- if (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 (getById("obfuscate_director_" + arg).checked) {
- string = obfuscateURL(string);
- }
-
- getById("director_block_" + arg).href = string;
- getById("director_block_" + arg).innerText = string;
- }
-}
-
-function updateLinkScene(arg, input) {
- 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 (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 = ' \
- and don\'t forget theOBS Browser Source Link: ' + viewstr + ' \
- \
- This invite link and OBS ingestion link are reusable. Only one person may use a specific invite at a time. Create Another Invite Link ';
- 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 = ' Scene: '+scene+' ';
- 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 = ' Scene: '+scene+' ';
- getById("container_" + UUID).appendChild(newScene);
- }
-
- if (session.showDirector){
- if (document.getElementById("container_director")){
- var newScene = document.createElement("div");
- newScene.innerHTML = ' Scene: '+scene+' ';
- 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. Retry Manually ';
-
- }
- }
- } 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=OBS.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 {
- 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));
-
-});
-
-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;
- }
-
- 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 = "auto";
- textOverlay.style.textAlign = "left";
- textOverlay.style.display = "block";
- textOverlay.style.position = "relative";
- }
- 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");
- 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();}
-}
-
-
-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)];
- 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();
- }
- }
- }
- });
- 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("OBSN 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]);
- }
- }
- }
- }
- });
- }
- });
- };
- 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);}
- }
- }
- } else if (session.midiIn==parseInt(session.midiIn)){
- try {
- var i = parseInt(session.midiIn);
- 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];
-}
-
-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.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();
-});
-
-
-// Warns user about network going down
-window.addEventListener("offline", function (e) {
- if ((session.view) && (session.permaid === false)) {
- log( "OBS.Ninja has no network connectivity and can't work properly." );
- } else if (session.scene !== false) {
- log( "OBS.Ninja has no network connectivity and can't work properly." );
- } else if (!session.cleanOutput) {
- warnUser("Network connection lost.");
- } else {
- log("OBS.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."
- );
- }
- });
+/*
+* Copyright (c) 2020 Steve Seguin. All Rights Reserved.
+*
+* Use of this source code is governed by the APGLv3 open-source license
+* that can be found in the LICENSE file in the root of the source
+* tree. Alternative licencing options can be made available on request.
+*
+*/
+/*jshint esversion: 6 */
+
+var formSubmitting = true;
+var activatedPreview = false;
+
+
+// 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;
+ }
+ }
+ }
+ 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 =
+ `
+
`;
+ 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.");
+ }
+ }
+ } 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 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;
+}
+document.addEventListener("visibilitychange", function() {
+ log(document.hidden, document.visibilityState);
+ if ((iOS) || (iPad)) { // fixes a bug on iOS devices. Not need with other devices?
+ if (document.visibilityState === 'visible') {
+ setTimeout(function() {
+ resetupAudioOut();
+ }, 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;}
+
+ 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();
+ }
+
+ } 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 (!(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 = "";
+ }
+ }
+ }
+
+ 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.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 && 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 && 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 || ondeck){ // BASIC TALLY LIGHT
+ 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;
+} 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");
+ getById("controlButtons").style.display = "inherit";
+ }
+}
+
+if (session.screenshare == true) {
+ 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');
+ 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 (session.password) {
+ session.password = sanitizePassword(session.password);
+ getById("passwordRoom").value = session.password;
+ session.defaultPassword = false;
+ getById("addPasswordBasic").style.display = "none";
+}
+
+
+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.)");
+ 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 {
+ 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.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 (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 (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();
+ }
+
+ //var supportedConstraints = navigator.mediaDevices.getSupportedConstraints();
+ //supportedConstraints.channelCount;
+
+ 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 (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;
+}
+
+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')) {
+ log("OBS feedback disabled");
+ session.disableOBS = true;
+}
+
+
+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')) {
+ 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;
+ }
+ }
+
+ 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) {
+ setTimeout(function() {
+ publishScreen();
+ }, 2000);
+ }
+}
+
+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 style = document.createElement('style');
+ style.innerHTML = `
+ video {
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=), none;
+ user-select: none;
+ }
+ `;
+ document.head.appendChild(style);
+
+}
+
+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;
+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('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 (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;
+}
+
+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 = "";
+ 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 (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);
+ }
+
+ 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('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);
+ }
+ } catch (e) {
+ if (!(session.cleanOutput)) {
+ warnUser("TURN server parameters were wrong.");
+ }
+ 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...
+ }
+ } 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);
+ }
+
+ 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) {
+ 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);
+ }
+ }
+ }
+ } 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);
+ }
+ }
+ }
+
+ }
+
+ if (session.pip){
+ v.onloadedmetadata = function(){
+ if (!v.paused){
+ if (!(v.pip)){
+ v.pip=true;
+ toggleSystemPip(v, true);
+ }
+ }
+ }
+ }
+
+
+ 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 (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 (session.fadein){
+ 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 (session.director){return;}
+ if (session.manual === true){return;}
+ var playarea = getById("gridlayout");
+ 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].targetBandwidth0){
+ if (session.nopreview!==false){
+ mediaPool = []; // we don't want to show our self-preview if in broadcast mode and there is a director.
+ }
+ }
+ }
+
+ if (roomQuality === 0){roomQuality=1;}
+
+ var totalRoomBitrate = session.totalRoomBitrate;
+ if ((session.controlRoomBitrate!==false) && (session.controlRoomBitrate!==true)){
+ totalRoomBitrate = Math.min(session.controlRoomBitrate, totalRoomBitrate);
+ }
+
+ roomQuality = parseInt(totalRoomBitrate/roomQuality);
+ //if (roomQuality<20){
+ // roomQuality=20;
+ //}
+
+ for (var i in session.rpcs){
+ if (session.rpcs[i]===null){continue;}
+
+ if (session.rpcs[i].iframeEle){
+ if (session.rpcs[i].order!==false){
+ session.rpcs[i].iframeEle.order=session.rpcs[i].order;
+ } else {
+ session.rpcs[i].iframeEle.order=0;
+ }
+ if (session.activeSpeaker && (!session.rpcs[i].activelySpeaking)){
+ mediaPool_invisible.push(session.rpcs[i].iframeEle);
+ } else {
+ mediaPool.push(session.rpcs[i].iframeEle);
+ }
+
+ if (session.rpcs[i].videoElement){
+ if (!(session.rpcs[i].videoElement in mediaPool_invisible)){
+ mediaPool_invisible.push(session.rpcs[i].videoElement);
+ }
+ session.requestRateLimit(0, i);
+ }
+
+ continue;
+ }
+
+ if (session.rpcs[i].imageElement){
+ //if (session.rpcs[i].videoElement.srcObject.getVideoTracks().length==0){ // video shouldn't be on if images are on.
+
+ if (session.rpcs[i].videoElement){ // is there audio?
+ mediaPool_invisible.push(session.rpcs[i].videoElement); // include audio as hidden track;
+ }
+
+ if (session.rpcs[i].videoMuted){
+ continue;
+ } else if (session.rpcs[i].directorVideoMuted){
+ continue;
+ }
+
+ if (session.rpcs[i].order!==false){
+ session.rpcs[i].imageElement.order=session.rpcs[i].order;
+ } else {
+ session.rpcs[i].imageElement.order=0;
+ }
+ if (session.activeSpeaker && (!session.rpcs[i].activelySpeaking)){
+ // mediaPool_invisible.push(session.rpcs[i].imageElement);
+ } else {
+ mediaPool.push(session.rpcs[i].imageElement);
+ }
+
+ continue;
+ // } else {
+ // errorlog("Video track added while in webp streaming mode? wasted bandwidth / cpu ..")
+ // }
+ }
+
+ if (session.rpcs[i].videoElement){ // remote feeds
+
+ //session.rpcs[i].targetBandwidth = -1;
+ if (session.rpcs[i].videoElement.style.opacity==="0"){
+ continue;
+ }
+
+ try{
+ session.rpcs[i].videoElement.style.visibility = "visible";
+ } catch(e){}
+
+ if (session.directorUUID ===session.rpcs[i].UUID){ // director is never audio-only. Video if need, yes, but not visualized-audio.
+ if (session.rpcs[i].videoElement.srcObject.getVideoTracks().length==0){
+ //if (session.style==1){ // avatars and waveforms might be better done elsewhere? as a canvas effect even?
+ continue;
+ //}
+ }
+ } else if (session.style==2){
+ log("style = 2");
+ if (session.rpcs[i].videoElement.srcObject.getVideoTracks().length==0){
+ if (session.rpcs[i].canvas){
+ if (session.rpcs[i].order!==false){
+ session.rpcs[i].canvas.order=session.rpcs[i].order;
+ } else {
+ session.rpcs[i].canvas.order=0;
+ }
+
+ if (session.activeSpeaker && (!session.rpcs[i].activelySpeaking)){
+ mediaPool_invisible.push(session.rpcs[i].canvas);
+ } else {
+ mediaPool.push(session.rpcs[i].canvas);
+ }
+ }
+ continue;
+ }
+ } else if (session.style==1){
+ if (session.rpcs[i].videoElement.srcObject.getVideoTracks().length==0){
+ //if (session.style==1){ // avatars and waveforms might be better done elsewhere? as a canvas effect even?
+ continue;
+ //}
+ }
+ } else if (session.scene!==false){
+ if (session.rpcs[i].videoElement.srcObject.getVideoTracks().length==0){ // unless style==2, then scenes don't show audio.
+ //if (session.style==1){ // avatars and waveforms might be better done elsewhere? as a canvas effect even?
+ continue;
+ //}
+ }
+ }
+
+ if (session.rpcs[i].videoMuted){
+ continue;
+ } else if (session.rpcs[i].directorVideoMuted){
+ continue;
+ }
+
+ if (session.director){ // director video should be low-bitrate, although this should never fire.
+ warnlog("Update should not be called on DIRECTORs view? sorta at least"); // the director should never be called.
+ return;
+ } else if (session.rpcs[i].videoElement.style.display=="none"){ // Video is disabled; run at lowest
+ if (session.scene!==false){
+ session.requestRateLimit(session.hiddenSceneViewBitrate, i); // hidden. I dont want it to be super low, for video quality reasons.
+ if (!session.hiddenSceneViewBitrate){
+ session.rpcs[i].videoElement.classList.add("nogb");
+ }
+ } else {
+ session.requestRateLimit(0, i); // w/e This is not in OBS, so we just set it as low as possible. Shoudln't exist really unless loading?
+ }
+ } else if (session.scene!==false){ // max
+ session.requestRateLimit(-1, i); // unlock.
+ if (session.rpcs[i].order!==false){
+ session.rpcs[i].videoElement.order=session.rpcs[i].order;
+ } else {
+ session.rpcs[i].videoElement.order=0;
+ }
+ if (session.activeSpeaker && (!session.rpcs[i].activelySpeaking)){
+ if (!(session.rpcs[i].videoElement in mediaPool_invisible)){
+ mediaPool_invisible.push(session.rpcs[i].videoElement);
+ } else {
+ errorlog("THIS SHOULD NOT HAPPEN; 650");
+ }
+ } else {
+ mediaPool.push(session.rpcs[i].videoElement);
+ }
+ } else if (session.roomid!==false){ // guests should see video at low bitrate, ie: 100kbps (not 35kbps like if disabled)
+ if (session.rpcs[i].order!==false){
+ session.rpcs[i].videoElement.order=session.rpcs[i].order;
+ } else {
+ session.rpcs[i].videoElement.order=0;
+ }
+ if (session.activeSpeaker && (!session.rpcs[i].activelySpeaking)){
+ if (!(session.rpcs[i].videoElement in mediaPool_invisible)){
+ mediaPool_invisible.push(session.rpcs[i].videoElement);
+ } else {
+ errorlog("THIS SHOULD NOT HAPPEN; 665");
+ }
+ } else {
+ mediaPool.push(session.rpcs[i].videoElement);
+ }
+ if ((session.roomid==="") && (session.bitrate)){
+ // we will let the URL specified bitrate hold, since this isn't a real room.
+ session.requestRateLimit(-1, i);
+ } else {
+ session.requestRateLimit(roomQuality, i); // well, screw that. Setting it to room quality.
+ }
+ } else { // view=xx,yy or whatever. This should be highest quality.
+ if (session.rpcs[i].order!==false){
+ session.rpcs[i].videoElement.order=session.rpcs[i].order;
+ } else {
+ session.rpcs[i].videoElement.order=0;
+ }
+ if (session.activeSpeaker && (!session.rpcs[i].activelySpeaking)){
+ if (!(session.rpcs[i].videoElement in mediaPool_invisible)){
+ mediaPool_invisible.push(session.rpcs[i].videoElement);
+ } else {
+ errorlog("THIS SHOULD NOT HAPPEN; 684");
+ }
+ } else {
+ mediaPool.push(session.rpcs[i].videoElement);
+ }
+ session.requestRateLimit(-1, i);
+ }
+ }
+ }
+ }
+ if (session.director){return;} // director view says go no further :)
+
+ if (document.fullscreenElement) {
+ log("FULL SCREEN: "+document.fullscreenElement.id);
+ return; // This is FULL SCREEN, so let's not continue.
+ }
+
+ var mpl = mediaPool.length;
+ if (mpl>1){
+ var BB = 0;
+ var rw = 1;
+ var rh = 1;
+ var NW;
+ var NH;
+ var current;
+ for (NW=1; NW <= mpl; NW++){
+ NH = Math.ceil(mpl/NW);
+ var www = ww/NW;
+ var hhh = hh/NH;
+ if (www>hhh){
+ current = hhh * hhh * (mpl/(NW*NH));
+ } else {
+ current = www * www * (mpl/(NW*NH));
+ }
+
+ if (current>=BB){
+ BB = current;
+ rw = NW;
+ rh = NH;
+ }
+
+ }
+ } else { var rw=1; var rh=1;}
+
+
+ if (playarea.getElementsByTagName("iframe").length){
+
+ var childNodes = playarea.childNodes;
+
+ for (var n=0;n{
+ vid.style.width = "0px";
+ vid.style.height = "0px";
+ vid.style.top = "0px";
+ vid.style.left = "0px";
+ //vid.alreadyAdded=false; // what am I doing here? wtf? TODO: this is a typo, right?
+ if (vid.alreadyAdded && vid.alreadyAdded==true){
+ vid.alreadyAdded=false;
+ return;
+ } else if (vid.dataset.doNotMove){
+ return;
+ }
+ playarea.appendChild(vid);
+ });
+
+ mediaPool.sort(compare_vids);
+
+ mediaPool.forEach(vid=>{
+
+ var container = document.createElement("div");
+
+ container.style.position = "absolute";
+ container.style.display = "flex";
+ container.style.alignItems = "center";
+ offsetx=0;
+
+ if (i!==0){
+ if (Math.ceil((i+0.01)/rw)==rh){
+ if (mediaPool.length%rw){
+ offsetx = ((rw - mediaPool.length%rw)*(window.innerWidth/rw))/2;
+ }
+ }
+ }
+
+ offsety = (h- Math.ceil(mediaPool.length/rw)*Math.ceil(h/rh))/2;
+
+ if (vid.alreadyAdded && vid.alreadyAdded==true){
+ container = vid.parentNode;
+ }
+
+ container.style.left = offsetx+Math.floor(((i%rw)+0)*w/rw)+"px";
+ container.style.top = offsety+Math.floor((Math.floor(i/rw)+0)*h/rh + hi)+"px";
+ container.style.width = Math.ceil(w/rw)+"px";
+ container.style.height = Math.ceil(h/rh)+"px";
+
+ if (vid.alreadyAdded && vid.alreadyAdded==true){
+ vid.alreadyAdded=false;
+ i+=1;
+ return;
+ } else if (vid.dataset.doNotMove){
+ vid.style.position = "absolute";
+ vid.style.left = container.style.left;
+ vid.style.top = container.style.top;
+ vid.style.width = container.style.width;
+ vid.style.height = container.style.height;
+ vid.style.display = "flex";
+ i+=1;
+ return;
+ }
+
+
+ playarea.appendChild(container);
+
+ var wrw = Math.ceil(w/rw);
+ var hrh = Math.ceil(h/rh);
+
+ if (session.dynamicScale){
+ if (vid.dataset.UUID){
+ if (wrw && hrh){
+ if (session.devicePixelRatio){
+ session.requestResolution(vid.dataset.UUID, wrw * session.devicePixelRatio, hrh * session.devicePixelRatio);
+ } else if (window.devicePixelRatio && parseInt(window.devicePixelRatio) > 1 ){
+ session.requestResolution(vid.dataset.UUID, wrw*window.devicePixelRatio, hrh*window.devicePixelRatio);
+ } else {
+ session.requestResolution(vid.dataset.UUID, wrw, hrh);
+ }
+ }
+ }
+ }
+
+
+ //vid.style.objectFit = "contain"; // set by .tile now
+ //vid.classList="";
+ vid.style.maxWidth = "100%";
+ vid.style.maxHeight = "100%";
+ //vid.style.margin = "auto";
+
+ // Creates relative positioned element, important for label pos
+ var holder = document.createElement("div");
+ holder.className = "holder";
+ //holder.appendChild(vid);
+ container.appendChild(vid);
+ container.appendChild(holder);
+
+
+
+ if (vid.videoWidth && vid.videoHeight){
+ var asw = wrw/vid.videoWidth;
+ var ash = hrh/vid.videoHeight;
+
+ if (asw < ash){
+ holder.style.width = Math.ceil(vid.videoWidth*asw)+"px";
+ holder.style.height = Math.ceil(vid.videoHeight*asw)+"px";
+ holder.style.left = Math.ceil((Math.ceil(w/rw) - Math.ceil(vid.videoWidth*asw))/2);
+ holder.style.top = Math.ceil(( Math.ceil(h/rh) - Math.ceil(vid.videoHeight*asw))/2);
+ } else {
+ holder.style.width = Math.ceil(vid.videoWidth*ash)+"px";
+ holder.style.height = Math.ceil(vid.videoHeight*ash)+"px";
+ holder.style.left = Math.ceil((Math.ceil(w/rw) - Math.ceil(vid.videoWidth*ash))/2);
+ holder.style.top = Math.ceil((Math.ceil(h/rh) - Math.ceil(vid.videoHeight*ash))/2);
+ }
+ } else if (vid.width && vid.height){
+ var asw = wrw/vid.width;
+ var ash = hrh/vid.height;
+
+ if (asw < ash){
+ holder.style.width = Math.ceil(vid.width*asw)+"px";
+ holder.style.height = Math.ceil(vid.height*asw)+"px";
+ holder.style.left = Math.ceil((Math.ceil(w/rw) - Math.ceil(vid.width*asw))/2);
+ holder.style.top = Math.ceil(( Math.ceil(h/rh) - Math.ceil(vid.height*asw))/2);
+ } else {
+ holder.style.width = Math.ceil(vid.width*ash)+"px";
+ holder.style.height = Math.ceil(vid.height*ash)+"px";
+ holder.style.left = Math.ceil((Math.ceil(w/rw) - Math.ceil(vid.width*ash))/2);
+ holder.style.top = Math.ceil((Math.ceil(h/rh) - Math.ceil(vid.height*ash))/2);
+ }
+ } else if (wrw/hrh < arW/arH){
+ holder.style.width = "100%";
+ holder.style.height = "100%";
+ if (vid.tagName.toLowerCase()=="iframe"){
+ holder.style.height = "100%";
+ }
+ holder.style.left = 0;
+ holder.style.top = 0;
+
+ } else {
+ holder.style.width = "100%";
+ holder.style.height = "100%";
+ if (vid.tagName.toLowerCase()=="iframe"){
+ holder.style.width = "100%";
+ }
+ holder.style.left = 0;
+ holder.style.top = 0;
+ }
+
+ if (session.cover){
+ holder.style.width = "100%";
+ holder.style.height = "100%";
+ holder.style.left = 0;
+ holder.style.top = 0;
+ }
+
+ holder.style.position = "absolute";
+
+ vid.style.width = "100%";
+ vid.style.height = "100%";
+
+ var fontsize = (vid.offsetWidth + vid.offsetHeight)*0.03;
+ log("fontsize " +fontsize + " - " +vid.offsetWidth + " - " + vid.offsetHeight);
+ if (!fontsize){
+ if (vid.videoWidth/holder.offsetWidth > vid.videoHeight/holder.offsetHeight){
+ fontsize = (holder.offsetHeight + vid.videoHeight/holder.offsetHeight*vid.offsetWidth)*0.03;
+ } else {
+ fontsize = (holder.offsetWidth + vid.videoWidth/holder.offsetWidth*vid.offsetHeight)*0.03;
+ }
+ }
+ if (!fontsize){
+
+ fontsize = (holder.offsetWidth + holder.offsetHeight)*0.03;
+ }
+ log("fontsize final:" +fontsize);
+
+
+ if (vid.dataset.UUID && session.rpcs[vid.dataset.UUID].label !== false && session.showlabels===true){ // remote source
+
+ // creates a video label holder inside the recently created label holder
+ var label = document.createElement("span");
+ if (session.labelstyle){
+ label.className = 'video-label '+session.labelstyle;
+ } else {
+ label.className = 'video-label';
+ }
+ if (fontsize){
+ if (session.labelsize){
+ fontsize = fontsize*session.labelsize/100;
+ }
+ fontsize = parseInt(fontsize);
+ fontsize = fontsize+"px";
+ label.style.fontSize = fontsize;
+ }
+ label.innerText = session.rpcs[vid.dataset.UUID].label;
+ holder.appendChild(label);
+ } else if ((session.showlabels===true) && (vid.id === "videosource") && (session.label)){ // local source
+ // creates a label holder that's the same size of the vid element.
+
+ // creates a video label holder inside the recently created label holder
+ var label = document.createElement("span");
+ if (session.labelstyle){
+ label.className = 'video-label '+session.labelstyle;
+ } else {
+ label.className = 'video-label';
+ }
+ if (fontsize){
+ if (session.labelsize){
+ fontsize = fontsize*session.labelsize/100;
+ }
+ fontsize = parseInt(fontsize);
+ fontsize = fontsize+"px";
+ label.style.fontSize = fontsize;
+ }
+
+ label.innerText = sanitizeLabel(session.label);//.replace(/[\W]+/g,"_").replace(/_+/g, ' ');
+ holder.appendChild(label);
+ }
+
+ if (vid.dataset.UUID && session.rpcs[vid.dataset.UUID] && session.rpcs[vid.dataset.UUID].voiceMeter){
+ holder.appendChild(session.rpcs[vid.dataset.UUID].voiceMeter);
+
+ }
+ if (vid.dataset.UUID && session.rpcs[vid.dataset.UUID] && session.rpcs[vid.dataset.UUID].remoteMuteElement){
+ holder.appendChild(session.rpcs[vid.dataset.UUID].remoteMuteElement);
+ }
+ try {
+ if (!(session.cleanOutput && session.cleanish==false)){
+ if (session.firstPlayTriggered===false){ // don't play unless needed; might cause clicking or who knows what else.
+ warnlog("VIDEO IS NOT PLAYING");
+ if (vid.tagName.toLowerCase()=="video"){ // we don't want to try playing an Iframe or Canvas.
+ var playPromise = vid.play();
+ if (playPromise !== undefined){
+ playPromise.then(_ => {
+ // playing
+ session.firstPlayTriggered=true; // global tracking. "user gesture obtained", so no longer needed if playing.
+ }).catch((err)=>{
+
+ var bigPlayButton = document.getElementById("bigPlayButton");
+ if (bigPlayButton){
+ bigPlayButton.innerHTML = ' ';
+ bigPlayButton.style.display="block";
+ }
+ });
+ } else {
+ session.firstPlayTriggered=true; // well, I don't know if it's playing, and so whatever. fail gracefully.
+ }
+ }
+ }
+ }
+ } catch(e) {
+ log("VIDEO IS PLAYING");
+ var bigPlayButton = document.getElementById("bigPlayButton");
+ if (bigPlayButton){
+ bigPlayButton.parentNode.removeChild(bigPlayButton);
+ }
+
+ }
+
+ if (vid.tagName.toLowerCase()=="iframe"){ // I need to add this back in at some point.
+ i+=1;
+ return;
+ }
+
+ if (!session.cleanOutput && !session.nocursor){
+ if ((session.roomid!==false) && (session.scene===false)){
+ var button = document.createElement("div");
+ button.id = "button_"+vid.id;
+
+ if (session.infocus){
+ button.innerHTML = " ";
+ button.title = "Show all active videos togethers";
+ } else if (mediaPool.length>1){
+ button.innerHTML = " ";
+ button.title = "Enlarge video and increase its clarity";
+ } else {
+ button.style.visibility = "hidden";
+ }
+ button.style.transition = "opacity 0.3s"
+ button.style.width ="4vh";
+ button.style.height = "4vh";
+ button.style.maxWidth ="30px";
+ button.style.maxHeight = "30px";
+ button.style.minWidth ="15px";
+ button.style.minHeight = "15px";
+ button.style.position = "absolute";
+ button.style.display="none";
+ //button.style.opacity="10%";
+ button.style.zIndex="6";
+ button.style.right = "4vh";//(Math.ceil(w/rw) -30 - 30 + offsetx+Math.floor(((i%rw)+0)*w/rw))+"px";
+ button.style.top = "4vh";//( offsety + 30 + Math.floor((Math.floor(i/rw)+0)*h/rh + hi))+"px";
+ button.style.color = "white";
+ button.style.cursor = "pointer";
+
+
+ container.appendChild(button);
+ if (vid.id == "videosource"){
+ button.onclick = function(){
+ var target = event.currentTarget;
+ log(target);
+ if (session.infocus === true){
+ session.infocus = false;
+ //target.childNodes[0].className = 'las la-arrows-alt';
+ } else {
+ session.infocus = true;
+ log("session: myself");
+ //target.childNodes[0].className = 'las la-compress';
+ }
+ setTimeout(()=>updateMixer(),10);
+ };
+
+ } else {
+ button.dataset.UUID = vid.dataset.UUID;
+ button.onclick = function(event){
+ var target = event.currentTarget;
+ log("fullscreen");
+ log(target);
+ if (session.infocus === target.dataset.UUID){
+ //target.childNodes[0].className = 'las la-arrows-alt';
+ session.infocus = false;
+ } else {
+ //target.childNodes[0].className = 'las la-compress';
+ session.infocus = target.dataset.UUID;
+ //log("session:"+target.dataset.UUID);
+ }
+ setTimeout(()=>updateMixer(),10);
+ };
+
+ }
+ vid.onclick = function(){
+ button.style.display="block";
+ container.style.backgroundColor= "#4444";
+ button.style.opacity="100%";
+ };
+ button.onmouseenter = function(){
+ button.style.display="block";
+ container.style.backgroundColor= "#4444";
+ setTimeout(function(button){button.style.opacity="100%";},0,button);
+
+ };
+ container.onmouseenter = function(){
+ button.style.display="block";
+ container.style.backgroundColor= "#4444";
+ setTimeout(function(button){button.style.opacity="100%";},0,button);
+ };
+ container.onmouseleave = function(){
+ button.style.display="none";
+ container.style.backgroundColor= null;
+ button.style.opacity="10%";
+ };
+ }
+ }
+ i+=1;
+ });
+}
+
+
+var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
+var eventer = window[eventMethod];
+var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
+eventer(messageEvent, function(e) { // this listens for child IFRAMES.
+ if ("action" in e.data) {
+ if (e.data.action == "screen-share-ended") {
+ if (session.screenShareElement) {
+ if (e.source == session.screenShareElement.contentWindow) { // reject messages send from other iframes
+ warnlog(e);
+ 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");
+ }
+ }
+ }
+ }
+});
+
+
+function requestKeyframeScene(ele) {
+ var UUID = ele.dataset.UUID;
+ if (ele.dataset.value == 1) {
+ } else {
+ ele.dataset.value = 1;
+ ele.classList.add("pressed");
+ session.requestKeyframe(UUID, true);
+ setTimeout(function(el){
+ el.dataset.value = 0;
+ el.classList.remove("pressed");
+ }, 1000, ele)
+ }
+}
+
+function pokeIframeAPI(action, value = null, UUID = null) {
+ if (!isIFrame){return;}
+ try {
+ var data = {};
+
+ data.action = action;
+
+ if (value !== null) {
+ data.value = value;
+ }
+ if (UUID !== null) {
+ data.UUID = UUID;
+ }
+
+ if (isIFrame) {
+ parent.postMessage(data, "*");
+ }
+ } catch (e) {
+ errorlog(e);
+ }
+}
+
+function jumptoroom(event = null) {
+
+ if (event) {
+ if (event.which !== 13) {
+ return;
+ }
+ }
+
+ var arr = window.location.href.split('?');
+ var roomname = getById("joinroomID").value;
+ roomname = sanitizeRoomName(roomname);
+ if (roomname.length) {
+
+ var passStr = "";
+ window.focus();
+ var pass = prompt("Enter a password if provided, otherwise just click cancel"); //sanitizePassword(session.password);
+ if (pass && pass.length) {
+ session.password = sanitizePassword(pass);
+ passStr = "&password=" + session.password;
+ } else {
+ session.password = false;
+ }
+
+ if (arr.length > 1 && arr[1] !== '') {
+ window.location += "&room=" + roomname + passStr;
+ } else {
+ window.location += "?room=" + roomname + passStr;
+ }
+ }
+}
+
+function sleep(ms = 0) {
+ return new Promise(r => setTimeout(r, ms)); // LOLz!
+}
+
+////////// Canvas Effects ///////////////
+
+function drawFrameMirrored() {
+ session.canvasCtx.save();
+ session.canvasCtx.scale(-1, 1);
+ session.canvasCtx.drawImage(session.canvasSource, 0, 0, session.canvas.width * -1, session.canvas.height);
+ session.canvasCtx.restore();
+}
+
+function setupCanvas() {
+ if (session.canvas === null) {
+ warnlog("SETUP CANVAS");
+ session.canvas = document.createElement("canvas");
+ session.canvas.width = 512;
+ session.canvas.height = 288;
+ session.canvasCtx = session.canvas.getContext('2d', {alpha: false, desynchronized: true});
+ //session.canvasCtx.width=288;
+ //session.canvasCtx.height=720;
+ session.canvasCtx.fillStyle = "blue";
+ session.canvasCtx.fillRect(0, 0, 512, 288);
+ session.canvasSource = document.createElement("video");
+ session.canvasSource.width=512;
+ session.canvasSource.height=288;
+ session.canvasSource.autoplay = true;
+ session.canvasSource.srcObject = new MediaStream();
+ }
+}
+
+function applyEffects(track, stream) {
+
+ setupCanvas();
+
+ session.canvasSource.srcObject.addTrack(track, stream);
+ session.canvasSource.width = track.getSettings().width || 1280;
+ session.canvasSource.height = track.getSettings().height || 720;
+ session.canvas.width = track.getSettings().width || 1280;
+ session.canvas.height = track.getSettings().height || 720;
+
+ var audioTracks = session.streamSrc.getAudioTracks();
+ session.streamSrc = session.canvas.captureStream();
+ audioTracks.forEach(function(trk) {
+ session.streamSrc.addTrack(trk);
+ });
+ session.videoElement.srcObject = session.streamSrc;
+
+ if (session.effects == 1) { // auto align face
+ setTimeout(function() {
+ drawFace();
+ }, 100);
+ } else if (session.effects == 2) { // mirror video at a canvas level
+ var drawRate = parseInt(1000 / track.getSettings().frameRate) + 1;
+ if (session.canvasInterval !== null) {
+ clearInterval(session.canvasInterval);
+ }
+ session.canvasInterval = setInterval(function() {
+ drawFrameMirrored();
+ }, drawRate);
+ } else if ((session.effects == 3) || (session.effects == 4) || (session.effects == 5)){ // blur & greenscreen (low and high)
+ TFLiteWorker();
+ } else if (session.effects == 6){
+ session.canvasSource.onloadeddata = mainMeshMask;
+ }
+ return session.streamSrc.getVideoTracks()[0];
+}
+
+function dataURItoArraybuffer(dataURI) {
+ var byteString = atob(dataURI.split(',')[1]);
+ var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
+ var ab = new ArrayBuffer(byteString.length);
+ var ia = new Uint8Array(ab);
+ for (var i = 0; i < byteString.length; i++) {
+ ia[i] = byteString.charCodeAt(i);
+ }
+ return ab;
+}
+
+
+var makeImagesActive = null;
+var makeImagesTimeout = null;
+async function makeImages(startup=false){
+ if (makeImagesActive===true){return;}
+ if (!session.videoElement){return;}
+ if (session.videoMuted){return;}
+ if (!session.videoElement.srcObject.getVideoTracks().length){return;}
+
+ if (makeImagesActive===null){
+ makeImagesActive=true;
+ session.webPcanvas = document.createElement("canvas");
+
+ var width = 480;
+ var height = 270;
+ var timeout = 60;
+
+ if (session.webPquality===0){
+ width = 1920;
+ height = 1080;
+ timeout = 15;
+ } else if (session.webPquality===1){
+ width = 1280;
+ height = 720;
+ timeout = 15;
+ } else if (session.webPquality===2){
+ width = 640;
+ height = 360;
+ timeout = 15;
+ } else if (session.webPquality===3){
+ width = 480;
+ height = 270;
+ timeout = 15;
+ } else if (session.webPquality===4){
+ width = 480;
+ height = 270;
+ timeout = 30;
+ } else {
+ width = 480;
+ height = 270;
+ timeout = 60;
+ }
+ session.webPcanvas.width = width;
+ session.webPcanvas.height = height;
+ session.webPcanvas.timeout = timeout;
+ session.webPcanvasCtx = session.webPcanvas.getContext('2d', {alpha: false, desynchronized: true});
+ session.webPcanvasCtx.fillStyle = "black";
+ session.webPcanvasCtx.fillRect(0, 0, width, height);
+ } else {
+ makeImagesActive=true;
+ }
+
+ if (startup){
+ var exit = true;
+ for (var i in session.pcs){
+ if (session.pcs[i].allowBroadcast){ // just for safety, to avoid a race condition, double check that it's still not active.
+ exit = false;
+ }
+ }
+ if (exit){
+ makeImagesActive=false;
+ return;
+ }
+ }
+
+ try{
+ session.webPcanvasCtx.drawImage(session.videoElement, 0, 0, session.webPcanvas.width, session.webPcanvas.height);
+ const webp = session.webPcanvas.toDataURL("image/webp",0.6); // seems like a good balance here
+ const arrayBuffer = dataURItoArraybuffer(webp);
+ var broadcasting = false;
+ for (var i in session.pcs){
+ try{
+ if (session.pcs[i].allowBroadcast){ // only publish to those seeking this stream
+ broadcasting = true;
+ if (!session.pcs[i].sendChannel.bufferedAmount){ // only send when the buffer is free. don't clog it up or wait.
+ session.pcs[i].sendChannel.send(arrayBuffer);
+ }
+ }
+ } catch(e){}
+ }
+ } catch(e){
+ warnlog(e);
+ makeImagesActive=false;
+ return;
+ }
+ makeImagesActive=false;
+ if (broadcasting){ // cancel broadcasting since now one is active.
+ clearTimeout(makeImagesTimeout);
+ makeImagesTimeout = setTimeout(function(){
+ window.requestAnimationFrame(makeImages);
+ },session.webPcanvas.timeout);
+ } else {
+ for (var i in session.pcs){
+ if (session.pcs[i].allowBroadcast){ // just for safety, to avoid a race condition, double check that it's still not active.
+ clearTimeout(makeImagesTimeout);
+ makeImagesTimeout = setTimeout(function(){
+ window.requestAnimationFrame(makeImages);
+ },session.webPcanvas.timeout);
+ return;
+ }
+ }
+ log("Stopping webP broadcast.");
+ }
+}
+
+var updateUserListTimeout=null
+var updateUserListActive = false;
+function updateUserList(){
+ if ((session.showList!==true) && (session.cleanOutput || (session.scene!==false) || !session.roomid || session.director || (session.showList===false))){return;}
+ clearInterval(updateUserListTimeout);
+ updateUserListTimeout = setTimeout(function(){
+ if (updateUserListActive){return;}
+ updateUserListActive=true;
+ try {
+ var added = false;
+ getById("userList").innerHTML = "";
+
+ for (var UUID in session.rpcs){
+ var track = false;
+ if (session.rpcs[UUID].streamSrc && session.rpcs[UUID].streamSrc.getVideoTracks().length){
+ var tracks = session.rpcs[UUID].streamSrc.getVideoTracks().forEach(function(trk){
+ //if (!trk.muted){
+ track=true;
+ //}
+ });
+ }
+ if (((session.rpcs[UUID].videoMuted || (track==false && !session.rpcs[UUID].imageElement)) && !session.rpcs[UUID].canvas) || ( session.infocus && session.infocus!==UUID )){
+
+ if (UUID === session.directorUUID){
+ if (!session.rpcs[UUID].streamSrc){ // director not active yet, so we won't bother showing it.
+ continue;
+ }
+ }
+
+ var insert = document.createElement("div");
+ if (session.rpcs[UUID].label){
+ insert.innerText = session.rpcs[UUID].label + "";
+ } else if (session.directorUUID === UUID){
+ insert.innerText = "Director";
+ } else {
+ insert.innerText = "Unknown User";
+ }
+ getById("userList").appendChild(insert);
+
+ if (session.rpcs[UUID].remoteMuteState || !(session.rpcs[UUID].streamSrc)){
+ var muteInsert = document.createElement("div");
+ muteInsert.className = "video-mute-state-userlist";
+ muteInsert.innerHTML = ' ';
+ insert.appendChild(muteInsert);
+ } else if (session.rpcs[UUID].voiceMeter){
+ insert.appendChild(session.rpcs[UUID].voiceMeter);
+ }
+ //getById("userList").innerHTML += " ";
+ added=true;
+ }
+ }
+
+ if (!added){
+ getById("connectUsers").style.display = "none";
+ } else {
+ getById("connectUsers").style.display = "block";
+ }
+ } catch(e){}
+ updateUserListActive=false;
+ },200);
+}
+
+var LaunchTFWorkerCallback = false;
+function TFLiteWorker(){
+ if (session.tfliteModule==false){
+ LaunchTFWorkerCallback=true
+ return;
+ }
+ if (TFLITELOADING){LaunchTFWorkerCallback=true;return;}
+ LaunchTFWorkerCallback=false;
+
+ const segmentationWidth = 256;
+ const segmentationHeight = 144;
+ const segmentationPixelCount = segmentationWidth * segmentationHeight;
+ const inputMemoryOffset = session.tfliteModule._getInputMemoryOffset() / 4;
+ const outputMemoryOffset = session.tfliteModule._getOutputMemoryOffset() / 4;
+ const segmentationMask = new ImageData(segmentationWidth, segmentationHeight);
+ const segmentationMaskCanvas = document.createElement('canvas');
+ segmentationMaskCanvas.width = segmentationWidth;
+ segmentationMaskCanvas.height = segmentationHeight;
+ const segmentationMaskCtx = segmentationMaskCanvas.getContext('2d');
+
+ session.tfliteModule.img = document.createElement("img");
+ session.tfliteModule.img.onload = function(){
+ URL.revokeObjectURL(session.tfliteModule.img.src); // no longer needed, free memory
+ session.tfliteModule.img.ready = true;
+ }
+ session.tfliteModule.img.src = "./media/bg_sample.webp";
+ session.tfliteModule.img.ready = false;
+
+ console.log('Starting Loop');
+
+
+ function process(){
+ if (session.tfliteModule.activelyProcessing){return;}
+ session.tfliteModule.activelyProcessing=true;
+ try{
+ segmentationMaskCtx.drawImage(
+ session.canvasSource,
+ 0,
+ 0,
+ session.canvasSource.width,
+ session.canvasSource.height,
+ 0,
+ 0,
+ segmentationWidth,
+ segmentationHeight
+ )
+
+ const imageData = segmentationMaskCtx.getImageData(
+ 0,
+ 0,
+ segmentationWidth,
+ segmentationHeight
+ );
+
+ for (let i = 0; i < segmentationPixelCount; i++) {
+ session.tfliteModule.HEAPF32[inputMemoryOffset + i * 3] = imageData.data[i * 4] / 255;
+ session.tfliteModule.HEAPF32[inputMemoryOffset + i * 3 + 1] = imageData.data[i * 4 + 1] / 255;
+ session.tfliteModule.HEAPF32[inputMemoryOffset + i * 3 + 2] = imageData.data[i * 4 + 2] / 255;
+ }
+
+ session.tfliteModule._runInference();
+
+ for (let i = 0; i < segmentationPixelCount; i++) {
+ const background = session.tfliteModule.HEAPF32[outputMemoryOffset + i * 2];
+ const person = session.tfliteModule.HEAPF32[outputMemoryOffset + i * 2 + 1];
+ const shift = Math.max(background, person);
+ const backgroundExp = Math.exp(background - shift);
+ const personExp = Math.exp(person - shift);
+ segmentationMask.data[i * 4 + 3] = (255 * personExp) / (backgroundExp + personExp); // softmax
+ }
+ segmentationMaskCtx.putImageData(segmentationMask, 0, 0);
+
+ session.canvasCtx.globalCompositeOperation = 'copy';
+ session.canvasCtx.filter = 'blur(4px)';
+ session.canvasCtx.drawImage(
+ segmentationMaskCanvas,
+ 0,
+ 0,
+ segmentationWidth,
+ segmentationHeight,
+ 0,
+ 0,
+ session.canvasSource.width,
+ session.canvasSource.height
+ )
+
+ session.canvasCtx.globalCompositeOperation = 'source-in';
+ session.canvasCtx.filter = 'none';
+ session.canvasCtx.drawImage(session.canvasSource, 0, 0);
+
+ session.canvasCtx.globalCompositeOperation = 'destination-over';
+ if (session.effects=="4"){ // greenscreen
+ session.canvasCtx.filter = 'none';
+ session.canvasCtx.fillStyle = "#0F0";
+ session.canvasCtx.fillRect(0, 0, session.canvas.width, session.canvas.height);
+ } else if (session.effects=="5"){
+ session.canvasCtx.filter = 'none';
+ if (session.tfliteModule.img.ready){
+ session.canvasCtx.drawImage(session.tfliteModule.img, 0, 0, session.canvas.width, session.canvas.height);
+ }
+ } else if (session.effects=="3"){ // BLUR
+ session.canvasCtx.filter = 'blur(4px)'; // Does not work on Safari
+ session.canvasCtx.drawImage(session.canvasSource, 0, 0);
+ } else {
+ session.tfliteModule.activelyProcessing=false;
+ return;
+ }
+ } catch (e){
+ errorlog(e);
+ session.tfliteModule.activelyProcessing=false;
+ return;
+ }
+ session.tfliteModule.activelyProcessing=false;
+ window.requestAnimationFrame(process);
+ }
+ process();
+}
+
+
+function mainMeshMask() {
+ if (model == false){
+ setTimeout(function(){mainMeshMask();},1000);
+ return;
+ }
+ function heatMapColorforValue(value){
+ var h = parseInt((1.0 - value) * 240);
+ if (h<0){h=0;}
+ if (h>240){h=240;}
+ return "hsl(" + h + ", 100%, 50%)";
+ }
+ async function innerLoop(){
+ const predictions = await model.estimateFaces({
+ input: session.canvasSource
+ });
+ if (predictions.length > 0) {
+ for (let j = 0; j < predictions.length; j++) {
+ const fp = predictions[j].annotations;
+ session.canvasCtx.fillStyle = "#000000";
+ session.canvasCtx.fillRect(0, 0, session.canvas.width, session.canvas.height);
+ const keypoints = predictions[j].scaledMesh
+ for (let i = 0; i < keypoints.length; i++) {
+ const [x, y, z] = keypoints[i];
+ session.canvasCtx.fillStyle = heatMapColorforValue((z+40)/60);
+ session.canvasCtx.fillRect(parseInt(x), parseInt(y), 5, 5);
+ }
+ }
+ }
+ window.requestAnimationFrame(innerLoop);
+ }
+ innerLoop();
+}
+
+function drawFace() {
+ var faceAlignment = (function() {
+ var vid = session.canvasSource;
+
+ var canvas = session.canvas;
+ var ctx = session.canvasCtx;
+
+ var canvas_tmp = document.createElement("canvas");
+ var ctx_tmp = canvas_tmp.getContext('2d');
+
+ //var stream = canvas.captureStream(30);
+
+ var image = new Image();
+ var zoom = 10;
+ var scale = 1;
+ var lastFace = {};
+
+ var w = vid.videoWidth;
+ var h = vid.videoHeight;
+ var x = vid.videoWidth / 2;
+ var y = vid.videoHeight / 2;
+
+ lastFace.x = vid.videoWidth / 2;
+ lastFace.y = vid.videoHeight / 2;
+ lastFace.w = vid.videoWidth;
+ lastFace.h = vid.videoHeight;
+ var yoffset = 0;
+
+ if (window.FaceDetector == undefined) {
+ //console.error('Face Detection not supported');
+ var faceDetector = false;
+ } else {
+ var faceDetector = new FaceDetector();
+ //console.log('FaceD Loaded');
+ setTimeout(function() {
+ detect();
+ }, 300);
+ setTimeout(function() {
+ draw();
+ }, 33);
+ }
+
+ canvas.height = vid.videoHeight;
+ canvas.width = vid.videoWidth;
+ canvas_tmp.height = vid.videoHeight;
+ canvas_tmp.width = vid.videoWidth;
+ image.src = canvas_tmp.toDataURL();
+ scale = canvas.width / image.width;
+ lastFace.x = 0;
+ lastFace.y = 0;
+ lastFace.w = 1280 / 3 / 16 * zoom;
+ lastFace.h = 720 / 3 / 9 * zoom;
+
+ w = 1280 / 5;
+ h = 720 / 5;
+ x = 1280 / 2;
+ y = 720 / 2 - w * 9 / zoom / 2;
+
+ async function detect() {
+
+ if (session.effects !== 1){return;}
+
+ ctx_tmp.drawImage(vid, 0, 0, vid.videoWidth, vid.videoHeight);
+ image.src = canvas_tmp.toDataURL();
+ await faceDetector.detect(image).then(faces => {
+
+ if (faces.length === 0) {
+ log("NO FACES");
+ setTimeout(function() {
+ detect();
+ }, 10);
+ return;
+ }
+ for (let face of faces) {
+ lastFace.x = (face.boundingBox.x + lastFace.x) / 2 || face.boundingBox.x;
+ lastFace.y = (face.boundingBox.y + lastFace.y) / 2 || face.boundingBox.y;
+ lastFace.w = (face.boundingBox.width + lastFace.w) / 2 || face.boundingBox.width;
+ lastFace.h = (face.boundingBox.height + lastFace.h) / 2 || face.boundingBox.height;
+ }
+
+ setTimeout(function() {
+ detect();
+ }, 300);
+ }).catch((e) => {
+ console.error("Boo, Face Detection failed: " + e);
+ });
+
+ }
+
+ function draw() {
+
+ if (session.effects !== 1){return;}
+
+ canvas.height = vid.videoHeight;
+ canvas.width = vid.videoWidth;
+
+ if (lastFace.w - w < 0.15 * lastFace.w) {
+ w = w * 0.999 + 0.001 * lastFace.w;
+ }
+ if (lastFace.h - h < 0.15 * lastFace.h) {
+ h = h * 0.999 + 0.001 * lastFace.h;
+ }
+ if (Math.abs(x - (lastFace.x + lastFace.w / 2)) > 0.15 * (lastFace.x + lastFace.w / 2.0)) {
+ x = x * 0.999 + 0.001 * (lastFace.x + lastFace.w / 2.0);
+ }
+ if (Math.abs(y - (lastFace.y + lastFace.h / 2)) > 0.15 * (lastFace.y + lastFace.h / 2.0)) {
+ y = y * 0.999 + 0.001 * (lastFace.y + lastFace.h / 2.0);
+ }
+
+ yoffset = w * 9 / zoom / 2;
+
+ var yyy = y - w * 9 / zoom - yoffset;
+ var hhh = w * 3 * 9 / zoom;
+ var www = w * 3 * 16 / zoom;
+ var xxx = x - w * 16 / zoom * 1.5;
+
+ if (www + xxx < 1280) {
+ xxx = 1280 - www;
+ }
+ if (hhh + yyy < 720) {
+ yyy = 720 - hhh;
+ }
+
+ if (www + xxx > 1280) {
+ xxx = 1280 - www;
+ }
+ if (hhh + yyy > 720) {
+ yyy = 720 - hhh;
+ }
+
+ if (yyy < 0) {
+ yyy = 0;
+ }
+ if (xxx < 0) {
+ xxx = 0;
+ }
+
+ ctx.drawImage(vid, xxx, yyy, www, hhh, 0, 0, vid.videoWidth, vid.videoHeight);
+
+ setTimeout(function() {
+ draw();
+ }, 30);
+ }
+ })();
+}
+
+
+//////// END CANVAS EFFECTS ///////////////////
+
+
+if (urlParams.has('permaid') || urlParams.has('push')) {
+ session.permaid = urlParams.get('push') || urlParams.get('permaid');
+
+ if (session.permaid) {
+ session.streamID = sanitizeStreamID(session.permaid);
+ } else {
+ session.permaid = null;
+ }
+
+ if (urlParams.has('permaid')) {
+ updateURL("permaid=" + session.streamID, true, false); // I'm not deleting the permaID first tho...
+ } else {
+ updateURL("push=" + session.streamID, true, false); // I'm not deleting the permaID first tho...
+ }
+
+ if (urlParams.has('director') || urlParams.has('dir')) { // if I do a short form of this, it will cause duplications in the code elsewhere.
+ //var director_room_input = urlParams.get('director');
+ //director_room_input = sanitizeRoomName(director_room_input);
+ //createRoom(director_room_input);
+ session.permaid = false; // used to avoid a trigger later on.
+ } else {
+ getById("container-1").className = 'column columnfade advanced';
+ getById("container-4").className = 'column columnfade advanced';
+ getById("dropButton").className = 'column columnfade advanced';
+
+ getById("info").innerHTML = "";
+ if (session.videoDevice === 0) {
+ getById("add_camera").innerHTML = "Share your Microphone";
+ miniTranslate(getById("add_camera"), "share-your-mic");
+ } else {
+ getById("add_camera").innerHTML = "Share your Camera";
+ miniTranslate(getById("add_camera"), "share-your-camera");
+ }
+ getById("add_screen").innerHTML = "Share your Screen";
+ miniTranslate(getById("add_screen"), "share-your-screen");
+
+ getById("passwordRoom").value = "";
+ getById("videoname1").value = "";
+ getById("dirroomid").innerHTML = "";
+ getById("roomid").innerHTML = "";
+
+ getById("mainmenu").style.alignSelf = "center";
+ getById("mainmenu").classList.add("mainmenuclass");
+ getById("header").style.alignSelf = "center";
+
+ if ((iOS) || (iPad)) {
+ getById("header").style.display = "none"; // just trying to free up space.
+ }
+
+ if (session.webcamonly == true) { // mobile or manual flag 'webcam' pflag set
+ getById("head1").innerHTML = '- Please accept any camera permissions ';
+ } else {
+ getById("head1").innerHTML = '- Please select which you wish to share ';
+ }
+ }
+}
+
+if ((session.roomid) || (urlParams.has('roomid')) || (urlParams.has('r')) || (urlParams.has('room')) || (filename) || (session.permaid !== false)) {
+
+ var roomid = "";
+ if (filename) {
+ roomid = filename;
+ } else if (urlParams.has('room')) {
+ roomid = urlParams.get('room');
+ } else if (urlParams.has('roomid')) {
+ roomid = urlParams.get('roomid');
+ } else if (urlParams.has('r')) {
+ roomid = urlParams.get('r');
+ } else if (session.roomid) {
+ roomid = session.roomid;
+ }
+
+ session.roomid = sanitizeRoomName(roomid);
+
+ if (!(session.cleanOutput)) {
+ if (session.roomid === "test") {
+ if (session.password === session.defaultPassword) {
+ window.focus();
+ var testRoomResponse = confirm("The room name 'test' is very commonly used and may not be secure.\n\nAre you sure you wish to proceed?");
+ if (testRoomResponse == false) {
+ hangup();
+ throw new Error("User requested to not enter room 'room'.");
+ }
+ }
+ }
+ }
+
+ if (session.audioDevice === false && session.outputDevice === false) {
+ getById("headphonesDiv2").style.display = "inline-block";
+ getById("headphonesDiv").style.display = "inline-block";
+ }
+ getById("addPasswordBasic").style.display = "none";
+
+ getById("info").innerHTML = "";
+ getById("info").style.color = "#CCC";
+ getById("videoname1").value = session.roomid;
+ getById("dirroomid").innerText = session.roomid;
+ getById("roomid").innerText = session.roomid;
+ getById("container-1").className = 'column columnfade advanced';
+ getById("container-4").className = 'column columnfade advanced';
+ getById("container-7").style.display = 'none';
+ getById("container-8").style.display = 'none';
+ getById("mainmenu").style.alignSelf = "center";
+ getById("mainmenu").classList.add("mainmenuclass");
+ getById("header").style.alignSelf = "center";
+
+ if (session.webcamonly == true) { // mobile or manual flag 'webcam' pflag set
+ getById("head1").innerHTML = '';
+ } else {
+ getById("head1").innerHTML = 'Please select an option to join. ';
+ }
+
+ if (session.roomid.length > 0) {
+ if (session.videoDevice === 0) {
+ if (session.audioDevice === 0) {
+ getById("add_camera").innerHTML = "Join room";
+ miniTranslate(getById("add_camera"), "join-room");
+ } else {
+ getById("add_camera").innerHTML = "Join room with Microphone";
+ miniTranslate(getById("add_camera"), "join-room-with-mic");
+ }
+ } else {
+ getById("add_camera").innerHTML = "Join Room with Camera";
+ miniTranslate(getById("add_camera"), "join-room-with-camera");
+ }
+ getById("add_screen").innerHTML = "Screenshare with Room";
+ miniTranslate(getById("add_screen"), "share-screen-with-room");
+ } else {
+ if (session.videoDevice === 0) {
+ getById("add_camera").innerHTML = "Share your Microphone";
+ miniTranslate(getById("add_camera"), "share-your-mic");
+ } else {
+ getById("add_camera").innerHTML = "Share your Camera";
+ miniTranslate(getById("add_camera"), "share-your-camera");
+ }
+ getById("add_screen").innerHTML = "Share your Screen";
+ miniTranslate(getById("add_screen"), "share-your-screen");
+ }
+ getById("head3").className = 'advanced';
+
+ if (session.scene !== 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("head1").className = 'advanced';
+ getById("head2").className = 'advanced';
+ getById("mainmenu").style.display = "none";
+ getById("translateButton").style.display = "none";
+ log("Update Mixer Event on REsize SET");
+ window.addEventListener("resize", updateMixer);
+ window.addEventListener("orientationchange", function() {
+ setTimeout(updateMixer, 200);
+ });
+ joinRoom(session.roomid); // this is a scene, so we want high resolutions
+ getById("main").style.overflow = "hidden";
+ } else {
+ if ((session.permaid === null) && (session.roomid == "")) {
+ if (!(session.cleanOutput)) {
+ getById("head3").className = '';
+ }
+ }
+ }
+
+} else if (urlParams.has('director') || urlParams.has('dir')) { // if I do a short form of this, it will cause duplications in the code elsewhere.
+ if (directorLanding == false) {
+ var director_room_input = urlParams.get('director') || urlParams.get('dir');
+ director_room_input = sanitizeRoomName(director_room_input);
+ log("director_room_input:" + director_room_input);
+ createRoom(director_room_input);
+ }
+} else if ((session.view) && (session.permaid === false)) {
+ //if (!session.activeSpeaker){
+ session.audioMeterGuest = false;
+ //}
+ if (session.audioEffects === null) {
+ session.audioEffects = false;
+ }
+ log("Update Mixer Event on REsize SET");
+ getById("translateButton").style.display = "none";
+ window.addEventListener("resize", updateMixer);
+ window.addEventListener("orientationchange", function() {
+ setTimeout(updateMixer, 200);
+ });
+ getById("main").style.overflow = "hidden";
+}
+
+if (session.audioEffects === null) {
+ session.audioEffects = true;
+}
+
+if (session.audioEffects) {
+ getById("channelGroup1").style.display = "block";
+ getById("channelGroup2").style.display = "block";
+}
+
+if (urlParams.has('hidemenu') || urlParams.has('hm')) { // needs to happen the room and permaid applications
+ getById("mainmenu").style.display = "none";
+ getById("header").style.display = "none";
+ getById("mainmenu").style.opacity = 0;
+ getById("header").style.opacity = 0;
+}
+
+if (urlParams.has('hideheader') || urlParams.has('noheader') || urlParams.has('hh')) { // needs to happen the room and permaid applications
+ getById("header").style.display = "none";
+ getById("header").style.opacity = 0;
+}
+
+function checkConnection() {
+ if (session.ws === null) {
+ return;
+ }
+ if (document.getElementById("qos")) { // true or false; null might cause problems?
+ if ((session.ws) && (session.ws.readyState === WebSocket.OPEN)) {
+ getById("qos").style.color = "white";
+ } else {
+ getById("qos").style.color = "red";
+ }
+ }
+}
+setInterval(function() {
+ checkConnection();
+}, 5000);
+
+
+function remoteStats(msg){
+ if (session.director){
+ var output = "";
+ var size = 0;
+ for (var key in msg.remoteStats) {
+ if (msg.remoteStats.hasOwnProperty(key)) size++;
+ }
+ output += "Total Viewers: "+size;
+ for (var uuid in msg.remoteStats){
+ if ("scene" in msg.remoteStats[uuid] && msg.remoteStats[uuid].scene !== false){
+ output+=" scene: "+msg.remoteStats[uuid].scene;
+ if ("video_bitrate_kbps" in msg.remoteStats[uuid]){
+ output+=" video_bitrate_kbps: "+msg.remoteStats[uuid].video_bitrate_kbps;
+ }
+ if ("audio_bitrate_kbps" in msg.remoteStats[uuid]){
+ output+=" audio_bitrate_kbps: "+msg.remoteStats[uuid].audio_bitrate_kbps;
+ }
+ if (msg.remoteStats[uuid].resolution){
+ output+=" resolution: "+msg.remoteStats[uuid].resolution;
+ }
+ if (msg.remoteStats[uuid].video_encoder){
+ output+=" video_encoder: "+msg.remoteStats[uuid].video_encoder;
+ }
+ if ("scaleFactor" in msg.remoteStats[uuid]){
+ output+=" scaleFactor: "+msg.remoteStats[uuid].scaleFactor;
+ }
+ if ("nacks_per_second" in msg.remoteStats[uuid]){
+ output+=" nacks_per_second: "+msg.remoteStats[uuid].nacks_per_second;
+ }
+ if (msg.remoteStats[uuid].retransmitted_kbps){
+ output+=" quality_limitation_reason: "+msg.remoteStats[uuid].retransmitted_kbps;
+ }
+ if (msg.remoteStats[uuid].quality_limitation_reason){
+ output+=" quality_limitation_reason: "+msg.remoteStats[uuid].quality_limitation_reason;
+ }
+ }
+ }
+ warnUser(output);
+ };
+ if (isIFrame){
+ parent.postMessage({"remoteStats": msg.remoteStats }, "*");
+ }
+}
+
+
+function printViewStats(menu, UUID) { // Stats for viewing a remote video
+ if (!session.rpcs[UUID]){
+ menu.innerHTML = " Remote Publisher Disconnected";
+ return;
+ }
+
+ var statsObj = session.rpcs[UUID].stats;
+ var streamID = session.rpcs[UUID].streamID;
+ var scrollLeft = menu.scrollLeft;
+ var scrollTop = menu.scrollTop;
+ menu.innerHTML = "StreamID: " + streamID + " ";
+ menu.innerHTML += printValues(statsObj);
+ menu.scrollTop = scrollTop;
+ menu.scrollLeft = scrollLeft;
+
+ errorlog(statsObj);
+}
+
+function printValues(obj) { // see: printViewStats
+ var out = "";
+ for (var key in obj) {
+ if (typeof obj[key] === "object") {
+ if (obj[key] != null) {
+ var tmp = key;
+ tmp = sanitizeChat((tmp));
+ out += "" + tmp + " "
+ out += printValues(obj[key]);
+ }
+ } else {
+ if (key.startsWith("_")) {
+ // if it starts with _, we don't want to show it.
+ } else {
+ try {
+ var unit = '';
+
+ var value = obj[key];
+
+ var stat = sanitizeChat(key);
+
+ if (typeof obj[key] == "string") {
+ value = sanitizeChat((value));
+ }
+
+ //
+ if (key == 'useragent') {
+ value = ""+value+" "
+ }
+
+ if (key == 'Bitrate_in_kbps') {
+ var unit = " kbps";
+ stat = "Bitrate";
+ }
+ else if (key == 'type') {
+ var unit = "";
+ stat = 'Type';
+
+ if (value == "Audio Track") {
+ value = "🔊 " + value;
+ //out += " ";
+ }
+
+ if (value == "Video Track") {
+ value = "📺 " + value;
+ }
+
+ }
+ else if (key == 'packetLoss_in_percentage') {
+ var unit = " %";
+ stat = 'Packet Loss 📶';
+ value = parseInt(parseFloat(value) * 10000) / 10000.0;
+ }
+ else if (key == 'local_relayIP') {
+ value = "" + value + " ";
+ }
+ else if (key == 'remote_relay_IP') {
+ value = "" + value + " ";
+ }
+ else if (key == 'local_candidateType') {
+ if (value == "relay") {
+ value = "💸 relay server";
+ }
+ }
+ else if (key == 'remote_candidateType') {
+ if (value == "relay") {
+ value = "💸 relay server";
+ }
+ }
+ else if (key == 'height_url') {
+ if (value == false) {
+ continue;
+ }
+ }
+ else if (key == 'width_url') {
+ if (value == false) {
+ continue;
+ }
+ }
+ else if (key == 'height_url') {
+ if (value == false) {
+ continue;
+ }
+ }
+ else if (key == 'version') {
+ stat = "VDO.Ninja Version";
+ } else if (key == 'platform') {
+ stat = "Platform (OS)";
+ }
+ else if (key == 'aec_url') {
+ stat = "Echo-Cancellation";
+ }
+ else if (key == 'agc_url') {
+ stat = "Auto-Gain (agc)";
+ }
+ else if (key == 'denoise_url') {
+ stat = "De-noising ";
+ }
+ else if (key == 'audio_level') {
+ stat = "Audio Level";
+ }
+ else if (key == 'Buffer_Delay_in_ms') {
+ var unit = " ms";
+ stat = 'Buffer Delay';
+ }
+ else if (value === null) {
+ value = "null";
+ }
+ else if (key == "stereo_url") {
+ stat = "Pro-Audio (Stereo-mode)";
+ if (value == 3) {
+ value = "3 (outbound hi-fi) Use Headphones";
+ } else if (value == 1) {
+ value = "1 (in & out hi-fi) Use Headphones";
+ } else if (value == 2) {
+ value = "3 (inbound hi-fi)";
+ } else if (value == 4) {
+ value = "3 (multichannel) Use Headphones";
+ } else if (value == 5) {
+ value = "5 (auto-mode) Use Headphones";
+ }
+ }
+ else if (value === false) {
+ continue
+ }
+ else if (value === "false") {
+ continue
+ }
+ out += "" + stat + " " + value + unit + " ";
+ } catch (e) {
+ warnlog(e);
+ }
+ }
+ }
+ }
+ return out;
+}
+
+
+function printMyStats(menu) { // see: setupStatsMenu
+ var scrollLeft = getById("menuStatsBox").scrollLeft;
+ var scrollTop = getById("menuStatsBox").scrollTop;
+ menu.innerHTML = "";
+
+ session.stats.outbound_connections = Object.keys(session.pcs).length;
+ session.stats.inbound_connections = Object.keys(session.rpcs).length;
+
+ function printViewValues(obj) {
+
+ if (!(document.getElementById("menuStatsBox"))){
+ return;
+ }
+
+ for (var key in obj) {
+ if (typeof obj[key] === "object") {
+ printViewValues(obj[key]);
+ } else {
+
+ if (key.startsWith("_")){continue;}
+
+ var stat = sanitizeChat(key);
+ var value = obj[key];
+ if (typeof value == "string") {
+ value = sanitizeChat((value));
+ }
+
+ if (value === false){continue;}
+
+ if (key == 'useragent') {
+ value = ""+value+" "
+ }
+
+ if (key == 'local_relayIP') {
+ value = "" + value + " ";
+ }
+ if (key == 'remote_relay_IP') {
+ value = "" + value + " ";
+ }
+ if (key == 'local_candidateType') {
+ if (value == "relay") {
+ value = "💸 relay server";
+ }
+ }
+ if (key == 'remote_candidateType') {
+ if (value == "relay") {
+ value = "💸 relay server";
+ }
+ }
+
+ menu.innerHTML += "" + stat + " " + value + " ";
+ }
+ }
+ }
+ printViewValues(session.stats);
+ menu.innerHTML += "Send Keyframe to Viewers ";
+ for (var uuid in session.pcs) {
+ printViewValues(session.pcs[uuid].stats);
+ menu.innerHTML += " ";
+ }
+ if ((iOS) || (iPad)){
+ menu.innerHTML += "
";
+ }
+ try {
+ getById("menuStatsBox").scrollLeft = scrollLeft;
+ getById("menuStatsBox").scrollTop = scrollTop;
+ } catch (e) {}
+}
+
+
+function updateLocalStats(){
+
+ var totalBitrate = 0;
+ var totalBitrate2 = 0;
+ var cpuLimited = false;
+ for (var uuid in session.pcs) {
+ if ("video_bitrate_kbps" in session.pcs[uuid].stats){
+ totalBitrate+=session.pcs[uuid].stats.video_bitrate_kbps || 0;
+ }
+ if ("audio_bitrate_kbps" in session.pcs[uuid].stats){
+ totalBitrate+=session.pcs[uuid].stats.audio_bitrate_kbps || 0;
+ }
+ if ("total_sending_bitrate_kbps" in session.pcs[uuid].stats){
+ totalBitrate2+=session.pcs[uuid].stats.total_sending_bitrate_kbps || 0;
+ }
+
+ if ("quality_limitation_reason" in session.pcs[uuid].stats){
+ if (session.pcs[uuid].stats.quality_limitation_reason == "cpu"){
+ cpuLimited=true;
+ }
+ }
+
+ if (uuid in session.rpcs){
+ if (session.pcs[uuid].stats.label){
+ session.pcs[uuid].stats.label = session.rpcs[uuid].label;
+ }
+ if (session.pcs[uuid].stats.streamID){
+ session.pcs[uuid].stats.streamID = session.rpcs[uuid].streamID;
+ }
+ }
+
+ setTimeout(function(UUID) {
+ if (!( session.pcs[UUID])){return;}
+ session.pcs[UUID].getStats().then(function(stats) {
+ if ("audio_bitrate_kbps" in session.pcs[UUID].stats){
+ session.pcs[UUID].stats.audio_bitrate_kbps=0;
+ }
+ stats.forEach(stat => {
+ if (stat.type == "transport"){
+ if ("bytesSent" in stat) {
+ if ("_bytesSent" in session.pcs[UUID].stats){
+ if (session.pcs[UUID].stats._timestamp){
+ if (stat.timestamp){
+ session.pcs[UUID].stats.total_sending_bitrate_kbps = parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSent)/(stat.timestamp - session.pcs[UUID].stats._timestamp));
+ }
+ }
+ }
+ session.pcs[UUID].stats._bytesSent = stat.bytesSent;
+ }
+ if ("timestamp" in stat) {
+ session.pcs[UUID].stats._timestamp = stat.timestamp;
+ }
+ } else 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.video_encoder = stat.encoderImplementation;
+ }
+ if ("bytesSent" in stat) {
+ if ("_bytesSentVideo" in session.pcs[UUID].stats){
+ if (session.pcs[UUID].stats._timestamp1){
+ session.pcs[UUID].stats.video_bitrate_kbps = parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSentVideo)/(stat.timestamp - session.pcs[UUID].stats._timestamp1));
+ if (stat.timestamp){
+ }
+ }
+ }
+ session.pcs[UUID].stats._bytesSentVideo = stat.bytesSent;
+ }
+
+ if ("nackCount" in stat) {
+ if ("_nackCount" in session.pcs[UUID].stats){
+ if (session.pcs[UUID].stats._timestamp1){
+ if (stat.timestamp){
+ session.pcs[UUID].stats.nacks_per_second = parseInt(10000*(stat.nackCount - session.pcs[UUID].stats._nackCount)/(stat.timestamp - session.pcs[UUID].stats._timestamp1))/10;
+ }
+ }
+ }
+ }
+ if ("retransmittedBytesSent" in stat) {
+ if ("_retransmittedBytesSent" in session.pcs[UUID].stats){
+ if (session.pcs[UUID].stats._timestamp1){
+ if (stat.timestamp){
+ session.pcs[UUID].stats.retransmitted_kbps = parseInt(8*(stat.retransmittedBytesSent - session.pcs[UUID].stats._retransmittedBytesSent)/(stat.timestamp - session.pcs[UUID].stats._timestamp1));
+ }
+ }
+ }
+ }
+
+ if ("nackCount" in stat) {
+ session.pcs[UUID].stats._nackCount = stat.nackCount;
+
+ }
+
+ if ("retransmittedBytesSent" in stat) {
+ session.pcs[UUID].stats._retransmittedBytesSent = stat.retransmittedBytesSent;
+
+ }
+
+ if ("timestamp" in stat) {
+ session.pcs[UUID].stats._timestamp1 = stat.timestamp;
+ }
+
+ if ("pliCount" in stat) {
+ session.pcs[UUID].stats.total_pli_count = stat.pliCount;
+ }
+ if ("keyFramesEncoded" in stat) {
+ session.pcs[UUID].stats.total_key_frames_encoded = stat.keyFramesEncoded;
+ }
+
+
+ } else if (stat.kind == "audio") {
+ if ("bytesSent" in stat) {
+ if (session.pcs[UUID].stats._bytesSentAudio){
+ if (session.pcs[UUID].stats._timestamp2){
+ if (stat.timestamp){
+ if ("audio_bitrate_kbps" in session.pcs[UUID].stats){
+ session.pcs[UUID].stats.audio_bitrate_kbps += parseInt(8*(stat.bytesSent - session.pcs[UUID].stats._bytesSentAudio)/(stat.timestamp - session.pcs[UUID].stats._timestamp2));
+ } else {
+ session.pcs[UUID].stats.audio_bitrate_kbps=0;
+ }
+ }
+ }
+ }
+ }
+ if ("timestamp" in stat) {
+ session.pcs[UUID].stats._timestamp2 = stat.timestamp;
+ }
+
+ if ("bytesSent" in stat) {
+ session.pcs[UUID].stats._bytesSentAudio = stat.bytesSent;
+
+ }
+ }
+ } 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);
+ }
+ var headerStats = "Viewers: ";
+ try{
+ headerStats += Object.keys(session.pcs).length || 0;
+ } catch(e){}
+ headerStats += ", Upload (kbps): "+totalBitrate2; // + " / "+totalBitrate;
+ if (cpuLimited){
+ headerStats += ", CPU Overloaded";
+ }
+ try{
+ if (Object.keys(session.pcs).length){
+ getById("head5").classList.remove("advanced");
+ }
+ } catch(e){}
+ getById("head5").innerHTML = headerStats;
+}
+
+
+function updateStats(obsvc = false) {
+ log('updateStats - resolution found');
+ if (document.getElementById('previewWebcam')) {
+ var ele = document.getElementById('previewWebcam');
+ var wcs = "webcamstats";
+ } else if (document.getElementById('videosource')) {
+ var ele = document.getElementById('videosource');
+ var wcs = "webcamstats3";
+ } else {
+ return;
+ }
+
+ try {
+ getById(wcs).innerHTML = "";
+ ele.srcObject.getVideoTracks().forEach(
+ function(track) {
+ if ((obsvc) && (parseInt(track.getSettings().frameRate) == 30)) {
+ getById(wcs).innerHTML = "Video Settings: " + (track.getSettings().width || 0) + "x" + (track.getSettings().height || 0) + " @ up to 60fps";
+ } else {
+ getById(wcs).innerHTML = "Current Video Settings: " + (track.getSettings().width || 0) + "x" + (track.getSettings().height || 0) + "@" + (parseInt(track.getSettings().frameRate * 10) / 10) + "fps";
+ }
+ }
+ );
+
+ } catch (e) {
+ errorlog(e);
+ }
+}
+
+function toggleMute(apply = false) { // TODO: I need to have this be MUTE, toggle, with volume not touched.
+
+ log("muting");
+
+ if (session.director) {
+ if (!session.directorEnabledPPT) {
+ log("Director doesn't have PPT enabled yet");
+ // director has not enabled PTT yet.
+ return;
+ }
+ }
+
+ if (apply) {
+ session.muted = !session.muted; // we flip here as we are going to flip again in a second.
+ }
+ //try{var ptt = getById("press2talk");} catch(e){var ptt=false;}
+
+
+ if (session.muted == false) {
+ session.muted = true;
+ getById("mutetoggle").className = "las la-microphone-slash my-float toggleSize";
+ if (!(session.cleanOutput)){
+ getById("mutebutton").className = "float2 red puslate";
+ getById("header").classList.add('red');
+
+ if (session.localMuteElement){
+ session.localMuteElement.style.display = "block";
+ }
+
+ }
+ if (session.streamSrc) {
+ session.streamSrc.getAudioTracks().forEach((track) => {
+ track.enabled = false;
+ });
+ }
+ //if (ptt){
+ // ptt.innerHTML = "🔇 Push to Talk ";
+ //}
+
+ } else {
+ session.muted = false;
+ getById("mutetoggle").className = "las la-microphone my-float toggleSize";
+ if (!(session.cleanOutput)){
+ getById("mutebutton").className = "float";
+ getById("header").classList.remove('red');
+
+ if (session.localMuteElement){
+ session.localMuteElement.style.display = "none";
+ }
+
+ }
+ if (session.streamSrc) {
+ session.streamSrc.getAudioTracks().forEach((track) => {
+ track.enabled = true;
+ });
+ }
+ //if (ptt){
+ // ptt.innerHTML = "🔴 Push to Mute ";
+ //}
+ }
+
+ if (document.getElementById("screensharesource")){
+ document.getElementById("screensharesource").contentWindow.postMessage({"mic":!session.muted}, '*');
+ }
+
+ if (!apply) { // only if they are changing states do we bother to spam.
+ data = {};
+ data.muteState = session.muted;
+ session.sendMessage(data);
+ log("SEND DATA");
+ pokeIframeAPI('mic-mute-state', session.muted);
+ }
+}
+
+
+function toggleSpeakerMute(apply = false) { // TODO: I need to have this be MUTE, toggle, with volume not touched.
+
+ if (CtrlPressed) {
+ resetupAudioOut();
+ }
+
+ if (apply) {
+ session.speakerMuted = !session.speakerMuted;
+ }
+ if (session.speakerMuted == false) {
+ session.speakerMuted = true;
+ getById("mutespeakertoggle").className = "las la-volume-mute my-float toggleSize";
+ if (!(session.cleanOutput)){
+ getById("mutespeakerbutton").className = "float2 red";
+ }
+ var sounds = document.getElementsByTagName("video");
+ for (var i = 0; i < sounds.length; ++i) {
+ sounds[i].muted = session.speakerMuted;
+ }
+
+ } else {
+ session.speakerMuted = false;
+
+ getById("mutespeakertoggle").className = "las la-volume-up my-float toggleSize";
+ if (!(session.cleanOutput)){
+ getById("mutespeakerbutton").className = "float";
+ }
+
+ var sounds = document.getElementsByTagName("video");
+ for (var i = 0; i < sounds.length; ++i) {
+
+ if (sounds[i].id === "videosource") { // don't unmute ourselves. feedback galore if so.
+ continue;
+ } else if (sounds[i].id === "previewWebcam") {
+ continue;
+ } else if (sounds[i].id === "screenshare") {
+ continue;
+ } else {
+ sounds[i].muted = session.speakerMuted;
+ }
+ }
+ }
+
+ for (var UUID in session.rpcs) {
+ if (session.rpcs[UUID].videoElement) {
+ //if (UUID === session.directorUUID) {
+ // session.rpcs[UUID].videoElement.muted = false; // unmute director
+ // log("MAKE SURE DIRECTOR ISN'T MUTED");
+ //} else {
+ session.rpcs[UUID].videoElement.muted = session.speakerMuted;
+ // }
+ }
+ if (session.rpcs[UUID].iframeEle){
+ try{
+ session.rpcs[UUID].iframeEle.contentWindow.postMessage({"mute":session.speakerMuted}, '*');
+ } catch(e){errorlog(e);}
+ }
+ }
+
+
+ if ((iOS) || (iPad)) {
+ resetupAudioOut();
+ }
+}
+
+
+function toggleChat(event = null) { // TODO: I need to have this be MUTE, toggle, with volume not touched.
+ if (session.chat == false) {
+ setTimeout(function() {
+ document.addEventListener("click", toggleChat);
+ }, 10);
+
+ getById("chatModule").addEventListener("click", function(e) {
+ e.stopPropagation();
+ return false;
+ });
+ session.chat = true;
+ getById("chattoggle").className = "las la-comment-dots my-float toggleSize";
+ getById("chatbutton").className = "float2";
+ getById("chatModule").style.display = "block";
+ getById("chatInput").focus(); // give it keyboard focus
+ } else {
+ session.chat = false;
+ getById("chattoggle").className = "las la-comment-alt my-float toggleSize";
+ getById("chatbutton").className = "float";
+ getById("chatModule").style.display = "none";
+
+ document.removeEventListener("click", toggleChat);
+ getById("chatModule").removeEventListener("click", function(e) {
+ e.stopPropagation();
+ return false;
+ });
+ }
+ if (getById("chatNotification").value) {
+ getById("chatNotification").value = 0;
+ }
+ getById("chatNotification").classList.remove("notification");
+}
+
+function directorAdvanced(ele) {
+ var target = document.createElement("div");
+ target.style = "position:absolute;float:left;width:270px;height:222px;background-color:#7E7E7E;";
+
+ var closeButton = document.createElement("button");
+ closeButton.innerHTML = " close";
+ closeButton.style.left = "5px";
+ closeButton.style.position = "relative";
+ closeButton.onclick = function() {
+ target.parentNode.removeChild(target);
+ };
+ target.appendChild(closeButton);
+
+ var someButton = document.createElement("button");
+ someButton.innerHTML = " some action ";
+ someButton.style.left = "5px";
+ someButton.style.position = "relative";
+ someButton.onclick = function() {
+ var actionMsg = {};
+ session.sendRequest(actionMsg, ele.dataset.UUID);
+ };
+ target.appendChild(someButton);
+
+ ele.parentNode.appendChild(target);
+}
+
+function directorSendMessage(ele) {
+ var target = document.createElement("div");
+ target.style = "position:absolute;float:left;width:270px;height:222px;background-color:#7E7E7E;";
+
+ var inputField = document.createElement("textarea");
+ inputField.placeholder = "Enter your message here";
+ inputField.style.width = "255px";
+ inputField.style.height = "170px";
+ inputField.style.margin = "5px 10px 5px 10px";
+ inputField.style.padding = "5px";
+
+ target.appendChild(inputField);
+
+ var sendButton = document.createElement("button");
+ sendButton.innerHTML = " send message ";
+ sendButton.style.left = "5px";
+ sendButton.style.position = "relative";
+ sendButton.onclick = function() {
+ var chatMsg = {};
+ chatMsg.chat = inputField.value;
+ if (sendButton.parentNode.overlay) {
+ chatMsg.overlay = sendButton.parentNode.overlay;
+ }
+ session.sendRequest(chatMsg, ele.dataset.UUID);
+ inputField.value = "";
+ //target.parentNode.removeChild(target);
+ };
+
+
+ var closeButton = document.createElement("button");
+ closeButton.innerHTML = " close";
+ closeButton.style.left = "5px";
+ closeButton.style.position = "relative";
+ closeButton.onclick = function() {
+ inputField.value = "";
+ target.parentNode.removeChild(target);
+ };
+
+ var overlayMsg = document.createElement("span");
+
+ overlayMsg.style.left = "16px";
+ overlayMsg.style.top = "6px";
+ overlayMsg.style.position = "relative";
+ overlayMsg.innerHTML = " ";
+ target.overlay = true;
+
+ overlayMsg.onclick = function(e) {
+ log(e.target.parentNode.parentNode);
+ if (e.target.parentNode.parentNode.overlay === true) {
+ e.target.parentNode.parentNode.overlay = false;
+ e.target.parentNode.innerHTML = " ";
+ } else {
+ e.target.parentNode.parentNode.overlay = true;
+ e.target.parentNode.innerHTML = " ";
+ }
+ }
+
+
+ inputField.addEventListener("keydown", function(e) {
+ if (e.keyCode == 13) {
+ e.preventDefault();
+ sendButton.click();
+ } else if (e.keyCode == 27) {
+ e.preventDefault();
+ inputField.value = "";
+ target.parentNode.removeChild(target);
+ }
+ });
+ target.appendChild(closeButton);
+ target.appendChild(sendButton);
+ target.appendChild(overlayMsg);
+ ele.parentNode.appendChild(target);
+ inputField.focus();
+ inputField.select();
+}
+
+function toggleVideoMute(apply = false) { // TODO: I need to have this be MUTE, toggle, with volume not touched.
+ if (apply) {
+ session.videoMuted = !session.videoMuted;
+ }
+ if (session.videoMuted == false) {
+ session.videoMuted = true;
+ getById("mutevideotoggle").className = "las la-video-slash my-float toggleSize";
+ if (!(session.cleanOutput)){
+ getById("mutevideobutton").className = "float2 red";
+ }
+ if (session.streamSrc) {
+ session.streamSrc.getVideoTracks().forEach((track) => {
+ track.enabled = false;
+ });
+ }
+
+ } else {
+ session.videoMuted = false;
+
+ getById("mutevideotoggle").className = "las la-video my-float toggleSize";
+ if (!(session.cleanOutput)){
+ getById("mutevideobutton").className = "float";
+ }
+ if (session.streamSrc) {
+ session.streamSrc.getVideoTracks().forEach((track) => {
+ // try {
+ // if (document.querySelector("select#videoSource3").value == "ZZZ"){
+ // return;
+ // }
+ // } catch(e){}
+ track.enabled = true;
+ });
+ }
+ }
+
+
+
+ if (!apply) {
+ var msg = {};
+ msg.videoMuted = session.videoMuted;
+ session.sendMessage(msg);
+ pokeIframeAPI('video-mute-state', session.videoMuted);
+ if (!session.videoMuted){makeImages();}
+ }
+}
+
+var toggleSettingsState = false;
+
+function toggleSettings(forceShow = false) { // TODO: I need to have this be MUTE, toggle, with volume not touched.
+
+ getById("multiselect-trigger3").dataset.state = "0";
+ getById("multiselect-trigger3").classList.add('closed');
+ getById("multiselect-trigger3").classList.remove('open');
+ getById("chevarrow2").classList.add('bottom');
+
+ if (toggleSettingsState == true) {
+ if (forceShow == true) {
+ enumerateDevices().then(gotDevices2);
+ return;
+ }
+ } // don't close if already open
+ if (getById("popupSelector").style.display == "none") {
+
+ updateConstraintSliders();
+
+ setTimeout(function() {
+ document.addEventListener("click", toggleSettings);
+ }, 10);
+
+ getById("popupSelector").addEventListener("click", function(e) {
+ e.stopPropagation();
+ return false;
+ });
+
+ if (navigator.userAgent.indexOf('Chrome') != -1) {
+ try {
+ navigator.permissions.query({
+ name: "camera"
+ }).then(function(promise) {
+ if (promise && promise.state) {
+ if (promise.state == "prompt") {
+ navigator.mediaDevices.getUserMedia({
+ video: true
+ , audio: false
+ }).then(function(stream) {
+ enumerateDevices().then(gotDevices2).then(function() {
+ stream.getTracks().forEach(function(track) {
+ //stream.removeTrack(track);
+ track.stop(); // clean up?
+ });
+ });
+
+ }).catch(function(err) {
+ enumerateDevices().then(gotDevices2).then(function() {});
+ });
+ } else {
+ enumerateDevices().then(gotDevices2).then(function() {});
+ }
+ // console.log(promise.state); //"granted", "prompt" or "rejected"
+ } else {
+ enumerateDevices().then(gotDevices2).then(function() {});
+ }
+ });
+ } catch (e) {
+ enumerateDevices().then(gotDevices2).then(function() {});
+ }
+ } else {
+ enumerateDevices().then(gotDevices2).then(function() {});
+ }
+
+ getById("popupSelector").style.display = "inline-block"
+ getById("settingsbutton").classList.add("float2");
+ getById("settingsbutton").classList.remove("float");
+ setTimeout(function() {
+ getById("popupSelector").style.right = "0px";
+ }, 1);
+ toggleSettingsState = true;
+ } else {
+ document.removeEventListener("click", toggleSettings);
+ getById("popupSelector").removeEventListener("click", function(e) {
+ e.stopPropagation();
+ return false;
+ });
+
+ getById("popupSelector").style.right = "-400px";
+
+ getById("settingsbutton").classList.add("float");
+ getById("settingsbutton").classList.remove("float2");
+ setTimeout(function() {
+ getById("popupSelector").style.display = "none";
+ }, 200);
+ toggleSettingsState = false;
+ }
+}
+
+function hangup() { // TODO: I need to have this be MUTE, toggle, with volume not touched.
+ getById("main").innerHTML = "👋 ";
+ setTimeout(function() {
+ session.hangup();
+ }, 0);
+}
+
+function hangup2() {
+ session.hangupDirector();
+ getById("miniPerformer").innerHTML = "";
+ getById("press2talk").dataset.value = 0;
+ getById("screensharebutton").classList.add("advanced");
+ getById("settingsbutton").classList.add("advanced");
+ getById("mutebutton").classList.add("advanced");
+ getById("hangupbutton2").classList.add("advanced");
+ //getById("chatbutton").classList.remove("advanced");
+ getById("controlButtons").style.display = "inherit";
+ //getById("mutespeakerbutton").classList.add("advanced");
+ getById("mutevideobutton").classList.add("advanced");
+ getById("screenshare2button").classList.add("advanced");
+
+ getById("screensharebutton").classList.add("float");
+ getById("screensharebutton").classList.remove("float2");
+
+ if (session.showDirector == false) {
+ getById("miniPerformer").innerHTML = ' enable director`s microphone or video (only guests can see this feed) ';
+ } else {
+ getById("miniPerformer").innerHTML = ' enable director`s microphone or video ';
+ }
+ getById("miniPerformer").className = "";
+}
+
+function hangupComplete() {
+ getById("main").innerHTML = "👋 ";
+}
+
+
+function raisehand() {
+ if (session.directorUUID == false) {
+ log("no director in room yet");
+ return;
+ }
+
+ var data = {};
+ data.UUID = session.directorUUID;
+
+ log(data);
+ if (getById("raisehandbutton").dataset.raised == "0") {
+ getById("raisehandbutton").dataset.raised = "1";
+ getById("raisehandbutton").classList.add("raisedHand");
+ data.chat = "Raised hand";
+ log("hand raised");
+ } else {
+ log("hand lowered");
+ getById("raisehandbutton").dataset.raised = "0";
+ getById("raisehandbutton").classList.remove("raisedHand");
+ data.chat = "Lowered hand";
+ }
+ session.sendMessage(data, data.UUID);
+}
+
+function lowerhand() {
+ log("hand lowered");
+ getById("raisehandbutton").dataset.raised = "0";
+ getById("raisehandbutton").classList.remove("raisedHand");
+}
+
+var previousRoom = "";
+var stillNeedRoom = true;
+var transferCancelled = false;
+var armedTransfer = false;
+
+function directMigrate(ele, event) { // everyone in the room will hangup this guest also? I like that idea. What about the STREAM ID? I suppose we don't kick out if the viewID matches.
+ log("directMigrate");
+ if (event === false) {
+ if (previousRoom === null) { // user cancelled in previous callback
+ ele.innerHTML = ' Transfer ';
+ ele.style.backgroundColor = null;
+ return;
+ }
+ if (transferCancelled === true) {
+ ele.innerHTML = ' Transfer ';
+ ele.style.backgroundColor = null;
+ return;
+ }
+ var migrateRoom = previousRoom
+ } else if ((event.ctrlKey) || (event.metaKey)) {
+ ele.innerHTML = ' Armed ';
+ ele.style.backgroundColor = "#BF3F3F";
+ transferCancelled = false;
+ //armedTransfer=true;
+ Callbacks.push([directMigrate, ele, stillNeedRoom]);
+ stillNeedRoom = false;
+ log("Migrate queued");
+ return;
+ // } else if (armedTransfer){
+ //migrateRoom = sanitizeRoomName(previousRoom);
+ } else {
+ if (armedTransfer!==false && previousRoom!==""){
+ var migrateRoom = sanitizeRoomName(previousRoom);
+ } else {
+ window.focus();
+ var migrateRoom = prompt("Transfer guests to room:\n\n(Please note rooms must share the same password)", previousRoom);
+ }
+ stillNeedRoom = true;
+ if (migrateRoom === null) { // user cancelled
+ ele.innerHTML = ' Transfer ';
+ ele.style.backgroundColor = null;
+ transferCancelled = true;
+ return;
+ }
+ try {
+ migrateRoom = sanitizeRoomName(migrateRoom);
+ previousRoom = migrateRoom;
+ } catch (e) {}
+
+ }
+ ele.innerHTML = ' Transfer ';
+ ele.style.backgroundColor = null;
+
+ if (migrateRoom) {
+ previousRoom = migrateRoom;
+
+ var msg = {};
+ msg.request = "migrate";
+ if (session.password) {
+ return session.generateHash(migrateRoom + session.password + session.salt, 16).then(function(rid) {
+ var msg = {};
+ msg.request = "migrate";
+ msg.roomid = rid;
+ msg.target = ele.dataset.UUID;
+ session.sendMsg(msg); // send to everyone in the room, so they know if they are on air or not.
+ });
+ } else {
+ var msg = {};
+ msg.request = "migrate";
+ msg.roomid = migrateRoom;
+ msg.target = ele.dataset.UUID;
+ session.sendMsg(msg); // send to everyone in the room, so they know if they are on air or not.
+ }
+ }
+}
+var stillNeedHangupTarget = 1;
+
+function directHangup(ele, event) { // everyone in the room will hangup this guest? I like that idea.
+ if (event == false) {
+ if (stillNeedHangupTarget === 1) {
+ window.focus();
+ var confirmHangup = confirm("Are you sure you wish to disconnect these users?");
+ stillNeedHangupTarget = confirmHangup;
+ } else {
+ confirmHangup = stillNeedHangupTarget;
+ }
+ } else if ((event.ctrlKey) || (event.metaKey)) {
+ ele.innerHTML = ' ARMED ';
+ ele.style.backgroundColor = "#BF3F3F";
+ stillNeedHangupTarget = 1;
+ Callbacks.push([directHangup, ele, false]);
+ log("Hangup queued");
+ return;
+ } else {
+ window.focus();
+ var confirmHangup = confirm("Are you sure you wish to disconnect this user?");
+ }
+
+ if (confirmHangup) {
+ var msg = {};
+ msg.hangup = true;
+ log(msg);
+ log(ele.dataset.UUID);
+ session.sendRequest(msg, ele.dataset.UUID);
+ //session.anysend(msg); // send to everyone in the room, so they know if they are on air or not.
+ } else {
+ ele.innerHTML = ' Hangup ';
+ ele.style.backgroundColor = null;
+ }
+}
+
+function directEnable(ele, event, scene=1, director=false) { // A directing room only is controlled by the Director, with the exception of MUTE.
+
+ if (!((event.ctrlKey) || (event.metaKey))) {
+ if (ele.dataset.value == 1) {
+ ele.dataset.value = 0;
+ ele.classList.remove("pressed");
+ if (ele.children[1]){
+ ele.children[1].innerHTML = "Add to Scene "+scene;
+ }
+ if (director){
+ if (getById("container_director").querySelectorAll('[data-action-type="addToScene"][data-value="1"]').length==0){
+ getById("container_director").style.backgroundColor = null;
+ }
+ } else {
+ if (getById("container_" + ele.dataset.UUID).querySelectorAll('[data-action-type="addToScene"][data-value="1"]').length==0){
+ getById("container_" + ele.dataset.UUID).style.backgroundColor = null;
+ }
+ }
+ } else {
+ ele.dataset.value = 1;
+ ele.classList.add("pressed");
+ if (ele.children[1]){
+ ele.children[1].innerHTML = "Remove";
+ }
+ if (director){
+ getById("container_director").style.backgroundColor = "#649166";
+ } else {
+ getById("container_" + ele.dataset.UUID).style.backgroundColor = "#649166";
+ }
+ }
+ }
+ var msg = {};
+
+ scene = scene+"";
+
+ msg.scene = scene;
+ msg.action = "display";
+ msg.value = ele.dataset.value;
+ msg.target = ele.dataset.sid;
+
+ for (var uuid in session.pcs){
+ if (session.pcs[uuid].stats.info && ("version" in session.pcs[uuid].stats.info) && (session.pcs[uuid].stats.info.version < 17.2)){
+ msg.request = "sendroom";
+ session.sendMsg(msg);
+ return;
+ }
+ }
+
+ for (var uuid in session.pcs){
+ if (session.pcs[uuid].scene===scene){
+ session.sendMessage(msg, uuid);
+ }
+ }
+}
+
+var previousURL = "";
+var stillNeedURL = true;
+var reloadCancelled = false;
+var armedReload = false;
+
+function directPageReload(ele, event) {
+ log("URL Page reload");
+ if (event === false) {
+ if (previousURL === null) { // user cancelled in previous callback
+ ele.innerHTML = ' Change URL ';
+ ele.style.backgroundColor = null;
+ return;
+ }
+ if (reloadCancelled === true) {
+ ele.innerHTML = ' Change URL ';
+ ele.style.backgroundColor = null;
+ return;
+ }
+ reloadURL = previousURL
+ } else if ((event.ctrlKey) || (event.metaKey)) {
+ ele.innerHTML = ' Armed ';
+ ele.style.backgroundColor = "#BF3F3F";
+ reloadCancelled = false;
+ armedReload=true;
+ Callbacks.push([directPageReload, ele, stillNeedURL]);
+ stillNeedURL = false;
+ log("URL update queued");
+ return;
+ } else if (armedReload){
+ reloadURL = previousURL;
+ } else {
+ window.focus();
+ var reloadURL = prompt("Transfer guests to new website URL.\n\n(Guests will be prompted to accept)", previousURL);
+ stillNeedURL = true;
+ if (reloadURL === null) { // user cancelled
+ ele.innerHTML = ' Change URL ';
+ ele.style.backgroundColor = null;
+ reloadCancelled = true;
+ return;
+ }
+ try {
+ previousURL = reloadURL;
+ } catch (e) {}
+
+ }
+ ele.innerHTML = ' Change URL ';
+ ele.style.backgroundColor = null;
+
+ if (reloadURL) {
+ previousURL = reloadURL;
+
+ var msg = {};
+ msg.changeURL = reloadURL;
+ if (ele.dataset.UUID in session.rpcs){
+ session.rpcs[ele.dataset.UUID].receiveChannel.send(JSON.stringify(msg));
+ }
+ }
+}
+
+function directMute(ele, event=false) { // A directing room only is controlled by the Director, with the exception of MUTE.
+ log("mute");
+ if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
+ if (ele.dataset.value == 0) {
+ ele.dataset.value = 1;
+ ele.classList.remove("pressed");
+ ele.children[1].innerHTML = "Mute in scene";
+ } else {
+ ele.dataset.value = 0;
+ ele.classList.add("pressed");
+ ele.children[1].innerHTML = "Un-mute";
+ }
+ }
+ var msg = {};
+ msg.scene = true;
+ msg.action = "mute";
+ msg.value = ele.dataset.value;
+ msg.target = ele.dataset.sid;
+
+ for (var uuid in session.pcs){
+ if (session.pcs[uuid].stats.info && ("version" in session.pcs[uuid].stats.info) && (session.pcs[uuid].stats.info.version < 17.2)){
+ msg.request = "sendroom";
+ session.sendMsg(msg);
+ return;
+ }
+ }
+
+ for (var uuid in session.pcs){
+ if (session.pcs[uuid].scene!==false){ // send to all scenes (but scene = 0)
+ session.sendMessage(msg, uuid);
+ }
+ }
+}
+
+function remoteSpeakerMute(ele, event=false){
+ log("speaker mute");
+ if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
+ if (ele.dataset.value == 1) {
+ ele.dataset.value = 0;
+ ele.classList.remove("pressed");
+ ele.children[1].innerHTML = "deafen guest";
+ } else {
+ ele.dataset.value = 1;
+ ele.classList.add("pressed");
+ ele.children[1].innerHTML = "Un-deafen";
+ }
+ }
+
+ var msg = {};
+ if (ele.dataset.value == 0) {
+ msg.speakerMute = false
+ } else {
+ msg.speakerMute = true;
+ }
+ msg.UUID = ele.dataset.UUID;
+ session.sendRequest(msg, ele.dataset.UUID);
+}
+
+function updateRemoteSpeakerMute(UUID) {
+ var ele = document.querySelectorAll('[data-action-type="toggle-remote-speaker"][data--u-u-i-d="' + UUID + '"]');
+ if (ele[0]) {
+ ele[0].classList.add("pressed");
+ ele[0].dataset.value = 1;
+ ele[0].children[1].innerHTML = "Un-deafen";
+ }
+}
+
+function updateRemoteDisplayMute(UUID) {
+ var ele = document.querySelectorAll('[data-action-type="toggle-remote-display"][data--u-u-i-d="' + UUID + '"]');
+ if (ele[0]) {
+ ele[0].classList.add("pressed");
+ ele[0].dataset.value = 1;
+ ele[0].children[1].innerHTML = "Un-blind";
+ }
+}
+
+function remoteDisplayMute(ele, event=false) {
+ log("display mute");
+ if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
+ if (ele.dataset.value == 1) {
+ ele.dataset.value = 0;
+ ele.classList.remove("pressed");
+ ele.children[1].innerHTML = "blind guest";
+ } else {
+ ele.dataset.value = 1;
+ ele.classList.add("pressed");
+ ele.children[1].innerHTML = "Un-blind";
+ }
+ }
+
+ var msg = {};
+ if (ele.dataset.value == 0) {
+ msg.displayMute = false;
+ } else {
+ msg.displayMute = true;
+ }
+ msg.UUID = ele.dataset.UUID;
+ session.sendRequest(msg, ele.dataset.UUID);
+}
+
+function remoteLowerhands(UUID) {
+ var msg = {};
+ msg.lowerhand = true;
+ msg.UUID = UUID;
+ session.sendRequest(msg, UUID);
+}
+
+
+function remoteMute(ele, event=false) {
+ log("mute");
+ if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
+ if (ele.dataset.value == 1) {
+ ele.dataset.value = 0;
+ ele.classList.remove("pressed");
+ ele.children[1].innerHTML = "mute guest";
+ } else {
+ ele.dataset.value = 1;
+ ele.classList.add("pressed");
+ ele.children[1].innerHTML = "Un-mute guest";
+ }
+ }
+
+ try {
+ session.rpcs[ele.dataset.UUID].directorMutedState = ele.dataset.mute;
+ var volume = session.rpcs[ele.dataset.UUID].directorVolumeState;
+ } catch (e) {
+ errorlog(e);
+ var volume = 100;
+ }
+
+ var msg = {};
+ if (ele.dataset.value == 0) {
+ msg.volume = volume;
+ } else {
+ msg.volume = 0;
+ }
+ msg.UUID = ele.dataset.UUID;
+ session.sendRequest(msg, ele.dataset.UUID);
+}
+
+function remoteMuteVideo(ele, event=false) {
+ log("video mute");
+
+ if (!event || ((event.ctrlKey) || (event.metaKey))) {
+ ele.children[1].innerHTML = "ARMED";
+ ele.style.backgroundColor = "#BF3F3F";
+ Callbacks.push([remoteMuteVideo, ele, false]);
+ log("video queued");
+ return;
+ } else {
+ if (ele.dataset.value == 1) {
+ ele.dataset.value = 0;
+ ele.classList.remove("pressed");
+ ele.children[1].innerHTML = "hide guest";
+ } else {
+ ele.dataset.value = 1;
+ ele.classList.add("pressed");
+ ele.children[1].innerHTML = "Unhide guest";
+ }
+ ele.style.backgroundColor = null;
+ }
+
+ var msg = {};
+ if (ele.dataset.value == 0) {
+ msg.directVideoMuted = false;
+ } else {
+ msg.directVideoMuted = true;
+ }
+
+ for (var i in session.pcs){
+ msg.target = ele.dataset.UUID;
+
+ if (i === msg.target){
+ msg.target = true;
+ }
+ try{
+ session.pcs[i].sendChannel.send(JSON.stringify(msg));
+ } catch(e){}
+
+ }
+}
+
+function updateDirectorVideoMute(UUID) {
+ var ele = document.querySelectorAll('[data-action-type="hide-guest"][data--u-u-i-d="' + UUID + '"]');
+ if (ele[0]) {
+ ele[0].dataset.value = 1;
+ ele[0].classList.add("pressed");
+ ele[0].children[1].innerHTML = "Unhide guest";
+ }
+}
+
+function directVolume(ele) { // NOT USED ANYMORE
+ log("volume");
+ var msg = {};
+ msg.scene = true;
+ msg.action = "volume";
+ msg.target = ele.dataset.sid; // i want to focus on the STREAM ID, not the UUID...
+ msg.value = ele.value;
+
+ for (var uuid in session.pcs){
+ if (session.pcs[uuid].stats.info && ("version" in session.pcs[uuid].stats.info) && (session.pcs[uuid].stats.info.version < 17.2)){
+ msg.request = "sendroom";
+ session.sendMsg(msg);
+ return;
+ }
+ }
+
+ for (var uuid in session.pcs){
+ if (session.pcs[uuid].scene!==false){ // send to all scenes (but scene = 0)
+ session.sendMessage(msg, uuid);
+ }
+ }
+}
+
+function remoteVolumeUI(ele){
+ ele.nextSibling.innerHTML = ele.value;
+}
+
+function remoteVolume(ele) { // A directing room only is controlled by the Director, with the exception of MUTE.
+ log("volume");
+ var msg = {};
+ var muted = session.rpcs[ele.dataset.UUID].directorMutedState;
+ if (muted == 1) { // 1 is a string, not an int, so == and not ===. this happens in a few places :/
+ session.rpcs[ele.dataset.UUID].directorVolumeState = ele.value;
+ } else {
+ session.rpcs[ele.dataset.UUID].directorVolumeState = ele.value;
+ msg.volume = ele.value;
+ msg.UUID = ele.dataset.UUID;
+ session.sendRequest(msg, ele.dataset.UUID);
+ }
+}
+
+function clearDirectorSettings(){
+ setStorage("directorCustomize", {});
+}
+
+function saveDirectorSettings(){
+ var settings = {};
+
+ console.log("SAVE DIRECTOR SETTING");
+
+ if (getById("customizeLinks").classList.contains("advanced")){
+ settings.customizeLinks = true;
+ }
+
+ var customizeLinks1 = getById("customizeLinks1").querySelectorAll("input");
+ settings.customizeLinks1 = {};
+ for (var i=0;i {
+ customizeLinks1.querySelector('[data-param="'+key+'"]').checked = settings.customizeLinks1[key];
+ customizeLinks1.querySelector('[data-param="'+key+'"]').onchange();
+ });
+ }
+
+ if (settings.customizeLinks3){
+ var customizeLinks3 = getById("customizeLinks3");
+ Object.keys(settings.customizeLinks3).forEach((key, index) => {
+ customizeLinks3.querySelector('[data-param="'+key+'"]').checked = settings.customizeLinks3[key];
+ customizeLinks3.querySelector('[data-param="'+key+'"]').onchange();
+ });
+ }
+
+ if (settings.directorLinks1){
+ var directorLinks1 = getById("directorLinks1");
+ Object.keys(settings.directorLinks1).forEach((key, index) => {
+ directorLinks1.querySelector('[data-param="'+key+'"]').checked = settings.directorLinks1[key];
+ directorLinks1.querySelector('[data-param="'+key+'"]').onchange();
+ });
+ }
+
+ if (settings.directorLinks2){
+ var directorLinks2 = getById("directorLinks2");
+ Object.keys(settings.directorLinks2).forEach((key, index) => {
+ directorLinks2.querySelector('[data-param="'+key+'"]').checked = settings.directorLinks2[key];
+ directorLinks2.querySelector('[data-param="'+key+'"]').onchange();
+ });
+ }
+
+}
+
+
+
+function sendChat(chatmessage = "hi", UUID=false) { // A directing room only is controlled by the Director, with the exception of MUTE.
+ log("Chat message");
+ var msg = {};
+ msg.chat = chatmessage;
+
+ session.sendPeers(msg, UUID);
+}
+
+var activatedStream = false;
+
+function publishScreen() {
+ if (activatedStream == true) {
+ return;
+ }
+ activatedStream = true;
+ setTimeout(function() {
+ activatedStream = false;
+ }, 1000);
+
+ var title = "ScreenShare"; //getById("videoname2").value;
+
+ formSubmitting = false;
+
+ var quality = parseInt(getById("webcamquality2").elements.namedItem("resolution2").value);
+
+ if (session.quality !== false) {
+ quality = session.quality; // override the user's setting
+ }
+
+ if (quality == 0) {
+ 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 = window.constraints = {
+ audio: {
+ echoCancellation: false
+ , autoGainControl: false
+ , noiseSuppression: false
+ }
+ , video: {
+ width: width
+ , height: height
+ }
+ };
+
+ if (session.noiseSuppression === true) {
+ constraints.audio.noiseSuppression = true;; // the defaults for screen publishing should be off.
+ }
+ if (session.autoGainControl === true) {
+ constraints.audio.autoGainControl = true; // the defaults for screen publishing should be off.
+ }
+ if (session.echoCancellation === true) {
+ constraints.audio.echoCancellation = true; // the defaults for screen publishing should be off.
+ }
+
+ try {
+ let supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); // cursor hidding isn't supported by most browsers anyways.
+ if (supportedConstraints.cursor) {
+ constraints.video.cursor = "never";
+ }
+ } catch(e){
+ warnlog("navigator.mediaDevices.getSupportedConstraints() not supported");
+ }
+
+ //if (session.nocursor) { // we assume no cursor on screen share anyways. maybe make a different flag for screenshare cursor
+ // constraints.video.cursor = {
+ // exact: "none"
+ // }; // Not sure this does anything, but whatever.
+ //}
+
+ if (session.framerate !== false) {
+ constraints.video.frameRate = session.framerate;
+ } else if (session.maxframerate != false){
+ constraints.video.frameRate = {
+ ideal: session.maxframerate,
+ max: session.maxframerate
+ };
+ } else {
+ constraints.video.frameRate = {
+ ideal: 60
+ };
+ }
+
+ var audioSelect = getById('audioSourceScreenshare');
+ var outputSelect = getById('outputSourceScreenshare');
+
+ try {
+ session.sink = outputSelect.options[outputSelect.selectedIndex].value; // will probably fail on Safari.
+ log("Session SInk: " + session.sink);
+ if (session.sink == "default") {
+ session.sink = false;
+ }
+ } catch (e){errorlog(e);}
+
+ session.publishScreen(constraints, title, audioSelect).then((res) => {
+ if (res == false) {
+ return;
+ } // no screen selected
+ log("streamID is: " + session.streamID);
+
+ if (session.transcript) {
+ setTimeout(function() {
+ setupClosedCaptions();
+ }, 0);
+ }
+ //session.screenShareState=true;
+ if (!(session.cleanOutput)) {
+ getById("mutebutton").className = "float";
+ getById("mutespeakerbutton").classList.remove("advanced");
+ //getById("mutespeakerbutton").className="float";
+ getById("chatbutton").className = "float";
+ getById("mutevideobutton").className = "float";
+ getById("hangupbutton").className = "float";
+ if (session.showSettings) {
+ getById("settingsbutton").className = "float";
+ }
+ if (session.raisehands) {
+ getById("raisehandbutton").className = "float";
+ }
+ if (session.recordLocal !== false) {
+ getById("recordLocalbutton").className = "float";
+ }
+ if (screensharebutton) {
+ getById("screensharebutton").className = "float2";
+ }
+ getById("controlButtons").style.display = "flex";
+ getById("helpbutton").style.display = "inherit";
+ getById("reportbutton").style.display = "";
+ } else if (session.cleanish && session.recordLocal!==false){
+ getById("recordLocalbutton").className = "float";
+ getById("mutebutton").classList.add("advanced");
+ getById("mutespeakerbutton").classList.add("advanced");
+ getById("chatbutton").classList.add("advanced");
+ getById("mutevideobutton").classList.add("advanced");
+ getById("hangupbutton").classList.add("advanced");
+ getById("hangupbutton2").classList.add("advanced");
+ getById("controlButtons").style.display = "flex";
+ getById("settingsbutton").classList.add("advanced");
+ getById("screenshare2button").classList.add("advanced");
+ getById("screensharebutton").classList.add("advanced");
+ getById("queuebutton").classList.add("advanced");
+ } else {
+ getById("controlButtons").style.display = "none";
+ }
+
+ if (session.chatbutton === true) {
+ getById("chatbutton").classList.remove("advanced");
+ getById("controlButtons").style.display = "inherit";
+ } else if (session.chatbutton === false) {
+ getById("chatbutton").classList.add("advanced");
+ }
+
+ getById("head1").className = 'advanced';
+ getById("head2").className = 'advanced';
+ }).catch(() => {});
+
+}
+
+function publishWebcam(btn = false) {
+ if (btn) {
+ if (btn.dataset.ready == "false") {
+ warnlog("Clicked too quickly; button not enabled yet");
+ return;
+ }
+
+ if (getById("passwordBasicInput").value.length){
+ session.password = getById("passwordBasicInput").value;
+ session.password = sanitizePassword(session.password);
+ if (session.password.length==0){
+ session.password = false;
+ } else {
+ session.defaultPassword = false;
+ if (urlParams.has('pass')) {
+ updateURL("pass=" + session.password);
+ } else if (urlParams.has('pw')) {
+ updateURL("pw=" + session.password);
+ } else if (urlParams.has('p')) {
+ updateURL("p=" + session.password);
+ } else {
+ updateURL("password=" + session.password);
+ }
+ }
+ }
+ }
+
+ if (activatedStream == true) {
+ return;
+ }
+ activatedStream = true;
+ log("PRESSED PUBLISH WEBCAM!!");
+
+ var title = "Webcam"; // getById("videoname3").value;
+ var ele = getById("previewWebcam");
+
+ formSubmitting = false;
+ window.scrollTo(0, 0); // iOS has a nasty habit of overriding the CSS when changing camaera selections, so this addresses that.
+
+ getById("head2").className = 'advanced';
+
+ if (session.roomid !== false) {
+ if ((session.roomid === "") && ((!(session.view)) || (session.view === ""))) {
+ // no room, no viewing, viewing disabled
+ session.manual = true;
+ window.addEventListener("resize", updateMixer);
+ window.addEventListener("orientationchange", function() {
+ setTimeout(updateMixer, 200);
+ });
+ } else {
+ log("ROOM ID ENABLED");
+ log("Update Mixer Event on REsize SET");
+ window.addEventListener("resize", updateMixer);
+ window.addEventListener("orientationchange", function() {
+ setTimeout(updateMixer, 200);
+ });
+ getById("main").style.overflow = "hidden";
+ //session.cbr=0; // we're just going to override it
+
+ if (session.stereo == 5) {
+ if (session.roomid === "") {
+ session.stereo = 1;
+ } else {
+ session.stereo = 3;
+ }
+ }
+ joinRoom(session.roomid);
+ if (session.roomid !== "") {
+ if (!(session.cleanOutput)) {
+ getById("head2").className = '';
+ }
+ }
+ getById("head3").className = 'advanced';
+
+ }
+
+ } else {
+ getById("head3").className = '';
+ getById("logoname").style.display = 'none';
+ }
+
+ log("streamID is: " + session.streamID);
+ getById("head1").className = 'advanced';
+
+
+ if (!(session.cleanOutput)) {
+ getById("mutebutton").className = "float";
+ getById("mutespeakerbutton").classList.remove("advanced");
+ //getById("mutespeakerbutton").className="float";
+ getById("chatbutton").className = "float";
+ getById("mutevideobutton").className = "float";
+ getById("hangupbutton").className = "float";
+ if (session.showSettings) {
+ getById("settingsbutton").className = "float";
+ }
+ if (session.raisehands) {
+ getById("raisehandbutton").className = "float";
+ }
+ if (session.recordLocal !== false) {
+ getById("recordLocalbutton").className = "float";
+ }
+ if (screensharebutton) {
+ if (session.roomid) {
+ getById("screenshare2button").className = "float";
+ getById("screensharebutton").className = "float advanced";
+ } else {
+ getById("screensharebutton").className = "float";
+ getById("screenshare2button").className = "float advanced";
+ }
+ }
+ getById("controlButtons").style.display = "flex";
+ getById("helpbutton").style.display = "inherit";
+ getById("reportbutton").style.display = "";
+ } else if (session.cleanish && session.recordLocal!==false){
+ getById("recordLocalbutton").className = "float";
+ getById("mutebutton").classList.add("advanced");
+ getById("mutespeakerbutton").classList.add("advanced");
+ getById("chatbutton").classList.add("advanced");
+ getById("mutevideobutton").classList.add("advanced");
+ getById("hangupbutton").classList.add("advanced");
+ getById("hangupbutton2").classList.add("advanced");
+ getById("controlButtons").style.display = "flex";
+ getById("settingsbutton").classList.add("advanced");
+ getById("screenshare2button").classList.add("advanced");
+ getById("screensharebutton").classList.add("advanced");
+ getById("queuebutton").classList.add("advanced");
+ } else {
+ getById("controlButtons").style.display = "none";
+ }
+
+ if (session.chatbutton === true) {
+ getById("chatbutton").classList.remove("advanced");
+ getById("controlButtons").style.display = "inherit";
+ } else if (session.chatbutton === false) {
+ getById("chatbutton").classList.add("advanced");
+ }
+
+ if (urlParams.has('permaid')) {
+ updateURL("permaid=" + session.streamID);
+ } else {
+ updateURL("push=" + session.streamID);
+ }
+
+ session.publishStream(ele, title);
+
+}
+
+
+session.publishIFrame = function(iframeURL){
+
+ if (session.transcript){
+ setTimeout(function(){setupClosedCaptions();},0);
+ }
+
+ if (iframeURL==""){
+ iframeURL="./";
+ }
+ if (iframeURL === session.iframeSrc){return;}
+
+ if (iframeURL.startsWith("http://")){
+ try{
+ iframeURL = "https://"+ iframeURL.split("http://")[1];
+ }catch(e){errorlog(e);}
+ }
+
+
+ if (iframeURL.startsWith("https://") || iframeURL.startsWith("http://")){
+ 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);
+ }
+ }
+
+ }
+
+
+ // https://player.twitch.tv/?channel=twitchpresents&parent=vdo.ninja
+
+ session.iframeSrc = iframeURL;
+
+ var container = document.createElement("div");
+ container.id = "container";
+
+ var iframe = document.createElement("iframe");
+ iframe.allow="autoplay;camera;microphone;fullscreen;picture-in-picture";
+ iframe.allowtransparency="true";
+ iframe.allowfullscreen ="true";
+ iframe.src = session.iframeSrc;
+ iframe.id = "iframe_source"
+ session.iframeEle = iframe;
+
+ if (session.roomid!==false){
+
+ window.addEventListener("resize", updateMixer);
+
+ if ((session.roomid==="") && ((!(session.view)) || (session.view===""))){
+
+ } else {
+ log("ROOMID EANBLED");
+ 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";
+ }
+
+
+
+ if (session.director){
+ } else if (session.scene!==false){
+ updateMixer();
+ } else if (session.roomid!==false){
+ if (session.roomid===""){
+ if (!(session.view) || (session.view==="")){
+
+
+ getById("mutespeakerbutton").classList.add("advanced");
+
+ container.style.width="100%";
+ container.style.height="100%";
+ container.style.alignItems = "center";
+ container.style.maxWidth= "1280px";
+ container.style.maxHeight= "720px";
+ container.style.verticalAlign= "middle";
+ container.style.margin= "auto";
+ container.style.backgroundColor = "#666";
+ container.style.border = "2px solid";
+
+ } else {
+ session.windowed = false;
+ updateMixer();
+ }
+ } else {
+
+ session.windowed = false;
+ updateMixer();
+ }
+ } else {
+
+ container.style.maxHeight= "1280px";
+ container.style.maxWidth= "720px";
+ container.style.verticalAlign= "middle";
+ container.style.height="100%";
+ container.style.width= "100%";
+ container.style.margin= "auto";
+ container.style.alignItems = "center";
+ container.style.backgroundColor = "#666";
+ }
+
+ getById("mainmenu").parentElement.removeChild(getById("mainmenu"));
+
+ getById("gridlayout").innerHTML = "";
+ container.appendChild(iframe);
+ getById("gridlayout").appendChild(container);
+
+
+ session.seeding=true;
+
+ getById("reshare").href = "https://"+location.host+location.pathname+"?view="+session.streamID;
+ getById("reshare").text = "https://"+location.host+location.pathname+"?view="+session.streamID;
+ getById("reshare").style.width = ((getById("reshare").text.length + 1)*1.15 * 8) + 'px';
+ pokeIframeAPI('started-iframe-share');
+
+ session.seedStream();
+}
+
+function outboundAudioPipeline(stream) {
+ if (session.disableWebAudio) {
+ var newStream = new MediaStream();
+ stream.getTracks().forEach(function(track) { // this seems to fix a bug with macbooks
+ newStream.addTrack(track, stream);
+ });
+ return newStream;
+ }
+
+ try {
+ log("Web Audio");
+ var tracks = stream.getAudioTracks();
+ if (tracks.length) {
+ for (var waid in session.webAudios) { // TODO: EXCLUDE CURRENT TRACK IF ALREADY EXISTS ... if (track.id === wa.id){..
+ session.webAudios[waid].stop();
+ delete session.webAudios[waid];
+ }
+
+
+ var webAudio = {};
+ webAudio.micDelay = false;
+ webAudio.compressor = false;
+ webAudio.analyser = false;
+ webAudio.gainNode = false;
+
+ webAudio.lowEQ = false;
+ webAudio.midEQ = false;
+ webAudio.highEQ = false;
+
+ webAudio.id = tracks[0].id; // first track is used.
+
+ if (session.audioLatency !== false) { // session.audioLatency could be useful for fixing clicking issues?
+ var audioContext = new AudioContext({
+ latencyHint: session.audioLatency / 1000.0 //, // needs to be in seconds, but VDON user input is via milliseconds
+ // sampleRate: 48000 // not sure this is a great idea, but might as well add this here, versus later on since it is needed anyways.
+ });
+ } else {
+ var audioContext = new AudioContext();
+ }
+
+ webAudio.audioContext = audioContext;
+ webAudio.mediaStreamSource = audioContext.createMediaStreamSource(stream); // clone to fix iOS issue
+ webAudio.destination = audioContext.createMediaStreamDestination();
+ webAudio.gainNode = audioGainNode(webAudio.mediaStreamSource, audioContext);
+
+ var anonNode = webAudio.gainNode;
+
+ if (session.micDelay) {
+ webAudio.micDelay = micDelayNode(anonNode, audioContext);
+ anonNode = webAudio.micDelay;
+ }
+
+ if (session.audioInputChannels == 1) {
+ webAudio.splitter = audioContext.createChannelSplitter(6);
+ anonNode.connect(webAudio.splitter);
+
+ webAudio.merger = audioContext.createChannelMerger(6);
+ webAudio.splitter.connect(webAudio.merger, 0, 0);
+ webAudio.splitter.connect(webAudio.merger, 0, 1);
+ webAudio.splitter.connect(webAudio.merger, 0, 2);
+ webAudio.splitter.connect(webAudio.merger, 0, 3);
+ webAudio.splitter.connect(webAudio.merger, 0, 4);
+ webAudio.splitter.connect(webAudio.merger, 0, 5);
+ anonNode = webAudio.merger;
+ }
+
+
+ if (session.lowcut) { // https://webaudioapi.com/samples/frequency-response/ for a tool to help set values
+ webAudio.lowcut1 = audioContext.createBiquadFilter();
+ webAudio.lowcut1.type = "highpass";
+ webAudio.lowcut1.frequency.value = session.lowcut;
+
+ webAudio.lowcut2 = audioContext.createBiquadFilter();
+ webAudio.lowcut2.type = "highpass";
+ webAudio.lowcut2.frequency.value = session.lowcut;
+
+ webAudio.lowcut3 = audioContext.createBiquadFilter();
+ webAudio.lowcut3.type = "highpass";
+ webAudio.lowcut3.frequency.value = session.lowcut;
+
+ anonNode.connect(webAudio.lowcut1);
+ webAudio.lowcut1.connect(webAudio.lowcut2);
+ webAudio.lowcut2.connect(webAudio.lowcut3);
+ anonNode = webAudio.lowcut3;
+ }
+
+
+ if (session.equalizer) { // https://webaudioapi.com/samples/frequency-response/ for a tool to help set values
+ webAudio.lowEQ = audioContext.createBiquadFilter();
+ webAudio.lowEQ.type = "lowshelf";
+ webAudio.lowEQ.frequency.value = 100;
+ webAudio.lowEQ.gain.value = 0;
+
+ webAudio.midEQ = audioContext.createBiquadFilter();
+ webAudio.midEQ.type = "peaking";
+ webAudio.midEQ.frequency.value = 1000;
+ webAudio.midEQ.Q.value = 0.5;
+ webAudio.midEQ.gain.value = 0;
+
+ webAudio.highEQ = audioContext.createBiquadFilter();
+ webAudio.highEQ.type = "highshelf";
+ webAudio.highEQ.frequency.value = 10000;
+ webAudio.highEQ.gain.value = 0;
+
+ anonNode.connect(webAudio.lowEQ);
+ webAudio.lowEQ.connect(webAudio.midEQ);
+ webAudio.midEQ.connect(webAudio.highEQ);
+ anonNode = webAudio.highEQ;
+ }
+
+ if (session.compressor === 1) {
+ webAudio.compressor = audioCompressor(anonNode, audioContext);
+ anonNode = webAudio.compressor;
+ } else if (session.compressor === 2) {
+ webAudio.compressor = audioLimiter(anonNode, audioContext);
+ anonNode = webAudio.compressor;
+ }
+
+ webAudio.analyser = audioMeter(anonNode, audioContext);
+ webAudio.analyser.connect(webAudio.destination);
+
+ webAudio.stop = function() {
+ try {
+ webAudio.destination.disconnect();
+ } catch (e) {}
+ try {
+ clearInterval(webAudio.analyser.interval);
+ } catch (e) {}
+ try {
+ webAudio.analyser.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.splitter.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.merger.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.lowcut1.disconnect();
+ webAudio.lowcut2.disconnect();
+ webAudio.lowcut3.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.lowEQ.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.midEQ.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.highEQ.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.gainNode.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.micDelay.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.compressor.disconnect();
+ } catch (e) {}
+ try {
+ webAudio.mediaStreamSource.context.close();
+ } catch (e) {}
+ }
+
+ webAudio.mediaStreamSource.onended = function() {
+ webAudio.stop();
+ };
+
+ session.webAudios[webAudio.id] = webAudio;
+
+ stream.getTracks().forEach(function(track) {
+ if (webAudio.id != track.id) {
+ webAudio.destination.stream.addTrack(track, stream);
+ }
+ });
+
+ return webAudio.destination.stream;
+ } else {
+ var newStream = new MediaStream();
+ stream.getTracks().forEach(function(track) { // this seems to fix a bug with macbooks
+ newStream.addTrack(track, stream);
+ });
+ return newStream;
+ //return stream; // no audio track
+ }
+ } catch (e) {
+ errorlog(e);
+ return stream;
+ }
+}
+
+function changeLowCut(freq, trackid = 0) {
+ if (trackid != 0) {
+ errorlog("EQ Doesn't work for anything but track 0. yet");
+ }
+ log("LOW EQ");
+
+ for (var webAudio in session.webAudios) {
+ if (!session.webAudios[webAudio].lowcut1) {
+ errorlog("EQ not setup");
+ return;
+ }
+ if (!session.webAudios[webAudio].lowcut2) {
+ errorlog("EQ not setup");
+ return;
+ }
+ if (!session.webAudios[webAudio].lowcut3) {
+ errorlog("EQ not setup");
+ return;
+ }
+ session.webAudios[webAudio].lowcut1.frequency.setValueAtTime(freq, session.webAudios[webAudio].audioContext.currentTime);
+ session.webAudios[webAudio].lowcut2.frequency.setValueAtTime(freq, session.webAudios[webAudio].audioContext.currentTime);
+ session.webAudios[webAudio].lowcut3.frequency.setValueAtTime(freq, session.webAudios[webAudio].audioContext.currentTime);
+ }
+
+}
+
+function changeLowEQ(lowEQ, trackid = 0) {
+ if (trackid != 0) {
+ errorlog("EQ Doesn't work for anything but track 0. yet");
+ }
+ log("LOW EQ");
+
+ for (var webAudio in session.webAudios) {
+ if (!session.webAudios[webAudio].lowEQ) {
+ errorlog("EQ not setup");
+ return;
+ }
+ session.webAudios[webAudio].lowEQ.gain.setValueAtTime(lowEQ, session.webAudios[webAudio].audioContext.currentTime);
+ }
+
+}
+
+function changeMidEQ(midEQ, trackid = 0) {
+ if (trackid != 0) {
+ errorlog("EQ Doesn't work for anything but track 0. yet");
+ }
+
+ for (var webAudio in session.webAudios) {
+ if (!session.webAudios[webAudio].midEQ) {
+ errorlog("EQ not setup");
+ return;
+ }
+ session.webAudios[webAudio].midEQ.gain.setValueAtTime(midEQ, session.webAudios[webAudio].audioContext.currentTime);
+ }
+
+}
+
+function changeHighEQ(highEQ, trackid = 0) {
+ if (trackid != 0) {
+ errorlog("EQ Doesn't work for anything but track 0. yet");
+ }
+
+ for (var webAudio in session.webAudios) {
+ if (!session.webAudios[webAudio].highEQ) {
+ errorlog("EQ not setup");
+ return;
+ }
+ session.webAudios[webAudio].highEQ.gain.setValueAtTime(highEQ, session.webAudios[webAudio].audioContext.currentTime);
+ }
+
+}
+
+
+function micDelayNode(mediaStreamSource, audioContext) {
+ var delayNode = audioContext.createDelay();
+ if (session.micDelay !== false) {
+ var delay = parseFloat(session.micDelay/1000) || 0;
+ } else {
+ var delay = 0;
+ }
+ delayNode.delayTime.value = delay;
+ mediaStreamSource.connect(delayNode);
+ return delayNode;
+}
+
+function audioGainNode(mediaStreamSource, audioContext) {
+ var gainNode = audioContext.createGain();
+ if (session.audioGain !== false) {
+ var gain = parseFloat(session.audioGain / 100.0) || 0;
+ } else {
+ var gain = 1.0;
+ }
+ gainNode.gain.value = gain;
+ mediaStreamSource.connect(gainNode);
+ return gainNode;
+}
+
+function audioMeter(mediaStreamSource, audioContext) {
+ var analyser = audioContext.createAnalyser();
+ mediaStreamSource.connect(analyser);
+ analyser.fftSize = 256;
+ analyser.smoothingTimeConstant = 0.05;
+
+ var bufferLength = analyser.frequencyBinCount;
+ var dataArray = new Uint8Array(bufferLength);
+
+
+ function draw() {
+ analyser.getByteFrequencyData(dataArray);
+ var total = 0;
+ for (var i = 0; i < dataArray.length; i++) {
+ total += dataArray[i];
+ }
+ total = total / 100;
+
+ if (document.getElementById("meter1")) {
+ if (total == 0) {
+ getById("meter1").style.width = "1px";
+ getById("meter2").style.width = "0px";
+ } else if (total <= 1) {
+ getById("meter1").style.width = "1px";
+ getById("meter2").style.width = "0px";
+ } else if (total <= 150) {
+ getById("meter1").style.width = total + "px";
+ getById("meter2").style.width = "0px";
+ } else if (total > 150) {
+ if (total > 200) {
+ total = 200;
+ }
+ getById("meter1").style.width = "150px";
+ getById("meter2").style.width = (total - 150) + "px";
+ }
+ } else if (session.cleanOutput){
+ return;
+ } else if (document.getElementById("mutetoggle")) {
+ if (total > 200) {
+ total = 200;
+ }
+ total = parseInt(total);
+ document.getElementById("mutetoggle").style.color = "rgb(" + (255 - total) + ",255," + (255 - total) + ")";
+ } else {
+ clearInterval(analyser.interval);
+ warnlog("METERS NOT FOUND");
+ return;
+ }
+ };
+
+ analyser.interval = setInterval(function() {
+ draw();
+ }, 100);
+ return analyser;
+}
+
+
+
+function audioCompressor(mediaStreamSource, audioContext) {
+ var compressor = audioContext.createDynamicsCompressor();
+ compressor.threshold.value = -50;
+ compressor.knee.value = 40;
+ compressor.ratio.value = 12;
+ compressor.attack.value = 0;
+ compressor.release.value = 0.25;
+ mediaStreamSource.connect(compressor);
+ return compressor;
+}
+
+function audioLimiter(mediaStreamSource, audioContext) {
+ var compressor = audioContext.createDynamicsCompressor();
+ compressor.threshold.value = -5;
+ compressor.knee.value = 0;
+ compressor.ratio.value = 20.0; // 1 to 20
+ compressor.attack.value = 0.001;
+ compressor.release.value = 0.1;
+ mediaStreamSource.connect(compressor);
+ return compressor;
+}
+
+
+function activeSpeaker(border=false) {
+ var lastActiveSpeaker = null;
+ var changed = false;
+ for (var UUID in session.rpcs) {
+ if (session.rpcs[UUID].stats._Audio_Loudness_average) {
+ session.rpcs[UUID].stats._Audio_Loudness_average = parseFloat(session.rpcs[UUID].stats.Audio_Loudness*0.2 + session.rpcs[UUID].stats._Audio_Loudness_average*0.8);
+ } else {
+ session.rpcs[UUID].stats._Audio_Loudness_average = 1;
+ }
+ //log(session.rpcs[UUID].stats._Audio_Loudness_average);
+ if (session.rpcs[UUID].stats._Audio_Loudness_average > 13) {
+
+ if (border) {
+ if (session.rpcs[UUID].videoElement) {
+ session.rpcs[UUID].videoElement.style.border = "green solid 1px";
+ session.rpcs[UUID].videoElement.style.padding = "0";
+ }
+ } else if (!session.rpcs[UUID].activelySpeaking){
+ session.rpcs[UUID].activelySpeaking = true;
+ changed = true;
+ lastActiveSpeaker = UUID;
+ session.rpcs[UUID].stats._Audio_Loudness_average+=2000000;
+ }
+
+ } else if (session.rpcs[UUID].stats._Audio_Loudness_average > 6) {
+
+ } else {
+ if (border){
+ if (session.rpcs[UUID].videoElement) {
+ session.rpcs[UUID].videoElement.style.border = "";
+ session.rpcs[UUID].videoElement.style.padding = "1px";
+ }
+ } else if (session.rpcs[UUID].activelySpeaking) {
+ changed = true;
+ session.rpcs[UUID].activelySpeaking=false;
+ lastActiveSpeaker = UUID;
+ }
+ }
+ }
+
+ var speaker = false;
+ for (var UUID in session.rpcs) {
+ if (session.rpcs[UUID].activelySpeaking){speaker=true;}
+ }
+
+ if (!speaker && lastActiveSpeaker && (session.nopreview || session.minipreview || (session.scene!==false) || (session.permaid === false))){
+ session.rpcs[lastActiveSpeaker].activelySpeaking=true;
+ } else if (changed) {
+ setTimeout(function(){updateMixer();},0);
+ }
+}
+
+
+
+function randomizeArray(unshuffled) {
+
+ var arr = unshuffled.map((a) => ({
+ sort: Math.random(), value: a
+ })).sort((a, b) => a.sort - b.sort).map((a) => a.value); // shuffle once
+
+ for (var i = arr.length - 1; i > 0; i--) { // shuffle twice
+ var j = Math.floor(Math.random() * (i + 1));
+ var tmp = arr[i];
+ arr[i] = arr[j];
+ arr[j] = tmp;
+ }
+ return arr
+}
+
+function joinRoom(roomname) {
+ if (roomname.length) {
+ roomname = sanitizeRoomName(roomname);
+ log("Join room");
+ log(roomname);
+ session.joinRoom(roomname).then(function(response) { // callback from server; we've joined the room. Just the listing is returned
+
+ if (session.joiningRoom === "seedPlz") { // allow us to seed, now that we have joined the room.
+ session.joiningRoom = false; // joined
+ session.seedStream();
+ } else {
+ session.joiningRoom = false; // no seeding callback
+ }
+
+ log("Members in Room");
+ log(response);
+
+ if (session.randomize === true) {
+ response = randomizeArray(response);
+ log("Randomized List of Viewers");
+ log(response);
+ for (var i in response) {
+ if ("UUID" in response[i]) {
+ if ("streamID" in response[i]) {
+ if (response[i].UUID in session.rpcs) {
+ log("RTC already connected"); /// lets just say instead of Stream, we have
+ } else {
+ log(response[i].streamID);
+ var streamID = session.desaltStreamID(response[i].streamID);
+ if (session.queue){
+ if (session.directorUUID === response[i].UUID){
+ play(streamID);
+ } else if (session.queueList.length<5000){
+ if (!session.queueList.includes(streamID)){
+ session.queueList.push(streamID);
+ }
+ }
+ } else {
+ log("STREAM ID DESALTED 3: " + streamID);
+ setTimeout(function(sid) {
+ play(sid);
+ }, (Math.floor(Math.random() * 100)), streamID); // add some furtherchance with up to 100ms added latency
+ }
+ }
+ }
+ }
+ }
+ } else {
+ for (var i in response) {
+ if ("UUID" in response[i]) {
+ if ("streamID" in response[i]) {
+ if (response[i].UUID in session.rpcs) {
+ log("RTC already connected"); /// lets just say instead of Stream, we have
+ } else {
+ log(response[i].streamID);
+ var streamID = session.desaltStreamID(response[i].streamID);
+ if (session.queue){
+ if (session.directorUUID === response[i].UUID){
+ play(streamID);
+ } else if (session.queueList.length<5000){
+ if (!session.queueList.includes(streamID)){
+ session.queueList.push(streamID);
+ }
+ }
+ } else {
+ log("STREAM ID DESALTED 3: " + streamID);
+ play(streamID); // play handles the group room mechanics here
+ }
+ }
+ }
+ }
+ }
+ }
+ session.updateQueue();
+ }, function(error) {
+ return {};
+ });
+ } else {
+ log("Room name not long enough or contained all bad characaters");
+ }
+}
+
+function createRoom(roomname = false) {
+
+ if (roomname == false) {
+ roomname = getById("videoname1").value;
+ roomname = sanitizeRoomName(roomname);
+
+ clearDirectorSettings();
+
+ if (roomname.length != 0) {
+ if (urlParams.has('dir')){
+ updateURL("dir=" + roomname, true, false); // make the link reloadable.
+ } else {
+ updateURL("director=" + roomname, true, false); // make the link reloadable.
+ }
+ }
+ }
+ if (roomname.length == 0) {
+ if (!(session.cleanOutput)) {
+ warnUser("Please enter a room name before continuing");
+ }
+ return;
+ }
+ log(roomname);
+ session.roomid = roomname;
+
+ getById("dirroomid").innerHTML = decodeURIComponent(session.roomid);
+ getById("roomid").innerHTML = session.roomid;
+
+ var passwordRoom = getById("passwordRoom").value;
+ passwordRoom = sanitizePassword(passwordRoom);
+ if (passwordRoom.length) {
+ session.password = passwordRoom;
+ session.defaultPassword = false;
+
+ if (urlParams.has('pass')) {
+ updateURL("pass=" + session.password);
+ } else if (urlParams.has('pw')) {
+ updateURL("pw=" + session.password);
+ } else if (urlParams.has('p')) {
+ updateURL("p=" + session.password);
+ } else {
+ updateURL("password=" + session.password);
+ }
+ }
+
+ var passAdd = "";
+ var passAdd2 = "";
+
+ if ((session.defaultPassword === false) && (session.password)) {
+ passAdd2 = "&password=" + session.password;
+ return session.generateHash(session.password + session.salt, 4).then(function(hash) {
+ passAdd = "&hash=" + hash;
+ createRoomCallback(passAdd, passAdd2);
+ });
+ } else {
+ createRoomCallback(passAdd, passAdd2);
+ }
+}
+
+function hideDirectorinvites(ele, skip=true) {
+
+ if (getById("directorLinks2").style.display == "none") {
+ ele.innerHTML = ' LINKS (GUEST INVITES & SCENES) ';
+ getById("directorLinks2").style.display = "inline-block";
+ getById("customizeLinks").classList.remove("advanced");
+ } else {
+ ele.innerHTML = ' LINKS (GUEST INVITES & SCENES) '
+ getById("directorLinks2").style.display = "none";
+ getById("help_directors_room").style.display = "none";
+ getById("roomnotes2").style.display = "none";
+ getById("customizeLinks").classList.add("advanced");
+ }
+ if (getById("directorLinks1").style.display == "none") {
+ getById("directorLinks1").style.display = "inline-block";
+ getById("customizeLinks").classList.remove("advanced");
+ } else {
+ getById("directorLinks1").style.display = "none";
+ getById("help_directors_room").style.display = "none";
+ getById("roomnotes2").style.display = "none";
+ getById("customizeLinks").classList.add("advanced");
+
+ }
+ if (skip){
+ saveDirectorSettings();
+ }
+}
+
+function createRoomCallback(passAdd, passAdd2) {
+
+ var gridlayout = getById("gridlayout");
+ gridlayout.classList.add("directorsgrid");
+
+ var broadcastFlag = getById("broadcastFlag");
+ try {
+ if (broadcastFlag.checked) {
+ broadcastFlag = true;
+ } else {
+ broadcastFlag = false;
+ }
+ } catch (e) {
+ broadcastFlag = false;
+ }
+
+ var broadcastString = "";
+ if (broadcastFlag) {
+ broadcastString = "&broadcast";
+ getById("broadcastSlider").checked = true;
+ }
+
+ var pie = "";
+ if (session.pie){
+ if (session.pie!==true){
+ pie = "&pie="+session.pie;
+ }
+ }
+
+ var showdirectorFlag = getById("showdirectorFlag");
+ try {
+ if (showdirectorFlag.checked) {
+ showdirectorFlag = true;
+ } else {
+ showdirectorFlag = false;
+ }
+ } catch (e) {
+ showdirectorFlag = false;
+ }
+
+ if (showdirectorFlag) {
+ updateURL("showdirector", true, false);
+ session.showDirector = true;
+ //getById("broadcastSlider").checked=true;
+ }
+
+
+ var codecGroupFlag = getById("codecGroupFlag");
+
+ if (codecGroupFlag.value) {
+ if (codecGroupFlag.value === "vp9") {
+ codecGroupFlag = "&codec=vp9";
+ getById("codech264toggle").disabled=true;
+ } else if (codecGroupFlag.value === "h264") {
+ codecGroupFlag = "&codec=h264";
+ getById("codech264toggle").checked=true;
+ } else if (codecGroupFlag.value === "vp8") {
+ codecGroupFlag = "&codec=vp8";
+ getById("codech264toggle").disabled=true;
+ } else if (codecGroupFlag.value === "av1") {
+ codecGroupFlag = "&codec=av1";
+ getById("codech264toggle").disabled=true;
+ } else {
+ codecGroupFlag = "";
+ }
+ } else {
+ codecGroupFlag = "";
+ }
+ if (codecGroupFlag) {
+ session.codecGroupFlag = codecGroupFlag;
+ }
+
+ formSubmitting = false;
+
+ var m = getById("mainmenu");
+ m.remove();
+
+ getById("head1").className = 'advanced';
+ getById("head2").className = 'advanced';
+ //getById("head3").className = 'advanced';
+ getById("head4").className = '';
+
+ try {
+ if (session.label === false) {
+ document.title = "Control Room";
+ }
+ } catch (e) {
+ errorlog(e);
+ };
+
+ session.director = true;
+ screensharesupport = false;
+
+ window.addEventListener("resize", updateMixer);
+ window.addEventListener("orientationchange", updateMixer);
+ getById("reshare").parentNode.removeChild(getById("reshare"));
+
+
+ //getById("mutespeakerbutton").style.display = null;
+ session.speakerMuted = true; // the director will start with audio playback muted.
+ toggleSpeakerMute(true);
+
+
+ if (session.cleanDirector == false) {
+
+ getById("roomHeader").style.display = "";
+ //getById("directorLinks").style.display = "";
+ getById("directorLinks1").style.display = "inline-block";
+ getById("directorLinks2").style.display = "inline-block";
+
+
+ getById("director_block_1").dataset.raw = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd + pie;
+ getById("director_block_1").href = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd + pie;
+ getById("director_block_1").innerText = "https://" + location.host + location.pathname + "?room=" + session.roomid + broadcastString + passAdd + pie;
+
+
+ getById("director_block_3").dataset.raw = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2 + pie;
+ getById("director_block_3").href = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2 + pie;
+ getById("director_block_3").innerText = "https://" + location.host + location.pathname + "?scene&room=" + session.roomid + codecGroupFlag + passAdd2 + pie;
+
+ getById("calendarButton").style.display = "inline-block";
+
+
+ } else {
+ getById("guestFeeds").innerHTML = '';
+ }
+ getById("guestFeeds").style.display = "";
+
+ if (!(session.cleanOutput)) {
+ if (session.queue){
+ getById("queuebutton").classList.remove("advanced");
+ }
+ getById("chatbutton").classList.remove("advanced");
+ getById("controlButtons").style.display = "inherit";
+ getById("mutespeakerbutton").classList.remove("advanced");
+ getById("websitesharebutton").classList.remove("advanced");
+
+ if (session.totalRoomBitrate){
+ getById("roomsettingsbutton").classList.remove("advanced");
+ }
+
+ if (session.showDirector == false) {
+ getById("miniPerformer").innerHTML = ' enable director`s microphone or video (only guests can see this feed) ';
+ } else {
+ getById("miniPerformer").innerHTML = ' enable director`s microphone or video ';
+ }
+ getById("miniPerformer").className = "";
+
+ var tabindex = 26;
+ if (session.rooms && session.rooms.length > 0){
+ var container = getById("rooms");
+ container.innerHTML += 'Arm Transfer: ';
+ session.rooms.forEach(function (r) {
+ if(session.roomid == r) return; //don't include self
+ container.innerHTML += ' ' + r + ' ';
+ tabindex++;
+ });
+ }
+
+ } else {
+ getById("miniPerformer").style.display = "none";
+ getById("controlButtons").style.display = "none";
+ }
+
+ if (session.chatbutton === true) {
+ getById("chatbutton").classList.remove("advanced");
+ getById("controlButtons").style.display = "inherit";
+ } else if (session.chatbutton === false) {
+ getById("chatbutton").classList.add("advanced");
+ }
+
+ clearInterval(session.updateLocalStatsInterval);
+ session.updateLocalStatsInterval = setInterval(function(){updateLocalStats();},3000);
+
+ setTimeout(function(){loadDirectorSettings();},100);
+
+ joinRoom(session.roomid);
+
+ if (session.autostart){
+ setTimeout(function(){press2talk(true);},400);
+ } else {
+ session.seeding=true;
+ session.seedStream();
+ }
+}
+/**
+ * Handles click actions on the room selection buttons in #controlButtons
+ * @param {string} room - Room name to select/deselect for the next transfer call
+ */
+function handleRoomSelect(room) {
+ var elems = document.querySelectorAll(".btnArmTransferRoom");
+ [].forEach.call(elems, function(el) {
+ el.classList.remove("selected");
+ });
+ if (previousRoom == room) {
+ previousRoom = "";
+ armedTransfer = false;
+ stillNeedRoom = true;
+ } else {
+ previousRoom = room;
+ stillNeedRoom = false;
+ armedTransfer = true;
+ getById("roomselect_" + room).classList.add('selected');
+ }
+}
+
+function getDirectorSettings(scene){
+ var settings = {};
+ var eles = document.querySelectorAll('[data-action-type="solo-video"]');
+ settings.soloVideo = false;
+ for (var i=0;i\
+ \
+ Add a label \
+ \
+
\
+
" + soloLink + "\
+
copy Solo link\
+
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 = '
Scene: '+scene+'';
+ 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 + "\
+
copy Solo link\
+
\
+
\
+ \
+ Lower Raised Hand \
+ \
+
";
+
+ 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
+ }
+ getById("advanced_audio_director_" + UUID).appendChild(audioSelect);
+ getById("advanced_audio_director_" + UUID).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 ((audioList[i].value == "default") && (session.echoCancellation !== false) && (session.autoGainControl !== false) && (session.noiseSuppression !== false)) {
+ var constraint = {
+ audio: true
+ };
+ } 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{
+ session.rpcs[UUID].videoElement.pause().then(() => {
+ setTimeout(function(uuid) {
+ 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 (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 {
+ const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] });
+
+ const selectionElem = document.createElement('div');
+ selectionElem.classList = 'desktop-capturer-selection';
+ selectionElem.innerHTML = `
+
+ `;
+ 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() {
+ warnUser(err);
+ }, 1); // 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();
+ 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 ((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();},0);
+ }
+
+ 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();
+
+};
+
+
+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.obs.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==="")){
+
+ if (session.fullscreen){
+ session.windowed = false;
+ } else {
+ v.className = "myVideo";
+ session.windowed = true;
+ }
+ getById("mutespeakerbutton").classList.add("advanced");
+
+ 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 {
+
+ if (session.fullscreen){
+ session.windowed = false;
+ } else {
+ v.className = "myVideo";
+ session.windowed = true;
+ }
+ getById("mutespeakerbutton").classList.add("advanced");
+
+ 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();},0);
+ }
+
+ 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);
+ window.addEventListener("orientationchange", updateMixer);
+ 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";
+ 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);
+ } else if (session.roomid!==false){
+ if (session.roomid===""){
+ if (!(session.view) || (session.view==="")){
+
+ if (session.fullscreen){
+ session.windowed = false;
+ } else {
+ v.className = "myVideo clean";
+ 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);
+ }
+ } 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);
+ }
+ } else {
+
+
+ if (session.fullscreen){
+ session.windowed = false;
+ } else {
+ v.className = "myVideo clean";
+ 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";
+ iframe.allowtransparency = "true";
+ iframe.allowfullscreen = "true";
+ 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";
+ iframe.allowtransparency = "true";
+ iframe.allowfullscreen = "true";
+ 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;
+
+function setupClosedCaptions() {
+ 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");
+ };
+ Recognition.onerror = function(event) {
+ errorlog(event);
+ try {
+ Recognition.stop();
+ } catch (e) {}
+ setTimeout(function() {
+ setupClosedCaptions();
+ }, 0); // restart it if it fails.
+ };
+ Recognition.onend = function(e) {
+ warnlog(e);
+ log("Stopped transcription");
+ setTimeout(function() {
+ setupClosedCaptions();
+ }, 0); // restart it if it fails.
+ };
+
+ 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) && (session.audioDevice !== 1)) { // 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;
+ session.iframeEle = null;
+ 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;
+
+ var iframe = document.createElement("iframe");
+ iframe.allow="autoplay;camera;microphone;fullscreen;picture-in-picture";
+ iframe.allowtransparency="true";
+ iframe.allowfullscreen ="true";
+ iframe.src = session.iframeSrc;
+ iframe.id = "iframe_source"
+ session.iframeEle = iframe;
+
+ 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";
+ 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(input.dataset.param);
+ if (input.checked) {
+
+ getById("director_block_" + arg).dataset.raw += input.dataset.param;
+
+ var string = getById("director_block_" + arg).dataset.raw;
+
+ if (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 (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(input.dataset.param);
+ if (!(input.checked)) {
+
+ getById("director_block_" + arg).dataset.raw += input.dataset.param;
+
+ var string = getById("director_block_" + arg).dataset.raw;
+
+ if (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 (getById("obfuscate_director_" + arg).checked) {
+ string = obfuscateURL(string);
+ }
+
+ getById("director_block_" + arg).href = string;
+ getById("director_block_" + arg).innerText = string;
+ }
+}
+
+function updateLinkScene(arg, input) {
+ 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 (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 = ' \
+ and don\'t forget theOBS Browser Source Link: ' + viewstr + ' \
+ \
+ This invite link and OBS ingestion link are reusable. Only one person may use a specific invite at a time. Create Another Invite Link ';
+ 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 = ' Scene: '+scene+' ';
+ 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 = ' Scene: '+scene+' ';
+ getById("container_" + UUID).appendChild(newScene);
+ }
+
+ if (session.showDirector){
+ if (document.getElementById("container_director")){
+ var newScene = document.createElement("div");
+ newScene.innerHTML = ' Scene: '+scene+' ';
+ 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. Retry Manually ';
+
+ }
+ }
+ } 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 {
+ 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));
+
+});
+
+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;
+ }
+
+ 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 = "auto";
+ textOverlay.style.textAlign = "left";
+ textOverlay.style.display = "block";
+ textOverlay.style.position = "relative";
+ }
+ 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");
+ 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();}
+}
+
+
+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();
+ }
+ }
+ }
+ });
+ 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]);
+ }
+ }
+ }
+ }
+ });
+ }
+ });
+ };
+ 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);}
+ }
+ }
+ } 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];
+}
+
+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.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();
+});
+
+
+// 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."
+ );
+ }
+ });
diff --git a/webrtc.js b/webrtc.js
index 866b88f..baac93f 100644
--- a/webrtc.js
+++ b/webrtc.js
@@ -1,9 +1,9 @@
-/*
-* Copyright (c) 2020 Steve Seguin. All Rights Reserved.
-*
-* This file is part of OBS.Ninja, yet is not intended to be modified.
-* This file cannot be modified without the express permission of its author.
-* No warranty, explicit or implicit, provided.
-*
-*/
-var _0x4e0f=['type','iceServers','mgICo','Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit','connectPeer','FORCE\x20KEYFRAME\x20FOR\x20SCENE','audioInputChannels','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x202','setResolution','generateHash','elUNs','processDescription','scale','muted_savedState','sticky','_timestampStart','maxptime','onopen','has','userAgent','nqESF','fromCharCode','length','vector','focus','ab_url','Someone\x20Joined\x20the\x20Room\x20with\x20a\x20video','streams','requestAudioRateLimit','OxvzX','could\x20not\x20be\x20sent;\x20queuing\x20it','HhUeW','float','firstPlayTriggered','vb_url','obsninja','228589ehVWUA','wss','stun:stun.l.google.com:19302','currentTime','done\x20clearing\x20audio','bsUKL','packetsLost','oninactive','_last_time','bandwidth','iframeSrc','optimizedBitrate','stopPropagation','send\x20channel\x20closed','\x0aPress\x20OK\x20to\x20be\x20redirected.','sceneSync','requestFocusChange','CxAPH','obsStateSync','\x20x\x20','agc_url','createOffer','max','visibility','querySelectorAll','fSjDB','nAzCF','turns:www.turn.obs.ninja:443','ICE\x20target\x20no\x20longer\x20exists?','remove','speakerMute','applySoloChat','sourceActive','Remote\x20peer\x20disconnected.\x20Due\x20to\x20enhanced\x20security,\x20please\x20refresh\x20to\x20create\x20a\x20new\x20connection.','obsfix','cleanDirector','subtle','label_','zFtXZ','hash','signData','32284CNASeD','Transferred','trackIdentifier','Pinging','changeLabel','localCandidateId','pliDelta','framesDecoded','hJcoH','RECONNECTING\x20to\x20HSS;\x20DISCONNECTING\x20FROM\x20TRANSFERRED\x20ROOM','FPS','does\x20any\x20audio\x20exist?','Message\x20to\x20be\x20sent:\x20','steves','span','setVideoBitrate','hash\x20is\x20not\x20false','bigmutebutton','equalizer','requestVideoRecord','sendMessage','Someone\x20sent\x20us\x20an\x20ANSWER\x20sdp??','videoaddedtoroom','getSenders','playoutdelay','stringify','VrYOV','RTC\x20Connection','createDataChannel','getVideoSettings','gridlayout','done\x20replacing/adding\x20tracks','reverse','LvOGG','lRvkE','cbr','pleaseDoNotAbuse','already\x20closed\x20PCS','limitBitrate','toggleSoloChat','ZcFmE','Android','zeWAp','localVoiceMeter','sdp','labelstyle','problem','Couldn\x27t\x20re-connect','_jitter_count','onclose','nopreview','iCMHS','removeChild','screenShareState','fPMsv','showDirector','SoyDm','apply','SDP\x20Sessions\x20Match.\x20I\x20assume\x20ADDING\x20TRACKS','guest','encodering\x20being\x20kicked','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!','empty\x20ice..','noiframe','taintedSession','obs','savedBitrate','screensharequality','queue','no\x20audio\x20track\x20to\x20poke','CeCox','getTracks','AmnRx','nominated','obsstudio','keyFramesRequested_pli','directorSpeakerMuted','showlabels','DTlEf','pre\x20pixel\x20fix\x20','local_relayIP','message','connect','MEawt','channel','minptime','GOT\x20ICEs!!','return\x20/\x22\x20+\x20this\x20+\x20\x22/','next\x20stream\x20loading:\x20','recording_audio_pipeline','Answer\x20SDP\x20does\x20not\x20have\x20a\x20matching\x20session\x20ID','packetLoss_in_percentage','state','bvOzr','fZQCS','enhance_audio','_codecIdTrackId','framerate','nmQMX','mid','reportbutton','QHmwI','directorVideoMuted','playback_audio_samplerate','rrzcN','warn','Final\x20streamID:\x20','addTrack','bQMTW','hangup','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. ','firefox','noNacks','bmFwq','NfpFU','TOO\x20MANY\x20PUBLISHING\x20PEERS','bitrateTimeout','Bmjbs','webAudios','screenshareid','running','streamErrors_nackCount','mag','streaming','https://','relative','pip','parse','scaleResolution','inbound-rtp','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x201','sendChannel','recordLocal','permaid','sendroom','stun:stun4.l.google.com:19302','Buffer_Delay_in_ms','successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS\x20to\x20all\x20RTC\x20Peers','img','changeParams','cZbyB','_frameHeight','RTCRtpSender','directorSpeakerMute','keys','Unhandeled\x20Error\x20occured','enc','sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message;\x20RTC\x20peers\x20only','HBbbc','roombitrate','RNQhA','SDP\x20Sessions\x20do\x20not\x20match.\x20Do\x20I\x20delete\x20an\x20accept\x20this\x20new\x20SDP?','OOO','chat','stereo_url','LrVVH','WOWqy','SuiHw','urls','transport','changeSpeaker','suspended','noaudio','getSettings','remote','STREAM\x20ID\x20desalted\x202:','width','enhanceAudioEncoder','hands_','onicecandidate','_packetsReceived','turn:turn-eu2.obs.ninja:3478','generateCrypto','AwGoX','directorViewBitrate','createElement','scaleDueToBitrate','removeTrack','rmXvM','directorSettings','cloneNode','request','dataset','disableWebAudio','sign','JvEXX','_framesDecoded','connected','requestRateLimit','resolution\x20scale','position','ICE\x20FAILED','PCS\x20WINS\x20ICE','new-push-connection','charAt','audio_delay\x20:\x20','KGAhZ','1vh','currentTarget','watchTimeoutList','href','directorVolumeState','audiobitrate','AudioContext','URVLE','session.videoElement.srcObject\x20failed;\x20but\x20streamSrc\x20worked?','SqhjV','turn:turn.obs.ninja:3478','reduce','pressed','maxframerate_q2','PHEdn','getTime','nocursor','audio_level','QRCVq','call','soloChatUUID','pjNUb','enhanceAudio','midiOut','getOpusBitrate','answer','hTyhL','novideo','getRandomValues','changeMicrophone','zoom','replace','GovEt','IYtYe','encodings','32071YCqRkj','right','ptime','_jitter_delay','ZLLvn','8px','getCapabilities','fullscreen','resolution\x20scale:\x20','24668UzqsMZ','directVideoMuted','directorDisplayMute','toString','allowVideo','allowAudio','AES-CBC','sceneList','keyframeTimeout','what\x20is\x20this?','hssConnection','pixelFix','^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}','stop','publicKey','configuration','dropped\x20candidate\x20due\x20to\x20filter','encryptMessage','oARwN','WdKUp','remote_networkType','signature','disabled','acc','autostart','voePV','join','decryptMessage','manualBandwidth','remoteMuteState_','nackTrigger','roomenc','PCS:\x20ICE\x20Disconnected;\x20wait\x20for\x20retry?\x20pcs','mimeType','OBS\x20PLI\x20FIX\x20MODE\x20ON','info','AUOSp','fOmOY','nJSsl','VpOvt','FORCING\x20A\x20KEY\x20FRAME:\x20','block','limitAudioEncoder','ROOMID\x20EANBLED','codecs','indexOf','Audio\x20Track','left','webcamonly','sendKeyFrameScenes','bitrate_set','5317akfoKi','onconnectionstatechange','received\x20data\x20from\x20viewer','remote_relayProtocol','unified-plan','sCdWn','successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS','close','videoDevice','focusDistance','msg\x20size\x20error','MORE\x20THAN\x20ONE\x20VIDEO\x20TRACK\x20IS\x20BEING\x20ADDED','chatbutton','split','VIDEO\x20TRACK;\x20already\x20one\x20added','audioMeterGuest','VdGJE','CLOSED','qeyEZ','The\x20director\x20wishes\x20to\x20redirect\x20you\x20to\x20the\x20URL:\x20','someonejoined','innerHTML','WEBRTC\x20CONNECTION\x20OPEN','oTdoo','setParameters','ICE\x20Disconnected;\x20wait\x20for\x20retry?\x20rpcs','null\x20ice\x20rpcs','GOT\x20ICES!!','onerror','&password=','local_relayProtocol','recording_audio_compressor_type','Does\x20Local\x20Stream\x20Source\x20EXIST?','HKPCw','scaleHeight','qzYwp','local-candidate','LtKXk','turns:turn.obs.ninja:443','joinroom','anyrequest','video/VP8','listing','reconnected','list','obLoT','keyname','then','xbbMg','EVENT\x20TRACK\x20instead\x20of\x20event\x20Stream','You\x27ve\x20been\x20transferred','audioCodecs','createObjectURL','remoteZoom','YjAHs','getReceivers','offer','[data-action-type=\x22volume\x22][data--u-u-i-d=\x22','ZhLOT','KDZRV','CONNECTED\x20TO\x20FIRST\x20PEER','changeURL','match','title','deferring\x20with\x20a\x20promise','NZgDZ','Adjusting\x20Gain;\x20only\x20track\x200\x20in\x20all\x20likely\x20hood,\x20unless\x20more\x20than\x20track\x200\x20support\x20is\x20added.','Websockets\x20timed\x20out;\x2020\x20seconds','optimizeBitrate','min','uanel','Incoming\x20Ice\x20Offer\x20does\x20not\x20match\x20Session','You\x27ve\x20been\x20transferred\x20to\x20a\x20different\x20room','Un-mute\x20guest','FxfDZ','udp','czVxf','kddtq','PUBLISHER\x27s\x20RTC\x20Connection\x20seems\x20to\x20be\x20dead?\x20','outboundAudioBitrate','Not\x20director','lowerhand','dLHGN','TRYING\x20TO\x20RECONNECT\x203','actual\x20bitrate:','autoGainControl','verify','playoutDelayHint','audioGain','hRLnQ','website','obsVisibility','audioOptions','width_url','delay','bytesReceived','10px','uZine','password','children','ezBGf','SyAuM','\x20is\x20not\x20defined;\x20skipping.','disableNACK','hostname','byteLength','Resolution','request\x20focus\x20change:\x20','_bytesReceived','Room\x20is\x20already\x20claimed\x20by\x20someone\x20else.','audioLatency','setAudioBitrate','Someone\x20published\x20a\x20video\x20to\x20the\x20Room','mediaType','seed','totalRoomBitrate_default','OkzsZ','jgItG','add','find','frameWidth','raisehands','Not\x20a\x20scene','createAnswer','HFgVD','remote_candidateType','providing\x20answer','disconnectedTimeout','Tscwp','safari','maxframerate','playback_audio_pipeline','activelySpeaking','Firefox','forcePLI','allowIframe','BFiPR','sXkEq','MkrDQ','Dhxvb','pEFsZ','credential','oniceconnectionstatechange','dHMAx','zzaAn','lowiosviewers','exclude','Uduly','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.','test','Unable\x20to\x20set\x20update\x20OBS\x20Visibility','remoteVideoMuteElement','labelsize','substring','maxpublishers','videosource','click','lin','metaKey','ptoIx','transparent','pluginVersion','start','stereo','candidates','webPquality','ejZrN','WNnpk','recordedBlobs','keyframerate','remoteDescription','privateKey','startTime','CfGEU','muteStateTemplate','noPLIs','broadcast','AQAB','processIceBundle','scaleResolutionDownBy\x20set\x202!','mutedState','scene','windowed','pcs','chrome','IarPO','outputDevice','keyframe','salt','audio\x20bandwidth\x20set!','cleanOutput','stats','Audio\x20processing\x20is\x20disabled\x20with\x20this\x20guest.\x20Can\x27t\x20mute\x20or\x20change\x20volume','Media','lsLge','maxconnections','nextQueue','voiceMeterTemplate','localDescription','session','version','mxKIs','onremovetrack','audioConstraints','map','checking','delayTime','sendMsg','enhanceaudio','tfliteModule','failed','cleanish','jiUDU','URL','directorEnabledPPT','remoteMuteElement','bind','setupIncoming','quality_wb','description','dzVDJ','kHkgE','oWoOT','low','codecGroupFlag','Lowered\x20hand','changeOrder','string','setValueAtTime','cleanup','audioCtx\x20:\x20','paFmX','open','offerSDP','networkPriority','ASKING\x20FOR\x20AUDIO\x20AND\x20VIDEO?','Failed\x20to\x20connect\x20to\x20service:\x20Error\x20503 Possibly\x20too\x20many\x20connections\x20from\x20the\x20same\x20address\x20tried\x20to\x20connect. Visit\x20https://discord.obs.ninja\x20for\x20support.','candidate','publishing\x20SDP\x20Offer:\x20','seeding\x20blocked','_trackID','mainmenu','pEUAg','queueNotification','CAMERA/MIC\x20SOURCE\x20ALLOCATION\x20FAILED.\x20Cant\x27\x20share\x20media\x20streams\x20as\x20a\x20result.\x20Maybe\x20this\x20is\x20a\x20Director\x20joining?','Safari','rejected','overlay','directorMutedState','timestamp','_local_ice_id','storekey','Setting\x20view\x20to\x20null\x20disables\x20all\x20playback','LlKix','SET\x20SCALING\x20IS\x20FIRING,\x20which\x20is\x20GOOD\x20!!!!!!','RPCS\x20WINS\x20ICE','maxviewers','requestVideoHack','quality_url','charCodeAt','RBBhS','setOpusAttributes','sendRequest','doZWj','setScale','sceneDisplay','GtyTb','sync','nackCount','vXXZf','ykzXW','catch','FSeSm','optimize','New\x20Label:\x20','webkitAudioContext','bit\x20rate\x20being\x20munged','midi','efuYb','local','QBIFk','requestKeyframe','transcript','random','332971lwTwCQ','fRCul','videoMuted','POST','obsRecording','object','KxuNl','sink','PGwzt','echoCancellation','director','offsetChannel','addEventListener','now','isDirector\x20','buLad','displayMute','_sync_offset','changeCamera','sid','_type','queueList','video\x20element\x20is\x20being\x20created\x20and\x20media\x20track\x20added','listPromise','showList','jPVnL','prototype','controls','marginLeft','forceTcpMode','view_set','getParameters','utf-8','uMlIk','audioLevel','Audio_Loudness','gyro','allowMIDI','codec','flipped','new-view-connection','zqauu','aDJOy','privacy','rampUpTime','aGAzt','recording_audio_gain','rYqdG','infocus','aJYCd','RTC\x20closed','exportKey','sensorData','eventPlayActive','UUID','&pie','framesPerSecond','maxvideobitrate','activeSpeaker','29WZZhmw','production','localstats','voiceMeter','VVVuf','vequE','inboundAudioPipeline','outboundVideoBitrate','eNLUC','can\x27t\x20change\x20audio\x20bitrate;\x20no\x20audio\x20sender\x20found','_packetsLost','onmessage','uupbS','rpcs','importKey','Mute\x20video\x20-306','onclick','Inbound\x20User-based\x20Message\x20from\x20Room','cameraConstraints','audioCtx','display','track\x20made\x20inactive;\x20removing','UUID\x20not\x20found\x20in\x20pcs','_last_bytes','className','maxiosbitrate','1.0','HANG\x20UP\x202\x20COMPLETE','abpjG','forEach','aHnnp','iceConnectionState\x20==\x20connected','meterStyle','obsSourceActive','platform','queuebutton','directorActions','dOdtA','QfTDa','desaltStreamID','cdyWV','soloVideo','qtUey','local_candidateType','UNRCv','Track\x20stopped','raw','seedStream','qOMhz','limitTotalBitrateGuests','THIS\x20SHOULD\x20BE\x20DELETED','YJbcI','remote_relay_IP','Trying\x20to\x20reconnect\x202','push','style','setLocalDescription','iOS\x20devices\x20do\x20not\x20support\x20dynamic\x20bitrates\x20correctly;\x20skipping','requestAudioHack','OdlKG','obsStreaming','speedtest','mono','ctrlKey','video/VP9','receiveChannel','RPC\x20closed','_remote_ice_id','screenShareElement','bitrate','turn:www.turn.obs.ninja:3478','container_','requestChangeLowcut','value\x20there','getAudioSettings','Connection\x20to\x20Control\x20Server\x20lost.\x0a\x0aAuto-reconnect\x20is\x20partially\x20implemented','_timestamp','LjZgz','resending\x20message','minipreview','qPZcS','play','MPpsO','requestZoomChange','The\x20request\x20failed;\x20the\x20remote\x20user\x20did\x20not\x20recognize\x20you\x20as\x20the\x20director','parentNode','wss://wss13.obs.ninja:443','maxBitrate','CeAEU','zoomedBitrate','kplQf','OpZEg','level','turn:turn-usc1.obs.ninja:3478','screensharefps','\x20Pixel\x20','kblLo','stopping\x20old\x20track','gGlzX','esBTC','ICE\x20DID\x20NOT\x20FIND\x20A\x20PC\x20OPTION?','watchTimeoutList2:','WwZGu','roomclaimed','ACTION\x20REJECTED:\x20','delta','cWxWV','ngnIS','muted','Generate\x20Some\x20Crypto\x20keys\x20first','abs','vqoJr','remoteFocus','crypto','hanging\x20up','ontrack','WRoJp','network_type','Browser','showSettings','audio','XqNLL','height','totalRoomBitrate','disconnected','ping','broadcastChannel','Ythpa','QXYvU','connectionState','initialPublish','rejoining\x20room','browser','forceios','bIJNl','qOZHv','sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message','[data-action-type=\x22mute-guest\x22][data--u-u-i-d=\x22','localMuteElement','host','seedPlz','KkpMP','reject','value','none','ixGAu','2px','cEJRn','roomid','zRnit','PbWJq','MaVQO','innerText','volume','gjSmo','MjxwA','SHA-1','jitterBufferEmittedCount','pie','muteState','vp8','srcObject','npPKd','useragent','btYCX','total_recv_bitrate_kbps','MAKING\x20A\x20NEW\x20RTC\x20CONNECTION','getAudioTracks','includes','applyConstraints','paused','BITRATE:\x20','wZrra','remoteStats','scaleWidth','time_active_minutes','frameHeight','ICE\x20FAILed.\x20bad?','qKRWj','maxsamplerate','EtYyB','Clean\x20up','zaJMk','canvas','midiIn','WebRTC\x20Connection\x20Closed.\x20Clean\x20up.\x20657','setBitrate','videoCodecs','dLUbY','ondatachannel','concat','decrypt','mediaDevices','directorChat','pushLoudness','controlTimer','sAClO','track','forceMediaSettings','WBFgg','generateStreamID','RSIjt','IraWJ','Press\x20OK\x20to\x20submit\x20any\x20error\x20logs\x20to\x20OBS.Ninja.\x20Error\x20logs\x20may\x20contain\x20private\x20information.','turn:turn-usw1.obs.ninja:443','&room=','h264','scale\x20set!','LOADING\x20UP\x20WAITING\x20WATCH\x20STREAM','MediaStreamAudioDestinationNode','from','GBpRj','readyState','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.','undefined','audioDevice','oTtxL','feQys','pcs\x20RTC\x20CLOSED','\x20-\x20Transferred','kind','PqKBX','order','mute','Stream\x20ID\x20is\x20already\x20in\x20use.','icefilter','disableREMB','requestChangeEQ','UN-MUTED','RSASSA-PKCS1-v1_5','data','wIgEc','setupYourOwnPlease','delayNode','padStart','Someone\x20Joined\x20the\x20Room','limitAudioBitrate','scaleResolutionDownBy\x20set\x201!','mykey','head2','currentRoundTripTime','generateKey','ynkrt','scaleResolutionDownBy','digest','iRrGT','compressor','float2','manual','PROBLEM!\x20RESENDING\x20SDP\x20OFFER\x20SHOULD\x20NOT\x20HAPPEN','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.','IDEON','floor','jitterBufferDelay','ICE\x20closed?','targetBandwidth','fadein','[data-action-type=\x22solo-chat\x22][data--u-u-i-d=\x22','QfbZP','This\x20shouldn\x27t\x20happen','sensors','MzQPS','classList','playing',',\x20isDirector:\x20','candidateType','enabled','claim','image/webp','TRYING\x20KEYFRAME','Create\x20a\x20new\x20RTC\x20connection;\x20offering\x20SDP\x20on\x20request','username','closed','pJBEP','failed\x20to\x20send\x20focus\x20change\x20request','label','issYY','getVideoTracks','SHA-256','code','jMNVp','limitaudio','failed\x20to\x20disconnect','hidden','buffer','WJbND','recorder','stereo\x20enabled','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x203','getTimezoneOffset','updateQueue','directorDisplayMuted','remoteCandidateId','vp9','remoteRaisedHandElement','postMessage','post\x20pixel\x20fix\x20','canvasSource','&scene','setRemoteDescription','ohBDQ','ACRVg','HANG\x20UP\x20COMPLETE','request\x20rate\x20limit:\x20','LqSRt','cursor','enhance','packetsReceived','Your\x20room\x20has\x20changed ','KYmPH','imageElement','codecId','Failed\x20to\x20request\x20video\x20and\x20audio;\x20iOS\x20device\x20asking?','PASSED','sampleRate','requestResolution','mZssJ','target','high','jyxLv','resolve','action','Refreshing\x20scale','slice','red','seedAttempts','encode','WMPmk','setVideoScale','[data-action-type=\x22order-value\x22][data--u-u-i-d=\x22','can\x27t\x20change\x20bitrate;\x20no\x20video\x20sender\x20found','seeding','HeFpN','755402lqrTOi','resume','maxTouchPoints','deferring\x20with\x20a\x20promise;\x20hashed\x20room','transferred','processStats','limitAudio','mirrored','quality','room\x20rate\x20restriction\x20detected.\x20No\x20videos\x20will\x20be\x20published\x20to\x20other\x20guests','randomize','deltaY','videoElement','trying\x20to\x20play','sceneMute','encrypt','audioEffects','opacity','_codecId','beepToNotify','Audio_Sync_Delay_ms','Round_Trip_Time_ms','FEljv','GQdVS','request\x20zoom\x20change:\x20','Chromium-based\x20v','pmjWy','streamID','pliCount','timeout','audioBitrate','wTfor','RS1','LBXXt','RfYGw','remoteControl','sendPeers','pop','videoOptions','noREMB','nhYix','browserDetails','sceneType','height_url','msg','zoHce','eozwS','LmCAR','addIceCandidate','removeEventListener','_frameWidth','getElementById','bandwidth\x20set!','[data-action-type=\x22solo-chat\x22]','yZEIU','pcs\x20RTC\x20Failed','adaptivePtime','51ojcUmJ','location','iframeEle','iframe_','pingTimeout','HQZzb','iceBundle','Fhxxo','gainNode','joiningRoom','bQPIY','Video\x20Track','CONNECTEED!','nMBlY','remoteMuteState','directorUUID','dynamicScale','jfpwe','joinRoom','PVpPI','disableOBS','lXFWF','allowBroadcast','mirrorExclude','adding\x20track','LKqUt','?view=','send','audioContext','recording','GOT\x20ICE!!','noiseSuppression','scaleFactor','setVideoBitrates','relayProtocol','Untitled','cSQXi','MEErX','Publisher\x20is\x20being\x20sent\x20a\x20video\x20stream???\x20NOT\x20EXPECTED!','Add\x20a\x20label','trackId','The\x20Director\x20has\x20disabled\x20your\x20vision\x20temporarily ','preferCodec','Bitrate_in_kbps','preventDefault','ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789','watchStream','micDelay','processIce2','video_muted_init','allowmidi','maxvb_url','head4','interval','QoOqy','networkType','defaultPassword','cNPKk','setup\x20peer\x20complete','CJWhl','closedCaptions','inline-block','gpnZq','Raised\x20hand','substr','Saiwn','Stream\x20ID\x20pre:','active','WkHAE','iceConnectionState','iceTimer','**\x20connected','importCrypto','onconnectionstatechange\x20pcs\x20ice\x20--\x20disconnected,\x20but\x20not\x20yet\x20closed?\x20','midiHotkeys','waitingWatchList','iframe','webp','mFKgb','RSA','mobile','retryTimeout','speakerMuted','seeding\x20!!','BGzTM','getVideoBitrates','zrzzu','quality_ss','effects','currentCameraConstraints','jwk','migrate','Unmute\x20video','dbOia','video','obsState','anysend','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x204','steve','streamSrc','kpZPP','videoMutedFlag','visible','28AsOofM','channelOffset','Update\x20Mixer\x20Event\x20on\x20REsize\x20SET','controlRoomBitrate','security','processIce','limitTotalBitrate','view','TRYING\x20TO\x20RECONNECT\x201','XXTaa'];var _0x18b08f=_0x447b;(function(_0x23d1a5,_0x27e000){var _0x1d4ef8=_0x447b;while(!![]){try{var _0x5cdbd9=parseInt(_0x1d4ef8(0x402))+parseInt(_0x1d4ef8(0x3d4))*parseInt(_0x1d4ef8(0x42b))+-parseInt(_0x1d4ef8(0x1ac))+parseInt(_0x1d4ef8(0x334))+parseInt(_0x1d4ef8(0x513))+parseInt(_0x1d4ef8(0x1e7))*parseInt(_0x1d4ef8(0x54f))+-parseInt(_0x1d4ef8(0x51c))*parseInt(_0x1d4ef8(0x36d));if(_0x5cdbd9===_0x27e000)break;else _0x23d1a5['push'](_0x23d1a5['shift']());}catch(_0x3c5607){_0x23d1a5['push'](_0x23d1a5['shift']());}}}(_0x4e0f,0x75f60));function log(_0x2329ab){}function warnlog(_0x50dcc1,_0x54b052=![],_0x2d460d=![]){if(_0x2d460d){}}function errorlog(_0x58f3e9,_0x51fef7=![],_0x572e81=![]){appendDebugLog(_0x58f3e9);if(_0x572e81){}}window[_0x18b08f(0x56b)]=function backupErr(_0x32e878,_0xd38ac2=![],_0x5cebf9=![]){var _0x3980d3=_0x18b08f;return errorlog(_0x32e878),errorlog(_0x5cebf9),errorlog(_0x3980d3(0x4bc)),appendDebugLog(_0x32e878),_0x5cebf9&&appendDebugLog(_0x5cebf9),![];},window[_0x18b08f(0x4f6)]=window['AudioContext']||window[_0x18b08f(0x1a3)];function getById(_0x563caf){var _0x102c20=_0x18b08f,_0x5672c4=document[_0x102c20(0x367)](_0x563caf);return!_0x5672c4&&(warnlog(_0x563caf+_0x102c20(0xf6)),_0x5672c4=document[_0x102c20(0x4da)](_0x102c20(0x439))),_0x5672c4;}var errorReport=[];function appendDebugLog(_0x2a1390){var _0xcc5b1e=_0x18b08f;try{var _0x5ac876=new Date(),_0x6e6820=_0x5ac876[_0xcc5b1e(0x4ff)]();if(_0x2a1390[_0xcc5b1e(0x47c)])errorReport[_0xcc5b1e(0x21d)]({'message':_0x2a1390[_0xcc5b1e(0x47c)],'name':_0x2a1390['name'],'time':_0x6e6820});else{if(typeof _0x2a1390==='string')errorReport[_0xcc5b1e(0x21d)]({'note':_0x2a1390,'time':_0x6e6820});else{if(_0xcc5b1e(0x45e)==='nqBtd'){function _0x5e1487(){_0x4c3a95();}}else errorReport[_0xcc5b1e(0x21d)]({'other':_0x2a1390,'time':_0x6e6820});}}errorReport=errorReport[_0xcc5b1e(0x32a)](-0xc8),document[_0xcc5b1e(0x367)]('reportbutton')&&(getById('reportbutton')[_0xcc5b1e(0x21e)][_0xcc5b1e(0x419)]=_0xcc5b1e(0x3d3));}catch(_0x33640c){}}function submitDebugLog(_0x274b6e){var _0x52e828=_0x18b08f;try{appendDebugLog({'connection_type':session[_0x52e828(0x14f)][_0x52e828(0x25c)]});if(navigator[_0x52e828(0x3f1)]){var _0x2430bc,_0x5e7728=navigator[_0x52e828(0x3f1)];appendDebugLog({'userAgent':_0x5e7728});}navigator[_0x52e828(0x209)]&&appendDebugLog({'userAgent':navigator[_0x52e828(0x209)]});}catch(_0x3bee86){}window['focus']();var _0x39bd0b=confirm(_0x52e828(0x2b2));if(_0x39bd0b){var _0x40adc7=new XMLHttpRequest();_0x40adc7[_0x52e828(0x178)](_0x52e828(0x1af),'https://reports.obs.ninja/'),_0x40adc7[_0x52e828(0x388)](JSON['stringify'](errorReport)),errorReport=[],document['getElementById'](_0x52e828(0x48f))&&(getById(_0x52e828(0x48f))[_0x52e828(0x21e)][_0x52e828(0x419)]=_0x52e828(0x302));}}function isAlphaNumeric(_0x2f595b){var _0x3ade95=_0x18b08f,_0x2de24b,_0xa4f725,_0x46cec7;for(_0xa4f725=0x0,_0x46cec7=_0x2f595b[_0x3ade95(0x3f4)];_0xa4f725<_0x46cec7;_0xa4f725++){_0x2de24b=_0x2f595b[_0x3ade95(0x193)](_0xa4f725);if(!(_0x2de24b>0x2f&&_0x2de24b<0x3a)&&!(_0x2de24b>0x40&&_0x2de24b<0x5b)&&!(_0x2de24b>0x60&&_0x2de24b<0x7b))return![];}return!![];}var iOS=!!navigator[_0x18b08f(0x209)]&&/iPad|iPhone|iPod/[_0x18b08f(0x125)](navigator['platform']),iPad=navigator[_0x18b08f(0x336)]&&navigator[_0x18b08f(0x336)]>0x2&&/MacIntel/[_0x18b08f(0x125)](navigator[_0x18b08f(0x209)]);function play(_0x1a366b=null){var _0x3417ad=_0x18b08f;log('play\x20stream:\x20'+session[_0x3417ad(0x3db)]);if(session[_0x3417ad(0x3db)]==='')log(_0x3417ad(0x18c));else{if(session[_0x3417ad(0x3db)]!==![]){var _0x447f59=session['view'][_0x3417ad(0x55c)](',');for(var _0x5c6197 in _0x447f59){if(_0x447f59[_0x5c6197]==''){}else{if(_0x1a366b===null)session[_0x3417ad(0x39b)](_0x447f59[_0x5c6197]);else{if(_0x1a366b===_0x447f59[_0x5c6197])session['watchStream'](_0x447f59[_0x5c6197]);else{}}}}}else{if(session[_0x3417ad(0x122)]!==![]){if(session[_0x3417ad(0x122)][_0x3417ad(0x28f)](_0x1a366b)){}else session[_0x3417ad(0x39b)](_0x1a366b);}else _0x1a366b&&session[_0x3417ad(0x39b)](_0x1a366b);}}}function showControlBar(_0x1444c5){var _0x2c4d96=_0x18b08f;try{_0x1444c5[_0x2c4d96(0x1c7)]=!![];}catch(_0x120dac){if('CmrbP'!==_0x2c4d96(0x41c))errorlog(_0x120dac);else{function _0x9b3ff8(){var _0x3da359=_0x2c4d96;_0x3a930f(_0x48564f[_0x3da359(0x1f4)][_0x4fc15f][_0x3da359(0x340)][_0x3da359(0x2aa)]);}}}}function playAllVideos(){var _0x3516fc=_0x18b08f;for(var _0x30acd6 in session[_0x3516fc(0x1f4)]){try{session[_0x3516fc(0x1f4)][_0x30acd6][_0x3516fc(0x340)]&&(session[_0x3516fc(0x1f4)][_0x30acd6][_0x3516fc(0x340)][_0x3516fc(0x291)]&&session[_0x3516fc(0x1f4)][_0x30acd6][_0x3516fc(0x340)][_0x3516fc(0x238)]()[_0x3516fc(0x57e)](_0x23bb33=>{var _0x2d401a=_0x3516fc;log(_0x2d401a(0x2ee));})[_0x3516fc(0x19f)](warnlog));}catch(_0x5c52b3){}}}function getTURNList(){var _0x13715b=_0x18b08f,_0x12cb5f=[];turn={},turn[_0x13715b(0x2f6)]=_0x13715b(0x3cf),turn[_0x13715b(0x11d)]=_0x13715b(0x2cf),turn[_0x13715b(0x4c9)]=[_0x13715b(0x41d)],turn['tz']=0x12c,turn[_0x13715b(0xdb)]=![],turn['production']=!![];if(session[_0x13715b(0x224)]&&turn[_0x13715b(0xdb)]==session[_0x13715b(0x1c9)]){}else{if(session['forceTcpMode']&&turn[_0x13715b(0xdb)]){}else{if(session[_0x13715b(0x224)]==![]&&turn['production']==![]){}else _0x12cb5f[_0x13715b(0x21d)](turn);}}turn={},turn['username']=_0x13715b(0x3cf),turn[_0x13715b(0x11d)]=_0x13715b(0x2cf),turn[_0x13715b(0x4c9)]=[_0x13715b(0x22d)],turn['tz']=0x12c,turn[_0x13715b(0xdb)]=!![],turn[_0x13715b(0x1e8)]=!![];if(session[_0x13715b(0x224)]&&turn[_0x13715b(0xdb)]==session[_0x13715b(0x1c9)]){}else{if(session[_0x13715b(0x1c9)]&&turn['udp']){}else{if(session[_0x13715b(0x224)]==![]&&turn[_0x13715b(0x1e8)]==![]){}else _0x12cb5f[_0x13715b(0x21d)](turn);}}turn={},turn[_0x13715b(0x2f6)]=_0x13715b(0x3cf),turn[_0x13715b(0x11d)]=_0x13715b(0x2cf),turn[_0x13715b(0x4c9)]=[_0x13715b(0x575)],turn['tz']=-0x3c,turn[_0x13715b(0xdb)]=![],turn[_0x13715b(0x1e8)]=!![];if(session[_0x13715b(0x224)]&&turn[_0x13715b(0xdb)]==session[_0x13715b(0x1c9)]){}else{if(session[_0x13715b(0x1c9)]&&turn['udp']){}else{if(session[_0x13715b(0x224)]==![]&&turn[_0x13715b(0x1e8)]==![]){}else _0x12cb5f[_0x13715b(0x21d)](turn);}}turn={},turn[_0x13715b(0x2f6)]=_0x13715b(0x3cf),turn[_0x13715b(0x11d)]=_0x13715b(0x2cf),turn[_0x13715b(0x4c9)]=[_0x13715b(0x4fa)],turn['tz']=-0x3c,turn[_0x13715b(0xdb)]=!![],turn['production']=![];if(session[_0x13715b(0x224)]&&turn[_0x13715b(0xdb)]==session[_0x13715b(0x1c9)]){}else{if(session[_0x13715b(0x1c9)]&&turn[_0x13715b(0xdb)]){}else{if(session[_0x13715b(0x224)]==![]&&turn[_0x13715b(0x1e8)]==![]){}else _0x12cb5f[_0x13715b(0x21d)](turn);}}turn={},turn[_0x13715b(0x2f6)]=_0x13715b(0x438),turn[_0x13715b(0x11d)]=_0x13715b(0x44f),turn[_0x13715b(0x4c9)]=[_0x13715b(0x2b3)],turn['tz']=0x1e0,turn[_0x13715b(0xdb)]=!![],turn[_0x13715b(0x1e8)]=!![];if(session[_0x13715b(0x224)]&&turn[_0x13715b(0xdb)]==session[_0x13715b(0x1c9)]){}else{if(session[_0x13715b(0x1c9)]&&turn['udp']){}else{if(session['speedtest']==![]&&turn[_0x13715b(0x1e8)]==![]){}else _0x12cb5f[_0x13715b(0x21d)](turn);}}turn={},turn[_0x13715b(0x2f6)]=_0x13715b(0x401),turn['credential']=_0x13715b(0x44f),turn['urls']=[_0x13715b(0x244)],turn['tz']=0x168,turn[_0x13715b(0xdb)]=!![],turn[_0x13715b(0x1e8)]=!![];if(session[_0x13715b(0x224)]&&turn[_0x13715b(0xdb)]==session[_0x13715b(0x1c9)]){}else{if(session[_0x13715b(0x1c9)]&&turn[_0x13715b(0xdb)]){}else{if(session['speedtest']==![]&&turn['production']==![]){}else _0x12cb5f[_0x13715b(0x21d)](turn);}}turn={},turn['username']=_0x13715b(0x401),turn[_0x13715b(0x11d)]='tabernac',turn[_0x13715b(0x4c9)]=[_0x13715b(0x4d6)],turn['tz']=-0x3c,turn[_0x13715b(0xdb)]=!![],turn[_0x13715b(0x1e8)]=!![];if(session['speedtest']&&turn[_0x13715b(0xdb)]==session['forceTcpMode']){}else{if(session[_0x13715b(0x1c9)]&&turn[_0x13715b(0xdb)]){}else{if(session[_0x13715b(0x224)]==![]&&turn[_0x13715b(0x1e8)]==![]){}else _0x12cb5f['push'](turn);}}return _0x12cb5f;}function chooseBestTURN(){var _0xba32df=_0x18b08f;if(session[_0xba32df(0x52b)])return;var _0x4e6cd9=getTURNList(),_0x362816=new Date(),_0x330c8b=_0x362816[_0xba32df(0x308)]();for(var _0x28931e=0x0;_0x28931e<_0x4e6cd9[_0xba32df(0x3f4)];_0x28931e++){var _0x32c64a=Math[_0xba32df(0x255)](_0x4e6cd9[_0x28931e]['tz']-_0x330c8b);Math[_0xba32df(0x255)](_0x32c64a-0x3c*0x18)<_0x32c64a&&(_0x32c64a=Math[_0xba32df(0x255)](_0x32c64a-0x3c*0x18)),_0x4e6cd9[_0x28931e][_0xba32df(0x250)]=_0x32c64a;}_0x4e6cd9['sort'](compare_deltas),_0x4e6cd9=_0x4e6cd9[_0xba32df(0x32a)](0x0,0x3),session[_0xba32df(0x52b)]={'iceServers':[{'urls':[_0xba32df(0x404),_0xba32df(0x4b2)]}],'sdpSemantics':_0xba32df(0x553)},session[_0xba32df(0x52b)][_0xba32df(0x3df)]=session[_0xba32df(0x52b)][_0xba32df(0x3df)][_0xba32df(0x2a5)](_0x4e6cd9),log(session[_0xba32df(0x52b)]);}function compare_deltas(_0x3818fd,_0x2a009d){var _0x176954=_0x18b08f,_0x49726e=_0x3818fd[_0x176954(0x250)]||0x0,_0x2a6bfd=_0x2a009d[_0x176954(0x250)]||0x0;if(_0x49726e>_0x2a6bfd)return 0x1;if(_0x49726e<_0x2a6bfd){if(_0x176954(0x4c7)!==_0x176954(0x152))return-0x1;else{function _0x499044(){var _0x37773e=_0x176954;_0x43a692(_0x12daec[_0x37773e(0x57d)],_0x4ca4de['value']);}}}return 0x0;}function compare_vids(_0x34bd73,_0xfd1883){var _0x55bd7c=_0x18b08f,_0x1a2554=_0x34bd73[_0x55bd7c(0x2c5)]||0x0,_0xf8ef21=_0xfd1883[_0x55bd7c(0x2c5)]||0x0;if(_0x1a2554<_0xf8ef21)return 0x1;if(_0x1a2554>_0xf8ef21){if(_0x55bd7c(0x3c1)!==_0x55bd7c(0x3c1)){function _0xa0d51f(){var _0x453aff=_0x55bd7c;if(_0x322b7d[_0x453aff(0x4bb)](_0x39667e[_0x453aff(0x1f4)])[_0x453aff(0x3f4)]+_0x5944f3[_0x453aff(0x4bb)](_0x494feb[_0x453aff(0x147)])[_0x453aff(0x3f4)]>=_0x5da90e[_0x453aff(0x153)]){delete _0x7abeba[_0x453aff(0x1f4)][_0x2ab7f2],_0x3d4a47(),_0x4dde18(_0x453aff(0x3e1));return;}}}else return-0x1;}return 0x0;}function _0x447b(_0x177555,_0xb8bb51){_0x177555=_0x177555-0xce;var _0x46edd4=_0x4e0f[_0x177555];return _0x46edd4;}var updateMixerTimer=null,updateMixerActive=![];function updateMixer(_0x44104c=![]){var _0x5eeaf4=_0x18b08f;clearInterval(updateMixerTimer);if(updateMixerActive){updateMixerTimer=setTimeout(function(){updateMixer();},0x1f4);return;}updateMixerActive=!![];try{if(_0x5eeaf4(0x391)!==_0x5eeaf4(0x317))updateMixerRun(_0x44104c);else{function _0x1872ba(){return;}}}catch(_0x4f1ca3){}updateMixerActive=![];}var WebRTC={};WebRTC[_0x18b08f(0x151)]=function(){var _0x44a3fc=_0x18b08f,_0x16e2c4=function(){var _0x2aabf6=!![];return function(_0x38f331,_0x61991b){var _0xdca7ac=_0x447b;if(_0xdca7ac(0x1dd)===_0xdca7ac(0x1dd)){var _0x41ded8=_0x2aabf6?function(){var _0x1d89d9=_0xdca7ac;if(_0x61991b){if(_0x1d89d9(0x34a)!==_0x1d89d9(0x34a)){function _0x1965bc(){var _0x1fb31a=_0x1d89d9;_0x5c3d1e[_0x1fb31a(0x1f4)][_0x5cecac][_0x1fb31a(0x538)]=![];}}else{var _0x2c8773=_0x61991b[_0x1d89d9(0x464)](_0x38f331,arguments);return _0x61991b=null,_0x2c8773;}}}:function(){};return _0x2aabf6=![],_0x41ded8;}else{function _0x1a8c3d(){var _0x2445a5=_0xdca7ac;if(_0x356b91['rpcs'][_0x4dba7b][_0x2445a5(0x538)]===_0x41388f)return;_0x47fc46[_0x2445a5(0x1f4)][_0x33baa1][_0x2445a5(0x2e6)]=_0x49bda1[_0x2445a5(0x1f4)][_0x5a15ca][_0x2445a5(0x538)];}}};}(),_0x10b201=_0x16e2c4(this,function(){var _0x31bb1d=function(){var _0x4c0888=_0x447b,_0x268b60=_0x31bb1d['constructor'](_0x4c0888(0x482))()['constructor'](_0x4c0888(0x528));return!_0x268b60[_0x4c0888(0x125)](_0x10b201);};return _0x31bb1d();});_0x10b201();var _0x162eb3={};function _0xb5baf3(){}function _0x1e01e3(_0x1b3380){errorlog(_0x1b3380);}function _0xfc9fab(){var _0x2ef3e1=_0x447b,_0x21285c,_0x308cf2,_0x532664=new Promise((_0x17865b,_0x54524a)=>{_0x21285c=_0x17865b,_0x308cf2=_0x54524a;});return _0x532664[_0x2ef3e1(0x327)]=_0x21285c,_0x532664[_0x2ef3e1(0x275)]=_0x308cf2,_0x532664;}_0x162eb3[_0x44a3fc(0x4cd)]=![],_0x162eb3['novideo']=![],_0x162eb3[_0x44a3fc(0x1e6)]=![],_0x162eb3[_0x44a3fc(0x114)]=!![],_0x162eb3[_0x44a3fc(0x4f5)]=![],_0x162eb3['audioChannels']=0x8,_0x162eb3[_0x44a3fc(0x2be)]=![],_0x162eb3[_0x44a3fc(0x14a)]=![],_0x162eb3[_0x44a3fc(0xe8)]=![],_0x162eb3[_0x44a3fc(0x55e)]=!![],_0x162eb3['audioEffects']=null,_0x162eb3[_0x44a3fc(0x3e4)]=![],_0x162eb3[_0x44a3fc(0x534)]=![],_0x162eb3[_0x44a3fc(0x1fa)]=new AudioContext(),_0x162eb3['aspectratio']=![],_0x162eb3[_0x44a3fc(0xfe)]=![],_0x162eb3[_0x44a3fc(0x1b5)]=null,_0x162eb3[_0x44a3fc(0xe5)]=null,_0x162eb3[_0x44a3fc(0x38c)]=null,_0x162eb3[_0x44a3fc(0x140)]=![],_0x162eb3[_0x44a3fc(0x265)]=![],_0x162eb3[_0x44a3fc(0x43c)]=![],_0x162eb3[_0x44a3fc(0x22c)]=![],_0x162eb3['bitrate_set']=![],_0x162eb3[_0x44a3fc(0x303)]=![],_0x162eb3[_0x44a3fc(0x347)]=![],_0x162eb3[_0x44a3fc(0x29e)]=null,_0x162eb3['canvasSource']=null,_0x162eb3[_0x44a3fc(0x3d7)]=![],_0x162eb3[_0x44a3fc(0x425)]=![],_0x162eb3['cleanOutput']=![],_0x162eb3[_0x44a3fc(0x163)]=![],_0x162eb3[_0x44a3fc(0x3a9)]=![],_0x162eb3[_0x44a3fc(0x52b)]=![],_0x162eb3[_0x44a3fc(0x2dd)]=![],_0x162eb3[_0x44a3fc(0x4c4)]=![],_0x162eb3[_0x44a3fc(0x1d2)]=![],_0x162eb3[_0x44a3fc(0x3ec)]=![],_0x162eb3[_0x44a3fc(0x44e)]=0x1,_0x162eb3['cover']=![],_0x162eb3[_0x44a3fc(0x55b)]=null,_0x162eb3[_0x44a3fc(0x1f9)]={},_0x162eb3[_0x44a3fc(0x15b)]={},_0x162eb3[_0x44a3fc(0x3c6)]={},_0x162eb3['currentAudioConstraints']={},_0x162eb3[_0x44a3fc(0x2a8)]=![],_0x162eb3[_0x44a3fc(0x4d9)]=0x23,_0x162eb3['hiddenSceneViewBitrate']=0x190,_0x162eb3[_0x44a3fc(0x240)]=0x25a,_0x162eb3[_0x44a3fc(0x170)]=![],_0x162eb3[_0x44a3fc(0x3a5)]=![],_0x162eb3[_0x44a3fc(0x1b6)]=![],_0x162eb3[_0x44a3fc(0x166)]=![],_0x162eb3[_0x44a3fc(0x477)]=null,_0x162eb3[_0x44a3fc(0x30a)]=null,_0x162eb3[_0x44a3fc(0x37c)]=![],_0x162eb3['disableOBS']=![],_0x162eb3[_0x44a3fc(0x37d)]=!![],_0x162eb3[_0x44a3fc(0x3c5)]=null,_0x162eb3[_0x44a3fc(0x43d)]=![],_0x162eb3['lowcut']=![],_0x162eb3[_0x44a3fc(0x4bd)]=new TextEncoder('utf-8'),_0x162eb3[_0x44a3fc(0x122)]=![],_0x162eb3[_0x44a3fc(0x128)]=![],_0x162eb3['limitTotalBitrate']=![],_0x162eb3[_0x44a3fc(0x2e7)]=!![],_0x162eb3[_0x44a3fc(0x3ff)]=![],_0x162eb3[_0x44a3fc(0x1d3)]=![],_0x162eb3[_0x44a3fc(0x48c)]=![],_0x162eb3[_0x44a3fc(0x558)]=![],_0x162eb3[_0x44a3fc(0x26c)]=![],_0x162eb3[_0x44a3fc(0x2ad)]=![],_0x162eb3[_0x44a3fc(0x51a)]=![],_0x162eb3[_0x44a3fc(0x429)]=![],_0x162eb3[_0x44a3fc(0x261)]=![],_0x162eb3['iframeSrc']=![],_0x162eb3[_0x44a3fc(0x36f)]=![],_0x162eb3[_0x44a3fc(0x46a)]=![],_0x162eb3[_0x44a3fc(0x33c)]=![],_0x162eb3[_0x44a3fc(0x16a)]=0x1,_0x162eb3[_0x44a3fc(0x3c4)]=0x0,_0x162eb3[_0x44a3fc(0x2c8)]=![],_0x162eb3[_0x44a3fc(0x1dc)]=![],_0x162eb3[_0x44a3fc(0x376)]=![],_0x162eb3['label']=![],_0x162eb3['keyframerate']=![],_0x162eb3['keys']={},_0x162eb3[_0x44a3fc(0x39c)]=![],_0x162eb3[_0x44a3fc(0x190)]=![],_0x162eb3[_0x44a3fc(0x12a)]=![],_0x162eb3[_0x44a3fc(0x153)]=![],_0x162eb3[_0x44a3fc(0x3bd)]=![],_0x162eb3[_0x44a3fc(0x112)]=![],_0x162eb3[_0x44a3fc(0x4fd)]=![],_0x162eb3[_0x44a3fc(0x1e5)]=![],_0x162eb3[_0x44a3fc(0x29a)]=![],_0x162eb3[_0x44a3fc(0x3ee)]=![],_0x162eb3[_0x44a3fc(0x480)]=![],_0x162eb3[_0x44a3fc(0x515)]=![],_0x162eb3['maxiosbitrate']=0x19,_0x162eb3[_0x44a3fc(0x121)]=0xa,_0x162eb3[_0x44a3fc(0x207)]=![],_0x162eb3[_0x44a3fc(0x2df)]=![],_0x162eb3[_0x44a3fc(0x3b7)]=![],_0x162eb3[_0x44a3fc(0x507)]=![],_0x162eb3[_0x44a3fc(0x29f)]=![],_0x162eb3[_0x44a3fc(0x236)]=![],_0x162eb3[_0x44a3fc(0x33b)]=![],_0x162eb3[_0x44a3fc(0x384)]=![],_0x162eb3[_0x44a3fc(0x360)]=[],_0x162eb3[_0x44a3fc(0x253)]=![],_0x162eb3[_0x44a3fc(0x3eb)]=![],_0x162eb3[_0x44a3fc(0x225)]=![],_0x162eb3[_0x44a3fc(0x2d5)]={},_0x162eb3['noREMB']=![],_0x162eb3[_0x44a3fc(0x49b)]=![],_0x162eb3[_0x44a3fc(0x13f)]=![],_0x162eb3[_0x44a3fc(0x500)]=![],_0x162eb3[_0x44a3fc(0x424)]=![],_0x162eb3[_0x44a3fc(0x1b7)]=![],_0x162eb3[_0x44a3fc(0x1a1)]=![],_0x162eb3[_0x44a3fc(0x3cc)]={},_0x162eb3[_0x44a3fc(0x3cc)][_0x44a3fc(0x419)]=null,_0x162eb3[_0x44a3fc(0x3cc)]['streaming']=null,_0x162eb3[_0x44a3fc(0x3cc)]['recording']=null,_0x162eb3[_0x44a3fc(0x3cc)][_0x44a3fc(0x422)]=null,_0x162eb3['obsState'][_0x44a3fc(0x38a)]=null,_0x162eb3[_0x44a3fc(0x1ee)]=![],_0x162eb3[_0x44a3fc(0xdf)]=![],_0x162eb3[_0x44a3fc(0x2c5)]=![],_0x162eb3[_0x44a3fc(0xf2)]=![],_0x162eb3[_0x44a3fc(0x147)]={},_0x162eb3[_0x44a3fc(0x4a9)]=![],_0x162eb3[_0x44a3fc(0x285)]=![],_0x162eb3['pcm']=![],_0x162eb3[_0x44a3fc(0x4b0)]=![],_0x162eb3[_0x44a3fc(0x1d7)]=![],_0x162eb3[_0x44a3fc(0x371)]=null,_0x162eb3[_0x44a3fc(0x45d)]=null,_0x162eb3[_0x44a3fc(0x46f)]=![],_0x162eb3[_0x44a3fc(0x1c1)]=[],_0x162eb3[_0x44a3fc(0x2a9)]=![],_0x162eb3[_0x44a3fc(0x33e)]=![],_0x162eb3[_0x44a3fc(0x138)]=![],_0x162eb3[_0x44a3fc(0x4af)]=![],_0x162eb3['remote']=![],_0x162eb3['rampUpTime']=0xbb8,_0x162eb3[_0x44a3fc(0x109)]=![],_0x162eb3[_0x44a3fc(0x3be)]=0x1388,_0x162eb3['roomenc']=![],_0x162eb3['roomid']=![],_0x162eb3[_0x44a3fc(0x4c0)]=![],_0x162eb3['ptz']=![],_0x162eb3['rpcs']={},_0x162eb3['sampleRate']=![],_0x162eb3[_0x44a3fc(0x14c)]='',_0x162eb3[_0x44a3fc(0x3ea)]=![],_0x162eb3['scene']=![],_0x162eb3[_0x44a3fc(0x523)]={},_0x162eb3['screenshare']=![],_0x162eb3[_0x44a3fc(0x22b)]=![],_0x162eb3[_0x44a3fc(0x4a2)]=![],_0x162eb3[_0x44a3fc(0x46e)]=![],_0x162eb3[_0x44a3fc(0x245)]=![],_0x162eb3['screenShareState']=![],_0x162eb3['security']=![],_0x162eb3[_0x44a3fc(0x332)]=![],_0x162eb3[_0x44a3fc(0x1e0)]=![],_0x162eb3[_0x44a3fc(0x32c)]=0x0,_0x162eb3['devicePixelRatio']=![],_0x162eb3[_0x44a3fc(0x478)]=![],_0x162eb3[_0x44a3fc(0x1c4)]=null,_0x162eb3[_0x44a3fc(0x458)]=![],_0x162eb3['soloChatUUID']=![],_0x162eb3[_0x44a3fc(0x25e)]=!![],_0x162eb3[_0x44a3fc(0x462)]=![],_0x162eb3[_0x44a3fc(0x1b3)]=![],_0x162eb3[_0x44a3fc(0x2eb)]=![],_0x162eb3[_0x44a3fc(0x3bf)]=![],_0x162eb3[_0x44a3fc(0x14f)]={},_0x162eb3[_0x44a3fc(0x35e)]=![],_0x162eb3['statsMenu']=![],_0x162eb3[_0x44a3fc(0x133)]=![],_0x162eb3[_0x44a3fc(0x34f)]=null,_0x162eb3[_0x44a3fc(0x3d0)]=null,_0x162eb3['style']=![],_0x162eb3[_0x44a3fc(0x19b)]=![],_0x162eb3['forceTcpMode']=![],_0x162eb3[_0x44a3fc(0x262)]=![],_0x162eb3[_0x44a3fc(0x103)]=0x1f4,_0x162eb3['title']=_0x44a3fc(0x390),_0x162eb3[_0x44a3fc(0x161)]=![],_0x162eb3[_0x44a3fc(0x130)]=![],_0x162eb3[_0x44a3fc(0x46b)]=![],_0x162eb3[_0x44a3fc(0x1aa)]=![],_0x162eb3[_0x44a3fc(0x338)]=![],_0x162eb3[_0x44a3fc(0x557)]=![],_0x162eb3[_0x44a3fc(0x340)]=![],_0x162eb3[_0x44a3fc(0x1ae)]=![],_0x162eb3[_0x44a3fc(0x491)]=![],_0x162eb3[_0x44a3fc(0x3d2)]=![],_0x162eb3[_0x44a3fc(0x3db)]=![],_0x162eb3[_0x44a3fc(0x1ca)]=![],_0x162eb3[_0x44a3fc(0x280)]=0x64,_0x162eb3[_0x44a3fc(0x4d1)]=![],_0x162eb3[_0x44a3fc(0x50e)]=![],_0x162eb3[_0x44a3fc(0x4e2)]=![],_0x162eb3[_0x44a3fc(0x4f2)]={},_0x162eb3[_0x44a3fc(0x4a1)]={},_0x162eb3[_0x44a3fc(0x54c)]=![],_0x162eb3[_0x44a3fc(0x146)]=![],_0x162eb3[_0x44a3fc(0x3b8)]={},_0x162eb3[_0x44a3fc(0x3ba)]=![],_0x162eb3[_0x44a3fc(0x135)]=![],_0x162eb3['ws']=null,_0x162eb3[_0x44a3fc(0x403)]=![],_0x162eb3[_0x44a3fc(0xea)]=![],_0x162eb3['version']=null,_0x162eb3['updateLocalStatsInterval']=null,_0x162eb3['UUID']=![],_0x162eb3[_0x44a3fc(0x271)]=getById(_0x44a3fc(0x13e))[_0x44a3fc(0x4df)](!![]),_0x162eb3['localMuteElement'][_0x44a3fc(0x21e)]['top']=_0x44a3fc(0x4f0),_0x162eb3['localMuteElement'][_0x44a3fc(0x21e)][_0x44a3fc(0x514)]=_0x44a3fc(0x4f0),_0x162eb3[_0x44a3fc(0x271)]['id']=_0x44a3fc(0x271),_0x162eb3[_0x44a3fc(0x1ea)]=getById(_0x44a3fc(0x155))[_0x44a3fc(0x4df)](!![]),_0x162eb3[_0x44a3fc(0x1ea)]['id']=_0x44a3fc(0x456),_0x162eb3[_0x44a3fc(0x1ea)][_0x44a3fc(0x21e)]['opacity']=0x0,_0x162eb3[_0x44a3fc(0x1ea)][_0x44a3fc(0x4e1)][_0x44a3fc(0x243)]=0x0,_0x162eb3[_0x44a3fc(0x1ea)][_0x44a3fc(0x21e)][_0x44a3fc(0x4d1)]=_0x44a3fc(0xf0),_0x162eb3['voiceMeter'][_0x44a3fc(0x21e)][_0x44a3fc(0x261)]=_0x44a3fc(0xf0),_0x162eb3['voiceMeter'][_0x44a3fc(0x21e)]['top']=_0x44a3fc(0x518),_0x162eb3[_0x44a3fc(0x1ea)][_0x44a3fc(0x21e)][_0x44a3fc(0x514)]=_0x44a3fc(0xf0),_0x162eb3[_0x44a3fc(0x2af)]=function(_0x357109=0x7){var _0x1ef0c8=_0x44a3fc,_0x5e444a='',_0x1f6c5e=_0x1ef0c8(0x39a);for(var _0x224852=0x0;_0x224852<_0x357109;_0x224852++){_0x5e444a+=_0x1f6c5e[_0x1ef0c8(0x4ed)](Math[_0x1ef0c8(0x2e3)](Math[_0x1ef0c8(0x1ab)]()*_0x1f6c5e[_0x1ef0c8(0x3f4)]));}return log(_0x5e444a),_0x5e444a;};function _0x2c85d2(_0xd9217b){var _0x38abf5=_0x44a3fc,_0x13de71=new Uint8Array(_0xd9217b[_0x38abf5(0x3f4)]);for(var _0x4ef94e=0x0;_0x4ef94e<_0xd9217b['length'];_0x4ef94e++){_0x13de71[_0x4ef94e]=_0xd9217b['charCodeAt'](_0x4ef94e);}return _0x13de71;}function _0x300327(_0x15f078){var _0x57c6e0=_0x44a3fc;return Array['prototype'][_0x57c6e0(0x15c)][_0x57c6e0(0x503)](_0x15f078,function(_0x140069){var _0x524e00=_0x57c6e0;return('0'+(_0x140069&0xff)['toString'](0x10))[_0x524e00(0x32a)](-0x2);})[_0x57c6e0(0x536)]('');}function _0xd1411d(_0x266564){var _0x1e4189=_0x44a3fc,_0x308704=[];for(var _0x391e3b=0x0;_0x391e3b<_0x266564[_0x1e4189(0x3f4)];_0x391e3b+=0x2){_0x308704['push'](parseInt(_0x266564[_0x1e4189(0x3ad)](_0x391e3b,0x2),0x10));}return new Uint8Array(_0x308704);}_0x162eb3[_0x44a3fc(0x3e7)]=function(_0x2dd55c,_0x1096bc=![]){var _0x52bde1=_0x44a3fc,_0x143fe3=new TextEncoder(_0x52bde1(0x1cc))[_0x52bde1(0x32d)](_0x2dd55c);return crypto[_0x52bde1(0x426)][_0x52bde1(0x2db)](_0x52bde1(0x2fd),_0x143fe3)['then'](function(_0x3d6feb){var _0x368f16=_0x52bde1;if(_0x368f16(0x1f3)!==_0x368f16(0x1f3)){function _0x5ba027(){var _0xf0de67=_0x368f16;_0x2d2d05[_0xf0de67(0x1f4)][_0x58651c][_0xf0de67(0x14f)][_0x26bb28[_0xf0de67(0x395)]]['FPS']=_0x5dee17(_0xa075f[_0xf0de67(0x1e4)]);}}else return _0x3d6feb=new Uint8Array(_0x3d6feb),_0x1096bc&&(_0x3d6feb=_0x3d6feb[_0x368f16(0x32a)](0x0,parseInt(parseInt(_0x1096bc)/0x2))),_0x3d6feb=_0x300327(_0x3d6feb),_0x3d6feb;});},_0x162eb3[_0x44a3fc(0x52d)]=function(_0x2fdc4d){var _0x5178dd=_0x44a3fc,_0x31de0a=crypto[_0x5178dd(0x50c)](new Uint8Array(0x10));return crypto[_0x5178dd(0x426)][_0x5178dd(0x2db)]({'name':_0x5178dd(0x2fd)},_0x2c85d2(_0x162eb3[_0x5178dd(0xf2)]+_0x162eb3[_0x5178dd(0x14c)]))[_0x5178dd(0x57e)](function(_0x3734a7){var _0x28cc88=_0x5178dd;return window[_0x28cc88(0x258)]['subtle'][_0x28cc88(0x1f5)](_0x28cc88(0x215),_0x3734a7,{'name':_0x28cc88(0x522)},![],[_0x28cc88(0x343),'decrypt'])[_0x28cc88(0x57e)](function(_0x42939e){var _0x339e68=_0x28cc88;return crypto[_0x339e68(0x426)][_0x339e68(0x343)]({'name':'AES-CBC','iv':_0x31de0a},_0x42939e,_0x2c85d2(_0x2fdc4d))[_0x339e68(0x57e)](function(_0x47de06){return encrypted_data=new Uint8Array(_0x47de06),encrypted_data=_0x300327(encrypted_data),_0x31de0a=_0x300327(_0x31de0a),[encrypted_data,_0x31de0a];},function(_0x28caa8){return errorlog(_0x28caa8['message']),![];});},function(_0x4c34b9){return errorlog(_0x4c34b9),![];});});},_0x162eb3[_0x44a3fc(0x537)]=function(_0x3c6f12,_0xf8421c){var _0x2a7ea6=_0x44a3fc;if('RBBhS'===_0x2a7ea6(0x194))return _0x3c6f12=_0xd1411d(_0x3c6f12),_0xf8421c=_0xd1411d(_0xf8421c),crypto['subtle'][_0x2a7ea6(0x2db)]({'name':_0x2a7ea6(0x2fd)},_0x2c85d2(_0x162eb3[_0x2a7ea6(0xf2)]+_0x162eb3[_0x2a7ea6(0x14c)]))[_0x2a7ea6(0x57e)](function(_0x74911){var _0x393854=_0x2a7ea6;return window[_0x393854(0x258)][_0x393854(0x426)][_0x393854(0x1f5)](_0x393854(0x215),_0x74911,{'name':_0x393854(0x522)},![],['encrypt',_0x393854(0x2a6)])[_0x393854(0x57e)](function(_0x3824af){var _0xfc2f99=_0x393854;return crypto['subtle'][_0xfc2f99(0x2a6)]({'name':_0xfc2f99(0x522),'iv':_0xf8421c},_0x3824af,_0x3c6f12)[_0xfc2f99(0x57e)](function(_0x108e16){var _0x5164a3=_0xfc2f99,_0x47bfa6=new Uint8Array(_0x108e16),_0x3b015e='';for(var _0x3091b6=0x0;_0x3091b6<_0x47bfa6[_0x5164a3(0xf9)];_0x3091b6++){_0x3b015e+=String[_0x5164a3(0x3f3)](_0x47bfa6[_0x3091b6]);}return _0x3b015e;},function(_0x9d17b8){var _0x1f2995=_0xfc2f99;return errorlog(_0x9d17b8[_0x1f2995(0x47c)]),![];});});});else{function _0x1d0d4f(){var _0x2c6f18=_0x2a7ea6;_0x2bccf3[_0x2c6f18(0x4cd)][_0x2c6f18(0x28f)](_0x4bf8d2[_0x2c6f18(0x1f4)][_0x592744][_0x2c6f18(0x34f)])?_0x163465['audio']=!![]:_0x2f0777[_0x2c6f18(0x25f)]=![];}}},_0x162eb3[_0x44a3fc(0x4d7)]=function _0x47a1cc(){var _0x4609be=_0x44a3fc;window[_0x4609be(0x258)][_0x4609be(0x426)][_0x4609be(0x2d8)]({'name':_0x4609be(0x2cc),'modulusLength':0x200,'publicExponent':new Uint8Array([0x1,0x0,0x1]),'hash':{'name':_0x4609be(0x283)}},!![],[_0x4609be(0x4e3),_0x4609be(0xe6)])[_0x4609be(0x57e)](function(_0x2ad7b0){var _0x3b9451=_0x4609be;log(_0x2ad7b0['publicKey']),log(_0x2ad7b0[_0x3b9451(0x13b)]),_0x162eb3[_0x3b9451(0x2d5)]=_0x2ad7b0,window[_0x3b9451(0x258)][_0x3b9451(0x426)][_0x3b9451(0x1df)](_0x3b9451(0x3c7),_0x2ad7b0[_0x3b9451(0x52a)])['then'](function(_0x15ce1e){var _0x420524=_0x3b9451,_0x10e07d={};_0x10e07d[_0x420524(0x4e0)]=_0x420524(0x18b),_0x10e07d['key']=_0x420524(0x4c3),_0x162eb3[_0x420524(0x15f)](_0x10e07d);})[_0x3b9451(0x19f)](errorlog);})[_0x4609be(0x19f)](errorlog);},_0x162eb3[_0x44a3fc(0x3b5)]=function(_0x3d4a32,_0x4bfa16){var _0x31f8fa=_0x44a3fc;if('kHkgE'!==_0x31f8fa(0x16d)){function _0x5f422c(){var _0x50f625=_0x31f8fa;_0x238ba7[_0x50f625(0x2ac)]['kind']==_0x50f625(0x3cb)&&_0x3110a8[_0x50f625(0x1f4)][_0xb7dca2][_0x50f625(0x3d0)][_0x50f625(0x2fc)]()[_0x50f625(0x204)](_0x3f7b94=>{var _0x9450e7=_0x50f625;_0x2a5c4c[_0x9450e7(0x1f4)][_0x364ba7][_0x9450e7(0x3d0)]['removeTrack'](_0x3f7b94);});}}else window[_0x31f8fa(0x258)][_0x31f8fa(0x426)][_0x31f8fa(0x1f5)](_0x31f8fa(0x3c7),{'kty':_0x31f8fa(0x3bc),'e':_0x31f8fa(0x141),'n':_0x3d4a32,'alg':_0x31f8fa(0x354),'ext':!![]},{'name':_0x31f8fa(0x2cc),'hash':{'name':_0x31f8fa(0x283)}},!![],['verify'])['then'](function(_0x44212c){var _0x4c36c4=_0x31f8fa;if(_0x4c36c4(0x392)===_0x4c36c4(0x505)){function _0x38d0f9(){_0x493746('Someone\x20sent\x20us\x20an\x20ANSWER\x20sdp??');}}else _0x162eb3['keys'][_0x4bfa16]={},_0x162eb3['keys'][_0x4bfa16][_0x4c36c4(0x52a)]=_0x44212c,_0x162eb3['keys'][_0x4bfa16][_0x4c36c4(0x13b)]=null;})[_0x31f8fa(0x19f)](errorlog);},_0x162eb3[_0x44a3fc(0x1a9)]=function(_0xb03731,_0x5d124d=![]){var _0x13f470=_0x44a3fc,_0x42ec7f={};_0x42ec7f[_0x13f470(0x14b)]=!![],_0x42ec7f[_0x13f470(0x145)]=!![],_0x162eb3[_0x13f470(0x196)](_0x42ec7f,_0xb03731);},_0x162eb3[_0x44a3fc(0x3fa)]=function(_0x529d7a,_0x1920b1){var _0x77fb1c=_0x44a3fc,_0x4e4ae1={};_0x4e4ae1[_0x77fb1c(0x352)]=_0x529d7a,log(_0x4e4ae1),_0x162eb3[_0x77fb1c(0x196)](_0x4e4ae1,_0x1920b1);},_0x162eb3[_0x44a3fc(0x4e7)]=function(_0x3fe325,_0x51b01b){var _0x111e20=_0x44a3fc;if(!_0x162eb3[_0x111e20(0x1f4)][_0x51b01b])return;if(_0x162eb3[_0x111e20(0x1f4)][_0x51b01b][_0x111e20(0x538)]!==![]){if(_0x162eb3[_0x111e20(0x1f4)][_0x51b01b][_0x111e20(0x538)]===_0x3fe325)return;_0x162eb3[_0x111e20(0x1f4)][_0x51b01b]['targetBandwidth']=_0x162eb3[_0x111e20(0x1f4)][_0x51b01b][_0x111e20(0x538)];}else{if(_0x3fe325===![]){if(_0x162eb3[_0x111e20(0x1f4)][_0x51b01b][_0x111e20(0x2e6)]===_0x162eb3['rpcs'][_0x51b01b][_0x111e20(0x40b)])return;}else _0x162eb3[_0x111e20(0x1f4)][_0x51b01b][_0x111e20(0x2e6)]=_0x3fe325;}_0x3fe325=parseInt(_0x162eb3[_0x111e20(0x1f4)][_0x51b01b]['targetBandwidth']);if(_0x162eb3['obsState'][_0x111e20(0x419)]===![]){if(_0x162eb3[_0x111e20(0x1a1)]!==![]){if(window[_0x111e20(0x475)])return;}}_0x3fe325===0x0&&_0x162eb3[_0x111e20(0x1f4)][_0x51b01b][_0x111e20(0x37b)]&&(_0x3fe325=0x1);if(_0x162eb3[_0x111e20(0x1f4)][_0x51b01b][_0x111e20(0x40b)]===_0x3fe325)return;log(_0x111e20(0x316)+_0x3fe325);var _0x5e21f9={};_0x5e21f9[_0x111e20(0x22c)]=_0x3fe325,log(_0x5e21f9),_0x162eb3['sendRequest'](_0x5e21f9,_0x51b01b)?_0x162eb3['rpcs'][_0x51b01b][_0x111e20(0x40b)]=_0x3fe325:(setTimeout(function _0x4a2daf(){var _0x312a80=_0x111e20;if(_0x312a80(0x24a)==='esBTC')_0x162eb3[_0x312a80(0x4e7)](![],_0x51b01b);else{function _0xc581d6(){var _0x4c10ac=_0x312a80;try{var _0x9a5bdc=_0x381e88[_0x4c10ac(0x360)][_0x4c10ac(0x32a)](-0xa);_0x23d75a[_0x4c10ac(0x360)]=[];for(var _0x3f1c4e in _0x9a5bdc){_0x17a57b(_0x4c10ac(0x235)),_0x10bd47[_0x4c10ac(0x15f)](_0x9a5bdc[_0x3f1c4e]);}}catch(_0x424c68){_0x86aea9(_0x424c68);}}}},0x1388),warnlog('couldn\x27t\x20set\x20rate\x20limit'));},_0x162eb3[_0x44a3fc(0x452)]=function(_0x4be982){var _0x1e0221=_0x44a3fc;if(_0x162eb3[_0x1e0221(0x1b6)]){if(!_0x162eb3[_0x1e0221(0x166)]){warnUser('Enable\x20the\x20director\x27s\x20microphone\x20first.');return;}}_0x162eb3[_0x1e0221(0x504)]===_0x4be982?_0x162eb3[_0x1e0221(0x504)]=![]:_0x162eb3[_0x1e0221(0x504)]=_0x4be982;var _0x38562c=document[_0x1e0221(0x41a)](_0x1e0221(0x369));for(var _0x4f3a11=0x0;_0x4f3a11<_0x38562c[_0x1e0221(0x3f4)];_0x4f3a11++){if(_0x162eb3[_0x1e0221(0x504)]&&_0x38562c[_0x4f3a11][_0x1e0221(0x4e1)][_0x1e0221(0x1e2)]===_0x162eb3[_0x1e0221(0x504)]){}else{if('BeBdB'!==_0x1e0221(0x1a0))_0x38562c[_0x4f3a11][_0x1e0221(0x2ed)]['remove'](_0x1e0221(0x4fc));else{function _0x3575db(){_0x2232a6();}}}}_0x162eb3[_0x1e0221(0x421)](![]);},_0x162eb3['applySoloChat']=function(_0xa1e5f9=!![]){var _0x5960a9=_0x44a3fc;if(_0x162eb3[_0x5960a9(0x1b6)]===![]){if('zFmIg'==='zFmIg')return;else{function _0x3034d4(){var _0x31be55=_0x5960a9;_0x10f7d0['pcs'][_0x49cfde][_0x31be55(0x40d)]=_0x1cf303(_0x3ea7d7[_0x31be55(0x40d)]);}}}else{if(!_0x162eb3[_0x5960a9(0x166)])return;}if(_0x162eb3[_0x5960a9(0x504)]){if(_0x162eb3[_0x5960a9(0x504)]in _0x162eb3['pcs']){}else _0x162eb3['soloChatUUID']=![];}for(var _0x52c26e in _0x162eb3[_0x5960a9(0x147)]){try{var _0x418320=_0x162eb3[_0x5960a9(0x147)][_0x52c26e][_0x5960a9(0x442)]();_0x418320[_0x5960a9(0x204)](_0x49050d=>{var _0x5240a9=_0x5960a9;if(_0x5240a9(0x2e9)!=='QfbZP'){function _0x498277(){var _0xa8d531=_0x5240a9;_0x5af0db(_0xa8d531(0x20a))['classList'][_0xa8d531(0x106)](_0xa8d531(0x3fe)),_0x22f8d7(_0xa8d531(0x20a))[_0xa8d531(0x2ed)][_0xa8d531(0x41f)](_0xa8d531(0x2de)),_0x2fcb96(_0xa8d531(0x20a))[_0xa8d531(0x2ed)][_0xa8d531(0x41f)]('red');}}else{if(!_0x49050d[_0x5240a9(0x2ac)])return;if(_0x49050d['track'][_0x5240a9(0x2c3)]!==_0x5240a9(0x25f)){if(_0x5240a9(0x12f)===_0x5240a9(0x12f))return;else{function _0x418dea(){var _0x56b362=_0x5240a9;_0x3fbdc1[0x0][_0x56b362(0x4e1)][_0x56b362(0x276)]=0x1,_0x415705[0x0][_0x56b362(0x1ff)]=_0x56b362(0x4fc),_0x407173[0x0][_0x56b362(0xf3)][0x1][_0x56b362(0x564)]=_0x56b362(0xd9),_0x402115[_0x56b362(0x1f4)][_0x4c1118][_0x56b362(0x188)]=0x1;}}}const _0x42539b=_0x49050d[_0x5240a9(0x1cb)]();if(!_0x42539b[_0x5240a9(0x512)])_0x42539b[_0x5240a9(0x512)]=[{}];else{if(!_0x42539b[_0x5240a9(0x512)][_0x5240a9(0x3f4)])return;}if(_0x162eb3[_0x5240a9(0x504)]&&_0x162eb3[_0x5240a9(0x504)]===_0x52c26e)_0x42539b[_0x5240a9(0x512)][0x0][_0x5240a9(0x3b0)]=!![],setTimeout(function(_0x457325,_0x24acfd,_0x565b07){var _0x49640c=_0x5240a9;if(_0x49640c(0x1d6)===_0x49640c(0x278)){function _0x4a95fa(){var _0x10ff2e=_0x49640c;_0x50be4c[_0x10ff2e(0x2b9)]=_0x8124b2[_0x10ff2e(0x1e2)];}}else _0x565b07[_0x49640c(0x567)](_0x24acfd)[_0x49640c(0x57e)](()=>{var _0x5147d0=_0x49640c;document['querySelectorAll'](_0x5147d0(0x2e8)+_0x457325+'\x22]')[0x0][_0x5147d0(0x2ed)][_0x5147d0(0x106)](_0x5147d0(0x4fc));})[_0x49640c(0x19f)](warnlog);},0x0,_0x52c26e,_0x42539b,_0x49050d);else{if(_0x162eb3['soloChatUUID']===![])_0x42539b[_0x5240a9(0x512)][0x0][_0x5240a9(0x3b0)]=!![],_0x49050d[_0x5240a9(0x567)](_0x42539b)[_0x5240a9(0x57e)](()=>{})[_0x5240a9(0x19f)](warnlog);else{if(_0x5240a9(0x11f)!==_0x5240a9(0x1a8))_0x42539b[_0x5240a9(0x512)][0x0][_0x5240a9(0x3b0)]=![],setTimeout(function(_0x2b507d,_0x5d9722,_0x559e2b){var _0x5799f8=_0x5240a9;_0x559e2b['setParameters'](_0x5d9722)[_0x5799f8(0x57e)]()[_0x5799f8(0x19f)](_0x142daf=>{var _0x508615=_0x5799f8;warnlog(_0x142daf),document[_0x508615(0x41a)](_0x508615(0x2e8)+_0x2b507d+'\x22]')[0x0]['classList']['add'](_0x508615(0x4fc));});},0x0,_0x52c26e,_0x42539b,_0x49050d);else{function _0x429dd9(){var _0x354a1a=_0x5240a9,_0x5171db=_0x1e2ca8(_0x5dbc6a[_0x354a1a(0x147)][_0x48e8b6][_0x354a1a(0x145)]);}}}}}});}catch(_0x58c120){errorlog(_0x58c120);}}_0xa1e5f9==![]&&(_0x162eb3[_0x5960a9(0x504)]?(_0x162eb3[_0x5960a9(0x3eb)]=_0x162eb3[_0x5960a9(0x253)],_0x162eb3[_0x5960a9(0x253)]=![],data={},data[_0x5960a9(0x286)]=_0x162eb3[_0x5960a9(0x253)],_0x162eb3[_0x5960a9(0x43f)](data,_0x162eb3[_0x5960a9(0x504)])):_0x162eb3[_0x5960a9(0x253)]=_0x162eb3[_0x5960a9(0x3eb)],toggleMute(!![]));},_0x162eb3[_0x44a3fc(0x4ba)]=function(){var _0x1f8f2b=_0x44a3fc;if(_0x162eb3[_0x1f8f2b(0x477)]===null)return;for(var _0xeea985 in _0x162eb3[_0x1f8f2b(0x1f4)]){try{var _0x2bf5cf=_0x162eb3[_0x1f8f2b(0x1f4)][_0xeea985]['getReceivers']();for(var _0x8021a9=0x0;_0x8021a9<_0x2bf5cf['length'];_0x8021a9++){_0x2bf5cf[_0x8021a9][_0x1f8f2b(0x2ac)][_0x1f8f2b(0x2c3)]==_0x1f8f2b(0x25f)&&(_0x2bf5cf[_0x8021a9][_0x1f8f2b(0x2ac)][_0x1f8f2b(0x2f1)]=!_0x162eb3[_0x1f8f2b(0x477)]);}}catch(_0x3ca07f){}}_0x162eb3[_0x1f8f2b(0x477)]&&(getById(_0x1f8f2b(0x12b))[_0x1f8f2b(0x253)]=!![]);},_0x162eb3['directorDisplayMute']=function(){var _0xdaff55=_0x44a3fc;if(_0x162eb3[_0xdaff55(0x30a)]===null)return;_0x162eb3['directorDisplayMuted']?(getById(_0xdaff55(0x449))['style'][_0xdaff55(0x1fb)]=_0xdaff55(0x277),!_0x162eb3[_0xdaff55(0x14e)]&&warnUser(_0xdaff55(0x396))):(getById('gridlayout')[_0xdaff55(0x21e)][_0xdaff55(0x1fb)]='',!_0x162eb3['cleanOutput']&&closeModal());for(var _0x20bb13 in _0x162eb3[_0xdaff55(0x1f4)]){try{if(_0xdaff55(0x289)===_0xdaff55(0x566)){function _0x55f04f(){var _0xbd935e=_0xdaff55,_0x1b48a9={};_0x1b48a9[_0xbd935e(0x40c)]=_0x53e291['iframeSrc'],_0x164c8c[_0xbd935e(0x43f)](_0x1b48a9,_0x5d0e80);}}else{var _0x578a6f=_0x162eb3[_0xdaff55(0x1f4)][_0x20bb13][_0xdaff55(0x586)]();for(var _0x552853=0x0;_0x552853<_0x578a6f[_0xdaff55(0x3f4)];_0x552853++){_0x578a6f[_0x552853][_0xdaff55(0x2ac)][_0xdaff55(0x2c3)]==_0xdaff55(0x3cb)&&(_0x578a6f[_0x552853][_0xdaff55(0x2ac)][_0xdaff55(0x2f1)]=!_0x162eb3[_0xdaff55(0x30a)]);}}}catch(_0x1260e7){errorlog(_0x1260e7);}}_0x162eb3[_0xdaff55(0x30a)]&&(getById(_0xdaff55(0x12b))[_0xdaff55(0x253)]=!![]);},_0x162eb3[_0x44a3fc(0x357)]=function(_0x42859e){var _0x1a02d1=_0x44a3fc;_0x42859e[_0x1a02d1(0x399)]();var _0xcefa1e=parseFloat(_0x42859e[_0x1a02d1(0x33f)]*-0.001);log(_0x42859e[_0x1a02d1(0x4f1)]),_0x42859e[_0x1a02d1(0x226)]||_0x42859e[_0x1a02d1(0x12e)]?_0x162eb3[_0x1a02d1(0x412)](_0xcefa1e,_0x42859e['currentTarget'][_0x1a02d1(0x4e1)][_0x1a02d1(0x1e2)]):_0x162eb3[_0x1a02d1(0x23a)](_0xcefa1e,_0x42859e[_0x1a02d1(0x4f1)][_0x1a02d1(0x4e1)][_0x1a02d1(0x1e2)]);},_0x162eb3[_0x44a3fc(0x23a)]=function(_0x82ec6,_0x481859,_0x2211b4=_0x162eb3[_0x44a3fc(0x4cf)]){var _0x10fb62=_0x44a3fc;log(_0x10fb62(0x34c)+_0x82ec6),log(_0x481859);var _0x52dd25={};_0x52dd25[_0x10fb62(0x50e)]=_0x82ec6,_0x52dd25['remote']=_0x2211b4,_0x162eb3[_0x10fb62(0x196)](_0x52dd25,_0x481859)?log('zoom\x20success'):errorlog('failed\x20to\x20send\x20zoom\x20change\x20request');},_0x162eb3[_0x44a3fc(0x412)]=function(_0x46775f,_0x57244,_0x5cfcb7=_0x162eb3[_0x44a3fc(0x4cf)]){var _0x15ae7e=_0x44a3fc;log(_0x15ae7e(0xfb)+_0x46775f);var _0x516c29={};_0x516c29[_0x15ae7e(0x3f6)]=_0x46775f,_0x516c29[_0x15ae7e(0x4cf)]=_0x5cfcb7,_0x162eb3[_0x15ae7e(0x196)](_0x516c29,_0x57244)?log('focus\x20success'):errorlog(_0x15ae7e(0x2f9));},_0x162eb3[_0x44a3fc(0x216)]=function(){var _0x3b203b=_0x44a3fc;_0x162eb3[_0x3b203b(0x47d)]();if(_0x162eb3[_0x3b203b(0x376)]!==![])_0x162eb3[_0x3b203b(0x376)]=_0x3b203b(0x273),log('seeding\x20blocked');else{var _0x539cf2={};_0x539cf2[_0x3b203b(0x4e0)]=_0x3b203b(0x102),_0x539cf2[_0x3b203b(0x34f)]=_0x162eb3[_0x3b203b(0x34f)],_0x162eb3[_0x3b203b(0x15f)](_0x539cf2),log(_0x3b203b(0x3c0));}},_0x162eb3[_0x44a3fc(0x527)]=function(_0x2babbc){var _0x413714=_0x44a3fc;if(_0x413714(0x222)!==_0x413714(0x222)){function _0xcc05fc(){var _0x12132a=_0x413714;_0x1cdad0['sdp']=_0x1b6799[_0x12132a(0x195)](_0x631b24[_0x12132a(0x457)],{'maxaveragebitrate':_0x238f7e[_0x12132a(0x4f5)]*0x400,'cbr':_0x22009c[_0x12132a(0x44e)],'useinbandfec':0x1,'maxptime':_0x14c8cb['maxptime'],'minptime':_0x59f261[_0x12132a(0x480)],'ptime':_0x5920ee[_0x12132a(0x515)]});}}else try{if(navigator['userAgent'][_0x413714(0x549)](_0x413714(0x246))!=-0x1){if(!_0x162eb3[_0x413714(0x340)][_0x413714(0x288)])return _0x2babbc;if(!_0x162eb3[_0x413714(0x340)][_0x413714(0x288)][_0x413714(0x2fc)]()[_0x413714(0x3f4)])return _0x2babbc;if(_0x2babbc<=0x0)return _0x2babbc;var _0x5ba031=_0x162eb3[_0x413714(0x340)][_0x413714(0x288)][_0x413714(0x2fc)]()[0x0][_0x413714(0x4ce)](),_0x24bbcd=_0x5ba031[_0x413714(0x261)],_0x5d727f=_0x5ba031[_0x413714(0x4d1)],_0x4f0817=_0x24bbcd*_0x2babbc/0x64,_0x41542d=_0x5d727f*_0x2babbc/0x64;if(_0x4f0817>_0x41542d){_0x4f0817=parseInt(_0x4f0817/0x10)*0x10;var _0x28b8cd=0x64*_0x4f0817/_0x24bbcd;}else{_0x41542d=parseInt(_0x41542d/0x10)*0x10;var _0x28b8cd=0x64*_0x41542d/_0x5d727f;}return _0x28b8cd;}else{if(navigator[_0x413714(0x3f1)][_0x413714(0x549)](_0x413714(0x454))>-0x1){if(!_0x162eb3['videoElement'][_0x413714(0x288)])return _0x2babbc;if(!_0x162eb3[_0x413714(0x340)]['srcObject'][_0x413714(0x2fc)]()[_0x413714(0x3f4)])return _0x2babbc;if(_0x2babbc<=0x0){if('hfFcu'!==_0x413714(0x489))return _0x2babbc;else{function _0x2c137f(){var _0x13badf=_0x413714;_0x16ba77[_0x13badf(0x1f4)][_0x39011a][_0x13badf(0x37b)]?_0x442962['rpcs'][_0x2f1f1d]['remoteMuteElement'][_0x13badf(0x21e)][_0x13badf(0x1fb)]=_0x13badf(0x545):_0x47e989[_0x13badf(0x1f4)][_0x4163ab]['remoteMuteElement']['style'][_0x13badf(0x1fb)]=_0x13badf(0x277);}}}var _0x5ba031=_0x162eb3['videoElement'][_0x413714(0x288)][_0x413714(0x2fc)]()[0x0][_0x413714(0x4ce)](),_0x24bbcd=_0x5ba031[_0x413714(0x261)],_0x5d727f=_0x5ba031['width'],_0x4f0817=_0x24bbcd*_0x2babbc/0x64,_0x41542d=_0x5d727f*_0x2babbc/0x64;if(_0x4f0817>_0x41542d){_0x4f0817=parseInt(_0x4f0817/0x10)*0x10;var _0x28b8cd=0x64*_0x4f0817/_0x24bbcd;}else{_0x41542d=parseInt(_0x41542d/0x10)*0x10;var _0x28b8cd=0x64*_0x41542d/_0x5d727f;}return _0x28b8cd;}else{if(_0x162eb3[_0x413714(0x1d2)]===_0x413714(0x30c)){if(!_0x162eb3[_0x413714(0x340)][_0x413714(0x288)])return _0x2babbc;if(!_0x162eb3[_0x413714(0x340)][_0x413714(0x288)]['getVideoTracks']()[_0x413714(0x3f4)])return _0x2babbc;if(_0x2babbc<=0x0)return _0x2babbc;var _0x5ba031=_0x162eb3[_0x413714(0x340)][_0x413714(0x288)]['getVideoTracks']()[0x0][_0x413714(0x4ce)](),_0x24bbcd=_0x5ba031[_0x413714(0x261)],_0x5d727f=_0x5ba031[_0x413714(0x4d1)],_0x4f0817=_0x24bbcd*_0x2babbc/0x64,_0x41542d=_0x5d727f*_0x2babbc/0x64;if(_0x4f0817>_0x41542d){_0x4f0817=parseInt(_0x4f0817/0x10)*0x10;var _0x28b8cd=0x64*_0x4f0817/_0x24bbcd;}else{_0x41542d=parseInt(_0x41542d/0x10)*0x10;var _0x28b8cd=0x64*_0x41542d/_0x5d727f;}return _0x28b8cd;}else return _0x2babbc;}}}catch(_0x1e1df3){return _0x2babbc;}},_0x162eb3['refreshScale']=function(){var _0x31af2b=_0x44a3fc;log(_0x31af2b(0x329));for(var _0x25549 in _0x162eb3['pcs']){setTimeout(function(_0x4206f2){var _0x5231c6=_0x31af2b;if(_0x162eb3[_0x5231c6(0x147)][_0x4206f2][_0x5231c6(0x4ab)]!==![])log(_0x5231c6(0x4e8)),_0x162eb3[_0x5231c6(0x3e6)](_0x4206f2,_0x162eb3[_0x5231c6(0x147)][_0x4206f2]['scaleWidth'],_0x162eb3['pcs'][_0x4206f2][_0x5231c6(0x571)]);else _0x162eb3[_0x5231c6(0x147)][_0x4206f2][_0x5231c6(0x3ea)]!==![]&&(log('scale\x20scale'),_0x162eb3[_0x5231c6(0x198)](_0x4206f2,_0x162eb3[_0x5231c6(0x147)][_0x4206f2][_0x5231c6(0x3ea)]));},0x0,_0x25549);}},_0x162eb3[_0x44a3fc(0x198)]=function(_0x45b819,_0xd45b22){var _0x421b1d=_0x44a3fc;warnlog(_0x421b1d(0x18e));if(_0x162eb3[_0x421b1d(0x147)][_0x45b819][_0x421b1d(0x3ea)]!==_0xd45b22){_0x162eb3[_0x421b1d(0x147)][_0x45b819][_0x421b1d(0x3ea)]=_0xd45b22;try{if(safariVersion()<=0xd&&(iOS||iPad))log(_0x421b1d(0x220));else{if((adapter[_0x421b1d(0x35d)][_0x421b1d(0x26b)]===_0x421b1d(0x148)||adapter[_0x421b1d(0x35d)][_0x421b1d(0x26b)]===_0x421b1d(0x111)||adapter[_0x421b1d(0x35d)][_0x421b1d(0x26b)]===_0x421b1d(0x49a)&&adapter[_0x421b1d(0x35d)][_0x421b1d(0x158)]>=0x40)&&_0x421b1d(0x4b9)in window&&_0x421b1d(0x567)in window['RTCRtpSender'][_0x421b1d(0x1c6)]){if('jOBuT'!==_0x421b1d(0xe9)){var _0x484af6=_0x162eb3[_0x421b1d(0x147)][_0x45b819][_0x421b1d(0x442)]()[_0x421b1d(0x107)](function(_0x3e7cfb){var _0x29f896=_0x421b1d;return _0x3e7cfb[_0x29f896(0x2ac)]&&_0x3e7cfb[_0x29f896(0x2ac)]['kind']==_0x29f896(0x3cb);});if(!_0x484af6){warnlog(_0x421b1d(0x331));return;}var _0x30e575=_0x484af6[_0x421b1d(0x1cb)]();(!_0x30e575[_0x421b1d(0x512)]||_0x30e575['encodings'][_0x421b1d(0x3f4)]==0x0)&&(_0x30e575[_0x421b1d(0x512)]=[{}]);_0x162eb3[_0x421b1d(0x147)][_0x45b819][_0x421b1d(0x4ab)]&&(_0x162eb3['pcs'][_0x45b819][_0x421b1d(0x4ab)]<_0xd45b22&&(_0xd45b22=_0x162eb3[_0x421b1d(0x147)][_0x45b819][_0x421b1d(0x4ab)]));_0x162eb3['pcs'][_0x45b819]['scaleDueToBitrate']&&_0x162eb3[_0x421b1d(0x147)][_0x45b819][_0x421b1d(0x4db)]<_0xd45b22&&(_0xd45b22=_0x162eb3[_0x421b1d(0x147)][_0x45b819]['scaleDueToBitrate']);_0xd45b22=_0x162eb3[_0x421b1d(0x527)](_0xd45b22);if(_0xd45b22<=0x0)_0x30e575[_0x421b1d(0x512)][0x0][_0x421b1d(0x2da)]=0x1;else{if(_0x421b1d(0xdc)===_0x421b1d(0xdc))_0x30e575[_0x421b1d(0x512)][0x0]['scaleResolutionDownBy']=0x64/_0xd45b22;else{function _0x537030(){var _0x33fcf9=_0x421b1d;_0x33fcf9(0x305)in _0x3b11e6['rpcs'][this[_0x33fcf9(0x1e2)]][_0x33fcf9(0x340)]&&_0x4bbc2b[_0x33fcf9(0x1f4)][this[_0x33fcf9(0x1e2)]][_0x33fcf9(0x340)][_0x33fcf9(0x305)][_0x33fcf9(0x529)]();}}}_0x484af6[_0x421b1d(0x567)](_0x30e575)[_0x421b1d(0x57e)](()=>{var _0x2cbba1=_0x421b1d;if(_0x2cbba1(0x281)!==_0x2cbba1(0x1c5))log(_0x2cbba1(0x2b6)),log(_0x484af6[_0x2cbba1(0x1cb)]()),pokeIframeAPI(_0x2cbba1(0x32f),_0xd45b22,_0x45b819);else{function _0x82089f(){var _0x3186e0=_0x2cbba1;_0x3821ea['seedAttempts']=_0x50f629(_0x44799f[_0x3186e0(0x32c)])+0x1,_0x5426ae(function(){var _0x2f846f=_0x3186e0;_0x57faf7[_0x2f846f(0x216)]();},0x1388);}}})[_0x421b1d(0x19f)](warnlog),_0x162eb3[_0x421b1d(0x147)][_0x45b819][_0x421b1d(0x14f)]['scaleFactor']=parseInt(_0xd45b22)+'%';return;}else{function _0x11bc39(){var _0x59f5ff=_0x421b1d;if(_0x414a9c[_0x59f5ff(0x1a1)]!==![]){if(_0x5f5d56[_0x59f5ff(0x475)])return;}}}}}}catch(_0x52dff3){errorlog(_0x52dff3);}}},_0x162eb3[_0x44a3fc(0x322)]=function(_0x44668b,_0x51638b,_0x281589){var _0x1a4dda=_0x44a3fc;if(!_0x162eb3[_0x1a4dda(0x1f4)][_0x44668b])return;var _0x516cae=![];_0x162eb3[_0x1a4dda(0x1f4)][_0x44668b][_0x1a4dda(0x295)]!=_0x51638b&&(_0x162eb3[_0x1a4dda(0x1f4)][_0x44668b][_0x1a4dda(0x295)]=_0x51638b,_0x516cae=!![]);_0x162eb3[_0x1a4dda(0x1f4)][_0x44668b][_0x1a4dda(0x571)]!=_0x281589&&(_0x162eb3[_0x1a4dda(0x1f4)][_0x44668b]['scaleHeight']=_0x281589,_0x516cae=!![]);log(_0x51638b+'\x20'+_0x281589);if(_0x516cae){var _0x108448={};_0x108448[_0x1a4dda(0x1e2)]=_0x44668b,_0x108448[_0x1a4dda(0x322)]={'w':_0x51638b,'h':_0x281589},warnlog(_0x1a4dda(0x322)),warnlog(_0x108448),_0x162eb3[_0x1a4dda(0x196)](_0x108448,_0x44668b);}_0x162eb3[_0x1a4dda(0x1f4)][_0x44668b][_0x1a4dda(0x14f)]['Requested_resolution']=parseInt(_0x51638b)+_0x1a4dda(0x415)+parseInt(_0x281589);},_0x162eb3[_0x44a3fc(0x3e6)]=function(_0x315489,_0x4621c9,_0xc36059){var _0x41bdfb=_0x44a3fc;_0x162eb3[_0x41bdfb(0x147)][_0x315489][_0x41bdfb(0x295)]=_0x4621c9,_0x162eb3[_0x41bdfb(0x147)][_0x315489][_0x41bdfb(0x571)]=_0xc36059;if(safariVersion()<=0xd&&(iOS||iPad))return;if((adapter[_0x41bdfb(0x35d)][_0x41bdfb(0x26b)]===_0x41bdfb(0x148)||adapter[_0x41bdfb(0x35d)][_0x41bdfb(0x26b)]===_0x41bdfb(0x111)||adapter['browserDetails'][_0x41bdfb(0x26b)]===_0x41bdfb(0x49a)&&adapter[_0x41bdfb(0x35d)][_0x41bdfb(0x158)]>=0x40)&&_0x41bdfb(0x4b9)in window&&_0x41bdfb(0x567)in window[_0x41bdfb(0x4b9)][_0x41bdfb(0x1c6)]){var _0x82fe72=_0x162eb3['pcs'][_0x315489][_0x41bdfb(0x442)]()[_0x41bdfb(0x107)](function(_0x544e74){var _0x56bbdd=_0x41bdfb;return _0x544e74[_0x56bbdd(0x2ac)]&&_0x544e74[_0x56bbdd(0x2ac)][_0x56bbdd(0x2c3)]=='video';});if(!_0x82fe72){warnlog(_0x41bdfb(0x331));return;}var _0x396f4e=_0x82fe72[_0x41bdfb(0x1cb)]();if(!_0x396f4e[_0x41bdfb(0x512)]||_0x396f4e[_0x41bdfb(0x512)][_0x41bdfb(0x3f4)]==0x0){if(_0x41bdfb(0x3c3)!=='cxNjE')_0x396f4e[_0x41bdfb(0x512)]=[{}];else{function _0x3630af(){var _0x145e82=_0x41bdfb;!_0x5a2755[_0x145e82(0x14e)]&&_0x47fb1f(function(){var _0x5c807c=_0x145e82;_0x59ec13(_0x5c807c(0x423));},0x1);}}}if(_0x162eb3['videoElement']){if(_0x41bdfb(0x110)!==_0x41bdfb(0x110)){function _0x4f181d(){var _0x31aa13=_0x41bdfb;_0x2a52e4(_0x31aa13(0x10a));}}else{var _0x485b2f=_0x162eb3[_0x41bdfb(0x340)][_0x41bdfb(0x288)][_0x41bdfb(0x2fc)]();if(_0x485b2f['length'])var _0x156c2c=_0x162eb3[_0x41bdfb(0x340)][_0x41bdfb(0x288)][_0x41bdfb(0x2fc)]()[0x0][_0x41bdfb(0x4ce)](),_0x2db320=_0x156c2c[_0x41bdfb(0x261)],_0x64e30a=_0x156c2c['width'];else return;}}else return;var _0x2a8957=0x64*_0x4621c9/_0x64e30a,_0x2c5758=0x64*_0xc36059/_0x2db320;log(_0x2a8957+_0x41bdfb(0x415)+_0x2c5758);var _0x49d21a=0x64;if(_0x2a8957>_0x2c5758)_0x49d21a=_0x2c5758;else{if(_0x41bdfb(0x4e4)!==_0x41bdfb(0x2f8))_0x49d21a=_0x2a8957;else{function _0x574ae5(){var _0x250767=_0x41bdfb;_0x439ef4[_0x250767(0x52d)](_0x3bebfe[_0x250767(0x444)](_0x4a42db[_0x250767(0x134)]))[_0x250767(0x57e)](function(_0x50f850){var _0x40aa3e=_0x250767;_0x2d1b75[_0x40aa3e(0x134)]=_0x50f850[0x0],_0x52ade3[_0x40aa3e(0x3f5)]=_0x50f850[0x1],_0x2e0113[_0x40aa3e(0x577)](_0x6a3c9c);});}}}_0x49d21a>0x64&&(_0x49d21a=0x64);log(_0x41bdfb(0x51b)+_0x49d21a),_0x162eb3[_0x41bdfb(0x147)][_0x315489][_0x41bdfb(0x4ab)]=_0x49d21a;var _0x5a25ab=0x64;log('session.pcs[UUID].scale\x20=\x20'+_0x162eb3[_0x41bdfb(0x147)][_0x315489]['scale']);_0x162eb3['pcs'][_0x315489][_0x41bdfb(0x3ea)]&&(_0x5a25ab=_0x162eb3[_0x41bdfb(0x147)][_0x315489]['scale']);if(_0x5a25ab>_0x49d21a){if('UKnxJ'===_0x41bdfb(0x11a)){function _0x23190b(){_0x802b6(_0xd9d63b);}}else _0x5a25ab=_0x49d21a;}_0x162eb3[_0x41bdfb(0x147)][_0x315489][_0x41bdfb(0x4ab)]&&(_0x162eb3['pcs'][_0x315489][_0x41bdfb(0x4ab)]<_0x5a25ab&&(_0x5a25ab=_0x162eb3[_0x41bdfb(0x147)][_0x315489][_0x41bdfb(0x4ab)]));_0x162eb3[_0x41bdfb(0x147)][_0x315489][_0x41bdfb(0x4db)]&&_0x162eb3['pcs'][_0x315489]['scaleDueToBitrate']<_0x5a25ab&&(_0x5a25ab=_0x162eb3['pcs'][_0x315489][_0x41bdfb(0x4db)]);log('pre\x20pixel\x20fix\x20'+_0x5a25ab),_0x5a25ab=_0x162eb3[_0x41bdfb(0x527)](_0x5a25ab),log(_0x41bdfb(0x30f)+_0x5a25ab);_0x5a25ab<=0x0?_0x396f4e['encodings'][0x0][_0x41bdfb(0x2da)]=0x1:_0x396f4e[_0x41bdfb(0x512)][0x0][_0x41bdfb(0x2da)]=0x64/_0x5a25ab;_0x82fe72[_0x41bdfb(0x567)](_0x396f4e)[_0x41bdfb(0x57e)](()=>{var _0xfd4f99=_0x41bdfb;log(_0xfd4f99(0x2b6)),log(_0x396f4e),pokeIframeAPI(_0xfd4f99(0x32f),_0x5a25ab,_0x315489);})[_0x41bdfb(0x19f)](warnlog),_0x162eb3[_0x41bdfb(0x147)][_0x315489][_0x41bdfb(0x14f)][_0x41bdfb(0x38d)]=parseInt(_0x5a25ab)+'%';return;}},_0x162eb3[_0x44a3fc(0x116)]=function(_0x3b4c9e=null,_0x3a4e27=null){var _0x3fb432=_0x44a3fc;_0x3a4e27&&_0x3a4e27[_0x3fb432(0x40e)]();log(_0x3fb432(0x544)+_0x3b4c9e);if(iOS||iPad)log(_0x3fb432(0x220));else{if((adapter[_0x3fb432(0x35d)][_0x3fb432(0x26b)]==='chrome'||adapter[_0x3fb432(0x35d)]['browser']===_0x3fb432(0x111)||adapter[_0x3fb432(0x35d)][_0x3fb432(0x26b)]===_0x3fb432(0x49a)&&adapter[_0x3fb432(0x35d)]['version']>=0x40)&&_0x3fb432(0x4b9)in window&&_0x3fb432(0x567)in window[_0x3fb432(0x4b9)][_0x3fb432(0x1c6)]){if(_0x3b4c9e==null){for(_0x3b4c9e in _0x162eb3[_0x3fb432(0x147)]){_0x162eb3[_0x3fb432(0x116)](_0x3b4c9e);}return![];}if(!(_0x3b4c9e in _0x162eb3['pcs']))return![];_0x162eb3['pcs'][_0x3b4c9e][_0x3fb432(0x139)]&&(_0x162eb3[_0x3fb432(0x147)][_0x3b4c9e][_0x3fb432(0x524)]&&(clearTimeout(_0x162eb3[_0x3fb432(0x147)][_0x3b4c9e][_0x3fb432(0x524)]),_0x162eb3[_0x3fb432(0x147)][_0x3b4c9e]['keyframeTimeout']=null),_0x162eb3[_0x3fb432(0x147)][_0x3b4c9e]['keyframeTimeout']=setTimeout(function(){var _0x3a8b41=_0x3fb432;if(_0x3a8b41(0x4dd)!==_0x3a8b41(0x4dd)){function _0x5246da(){var _0x55ae56=_0x3a8b41;_0xa65b95[_0x55ae56(0x1f4)][_0x431d78][_0x55ae56(0x14f)][_0x55ae56(0x446)][_0x55ae56(0x212)]=_0x29e455[_0x55ae56(0x2f0)];}}else _0x162eb3[_0x3a8b41(0x116)](_0x3b4c9e);},parseInt(_0x162eb3[_0x3fb432(0x147)][_0x3b4c9e]['keyframerate'])));try{var _0x13fcc8=_0x162eb3[_0x3fb432(0x147)][_0x3b4c9e][_0x3fb432(0x442)]()[_0x3fb432(0x107)](function(_0x266d98){var _0x170845=_0x3fb432;return _0x266d98[_0x170845(0x2ac)]&&_0x266d98[_0x170845(0x2ac)]['kind']==_0x170845(0x3cb);});if(!_0x13fcc8)return warnlog('can\x27t\x20change\x20bitrate;\x20no\x20video\x20sender\x20found'),![];var _0x1db818=_0x13fcc8[_0x3fb432(0x1cb)]();if(!_0x1db818[_0x3fb432(0x512)]||_0x1db818['encodings'][_0x3fb432(0x3f4)]==0x0){if(_0x3fb432(0x4ef)===_0x3fb432(0x260)){function _0x3c891b(){var _0x2a8201=_0x3fb432,_0x55d3ab=_0x513f6f[_0x2a8201(0x4bb)](_0x8ee752[_0x2a8201(0x3b8)]);for(var _0x181825 in _0x55d3ab){_0x24b9b2(_0x2a8201(0x2b7)+_0x55d3ab[_0x181825]),_0xb2fcf3[_0x2a8201(0x39b)](_0x55d3ab[_0x181825]);}}}else _0x1db818['encodings']=[{}];}var _0x33ac02=![];_0x1db818[_0x3fb432(0x512)][0x0][_0x3fb432(0x2da)]=0xa,_0x13fcc8[_0x3fb432(0x567)](_0x1db818)[_0x3fb432(0x57e)](()=>{var _0x34d742=_0x3fb432;log(_0x34d742(0x2d4));var _0x5f4fd4=_0x162eb3[_0x34d742(0x147)][_0x3b4c9e]['scaleResolution'],_0x4170c6=0x64;if(!_0x5f4fd4){if('EaDfb'!==_0x34d742(0x572))_0x5f4fd4=_0x4170c6;else{function _0x4dc6e7(){var _0x28de2c=_0x34d742,_0x28d015=_0x3b7bb1[_0x28de2c(0x41a)]('[data-action-type=\x22mute-guest\x22][data--u-u-i-d=\x22'+_0x56e067+'\x22]');_0x28d015[0x0]&&(_0x28d015[0x0][_0x28de2c(0x532)]=!![],_0x28d015[0x0][_0x28de2c(0xcf)]=_0x28de2c(0x150));var _0x28d015=_0x2473c3[_0x28de2c(0x41a)](_0x28de2c(0x588)+_0x381087+'\x22]');_0x28d015[0x0]&&(_0x28d015[0x0][_0x28de2c(0x532)]=!![],_0x28d015[0x0][_0x28de2c(0xcf)]=_0x28de2c(0x150),_0x28d015[0x0]['style'][_0x28de2c(0x345)]=0.2);}}}_0x162eb3[_0x34d742(0x147)][_0x3b4c9e][_0x34d742(0x3ea)]&&(_0x4170c6=_0x162eb3[_0x34d742(0x147)][_0x3b4c9e][_0x34d742(0x3ea)]);_0x4170c6>_0x5f4fd4&&(_0x4170c6=_0x5f4fd4);_0x162eb3[_0x34d742(0x147)][_0x3b4c9e][_0x34d742(0x4ab)]&&(_0x162eb3[_0x34d742(0x147)][_0x3b4c9e]['scaleResolution']<_0x4170c6&&(_0x4170c6=_0x162eb3[_0x34d742(0x147)][_0x3b4c9e][_0x34d742(0x4ab)]));_0x162eb3[_0x34d742(0x147)][_0x3b4c9e][_0x34d742(0x4db)]&&_0x162eb3[_0x34d742(0x147)][_0x3b4c9e]['scaleDueToBitrate']<_0x4170c6&&(_0x4170c6=_0x162eb3[_0x34d742(0x147)][_0x3b4c9e][_0x34d742(0x4db)]);log(_0x34d742(0x47a)+_0x4170c6),_0x4170c6=_0x162eb3[_0x34d742(0x527)](_0x4170c6);var _0x2ee398=_0x13fcc8[_0x34d742(0x1cb)]();_0x2ee398['encodings'][0x0][_0x34d742(0x2da)]=0x64/_0x4170c6,log(_0x34d742(0x201)),_0x13fcc8['setParameters'](_0x2ee398)[_0x34d742(0x57e)](()=>{var _0x530916=_0x34d742;log(_0x530916(0x143));})['catch'](warnlog);})[_0x3fb432(0x19f)](warnlog);}catch(_0x540b74){errorlog(_0x540b74);}}}return![];},_0x162eb3[_0x44a3fc(0x4d2)]=function(_0x34caae){var _0x22aa9e=_0x44a3fc;log('enhacing\x20audio\x20encoder');var _0x19a187=_0x162eb3[_0x22aa9e(0x147)][_0x34caae][_0x22aa9e(0x442)]()[_0x22aa9e(0x107)](function(_0x16a0d8){var _0x432530=_0x22aa9e;return _0x16a0d8[_0x432530(0x2ac)]&&_0x16a0d8[_0x432530(0x2ac)][_0x432530(0x2c3)]==_0x432530(0x25f);});if(!_0x19a187)return log('no\x20audio\x20track\x20to\x20poke'),![];var _0x402f77=_0x19a187[_0x22aa9e(0x1cb)]();(!_0x402f77[_0x22aa9e(0x512)]||_0x402f77['encodings'][_0x22aa9e(0x3f4)]==0x0)&&(_0x402f77[_0x22aa9e(0x512)]=[{}]);try{_0x402f77[_0x22aa9e(0x512)][0x0][_0x22aa9e(0x17a)]=_0x22aa9e(0x325),_0x402f77[_0x22aa9e(0x512)][0x0]['priority']=_0x22aa9e(0x325),_0x402f77[_0x22aa9e(0x512)][0x0][_0x22aa9e(0x36c)]=!![],_0x19a187[_0x22aa9e(0x567)](_0x402f77)['then'](()=>{var _0x5829ff=_0x22aa9e;log(_0x5829ff(0x406)),pokeIframeAPI(_0x5829ff(0x4d2),!![],_0x34caae);});}catch(_0x238587){errorlog(_0x238587);}},_0x162eb3[_0x44a3fc(0x546)]=function(_0x468ed1,_0x2ade9e=0x7d00,_0x44d6fc=0x3e8){var _0x50d96c=_0x44a3fc;if('wIgEc'!==_0x50d96c(0x2ce)){function _0x399edf(){var _0x4e30ac=_0x50d96c;delete _0x35313f[_0x4e30ac(0x1f4)][_0x2a362a],_0x5f5329(),_0x157716('Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit');return;}}else{log(_0x50d96c(0x467));var _0x1236c9=_0x162eb3[_0x50d96c(0x147)][_0x468ed1][_0x50d96c(0x442)]()[_0x50d96c(0x107)](function(_0x864004){var _0x200a3e=_0x50d96c;return _0x864004[_0x200a3e(0x2ac)]&&_0x864004[_0x200a3e(0x2ac)][_0x200a3e(0x2c3)]=='audio';});if(!_0x1236c9)return log('no\x20audio\x20track\x20to\x20poke'),![];var _0x3062dc=_0x1236c9[_0x50d96c(0x1cb)]();(!_0x3062dc[_0x50d96c(0x512)]||_0x3062dc[_0x50d96c(0x512)][_0x50d96c(0x3f4)]==0x0)&&(_0x3062dc[_0x50d96c(0x512)]=[{}]),_0x3062dc[_0x50d96c(0x512)][0x0][_0x50d96c(0x23e)]=_0x2ade9e,_0x1236c9['setParameters'](_0x3062dc)[_0x50d96c(0x57e)](()=>{pokeIframeAPI('setAudioBitrate',_0x2ade9e,_0x468ed1),_0x44d6fc>0x0&&setTimeout(function(){var _0x4c8880=_0x447b;try{if(_0x468ed1 in _0x162eb3[_0x4c8880(0x147)])var _0x3e7013=_0x162eb3[_0x4c8880(0x147)][_0x468ed1][_0x4c8880(0x442)]()[_0x4c8880(0x107)](function(_0x26499a){var _0x5db805=_0x4c8880;return _0x26499a[_0x5db805(0x2ac)]&&_0x26499a[_0x5db805(0x2ac)][_0x5db805(0x2c3)]=='audio';});else return![];if(!_0x3e7013)return log(_0x4c8880(0x470)),![];var _0x342576=_0x3e7013[_0x4c8880(0x1cb)]();delete _0x342576[_0x4c8880(0x512)][0x0][_0x4c8880(0x23e)],_0x3e7013[_0x4c8880(0x567)](_0x342576)[_0x4c8880(0x57e)](()=>{var _0x42b75a=_0x4c8880;log(_0x42b75a(0x406));});}catch(_0x44e636){errorlog(_0x44e636);}},_0x44d6fc,_0x468ed1);});}},_0x162eb3[_0x44a3fc(0x2d3)]=function(_0x3225c3,_0x393feb){var _0x3839e8=_0x44a3fc;_0x393feb=parseInt(_0x393feb);try{var _0x3fcc02=_0x162eb3[_0x3839e8(0x147)][_0x3225c3][_0x3839e8(0x442)]()['find'](function(_0x564db5){var _0x24bf5b=_0x3839e8;if(_0x24bf5b(0x2e2)===_0x24bf5b(0x2e2))return _0x564db5[_0x24bf5b(0x2ac)]&&_0x564db5[_0x24bf5b(0x2ac)][_0x24bf5b(0x2c3)]==_0x24bf5b(0x25f);else{function _0x77adb(){var _0x1162b7=_0x24bf5b,_0x53861c=_0x3f0b8b(_0xbcdee6[_0x1162b7(0x2ac)]);_0x53861c<_0x3d0fe3[_0x1162b7(0x3f4)]&&(_0x5b9011=_0x4fab63[_0x53861c],_0x354dd8(_0x570026[_0x1162b7(0x57d)],_0x1bc501[_0x1162b7(0x276)]));}}});if(!_0x3fcc02){if(_0x3839e8(0x3a6)!=='cNPKk'){function _0x427415(){var _0x5df09d=_0x3839e8;_0x3e7460[_0x5df09d(0x39b)](_0x31293d[_0x42f815]);}}else{warnlog(_0x3839e8(0x1f0));return;}}var _0x3d0c03=_0x3fcc02['getParameters']();if(!_0x3d0c03[_0x3839e8(0x512)]||_0x3d0c03[_0x3839e8(0x512)][_0x3839e8(0x3f4)]==0x0){if('yZEIU'===_0x3839e8(0x36a))_0x3d0c03[_0x3839e8(0x512)]=[{}];else{function _0x1262cd(){var _0x12426a=_0x3839e8,_0x3c8edb=_0x5f4cf8[_0x12426a(0x508)](_0x4f5ed6[_0x12426a(0x16b)][_0x12426a(0x457)])||0x0;_0x5da45e[_0x12426a(0x16b)][_0x12426a(0x457)]=_0x21fb28[_0x12426a(0x38e)](_0x598677[_0x12426a(0x16b)][_0x12426a(0x457)],{'min':_0x61ec4f(_0x4c57ac/0xa)||0x1,'max':_0x3e3b43(_0xe2c2d7+_0x3c8edb/0x400)}),_0x44e02b[_0x12426a(0x147)][_0x1e28c3[_0x12426a(0x1e2)]][_0x12426a(0x2a1)]=_0x26b91c;}}}if(_0x393feb<0x0)_0x3d0c03['encodings'][0x0][_0x3839e8(0x3b0)]==![]&&(_0x3d0c03[_0x3839e8(0x512)][0x0]['active']=!![]),safariVersion()<=0xd&&(iOS||iPad)?(_0x393feb=0x20,_0x162eb3['audiobitrate']&&(_0x393feb=_0x162eb3[_0x3839e8(0x4f5)]),_0x3d0c03[_0x3839e8(0x512)][0x0][_0x3839e8(0x23e)]=_0x393feb*0x400):delete _0x3d0c03[_0x3839e8(0x512)][0x0][_0x3839e8(0x23e)];else _0x393feb===0x0?_0x3d0c03['encodings'][0x0][_0x3839e8(0x3b0)]=![]:(_0x3d0c03[_0x3839e8(0x512)][0x0][_0x3839e8(0x3b0)]==![]&&(_0x3d0c03['encodings'][0x0][_0x3839e8(0x3b0)]=!![]),_0x3d0c03[_0x3839e8(0x512)][0x0][_0x3839e8(0x23e)]=_0x393feb*0x400);_0x3fcc02[_0x3839e8(0x567)](_0x3d0c03)['then'](()=>{var _0x154f60=_0x3839e8;pokeIframeAPI(_0x154f60(0xff),_0x393feb,_0x3225c3),log(_0x154f60(0x14d));})[_0x3839e8(0x19f)](warnlog);}catch(_0x48cd5f){if(_0x3839e8(0x2ff)!==_0x3839e8(0x1db))errorlog(_0x48cd5f);else{function _0x335718(){var _0x27897c=_0x3839e8;_0x50b24d[_0x27897c(0x39b)](_0x465f36);}}}},_0x162eb3[_0x44a3fc(0xd4)]=function(_0x62ca04){var _0x171245=_0x44a3fc;if(_0x162eb3[_0x171245(0x40c)]&&_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0x117)]===!![])_0x162eb3[_0x171245(0x451)](_0x62ca04,0x0),_0x162eb3['pcs'][_0x62ca04][_0x171245(0x40d)]===0x0&&(_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0xeb)]===![]?_0x162eb3[_0x171245(0x2d3)](_0x62ca04,0x0):_0x162eb3[_0x171245(0x2d3)](_0x62ca04,-0x1));else{if(_0x162eb3[_0x171245(0x147)][_0x62ca04]&&_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0x40d)]!==![]){if(_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0xeb)]===![]){var _0x3374db=_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0x40d)];_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0x46d)]&&_0x162eb3['pcs'][_0x62ca04][_0x171245(0x46d)]>0x0&&(_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0x46d)]<_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0x40d)]&&(_0x3374db=_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0x46d)])),_0x162eb3[_0x171245(0x451)](_0x62ca04,_0x3374db),_0x162eb3[_0x171245(0x147)][_0x62ca04][_0x171245(0x40d)]===0x0&&_0x162eb3[_0x171245(0x2d3)](_0x62ca04,0x0);}else _0x162eb3['pcs'][_0x62ca04][_0x171245(0x40d)]===0x0&&_0x162eb3[_0x171245(0x2d3)](_0x62ca04,-0x1);}}},_0x162eb3[_0x44a3fc(0x218)]=function(_0x703b8=0x0,_0x5074a5=![]){var _0x2af263=_0x44a3fc;if('OyJsU'!==_0x2af263(0x377)){if(_0x162eb3['limitTotalBitrate']){var _0xb9e8e1=_0x703b8;warnlog(_0xb9e8e1);var _0xe9cb0a=0x0;for(var _0x18ce69 in _0x162eb3[_0x2af263(0x147)]){if(_0x5074a5===_0x18ce69)continue;var _0x4b112d=_0x162eb3['pcs'][_0x18ce69][_0x2af263(0x442)]()[_0x2af263(0x107)](function(_0x5a04df){var _0x36fbd2=_0x2af263;return _0x5a04df[_0x36fbd2(0x2ac)]&&_0x5a04df[_0x36fbd2(0x2ac)][_0x36fbd2(0x2c3)]==_0x36fbd2(0x3cb);});if(!_0x4b112d)continue;var _0x724ffe=_0x4b112d[_0x2af263(0x1cb)]();if(!_0x724ffe[_0x2af263(0x512)]||_0x724ffe[_0x2af263(0x512)][_0x2af263(0x3f4)]==0x0){if(_0x2af263(0x4c6)!=='LrVVH'){function _0x3f05a1(){var _0x19dcdc=_0x2af263;_0x46bba6[_0x19dcdc(0x223)]=_0x5b52f9[_0x19dcdc(0x3cc)][_0x19dcdc(0x4a6)];}}else{_0xb9e8e1+=_0x162eb3[_0x2af263(0x147)][_0x18ce69][_0x2af263(0x2a1)]||0x9c4,warnlog(_0xb9e8e1),_0xe9cb0a+=0x1;continue;}}if(_0x724ffe[_0x2af263(0x512)][0x0][_0x2af263(0x3b0)]==![])continue;_0x724ffe['encodings'][0x0][_0x2af263(0x23e)]?(_0xb9e8e1+=parseInt(_0x724ffe['encodings'][0x0][_0x2af263(0x23e)])/0x400,warnlog(_0xb9e8e1)):(_0xb9e8e1+=_0x162eb3[_0x2af263(0x147)][_0x18ce69][_0x2af263(0x2a1)]||0x9c4,warnlog(_0xb9e8e1)),_0xe9cb0a+=0x1;}if(!_0xb9e8e1)return![];var _0x33ae49=parseFloat(_0xb9e8e1/_0x162eb3[_0x2af263(0x3da)]);if(_0x33ae49>0x1)for(var _0x18ce69 in _0x162eb3[_0x2af263(0x147)]){if(_0x2af263(0x2ec)===_0x2af263(0x2ec)){if(_0x5074a5===_0x18ce69)continue;var _0x4b112d=_0x162eb3[_0x2af263(0x147)][_0x18ce69][_0x2af263(0x442)]()['find'](function(_0x198041){var _0x3a765d=_0x2af263;return _0x198041['track']&&_0x198041[_0x3a765d(0x2ac)][_0x3a765d(0x2c3)]==_0x3a765d(0x3cb);});if(!_0x4b112d)continue;var _0x724ffe=_0x4b112d[_0x2af263(0x1cb)]();if(!_0x724ffe[_0x2af263(0x512)]||_0x724ffe[_0x2af263(0x512)]['length']==0x0){var _0x49d733=_0x162eb3[_0x2af263(0x147)][_0x18ce69]['setBitrate']||0x9c4;_0x162eb3[_0x2af263(0x451)](_0x18ce69,parseInt(_0x49d733/_0x33ae49),!![]),errorlog(parseInt(_0x49d733/_0x33ae49));continue;}if(_0x724ffe[_0x2af263(0x512)][0x0][_0x2af263(0x3b0)]==![])continue;if(_0x724ffe[_0x2af263(0x512)][0x0][_0x2af263(0x23e)]){if(_0x2af263(0x4c1)===_0x2af263(0x1d5)){function _0x834b3e(){var _0x3269a6=_0x2af263;_0x102002['pcs'][_0x9a73da][_0x3269a6(0x506)]=!![];}}else errorlog(parseInt(parseInt(_0x724ffe[_0x2af263(0x512)][0x0][_0x2af263(0x23e)])/0x400/_0x33ae49)),_0x162eb3['limitBitrate'](_0x18ce69,parseInt(parseInt(_0x724ffe['encodings'][0x0][_0x2af263(0x23e)])/0x400/_0x33ae49),!![]);}else{var _0x49d733=_0x162eb3[_0x2af263(0x147)][_0x18ce69][_0x2af263(0x2a1)]||0x9c4;errorlog(parseInt(_0x49d733/_0x33ae49)),_0x162eb3[_0x2af263(0x451)](_0x18ce69,parseInt(_0x49d733/_0x33ae49),!![]);}}else{function _0xadd5d(){var _0x3ea2bc=_0x2af263;try{_0x53aeda[_0x3ea2bc(0x1f4)][_0x2f097f]['stats'][_0x3ea2bc(0x53f)][_0x3ea2bc(0x1b6)]=!![];}catch(_0x49f417){}}}}return parseInt(_0x703b8/_0x33ae49);}else return![];}else{function _0x3783a9(){var _0x46b97f=_0x2af263;_0x48dcf3(_0x46b97f(0x459)),_0x3e38a3[_0x46b97f(0x147)][_0x4b0d83['UUID']][_0x46b97f(0x556)](),delete _0x2dea10[_0x46b97f(0x147)][_0x223dbe[_0x46b97f(0x1e2)]],_0x13dc6c[_0x46b97f(0x421)](),_0x491014();}}},_0x162eb3['limitBitrate']=function(_0x4c7c35,_0x15cbc9,_0xb903f0=![]){var _0x5d731b=_0x44a3fc;_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x49f)]&&(clearInterval(_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x49f)]),_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x49f)]=null);if(_0x15cbc9===null){if(_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x46d)]===![])return;_0x15cbc9=_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['savedBitrate'];}_0x15cbc9=parseInt(_0x15cbc9);_0x162eb3[_0x5d731b(0x1e5)]&&(_0x15cbc9>_0x162eb3[_0x5d731b(0x1e5)]&&(_0x15cbc9=_0x162eb3['maxvideobitrate']));_0x162eb3['pcs'][_0x4c7c35][_0x5d731b(0x46d)]=_0x15cbc9;if(_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['optimizedBitrate']!==![]){if(_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0xeb)]===![]){if('RfYGw'===_0x5d731b(0x356))_0x15cbc9>_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x40d)]&&(_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['savedBitrate']=_0x15cbc9,_0x15cbc9=parseInt(_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x40d)])||0x0);else{function _0x4dfa8d(){var _0xbb7b6a=_0x5d731b;_0x548275[_0xbb7b6a(0x179)](_0x5ab2c6[_0xbb7b6a(0x1e2)]);}}}}_0xb903f0===![]&&(_0x162eb3[_0x5d731b(0x3da)]&&(_0x15cbc9=_0x162eb3[_0x5d731b(0x218)](_0x15cbc9,_0x4c7c35)));if(_0x15cbc9==0x0){if(_0x5d731b(0x52e)===_0x5d731b(0x52e)){var _0x1bbe40=Date[_0x5d731b(0x1b9)]()-_0x162eb3['pcs'][_0x4c7c35][_0x5d731b(0x13c)];_0x1bbe40<_0x162eb3[_0x5d731b(0x1d8)]&&(_0x15cbc9=0x23,_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x49f)]=setTimeout(function(_0x5772f0){_0x162eb3['limitBitrate'](_0x5772f0,null);},_0x1bbe40,_0x4c7c35));}else{function _0x3646dc(){var _0x3ffb43=_0x5d731b;_0x53c188['rpcs'][_0x417506][_0x3ffb43(0x2c5)]=_0x39f941(_0x49463b[_0x3ffb43(0x2c5)])||0x0;_0x1aa08a in _0x12a93a[_0x3ffb43(0x147)]&&(_0xb0c226[_0x3ffb43(0x147)][_0x54a4bc][_0x3ffb43(0x2c5)]=_0x1d54d4(_0x44c946[_0x3ffb43(0x2c5)])||0x0);if(_0x1b0331['director']){var _0x2947b7=_0x51d476[_0x3ffb43(0x41a)](_0x3ffb43(0x330)+_0xa6aeb3+'\x22]');_0x2947b7[0x0]&&(_0x2947b7[0x0][_0x3ffb43(0x27f)]=_0x3feaf1(_0x44ef1b[_0x3ffb43(0x2c5)])||0x0);}_0x5ae623=!![];}}}try{if(safariVersion()<=0xd&&(iOS||iPad)){log('iOS\x20devices\x20do\x20not\x20support\x20dynamic\x20bitrates\x20correctly;\x20skipping');if(_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x466)]==!![]&&_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x26c)]==![])return;var _0x4431a9=_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['getSenders']()[_0x5d731b(0x107)](function(_0x2a5d91){var _0x5b2acf=_0x5d731b;return _0x2a5d91[_0x5b2acf(0x2ac)]&&_0x2a5d91[_0x5b2acf(0x2ac)][_0x5b2acf(0x2c3)]==_0x5b2acf(0x3cb);});if(!_0x4431a9){warnlog(_0x5d731b(0x331));return;}var _0x3f8ed=_0x4431a9[_0x5d731b(0x1cb)]();(!_0x3f8ed[_0x5d731b(0x512)]||_0x3f8ed[_0x5d731b(0x512)][_0x5d731b(0x3f4)]==0x0)&&(_0x3f8ed[_0x5d731b(0x512)]=[{}]);if(_0x15cbc9<0x0){_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x3b0)]==![]&&(_0x3f8ed[_0x5d731b(0x512)][0x0]['active']=!![]);_0x15cbc9=0x9c4;if(_0x162eb3['bitrate']){if(_0x5d731b(0x2c4)!==_0x5d731b(0x2c4)){function _0x420400(){var _0x5d8fa7=_0x5d731b;return _0x990a23[_0x5d8fa7(0x2ac)]&&_0x493e8f['track'][_0x5d8fa7(0x2c3)]==_0x5d8fa7(0x3cb);}}else _0x15cbc9=_0x162eb3['bitrate'];}_0x162eb3[_0x5d731b(0x1e5)]&&(_0x15cbc9>_0x162eb3[_0x5d731b(0x1e5)]&&(_0x15cbc9=_0x162eb3[_0x5d731b(0x1e5)])),_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x23e)]=_0x15cbc9*0x400;}else{if(_0x15cbc9===0x0)_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x3b0)]=![];else{if(_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x3b0)]==![]){if(_0x5d731b(0x242)===_0x5d731b(0x242))_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x3b0)]=!![];else{function _0x3285aa(){var _0x1cb6a1=_0x5d731b;_0x1b55a4[_0x1cb6a1(0x21d)](_0x2ca3e5);}}}_0x3f8ed['encodings'][0x0][_0x5d731b(0x23e)]=_0x15cbc9*0x400;}}_0x4431a9[_0x5d731b(0x567)](_0x3f8ed)['then'](()=>{var _0x2188c0=_0x5d731b;pokeIframeAPI(_0x2188c0(0x43a),_0x15cbc9,_0x4c7c35),log(_0x2188c0(0x368));})['catch'](warnlog);return;}else{if((iOS||iPad)&&(_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x466)]==!![]&&_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['forceios']==![])){var _0x2437df=0x64;_0x162eb3['pcs'][_0x4c7c35]['scale']&&(_0x2437df=_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x3ea)]),_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4ab)]&&_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4ab)]<_0x2437df&&(_0x2437df=_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['scaleResolution']),_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['scaleDueToBitrate']=0x64/0x3,_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4db)]<_0x2437df&&(_0x2437df=_0x162eb3['pcs'][_0x4c7c35]['scaleDueToBitrate']),_0x2437df=_0x162eb3[_0x5d731b(0x527)](_0x2437df),_0x3f8ed['encodings'][0x0][_0x5d731b(0x2da)]=0x64/_0x2437df,_0x4431a9[_0x5d731b(0x567)](_0x3f8ed)['then'](()=>{log('iOS\x20guest\x20SCALE\x20set!'),pokeIframeAPI('setVideoScale',_0x2437df,_0x4c7c35);})[_0x5d731b(0x19f)](warnlog),_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x14f)]['scaleFactor']=parseInt(_0x2437df)+'%';}else{if((adapter[_0x5d731b(0x35d)][_0x5d731b(0x26b)]==='chrome'||adapter[_0x5d731b(0x35d)]['browser']===_0x5d731b(0x111)||adapter[_0x5d731b(0x35d)]['browser']===_0x5d731b(0x49a)&&adapter[_0x5d731b(0x35d)][_0x5d731b(0x158)]>=0x40)&&_0x5d731b(0x4b9)in window&&_0x5d731b(0x567)in window[_0x5d731b(0x4b9)][_0x5d731b(0x1c6)]){var _0x4431a9=_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x442)]()[_0x5d731b(0x107)](function(_0x1f6d23){var _0x333c25=_0x5d731b;return _0x1f6d23[_0x333c25(0x2ac)]&&_0x1f6d23[_0x333c25(0x2ac)][_0x333c25(0x2c3)]==_0x333c25(0x3cb);});if(!_0x4431a9){warnlog(_0x5d731b(0x331));return;}var _0x3f8ed=_0x4431a9['getParameters']();(!_0x3f8ed[_0x5d731b(0x512)]||_0x3f8ed[_0x5d731b(0x512)][_0x5d731b(0x3f4)]==0x0)&&(_0x3f8ed['encodings']=[{}]);if(_0x15cbc9<0x0)_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x3b0)]==![]&&(_0x3f8ed['encodings'][0x0]['active']=!![]),delete _0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x23e)];else _0x15cbc9===0x0?_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x3b0)]=![]:(_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x3b0)]==![]&&(_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x3b0)]=!![]),_0x3f8ed[_0x5d731b(0x512)][0x0][_0x5d731b(0x23e)]=_0x15cbc9*0x400);var _0x2437df=0x64;_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['scale']&&(_0x2437df=_0x162eb3['pcs'][_0x4c7c35][_0x5d731b(0x3ea)]);_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['scaleResolution']&&_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4ab)]<_0x2437df&&(_0x2437df=_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4ab)]);if(_0x15cbc9<0x0)_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4db)]=0x64;else{if(_0x15cbc9>=0x259)_0x162eb3['pcs'][_0x4c7c35][_0x5d731b(0x4db)]=0x64;else{if(_0x162eb3['pcs'][_0x4c7c35][_0x5d731b(0x145)]===![]&&_0x162eb3[_0x5d731b(0x37c)]!==_0x4c7c35&&_0x162eb3[_0x5d731b(0x460)])_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4db)]=0x64;else{if(_0x15cbc9>=0xc9)_0x162eb3[_0x5d731b(0x3bd)]?_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4db)]=0x64/2.5:_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4db)]=0x64/0x2;else _0x15cbc9>=0x51?_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4db)]=0x64/0x3:_0x162eb3[_0x5d731b(0x147)][_0x4c7c35]['scaleDueToBitrate']=0x64/0x4;}}}_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4db)]<_0x2437df&&(_0x2437df=_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x4db)]);_0x2437df=_0x162eb3[_0x5d731b(0x527)](_0x2437df),_0x3f8ed['encodings'][0x0][_0x5d731b(0x2da)]=0x64/_0x2437df,_0x4431a9[_0x5d731b(0x567)](_0x3f8ed)[_0x5d731b(0x57e)](()=>{var _0xaf7aec=_0x5d731b;log(_0xaf7aec(0x368)),pokeIframeAPI('setVideoBitrate',_0x15cbc9,_0x4c7c35),pokeIframeAPI(_0xaf7aec(0x32f),_0x2437df,_0x4c7c35);})[_0x5d731b(0x19f)](warnlog),_0x162eb3[_0x5d731b(0x147)][_0x4c7c35][_0x5d731b(0x14f)][_0x5d731b(0x38d)]=parseInt(_0x2437df)+'%';return;}}}}catch(_0x341117){if(_0x5d731b(0x256)!==_0x5d731b(0x197))errorlog(_0x341117);else{function _0x45f46e(){return _0x40771b;}}}};function _0x2bcdde(_0x15f873,_0x54ab28=0x2710){var _0x3e8c8b=_0x44a3fc;_0x54ab28=parseInt(_0x54ab28);if(_0x162eb3[_0x3e8c8b(0x4f5)]){if('HeFpN'===_0x3e8c8b(0x333))_0x54ab28+=_0x162eb3[_0x3e8c8b(0x4f5)];else{function _0x274470(){var _0x2bf93f=_0x3e8c8b;if(_0x5ea87c[_0x2bf93f(0x37c)]===_0x40aa44['UUID'])_0x46626d[_0x2bf93f(0x179)](_0x5247d6[_0x2bf93f(0x1e2)]);else _0x2293a8[_0x2bf93f(0x1b6)]&&(_0x112bc1['UUID']in _0x218ab8['rpcs']&&_0xa37a34[_0x2bf93f(0x179)](_0x23fdfd[_0x2bf93f(0x1e2)]));}}}else{if(_0x162eb3[_0x3e8c8b(0x1b6)]&&_0x162eb3['stereo']==0x5)_0x54ab28+=0x20;else _0x162eb3[_0x3e8c8b(0x133)]&&_0x162eb3[_0x3e8c8b(0x133)]!=0x3?_0x54ab28+=0x100:_0x54ab28+=0x20;}return log(_0x3e8c8b(0xe4)+_0x54ab28),_0x54ab28<0x1&&(_0x54ab28=0x1),_0x15f873=CodecsHandler[_0x3e8c8b(0x38e)](_0x15f873,{'min':parseInt(_0x54ab28/0xa)||0x1,'max':_0x54ab28},_0x162eb3[_0x3e8c8b(0x1d2)]),_0x15f873;}return _0x162eb3[_0x44a3fc(0x42a)]=function(_0x22597e,_0x2b6c7e){var _0x482da7=_0x44a3fc;log(_0x22597e),_0x162eb3['mykey']==={}&&log(_0x482da7(0x254)),window[_0x482da7(0x258)][_0x482da7(0x426)][_0x482da7(0x4e3)]({'name':_0x482da7(0x2cc)},_0x162eb3[_0x482da7(0x2d5)]['privateKey'],_0x162eb3[_0x482da7(0x4bd)]['encode'](_0x22597e))[_0x482da7(0x57e)](function(_0x57acb9){var _0x3515cb=_0x482da7;_0x57acb9=new Uint8Array(_0x57acb9),_0x57acb9=_0x57acb9[_0x3515cb(0x4fb)]((_0x209d34,_0x4c5a99)=>_0x209d34+_0x4c5a99[_0x3515cb(0x51f)](0x10)[_0x3515cb(0x2d1)](0x2,'0'),''),_0x2b6c7e(_0x22597e,_0x57acb9),log(JSON[_0x3515cb(0x444)](_0x57acb9));})[_0x482da7(0x19f)](errorlog);},_0x162eb3['verifyData']=function(_0x5f424c,_0x5d4d8d){var _0x3bf540=_0x44a3fc;_0x5f424c[_0x3bf540(0x531)]=new Uint8Array(_0x5f424c['signature'][_0x3bf540(0xce)](/.{1,2}/g)[_0x3bf540(0x15c)](_0x24a8cd=>parseInt(_0x24a8cd,0x10)));if(_0x162eb3[_0x3bf540(0x4bb)][_0x5d4d8d]['publicKey'])return window[_0x3bf540(0x258)]['subtle']['verify']({'name':_0x3bf540(0x2cc)},_0x162eb3[_0x3bf540(0x4bb)][_0x5d4d8d][_0x3bf540(0x52a)],_0x5f424c[_0x3bf540(0x531)],_0x162eb3[_0x3bf540(0x4bd)][_0x3bf540(0x32d)](_0x5f424c[_0x3bf540(0x2cd)]))[_0x3bf540(0x57e)](function(_0x470cac){return log(_0x470cac),_0x470cac;})[_0x3bf540(0x19f)](function(_0x45ed04){return errorlog(_0x45ed04),![];});},_0x162eb3['desaltStreamID']=function(_0x4ada52){var _0x51e7b0=_0x44a3fc;if(_0x162eb3[_0x51e7b0(0xf2)]){if(_0x51e7b0(0x540)!==_0x51e7b0(0x473))return _0x162eb3[_0x51e7b0(0x429)]!==![]?(log(_0x51e7b0(0x43b)),_0x4ada52=_0x4ada52[_0x51e7b0(0x32a)](0x0,-0x1*_0x162eb3[_0x51e7b0(0x429)][_0x51e7b0(0x3f4)]),_0x4ada52):(log(_0x51e7b0(0x3af)+_0x4ada52),_0x162eb3['generateHash'](_0x162eb3[_0x51e7b0(0xf2)]+_0x162eb3[_0x51e7b0(0x14c)],0x6)['then'](function(_0x3b454d){var _0x316abc=_0x51e7b0;return _0x162eb3[_0x316abc(0x429)]=_0x3b454d,log(_0x4ada52),_0x4ada52=_0x4ada52[_0x316abc(0x32a)](0x0,-0x1*_0x162eb3[_0x316abc(0x429)][_0x316abc(0x3f4)]),log(_0x316abc(0x495)+_0x4ada52),_0x4ada52;}));else{function _0x288a7a(){var _0x43a7bc=_0x51e7b0;_0x5ad719[_0x43a7bc(0x34f)]=_0x3d5bd7[_0x43a7bc(0x34f)][_0x43a7bc(0x129)](0x0,0x18)+_0x434fe5['hash']['substring'](0x0,0x6);var _0x2fa821=_0x1d2396['stringify'](_0x4ed7f5);if(_0x2fa821[_0x43a7bc(0x3f4)]>0x3a98){_0x5e55a9(_0x43a7bc(0x559));return;}_0x12c94c['ws'][_0x43a7bc(0x388)](_0x2fa821);}}}return _0x4ada52;},_0x162eb3[_0x44a3fc(0x309)]=function(){var _0x321cad=_0x44a3fc;if(!_0x162eb3[_0x321cad(0x46f)])return;if(!_0x162eb3[_0x321cad(0x1b6)]){if('aGrqL'===_0x321cad(0x16e)){function _0x5b7958(){return;}}else return;}_0x162eb3[_0x321cad(0x1c1)][_0x321cad(0x3f4)]?(_0x162eb3[_0x321cad(0x1c1)][_0x321cad(0x3f4)]>0xa?getById(_0x321cad(0x183))['innerHTML']='‼':getById(_0x321cad(0x183))[_0x321cad(0x564)]=_0x162eb3['queueList'][_0x321cad(0x3f4)],getById(_0x321cad(0x183))[_0x321cad(0x2ed)][_0x321cad(0x106)](_0x321cad(0x183))):(getById(_0x321cad(0x183))[_0x321cad(0x564)]='',getById(_0x321cad(0x183))[_0x321cad(0x2ed)][_0x321cad(0x41f)](_0x321cad(0x183)));},_0x162eb3[_0x44a3fc(0x154)]=function(){var _0x1cd5d7=_0x44a3fc;if(!_0x162eb3[_0x1cd5d7(0x46f)]){if(_0x1cd5d7(0x252)==='ngnIS')return;else{function _0xab50b5(){var _0x4c8d37=_0x1cd5d7;_0x55c4bc['rpcs'][_0x52c33a][_0x4c8d37(0x167)]['style'][_0x4c8d37(0x1fb)]=_0x4c8d37(0x277);}}}if(!_0x162eb3['director'])return;if(_0x162eb3[_0x1cd5d7(0x1c1)][_0x1cd5d7(0x3f4)]==0x0){getById(_0x1cd5d7(0x20a))['classList'][_0x1cd5d7(0x106)](_0x1cd5d7(0x2de)),getById(_0x1cd5d7(0x20a))[_0x1cd5d7(0x2ed)][_0x1cd5d7(0x106)](_0x1cd5d7(0x32b)),getById('queuebutton')[_0x1cd5d7(0x2ed)][_0x1cd5d7(0x41f)](_0x1cd5d7(0x3fe)),setTimeout(function(){var _0x376d11=_0x1cd5d7;getById(_0x376d11(0x20a))[_0x376d11(0x2ed)]['add']('float'),getById(_0x376d11(0x20a))['classList'][_0x376d11(0x41f)](_0x376d11(0x2de)),getById(_0x376d11(0x20a))[_0x376d11(0x2ed)][_0x376d11(0x41f)]('red');},0x32);return;}var _0x354a40=_0x162eb3['queueList'][_0x1cd5d7(0x359)]();getById(_0x1cd5d7(0x20a))[_0x1cd5d7(0x2ed)]['add'](_0x1cd5d7(0x2de)),getById(_0x1cd5d7(0x20a))['classList'][_0x1cd5d7(0x41f)]('float'),setTimeout(function(){var _0x54e0f7=_0x1cd5d7;getById(_0x54e0f7(0x20a))[_0x54e0f7(0x2ed)][_0x54e0f7(0x106)](_0x54e0f7(0x3fe)),getById(_0x54e0f7(0x20a))[_0x54e0f7(0x2ed)][_0x54e0f7(0x41f)]('float2');},0xc8),_0x162eb3[_0x1cd5d7(0x309)](),_0x162eb3[_0x1cd5d7(0x39b)](_0x354a40),log(_0x1cd5d7(0x483)+_0x354a40);},_0x162eb3[_0x44a3fc(0x264)]=function(){var _0x2f802c=_0x44a3fc;if(_0x162eb3[_0x2f802c(0x285)]){if(_0x2f802c(0xf1)===_0x2f802c(0x493)){function _0x1c5144(){var _0x44b831=_0x2f802c;_0x187ea1(_0x9cb730),_0x13b52d(_0x44b831(0x24b));}}else return;}clearTimeout(_0x162eb3[_0x2f802c(0x371)]);if(!_0x162eb3['ws']||_0x162eb3['ws']['readyState']!==0x1)return;_0x162eb3[_0x2f802c(0x371)]=setTimeout(function(){var _0x584b04=_0x2f802c;log(_0x584b04(0x42e));var _0x529f46={};_0x529f46[_0x584b04(0x4e0)]=_0x584b04(0x264),_0x162eb3['sendMsg'](_0x529f46);},0xbb8);},_0x162eb3[_0x44a3fc(0x39b)]=function(_0x24e6c5){var _0x9beaee=_0x44a3fc;_0x162eb3['connect']();if(_0x24e6c5[_0x9beaee(0x3f4)]>0x0){var _0x19b0b6={};_0x19b0b6[_0x9beaee(0x4e0)]=_0x9beaee(0x238),_0x19b0b6[_0x9beaee(0x34f)]=_0x24e6c5,_0x162eb3['sendMsg'](_0x19b0b6),_0x162eb3[_0x9beaee(0x3b8)][_0x24e6c5]=!![];}else log('stream\x20ID\x20is\x200\x20length');},_0x162eb3[_0x44a3fc(0x37f)]=function _0x21766c(_0x390a80){var _0x4bc49b=_0x44a3fc;_0x162eb3['connect']();var _0xcdea3c={};return _0xcdea3c['request']='joinroom',_0x162eb3[_0x4bc49b(0x1b6)]&&(_0xcdea3c[_0x4bc49b(0x2f2)]=!![]),_0x162eb3[_0x4bc49b(0x285)]&&(_0xcdea3c[_0x4bc49b(0x34f)]=_0x162eb3['streamID']),_0x162eb3[_0x4bc49b(0x376)]===![]&&(_0x162eb3[_0x4bc49b(0x376)]=!![]),_0x162eb3[_0x4bc49b(0xf2)]?_0x162eb3[_0x4bc49b(0x429)]?_0x162eb3[_0x4bc49b(0x3e7)](_0x390a80+_0x162eb3['password']+_0x162eb3[_0x4bc49b(0x14c)],0x10)[_0x4bc49b(0x57e)](function(_0x16b5db){var _0x891f43=_0x4bc49b;if('UTeNX'!=='VKwws'){if(_0x162eb3[_0x891f43(0x285)]){if(_0x891f43(0x323)!==_0x891f43(0x323)){function _0x4e6932(){_0x59f428('Answer\x20SDP\x20does\x20not\x20have\x20a\x20matching\x20session\x20ID');return;}}else _0x162eb3[_0x891f43(0x53b)]=_0x16b5db;}return _0xcdea3c[_0x891f43(0x27b)]=_0x16b5db,_0x162eb3[_0x891f43(0x15f)](_0xcdea3c),_0x162eb3[_0x891f43(0x1c3)]=_0xfc9fab(),log(_0x891f43(0x337)),_0x162eb3[_0x891f43(0x1c3)];}else{function _0x50cbd6(){var _0x8d6d1b=_0x891f43;_0x3fca81[_0x8d6d1b(0x1f4)][this[_0x8d6d1b(0x1e2)]][_0x8d6d1b(0x340)][_0x8d6d1b(0x21e)][_0x8d6d1b(0x1fb)]=_0x8d6d1b(0x277);}}}):_0x162eb3[_0x4bc49b(0x3e7)](_0x162eb3[_0x4bc49b(0xf2)]+_0x162eb3[_0x4bc49b(0x14c)],0x6)['then'](function(_0x4d7bad){var _0x2300bd=_0x4bc49b;return _0x162eb3[_0x2300bd(0x429)]=_0x4d7bad,log('hash\x20is\x20'+_0x4d7bad),log(_0x2300bd(0x26a)),_0x162eb3['joinRoom'](_0x390a80);}):(_0x162eb3[_0x4bc49b(0x285)]&&(_0x162eb3['roomenc']=_0x390a80),_0xcdea3c[_0x4bc49b(0x27b)]=_0x390a80,_0x162eb3[_0x4bc49b(0x15f)](_0xcdea3c),_0x162eb3[_0x4bc49b(0x1c3)]=_0xfc9fab(),log(_0x4bc49b(0xd0)),_0x162eb3[_0x4bc49b(0x1c3)]);},_0x162eb3['sendMsg']=function(_0x317136){var _0x4716df=_0x44a3fc;_0x162eb3[_0x4716df(0x285)]&&(_0x162eb3[_0x4716df(0x1e2)]?_0x317136[_0x4716df(0x2b9)]=_0x162eb3[_0x4716df(0x1e2)]:(_0x162eb3['UUID']=_0x162eb3[_0x4716df(0x2af)](0x14),_0x317136['from']=_0x162eb3[_0x4716df(0x1e2)]),_0x162eb3[_0x4716df(0x1b6)]&&(_0x317136[_0x4716df(0x1b6)]=!![]),!(_0x4716df(0x27b)in _0x317136)&&(_0x162eb3[_0x4716df(0x53b)]&&(_0x317136[_0x4716df(0x27b)]=_0x162eb3[_0x4716df(0x53b)])));clearTimeout(_0x162eb3[_0x4716df(0x371)]);try{if(_0x162eb3[_0x4716df(0xf2)]){if(_0x317136[_0x4716df(0x34f)]){if(_0x4716df(0x353)==='wTfor'){if(_0x162eb3[_0x4716df(0x429)]!==![]){if(typeof _0x162eb3['ws']!==_0x4716df(0x1b1)||_0x162eb3['ws'][_0x4716df(0x2bb)]!==0x1)log(_0x317136,_0x4716df(0x3fc)),_0x162eb3['msg'][_0x4716df(0x21d)](_0x317136);else{_0x317136[_0x4716df(0x34f)]=_0x317136[_0x4716df(0x34f)][_0x4716df(0x129)](0x0,0x18)+_0x162eb3[_0x4716df(0x429)][_0x4716df(0x129)](0x0,0x6);var _0x5ec857=JSON[_0x4716df(0x444)](_0x317136);if(_0x5ec857[_0x4716df(0x3f4)]>0x3a98){if(_0x4716df(0x407)!==_0x4716df(0x407)){function _0x21abb1(){return;}}else{errorlog(_0x4716df(0x559));return;}}_0x162eb3['ws']['send'](_0x5ec857);}}else return _0x162eb3['generateHash'](_0x162eb3[_0x4716df(0xf2)]+_0x162eb3[_0x4716df(0x14c)],0x6)['then'](function(_0x512e05){var _0x4d25d6=_0x4716df;_0x162eb3[_0x4d25d6(0x429)]=_0x512e05;if(typeof _0x162eb3['ws']!==_0x4d25d6(0x1b1)||_0x162eb3['ws']['readyState']!==0x1){if('GvIxe'!=='OCvbC')log(_0x317136,'could\x20not\x20be\x20sent;\x20queuing\x20it'),_0x162eb3['msg'][_0x4d25d6(0x21d)](_0x317136);else{function _0x56313b(){var _0x238523=_0x4d25d6;_0x29d3be[_0x238523(0x4bb)][_0x5cdefc]={},_0x35e1ad['keys'][_0x39b3a2][_0x238523(0x52a)]=_0x4f57db,_0x1b206b[_0x238523(0x4bb)][_0x46eb4b][_0x238523(0x13b)]=null;}}}else{_0x317136[_0x4d25d6(0x34f)]=_0x317136[_0x4d25d6(0x34f)][_0x4d25d6(0x129)](0x0,0x18)+_0x162eb3[_0x4d25d6(0x429)][_0x4d25d6(0x129)](0x0,0x6);var _0x4ee0e7=JSON[_0x4d25d6(0x444)](_0x317136);if(_0x4ee0e7[_0x4d25d6(0x3f4)]>0x3a98){errorlog(_0x4d25d6(0x559));return;}_0x162eb3['ws']['send'](_0x4ee0e7);}});}else{function _0x545db1(){var _0x30b124=_0x4716df;_0x4cb646[_0x30b124(0x512)][0x0]['active']=![];}}}else{if(_0x4716df(0x2ab)==='sAClO'){if(typeof _0x162eb3['ws']!==_0x4716df(0x1b1)||_0x162eb3['ws']['readyState']!==0x1)log(_0x317136,'could\x20not\x20be\x20sent;\x20queuing\x20it'),_0x162eb3[_0x4716df(0x360)][_0x4716df(0x21d)](_0x317136);else{var _0x5ec857=JSON[_0x4716df(0x444)](_0x317136);if(_0x5ec857[_0x4716df(0x3f4)]>0x3a98){errorlog(_0x4716df(0x559));return;}_0x162eb3['ws'][_0x4716df(0x388)](_0x5ec857);}}else{function _0x3d9419(){var _0x2b292f=_0x4716df;_0x90f258[_0x2b292f(0x1f4)][_0x3524c0][_0x2b292f(0x340)][_0x2b292f(0x253)]=_0xfbed03[_0x2b292f(0x1f4)][_0x52a22f][_0x2b292f(0x144)];}}}}else{if(typeof _0x162eb3['ws']!==_0x4716df(0x1b1)||_0x162eb3['ws'][_0x4716df(0x2bb)]!==0x1)log(_0x317136,'could\x20not\x20be\x20sent;\x20queuing\x20it'),_0x162eb3[_0x4716df(0x360)][_0x4716df(0x21d)](_0x317136);else{var _0x5ec857=JSON[_0x4716df(0x444)](_0x317136);if(_0x5ec857[_0x4716df(0x3f4)]>0x3a98){errorlog(_0x4716df(0x559));return;}_0x162eb3['ws']['send'](_0x5ec857);}}}catch(_0x44f9e0){errorlog(_0x44f9e0);}},_0x162eb3[_0x44a3fc(0x47d)]=function _0x5a374e(_0x38ec87=![]){var _0x417729=_0x44a3fc;if(_0x162eb3[_0x417729(0x46b)]===!![]){log('tainted');return;}if(_0x162eb3['ws']!==null){log('already\x20connected');return;}_0x162eb3[_0x417729(0x403)]==![]&&(_0x162eb3[_0x417729(0x403)]=_0x417729(0x23d)),_0x162eb3['ws']=new WebSocket(_0x162eb3[_0x417729(0x403)]),_0x38ec87==![]&&(_0x162eb3[_0x417729(0x351)]=setTimeout(function(){var _0x5135ac=_0x417729;pokeIframeAPI(_0x5135ac(0x526),_0x5135ac(0x351)),errorlog(_0x5135ac(0xd3)),!_0x162eb3[_0x5135ac(0x14e)]&&(!window['obsstudio']&&setTimeout(function(){var _0x42d7e1=_0x5135ac;warnUser(_0x42d7e1(0x2e1));},0x1));},0x7530)),_0x162eb3['ws'][_0x417729(0x3ef)]=function _0x1d171c(){var _0xed77cb=_0x417729;clearTimeout(_0x162eb3[_0xed77cb(0x371)]),clearInterval(_0x162eb3[_0xed77cb(0x351)]),log('connected\x20to\x20video\x20server'),checkConnection();if(_0x162eb3[_0xed77cb(0x338)]){if(_0xed77cb(0x4bf)===_0xed77cb(0x4bf)){errorlog(_0xed77cb(0x434));for(_0x2fe5c0 in _0x162eb3['rpcs']){if(_0xed77cb(0x574)===_0xed77cb(0x574))try{_0x162eb3[_0xed77cb(0x1f4)][_0x2fe5c0][_0xed77cb(0x556)]();}catch(_0x2637ba){}else{function _0x1d1055(){var _0x54e93c=_0xed77cb;_0x25da93[_0x54e93c(0x3cc)][_0x54e93c(0x419)]===![]&&(_0x29a6e8=!![]),_0x42474d[_0x54e93c(0xeb)]=_0x49a647[_0x54e93c(0x3cc)][_0x54e93c(0x419)];}}}for(_0x2fe5c0 in _0x162eb3[_0xed77cb(0x147)]){try{_0x162eb3[_0xed77cb(0x147)][_0x2fe5c0]['close']();}catch(_0x2aa02d){}}_0x162eb3[_0xed77cb(0x338)]=![];}else{function _0x23644a(){var _0x1e770d=_0xed77cb;_0x4245c9[_0x1e770d(0x147)][_0x321f89][_0x1e770d(0x383)]=!![],_0x51a8ef(function(){_0x5651b1();},0x3e8);}}}if(_0x162eb3[_0xed77cb(0x360)]!==[])try{var _0x2b2c35=_0x162eb3[_0xed77cb(0x360)][_0xed77cb(0x32a)](-0xa);_0x162eb3[_0xed77cb(0x360)]=[];for(var _0x20b377 in _0x2b2c35){log(_0xed77cb(0x235)),_0x162eb3[_0xed77cb(0x15f)](_0x2b2c35[_0x20b377]);}}catch(_0x23d4a5){errorlog(_0x23d4a5);}if(_0x38ec87==!![]){pokeIframeAPI(_0xed77cb(0x526),_0xed77cb(0x57a));_0x162eb3[_0xed77cb(0x332)]&&_0x162eb3[_0xed77cb(0x216)]();if(_0x162eb3[_0xed77cb(0x27b)]!==![]){if(_0x162eb3[_0xed77cb(0x27b)]===''&&(!_0x162eb3[_0xed77cb(0x3db)]||_0x162eb3[_0xed77cb(0x3db)]==='')){}else log(_0xed77cb(0x547)),log(_0xed77cb(0x3d6)),joinRoom(_0x162eb3[_0xed77cb(0x27b)]);}else{var _0x23fe3e=Object[_0xed77cb(0x4bb)](_0x162eb3[_0xed77cb(0x3b8)]);for(var _0x2fe5c0 in _0x23fe3e){log(_0xed77cb(0x2b7)+_0x23fe3e[_0x2fe5c0]),_0x162eb3['watchStream'](_0x23fe3e[_0x2fe5c0]);}}}else pokeIframeAPI(_0xed77cb(0x526),_0xed77cb(0x4e6));},_0x162eb3[_0x417729(0x358)]=function(_0x3a58ac,_0x57f75a=![]){var _0x217a1b=_0x417729,_0x42f0e9=[];for(var _0x246d4d in _0x162eb3[_0x217a1b(0x147)]){if(_0x57f75a&&_0x57f75a!==_0x246d4d)continue;try{if(_0x217a1b(0x510)===_0x217a1b(0x510))_0x162eb3['pcs'][_0x246d4d][_0x217a1b(0x4ae)]['send'](JSON['stringify'](_0x3a58ac)),_0x42f0e9[_0x217a1b(0x21d)](_0x246d4d);else{function _0x1edf5a(){var _0x4f297c=_0x217a1b;_0x536528[_0x4f297c(0x1f4)][_0x25c0c7[_0x4f297c(0x37c)]][_0x4f297c(0x14f)][_0x4f297c(0x53f)]&&(_0x2a040e[_0x4f297c(0x1f4)][_0x9e9bbb['directorUUID']]['stats'][_0x4f297c(0x53f)][_0x4f297c(0x1b6)]=!![]);}}}catch(_0x591750){warnlog(_0x217a1b(0x4ad));}if(_0x57f75a&&_0x57f75a===_0x246d4d){if(_0x217a1b(0x35c)===_0x217a1b(0x326)){function _0x2b5dde(){return;}}else return;}}for(var _0x246d4d in _0x162eb3[_0x217a1b(0x1f4)]){if(_0x57f75a&&_0x57f75a!==_0x246d4d)continue;if(_0x42f0e9[_0x217a1b(0x28f)](_0x246d4d))continue;try{_0x162eb3[_0x217a1b(0x1f4)][_0x246d4d][_0x217a1b(0x228)][_0x217a1b(0x388)](JSON[_0x217a1b(0x444)](_0x3a58ac));}catch(_0x2c4fa0){warnlog(_0x217a1b(0x3e5));}}},_0x162eb3['anysend']=function(_0x2189d9,_0x2a731b=![]){var _0x294997=_0x417729,_0x1041d0=![];if(_0x294997(0x1e2)in _0x2189d9)_0x1041d0=_0x162eb3[_0x294997(0x43f)](_0x2189d9,_0x2189d9['UUID']),_0x1041d0?(log(_0x2189d9),log(_0x294997(0x555))):(log(_0x294997(0x26f)),_0x162eb3['sendMsg'](_0x2189d9));else _0x2a731b?(_0x1041d0=_0x162eb3[_0x294997(0x43f)](_0x2189d9),_0x1041d0?(log(_0x2189d9),log('successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS\x20to\x20all\x20RTC\x20Peers')):(log('sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message;\x20RTC\x20peers\x20only'),_0x162eb3['sendMsg'](_0x2189d9))):(_0x162eb3[_0x294997(0x15f)](_0x2189d9),log('sending\x20message\x20to\x20server'));},_0x162eb3['anyrequest']=function(_0x492208,_0x1f3580=![]){var _0x3864d1=_0x417729,_0x216b0a=![];if(_0x3864d1(0x1e2)in _0x492208)_0x216b0a=_0x162eb3[_0x3864d1(0x196)](_0x492208,_0x492208[_0x3864d1(0x1e2)]),_0x216b0a?log('successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS'):(log(_0x3864d1(0x26f)),_0x162eb3['sendMsg'](_0x492208));else _0x1f3580?(_0x216b0a=_0x162eb3['sendRequest'](_0x492208),_0x216b0a?log(_0x3864d1(0x4b4)):(log(_0x3864d1(0x4be)),_0x162eb3[_0x3864d1(0x15f)](_0x492208))):(_0x162eb3[_0x3864d1(0x15f)](_0x492208),log('sending\x20message\x20to\x20server'));},_0x162eb3[_0x417729(0x414)]=function(){var _0x234c3a=_0x417729;if(_0x162eb3[_0x234c3a(0x381)]===![]){if('GQdVS'===_0x234c3a(0x34b)){var _0x99f276={},_0x1d4cf8=![];_0x162eb3[_0x234c3a(0x3cc)][_0x234c3a(0x419)]!==null&&(_0x162eb3[_0x234c3a(0x3cc)][_0x234c3a(0x419)]===![]&&(_0x1d4cf8=!![]),_0x99f276['obsVisibility']=_0x162eb3[_0x234c3a(0x3cc)][_0x234c3a(0x419)]);_0x162eb3[_0x234c3a(0x3cc)][_0x234c3a(0x422)]!==null&&(_0x99f276['obsSourceActive']=_0x162eb3[_0x234c3a(0x3cc)][_0x234c3a(0x422)]);_0x162eb3[_0x234c3a(0x3cc)][_0x234c3a(0x38a)]!==null&&(_0x99f276['obsRecording']=_0x162eb3[_0x234c3a(0x3cc)][_0x234c3a(0x38a)]);_0x162eb3[_0x234c3a(0x3cc)]['streaming']!==null&&(_0x99f276[_0x234c3a(0x223)]=_0x162eb3['obsState']['streaming']);for(var _0x50f6c6 in _0x162eb3[_0x234c3a(0x1f4)]){if(_0x162eb3[_0x234c3a(0x1a1)]!==![]){var _0x17d3c1=parseInt(_0x162eb3['rpcs'][_0x50f6c6][_0x234c3a(0x2e6)]);_0x1d4cf8&&((_0x17d3c1>_0x162eb3[_0x234c3a(0x1a1)]||_0x17d3c1<0x0)&&(_0x17d3c1=_0x162eb3[_0x234c3a(0x1a1)])),_0x162eb3['rpcs'][_0x50f6c6][_0x234c3a(0x40b)]!==_0x17d3c1?(_0x99f276[_0x234c3a(0x22c)]=_0x17d3c1,warnlog(_0x234c3a(0x437)),warnlog(_0x99f276),_0x162eb3[_0x234c3a(0x196)](_0x99f276,_0x50f6c6)?_0x162eb3[_0x234c3a(0x1f4)][_0x50f6c6]['bandwidth']=_0x17d3c1:errorlog('Unable\x20to\x20set\x20update\x20OBS\x20Visibility')):(warnlog(_0x234c3a(0x437)),warnlog(_0x99f276),_0x162eb3['sendRequest'](_0x99f276,_0x50f6c6));}else warnlog('Message\x20to\x20be\x20sent:\x20'),warnlog(_0x99f276),_0x162eb3[_0x234c3a(0x196)](_0x99f276,_0x50f6c6);}}else{function _0x39f348(){var _0x5ce54a=_0x234c3a;_0x139e9b[_0x5ce54a(0x376)]=!![];}}}},_0x162eb3['sceneSync']=function(_0x4c5c9a){var _0x44b076=_0x417729;if(_0x44b076(0x3a8)!==_0x44b076(0x3a8)){function _0x4fbbe0(){var _0x113ab0=_0x44b076;try{_0x36a22d(_0x5c0ee9),_0x45876c['setResolution'](_0x30b26d[_0x113ab0(0x1e2)],_0xc65aaf[_0x113ab0(0x322)]['w'],_0x22d5a4['requestResolution']['h']);}catch(_0x231e67){_0x18e71c(_0x231e67);}}}else{if(!_0x162eb3['rpcs'][_0x4c5c9a]['videoElement'])return;var _0x889057={};_0x889057[_0x44b076(0x199)]=_0x162eb3[_0x44b076(0x1f4)][_0x4c5c9a][_0x44b076(0x340)]['style'][_0x44b076(0x1fb)]!=_0x44b076(0x277),_0x889057[_0x44b076(0x342)]=_0x162eb3[_0x44b076(0x1f4)][_0x4c5c9a]['videoElement'][_0x44b076(0x253)];if(_0x162eb3[_0x44b076(0x1a1)]!==![]){var _0x2eb34d=parseInt(_0x162eb3[_0x44b076(0x1f4)][_0x4c5c9a][_0x44b076(0x2e6)]);_0x889057[_0x44b076(0x199)]===![]&&((_0x2eb34d>_0x162eb3[_0x44b076(0x1a1)]||_0x2eb34d<0x0)&&(_0x2eb34d=_0x162eb3[_0x44b076(0x1a1)])),_0x162eb3[_0x44b076(0x1f4)][_0x4c5c9a]['bandwidth']!==_0x2eb34d?(_0x889057[_0x44b076(0x22c)]=_0x2eb34d,_0x162eb3[_0x44b076(0x196)](_0x889057,_0x4c5c9a)?_0x162eb3[_0x44b076(0x1f4)][_0x4c5c9a][_0x44b076(0x40b)]=_0x2eb34d:errorlog(_0x44b076(0x126))):_0x162eb3['sendRequest'](_0x889057,_0x4c5c9a);}else _0x162eb3[_0x44b076(0x196)](_0x889057,_0x4c5c9a);}},_0x162eb3[_0x417729(0x20b)]=function(_0x4cbeee){var _0x25ca02=_0x417729;if(_0x25ca02(0x328)in _0x4cbeee){if(_0x25ca02(0x324)in _0x4cbeee){if(_0x25ca02(0x145)in _0x4cbeee){if(_0x162eb3[_0x25ca02(0x145)]!==![]){var _0x264052=![];for(var _0x4b54d3 in _0x162eb3[_0x25ca02(0x1f4)]){if(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x34f)]===_0x4cbeee[_0x25ca02(0x324)]){if(_0x25ca02(0x276)in _0x4cbeee){if(_0x4cbeee[_0x25ca02(0x328)]==_0x25ca02(0x2c6)){if(_0x4cbeee[_0x25ca02(0x276)]==0x0)log(_0x25ca02(0x1f6)),_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]&&(_0x162eb3['rpcs'][_0x4b54d3]['videoElement'][_0x25ca02(0x253)]=!![],_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x144)]=!![]);else{log(_0x25ca02(0x3c9));if(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement']){if(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)]['display']==_0x25ca02(0x277)){if(_0x25ca02(0x16c)===_0x25ca02(0x16c))_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x144)]=![],_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x253)]=!![];else{function _0x575f50(){var _0x37a5b8=_0x25ca02;'ip'in _0x3bfd1b&&(_0x4ae3cc[_0x37a5b8(0x1f4)][_0x1bf725][_0x37a5b8(0x14f)][_0x37a5b8(0x446)][_0x37a5b8(0x21b)]=_0x21d48['ip']),_0x38858b['rpcs'][_0x4ce964][_0x37a5b8(0x14f)][_0x37a5b8(0x446)][_0x37a5b8(0x552)]=_0x174019['relayProtocol'];}}}else _0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x144)]=![],_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x253)]=![];}}_0x162eb3[_0x25ca02(0x411)](_0x4b54d3);}else{if(_0x4cbeee[_0x25ca02(0x328)]==_0x25ca02(0x1fb)){if(_0x162eb3[_0x25ca02(0x3db)])return;;if(_0x162eb3[_0x25ca02(0x145)]===_0x4cbeee['scene']){if(_0x162eb3[_0x25ca02(0x35e)]==0x2){if('rPjKz'===_0x25ca02(0x13d)){function _0x1bbceb(){var _0x58a485=_0x25ca02;_0x3c1c58(_0x4f579d,_0x294c5e[_0x58a485(0x305)]);}}else{if(_0x4cbeee[_0x25ca02(0x276)]==0x0){if(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement']){if(_0x25ca02(0x57f)==='xbbMg')_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x253)]=!![],_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)]['style'][_0x25ca02(0x1fb)]&&_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]!==_0x25ca02(0x277)&&(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement'][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]=_0x25ca02(0x277),_0x264052=!![]);else{function _0xc50e33(){var _0x156851=_0x25ca02,_0x3e13ca=new _0x432120(_0x5cca70),_0x391f2e='';for(var _0x65083f=0x0;_0x65083f<_0x3e13ca[_0x156851(0xf9)];_0x65083f++){_0x391f2e+=_0x1de68c[_0x156851(0x3f3)](_0x3e13ca[_0x65083f]);}return _0x391f2e;}}}}else{if(_0x25ca02(0x4fe)===_0x25ca02(0x137)){function _0x4c18bc(){var _0x1ba9a7=_0x25ca02;_0x56508e['getElementById'](_0x1ba9a7(0x22e)+this[_0x1ba9a7(0x1e2)])&&_0x14bf8a(_0x1ba9a7(0x22e)+this['UUID'])[_0x1ba9a7(0x23c)][_0x1ba9a7(0x45f)](_0x4c26d8(_0x1ba9a7(0x22e)+this[_0x1ba9a7(0x1e2)]));}}else{for(var _0x294b66 in _0x162eb3[_0x25ca02(0x1f4)]){if(_0x294b66!==_0x4b54d3){if(_0x25ca02(0xd6)!==_0x25ca02(0xd6)){function _0x46a32b(){var _0x4c5da3=_0x25ca02;_0x36a2f9[_0x4c5da3(0x21d)](_0x5c132b);}}else _0x162eb3[_0x25ca02(0x1f4)][_0x294b66]['videoElement']&&(_0x162eb3[_0x25ca02(0x1f4)][_0x294b66][_0x25ca02(0x340)]['muted']=!![],_0x162eb3[_0x25ca02(0x1f4)][_0x294b66][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]&&_0x162eb3[_0x25ca02(0x1f4)][_0x294b66][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]!==_0x25ca02(0x277)&&(_0x162eb3['rpcs'][_0x294b66][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]=_0x25ca02(0x277),_0x264052=!![]));}}_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]&&(_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)]['style'][_0x25ca02(0x1fb)]&&_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]!=='block'&&(_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]=_0x25ca02(0x545),_0x264052=!![]),_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x144)]===null?_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement']['muted']=![]:_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x253)]=_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x144)],_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x2aa)]&&clearInterval(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x2aa)]),_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x1c7)]=![],_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]['controlTimer']=setTimeout(showControlBar[_0x25ca02(0x168)](null,_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]),0xbb8));}}}}else{if(_0x162eb3[_0x25ca02(0x35e)]==0x1){if(_0x4cbeee[_0x25ca02(0x276)]==0x0)_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]&&(_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]&&_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]!==_0x25ca02(0x277)&&(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]='none',_0x264052=!![]));else{for(var _0x294b66 in _0x162eb3[_0x25ca02(0x1f4)]){_0x294b66!==_0x4b54d3&&(_0x162eb3['rpcs'][_0x294b66][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]&&_0x162eb3['rpcs'][_0x294b66][_0x25ca02(0x340)]['style'][_0x25ca02(0x1fb)]!==_0x25ca02(0x277)&&(_0x162eb3[_0x25ca02(0x1f4)][_0x294b66][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]=_0x25ca02(0x277),_0x264052=!![]));}_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]&&(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]&&_0x162eb3['rpcs'][_0x4b54d3]['videoElement'][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]!==_0x25ca02(0x545)&&(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]='block',_0x264052=!![]),_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x2aa)]&&clearInterval(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x2aa)]),_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement'][_0x25ca02(0x1c7)]=![],_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)]['controlTimer']=setTimeout(showControlBar[_0x25ca02(0x168)](null,_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)]),0xbb8));}}else{if(_0x4cbeee[_0x25ca02(0x276)]==0x0){if('bbnXU'===_0x25ca02(0x32e)){function _0x15626e(){var _0x2737f8=_0x25ca02,_0x4af0b1=_0x380694[_0x2737f8(0x444)](_0x58f737);if(_0x4af0b1[_0x2737f8(0x3f4)]>0x3a98){_0x314015(_0x2737f8(0x559));return;}_0x3f5675['ws'][_0x2737f8(0x388)](_0x4af0b1);}}else{if(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]){if(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]&&_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]!==_0x25ca02(0x277)){if(_0x25ca02(0x44c)!==_0x25ca02(0x313))_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement'][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]=_0x25ca02(0x277),_0x264052=!![];else{function _0x27156c(){var _0x4e2368=_0x25ca02;_0x2bc082[_0x4e2368(0x4e0)]='transferred',_0x42ac92[_0x4e2368(0x53b)]=_0x4efb86[_0x4e2368(0x27b)];var _0x4ca7fb={};_0x4ca7fb[_0x4e2368(0x4e0)]=_0x4e2368(0x576),_0x4ca7fb[_0x4e2368(0x27b)]=_0x51c537[_0x4e2368(0x53b)],_0x4ca7fb['streamID']=_0x180b46[_0x4e2368(0x34f)],_0x445097[_0x4e2368(0x15f)](_0x4ca7fb);}}}_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x253)]=!![];}}}else _0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]&&(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement'][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]&&_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]!=='block'&&(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x21e)][_0x25ca02(0x1fb)]=_0x25ca02(0x545),_0x264052=!![]),_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x144)]===null?_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x253)]=![]:_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x253)]=_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x144)],_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement'][_0x25ca02(0x2aa)]&&clearInterval(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x2aa)]),_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x1c7)]=![],_0x162eb3['rpcs'][_0x4b54d3][_0x25ca02(0x340)]['controlTimer']=setTimeout(showControlBar[_0x25ca02(0x168)](null,_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3]['videoElement']),0xbb8));}}}_0x162eb3[_0x25ca02(0x411)](_0x4b54d3);}else _0x4cbeee['action']=='volume'&&(log(parseInt(_0x4cbeee[_0x25ca02(0x276)])/0x64),_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)]&&(_0x162eb3[_0x25ca02(0x1f4)][_0x4b54d3][_0x25ca02(0x340)][_0x25ca02(0x280)]=parseInt(_0x4cbeee[_0x25ca02(0x276)])/0x64,log(_0x25ca02(0x2cb))));}}}}_0x264052&&updateMixer();}}else{if(_0x4cbeee[_0x25ca02(0x328)]==_0x25ca02(0x3c8)){}else{if(_0x4cbeee[_0x25ca02(0x328)]==_0x25ca02(0x498)){}}}}}},_0x162eb3['ws'][_0x417729(0x1f2)]=function(_0x30bc55){var _0x1b8812=_0x417729;clearTimeout(_0x162eb3[_0x1b8812(0x371)]);var _0xcf8f5b=JSON[_0x1b8812(0x4aa)](_0x30bc55[_0x1b8812(0x2cd)]);_0x1b8812(0x34f)in _0xcf8f5b&&(_0xcf8f5b[_0x1b8812(0x34f)]=_0x162eb3['desaltStreamID'](_0xcf8f5b[_0x1b8812(0x34f)]));if(_0x162eb3[_0x1b8812(0x285)]){if(_0x1b8812(0x49c)!==_0x1b8812(0x205)){if(_0x1b8812(0x1e2)in _0xcf8f5b){if(_0x162eb3[_0x1b8812(0x1e2)]){if(_0xcf8f5b[_0x1b8812(0x1e2)]!==_0x162eb3[_0x1b8812(0x1e2)])return;}else return;delete _0xcf8f5b[_0x1b8812(0x1e2)];}if('roomid'in _0xcf8f5b){if(!_0x162eb3[_0x1b8812(0x53b)])return;if('request'in _0xcf8f5b){if(_0xcf8f5b[_0x1b8812(0x4e0)]===_0x1b8812(0x3c8)){if('roomid'in _0xcf8f5b){if(_0x1b8812(0x37a)==='nMBlY'){if(_0x1b8812(0x324)in _0xcf8f5b){if(_0xcf8f5b['target']==_0x162eb3[_0x1b8812(0x1e2)]){_0xcf8f5b[_0x1b8812(0x4e0)]=_0x1b8812(0x338),_0x162eb3[_0x1b8812(0x53b)]=_0xcf8f5b[_0x1b8812(0x27b)];var _0x257e1b={};_0x257e1b[_0x1b8812(0x4e0)]='joinroom',_0x257e1b[_0x1b8812(0x27b)]=_0x162eb3[_0x1b8812(0x53b)],_0x257e1b[_0x1b8812(0x34f)]=_0x162eb3[_0x1b8812(0x34f)],_0x162eb3[_0x1b8812(0x15f)](_0x257e1b);}else return;}else return;}else{function _0x31e83d(){var _0x305e48=_0x1b8812;return _0x1a9401[_0x305e48(0x285)]&&(_0x57847d[_0x305e48(0x53b)]=_0x1e8204),_0x9477af['roomid']=_0x3aa49e,_0x436ddb[_0x305e48(0x15f)](_0x309412),_0x33ca6f[_0x305e48(0x1c3)]=_0x437b89(),_0x222fd1('deferring\x20with\x20a\x20promise'),_0x491cdc['listPromise'];}}}else return;}else{if(_0xcf8f5b[_0x1b8812(0x27b)]!==_0x162eb3[_0x1b8812(0x53b)])return;}}else{if(_0xcf8f5b[_0x1b8812(0x27b)]!==_0x162eb3[_0x1b8812(0x53b)])return;}delete _0xcf8f5b[_0x1b8812(0x27b)];}'director'in _0xcf8f5b&&(_0xcf8f5b[_0x1b8812(0x2b9)]&&(_0x162eb3[_0x1b8812(0x37c)]=_0xcf8f5b[_0x1b8812(0x2b9)]),delete _0xcf8f5b[_0x1b8812(0x1b6)]);_0x1b8812(0x2b9)in _0xcf8f5b&&(_0xcf8f5b[_0x1b8812(0x1e2)]=_0xcf8f5b['from'],delete _0xcf8f5b[_0x1b8812(0x2b9)]);if(_0x1b8812(0x4e0)in _0xcf8f5b){if(_0xcf8f5b['request']===_0x1b8812(0x238)){if(_0x1b8812(0x34f)in _0xcf8f5b){if(_0xcf8f5b[_0x1b8812(0x34f)]===_0x162eb3['streamID'])_0xcf8f5b[_0x1b8812(0x4e0)]=_0x1b8812(0x179);else return;}}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]===_0x1b8812(0x102)){if(_0x162eb3[_0x1b8812(0x1ca)]){if(_0x162eb3['view_set'][_0x1b8812(0x28f)](_0xcf8f5b['streamID'])){play(_0xcf8f5b[_0x1b8812(0x34f)]);return;}else return;}else{if(_0x162eb3['view']){if(_0x162eb3[_0x1b8812(0x3db)]!==_0xcf8f5b[_0x1b8812(0x34f)])return;else{play(_0xcf8f5b[_0x1b8812(0x34f)]);return;}}}}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]===_0x1b8812(0x576)){if(_0x1b8812(0x34f)in _0xcf8f5b){if(_0x162eb3['view_set']){if(_0x162eb3[_0x1b8812(0x1ca)][_0x1b8812(0x28f)](_0xcf8f5b[_0x1b8812(0x34f)]))play(_0xcf8f5b[_0x1b8812(0x34f)]);else{}}else{if(_0x162eb3[_0x1b8812(0x3db)]){if(_0x162eb3[_0x1b8812(0x3db)]!==_0xcf8f5b['streamID']){}else play(_0xcf8f5b[_0x1b8812(0x34f)]);}else play(_0xcf8f5b[_0x1b8812(0x34f)]);}}_0xcf8f5b[_0x1b8812(0x4e0)]=_0x1b8812(0x179);}}}}}else{function _0xc8e002(){var _0x5c437d=_0x1b8812;_0x254181[_0x5c437d(0x512)][0x0][_0x5c437d(0x2da)]=0x1;}}}if(_0xcf8f5b[_0x1b8812(0x4e0)]){if(_0xcf8f5b['request']==_0x1b8812(0x179)){if(_0x162eb3[_0x1b8812(0x46f)]){if(_0x162eb3[_0x1b8812(0x37c)]===_0xcf8f5b[_0x1b8812(0x1e2)])_0x162eb3[_0x1b8812(0x179)](_0xcf8f5b[_0x1b8812(0x1e2)]);else _0x162eb3[_0x1b8812(0x1b6)]&&(_0xcf8f5b[_0x1b8812(0x1e2)]in _0x162eb3[_0x1b8812(0x1f4)]&&_0x162eb3[_0x1b8812(0x179)](_0xcf8f5b['UUID']));}else _0x162eb3[_0x1b8812(0x179)](_0xcf8f5b[_0x1b8812(0x1e2)]);}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]==_0x1b8812(0x579)){log(_0xcf8f5b[_0x1b8812(0x57b)]);if(_0x1b8812(0x1b6)in _0xcf8f5b)_0x162eb3[_0x1b8812(0x37c)]=_0xcf8f5b[_0x1b8812(0x1b6)],_0x162eb3[_0x1b8812(0x37c)]in _0x162eb3[_0x1b8812(0x147)]&&(_0x162eb3[_0x1b8812(0x147)][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)][_0x1b8812(0x53f)]&&(_0x162eb3[_0x1b8812(0x147)][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)][_0x1b8812(0x53f)][_0x1b8812(0x1b6)]=!![])),_0x162eb3[_0x1b8812(0x37c)]in _0x162eb3[_0x1b8812(0x1f4)]&&(_0x162eb3[_0x1b8812(0x1f4)][_0x162eb3['directorUUID']][_0x1b8812(0x14f)][_0x1b8812(0x53f)]&&(_0x162eb3[_0x1b8812(0x1f4)][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)][_0x1b8812(0x53f)][_0x1b8812(0x1b6)]=!![]));else{if(_0x1b8812(0x26e)===_0x1b8812(0x26e))_0x162eb3['directorUUID']=![];else{function _0x2810e6(){var _0x1ae8e7=_0x1b8812;return _0x578d10[_0x1ae8e7(0x2ac)]&&_0x6df833[_0x1ae8e7(0x2ac)]['kind']==_0x1ae8e7(0x25f);}}}_0x1b8812(0x2f2)in _0xcf8f5b&&(_0xcf8f5b[_0x1b8812(0x2f2)]==![]&&(!_0x162eb3['cleanOutput']&&(setTimeout(function(){var _0x466b02=_0x1b8812;warnUser(_0x466b02(0x2bc));},0x1),getById(_0x1b8812(0x3a1))[_0x1b8812(0x564)]=_0x1b8812(0x499)))),_0x162eb3[_0x1b8812(0x1c3)]['resolve'](_0xcf8f5b[_0x1b8812(0x57b)]);}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]==_0x1b8812(0x338)){_0x162eb3[_0x1b8812(0x1c1)]=[],_0x162eb3[_0x1b8812(0x338)]=!![],log(_0x1b8812(0x581));if(!_0x162eb3[_0x1b8812(0x1b6)]){if(_0x1b8812(0x47e)!==_0x1b8812(0x453))_0x162eb3[_0x1b8812(0x46f)]=![];else{function _0x21606f(){return;}}}log(_0xcf8f5b['list']);if(_0x1b8812(0x1b6)in _0xcf8f5b){_0x162eb3['directorUUID']=_0xcf8f5b[_0x1b8812(0x1b6)];if(_0x162eb3['directorUUID']in _0x162eb3[_0x1b8812(0x147)]){if(_0x1b8812(0xdd)===_0x1b8812(0xdd))_0x162eb3[_0x1b8812(0x147)][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)]['info']&&(_0x162eb3[_0x1b8812(0x147)][_0x162eb3[_0x1b8812(0x37c)]]['stats'][_0x1b8812(0x53f)][_0x1b8812(0x1b6)]=!![]);else{function _0xdeb42e(){return;}}}_0x162eb3[_0x1b8812(0x37c)]in _0x162eb3['rpcs']&&(_0x162eb3['rpcs'][_0x162eb3[_0x1b8812(0x37c)]]['stats'][_0x1b8812(0x53f)]&&(_0x162eb3['rpcs'][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)][_0x1b8812(0x53f)][_0x1b8812(0x1b6)]=!![]));}else _0x162eb3[_0x1b8812(0x37c)]=![];for(_0x2500b8 in _0x162eb3['rpcs']){try{_0x162eb3['rpcs'][_0x2500b8]['close'](),delete _0x162eb3['rpcs'][_0x2500b8];}catch(_0xaa7a50){}}for(_0x2500b8 in _0x162eb3[_0x1b8812(0x147)]){try{_0x162eb3[_0x1b8812(0x147)][_0x2500b8][_0x1b8812(0x556)](),delete _0x162eb3[_0x1b8812(0x147)][_0x2500b8],applySceneState();}catch(_0x4743c6){}}getChatMessage(_0x1b8812(0xd8),label=![],director=![],overlay=!![]),getById(_0x1b8812(0x2d6))[_0x1b8812(0x564)]=_0x1b8812(0x31b);_0x162eb3[_0x1b8812(0x2fa)]?document[_0x1b8812(0xcf)]=_0x162eb3[_0x1b8812(0x2fa)]+_0x1b8812(0x2c2):document[_0x1b8812(0xcf)]=_0x1b8812(0x42c);_0x162eb3[_0x1b8812(0x262)]=_0x162eb3['totalRoomBitrate_default'],updateMixer(),updateUserList(),log('Members\x20in\x20Room'),log(_0xcf8f5b[_0x1b8812(0x57b)]);for(var _0x2500b8 in _0xcf8f5b['list']){if(_0x1b8812(0x1e2)in _0xcf8f5b[_0x1b8812(0x57b)][_0x2500b8]){if(_0x1b8812(0x34f)in _0xcf8f5b[_0x1b8812(0x57b)][_0x2500b8]){if(_0xcf8f5b['list'][_0x2500b8]['UUID']in _0x162eb3[_0x1b8812(0x1f4)])log('RTC\x20already\x20connected');else{var _0x5b36a1=_0x162eb3[_0x1b8812(0x20e)](_0xcf8f5b[_0x1b8812(0x57b)][_0x2500b8][_0x1b8812(0x34f)]);log(_0x1b8812(0x4d0)+_0x5b36a1);if(_0x162eb3[_0x1b8812(0x46f)]){if(_0x162eb3[_0x1b8812(0x37c)]===_0xcf8f5b[_0x1b8812(0x57b)][_0x2500b8]['UUID']){if(_0x1b8812(0x239)===_0x1b8812(0x4a0)){function _0x4b9cc8(){var _0x52f2d6=_0x1b8812;_0x27e5e1[_0x52f2d6(0xcf)]=_0x27a6f4[_0x52f2d6(0xf8)],_0x1ba8e5();}}else play(_0x5b36a1);}else _0x162eb3[_0x1b8812(0x1c1)][_0x1b8812(0x3f4)]<0x1388&&(!_0x162eb3['queueList']['includes'](_0x5b36a1)&&_0x162eb3[_0x1b8812(0x1c1)][_0x1b8812(0x21d)](_0x5b36a1));}else play(_0x5b36a1);}}}}_0x162eb3[_0x1b8812(0x309)]();}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]==_0x1b8812(0x24e)){if(_0x1b8812(0x570)!==_0x1b8812(0x274))log(_0xcf8f5b),_0x1b8812(0x1b6)in _0xcf8f5b?(_0x162eb3[_0x1b8812(0x37c)]=_0xcf8f5b[_0x1b8812(0x1b6)],_0x162eb3[_0x1b8812(0x37c)]in _0x162eb3['pcs']&&(_0x162eb3['pcs'][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)][_0x1b8812(0x53f)]&&(_0x162eb3[_0x1b8812(0x147)][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)][_0x1b8812(0x53f)][_0x1b8812(0x1b6)]=!![])),_0x162eb3[_0x1b8812(0x37c)]in _0x162eb3[_0x1b8812(0x1f4)]&&(_0x162eb3[_0x1b8812(0x1f4)][_0x162eb3[_0x1b8812(0x37c)]]['stats'][_0x1b8812(0x53f)]&&(_0x162eb3[_0x1b8812(0x1f4)][_0x162eb3[_0x1b8812(0x37c)]]['stats'][_0x1b8812(0x53f)][_0x1b8812(0x1b6)]=!![]))):(_0x162eb3[_0x1b8812(0x37c)]=![],errorlog(_0x1b8812(0x2ea))),updateUserList();else{function _0xc02cac(){var _0x435b33=_0x1b8812;_0x2cca08[_0x435b33(0x1f4)][_0x547888][_0x435b33(0x14f)]['info']['muted']=_0x411416[_0x435b33(0x1f4)][_0x3624a8][_0x435b33(0x37b)];}}}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]==_0x1b8812(0x4b1)){log(_0x1b8812(0x1f8)),log(_0xcf8f5b);try{_0x1b8812(0x1b6)in _0xcf8f5b&&(_0xcf8f5b[_0x1b8812(0x1b6)]==!![]&&_0x162eb3[_0x1b8812(0x20b)](_0xcf8f5b));}catch(_0x3cee1a){errorlog(_0x3cee1a);}}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]==_0x1b8812(0x563)){if(_0x1b8812(0x541)===_0x1b8812(0x23f)){function _0x4d0526(){_0x14fbec['video']=!![];}}else{_0xcf8f5b[_0x1b8812(0x1b6)]&&(_0x162eb3[_0x1b8812(0x37c)]=_0xcf8f5b['UUID'],_0x162eb3[_0x1b8812(0x37c)]in _0x162eb3[_0x1b8812(0x147)]&&(_0x162eb3[_0x1b8812(0x147)][_0x162eb3[_0x1b8812(0x37c)]]['stats'][_0x1b8812(0x53f)]&&(_0x162eb3['pcs'][_0x162eb3[_0x1b8812(0x37c)]]['stats']['info'][_0x1b8812(0x1b6)]=!![])),_0x162eb3[_0x1b8812(0x37c)]in _0x162eb3['rpcs']&&(_0x162eb3[_0x1b8812(0x1f4)][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)][_0x1b8812(0x53f)]&&(_0x162eb3[_0x1b8812(0x1f4)][_0x162eb3[_0x1b8812(0x37c)]][_0x1b8812(0x14f)][_0x1b8812(0x53f)]['director']=!![])),updateUserList());if('streamID'in _0xcf8f5b){log(_0x1b8812(0x3f8));if(_0x162eb3['queue']){if(_0x162eb3[_0x1b8812(0x37c)]===_0xcf8f5b['UUID'])play(_0x5b36a1);else _0x162eb3[_0x1b8812(0x1c1)][_0x1b8812(0x3f4)]<0x1388&&(!_0x162eb3[_0x1b8812(0x1c1)][_0x1b8812(0x28f)](_0xcf8f5b[_0x1b8812(0x34f)])&&(_0x162eb3[_0x1b8812(0x1c1)][_0x1b8812(0x21d)](_0xcf8f5b[_0x1b8812(0x34f)]),_0x162eb3[_0x1b8812(0x309)]()));}else play(_0xcf8f5b[_0x1b8812(0x34f)]);}else log(_0x1b8812(0x2d2));}}else{if(_0xcf8f5b['request']==_0x1b8812(0x441)){log(_0x1b8812(0x100)),log(_0xcf8f5b);if(_0x162eb3[_0x1b8812(0x46f)]){if(_0x162eb3[_0x1b8812(0x37c)]===_0xcf8f5b[_0x1b8812(0x1e2)])play(_0x5b36a1);else _0x162eb3[_0x1b8812(0x1c1)][_0x1b8812(0x3f4)]<0x1388&&(!_0x162eb3[_0x1b8812(0x1c1)][_0x1b8812(0x28f)](_0xcf8f5b[_0x1b8812(0x34f)])&&(_0x162eb3['queueList'][_0x1b8812(0x21d)](_0xcf8f5b[_0x1b8812(0x34f)]),_0x162eb3[_0x1b8812(0x309)]()));}else play(_0xcf8f5b[_0x1b8812(0x34f)]);}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]=='alert'){errorlog(_0xcf8f5b);if(_0x162eb3[_0x1b8812(0x145)]===![]){if(_0x1b8812(0x47c)in _0xcf8f5b){if(_0xcf8f5b[_0x1b8812(0x47c)]===_0x1b8812(0x2c7))_0x162eb3[_0x1b8812(0x32c)]<0x2?(_0x162eb3['seedAttempts']=parseInt(_0x162eb3[_0x1b8812(0x32c)])+0x1,setTimeout(function(){var _0x79649b=_0x1b8812;_0x162eb3[_0x79649b(0x216)]();},0x1388)):(hangup(),!_0x162eb3[_0x1b8812(0x14e)]&&setTimeout(function(){var _0x261ad7=_0x1b8812;warnUser(_0x261ad7(0x124));},0x1));else _0xcf8f5b[_0x1b8812(0x47c)]===_0x1b8812(0xfd)?!_0x162eb3['cleanOutput']&&(setTimeout(function(){var _0x4d7dad=_0x1b8812;if(_0x4d7dad(0x382)==='pxCrg'){function _0x570b60(){var _0x34c703=_0x4d7dad,_0x482afc={};_0x482afc[_0x34c703(0x186)]=_0x34c703(0xe1),_0x474ad8['sendMessage'](_0x482afc,_0x446099);}}else warnUser(_0x4d7dad(0x2bc));},0x1),getById(_0x1b8812(0x3a1))[_0x1b8812(0x564)]=_0x1b8812(0x499)):!_0x162eb3[_0x1b8812(0x14e)]&&setTimeout(function(){warnUser(_0xcf8f5b['message']);},0x1);}}}else{if(_0xcf8f5b[_0x1b8812(0x4e0)]==_0x1b8812(0x494)){if(_0x1b8812(0x3ab)!==_0x1b8812(0x3ab)){function _0x4f5a39(){var _0x5b875a=_0x1b8812;if(_0x3e0616[_0x5b875a(0x147)][_0x19752e][_0x5b875a(0x46d)]===![])return;_0x1e66c3=_0x191955['pcs'][_0x587053]['savedBitrate'];}}else _0x1b8812(0x47c)in _0xcf8f5b&&warnlog(_0xcf8f5b['message']);}else log(_0xcf8f5b);}}}}}}}}}else{if(_0xcf8f5b[_0x1b8812(0x16b)])_0x1b8812(0x34f)in _0xcf8f5b&&(_0xcf8f5b[_0x1b8812(0x34f)]in _0x162eb3[_0x1b8812(0x4f2)]&&(clearTimeout(_0x162eb3[_0x1b8812(0x4f2)][_0xcf8f5b[_0x1b8812(0x34f)]]),delete _0x162eb3[_0x1b8812(0x4f2)][_0xcf8f5b[_0x1b8812(0x34f)]])),_0x162eb3['processDescription'](_0xcf8f5b);else{if(_0xcf8f5b[_0x1b8812(0x17d)])log(_0x1b8812(0x38b)),_0x162eb3[_0x1b8812(0x3d9)](_0xcf8f5b);else{if(_0xcf8f5b[_0x1b8812(0x134)])log(_0x1b8812(0x56a)),_0x162eb3[_0x1b8812(0x142)](_0xcf8f5b);else{if(_0xcf8f5b[_0x1b8812(0x4e0)]==_0x1b8812(0x175)){warnlog(_0x1b8812(0x29c));if(_0xcf8f5b[_0x1b8812(0x1e2)]in _0x162eb3[_0x1b8812(0x147)]){if(_0x1b8812(0x304)!==_0x1b8812(0x361))warnlog('problem'),_0x162eb3[_0x1b8812(0x147)][_0xcf8f5b[_0x1b8812(0x1e2)]][_0x1b8812(0x556)](),delete _0x162eb3[_0x1b8812(0x147)][_0xcf8f5b[_0x1b8812(0x1e2)]],_0x162eb3['applySoloChat'](),applySceneState();else{function _0x242463(){var _0x24a542=_0x1b8812;_0x1e525c[_0x24a542(0x1b6)]=!![];}}}_0xcf8f5b[_0x1b8812(0x1e2)]in _0x162eb3[_0x1b8812(0x1f4)]&&(warnlog(_0x1b8812(0x459)),_0x162eb3[_0x1b8812(0x1f4)][_0xcf8f5b[_0x1b8812(0x1e2)]][_0x1b8812(0x556)](),delete _0x162eb3[_0x1b8812(0x1f4)][_0xcf8f5b[_0x1b8812(0x1e2)]]);}else log(_0x1b8812(0x525),_0xcf8f5b);}}}}},_0x162eb3['ws'][_0x417729(0x45c)]=function(_0x1ad044){var _0x70787=_0x417729;clearTimeout(_0x162eb3[_0x70787(0x371)]),pokeIframeAPI(_0x70787(0x526),'closed');try{if('code'in _0x1ad044){if(_0x1ad044[_0x70787(0x2fe)]==0x1f7){if(_0x38ec87==![]){clearInterval(_0x162eb3[_0x70787(0x351)]);if(!_0x162eb3['cleanOutput']){if('cmLSK'===_0x70787(0x241)){function _0x56ebdc(){var _0x51f6bc=_0x70787;_0x2ea79d(_0x51f6bc(0x560));}}else warnUser(_0x70787(0x17c),0x7530);}}}}}catch(_0x37f01f){errorlog(_0x37f01f);}errorlog(_0x70787(0x232));if(_0x162eb3[_0x70787(0x3d8)]==![]){if(_0x70787(0x34e)!==_0x70787(0x34e)){function _0x449c5b(){_0x311041+=0x20;}}else try{_0x162eb3['ws'][_0x70787(0x2bb)]===WebSocket[_0x70787(0x560)]&&(_0x162eb3['ws']=null,setTimeout(()=>{var _0x5d3132=_0x70787;_0x162eb3[_0x5d3132(0x47d)](!![]);},0x1388));}catch(_0x14da25){errorlog(_0x14da25);}}};},_0x162eb3['sendMessage']=function(_0x440eac,_0x376385=null){var _0x438b97=_0x44a3fc;_0x440eac=JSON[_0x438b97(0x444)](_0x440eac);if(_0x376385==null){for(var _0x4e23fe in _0x162eb3[_0x438b97(0x147)]){try{_0x162eb3['pcs'][_0x4e23fe][_0x438b97(0x4ae)]['send'](_0x440eac);}catch(_0x219ae1){warnlog(_0x438b97(0x3ce));}}return!![];}else try{return _0x162eb3[_0x438b97(0x147)][_0x376385][_0x438b97(0x4ae)][_0x438b97(0x388)](_0x440eac),!![];}catch(_0x51a2fa){return warnlog(_0x438b97(0x307)),![];}return![];},_0x162eb3[_0x44a3fc(0x196)]=function(_0xb9f792,_0x2cd391=null){var _0x5c3513=_0x44a3fc,_0x135fa0=JSON[_0x5c3513(0x444)](_0xb9f792);if(_0x2cd391==null)for(var _0x270f7d in _0x162eb3[_0x5c3513(0x1f4)]){try{_0x162eb3[_0x5c3513(0x1f4)][_0x270f7d][_0x5c3513(0x228)][_0x5c3513(0x388)](_0x135fa0);}catch(_0x2bdfc7){log(_0x5c3513(0xde));}}else try{return _0x162eb3['rpcs'][_0x2cd391][_0x5c3513(0x228)]['send'](_0x135fa0),!![];}catch(_0x507392){return log('PUBLISHER\x27s\x20RTC\x20Connection\x20seems\x20to\x20be\x20dead?\x20'),![];}},_0x162eb3[_0x44a3fc(0x1e9)]=function(){setTimeout(function(){var _0x299153=_0x447b;_0x162eb3[_0x299153(0x1e9)];},0xbb8);},_0x162eb3[_0x44a3fc(0x584)]=function(_0x21d452){var _0x26ba28=_0x44a3fc;try{var _0x460789=_0x162eb3[_0x26ba28(0x3d0)][_0x26ba28(0x2fc)]();_0x460789=_0x460789[0x0];if(_0x460789[_0x26ba28(0x519)]){var _0x1bfe5c=_0x460789['getCapabilities']();_0x162eb3[_0x26ba28(0x50e)]==![]&&(_0x162eb3[_0x26ba28(0x50e)]=_0x1bfe5c[_0x26ba28(0x50e)][_0x26ba28(0xd5)]);_0x162eb3[_0x26ba28(0x50e)]+=_0x21d452;if(_0x162eb3[_0x26ba28(0x50e)]>_0x1bfe5c[_0x26ba28(0x50e)]['max'])_0x162eb3['zoom']=_0x1bfe5c[_0x26ba28(0x50e)][_0x26ba28(0x418)];else _0x162eb3[_0x26ba28(0x50e)]<_0x1bfe5c[_0x26ba28(0x50e)][_0x26ba28(0xd5)]&&(_0x162eb3[_0x26ba28(0x50e)]=_0x1bfe5c[_0x26ba28(0x50e)][_0x26ba28(0xd5)]);_0x460789[_0x26ba28(0x290)]({'advanced':[{'zoom':_0x162eb3[_0x26ba28(0x50e)]}]});}}catch(_0xb4f0d7){if('kpZPP'!==_0x26ba28(0x3d1)){function _0x2259cc(){var _0x370dd1=_0x26ba28;_0x13d8c2[_0x370dd1(0x1f4)][_0x5bc059]['videoElement'][_0x370dd1(0x253)]=![];}}else errorlog(_0xb4f0d7);}},_0x162eb3[_0x44a3fc(0x498)]=function(){var _0x313c49=_0x44a3fc;_0x162eb3['taintedSession']=!![],warnlog(_0x313c49(0x259));try{var _0x1b931e={};_0x1b931e['videoMuted']=!![],_0x162eb3[_0x313c49(0x43f)](_0x1b931e);}catch(_0x3a9133){}try{if('gvUXx'===_0x313c49(0x455)){function _0x19f42a(){var _0x148939=_0x313c49;_0x1d89b0[_0x148939(0x179)](_0x19df99[_0x148939(0x1e2)]);}}else _0x162eb3['ws'][_0x313c49(0x556)]();}catch(_0x532480){}try{recordLocalVideo(_0x313c49(0x529));}catch(_0x2f023b){}try{if('zrzES'===_0x313c49(0x3a3)){function _0x55ad38(){var _0x37052b=_0x313c49;_0x2eeda9[_0x37052b(0x196)](_0x2616c2,_0x41064c);}}else{_0x162eb3[_0x313c49(0x310)]&&_0x162eb3['canvasSource'][_0x313c49(0x288)]['getTracks']()[_0x313c49(0x204)](function(_0x251ebf){var _0x90778=_0x313c49;_0x251ebf[_0x90778(0x529)](),_0x162eb3[_0x90778(0x340)][_0x90778(0x288)][_0x90778(0x4dc)](_0x251ebf),log(_0x90778(0x248));});_0x162eb3[_0x313c49(0x340)][_0x313c49(0x288)][_0x313c49(0x472)]()[_0x313c49(0x204)](function(_0x1c85dd){var _0x2873d7=_0x313c49;_0x1c85dd[_0x2873d7(0x529)](),_0x162eb3[_0x2873d7(0x340)][_0x2873d7(0x288)][_0x2873d7(0x4dc)](_0x1c85dd),log(_0x2873d7(0x248));}),_0x162eb3['streamSrc']['getTracks']()[_0x313c49(0x204)](function(_0x35d4b8){var _0x36559f=_0x313c49;_0x35d4b8[_0x36559f(0x529)](),_0x162eb3['videoElement'][_0x36559f(0x288)][_0x36559f(0x4dc)](_0x35d4b8),log('stopping\x20old\x20track');});for(i in _0x162eb3[_0x313c49(0x1f4)]){_0x162eb3[_0x313c49(0x1f4)][i][_0x313c49(0x340)]&&(_0x162eb3[_0x313c49(0x1f4)][i]['videoElement'][_0x313c49(0x38a)]&&(_0x162eb3[_0x313c49(0x1f4)][i][_0x313c49(0x340)]['recorder']['writer']['close'](),_0x162eb3['rpcs'][i][_0x313c49(0x340)][_0x313c49(0x38a)]=![])),_0x162eb3[_0x313c49(0x1f4)][i][_0x313c49(0x556)](),_0x162eb3[_0x313c49(0x1f4)][i]=null,delete _0x162eb3[_0x313c49(0x1f4)][i];}for(i in _0x162eb3[_0x313c49(0x147)]){_0x162eb3['pcs'][i][_0x313c49(0x556)](),_0x162eb3[_0x313c49(0x147)][i]=null,delete _0x162eb3[_0x313c49(0x147)][i],applySceneState();}}}catch(_0xc55495){errorlog('failed\x20to\x20disconnect');}setTimeout(function(){var _0x56b6d7=_0x313c49;if(_0x56b6d7(0x413)===_0x56b6d7(0x490)){function _0x49df5a(){var _0x43995b=_0x56b6d7;_0x554a46(_0x43995b(0x23b),0x1388);}}else{for(i in _0x162eb3){try{delete _0x162eb3[i];}catch(_0x31cbc3){}}delete _0x162eb3;}},0x4b0),hangupComplete(),log(_0x313c49(0x315));},_0x162eb3['hangupDirector']=function(){var _0x20310e=_0x44a3fc;_0x162eb3[_0x20310e(0x46b)]=!![],_0x162eb3[_0x20310e(0x460)]=![],warnlog(_0x20310e(0x259));try{_0x162eb3[_0x20310e(0x340)]['srcObject'][_0x20310e(0x472)]()[_0x20310e(0x204)](function(_0xe9a340){var _0x2a6a09=_0x20310e;_0xe9a340[_0x2a6a09(0x529)](),_0x162eb3[_0x2a6a09(0x340)][_0x2a6a09(0x288)][_0x2a6a09(0x4dc)](_0xe9a340),log('stopping\x20old\x20track');}),_0x162eb3['streamSrc']['getTracks']()[_0x20310e(0x204)](function(_0x32fe2c){var _0x3e43bf=_0x20310e;_0x32fe2c[_0x3e43bf(0x529)](),_0x162eb3['streamSrc'][_0x3e43bf(0x4dc)](_0x32fe2c),log(_0x3e43bf(0x248));});for(UUID in _0x162eb3[_0x20310e(0x147)]){var _0x4c1be1=_0x162eb3['pcs'][UUID][_0x20310e(0x442)]();_0x4c1be1['forEach'](_0x59db96=>{var _0x420cea=_0x20310e;_0x59db96[_0x420cea(0x2ac)]&&(_0x59db96[_0x420cea(0x2ac)][_0x420cea(0x2f1)]=![]);});}var _0x5c4c19={};_0x5c4c19[_0x20310e(0x1ae)]=!![],_0x162eb3[_0x20310e(0x43f)](_0x5c4c19);}catch(_0x2611fc){errorlog(_0x20310e(0x301));}log(_0x20310e(0x202));},_0x162eb3[_0x44a3fc(0x257)]=function(_0x3f6d50){var _0x449823=_0x44a3fc;try{var _0x55449d=_0x162eb3['streamSrc'][_0x449823(0x2fc)]();_0x55449d=_0x55449d[0x0];if(_0x55449d[_0x449823(0x519)]){var _0x3ccecf=_0x55449d['getCapabilities']();_0x162eb3[_0x449823(0x558)]==![]&&(_0x162eb3['focusDistance']=_0x3ccecf[_0x449823(0x558)][_0x449823(0xd5)]);_0x162eb3['focusDistance']+=_0x3f6d50;if(_0x162eb3[_0x449823(0x558)]>_0x3ccecf[_0x449823(0x558)][_0x449823(0x418)])_0x162eb3[_0x449823(0x558)]=_0x3ccecf[_0x449823(0x558)][_0x449823(0x418)];else _0x162eb3[_0x449823(0x558)]<_0x3ccecf[_0x449823(0x558)]['min']&&(_0x162eb3[_0x449823(0x558)]=_0x3ccecf['focusDistance'][_0x449823(0xd5)]);_0x55449d[_0x449823(0x290)]({'advanced':[{'focusMode':_0x449823(0x2df),'focusDistance':_0x162eb3[_0x449823(0x558)]}]});}}catch(_0x9e079f){errorlog(_0x9e079f);}},_0x162eb3[_0x44a3fc(0x417)]=function(_0xddb402){var _0x1b6520=_0x44a3fc;_0x162eb3[_0x1b6520(0x147)][_0xddb402][_0x1b6520(0x417)]()['then'](_0x51acd5=>{var _0x10ec20=_0x1b6520;log('create\x20offer\x20worked');if(safariVersion()<=0xd&&(iOS||iPad)){}else{if(_0x162eb3[_0x10ec20(0x133)]==0x3||_0x162eb3[_0x10ec20(0x133)]==0x5||_0x162eb3[_0x10ec20(0x133)]==0x1)_0x51acd5[_0x10ec20(0x457)]=CodecsHandler[_0x10ec20(0x195)](_0x51acd5['sdp'],{'stereo':0x1}),log(_0x10ec20(0x306));else{if(iOS||iPad){}else _0x162eb3[_0x10ec20(0x133)]==0x4&&(_0x51acd5[_0x10ec20(0x457)]=CodecsHandler[_0x10ec20(0x195)](_0x51acd5[_0x10ec20(0x457)],{'stereo':0x2}),log(_0x10ec20(0x306)));}}_0x162eb3[_0x10ec20(0x147)][_0xddb402][_0x10ec20(0x21f)](_0x51acd5)[_0x10ec20(0x57e)](function(){var _0x4be3ef=_0x10ec20;log(_0x4be3ef(0x17e)+_0xddb402);var _0x2f1f3d={};_0x2f1f3d[_0x4be3ef(0x1e2)]=_0xddb402,_0x2f1f3d['streamID']=_0x162eb3[_0x4be3ef(0x34f)],_0x2f1f3d[_0x4be3ef(0x16b)]=_0x162eb3[_0x4be3ef(0x147)][_0xddb402][_0x4be3ef(0x156)],_0x2f1f3d[_0x4be3ef(0x157)]=_0x162eb3[_0x4be3ef(0x147)][_0xddb402][_0x4be3ef(0x157)],_0x162eb3[_0x4be3ef(0xf2)]?_0x162eb3[_0x4be3ef(0x52d)](JSON[_0x4be3ef(0x444)](_0x2f1f3d[_0x4be3ef(0x16b)]))[_0x4be3ef(0x57e)](function(_0x3d4245){var _0x362d74=_0x4be3ef;_0x2f1f3d[_0x362d74(0x16b)]=_0x3d4245[0x0],_0x2f1f3d['vector']=_0x3d4245[0x1],_0x162eb3[_0x362d74(0x3cd)](_0x2f1f3d);}):_0x162eb3[_0x4be3ef(0x3cd)](_0x2f1f3d);})[_0x10ec20(0x19f)](errorlog);})[_0x1b6520(0x19f)](errorlog);},_0x162eb3[_0x44a3fc(0x54d)]=function(){var _0x1a39f7=_0x44a3fc;for(var _0x5b9a32 in _0x162eb3[_0x1a39f7(0x147)]){_0x162eb3['pcs'][_0x5b9a32][_0x1a39f7(0x145)]!==![]?(_0x162eb3[_0x1a39f7(0x116)](_0x5b9a32),log(_0x1a39f7(0x3e3))):log(_0x1a39f7(0x10a));}},_0x162eb3[_0x44a3fc(0x179)]=function(_0x55308e){var _0x1953f6=_0x44a3fc;if(_0x1953f6(0x41b)===_0x1953f6(0x3bb)){function _0x15a3f3(){var _0x33faec=_0x1953f6;_0x516223=_0x4784d0[_0x33faec(0x218)](_0x11b7e3,_0x4b5700);}}else{if(_0x55308e in _0x162eb3['pcs']){errorlog(_0x1953f6(0x2e0));try{_0x162eb3[_0x1953f6(0x147)][_0x55308e]['close']();}catch(_0x102355){errorlog(_0x1953f6(0x450));}_0x162eb3[_0x1953f6(0x147)][_0x55308e]=null,delete _0x162eb3['pcs'][_0x55308e],_0x162eb3[_0x1953f6(0x421)](),applySceneState();}else log(_0x1953f6(0x2f5));if(_0x162eb3[_0x1953f6(0x190)]!==![]){if(Object[_0x1953f6(0x4bb)](_0x162eb3['pcs'])['length']>_0x162eb3[_0x1953f6(0x190)]){delete _0x162eb3['pcs'][_0x55308e],_0x162eb3['applySoloChat'](),warnlog('Viewer\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit'),applySceneState();return;}}else{if(_0x162eb3[_0x1953f6(0x153)]!==![]){if(Object[_0x1953f6(0x4bb)](_0x162eb3[_0x1953f6(0x1f4)])[_0x1953f6(0x3f4)]+Object[_0x1953f6(0x4bb)](_0x162eb3[_0x1953f6(0x147)])['length']>_0x162eb3['maxconnections']){delete _0x162eb3[_0x1953f6(0x147)][_0x55308e],_0x162eb3['applySoloChat'](),warnlog('Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit'),applySceneState();return;}}}_0x162eb3[_0x1953f6(0x147)][_0x55308e]=new RTCPeerConnection(_0x162eb3[_0x1953f6(0x52b)]);if(_0x162eb3[_0x1953f6(0x3d8)]){if(Object[_0x1953f6(0x4bb)](_0x162eb3[_0x1953f6(0x147)])[_0x1953f6(0x3f4)]>0x1){delete _0x162eb3[_0x1953f6(0x147)][_0x55308e],_0x162eb3[_0x1953f6(0x421)](),applySceneState();return;}}_0x162eb3['pcs'][_0x55308e][_0x1953f6(0x199)]=null,_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x342)]=null,_0x162eb3[_0x1953f6(0x147)][_0x55308e]['obsVisibility']=null,_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x208)]=null,_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x223)]=null,_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x1b0)]=null,_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x40d)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e]['savedBitrate']=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x49f)]=null,_0x162eb3['pcs'][_0x55308e][_0x1953f6(0x2a1)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x157)]=_0x162eb3[_0x1953f6(0x2af)](),_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x14f)]={},_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x466)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x33a)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x506)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x26c)]=![],_0x162eb3['pcs'][_0x55308e][_0x1953f6(0x520)]=!![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x521)]=!![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x117)]=!![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x1d1)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x383)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x1e2)]=_0x55308e,_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x3ea)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x4db)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x295)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x571)]=![],_0x162eb3['pcs'][_0x55308e][_0x1953f6(0x4ab)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x145)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x4ae)]=_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x447)](_0x1953f6(0x4ae)),_0x162eb3[_0x1953f6(0x147)][_0x55308e]['sendChannel'][_0x1953f6(0x1e2)]=_0x55308e,_0x162eb3[_0x1953f6(0x147)][_0x55308e]['keyframerate']=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x524)]=null,_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x2fa)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x2c5)]=![],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x13c)]=Date[_0x1953f6(0x1b9)](),_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x4ae)][_0x1953f6(0x3ef)]=()=>{var _0x510b17=_0x1953f6;log('send\x20channel\x20open\x20pcs'),msg={},msg[_0x510b17(0x53f)]={},msg[_0x510b17(0x53f)][_0x510b17(0x2fa)]=_0x162eb3[_0x510b17(0x2fa)],msg[_0x510b17(0x53f)]['order']=_0x162eb3[_0x510b17(0x2c5)],msg[_0x510b17(0x53f)][_0x510b17(0x253)]=_0x162eb3[_0x510b17(0x253)];_0x162eb3[_0x510b17(0x504)]&&_0x162eb3[_0x510b17(0x504)]!==_0x55308e&&(msg['info']['muted']=!![]);msg[_0x510b17(0x53f)][_0x510b17(0x477)]=_0x162eb3[_0x510b17(0x477)],msg[_0x510b17(0x53f)]['directorDisplayMuted']=_0x162eb3[_0x510b17(0x30a)],msg['info'][_0x510b17(0x491)]=_0x162eb3['directorVideoMuted'],msg['info'][_0x510b17(0x39e)]=_0x162eb3[_0x510b17(0x1ae)];_0x162eb3[_0x510b17(0x1b6)]&&(msg[_0x510b17(0x4de)]={},msg[_0x510b17(0x4de)][_0x510b17(0x262)]=_0x162eb3[_0x510b17(0x262)]);msg[_0x510b17(0x53f)][_0x510b17(0xed)]=_0x162eb3[_0x510b17(0x4d1)],msg[_0x510b17(0x53f)][_0x510b17(0x35f)]=_0x162eb3[_0x510b17(0x261)],msg[_0x510b17(0x53f)][_0x510b17(0x192)]=_0x162eb3[_0x510b17(0x33c)],msg['info'][_0x510b17(0x3a0)]=_0x162eb3['maxvideobitrate'],msg[_0x510b17(0x53f)]['maxviewers_url']=_0x162eb3[_0x510b17(0x190)],msg[_0x510b17(0x53f)][_0x510b17(0x4c5)]=_0x162eb3[_0x510b17(0x133)],msg[_0x510b17(0x53f)]['aec_url']=_0x162eb3['echoCancellation'],msg['info'][_0x510b17(0x416)]=_0x162eb3[_0x510b17(0xe5)],msg[_0x510b17(0x53f)]['denoise_url']=_0x162eb3['noiseSuppression'],msg['info'][_0x510b17(0x158)]=_0x162eb3['version'],msg[_0x510b17(0x53f)][_0x510b17(0x1da)]=_0x162eb3[_0x510b17(0xe8)],msg[_0x510b17(0x53f)][_0x510b17(0x56e)]=_0x162eb3['compressor'],msg[_0x510b17(0x53f)]['recording_audio_ctx_latency']=_0x162eb3[_0x510b17(0xfe)],msg[_0x510b17(0x53f)]['recording_audio_pipeline']=!_0x162eb3['disableWebAudio'],msg[_0x510b17(0x53f)][_0x510b17(0x113)]=_0x162eb3[_0x510b17(0x344)],msg[_0x510b17(0x53f)][_0x510b17(0x492)]=_0x162eb3[_0x510b17(0x321)],msg[_0x510b17(0x53f)]['playback_audio_volume_meter']=_0x162eb3[_0x510b17(0x55e)];try{if(navigator[_0x510b17(0x3f1)]){var _0x4ed2bc,_0x4df75c=navigator[_0x510b17(0x3f1)];msg[_0x510b17(0x53f)][_0x510b17(0x28a)]=_0x4df75c;}navigator[_0x510b17(0x209)]&&(msg[_0x510b17(0x53f)]['platform']=navigator[_0x510b17(0x209)]);if(safariVersion())msg['info'][_0x510b17(0x25d)]=_0x510b17(0x185);else{if(getChromeVersion()>0x3c)msg[_0x510b17(0x53f)][_0x510b17(0x25d)]=_0x510b17(0x34d)+getChromeVersion();else _0x4df75c[_0x510b17(0x549)](_0x510b17(0x115))&&(msg['info'][_0x510b17(0x25d)]=_0x510b17(0x115));}}catch(_0x4c3f51){};_0x162eb3[_0x510b17(0x43f)](msg,_0x55308e),pokeIframeAPI(_0x510b17(0x4ec),!![],_0x55308e),updateUserList();},_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x4ae)]['onclose']=()=>{var _0x483a61=_0x1953f6;pokeIframeAPI(_0x483a61(0x4ec),![],_0x55308e),_0x162eb3[_0x483a61(0x264)](),warnlog(_0x483a61(0x40f));try{_0x162eb3[_0x483a61(0x147)][_0x55308e][_0x483a61(0x556)](),_0x162eb3['pcs'][_0x55308e]=null,delete _0x162eb3[_0x483a61(0x147)][_0x55308e],applySceneState();}catch(_0x35f5ea){}},_0x162eb3['pcs'][_0x55308e][_0x1953f6(0x4ae)][_0x1953f6(0x1f2)]=_0x3fc91c=>{var _0x44b3a4=_0x1953f6;log(_0x44b3a4(0x551));var _0x252667=JSON[_0x44b3a4(0x4aa)](_0x3fc91c[_0x44b3a4(0x2cd)]);_0x252667[_0x44b3a4(0x1e2)]=_0x55308e;if(_0x252667[_0x44b3a4(0x16b)]){_0x162eb3[_0x44b3a4(0x3e9)](_0x252667);return;}else{if(_0x252667[_0x44b3a4(0x17d)]){log(_0x44b3a4(0x38b)),_0x162eb3['processIce'](_0x252667);return;}else{if(_0x252667[_0x44b3a4(0x134)]){log(_0x44b3a4(0x481)),_0x162eb3[_0x44b3a4(0x142)](_0x252667);return;}}}warnlog(_0x252667);if(_0x44b3a4(0x53f)in _0x252667){_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x14f)][_0x44b3a4(0x53f)]=_0x252667['info'];_0x44b3a4(0x2fa)in _0x252667[_0x44b3a4(0x53f)]&&(typeof _0x252667[_0x44b3a4(0x53f)][_0x44b3a4(0x2fa)]==_0x44b3a4(0x173)?_0x162eb3[_0x44b3a4(0x147)][_0x55308e]['label']=sanitizeLabel(_0x252667[_0x44b3a4(0x53f)]['label']):_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x2fa)]=![]);if(_0x55308e===_0x162eb3[_0x44b3a4(0x37c)])try{_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x14f)][_0x44b3a4(0x53f)][_0x44b3a4(0x1b6)]=!![];}catch(_0x46fe73){}}_0x44b3a4(0x40d)in _0x252667&&(_0x162eb3['pcs'][_0x55308e][_0x44b3a4(0x40d)]=parseInt(_0x252667[_0x44b3a4(0x40d)]));_0x44b3a4(0x352)in _0x252667&&_0x162eb3[_0x44b3a4(0x2d3)](_0x55308e,_0x252667[_0x44b3a4(0x352)]);if('requestStats'in _0x252667){log(_0x252667);if(_0x162eb3[_0x44b3a4(0x37c)]===_0x55308e){var _0x262389={};for(var _0x530908 in _0x162eb3[_0x44b3a4(0x147)]){if(_0x44b3a4(0x10c)===_0x44b3a4(0x10c)){if(_0x530908===_0x55308e)continue;_0x262389[_0x530908]=_0x162eb3[_0x44b3a4(0x147)][_0x530908][_0x44b3a4(0x14f)];}else{function _0xa60376(){var _0x494bd8=_0x44b3a4;_0x5c1dd9=_0x29182e[_0x494bd8(0x340)]['srcObject'];}}}var _0x3ff848={};_0x3ff848[_0x44b3a4(0x294)]=_0x262389,_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0x4cf)in _0x252667){if(_0x252667[_0x44b3a4(0x4cf)]===_0x162eb3[_0x44b3a4(0x4cf)]&&_0x162eb3[_0x44b3a4(0x4cf)]){var _0x262389={};for(var _0x530908 in _0x162eb3[_0x44b3a4(0x147)]){if(_0x530908===_0x55308e)continue;_0x262389[_0x530908]=_0x162eb3[_0x44b3a4(0x147)][_0x530908]['stats'];}var _0x3ff848={};_0x3ff848[_0x44b3a4(0x294)]=_0x262389,_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}}}}if('requestResolution'in _0x252667)try{log(_0x252667),_0x162eb3['setResolution'](_0x252667[_0x44b3a4(0x1e2)],_0x252667[_0x44b3a4(0x322)]['w'],_0x252667[_0x44b3a4(0x322)]['h']);}catch(_0x3a62d4){errorlog(_0x3a62d4);}if(_0x44b3a4(0x14b)in _0x252667){if(_0x252667['scene']){if(_0x162eb3[_0x44b3a4(0x37c)]===_0x55308e)_0x162eb3[_0x44b3a4(0x54d)]();else{if('zQaSU'!==_0x44b3a4(0x511))errorlog(_0x44b3a4(0xe0));else{function _0x49848a(){var _0x3bc86b=_0x44b3a4;_0x56e7e7[_0x3bc86b(0x17d)]=_0x2a07e0['parse'](_0x542cc6),_0x1c9aa3['processIce2'](_0x67736);}}}}else _0x162eb3[_0x44b3a4(0x116)](_0x55308e);}if('chat'in _0x252667){var _0x334bc7=![],_0x4b0a09=![];if(_0x162eb3[_0x44b3a4(0x37c)]===_0x55308e){_0x334bc7=!![];if(_0x44b3a4(0x187)in _0x252667){if(_0x252667[_0x44b3a4(0x187)]==!![]){if(_0x44b3a4(0x445)===_0x44b3a4(0x445))_0x4b0a09=!![];else{function _0x404aeb(){var _0x3bdb3d=_0x44b3a4;_0x1808f3[_0x3bdb3d(0x39d)](_0x212d4f);}}}}}log(_0x44b3a4(0x1ba)+_0x334bc7),getChatMessage(_0x252667[_0x44b3a4(0x4c4)],_0x162eb3['pcs'][_0x55308e][_0x44b3a4(0x2fa)],_0x334bc7,_0x4b0a09);}if(_0x44b3a4(0x2c5)in _0x252667){_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x2c5)]=parseInt(_0x252667['order'])||0x0;_0x55308e in _0x162eb3['rpcs']&&(_0x162eb3[_0x44b3a4(0x1f4)][_0x55308e][_0x44b3a4(0x2c5)]=_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x2c5)]);if(_0x162eb3[_0x44b3a4(0x1b6)]){var _0x11d474=document['querySelectorAll'](_0x44b3a4(0x330)+_0x55308e+'\x22]');log(_0x11d474),_0x11d474[0x0]&&(_0x11d474[0x0][_0x44b3a4(0x27f)]=parseInt(_0x252667[_0x44b3a4(0x2c5)])||0x0);}updateMixer();}if(_0x44b3a4(0x3ea)in _0x252667){if(_0x44b3a4(0x3ca)===_0x44b3a4(0x3ca))_0x162eb3[_0x44b3a4(0x198)](_0x55308e,_0x252667[_0x44b3a4(0x3ea)]);else{function _0x5f58d9(){_0x15e19b['encodings'][0x0]['active']=![];}}}_0x44b3a4(0x186)in _0x252667&&(_0x162eb3[_0x44b3a4(0x1b6)]&&(!(_0x162eb3[_0x44b3a4(0x14e)]||_0x162eb3[_0x44b3a4(0x425)])&&warnUser(_0x44b3a4(0x23b),0x1388)),errorlog(_0x44b3a4(0x24f)+_0x252667[_0x44b3a4(0x186)]+',\x20isDirector:\x20'+_0x162eb3[_0x44b3a4(0x1b6)]));if(_0x55308e!==_0x162eb3['directorUUID']){if(_0x44b3a4(0x159)!==_0x44b3a4(0x159)){function _0x1d3680(){var _0x739ff6=_0x44b3a4;_0x24f044[_0x739ff6(0x1f4)][_0x3dbf7e]['order']=0x0;}}else{if('requestAudioHack'in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]=_0x44b3a4(0x221),_0x162eb3['sendMessage'](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0x43e)in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]=_0x44b3a4(0x43e),_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0x172)in _0x252667){var _0x3ff848={};_0x3ff848['rejected']=_0x44b3a4(0x172),_0x162eb3['sendMessage'](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0x58c)in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]=_0x44b3a4(0x58c),_0x162eb3['sendMessage'](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0x42f)in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]='changeLabel',_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0x2ca)in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]=_0x44b3a4(0x2ca),_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0xe1)in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]=_0x44b3a4(0xe1),_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0x498)in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]=_0x44b3a4(0x498),_0x162eb3['sendMessage'](_0x3ff848,_0x55308e);}else{if(_0x44b3a4(0x1bc)in _0x252667){var _0x3ff848={};_0x3ff848['rejected']=_0x44b3a4(0x1bc),_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}else{if('speakerMute'in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]=_0x44b3a4(0x420),_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}else{if('volume'in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x186)]=_0x44b3a4(0x280),_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}}}}}}}}}}}}}else{if(_0x55308e===_0x162eb3[_0x44b3a4(0x37c)]){if('requestAudioHack'in _0x252667){var _0x386b56=_0x162eb3[_0x44b3a4(0x3d0)][_0x44b3a4(0x28e)]();if(_0x386b56['length']){if(_0x44b3a4(0x2ac)in _0x252667){if(_0x44b3a4(0x52f)===_0x44b3a4(0x1cd)){function _0xccea3d(){_0x42496a(_0x5a7cb4);}}else{var _0x1af131=parseInt(_0x252667[_0x44b3a4(0x2ac)]);_0x1af131<_0x386b56[_0x44b3a4(0x3f4)]&&(_0x386b56=_0x386b56[_0x1af131],applyAudioHack(_0x252667[_0x44b3a4(0x57d)],_0x252667[_0x44b3a4(0x276)]));}}else _0x386b56=_0x386b56[0x0],applyAudioHack(_0x252667[_0x44b3a4(0x57d)],_0x252667[_0x44b3a4(0x276)]);}}if('requestVideoRecord'in _0x252667){if(_0x252667[_0x44b3a4(0x43e)]){if(_0x162eb3[_0x44b3a4(0x340)]){var _0x3043cc=0x1770;if(_0x252667['value']){if(_0x44b3a4(0x118)!==_0x44b3a4(0x2c0))_0x3043cc=parseInt(_0x252667[_0x44b3a4(0x276)]);else{function _0x1c910c(){var _0x254185=_0x44b3a4;_0x42fc4f[_0x254185(0x1f4)][_0x4208b3]['remoteMuteElement']['style'][_0x254185(0x1fb)]=_0x254185(0x545);}}}recordLocalVideo(_0x44b3a4(0x132),_0x3043cc);}}else _0x162eb3[_0x44b3a4(0x340)]&&recordLocalVideo('stop');}if('changeOrder'in _0x252667){_0x162eb3['order']==![]&&(_0x162eb3['order']=0x0);_0x162eb3[_0x44b3a4(0x2c5)]+=parseInt(_0x252667[_0x44b3a4(0x172)])||0x0;var _0x3ff848={};_0x3ff848={},_0x3ff848['order']=_0x162eb3[_0x44b3a4(0x2c5)],_0x162eb3[_0x44b3a4(0x358)](_0x3ff848),updateMixer();}if(_0x44b3a4(0x58c)in _0x252667){window[_0x44b3a4(0x3f6)]();var _0x3dc25f=confirm(_0x44b3a4(0x562)+_0x252667[_0x44b3a4(0x58c)]+_0x44b3a4(0x410));_0x3dc25f&&(window[_0x44b3a4(0x36e)][_0x44b3a4(0x4f3)]=_0x252667[_0x44b3a4(0x58c)]);;}if(_0x44b3a4(0x42f)in _0x252667){if(_0x44b3a4(0x276)in _0x252667){if(typeof _0x252667[_0x44b3a4(0x276)]==_0x44b3a4(0x173)){_0x162eb3[_0x44b3a4(0x2fa)]=sanitizeLabel(_0x252667[_0x44b3a4(0x276)]),log(_0x44b3a4(0x1a2)+_0x162eb3[_0x44b3a4(0x2fa)]);if(_0x162eb3['director']){var _0x11d474=getById(_0x44b3a4(0x427)+_0x55308e);_0x162eb3[_0x44b3a4(0x2fa)]?_0x11d474[_0x44b3a4(0x27f)]=_0x162eb3[_0x44b3a4(0x2fa)]:_0x11d474[_0x44b3a4(0x27f)]='Add\x20a\x20label';}else _0x162eb3[_0x44b3a4(0x478)]&&updateMixer();if(!_0x162eb3[_0x44b3a4(0x1b6)]){if(_0x44b3a4(0x105)!==_0x44b3a4(0x249))_0x162eb3[_0x44b3a4(0x2fa)]?document[_0x44b3a4(0xcf)]=_0x162eb3[_0x44b3a4(0x2fa)]:document['title']=location['hostname'];else{function _0xee61e3(){var _0x4b64ab=_0x44b3a4;_0x392018[_0x4b64ab(0x145)]=_0x2b369f[_0x4b64ab(0x145)];}}}var _0x4308a5=encodeURIComponent(_0x162eb3[_0x44b3a4(0x2fa)]);urlParams[_0x44b3a4(0x3f0)]('l')?updateURL('l='+_0x4308a5,!![],![]):updateURL('label='+_0x4308a5,!![],![]);var _0x3ff848={};_0x3ff848[_0x44b3a4(0x42f)]=!![],_0x3ff848[_0x44b3a4(0x276)]=_0x162eb3['label'],_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848);}else{_0x162eb3[_0x44b3a4(0x2fa)]=![];var _0x3ff848={};_0x3ff848[_0x44b3a4(0x42f)]=!![],_0x3ff848[_0x44b3a4(0x276)]=_0x162eb3[_0x44b3a4(0x2fa)],_0x162eb3['sendMessage'](_0x3ff848);if(_0x162eb3[_0x44b3a4(0x1b6)]){var _0x11d474=getById(_0x44b3a4(0x427)+_0x55308e);_0x11d474[_0x44b3a4(0x27f)]=_0x44b3a4(0x394);}else{if(_0x162eb3[_0x44b3a4(0x478)])document[_0x44b3a4(0xcf)]=location[_0x44b3a4(0xf8)],updateMixer();else{if(_0x44b3a4(0x27e)===_0x44b3a4(0x211)){function _0x28e2d5(){var _0x1dff38=_0x44b3a4;_0xadbc11['crypto'][_0x1dff38(0x426)][_0x1dff38(0x1f5)]('jwk',{'kty':'RSA','e':_0x1dff38(0x141),'n':_0x343998,'alg':_0x1dff38(0x354),'ext':!![]},{'name':_0x1dff38(0x2cc),'hash':{'name':_0x1dff38(0x283)}},!![],[_0x1dff38(0xe6)])['then'](function(_0x396d76){var _0x4f758c=_0x1dff38;_0x1c6fa7[_0x4f758c(0x4bb)][_0x220110]={},_0x5eff78[_0x4f758c(0x4bb)][_0x30a927][_0x4f758c(0x52a)]=_0x396d76,_0x1a18b4[_0x4f758c(0x4bb)][_0xcc984a]['privateKey']=null;})[_0x1dff38(0x19f)](_0x504446);}}else document['title']=location[_0x44b3a4(0xf8)];}}}}}if(_0x44b3a4(0x2ca)in _0x252667){if(_0x252667[_0x44b3a4(0x57d)]==_0x44b3a4(0x16f))changeLowEQ(parseFloat(_0x252667[_0x44b3a4(0x276)]),_0x252667[_0x44b3a4(0x2ac)]);else{if(_0x252667[_0x44b3a4(0x57d)]==_0x44b3a4(0x48e))changeMidEQ(parseFloat(_0x252667[_0x44b3a4(0x276)]),_0x252667[_0x44b3a4(0x2ac)]);else _0x252667[_0x44b3a4(0x57d)]==_0x44b3a4(0x325)&&changeHighEQ(parseFloat(_0x252667['value']),_0x252667[_0x44b3a4(0x2ac)]);}}if(_0x44b3a4(0xe1)in _0x252667){if('MjxwA'===_0x44b3a4(0x282))_0x162eb3[_0x44b3a4(0x109)]&&lowerhand();else{function _0x22daae(){var _0x1303e1=_0x44b3a4;delete _0x5b7fab[_0x1303e1(0x1f4)][_0xba0138],_0x2d65bd(),_0x98f19b(_0x1303e1(0x3e1));return;}}}if(_0x44b3a4(0x231)in _0x252667){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x1e2)]=_0x55308e,_0x3ff848[_0x44b3a4(0xec)]=listAudioSettingsPrep(),sendMediaDevices(_0x3ff848[_0x44b3a4(0x1e2)]),_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x3ff848['UUID']);}if(_0x44b3a4(0x448)in _0x252667){if(_0x44b3a4(0x28b)===_0x44b3a4(0x28b)){var _0x3ff848={};_0x3ff848[_0x44b3a4(0x1e2)]=_0x55308e,_0x3ff848[_0x44b3a4(0x35a)]=listVideoSettingsPrep(),sendMediaDevices(_0x3ff848[_0x44b3a4(0x1e2)]),_0x162eb3['sendMessage'](_0x3ff848,_0x3ff848[_0x44b3a4(0x1e2)]);}else{function _0x4a638f(){return;}}}'changeSpeaker'in _0x252667&&changeAudioOutputDeviceById(_0x252667[_0x44b3a4(0x4cb)],_0x55308e);_0x44b3a4(0x50d)in _0x252667&&changeAudioDeviceById(_0x252667[_0x44b3a4(0x50d)],_0x55308e);_0x44b3a4(0x1be)in _0x252667&&changeVideoDeviceById(_0x252667[_0x44b3a4(0x1be)],_0x55308e);_0x44b3a4(0x191)in _0x252667&&updateCameraConstraints(_0x252667['keyname'],_0x252667[_0x44b3a4(0x276)]);_0x44b3a4(0x22f)in _0x252667&&changeLowCut(parseFloat(_0x252667[_0x44b3a4(0x276)]),_0x252667['track']);_0x44b3a4(0x22f)in _0x252667&&changeLowCut(parseFloat(_0x252667['value']),_0x252667[_0x44b3a4(0x2ac)]);if(_0x44b3a4(0x498)in _0x252667){if(_0x44b3a4(0x3dd)===_0x44b3a4(0x3dd))_0x162eb3[_0x44b3a4(0x498)]();else{function _0x41d82d(){var _0x475e89=_0x44b3a4;_0x356604[_0x475e89(0x147)][_0x12f7d7][_0x475e89(0x26c)]=!![];}}}if(_0x44b3a4(0x2c6)in _0x252667){}if(_0x44b3a4(0x280)in _0x252667){var _0x37e456=parseInt(_0x252667['volume'])/0x64||0x0;_0x162eb3[_0x44b3a4(0xe8)]=parseInt(_0x252667[_0x44b3a4(0x280)])||0x0;for(var _0x75492f in _0x162eb3[_0x44b3a4(0x4a1)]){log(_0x44b3a4(0xd2)),_0x162eb3[_0x44b3a4(0x4a1)][_0x75492f][_0x44b3a4(0x375)]['gain'][_0x44b3a4(0x174)](_0x37e456,_0x162eb3['webAudios'][_0x75492f][_0x44b3a4(0x389)][_0x44b3a4(0x405)]);}}if(_0x44b3a4(0xee)in _0x252667){if(_0x44b3a4(0x136)===_0x44b3a4(0x1eb)){function _0x128898(){_0x1e9d37(_0x164f9d['limitAudioEncoder'],0x3e8,_0x380b7a,0x7d00,0x0);}}else{var _0x2c8ea8=parseFloat(_0x252667[_0x44b3a4(0xee)]/0x3e8)||0x0;_0x162eb3[_0x44b3a4(0x39c)]=parseInt(_0x252667[_0x44b3a4(0xee)])||0x0;for(var _0x75492f in _0x162eb3[_0x44b3a4(0x4a1)]){_0x162eb3[_0x44b3a4(0x4a1)][_0x75492f][_0x44b3a4(0x39c)][_0x44b3a4(0x15e)][_0x44b3a4(0x174)](_0x2c8ea8,_0x162eb3[_0x44b3a4(0x4a1)][_0x75492f][_0x44b3a4(0x389)][_0x44b3a4(0x405)]);}}}_0x44b3a4(0x420)in _0x252667&&(_0x252667[_0x44b3a4(0x420)]?(_0x162eb3['directorSpeakerMuted']=!![],_0x162eb3[_0x44b3a4(0x4ba)]()):(_0x162eb3['directorSpeakerMuted']=![],_0x162eb3[_0x44b3a4(0x4ba)]()));if(_0x44b3a4(0x1bc)in _0x252667){if(_0x44b3a4(0x266)===_0x44b3a4(0x266))_0x252667[_0x44b3a4(0x1bc)]?(_0x162eb3[_0x44b3a4(0x30a)]=!![],_0x162eb3['directorDisplayMute']()):(_0x162eb3['directorDisplayMuted']=![],_0x162eb3['directorDisplayMute']());else{function _0x16a7f4(){var _0x408452=_0x44b3a4;_0x1d24de(_0x408452(0x10e));var _0x65d684={};_0x65d684[_0x408452(0x1e2)]=_0x4a3b27[_0x408452(0x1e2)],_0x65d684[_0x408452(0x16b)]=_0x34ff42[_0x408452(0x1f4)][_0x44b6c3['UUID']][_0x408452(0x156)],_0x65d684['session']=_0x38b9db[_0x408452(0x1f4)][_0x926230[_0x408452(0x1e2)]]['session'],_0x2a94fd[_0x408452(0xf2)]?_0xfee6de[_0x408452(0x52d)](_0x430fd5[_0x408452(0x444)](_0x65d684[_0x408452(0x16b)]))[_0x408452(0x57e)](function(_0x49a60b){var _0x4d4f2a=_0x408452;_0x65d684['description']=_0x49a60b[0x0],_0x65d684[_0x4d4f2a(0x3f5)]=_0x49a60b[0x1],_0x289700[_0x4d4f2a(0x577)](_0x65d684);}):_0x39665a[_0x408452(0x577)](_0x65d684);}}}_0x44b3a4(0x4b6)in _0x252667&&applyNewParams(_0x252667[_0x44b3a4(0x4b6)]);}}if(_0x44b3a4(0x50e)in _0x252667){if(_0x44b3a4(0x589)===_0x44b3a4(0x589)){if(_0x162eb3[_0x44b3a4(0x4cf)]){if(_0x44b3a4(0x4cf)in _0x252667)_0x252667[_0x44b3a4(0x4cf)]===_0x162eb3[_0x44b3a4(0x4cf)]&&_0x162eb3['remote']&&_0x162eb3[_0x44b3a4(0x584)](parseFloat(_0x252667['zoom']));else{if(_0x55308e===_0x162eb3['directorUUID'])_0x162eb3[_0x44b3a4(0x584)](parseFloat(_0x252667[_0x44b3a4(0x50e)]));else return;}}}else{function _0x38d9a6(){var _0x8f2d27=_0x44b3a4;_0x749a32(_0x8f2d27(0x22e)+this[_0x8f2d27(0x1e2)])[_0x8f2d27(0x23c)][_0x8f2d27(0x45f)](_0x56c285(_0x8f2d27(0x22e)+this[_0x8f2d27(0x1e2)]));}}}if(_0x44b3a4(0x3f6)in _0x252667){if(_0x162eb3[_0x44b3a4(0x4cf)]){if(_0x44b3a4(0x4cf)in _0x252667)_0x252667[_0x44b3a4(0x4cf)]===_0x162eb3['remote']&&_0x162eb3[_0x44b3a4(0x4cf)]&&_0x162eb3[_0x44b3a4(0x257)](parseFloat(_0x252667[_0x44b3a4(0x3f6)]));else{if(_0x55308e===_0x162eb3[_0x44b3a4(0x37c)])_0x162eb3['remoteFocus'](parseFloat(_0x252667[_0x44b3a4(0x3f6)]));else return;}}}manageSceneState(_0x252667,_0x55308e);'bitrate'in _0x252667&&_0x162eb3[_0x44b3a4(0x451)](_0x55308e,_0x252667[_0x44b3a4(0x22c)]);if(_0x44b3a4(0x25f)in _0x252667&&_0x44b3a4(0x3cb)in _0x252667){log(_0x44b3a4(0x17b));_0x252667['audio']==![]&&(_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x521)]=![]);_0x252667[_0x44b3a4(0x3cb)]==![]&&(_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x520)]=![]);'broadcast'in _0x252667&&_0x252667[_0x44b3a4(0x140)]==!![]&&(_0x162eb3['pcs'][_0x55308e][_0x44b3a4(0x383)]=!![],setTimeout(function(){makeImages();},0x3e8));if(_0x44b3a4(0x3b9)in _0x252667&&_0x252667[_0x44b3a4(0x3b9)]==![]){if(_0x44b3a4(0x362)===_0x44b3a4(0x55f)){function _0x3d8c37(){_0x2674bf(_0x4563e6);}}else _0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x117)]=![];}_0x44b3a4(0x39f)in _0x252667&&_0x252667[_0x44b3a4(0x1a5)]!==![]&&(_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x1d1)]=_0x252667[_0x44b3a4(0x39f)]);if(_0x44b3a4(0x466)in _0x252667){if(_0x252667[_0x44b3a4(0x466)]==!![]){if(_0x44b3a4(0x24d)!==_0x44b3a4(0x488))_0x162eb3[_0x44b3a4(0x147)][_0x55308e]['guest']=!![];else{function _0xcbd1ef(){_0x2eb555['video']=![];}}}}'forceios'in _0x252667&&(_0x252667[_0x44b3a4(0x26c)]===!![]&&(_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x26c)]=!![]));if('director'in _0x252667){if(_0x252667[_0x44b3a4(0x1b6)]==!![]){if(_0x44b3a4(0x4f9)===_0x44b3a4(0x561)){function _0x8bfcb4(){var _0x160d78=_0x44b3a4;_0x341470[_0x160d78(0x1fa)][_0x160d78(0x335)]();}}else(iOS||iPad)&&(_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x26c)]==!![]&&(_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x466)]=!![]));}}_0x44b3a4(0x300)in _0x252667&&(_0x252667[_0x44b3a4(0x300)]==!![]&&(_0x162eb3[_0x44b3a4(0x147)][_0x55308e]['limitAudio']=!![]));_0x44b3a4(0x160)in _0x252667&&(_0x252667[_0x44b3a4(0x160)]==!![]&&(_0x162eb3['pcs'][_0x55308e][_0x44b3a4(0x506)]=!![]));_0x44b3a4(0x139)in _0x252667&&(_0x162eb3['pcs'][_0x55308e][_0x44b3a4(0x139)]=_0x252667[_0x44b3a4(0x139)],_0x162eb3['pcs'][_0x55308e]['keyframerate']&&setTimeout(function(){var _0x4e972a=_0x44b3a4;_0x162eb3[_0x4e972a(0x116)](_0x55308e);},0x1388));if(_0x44b3a4(0x145)in _0x252667){if(_0x252667[_0x44b3a4(0x145)]!==![]){try{if(typeof _0x252667[_0x44b3a4(0x145)]===_0x44b3a4(0x173))_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x145)]=_0x252667['scene'][_0x44b3a4(0x50f)](/[\W]+/g,'_');else{if(_0x44b3a4(0x2ba)===_0x44b3a4(0x2ba))_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x145)]=(parseInt(_0x252667[_0x44b3a4(0x145)])||0x0)+'';else{function _0x32cde9(){var _0x2f0fff=_0x44b3a4;_0x3e890c[_0x2f0fff(0x17d)]=_0xcbc957['candidates'][_0x122645],_0x474dfc[_0x2f0fff(0x39d)](_0x38c1ee);}}}_0x162eb3[_0x44b3a4(0x147)][_0x55308e]['stats'][_0x44b3a4(0x145)]=_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x145)],updateSceneList(_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x145)]);}catch(_0x57aeaa){errorlog(_0x57aeaa);}_0x162eb3[_0x44b3a4(0x1b6)]==!![]&&_0x162eb3[_0x44b3a4(0x462)]==![]&&(_0x162eb3['pcs'][_0x55308e]['allowAudio']=![],_0x162eb3[_0x44b3a4(0x147)][_0x55308e]['allowVideo']=![],_0x162eb3[_0x44b3a4(0x147)][_0x55308e]['allowIframe']=![]);}}if(_0x162eb3[_0x44b3a4(0x1b6)]==!![]){if(_0x162eb3[_0x44b3a4(0x147)][_0x55308e][_0x44b3a4(0x145)])var _0x50f767=getDirectorSettings(_0x162eb3['pcs'][_0x55308e][_0x44b3a4(0x145)]);else var _0x50f767=getDirectorSettings(![]);var _0x3ff848={};_0x3ff848[_0x44b3a4(0x4de)]=_0x50f767,_0x162eb3[_0x44b3a4(0x43f)](_0x3ff848,_0x55308e);}_0x162eb3[_0x44b3a4(0x269)](_0x55308e);}},_0x162eb3[_0x1953f6(0x269)]=function(_0x9b4a61){var _0x33474e=_0x1953f6;if(_0x9b4a61 in _0x162eb3[_0x33474e(0x147)]){}else{errorlog(_0x33474e(0x1fd));return;}if(_0x162eb3[_0x33474e(0x147)][_0x9b4a61][_0x33474e(0x117)]===!![]){if(_0x162eb3[_0x33474e(0x40c)]){var _0x31bb47={};_0x31bb47[_0x33474e(0x40c)]=_0x162eb3[_0x33474e(0x40c)],_0x162eb3[_0x33474e(0x43f)](_0x31bb47,_0x9b4a61);}}log(_0x33474e(0x56f)),log(_0x162eb3['streamSrc']);var _0x4165df=null;if(_0x162eb3[_0x33474e(0x340)][_0x33474e(0x288)])_0x4165df=_0x162eb3[_0x33474e(0x340)][_0x33474e(0x288)];else{if(_0x162eb3[_0x33474e(0x3d0)]&&_0x162eb3['streamSrc'][_0x33474e(0x472)]())errorlog(_0x33474e(0x4f8)),log(_0x162eb3[_0x33474e(0x3d0)][_0x33474e(0x472)]()),_0x4165df=_0x162eb3[_0x33474e(0x3d0)];else{warnlog(_0x33474e(0x184));return;}}_0x4165df[_0x33474e(0x472)]()['forEach'](_0x1e207f=>{var _0x43bd0a=_0x33474e;_0x162eb3['pcs'][_0x9b4a61][_0x43bd0a(0x521)]==!![]&&(_0x1e207f[_0x43bd0a(0x2c3)]==_0x43bd0a(0x25f)&&_0x162eb3['pcs'][_0x9b4a61][_0x43bd0a(0x496)](_0x1e207f,_0x4165df));if(_0x162eb3[_0x43bd0a(0x147)][_0x9b4a61][_0x43bd0a(0x520)]==!![]){if(_0x1e207f[_0x43bd0a(0x2c3)]==_0x43bd0a(0x3cb)){if(_0x43bd0a(0x2d9)!==_0x43bd0a(0x2d9)){function _0x40f910(){var _0x29b807=_0x43bd0a;_0x459032['rpcs'][_0x4e2d12]=null,delete _0x2895af[_0x29b807(0x1f4)][_0x1a58b8];}}else _0x162eb3[_0x43bd0a(0x147)][_0x9b4a61][_0x43bd0a(0x466)]==!![]&&_0x162eb3[_0x43bd0a(0x4c0)]===0x0?log(_0x43bd0a(0x33d)):(_0x162eb3[_0x43bd0a(0x147)][_0x9b4a61][_0x43bd0a(0x496)](_0x1e207f,_0x4165df),setTimeout(function(_0x55b0d7){var _0x1a8e76=_0x43bd0a;_0x162eb3[_0x1a8e76(0xd4)](_0x55b0d7);},_0x162eb3[_0x43bd0a(0x1d8)],_0x9b4a61));}}}),log(_0x33474e(0x436)),_0x4165df[_0x33474e(0x28e)]()['length']&&(_0x162eb3[_0x33474e(0x421)](),log('starting\x20kicker'),_0x162eb3[_0x33474e(0x147)][_0x9b4a61]['limitAudio']===!![]&&setTimeout(_0x162eb3[_0x33474e(0x546)],0x3e8,_0x9b4a61,0x7d00,0x0),_0x162eb3[_0x33474e(0x147)][_0x9b4a61][_0x33474e(0x506)]===!![]&&setTimeout(_0x162eb3[_0x33474e(0x4d2)],0x3e8,_0x9b4a61));},_0x162eb3[_0x1953f6(0x147)][_0x55308e]['onnegotiationneeded']=function(_0x2a5870){var _0x3ffe31=_0x1953f6;if(_0x3ffe31(0x203)===_0x3ffe31(0x203))_0x162eb3[_0x3ffe31(0x417)](_0x55308e);else{function _0x599c73(){var _0x5bc3f5=_0x3ffe31;_0xc0db9(_0x5bc3f5(0x3e5));}}},_0x162eb3['pcs'][_0x55308e][_0x1953f6(0x25a)]=_0x4529e2=>{var _0x1d9d2b=_0x1953f6;errorlog(_0x1d9d2b(0x393));},_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x3b3)]=null,_0x162eb3['pcs'][_0x55308e]['iceBundle']=[],_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x4d4)]=function(_0x338b2d){var _0xcc1a8b=_0x1953f6;if(_0xcc1a8b(0x25b)===_0xcc1a8b(0x25b)){if(_0x338b2d[_0xcc1a8b(0x17d)]==null){log(_0xcc1a8b(0x469));return;}try{if(_0x162eb3[_0xcc1a8b(0x2c8)]){if(_0x338b2d[_0xcc1a8b(0x17d)][_0xcc1a8b(0x17d)][_0xcc1a8b(0x549)](_0x162eb3[_0xcc1a8b(0x2c8)])===-0x1){log(_0xcc1a8b(0x52c));return;}else log(_0x338b2d['candidate']);}}catch(_0x8d2a2c){errorlog(_0x8d2a2c);}if(_0x162eb3[_0xcc1a8b(0x147)][_0x55308e][_0xcc1a8b(0x3b3)]!==null){_0x162eb3[_0xcc1a8b(0x147)][_0x55308e][_0xcc1a8b(0x373)][_0xcc1a8b(0x21d)](_0x338b2d['candidate']);return;}_0x162eb3[_0xcc1a8b(0x147)][_0x55308e][_0xcc1a8b(0x373)][_0xcc1a8b(0x21d)](_0x338b2d[_0xcc1a8b(0x17d)]),_0x162eb3[_0xcc1a8b(0x147)][_0x55308e][_0xcc1a8b(0x3b3)]=setTimeout(function(_0x456b3b){var _0x36113f=_0xcc1a8b;_0x162eb3[_0x36113f(0x147)][_0x456b3b][_0x36113f(0x3b3)]=null;var _0x5182a7={};_0x5182a7[_0x36113f(0x1e2)]=_0x456b3b,_0x5182a7[_0x36113f(0x3de)]=_0x36113f(0x1a7),_0x5182a7[_0x36113f(0x134)]=_0x162eb3[_0x36113f(0x147)][_0x456b3b][_0x36113f(0x373)],_0x5182a7['session']=_0x162eb3[_0x36113f(0x147)][_0x456b3b][_0x36113f(0x157)],_0x162eb3['pcs'][_0x456b3b][_0x36113f(0x373)]=[],_0x162eb3[_0x36113f(0xf2)]?_0x162eb3[_0x36113f(0x52d)](JSON[_0x36113f(0x444)](_0x5182a7[_0x36113f(0x134)]))[_0x36113f(0x57e)](function(_0x28605b){var _0x284138=_0x36113f;if(_0x284138(0x21a)!==_0x284138(0x21a)){function _0x14b393(){_0x4e1f0e=_0x2d28a3;}}else _0x5182a7[_0x284138(0x134)]=_0x28605b[0x0],_0x5182a7[_0x284138(0x3f5)]=_0x28605b[0x1],_0x162eb3[_0x284138(0x3cd)](_0x5182a7);}):_0x162eb3[_0x36113f(0x3cd)](_0x5182a7);},0xc8,_0x55308e);}else{function _0x57c7e8(){var _0x1ce460=_0xcc1a8b;_0x495d01[_0x1ce460(0x53f)][_0x1ce460(0x25d)]=_0x1ce460(0x185);}}},_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x11e)]=function(_0x1f5392){var _0x3b7328=_0x1953f6;try{if(_0x3b7328(0x27d)!==_0x3b7328(0x27d)){function _0x3e563b(){var _0x3c7034=_0x3b7328;_0x94c21f[_0x3c7034(0x116)](_0x5eff18);}}else{if(this['iceConnectionState']==_0x3b7328(0x2f7)){if(_0x3b7328(0x3fd)===_0x3b7328(0x50a)){function _0x498cb2(){var _0x32871e=_0x3b7328;_0x2419bb[_0x32871e(0x3eb)]=_0x2be78f[_0x32871e(0x253)],_0x59baa8[_0x32871e(0x253)]=![],_0x6a74cb={},_0x11aa1c[_0x32871e(0x286)]=_0x16ce4f[_0x32871e(0x253)],_0x20823d['sendMessage'](_0x44aeab,_0x1d111e['soloChatUUID']);}}else log(_0x3b7328(0x2e5));}else{if(this['iceConnectionState']=='disconnected')log(_0x3b7328(0x53c));else{if(this[_0x3b7328(0x3b2)]=='failed')log(_0x3b7328(0x298));else this[_0x3b7328(0x3b2)]==_0x3b7328(0x4e6)?(log(_0x3b7328(0x206)),_0x162eb3[_0x3b7328(0x147)][_0x55308e]['getSenders']()[_0x3b7328(0x204)](_0x1eccec=>{var _0x2a5398=_0x3b7328;if(!_0x1eccec['track'])return;if(_0x1eccec[_0x2a5398(0x2ac)]['kind']===_0x2a5398(0x3cb)){_0x162eb3[_0x2a5398(0x147)][_0x55308e]['videoCodecs']=_0x1eccec[_0x2a5398(0x1cb)]()[_0x2a5398(0x548)],log(_0x162eb3['pcs'][_0x55308e][_0x2a5398(0x2a2)]);return;}else{if(_0x1eccec[_0x2a5398(0x2ac)]['kind']===_0x2a5398(0x25f)){_0x162eb3['pcs'][_0x55308e][_0x2a5398(0x582)]=_0x1eccec[_0x2a5398(0x1cb)]()[_0x2a5398(0x548)],log(_0x162eb3[_0x2a5398(0x147)][_0x55308e]['audioCodecs']);return;}}})):log(this['iceConnectionState']);}}}}catch(_0x5a5188){errorlog(_0x5a5188);}},_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x550)]=function(_0x5d2e1c){var _0x28cef1=_0x1953f6;switch(_0x162eb3[_0x28cef1(0x147)][_0x55308e][_0x28cef1(0x268)]){case'connected':log(_0x28cef1(0x379));if(_0x162eb3[_0x28cef1(0x3d8)]){if(_0x162eb3['ws']['readyState']!==0x1){_0x162eb3['ws'][_0x28cef1(0x556)]();break;}_0x162eb3['ws'][_0x28cef1(0x556)](),setTimeout(function(){var _0x2bdda6=_0x28cef1;_0x162eb3[_0x2bdda6(0x14e)]!=!![]&&warnUser('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!');},0x1);}break;case _0x28cef1(0x263):log(_0x28cef1(0x3b6));break;case _0x28cef1(0x162):warnlog(_0x28cef1(0x36b)),_0x162eb3['pcs'][_0x55308e][_0x28cef1(0x556)](),_0x162eb3[_0x28cef1(0x147)][_0x55308e]=null;_0x162eb3[_0x28cef1(0x3d8)]&&(!_0x162eb3[_0x28cef1(0x14e)]&&setTimeout(function(){var _0x23bf4f=_0x28cef1;warnUser(_0x23bf4f(0x423));},0x1));delete _0x162eb3[_0x28cef1(0x147)][_0x55308e],_0x162eb3[_0x28cef1(0x421)](),applySceneState();break;case _0x28cef1(0x2f7):warnlog(_0x28cef1(0x2c1)),_0x162eb3['pcs'][_0x55308e]=null;if(_0x162eb3[_0x28cef1(0x3d8)]){if(_0x28cef1(0x502)===_0x28cef1(0x3e0)){function _0x54c416(){var _0x54565e=_0x28cef1;_0x31e6c8(_0x54565e(0x529));}}else!_0x162eb3[_0x28cef1(0x14e)]&&setTimeout(function _0x5d05ff(){var _0x43b246=_0x28cef1;warnUser(_0x43b246(0x423));},0x1);}delete _0x162eb3[_0x28cef1(0x147)][_0x55308e],_0x162eb3[_0x28cef1(0x421)](),applySceneState();break;}},_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x45c)]=function(_0x336b1a){var _0x141b12=_0x1953f6;warnlog(_0x141b12(0x2a0)),_0x162eb3[_0x141b12(0x147)][_0x55308e]=null,delete _0x162eb3[_0x141b12(0x147)][_0x55308e],_0x162eb3['applySoloChat'](),applySceneState();},_0x162eb3[_0x1953f6(0x147)][_0x55308e][_0x1953f6(0x3ef)]=function _0x2f6f39(){var _0x39d2f1=_0x1953f6;log(_0x39d2f1(0x565));};}},_0x162eb3[_0x44a3fc(0x3e9)]=function(_0x262daa){var _0x101628=_0x44a3fc;if(_0x162eb3[_0x101628(0xf2)])_0x101628(0x3f5)in _0x262daa&&_0x162eb3[_0x101628(0x537)](_0x262daa[_0x101628(0x16b)],_0x262daa[_0x101628(0x3f5)])[_0x101628(0x57e)](function(_0x377477){var _0x52d91e=_0x101628;_0x262daa[_0x52d91e(0x16b)]=JSON[_0x52d91e(0x4aa)](_0x377477);if(_0x262daa[_0x52d91e(0x16b)]['type']==_0x52d91e(0x587))_0x162eb3[_0x52d91e(0x169)](_0x262daa),_0x162eb3['connectPeer'](_0x262daa);else try{var _0x12359e=_0x162eb3[_0x52d91e(0x1e5)];if((iOS||iPad)&&_0x162eb3['pcs'][_0x262daa['UUID']][_0x52d91e(0x466)]==!![]&&_0x162eb3[_0x52d91e(0x147)][_0x262daa[_0x52d91e(0x1e2)]][_0x52d91e(0x26c)]==![]){if(_0x12359e===![]||_0x12359e>_0x162eb3[_0x52d91e(0x200)]){var _0xb32814=Object[_0x52d91e(0x4bb)](_0x162eb3[_0x52d91e(0x147)])[_0x52d91e(0x3f4)];_0xb32814>0x3?_0x12359e=_0x162eb3[_0x52d91e(0x121)]:_0x12359e=_0x162eb3[_0x52d91e(0x200)];}_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)]=CodecsHandler[_0x52d91e(0x397)](_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)],_0x52d91e(0x287)),_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)]=CodecsHandler[_0x52d91e(0x38e)](_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)],{'min':parseInt(_0x12359e/0x2)||0x1,'max':_0x12359e}),_0x12359e=![];}else _0x162eb3[_0x52d91e(0x147)][_0x262daa[_0x52d91e(0x1e2)]][_0x52d91e(0x466)]==!![]&&(_0x12359e!==![]?_0x162eb3[_0x52d91e(0x4c0)]!==![]&&(_0x162eb3[_0x52d91e(0x4c0)]<_0x12359e&&(_0x12359e=_0x162eb3['roombitrate'])):_0x12359e=_0x162eb3[_0x52d91e(0x4c0)]);if(_0x12359e){var _0x22228d=CodecsHandler[_0x52d91e(0x3c2)](_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)])||0x9c4;log('BITRATE:\x20'+_0x22228d);if(_0x22228d>_0x12359e){var _0x3cd884=CodecsHandler['getOpusBitrate'](_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)])||0x0;_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)]=CodecsHandler[_0x52d91e(0x38e)](_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)],{'min':parseInt(_0x12359e/0xa)||0x1,'max':parseInt(_0x12359e+_0x3cd884/0x400)}),_0x162eb3[_0x52d91e(0x147)][_0x262daa[_0x52d91e(0x1e2)]]['setBitrate']=_0x12359e;}else _0x162eb3[_0x52d91e(0x147)][_0x262daa[_0x52d91e(0x1e2)]]['setBitrate']=_0x22228d;}else{if(_0x162eb3['outboundVideoBitrate']!==![]){var _0x22228d=CodecsHandler[_0x52d91e(0x3c2)](_0x262daa[_0x52d91e(0x16b)]['sdp']);if(_0x22228d===![]){var _0x3cd884=CodecsHandler[_0x52d91e(0x508)](_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)])||0x0;_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)]=CodecsHandler[_0x52d91e(0x38e)](_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)],{'min':parseInt(_0x162eb3[_0x52d91e(0x1ee)]/0xa)||0x1,'max':parseInt(_0x162eb3[_0x52d91e(0x1ee)]+_0x3cd884/0x400)});}else _0x162eb3[_0x52d91e(0x147)][_0x262daa[_0x52d91e(0x1e2)]][_0x52d91e(0x2a1)]=_0x22228d;}else _0x162eb3[_0x52d91e(0x147)][_0x262daa[_0x52d91e(0x1e2)]][_0x52d91e(0x2a1)]=CodecsHandler[_0x52d91e(0x3c2)](_0x262daa[_0x52d91e(0x16b)]['sdp']);}_0x162eb3[_0x52d91e(0xdf)]&&(_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)]=CodecsHandler[_0x52d91e(0x195)](_0x262daa[_0x52d91e(0x16b)][_0x52d91e(0x457)],{'maxaveragebitrate':_0x162eb3[_0x52d91e(0xdf)]*0x400,'cbr':_0x162eb3[_0x52d91e(0x44e)]}));if(_0x52d91e(0x157)in _0x262daa&&_0x262daa[_0x52d91e(0x157)]!=_0x162eb3[_0x52d91e(0x147)][_0x262daa[_0x52d91e(0x1e2)]][_0x52d91e(0x157)]){errorlog(_0x52d91e(0x485));return;}_0x162eb3['pcs'][_0x262daa[_0x52d91e(0x1e2)]][_0x52d91e(0x312)](_0x262daa[_0x52d91e(0x16b)])[_0x52d91e(0x57e)]()['catch'](errorlog);}catch(_0x27ef17){errorlog(_0x27ef17);}});else{if(_0x101628(0x27c)!=='ogWxJ'){if(_0x262daa[_0x101628(0x16b)]['type']=='offer')_0x162eb3[_0x101628(0x169)](_0x262daa),_0x162eb3[_0x101628(0x3e2)](_0x262daa);else try{var _0x313ea9=_0x162eb3[_0x101628(0x1e5)];if((iOS||iPad)&&_0x162eb3['pcs'][_0x262daa['UUID']][_0x101628(0x466)]==!![]&&_0x162eb3[_0x101628(0x147)][_0x262daa[_0x101628(0x1e2)]][_0x101628(0x26c)]==![]){if(_0x313ea9===![]||_0x313ea9>_0x162eb3[_0x101628(0x200)]){var _0x3e39fb=Object[_0x101628(0x4bb)](_0x162eb3[_0x101628(0x147)])['length'];_0x3e39fb>0x3?_0x313ea9=_0x162eb3['lowiosviewers']:_0x313ea9=_0x162eb3[_0x101628(0x200)];}_0x262daa[_0x101628(0x16b)]['sdp']=CodecsHandler[_0x101628(0x397)](_0x262daa[_0x101628(0x16b)]['sdp'],_0x101628(0x287)),_0x262daa[_0x101628(0x16b)][_0x101628(0x457)]=CodecsHandler[_0x101628(0x38e)](_0x262daa[_0x101628(0x16b)][_0x101628(0x457)],{'min':parseInt(_0x313ea9/0x2)||0x1,'max':_0x313ea9}),_0x313ea9=![];}else _0x162eb3['pcs'][_0x262daa[_0x101628(0x1e2)]][_0x101628(0x466)]==!![]&&(_0x313ea9!==![]?_0x162eb3[_0x101628(0x4c0)]!==![]&&(_0x162eb3[_0x101628(0x4c0)]<_0x313ea9&&(_0x313ea9=_0x162eb3['roombitrate'])):_0x313ea9=_0x162eb3[_0x101628(0x4c0)]);if(_0x313ea9){var _0x5ede7a=CodecsHandler['getVideoBitrates'](_0x262daa[_0x101628(0x16b)]['sdp'])||0x9c4;log(_0x101628(0x292)+_0x5ede7a);if(_0x5ede7a>_0x313ea9){var _0x56274f=CodecsHandler[_0x101628(0x508)](_0x262daa[_0x101628(0x16b)][_0x101628(0x457)])||0x0;_0x262daa[_0x101628(0x16b)][_0x101628(0x457)]=CodecsHandler[_0x101628(0x38e)](_0x262daa[_0x101628(0x16b)][_0x101628(0x457)],{'min':parseInt(_0x313ea9/0xa)||0x1,'max':parseInt(_0x313ea9+_0x56274f/0x400)});}}else{if(_0x162eb3[_0x101628(0x1ee)]!==![]){var _0x5ede7a=CodecsHandler[_0x101628(0x3c2)](_0x262daa[_0x101628(0x16b)][_0x101628(0x457)]);if(_0x5ede7a===![]){var _0x56274f=CodecsHandler[_0x101628(0x508)](_0x262daa[_0x101628(0x16b)][_0x101628(0x457)])||0x0;_0x262daa[_0x101628(0x16b)][_0x101628(0x457)]=CodecsHandler[_0x101628(0x38e)](_0x262daa[_0x101628(0x16b)][_0x101628(0x457)],{'min':parseInt(_0x162eb3[_0x101628(0x1ee)]/0xa)||0x1,'max':parseInt(_0x162eb3[_0x101628(0x1ee)]+_0x56274f/0x400)});}}}_0x162eb3['outboundAudioBitrate']&&(_0x262daa['description'][_0x101628(0x457)]=CodecsHandler[_0x101628(0x195)](_0x262daa[_0x101628(0x16b)]['sdp'],{'maxaveragebitrate':_0x162eb3[_0x101628(0xdf)]*0x400,'cbr':_0x162eb3[_0x101628(0x44e)]}));if(_0x101628(0x157)in _0x262daa&&_0x262daa[_0x101628(0x157)]!=_0x162eb3['pcs'][_0x262daa[_0x101628(0x1e2)]][_0x101628(0x157)]){errorlog(_0x101628(0x485));return;}_0x162eb3[_0x101628(0x147)][_0x262daa[_0x101628(0x1e2)]]['setRemoteDescription'](_0x262daa[_0x101628(0x16b)])[_0x101628(0x57e)]()[_0x101628(0x19f)](errorlog);}catch(_0xccc154){errorlog(_0xccc154);}}else{function _0x46d421(){var _0x1b4522=_0x101628;_0x8ef5f[_0x1b4522(0x1e2)]=_0x3f8e4d,_0x46a477(_0x1b4522(0x56a)),_0x2dd2b1['processIceBundle'](_0x287bda);}}}},_0x162eb3[_0x44a3fc(0x3d9)]=function(_0x1a087e){var _0x249697=_0x44a3fc;_0x162eb3[_0x249697(0xf2)]&&_0x249697(0x3f5)in _0x1a087e?_0x162eb3['decryptMessage'](_0x1a087e[_0x249697(0x17d)],_0x1a087e[_0x249697(0x3f5)])['then'](function(_0xbd1c19){var _0x465099=_0x249697;_0x1a087e[_0x465099(0x17d)]=JSON[_0x465099(0x4aa)](_0xbd1c19),_0x162eb3['processIce2'](_0x1a087e);}):_0x162eb3[_0x249697(0x39d)](_0x1a087e);},_0x162eb3[_0x44a3fc(0x39d)]=function(_0x2a1548){var _0x3467e8=_0x44a3fc;try{if(_0x162eb3[_0x3467e8(0x2c8)]){if(_0x2a1548[_0x3467e8(0x17d)][_0x3467e8(0x17d)][_0x3467e8(0x549)](_0x162eb3[_0x3467e8(0x2c8)])===-0x1){log(_0x3467e8(0x52c)),log(_0x2a1548[_0x3467e8(0x17d)]);return;}else log(_0x3467e8(0x320)),log(_0x2a1548[_0x3467e8(0x17d)]);}}catch(_0x557016){errorlog(_0x557016);}if(_0x2a1548[_0x3467e8(0x17d)]&&_0x3467e8(0x17d)in _0x2a1548[_0x3467e8(0x17d)]&&_0x2a1548[_0x3467e8(0x17d)]['candidate']=='')return;if(_0x2a1548['UUID']in _0x162eb3[_0x3467e8(0x147)]&&_0x2a1548[_0x3467e8(0x3de)]==_0x3467e8(0x4cf)){log(_0x3467e8(0x4eb));if(!(_0x2a1548[_0x3467e8(0x1e2)]in _0x162eb3['pcs'])){errorlog(_0x3467e8(0x41e));return;}if('session'in _0x2a1548&&_0x162eb3[_0x3467e8(0x147)][_0x2a1548[_0x3467e8(0x1e2)]][_0x3467e8(0x157)]!=_0x2a1548[_0x3467e8(0x157)]){errorlog(_0x3467e8(0xd7));return;}_0x162eb3['pcs'][_0x2a1548[_0x3467e8(0x1e2)]][_0x3467e8(0x364)](_0x2a1548[_0x3467e8(0x17d)])[_0x3467e8(0x57e)]()[_0x3467e8(0x19f)](function(_0x51d653){errorlog(_0x51d653),errorlog(_0x2a1548);});}else{if(_0x2a1548[_0x3467e8(0x1e2)]in _0x162eb3[_0x3467e8(0x1f4)]&&_0x2a1548[_0x3467e8(0x3de)]==_0x3467e8(0x1a7)){log(_0x3467e8(0x18f));if(!(_0x2a1548[_0x3467e8(0x1e2)]in _0x162eb3['rpcs'])){errorlog(_0x3467e8(0x41e));return;}if(_0x3467e8(0x157)in _0x2a1548&&_0x162eb3['rpcs'][_0x2a1548['UUID']][_0x3467e8(0x157)]!=_0x2a1548['session']){errorlog(_0x3467e8(0xd7));return;}if(_0x162eb3[_0x3467e8(0x1f4)][_0x2a1548['UUID']]===null)return;_0x162eb3[_0x3467e8(0x1f4)][_0x2a1548[_0x3467e8(0x1e2)]]['addIceCandidate'](_0x2a1548[_0x3467e8(0x17d)])[_0x3467e8(0x57e)]()['catch'](function(_0xbd56ae){errorlog(_0xbd56ae),errorlog(_0x2a1548);});}else{if(_0x3467e8(0x177)!==_0x3467e8(0x386))errorlog(_0x2a1548),errorlog('ICE\x20DID\x20NOT\x20FIND\x20A\x20PC\x20OPTION?');else{function _0x50072d(){var _0x47493d=_0x3467e8;_0xfc5bef[_0x47493d(0x1f4)][_0x2ff6ce][_0x47493d(0x340)][_0x47493d(0x21e)]['display']=_0x47493d(0x545),_0x265e03=!![];}}}}},_0x162eb3['processIceBundle']=function(_0x32d3d2){var _0x48600c=_0x44a3fc;if(_0x162eb3['password']&&_0x48600c(0x3f5)in _0x32d3d2)_0x162eb3[_0x48600c(0x537)](_0x32d3d2[_0x48600c(0x134)],_0x32d3d2[_0x48600c(0x3f5)])[_0x48600c(0x57e)](function(_0x5d58f5){var _0x48cde2=_0x48600c;_0x32d3d2['candidates']=JSON[_0x48cde2(0x4aa)](_0x5d58f5);var _0xc79381={};_0xc79381[_0x48cde2(0x1e2)]=_0x32d3d2['UUID'],_0xc79381[_0x48cde2(0x3de)]=_0x32d3d2[_0x48cde2(0x3de)];for(var _0x433c51=0x0;_0x433c51<_0x32d3d2[_0x48cde2(0x134)]['length'];_0x433c51++){_0xc79381[_0x48cde2(0x17d)]=_0x32d3d2[_0x48cde2(0x134)][_0x433c51],_0x162eb3[_0x48cde2(0x39d)](_0xc79381);}});else{var _0x2d2690={};_0x2d2690[_0x48600c(0x1e2)]=_0x32d3d2['UUID'],_0x2d2690[_0x48600c(0x3de)]=_0x32d3d2[_0x48600c(0x3de)];for(var _0x49b2ee=0x0;_0x49b2ee<_0x32d3d2['candidates'][_0x48600c(0x3f4)];_0x49b2ee++){_0x2d2690[_0x48600c(0x17d)]=_0x32d3d2['candidates'][_0x49b2ee],_0x162eb3['processIce2'](_0x2d2690);}}},_0x162eb3[_0x44a3fc(0x3e2)]=function(_0x591f07){var _0x136723=_0x44a3fc;_0x162eb3[_0x136723(0x1f4)][_0x591f07[_0x136723(0x1e2)]][_0x136723(0x312)](_0x591f07[_0x136723(0x16b)])[_0x136723(0x57e)](function(){var _0x51132c=_0x136723;if(_0x162eb3[_0x51132c(0x1f4)][_0x591f07[_0x51132c(0x1e2)]]['remoteDescription'][_0x51132c(0x3de)]===_0x51132c(0x587))_0x162eb3[_0x51132c(0x1f4)][_0x591f07[_0x51132c(0x1e2)]][_0x51132c(0x10b)]()[_0x51132c(0x57e)](function(_0x47f31a){var _0x4570f7=_0x51132c;if(!_0x162eb3[_0x4570f7(0x1b6)]&&_0x162eb3[_0x4570f7(0x133)]==0x5)_0x47f31a[_0x4570f7(0x457)]=CodecsHandler[_0x4570f7(0x195)](_0x47f31a[_0x4570f7(0x457)],{'stereo':0x1,'maxaveragebitrate':(_0x162eb3[_0x4570f7(0x4f5)]||0x100)*0x400,'cbr':_0x162eb3[_0x4570f7(0x44e)],'useinbandfec':0x1,'maxptime':_0x162eb3[_0x4570f7(0x3ee)],'minptime':_0x162eb3['minptime'],'ptime':_0x162eb3[_0x4570f7(0x515)]});else{if(_0x162eb3[_0x4570f7(0x133)]==0x1||_0x162eb3[_0x4570f7(0x133)]==0x2||_0x162eb3[_0x4570f7(0x133)]==0x5){if(_0x4570f7(0x149)!==_0x4570f7(0x149)){function _0x3cb7a4(){var _0x59c50d=_0x4570f7;return _0x4e58aa=new _0x4045d4(_0x71ea66),_0x4418af&&(_0x52e7d1=_0x3b1cb4[_0x59c50d(0x32a)](0x0,_0x1cb132(_0x4f3db5(_0x246a27)/0x2))),_0x47a17c=_0x6da532(_0x5ea86c),_0x4169ec;}}else _0x47f31a[_0x4570f7(0x457)]=CodecsHandler[_0x4570f7(0x195)](_0x47f31a[_0x4570f7(0x457)],{'stereo':0x1,'maxaveragebitrate':(_0x162eb3[_0x4570f7(0x4f5)]||0x100)*0x400,'cbr':_0x162eb3[_0x4570f7(0x44e)],'useinbandfec':0x1,'maxptime':_0x162eb3[_0x4570f7(0x3ee)],'minptime':_0x162eb3[_0x4570f7(0x480)],'ptime':_0x162eb3[_0x4570f7(0x515)]});}else{if(_0x162eb3['stereo']==0x4)_0x47f31a['sdp']=CodecsHandler[_0x4570f7(0x195)](_0x47f31a['sdp'],{'stereo':0x2,'maxaveragebitrate':(_0x162eb3[_0x4570f7(0x4f5)]||0x100)*0x400,'cbr':_0x162eb3[_0x4570f7(0x44e)],'useinbandfec':0x1,'maxptime':_0x162eb3[_0x4570f7(0x3ee)],'minptime':_0x162eb3[_0x4570f7(0x480)],'ptime':_0x162eb3[_0x4570f7(0x515)]});else _0x162eb3[_0x4570f7(0x4f5)]&&(_0x47f31a[_0x4570f7(0x457)]=CodecsHandler[_0x4570f7(0x195)](_0x47f31a[_0x4570f7(0x457)],{'maxaveragebitrate':_0x162eb3[_0x4570f7(0x4f5)]*0x400,'cbr':_0x162eb3['cbr'],'useinbandfec':0x1,'maxptime':_0x162eb3[_0x4570f7(0x3ee)],'minptime':_0x162eb3[_0x4570f7(0x480)],'ptime':_0x162eb3[_0x4570f7(0x515)]}));}}if(_0x162eb3['codec'])_0x47f31a[_0x4570f7(0x457)]=CodecsHandler[_0x4570f7(0x397)](_0x47f31a['sdp'],_0x162eb3['codec']);else _0x162eb3[_0x4570f7(0x140)]!==![]&&(_0x47f31a[_0x4570f7(0x457)]=CodecsHandler[_0x4570f7(0x397)](_0x47f31a[_0x4570f7(0x457)],_0x4570f7(0x2b5)));_0x162eb3[_0x4570f7(0x49b)]&&(log(_0x47f31a[_0x4570f7(0x457)]),_0x47f31a[_0x4570f7(0x457)]=CodecsHandler['disableNACK'](_0x47f31a[_0x4570f7(0x457)]));_0x162eb3[_0x4570f7(0x13f)]&&(_0x47f31a[_0x4570f7(0x457)]=CodecsHandler['disablePLI'](_0x47f31a[_0x4570f7(0x457)]));_0x162eb3[_0x4570f7(0x35b)]&&(_0x47f31a[_0x4570f7(0x457)]=CodecsHandler[_0x4570f7(0x2c9)](_0x47f31a[_0x4570f7(0x457)]));if(_0x162eb3[_0x4570f7(0x1f4)][_0x591f07[_0x4570f7(0x1e2)]]['manualBandwidth'])log('bit\x20rate\x20being\x20munged'),_0x47f31a[_0x4570f7(0x457)]=_0x2bcdde(_0x47f31a[_0x4570f7(0x457)],_0x162eb3['rpcs'][_0x591f07[_0x4570f7(0x1e2)]][_0x4570f7(0x538)]);else _0x162eb3[_0x4570f7(0x22c)]&&(log(_0x4570f7(0x1a4)),_0x47f31a[_0x4570f7(0x457)]=_0x2bcdde(_0x47f31a[_0x4570f7(0x457)],_0x162eb3[_0x4570f7(0x22c)]));return _0x162eb3[_0x4570f7(0x1f4)][_0x591f07[_0x4570f7(0x1e2)]][_0x4570f7(0x21f)](_0x47f31a);})[_0x51132c(0x57e)](function _0x3bc531(){var _0x57265b=_0x51132c;log(_0x57265b(0x10e));var _0x2b4f2b={};_0x2b4f2b[_0x57265b(0x1e2)]=_0x591f07[_0x57265b(0x1e2)],_0x2b4f2b[_0x57265b(0x16b)]=_0x162eb3['rpcs'][_0x591f07[_0x57265b(0x1e2)]][_0x57265b(0x156)],_0x2b4f2b[_0x57265b(0x157)]=_0x162eb3[_0x57265b(0x1f4)][_0x591f07['UUID']][_0x57265b(0x157)],_0x162eb3['password']?_0x162eb3[_0x57265b(0x52d)](JSON['stringify'](_0x2b4f2b[_0x57265b(0x16b)]))[_0x57265b(0x57e)](function(_0x1f718){var _0x548a85=_0x57265b;_0x2b4f2b[_0x548a85(0x16b)]=_0x1f718[0x0],_0x2b4f2b[_0x548a85(0x3f5)]=_0x1f718[0x1],_0x162eb3['anyrequest'](_0x2b4f2b);}):_0x162eb3[_0x57265b(0x577)](_0x2b4f2b);})[_0x51132c(0x19f)](errorlog);else _0x162eb3['rpcs'][_0x591f07[_0x51132c(0x1e2)]][_0x51132c(0x13a)][_0x51132c(0x3de)]===_0x51132c(0x509)&&errorlog(_0x51132c(0x440));})[_0x136723(0x19f)](errorlog);},_0x162eb3[_0x44a3fc(0x169)]=function(_0x487cb5){var _0x4f7b4e=_0x44a3fc,_0x4f97d2=_0x487cb5[_0x4f7b4e(0x1e2)];if(_0x4f97d2 in _0x162eb3[_0x4f7b4e(0x1f4)]){log('RTC\x20connection\x20is\x20ALREADY\x20ready;\x20we\x20can\x20already\x20accept\x20answers'),log(_0x487cb5);if(_0x4f7b4e(0x157)in _0x487cb5){if(_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x157)]==_0x487cb5[_0x4f7b4e(0x157)]){if(_0x4f7b4e(0x4b7)!==_0x4f7b4e(0x4b7)){function _0x2e3ae7(){var _0x299ff7=_0x4f7b4e;_0xa1c77b[_0x299ff7(0x147)][_0x9bc98c]['iceTimer']=null;var _0x47a71a={};_0x47a71a['UUID']=_0x549a9c,_0x47a71a[_0x299ff7(0x3de)]=_0x299ff7(0x1a7),_0x47a71a[_0x299ff7(0x134)]=_0x1d88d0[_0x299ff7(0x147)][_0x12cef1]['iceBundle'],_0x47a71a[_0x299ff7(0x157)]=_0x686ed5[_0x299ff7(0x147)][_0x57fc8c]['session'],_0x5f0b64[_0x299ff7(0x147)][_0x5ebf3d][_0x299ff7(0x373)]=[],_0x56294d[_0x299ff7(0xf2)]?_0x51acac[_0x299ff7(0x52d)](_0x685ddf[_0x299ff7(0x444)](_0x47a71a[_0x299ff7(0x134)]))[_0x299ff7(0x57e)](function(_0x3bebca){var _0x4276e9=_0x299ff7;_0x47a71a[_0x4276e9(0x134)]=_0x3bebca[0x0],_0x47a71a[_0x4276e9(0x3f5)]=_0x3bebca[0x1],_0x27a545[_0x4276e9(0x3cd)](_0x47a71a);}):_0x50e4e9[_0x299ff7(0x3cd)](_0x47a71a);}}else{log(_0x4f7b4e(0x465));return;}}else warnlog(_0x4f7b4e(0x4c2));}}else log(_0x4f7b4e(0x28d));try{for(var _0x5c9c8a in _0x162eb3[_0x4f7b4e(0x1f4)]){if(_0x162eb3[_0x4f7b4e(0x1f4)][_0x5c9c8a][_0x4f7b4e(0x34f)]==_0x487cb5[_0x4f7b4e(0x34f)]){_0x162eb3['rpcs'][_0x5c9c8a][_0x4f7b4e(0x340)]&&(_0x162eb3[_0x4f7b4e(0x1f4)][_0x5c9c8a][_0x4f7b4e(0x340)][_0x4f7b4e(0x21e)][_0x4f7b4e(0x1fb)]=_0x4f7b4e(0x277));_0x162eb3[_0x4f7b4e(0x1f4)][_0x5c9c8a]=null,delete _0x162eb3[_0x4f7b4e(0x1f4)][_0x5c9c8a],warnlog(_0x4f7b4e(0x229));if(_0x162eb3[_0x4f7b4e(0x1b6)]){if('YjAHs'!==_0x4f7b4e(0x585)){function _0x4bd232(){var _0x456ce3=_0x4f7b4e;_0x44269b[_0x456ce3(0x2fe)]==0x1f7&&(_0x51811d==![]&&(_0x3816e6(_0x54965f[_0x456ce3(0x351)]),!_0x1259e8[_0x456ce3(0x14e)]&&_0x22228f('Failed\x20to\x20connect\x20to\x20service:\x20Error\x20503 Possibly\x20too\x20many\x20connections\x20from\x20the\x20same\x20address\x20tried\x20to\x20connect. Visit\x20https://discord.obs.ninja\x20for\x20support.',0x7530)));}}else try{document[_0x4f7b4e(0x367)](_0x4f7b4e(0x22e)+_0x5c9c8a)&&getById(_0x4f7b4e(0x22e)+_0x5c9c8a)['parentNode'][_0x4f7b4e(0x45f)](getById('container_'+_0x5c9c8a));}catch(_0x246eb9){errorlog(_0x246eb9);}}}}document[_0x4f7b4e(0x367)](_0x4f7b4e(0x181))&&document[_0x4f7b4e(0x367)](_0x4f7b4e(0x181))[_0x4f7b4e(0x23c)][_0x4f7b4e(0x45f)](document['getElementById'](_0x4f7b4e(0x181)));}catch(_0x12aee5){errorlog(_0x12aee5);}if(_0x162eb3[_0x4f7b4e(0x12a)]!==![]){if(Object[_0x4f7b4e(0x4bb)](_0x162eb3[_0x4f7b4e(0x1f4)])[_0x4f7b4e(0x3f4)]>=_0x162eb3[_0x4f7b4e(0x12a)]){delete _0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2],updateUserList(),warnlog(_0x4f7b4e(0x3e1));return;}}else{if(_0x162eb3[_0x4f7b4e(0x153)]!==![]){if(Object[_0x4f7b4e(0x4bb)](_0x162eb3[_0x4f7b4e(0x1f4)])[_0x4f7b4e(0x3f4)]+Object[_0x4f7b4e(0x4bb)](_0x162eb3['pcs'])[_0x4f7b4e(0x3f4)]>=_0x162eb3[_0x4f7b4e(0x153)]){if('ZpjDD'===_0x4f7b4e(0xf4)){function _0x438a05(){var _0x3b1dd3=_0x4f7b4e;_0x2f56d1[_0x3b1dd3(0x116)](_0x45a731);}}else{delete _0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2],updateUserList(),warnlog(_0x4f7b4e(0x3e1));return;}}}}if(_0x162eb3[_0x4f7b4e(0x46f)]){if(_0x162eb3[_0x4f7b4e(0x1b6)])!(_0x4f97d2 in _0x162eb3[_0x4f7b4e(0x147)])&&_0x162eb3['offerSDP'](_0x4f97d2);else{if(_0x162eb3[_0x4f7b4e(0x37c)]!==_0x4f97d2)return;}}_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2]=new RTCPeerConnection(_0x162eb3[_0x4f7b4e(0x52b)]);if(_0x162eb3[_0x4f7b4e(0x3d8)]){if(Object[_0x4f7b4e(0x4bb)](_0x162eb3['rpcs'])[_0x4f7b4e(0x3f4)]>0x1){warnlog(_0x4f7b4e(0x49e)),log(_0x162eb3[_0x4f7b4e(0x1f4)]),delete _0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2],updateUserList();return;}else warnlog(_0x4f7b4e(0x58b));}_0x487cb5[_0x4f7b4e(0x34f)]in _0x162eb3[_0x4f7b4e(0x3b8)]&&delete _0x162eb3[_0x4f7b4e(0x3b8)][_0x487cb5[_0x4f7b4e(0x34f)]];_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x34f)]=_0x487cb5[_0x4f7b4e(0x34f)];_0x487cb5[_0x4f7b4e(0x157)]?_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x157)]=_0x487cb5[_0x4f7b4e(0x157)]:_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x157)]=null;_0x162eb3['rpcs'][_0x4f97d2]['activelySpeaking']=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x14f)]={},_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x14f)][_0x4f7b4e(0x1cf)]=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2]['bandwidth']=-0x1,_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x3d5)]=![],_0x162eb3['rpcs'][_0x4f97d2]['targetBandwidth']=-0x1,_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x538)]=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x340)]=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x31d)]=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x1ea)]=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x1ae)]=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2]['directorVideoMuted']=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x37b)]=![],_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x167)]=![],_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x144)]=null,_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x2d0)]={},_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2]['scaleHeight']=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x295)]=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x3d0)]=null,_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x4f4)]=0x64,_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2]['directorMutedState']=0x0,_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x19c)]=0x0,_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x350)]=0x0,_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x2fa)]=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2]['order']=![],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2]['canvasCtx']=null,_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x29e)]=null,_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x1ed)]={},_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2]['iframeSrc']=![],_0x162eb3['rpcs'][_0x4f97d2]['iframeEle']=![],_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x13c)]=Date[_0x4f7b4e(0x1b9)]();var _0x1b0808='';_0x162eb3[_0x4f7b4e(0x170)]&&(_0x1b0808=_0x162eb3[_0x4f7b4e(0x170)]);if(_0x162eb3[_0x4f7b4e(0x1b6)]){if(_0x4f7b4e(0x18d)!==_0x4f7b4e(0x18d)){function _0x6757ae(){var _0x40e18d=_0x4f7b4e;_0x501ab5[_0x40e18d(0x367)](_0x40e18d(0x22e)+this[_0x40e18d(0x1e2)])&&_0x423947('container_'+this[_0x40e18d(0x1e2)])[_0x40e18d(0x23c)][_0x40e18d(0x45f)](_0x4c6999(_0x40e18d(0x22e)+this[_0x40e18d(0x1e2)]));}}else{var _0x29d2b7='';_0x162eb3['pie']&&(_0x162eb3[_0x4f7b4e(0x285)]!==!![]?_0x29d2b7='&pie='+_0x162eb3['pie']:_0x29d2b7=_0x4f7b4e(0x1e3));var _0x4d6a24='';if(_0x162eb3[_0x4f7b4e(0xf2)]){if('RIMsk'==='RIMsk')_0x162eb3[_0x4f7b4e(0x3a5)]===![]&&(_0x4d6a24=_0x4f7b4e(0x56c)+_0x162eb3['password']);else{function _0x38384e(){return;}}}createControlBox(_0x4f97d2,_0x4f7b4e(0x4a7)+location[_0x4f7b4e(0x272)]+location['pathname']+_0x4f7b4e(0x387)+_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x34f)]+_0x4f7b4e(0x311)+_0x1b0808+_0x4f7b4e(0x2b4)+_0x162eb3[_0x4f7b4e(0x27b)]+_0x4d6a24+_0x29d2b7,_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x34f)]);}}_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x1e2)]=_0x4f97d2;if(_0x4f7b4e(0x34f)in _0x487cb5){_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x34f)]=_0x487cb5['streamID'];try{if(_0x162eb3[_0x4f7b4e(0x1ca)]){if(_0x162eb3[_0x4f7b4e(0x1ca)]['includes'](_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x34f)])){if(_0x162eb3[_0x4f7b4e(0x54e)]!==![]){let _0x13daed=_0x162eb3[_0x4f7b4e(0x1ca)][_0x4f7b4e(0x549)](_0x162eb3['rpcs'][_0x4f97d2]['streamID']);_0x162eb3[_0x4f7b4e(0x54e)][_0x4f7b4e(0x3f4)]>_0x13daed&&(_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x538)]=parseInt(_0x162eb3[_0x4f7b4e(0x54e)][_0x13daed]),_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x538)]<=0x0&&(_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x538)]=![]));}}}}catch(_0x389cc7){errorlog(_0x389cc7);}}_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x45c)]=function(_0x1de84c){var _0x3aa45e=_0x4f7b4e;try{var _0x112d07=this[_0x3aa45e(0x34f)];}catch(_0x25e56a){}if(!_0x162eb3[_0x3aa45e(0x1b6)]){if(_0x162eb3[_0x3aa45e(0x145)]!==![]||_0x162eb3[_0x3aa45e(0x27b)]!==![])try{if(_0x3aa45e(0x123)!=='Uduly'){function _0x28af4c(){var _0xd0df47=_0x3aa45e;_0x62a70d['encodings'][0x0][_0xd0df47(0x3b0)]=!![];}}else _0x162eb3[_0x3aa45e(0x1f4)][this[_0x3aa45e(0x1e2)]][_0x3aa45e(0x340)]&&(_0x162eb3[_0x3aa45e(0x1f4)][this[_0x3aa45e(0x1e2)]][_0x3aa45e(0x340)][_0x3aa45e(0x21e)][_0x3aa45e(0x1fb)]=_0x3aa45e(0x277)),setTimeout(function(){updateMixer();},0x1);}catch(_0x10ad29){}}try{document[_0x3aa45e(0x367)]('container_'+this[_0x3aa45e(0x1e2)])&&getById(_0x3aa45e(0x22e)+this[_0x3aa45e(0x1e2)])[_0x3aa45e(0x23c)][_0x3aa45e(0x45f)](getById(_0x3aa45e(0x22e)+this[_0x3aa45e(0x1e2)]));}catch(_0x2602bd){errorlog(_0x2602bd);}try{this[_0x3aa45e(0x3d0)]&&this[_0x3aa45e(0x3d0)]['getTracks']()[_0x3aa45e(0x204)](function(_0x4b75ec){var _0x3a4907=_0x3aa45e;_0x4b75ec[_0x3a4907(0x529)]();});}catch(_0x21714b){errorlog(_0x21714b);}try{this[_0x3aa45e(0x228)][_0x3aa45e(0x556)]();}catch(_0x2db421){errorlog(_0x2db421);}try{_0x162eb3[_0x3aa45e(0x1f4)][this[_0x3aa45e(0x1e2)]]=null,delete _0x162eb3[_0x3aa45e(0x1f4)][this['UUID']];}catch(_0x207ea7){errorlog(_0x207ea7);}warnlog(_0x3aa45e(0x229));try{_0x162eb3[_0x3aa45e(0x39b)](_0x112d07);}catch(_0xa6af72){errorlog(_0x3aa45e(0x45a)),errorlog(_0xa6af72);}updateUserList();},_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x3b3)]=null,_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x373)]=[],_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x4d4)]=function(_0x32e380){var _0x61f007=_0x4f7b4e;if(_0x32e380['candidate']==null){log(_0x61f007(0x569));return;}try{if(_0x162eb3[_0x61f007(0x2c8)]){if(_0x32e380[_0x61f007(0x17d)][_0x61f007(0x17d)][_0x61f007(0x549)](_0x162eb3['icefilter'])===-0x1){log(_0x61f007(0x52c));return;}else log(_0x32e380[_0x61f007(0x17d)]);}}catch(_0x5add9a){errorlog(_0x5add9a);}if(_0x162eb3[_0x61f007(0x1f4)][_0x4f97d2]['iceTimer']!==null){if(_0x61f007(0x58a)==='nKxun'){function _0x457964(){_0x26c88e('successfully\x20requested\x20audio\x20and\x20video');}}else{_0x162eb3[_0x61f007(0x1f4)][_0x4f97d2][_0x61f007(0x373)][_0x61f007(0x21d)](_0x32e380[_0x61f007(0x17d)]);return;}}_0x162eb3[_0x61f007(0x1f4)][_0x4f97d2][_0x61f007(0x373)][_0x61f007(0x21d)](_0x32e380[_0x61f007(0x17d)]),_0x162eb3['rpcs'][_0x4f97d2]['iceTimer']=setTimeout(function(){var _0x16b5e2=_0x61f007;if(!(_0x4f97d2 in _0x162eb3[_0x16b5e2(0x1f4)]))return;_0x162eb3[_0x16b5e2(0x1f4)][_0x4f97d2][_0x16b5e2(0x3b3)]=null;if(_0x162eb3[_0x16b5e2(0x1f4)][_0x4f97d2]['iceBundle']==[])return;var _0x38b7d1={};_0x38b7d1[_0x16b5e2(0x1e2)]=_0x4f97d2,_0x38b7d1[_0x16b5e2(0x3de)]=_0x16b5e2(0x4cf),_0x38b7d1['candidates']=_0x162eb3[_0x16b5e2(0x1f4)][_0x4f97d2][_0x16b5e2(0x373)],_0x38b7d1['session']=_0x162eb3['rpcs'][_0x4f97d2][_0x16b5e2(0x157)],_0x162eb3[_0x16b5e2(0x1f4)][_0x4f97d2]['iceBundle']=[],_0x162eb3[_0x16b5e2(0xf2)]?_0x162eb3[_0x16b5e2(0x52d)](JSON[_0x16b5e2(0x444)](_0x38b7d1[_0x16b5e2(0x134)]))['then'](function(_0x3d61bb){var _0x26cdc3=_0x16b5e2;_0x38b7d1[_0x26cdc3(0x134)]=_0x3d61bb[0x0],_0x38b7d1[_0x26cdc3(0x3f5)]=_0x3d61bb[0x1],_0x162eb3[_0x26cdc3(0x577)](_0x38b7d1);}):_0x162eb3[_0x16b5e2(0x577)](_0x38b7d1);},0x190);},_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x550)]=function(_0x3a0ac9){var _0x13d76f=_0x4f7b4e;switch(this[_0x13d76f(0x268)]){case'new':log('new');case _0x13d76f(0x15d):log(_0x13d76f(0x15d));case _0x13d76f(0x4e6):log(_0x13d76f(0x3b4));if(_0x162eb3['security']){if(_0x162eb3['ws'][_0x13d76f(0x2bb)]!==0x1){_0x162eb3['ws'][_0x13d76f(0x556)]();break;}_0x162eb3['ws'][_0x13d76f(0x556)](),setTimeout(function(){var _0x22edc0=_0x13d76f;_0x162eb3[_0x22edc0(0x14e)]!=!![]&&warnUser(_0x22edc0(0x468));},0x1);}break;case _0x13d76f(0x263):warnlog(_0x13d76f(0x568));break;case _0x13d76f(0x162):warnlog('FAIL\x20rpcs');try{var _0x146ce1=this[_0x13d76f(0x34f)];}catch(_0x2cc4e8){}try{this[_0x13d76f(0x3d0)]&&this[_0x13d76f(0x3d0)][_0x13d76f(0x472)]()[_0x13d76f(0x204)](function(_0x1d3d05){var _0x534ff9=_0x13d76f;_0x1d3d05[_0x534ff9(0x529)](),log(_0x534ff9(0x214));});}catch(_0xed7b49){warnlog(_0xed7b49);}if(_0x162eb3['director'])try{_0x13d76f(0x305)in _0x162eb3[_0x13d76f(0x1f4)][this['UUID']]['videoElement']&&_0x162eb3['rpcs'][this['UUID']][_0x13d76f(0x340)][_0x13d76f(0x305)]['stop']();}catch(_0x4512de){warnlog(_0x4512de);}try{if(_0x13d76f(0x2ae)!==_0x13d76f(0x2ae)){function _0x14ac95(){var _0x4a0641=_0x13d76f;_0x1fe6ff[_0x4a0641(0x1f4)][_0x161847][_0x4a0641(0x340)][_0x4a0641(0x288)]=_0x5739bf[_0x4a0641(0x1f4)][_0x11abb2][_0x4a0641(0x3d0)];}}else document[_0x13d76f(0x367)](_0x13d76f(0x22e)+this[_0x13d76f(0x1e2)])&&getById(_0x13d76f(0x22e)+this['UUID'])[_0x13d76f(0x23c)][_0x13d76f(0x45f)](getById(_0x13d76f(0x22e)+this[_0x13d76f(0x1e2)]));}catch(_0x30d692){warnlog(_0x30d692);}_0x162eb3[_0x13d76f(0x1f4)][this[_0x13d76f(0x1e2)]][_0x13d76f(0x556)](),_0x162eb3[_0x13d76f(0x1f4)][this[_0x13d76f(0x1e2)]]=null,delete _0x162eb3[_0x13d76f(0x1f4)][this[_0x13d76f(0x1e2)]];!_0x162eb3['director']&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x146ce1==_0x13d76f(0x2bd))break;try{warnlog(_0x13d76f(0x21c)),_0x146ce1 in _0x162eb3[_0x13d76f(0x4f2)]&&clearTimeout(_0x162eb3[_0x13d76f(0x4f2)][_0x146ce1]),_0x162eb3['watchTimeoutList'][_0x146ce1]=setTimeout(function(_0x38f954){var _0x56e281=_0x13d76f;delete _0x162eb3[_0x56e281(0x4f2)][_0x38f954],_0x162eb3[_0x56e281(0x39b)](_0x38f954);},_0x162eb3['retryTimeout'],_0x146ce1);}catch(_0x2bd461){errorlog(_0x2bd461);}break;case _0x13d76f(0x2f7):warnlog(_0x13d76f(0x1de));try{if(_0x13d76f(0x433)===_0x13d76f(0x380)){function _0x183f81(){var _0x375617=_0x13d76f;_0x5934dd[_0x375617(0x27f)]=_0x5ac3e7[_0x375617(0x1f4)][_0x396eb8][_0x375617(0x2fa)];}}else var _0x146ce1=this[_0x13d76f(0x34f)];}catch(_0x186176){};try{this[_0x13d76f(0x3d0)]&&this[_0x13d76f(0x3d0)][_0x13d76f(0x472)]()[_0x13d76f(0x204)](function(_0x1b58e2){var _0x567b79=_0x13d76f;if(_0x567b79(0x372)===_0x567b79(0x372))_0x1b58e2['stop'](),log(_0x567b79(0x214));else{function _0x554f38(){var _0x1ba764=_0x567b79;_0x177181[_0x1ba764(0x512)]=[{}];}}});}catch(_0x506583){}if(_0x162eb3[_0x13d76f(0x1b6)])try{_0x13d76f(0x305)in _0x162eb3[_0x13d76f(0x1f4)][this['UUID']]['videoElement']&&_0x162eb3[_0x13d76f(0x1f4)][this['UUID']][_0x13d76f(0x340)][_0x13d76f(0x305)][_0x13d76f(0x529)]();}catch(_0x25600e){errorlog(_0x25600e);}try{document['getElementById'](_0x13d76f(0x22e)+this['UUID'])&&getById(_0x13d76f(0x22e)+this['UUID'])[_0x13d76f(0x23c)][_0x13d76f(0x45f)](getById(_0x13d76f(0x22e)+this['UUID']));}catch(_0x169c57){errorlog(_0x169c57);}_0x162eb3[_0x13d76f(0x1f4)][this[_0x13d76f(0x1e2)]][_0x13d76f(0x556)](),_0x162eb3[_0x13d76f(0x1f4)][this[_0x13d76f(0x1e2)]]=null,delete _0x162eb3['rpcs'][this[_0x13d76f(0x1e2)]];!_0x162eb3[_0x13d76f(0x1b6)]&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x146ce1==_0x13d76f(0x2bd))break;try{errorlog(_0x13d76f(0xe3)),_0x146ce1 in _0x162eb3[_0x13d76f(0x4f2)]&&clearTimeout(_0x162eb3[_0x13d76f(0x4f2)][_0x146ce1]),_0x162eb3[_0x13d76f(0x4f2)][_0x146ce1]=setTimeout(function(_0x541621){var _0x38751f=_0x13d76f;delete _0x162eb3[_0x38751f(0x4f2)][_0x541621],_0x162eb3[_0x38751f(0x39b)](_0x541621);},_0x162eb3['retryTimeout'],_0x146ce1);}catch(_0x3573d4){errorlog(_0x3573d4);}break;}},_0x162eb3['rpcs'][_0x4f97d2][_0x4f7b4e(0x11e)]=function(){var _0x54bc0f=_0x4f7b4e;if(_0x54bc0f(0xf5)!==_0x54bc0f(0x2a3))try{if(this[_0x54bc0f(0x3b2)]==_0x54bc0f(0x2f7))errorlog(_0x54bc0f(0x560));else{if(this[_0x54bc0f(0x3b2)]=='disconnected')warnlog('ICE\x20DISCONNECTED'),_0x162eb3[_0x54bc0f(0x1f4)][_0x4f97d2][_0x54bc0f(0x340)][_0x54bc0f(0x21e)][_0x54bc0f(0x345)]='0',_0x162eb3[_0x54bc0f(0x1f4)][_0x4f97d2]['disconnectedTimeout']=setTimeout(function(_0x34cac0){updateMixer();},0x1f4,_0x4f97d2);else this[_0x54bc0f(0x3b2)]==_0x54bc0f(0x162)?errorlog(_0x54bc0f(0x4ea)):(log('ICE:\x20'+this['iceConnectionState']),'opacity'in _0x162eb3[_0x54bc0f(0x1f4)][_0x4f97d2][_0x54bc0f(0x340)][_0x54bc0f(0x21e)]?_0x162eb3['rpcs'][_0x4f97d2][_0x54bc0f(0x340)]['style'][_0x54bc0f(0x345)]=='0'&&(_0x162eb3[_0x54bc0f(0x1f4)][_0x4f97d2]['videoElement'][_0x54bc0f(0x21e)][_0x54bc0f(0x345)]='1',updateMixer()):_0x162eb3[_0x54bc0f(0x1f4)][_0x4f97d2][_0x54bc0f(0x340)][_0x54bc0f(0x21e)][_0x54bc0f(0x345)]='1',_0x162eb3[_0x54bc0f(0x1f4)][_0x4f97d2][_0x54bc0f(0x10f)]&&clearTimeout(_0x162eb3[_0x54bc0f(0x1f4)][_0x4f97d2][_0x54bc0f(0x10f)]));}}catch(_0x4d9064){}else{function _0x4690d9(){var _0x30f96e=_0x54bc0f;_0x39df70['rpcs'][_0x3280a3][_0x30f96e(0x340)][_0x30f96e(0x21e)][_0x30f96e(0x1fb)]=_0x30f96e(0x277),_0x443f40=!![];}}},_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x2a4)]=function(_0x473cff){var _0x1a52d6=_0x4f7b4e;_0x162eb3['rpcs'][_0x4f97d2][_0x1a52d6(0x228)]=_0x473cff[_0x1a52d6(0x47f)],_0x162eb3['rpcs'][_0x4f97d2][_0x1a52d6(0x228)][_0x1a52d6(0x1e2)]=_0x4f97d2,_0x162eb3['rpcs'][_0x4f97d2][_0x1a52d6(0x228)][_0x1a52d6(0x3ef)]=_0x4781be=>{var _0x156cc8=_0x1a52d6,_0x211197={};_0x211197[_0x156cc8(0x140)]=![];if(_0x162eb3[_0x156cc8(0x50b)]!==![])_0x162eb3['novideo'][_0x156cc8(0x28f)](_0x162eb3[_0x156cc8(0x1f4)][_0x4f97d2]['streamID'])?_0x211197['video']=!![]:_0x211197[_0x156cc8(0x3cb)]=![];else{if(_0x162eb3[_0x156cc8(0x140)]!==![]){if(_0x162eb3[_0x156cc8(0x140)]!==null){if(_0x162eb3[_0x156cc8(0x1f4)][_0x4f97d2]['streamID']===_0x162eb3[_0x156cc8(0x140)])_0x162eb3[_0x156cc8(0x3ba)]?(_0x211197[_0x156cc8(0x140)]=!![],_0x211197[_0x156cc8(0x3cb)]=![]):_0x211197['video']=!![];else{if(_0x156cc8(0x4c8)===_0x156cc8(0xda)){function _0x200e7f(){var _0x505ada=_0x156cc8;_0x876f95[_0x505ada(0x147)][_0x279a17][_0x505ada(0x14f)][_0x505ada(0x53f)][_0x505ada(0x1b6)]=!![];}}else _0x211197[_0x156cc8(0x3cb)]=![];}}else _0x162eb3[_0x156cc8(0x37c)]&&(_0x4f97d2==_0x162eb3[_0x156cc8(0x37c)]?_0x162eb3[_0x156cc8(0x3ba)]?(_0x211197[_0x156cc8(0x3cb)]=![],_0x211197[_0x156cc8(0x140)]=!![]):_0x211197[_0x156cc8(0x3cb)]=!![]:_0x211197[_0x156cc8(0x3cb)]=![]);}else{if(_0x162eb3['exclude']!==![])_0x162eb3[_0x156cc8(0x122)][_0x156cc8(0x28f)](_0x162eb3[_0x156cc8(0x1f4)][_0x4f97d2][_0x156cc8(0x34f)])?_0x211197[_0x156cc8(0x3cb)]=![]:_0x211197[_0x156cc8(0x3cb)]=!![];else{if(_0x156cc8(0x29b)!==_0x156cc8(0x29b)){function _0x1c9945(){var _0xe97a4b=_0x156cc8;_0x2ab697[_0xe97a4b(0x376)]=_0xe97a4b(0x273),_0x3e9c7b(_0xe97a4b(0x17f));}}else _0x211197[_0x156cc8(0x3cb)]=!![];}}}_0x162eb3[_0x156cc8(0x29f)]&&(_0x211197[_0x156cc8(0x39f)]=_0x162eb3[_0x156cc8(0x29f)]);try{_0x211197[_0x156cc8(0x53f)]={},_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x2fa)]=_0x162eb3[_0x156cc8(0x2fa)],_0x211197[_0x156cc8(0x53f)]['order']=_0x162eb3[_0x156cc8(0x2c5)],_0x211197['info'][_0x156cc8(0x4c5)]=_0x162eb3[_0x156cc8(0x133)],_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x400)]=_0x162eb3[_0x156cc8(0x22c)],_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x3f7)]=_0x162eb3[_0x156cc8(0x4f5)],_0x211197[_0x156cc8(0x53f)]['codec_url']=_0x162eb3['codec'],_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x158)]=_0x162eb3['version'],_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x26c)]=_0x162eb3['forceios'],_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x48a)]=_0x162eb3[_0x156cc8(0x319)],_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x515)]=_0x162eb3['ptime'],_0x211197['info']['minptime']=_0x162eb3[_0x156cc8(0x480)],_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x3ee)]=_0x162eb3['maxptime'];if(navigator[_0x156cc8(0x3f1)]){var _0x103aad,_0x30a57b=navigator[_0x156cc8(0x3f1)];_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x28a)]=_0x30a57b;}navigator[_0x156cc8(0x209)]&&(_0x211197[_0x156cc8(0x53f)]['platform']=navigator['platform']);if(window[_0x156cc8(0x475)]){_0x211197[_0x156cc8(0x53f)][_0x156cc8(0x46c)]=window[_0x156cc8(0x475)][_0x156cc8(0x131)];if(_0x162eb3['obsState']){if('HEOCa'===_0x156cc8(0x4d8)){function _0x503c86(){var _0x48c0ca=_0x156cc8;_0x34aee6['encodings'][0x0][_0x48c0ca(0x3b0)]==![]&&(_0x34d103[_0x48c0ca(0x512)][0x0][_0x48c0ca(0x3b0)]=!![]),_0x34867e[_0x48c0ca(0x512)][0x0][_0x48c0ca(0x23e)]=_0x2c12d5*0x400;}}else{var _0x3d0e32=![];_0x162eb3['obsState']['visibility']!==null&&(_0x211197[_0x156cc8(0xeb)]=_0x162eb3[_0x156cc8(0x3cc)][_0x156cc8(0x419)],_0x162eb3[_0x156cc8(0x3cc)][_0x156cc8(0x419)]===![]&&(_0x3d0e32=!![]));_0x162eb3[_0x156cc8(0x3cc)][_0x156cc8(0x422)]!==null&&(_0x211197[_0x156cc8(0x208)]=_0x162eb3[_0x156cc8(0x3cc)][_0x156cc8(0x422)]);if(_0x162eb3[_0x156cc8(0x3cc)]['recording']!==null){if('ljlJq'!==_0x156cc8(0x1b2))_0x211197['obsRecording']=_0x162eb3[_0x156cc8(0x3cc)][_0x156cc8(0x38a)];else{function _0x1f668c(){var _0x2dca4e=_0x156cc8;_0x55a2d4[_0x2dca4e(0x147)][_0x15f2f5][_0x2dca4e(0x4ae)][_0x2dca4e(0x388)](_0x2206ae);}}}if(_0x162eb3[_0x156cc8(0x3cc)][_0x156cc8(0x4a6)]!==null){if(_0x156cc8(0x247)===_0x156cc8(0x247))_0x211197[_0x156cc8(0x223)]=_0x162eb3[_0x156cc8(0x3cc)]['streaming'];else{function _0x3fdef8(){var _0x19381e=_0x156cc8;_0x5e9e80['pcs'][_0x13ffc2][_0x19381e(0x556)](),delete _0x167f4b['pcs'][_0x32f38d],_0x575cb3();}}}}}if(_0x162eb3[_0x156cc8(0x1a1)]!==![]){if('IraWJ'!==_0x156cc8(0x2b1)){function _0x56708b(){var _0x233cc5=_0x156cc8;_0x2088a5[_0x233cc5(0x1f4)][_0x4934dd][_0x233cc5(0x14f)][_0x233cc5(0x446)][_0x233cc5(0x530)]=_0x25bf73[_0x233cc5(0x3a4)];}}else _0x211197[_0x156cc8(0x40d)]=parseInt(_0x162eb3[_0x156cc8(0x1a1)]),_0x3d0e32&&(_0x162eb3[_0x156cc8(0x1f4)][_0x4f97d2][_0x156cc8(0x40b)]=_0x211197['optimizedBitrate']);}}else _0x211197[_0x156cc8(0x53f)][_0x156cc8(0x46c)]=![];}catch(_0x382aff){};_0x162eb3[_0x156cc8(0x4cd)]!==![]?_0x162eb3[_0x156cc8(0x4cd)][_0x156cc8(0x28f)](_0x162eb3[_0x156cc8(0x1f4)][_0x4f97d2]['streamID'])?_0x211197[_0x156cc8(0x25f)]=!![]:_0x211197['audio']=![]:_0x211197['audio']=!![];_0x211197[_0x156cc8(0x3b9)]=![];if(_0x162eb3[_0x156cc8(0x46a)]!==![])_0x162eb3[_0x156cc8(0x46a)][_0x156cc8(0x28f)](_0x162eb3['rpcs'][_0x4f97d2]['streamID'])?_0x211197[_0x156cc8(0x3b9)]=!![]:_0x211197[_0x156cc8(0x3b9)]=![];else{if(_0x156cc8(0x314)!==_0x156cc8(0x461))_0x211197['iframe']=!![];else{function _0x2b3434(){_0x484e00('failed\x20to\x20disconnect');}}}_0x211197[_0x156cc8(0x466)]=![],_0x211197[_0x156cc8(0x145)]=![],_0x211197[_0x156cc8(0x1b6)]=![],_0x211197[_0x156cc8(0x139)]=_0x162eb3[_0x156cc8(0x139)],_0x211197[_0x156cc8(0x160)]=![],_0x211197[_0x156cc8(0x300)]=![],_0x211197[_0x156cc8(0x26c)]=![];_0x162eb3[_0x156cc8(0x319)]&&(_0x211197[_0x156cc8(0x160)]=!![]);if(_0x162eb3[_0x156cc8(0x1b6)])_0x211197[_0x156cc8(0x1b6)]=!![],_0x211197[_0x156cc8(0x26c)]=_0x162eb3[_0x156cc8(0x26c)];else{if(_0x162eb3[_0x156cc8(0x145)]!==![]){if('EqEYW'===_0x156cc8(0x29d)){function _0x24f808(){_0x57bc9e(_0x4d768c);}}else _0x211197[_0x156cc8(0x145)]=_0x162eb3[_0x156cc8(0x145)];}else{if(_0x162eb3[_0x156cc8(0x27b)]!==![]&&_0x162eb3['roomid']!==''){if(_0x156cc8(0x120)!==_0x156cc8(0x120)){function _0x108fe3(){var _0x4d862d=_0x156cc8;_0x336e49[_0x4d862d(0x134)]=_0xc3c3e3[0x0],_0x2d20e9['vector']=_0x3d3586[0x1],_0x4cb181[_0x4d862d(0x3cd)](_0x2effed);}}else _0x211197[_0x156cc8(0x26c)]=_0x162eb3[_0x156cc8(0x26c)],_0x211197[_0x156cc8(0x466)]=!![];}}}_0x162eb3[_0x156cc8(0x196)](_0x211197,_0x4f97d2)?log('successfully\x20requested\x20audio\x20and\x20video'):errorlog(_0x156cc8(0x31f)),pokeIframeAPI(_0x156cc8(0x1d4),!![],_0x4f97d2);},_0x162eb3[_0x1a52d6(0x1f4)][_0x4f97d2][_0x1a52d6(0x228)][_0x1a52d6(0x1f2)]=_0x372b1d=>{var _0x5ddf82=_0x1a52d6;if(typeof _0x372b1d[_0x5ddf82(0x2cd)]==_0x5ddf82(0x1b1)){if(!_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)])_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x31d)]=document[_0x5ddf82(0x4da)](_0x5ddf82(0x4b5)),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)][_0x5ddf82(0x4d1)]=0x10,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)]['height']=0x9,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)][_0x5ddf82(0x4e1)][_0x5ddf82(0x1e2)]=_0x4f97d2,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['imageElement'][_0x5ddf82(0x302)]=![],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)][_0x5ddf82(0x1b8)](_0x5ddf82(0x12c),function(_0x14782d){var _0x4ac7d0=_0x5ddf82;log('clicked');try{if(_0x14782d[_0x4ac7d0(0x226)]||_0x14782d['metaKey']){_0x14782d[_0x4ac7d0(0x399)]();var _0xd59c8c=_0x14782d[_0x4ac7d0(0x4f1)][_0x4ac7d0(0x4e1)][_0x4ac7d0(0x1e2)];if(_0x4ac7d0(0x14f)in _0x162eb3['rpcs'][_0xd59c8c]){var [_0x2ddb75,_0x27298c]=statsMenuCreator();printViewStats(_0x27298c,_0xd59c8c),_0x2ddb75[_0x4ac7d0(0x3a2)]=setInterval(printViewStats,0xbb8,_0x27298c,_0xd59c8c);}return _0x14782d[_0x4ac7d0(0x40e)](),![];}}catch(_0x1bc6a8){errorlog(_0x1bc6a8);}}),updateMixer();else _0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)][_0x5ddf82(0x302)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['imageElement']['hidden']=![],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)][_0x5ddf82(0x21e)][_0x5ddf82(0x419)]=_0x5ddf82(0x3d3));_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['imageElement']['src']=window[_0x5ddf82(0x165)][_0x5ddf82(0x583)](new Blob([new Uint8Array(_0x372b1d[_0x5ddf82(0x2cd)])],{'type':_0x5ddf82(0x2f3)}));return;}var _0x58cc22=JSON[_0x5ddf82(0x4aa)](_0x372b1d[_0x5ddf82(0x2cd)]);_0x58cc22['UUID']=_0x4f97d2;var _0x33935f=![],_0x18d207=![];if('rejected'in _0x58cc22){if(_0x162eb3[_0x5ddf82(0x1b6)]){if(!(_0x162eb3[_0x5ddf82(0x14e)]||_0x162eb3[_0x5ddf82(0x425)])){if('wZrra'===_0x5ddf82(0x293))warnUser(_0x5ddf82(0x23b),0x1388);else{function _0xf584d2(){var _0xe600=_0x5ddf82;if(_0x47a663[_0xe600(0x17d)][_0xe600(0x17d)][_0xe600(0x549)](_0x3a415a['icefilter'])===-0x1){_0x1984f6(_0xe600(0x52c));return;}else _0x16818a(_0x40d12d[_0xe600(0x17d)]);}}}}errorlog(_0x5ddf82(0x24f)+_0x58cc22[_0x5ddf82(0x186)]+',\x20isDirector:\x20'+_0x162eb3[_0x5ddf82(0x1b6)]);}if(_0x5ddf82(0x16b)in _0x58cc22)_0x162eb3[_0x5ddf82(0x3e9)](_0x58cc22);else{if(_0x5ddf82(0x17d)in _0x58cc22)_0x58cc22[_0x5ddf82(0x1e2)]=_0x4f97d2,log(_0x5ddf82(0x38b)),_0x162eb3[_0x5ddf82(0x3d9)](_0x58cc22);else{if(_0x5ddf82(0x134)in _0x58cc22)_0x58cc22[_0x5ddf82(0x1e2)]=_0x4f97d2,log(_0x5ddf82(0x56a)),_0x162eb3[_0x5ddf82(0x142)](_0x58cc22);else{if(_0x5ddf82(0x40c)in _0x58cc22)try{_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x40c)]=_0x58cc22[_0x5ddf82(0x40c)]||![];if(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['iframeSrc']==![])_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['iframeEle']=![],_0x33935f=!![];else{if(_0x162eb3['broadcast']!==![]){if(_0x162eb3['broadcast']!==null){if(_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x34f)]===_0x162eb3[_0x5ddf82(0x140)]){if(_0x162eb3[_0x5ddf82(0x46a)]===![]){_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]=loadIframe(_0x58cc22[_0x5ddf82(0x40c)]),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['id']='iframe_'+_0x4f97d2,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)][_0x5ddf82(0x4e1)][_0x5ddf82(0x1e2)]=_0x4f97d2,_0x33935f=!![];if(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]){if(_0x5ddf82(0x1a6)===_0x5ddf82(0x1a6))_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)][_0x5ddf82(0x4e1)][_0x5ddf82(0x1bf)]=_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x34f)];else{function _0x1e888d(){var _0x167c52=_0x5ddf82;_0x262535[_0x167c52(0x1b6)]&&(!(_0x80e37b[_0x167c52(0x14e)]||_0x4f61de['cleanDirector'])&&_0x781f5(_0x167c52(0x23b),0x1388)),_0x1418fa(_0x167c52(0x24f)+_0x8f602[_0x167c52(0x186)]+_0x167c52(0x2ef)+_0x2d7cde[_0x167c52(0x1b6)]);}}}}else _0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]in _0x162eb3[_0x5ddf82(0x46a)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['iframeEle']=loadIframe(_0x58cc22[_0x5ddf82(0x40c)]),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['id']=_0x5ddf82(0x370)+_0x4f97d2,_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x36f)][_0x5ddf82(0x4e1)][_0x5ddf82(0x1e2)]=_0x4f97d2,_0x33935f=!![],_0x162eb3['rpcs'][_0x4f97d2]['streamID']&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)][_0x5ddf82(0x4e1)][_0x5ddf82(0x1bf)]=_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]));}}else{if(_0x162eb3[_0x5ddf82(0x37c)]){if(_0x4f97d2==_0x162eb3[_0x5ddf82(0x37c)]){if(_0x162eb3['noiframe']===![])_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]=loadIframe(_0x58cc22[_0x5ddf82(0x40c)]),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['id']=_0x5ddf82(0x370)+_0x4f97d2,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)][_0x5ddf82(0x4e1)][_0x5ddf82(0x1e2)]=_0x4f97d2,_0x33935f=!![],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['dataset']['sid']=_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]);else _0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]in _0x162eb3[_0x5ddf82(0x46a)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]=loadIframe(_0x58cc22['iframeSrc']),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['id']=_0x5ddf82(0x370)+_0x4f97d2,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['iframeEle'][_0x5ddf82(0x4e1)][_0x5ddf82(0x1e2)]=_0x4f97d2,_0x33935f=!![],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['dataset'][_0x5ddf82(0x1bf)]=_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]));}}}}else{if(_0x162eb3[_0x5ddf82(0x46a)]===![])_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]=loadIframe(_0x58cc22['iframeSrc']),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['id']=_0x5ddf82(0x370)+_0x4f97d2,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['dataset']['UUID']=_0x4f97d2,_0x33935f=!![],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]&&(_0x162eb3['rpcs'][_0x4f97d2]['iframeEle'][_0x5ddf82(0x4e1)][_0x5ddf82(0x1bf)]=_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]);else _0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x34f)]in _0x162eb3[_0x5ddf82(0x46a)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]=loadIframe(_0x58cc22[_0x5ddf82(0x40c)]),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x36f)]['id']=_0x5ddf82(0x370)+_0x4f97d2,_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x36f)]['dataset']['UUID']=_0x4f97d2,_0x33935f=!![],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['iframeEle'][_0x5ddf82(0x4e1)][_0x5ddf82(0x1bf)]=_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x34f)]));}}}catch(_0x12fa27){errorlog(_0x12fa27);}}}}if(_0x5ddf82(0x4c4)in _0x58cc22){var _0x17ed15=![],_0x622fe3=![];if(_0x162eb3[_0x5ddf82(0x37c)]===_0x4f97d2){_0x17ed15=!![];if(_0x5ddf82(0x187)in _0x58cc22){if(_0x58cc22['overlay']==!![]){if(_0x5ddf82(0x517)===_0x5ddf82(0x517))_0x622fe3=!![];else{function _0x366407(){var _0xffe64=_0x5ddf82;_0x4dae77[_0xffe64(0xcf)]=_0x37d7fd['label']+'\x20-\x20Transferred';}}}}}if(_0x162eb3[_0x5ddf82(0x1b6)]){if(_0x58cc22[_0x5ddf82(0x4c4)]==_0x5ddf82(0x3ac))_0x162eb3['beepToNotify']&&playtone(),getById('hands_'+_0x4f97d2)[_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]=_0x5ddf82(0x545),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x30d)]['style'][_0x5ddf82(0x1fb)]=_0x5ddf82(0x3aa);else _0x58cc22['chat']==_0x5ddf82(0x171)&&(getById(_0x5ddf82(0x4d3)+_0x4f97d2)[_0x5ddf82(0x21e)]['display']=_0x5ddf82(0x277),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x30d)][_0x5ddf82(0x21e)]['display']=_0x5ddf82(0x277));}log(_0x5ddf82(0x1ba)+_0x17ed15),getChatMessage(_0x58cc22[_0x5ddf82(0x4c4)],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['label'],_0x17ed15,_0x622fe3);}if(_0x5ddf82(0x1aa)in _0x58cc22){log(_0x58cc22);if(_0x162eb3[_0x5ddf82(0x3a9)]){if(_0x5ddf82(0x44d)==='cSukY'){function _0x2cce1f(){var _0x2efb51=_0x5ddf82;return _0x2ca20e[_0x2efb51(0x2ac)]&&_0x300445[_0x2efb51(0x2ac)][_0x2efb51(0x2c3)]==_0x2efb51(0x3cb);}}else updateClosedCaptions(_0x58cc22,_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x2fa)],_0x4f97d2);}}_0x5ddf82(0xec)in _0x58cc22&&(_0x162eb3['director']&&updateDirectorsAudio(_0x58cc22[_0x5ddf82(0xec)],_0x4f97d2));_0x5ddf82(0x35a)in _0x58cc22&&(_0x162eb3[_0x5ddf82(0x1b6)]&&updateDirectorsVideo(_0x58cc22[_0x5ddf82(0x35a)],_0x4f97d2));_0x5ddf82(0x2a7)in _0x58cc22&&(_0x162eb3[_0x5ddf82(0x1b6)]&&gotDevicesRemote(_0x58cc22['mediaDevices'],_0x4f97d2));_0x5ddf82(0xe1)in _0x58cc22&&(_0x162eb3[_0x5ddf82(0x37c)]===_0x4f97d2&&(_0x162eb3[_0x5ddf82(0x109)]&&lowerhand()));if(_0x5ddf82(0x1dc)in _0x58cc22){log(_0x58cc22);if(_0x162eb3[_0x5ddf82(0x37c)]===_0x4f97d2){if(_0x58cc22[_0x5ddf82(0x1dc)]!==![]){if(_0x58cc22[_0x5ddf82(0x1dc)]===!![])_0x162eb3['infocus']=!![];else{if(_0x5ddf82(0x11b)==='AVMXj'){function _0x19bb9f(){var _0x3ab14b=_0x5ddf82;_0x43ab9a=!![],_0x3ab14b(0x187)in _0x5d76b9&&(_0x625dc4[_0x3ab14b(0x187)]==!![]&&(_0x35dbb7=!![]));}}else for(var _0x5a1578 in _0x162eb3['rpcs']){if(_0x5ddf82(0x542)===_0x5ddf82(0xd1)){function _0x26647b(){_0x50655e=0x0;}}else{if(_0x162eb3[_0x5ddf82(0x1f4)][_0x5a1578][_0x5ddf82(0x34f)]===_0x58cc22['infocus']){_0x162eb3['infocus']=_0x5a1578;break;}}}}}else _0x162eb3[_0x5ddf82(0x1dc)]=![];_0x33935f=!![],mustUpdateuserList=!![];}}if(_0x5ddf82(0x2eb)in _0x58cc22){_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x14f)][_0x5ddf82(0x2eb)]={};if('lin'in _0x58cc22){if(_0x5ddf82(0x554)!==_0x5ddf82(0x554)){function _0x4968d9(){var _0x3036b8=_0x5ddf82;_0x276ab0[_0x3036b8(0x4a1)][_0x232300]['micDelay']['delayTime'][_0x3036b8(0x174)](_0x44c2d3,_0x581627[_0x3036b8(0x4a1)][_0xa2dff6][_0x3036b8(0x389)]['currentTime']);}}else _0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x14f)][_0x5ddf82(0x2eb)][_0x5ddf82(0x12d)]=_0x58cc22[_0x5ddf82(0x12d)];}_0x5ddf82(0x533)in _0x58cc22&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x14f)][_0x5ddf82(0x2eb)][_0x5ddf82(0x533)]=_0x58cc22['acc']);_0x5ddf82(0x1d0)in _0x58cc22&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x14f)][_0x5ddf82(0x2eb)][_0x5ddf82(0x1d0)]=_0x58cc22[_0x5ddf82(0x1d0)]);if(_0x5ddf82(0x4a5)in _0x58cc22){if('QfTDa'!==_0x5ddf82(0x20d)){function _0x50dfec(){var _0x19fbca=_0x5ddf82;_0x565afe[_0x19fbca(0x1e2)]=_0x4a5550,_0x16cf70(_0x19fbca(0x38b)),_0x1d8b2f[_0x19fbca(0x3d9)](_0x148d55);}}else _0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x14f)]['sensors'][_0x5ddf82(0x4a5)]=_0x58cc22[_0x5ddf82(0x4a5)];}isIFrame&&parent[_0x5ddf82(0x30e)]({'sensors':_0x58cc22},'*');}_0x5ddf82(0x1a5)in _0x58cc22&&playbackMIDI(_0x58cc22['midi']);_0x5ddf82(0x305)in _0x58cc22&&updateRemoteRecordButton(_0x4f97d2,_0x58cc22['recorder']);if(_0x5ddf82(0x53f)in _0x58cc22){if(_0x5ddf82(0x2dc)==='hDPZX'){function _0x441460(){if(_0x134a57){}}}else{warnlog(_0x58cc22),_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x14f)][_0x5ddf82(0x53f)]=_0x58cc22[_0x5ddf82(0x53f)];if(_0x5ddf82(0x2fa)in _0x58cc22[_0x5ddf82(0x53f)]){if(typeof _0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x2fa)]==_0x5ddf82(0x173))_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2fa)]=sanitizeLabel(_0x58cc22['info'][_0x5ddf82(0x2fa)]);else{if(_0x5ddf82(0x471)!==_0x5ddf82(0x471)){function _0x1f7322(){var _0x191151=_0x5ddf82;_0x3db3c9(_0x191151(0x235)),_0x197bf5[_0x191151(0x15f)](_0x1c2e4b[_0x1e8a77]);}}else _0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2fa)]=![];}if(_0x162eb3[_0x5ddf82(0x1b6)]){var _0x3665d2=getById(_0x5ddf82(0x427)+_0x4f97d2);_0x3665d2&&(_0x3665d2[_0x5ddf82(0x21e)][_0x5ddf82(0x3fe)]=_0x5ddf82(0x54b),_0x3665d2[_0x5ddf82(0x21e)]['top']=_0x5ddf82(0x279),_0x3665d2[_0x5ddf82(0x21e)][_0x5ddf82(0x1c8)]='5px',_0x3665d2[_0x5ddf82(0x21e)][_0x5ddf82(0x4e9)]=_0x5ddf82(0x4a8),_0x3665d2['style'][_0x5ddf82(0x318)]='pointer',_0x3665d2[_0x5ddf82(0x4e1)][_0x5ddf82(0x1e2)]=_0x4f97d2,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2fa)]?_0x3665d2[_0x5ddf82(0x27f)]=_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2fa)]:_0x3665d2[_0x5ddf82(0x27f)]=_0x5ddf82(0x394),_0x3665d2[_0x5ddf82(0x1f7)]=function(_0x395400){var _0x213bbb=_0x5ddf82,_0x331f84=_0x395400[_0x213bbb(0x324)]['innerText'];if(_0x162eb3[_0x213bbb(0x1f4)][_0x395400['target'][_0x213bbb(0x4e1)][_0x213bbb(0x1e2)]]['label']===![]){if(_0x213bbb(0x4f7)!==_0x213bbb(0xe2))_0x331f84='';else{function _0x21fce1(){var _0x3489e5=_0x213bbb;_0x3d75a9[_0x3489e5(0x2ac)]&&(_0x489aa7[_0x3489e5(0x2ac)][_0x3489e5(0x2f1)]=![]);}}}window[_0x213bbb(0x3f6)]();var _0x12c746=prompt('Enter\x20a\x20new\x20Display\x20Name\x20for\x20this\x20stream',_0x331f84);if(_0x12c746!==null){_0x12c746==''?(_0x12c746=![],_0x395400[_0x213bbb(0x324)][_0x213bbb(0x27f)]='Add\x20a\x20label'):_0x395400[_0x213bbb(0x324)]['innerText']=_0x12c746;var _0x1c306d={};_0x1c306d[_0x213bbb(0x1e2)]=_0x395400[_0x213bbb(0x324)][_0x213bbb(0x4e1)]['UUID'],_0x1c306d[_0x213bbb(0x42f)]=!![],_0x1c306d[_0x213bbb(0x276)]=_0x12c746,_0x162eb3[_0x213bbb(0x196)](_0x1c306d,_0x1c306d[_0x213bbb(0x1e2)]);}});}}if(_0x5ddf82(0x2c5)in _0x58cc22[_0x5ddf82(0x53f)]){_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['order']=parseInt(_0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x2c5)])||0x0;if(_0x162eb3[_0x5ddf82(0x1b6)]){var _0xd954c9=document[_0x5ddf82(0x41a)](_0x5ddf82(0x330)+_0x4f97d2+'\x22]');_0xd954c9[0x0]&&(_0xd954c9[0x0][_0x5ddf82(0x27f)]=_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2c5)]);}}else _0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2c5)]=0x0;if(_0x162eb3[_0x5ddf82(0x1b6)]){if('recording_audio_pipeline'in _0x58cc22[_0x5ddf82(0x53f)]){if(_0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x484)]==![]){var _0xd954c9=document[_0x5ddf82(0x41a)](_0x5ddf82(0x270)+_0x4f97d2+'\x22]');if(_0xd954c9[0x0]){if(_0x5ddf82(0x267)===_0x5ddf82(0x237)){function _0x57be9f(){var _0x3a7ca6=_0x5ddf82;_0xa99c80[_0x3a7ca6(0x27b)]=_0x2f7985[_0x3a7ca6(0x53b)];}}else _0xd954c9[0x0][_0x5ddf82(0x532)]=!![],_0xd954c9[0x0][_0x5ddf82(0xcf)]=_0x5ddf82(0x150);}var _0xd954c9=document[_0x5ddf82(0x41a)](_0x5ddf82(0x588)+_0x4f97d2+'\x22]');_0xd954c9[0x0]&&(_0xd954c9[0x0][_0x5ddf82(0x532)]=!![],_0xd954c9[0x0][_0x5ddf82(0xcf)]=_0x5ddf82(0x150),_0xd954c9[0x0][_0x5ddf82(0x21e)][_0x5ddf82(0x345)]=0.2);}}if(_0x5ddf82(0x1da)in _0x58cc22[_0x5ddf82(0x53f)]){if(_0x5ddf82(0x20f)===_0x5ddf82(0x57c)){function _0x2db658(){var _0x3a2d03=_0x5ddf82;_0x1f7c9b[_0x3a2d03(0x147)][_0x17d52e][_0x3a2d03(0x145)]!==![]?(_0x32b15f[_0x3a2d03(0x116)](_0x283ab4),_0x4ba147(_0x3a2d03(0x3e3))):_0x186aa8(_0x3a2d03(0x10a));}}else{if(_0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x1da)]!==![]){var _0x10fcdb=parseInt(_0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x1da)])||0x0;if(_0x10fcdb===0x0){var _0xd954c9=document[_0x5ddf82(0x41a)](_0x5ddf82(0x270)+_0x4f97d2+'\x22]');_0xd954c9[0x0]&&(_0xd954c9[0x0][_0x5ddf82(0x4e1)][_0x5ddf82(0x276)]=0x1,_0xd954c9[0x0][_0x5ddf82(0x1ff)]=_0x5ddf82(0x4fc),_0xd954c9[0x0][_0x5ddf82(0xf3)][0x1]['innerHTML']='Un-mute\x20guest',_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x188)]=0x1);}else{var _0xd954c9=document[_0x5ddf82(0x41a)](_0x5ddf82(0x588)+_0x4f97d2+'\x22]');_0xd954c9[0x0]&&(_0xd954c9[0x0][_0x5ddf82(0x276)]=_0x10fcdb,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x4f4)]=_0x10fcdb,remoteVolumeUI(_0xd954c9[0x0]));}}}}}_0x5ddf82(0x253)in _0x58cc22[_0x5ddf82(0x53f)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['remoteMuteState']=_0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x253)],_0x162eb3[_0x5ddf82(0x145)]===![]&&(_0x162eb3[_0x5ddf82(0x27b)]&&(!_0x162eb3[_0x5ddf82(0x14e)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)]?_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x37b)]?_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x167)][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]=_0x5ddf82(0x545):_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]=_0x5ddf82(0x277):(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)]=getById(_0x5ddf82(0x13e))[_0x5ddf82(0x4df)](!![]),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)]['id']=_0x5ddf82(0x539)+_0x4f97d2,_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x37b)]?_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]=_0x5ddf82(0x545):_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)][_0x5ddf82(0x21e)]['display']=_0x5ddf82(0x277),_0x33935f=!![])))));_0x5ddf82(0x477)in _0x58cc22[_0x5ddf82(0x53f)]&&(_0x162eb3[_0x5ddf82(0x1b6)]&&(_0x58cc22['info'][_0x5ddf82(0x477)]&&updateRemoteSpeakerMute(_0x4f97d2)));if(_0x5ddf82(0x30a)in _0x58cc22[_0x5ddf82(0x53f)]){if(_0x5ddf82(0x299)!==_0x5ddf82(0x299)){function _0xa7cea4(){var _0x4e9050=_0x5ddf82;_0x4609a3(_0x417f82[_0x4e9050(0x351)]),!_0x1ad414[_0x4e9050(0x14e)]&&_0x2a354c(_0x4e9050(0x17c),0x7530);}}else _0x162eb3[_0x5ddf82(0x1b6)]&&(_0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x30a)]&&updateRemoteDisplayMute(_0x4f97d2));}if(_0x5ddf82(0x491)in _0x58cc22[_0x5ddf82(0x53f)]){if(_0x162eb3['director']){if(_0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x491)]){if('FqrUX'===_0x5ddf82(0x164)){function _0x148794(){var _0x446412=_0x5ddf82;_0x417668[_0x446412(0x584)](_0x507fca(_0xfdd51e[_0x446412(0x50e)]));}}else updateDirectorVideoMute(_0x4f97d2);}}else _0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x491)]=_0x58cc22[_0x5ddf82(0x53f)]['directorVideoMuted'],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['directorVideoMuted']&&(_0x4f97d2 in _0x162eb3[_0x5ddf82(0x1f4)]&&_0x162eb3[_0x5ddf82(0x4e7)](0x0,_0x4f97d2));}_0x5ddf82(0x39e)in _0x58cc22[_0x5ddf82(0x53f)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x1ae)]=_0x58cc22[_0x5ddf82(0x53f)][_0x5ddf82(0x39e)],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x1ae)]&&(_0x162eb3[_0x5ddf82(0x1b6)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x127)][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]=_0x5ddf82(0x545))));if(_0x4f97d2===_0x162eb3[_0x5ddf82(0x37c)])try{_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x14f)]['info'][_0x5ddf82(0x1b6)]=!![];}catch(_0x496f22){}mustUpdateuserList=!![];}}if(_0x5ddf82(0x4de)in _0x58cc22){if(_0x5ddf82(0x217)!==_0x5ddf82(0x1b4)){if(_0x162eb3[_0x5ddf82(0x37c)]===_0x4f97d2){_0x5ddf82(0x262)in _0x58cc22[_0x5ddf82(0x4de)]&&(_0x162eb3[_0x5ddf82(0x262)]=parseInt(_0x58cc22[_0x5ddf82(0x4de)][_0x5ddf82(0x262)])||0x0,_0x33935f=!![]);if(_0x58cc22[_0x5ddf82(0x4de)][_0x5ddf82(0x210)]){if(_0x58cc22['directorSettings'][_0x5ddf82(0x210)]===_0x162eb3[_0x5ddf82(0x34f)])_0x162eb3['infocus']=!![];else for(var _0x5a1578 in _0x162eb3[_0x5ddf82(0x1f4)]){if(_0x162eb3[_0x5ddf82(0x1f4)][_0x5a1578]['streamID']===_0x58cc22['directorSettings'][_0x5ddf82(0x210)]){if(_0x5ddf82(0x3b1)!=='xCgHZ'){_0x162eb3['infocus']=_0x5a1578;break;}else{function _0x1d6cbb(){var _0x235516=_0x5ddf82;_0x1a54b1[_0x235516(0x1f4)][_0xe9935][_0x235516(0x340)]&&(_0x5c7a29[_0x235516(0x1f4)][_0x2cb79f]['videoElement']['recording']&&(_0x41cdb0[_0x235516(0x1f4)][_0x5452fc][_0x235516(0x340)]['recorder']['writer'][_0x235516(0x556)](),_0x54ae20[_0x235516(0x1f4)][_0xe0c05b]['videoElement']['recording']=![])),_0x2899fa[_0x235516(0x1f4)][_0x2a9ad2][_0x235516(0x556)](),_0x1facd8[_0x235516(0x1f4)][_0xa6d46e]=null,delete _0x14ae3a[_0x235516(0x1f4)][_0x201682];}}}}_0x33935f=!![],mustUpdateuserList=!![];}if(_0x162eb3[_0x5ddf82(0x145)]!==![]){if(_0x58cc22[_0x5ddf82(0x4de)][_0x5ddf82(0x145)])for(var _0x5a1578 in _0x58cc22[_0x5ddf82(0x4de)][_0x5ddf82(0x145)]){setTimeout(function(_0x15783d){var _0x4f3e2e=_0x5ddf82;if(_0x4f3e2e(0x26d)!=='bIJNl'){function _0x386e38(){var _0x39cec5=_0x4f3e2e;if(_0x15554a['bitrate_set']!==![]){let _0x112792=_0x167594[_0x39cec5(0x1ca)][_0x39cec5(0x549)](_0x435256[_0x39cec5(0x1f4)][_0x3f3b02][_0x39cec5(0x34f)]);_0x1ad274['bitrate_set'][_0x39cec5(0x3f4)]>_0x112792&&(_0x126535[_0x39cec5(0x1f4)][_0xc4a886][_0x39cec5(0x538)]=_0x838f1d(_0x3e9e1e[_0x39cec5(0x54e)][_0x112792]),_0x4f4db7[_0x39cec5(0x1f4)][_0x2f8bc1][_0x39cec5(0x538)]<=0x0&&(_0x373a5e[_0x39cec5(0x1f4)][_0x4bbec6]['manualBandwidth']=![]));}}}else _0x162eb3[_0x4f3e2e(0x20b)](_0x15783d);},0x3e8,_0x58cc22[_0x5ddf82(0x4de)][_0x5ddf82(0x145)][_0x5a1578]);}if(_0x58cc22['directorSettings'][_0x5ddf82(0x2c6)])for(var _0x5a1578 in _0x58cc22[_0x5ddf82(0x4de)][_0x5ddf82(0x2c6)]){setTimeout(function(_0x3c2715){var _0x2d0027=_0x5ddf82;_0x162eb3[_0x2d0027(0x20b)](_0x3c2715);},0x3e8,_0x58cc22[_0x5ddf82(0x4de)][_0x5ddf82(0x2c6)][_0x5a1578]);}}}}else{function _0x43b25f(){_0x128008(_0x2ab4f1);}}}_0x162eb3[_0x5ddf82(0x37c)]===_0x4f97d2&&(_0x162eb3['scene']!==![]&&(_0x5ddf82(0x328)in _0x58cc22&&_0x162eb3[_0x5ddf82(0x20b)](_0x58cc22)));if('order'in _0x58cc22){_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2c5)]=parseInt(_0x58cc22[_0x5ddf82(0x2c5)])||0x0;_0x4f97d2 in _0x162eb3['pcs']&&(_0x162eb3[_0x5ddf82(0x147)][_0x4f97d2][_0x5ddf82(0x2c5)]=parseInt(_0x58cc22[_0x5ddf82(0x2c5)])||0x0);if(_0x162eb3[_0x5ddf82(0x1b6)]){var _0xd954c9=document[_0x5ddf82(0x41a)](_0x5ddf82(0x330)+_0x4f97d2+'\x22]');if(_0xd954c9[0x0]){if(_0x5ddf82(0x463)==='SoyDm')_0xd954c9[0x0][_0x5ddf82(0x27f)]=parseInt(_0x58cc22[_0x5ddf82(0x2c5)])||0x0;else{function _0x5648b8(){var _0x5cc745=_0x5ddf82;_0x3ffbe1[_0x5cc745(0x23a)](_0x4b5b9f,_0x5da69f[_0x5cc745(0x4f1)]['dataset'][_0x5cc745(0x1e2)]);}}}}_0x33935f=!![];}if(_0x5ddf82(0x42f)in _0x58cc22){log('Change\x20Label');if('value'in _0x58cc22){log(_0x5ddf82(0x230));if(typeof _0x58cc22['value']=='string'){if(_0x5ddf82(0x1ef)!==_0x5ddf82(0x1ef)){function _0x2cbe22(){var _0x27ebaf=_0x5ddf82;_0x30a583['roombitrate']!==![]&&(_0x31f1fd[_0x27ebaf(0x4c0)]<_0x3df95b&&(_0x320c96=_0x313423['roombitrate']));}}else{_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['label']=sanitizeLabel(_0x58cc22[_0x5ddf82(0x276)]);_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2fa)][_0x5ddf82(0x3f4)]==0x0&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['label']=![]);if(_0x162eb3[_0x5ddf82(0x1b6)]){var _0xd954c9=getById(_0x5ddf82(0x427)+_0x4f97d2);if(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['label']){if(_0x5ddf82(0x374)===_0x5ddf82(0x374))_0xd954c9['innerText']=_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['label'];else{function _0x296059(){var _0x3a5f2e=_0x5ddf82;_0x22cd66[_0x3a5f2e(0x16b)][_0x3a5f2e(0x457)]=_0x1b8b9f['setOpusAttributes'](_0x3d60db[_0x3a5f2e(0x16b)]['sdp'],{'maxaveragebitrate':_0x550783[_0x3a5f2e(0xdf)]*0x400,'cbr':_0x2c0567[_0x3a5f2e(0x44e)]});}}}else{if(_0x5ddf82(0x104)===_0x5ddf82(0x119)){function _0x45cf29(){var _0x218ead=_0x5ddf82;_0x37c900[0x0][_0x218ead(0x276)]=_0x51cd14,_0x22dcde[_0x218ead(0x1f4)][_0x506010][_0x218ead(0x4f4)]=_0x909f63,_0x1e2d1c(_0x49c1db[0x0]);}}else _0xd954c9[_0x5ddf82(0x27f)]=_0x5ddf82(0x394);}}else _0x162eb3[_0x5ddf82(0x478)]&&(_0x33935f=!![]);}}else{_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x2fa)]=![];if(_0x162eb3[_0x5ddf82(0x1b6)]){var _0xd954c9=getById(_0x5ddf82(0x427)+_0x4f97d2);_0xd954c9[_0x5ddf82(0x27f)]=_0x5ddf82(0x394);}else _0x162eb3[_0x5ddf82(0x478)]&&(_0x33935f=!![]);}mustUpdateuserList=!![];}}if(_0x5ddf82(0x286)in _0x58cc22){if('VpOvt'===_0x5ddf82(0x543)){log(_0x58cc22),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x37b)]=_0x58cc22['muteState'],_0x162eb3[_0x5ddf82(0x4e7)](![],_0x4f97d2);if(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['stats'][_0x5ddf82(0x53f)]){if(_0x5ddf82(0x2bf)===_0x5ddf82(0x2bf))_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x14f)]['info'][_0x5ddf82(0x253)]=_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x37b)];else{function _0x103c26(){var _0x23710f=_0x5ddf82;if(_0x3941c6['soloChatUUID']in _0x1841aa[_0x23710f(0x147)]){}else _0x403cf9[_0x23710f(0x504)]=![];}}}_0x162eb3[_0x5ddf82(0x145)]===![]&&(_0x162eb3[_0x5ddf82(0x27b)]&&(!_0x162eb3[_0x5ddf82(0x14e)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)]?_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x37b)]?_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)][_0x5ddf82(0x21e)]['display']=_0x5ddf82(0x545):_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['remoteMuteElement'][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]='none':(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['remoteMuteElement']=getById(_0x5ddf82(0x13e))[_0x5ddf82(0x4df)](!![]),_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x167)]['id']=_0x5ddf82(0x539)+_0x4f97d2,_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x37b)]?_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]=_0x5ddf82(0x545):_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x167)][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]=_0x5ddf82(0x277),_0x33935f=!![]),mustUpdateuserList=!![])));}else{function _0x1c3652(){var _0x154f72=_0x5ddf82,_0x48853c=_0x34ecd0[0x0];_0x48853c[_0x154f72(0x2fa)]!=_0x154f72(0x2b8)&&(_0x4e649c[_0x154f72(0x1f4)][_0x56f848][_0x154f72(0x340)][_0x154f72(0x288)]=_0x32605f(_0x2537f1[_0x154f72(0x1f4)][_0x1c592e][_0x154f72(0x3d0)],_0x311887,_0x48853c));}}}if('requestSceneUpdate'in _0x58cc22){var _0x56a447=getChromeVersion();_0x56a447&&(_0x56a447<0x50&&(_0x33935f=!![]));}_0x5ddf82(0x1ae)in _0x58cc22&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x1ae)]=_0x58cc22[_0x5ddf82(0x1ae)],!_0x162eb3[_0x5ddf82(0x1b6)]?(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x1ae)]&&(_0x162eb3[_0x5ddf82(0x4e7)](0x0,_0x4f97d2),_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x31d)][_0x5ddf82(0x302)]=!![],_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['imageElement']['style'][_0x5ddf82(0x419)]=_0x5ddf82(0x302))),_0x33935f=!![]):_0x162eb3['rpcs'][_0x4f97d2][_0x5ddf82(0x1ae)]?_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2][_0x5ddf82(0x127)][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]=_0x5ddf82(0x3aa):_0x162eb3[_0x5ddf82(0x1f4)][_0x4f97d2]['remoteVideoMuteElement'][_0x5ddf82(0x21e)][_0x5ddf82(0x1fb)]='none',mustUpdateuserList=!![]);if(_0x5ddf82(0x51d)in _0x58cc22){if(!_0x162eb3[_0x5ddf82(0x1b6)]){if('target'in _0x58cc22){if(_0x162eb3[_0x5ddf82(0x37c)]===_0x4f97d2){var _0x319206=_0x58cc22[_0x5ddf82(0x324)];if(_0x319206===!![])_0x162eb3[_0x5ddf82(0x491)]=_0x58cc22['directVideoMuted'];else _0x319206 in _0x162eb3[_0x5ddf82(0x1f4)]&&(_0x162eb3[_0x5ddf82(0x1f4)][_0x319206]['directorVideoMuted']=_0x58cc22[_0x5ddf82(0x51d)],_0x162eb3[_0x5ddf82(0x1f4)][_0x319206][_0x5ddf82(0x491)]&&(_0x319206 in _0x162eb3[_0x5ddf82(0x1f4)]&&_0x162eb3[_0x5ddf82(0x4e7)](0x0,_0x319206)),_0x33935f=!![]);}}}mustUpdateuserList=!![];}_0x5ddf82(0x294)in _0x58cc22&&remoteStats(_0x58cc22);if(_0x33935f)setTimeout(function(){updateMixer(),updateUserList();},0x1);else mustUpdateuserList&&updateUserList();},_0x162eb3[_0x1a52d6(0x1f4)][_0x4f97d2][_0x1a52d6(0x228)][_0x1a52d6(0x45c)]=()=>{var _0x4dfdec=_0x1a52d6;log('rpc\x20datachannel\x20closed');try{var _0x1bf00b=_0x162eb3[_0x4dfdec(0x1f4)][_0x4f97d2]['streamID'];}catch(_0x25878e){}try{_0x162eb3[_0x4dfdec(0x1f4)][_0x4f97d2]['close']();}catch(_0x18772d){if(_0x4dfdec(0x19d)!==_0x4dfdec(0x2fb))errorlog(_0x4dfdec(0x450));else{function _0x186555(){var _0x21b738=_0x4dfdec;return _0x1d881f[_0x21b738(0x426)][_0x21b738(0x2a6)]({'name':_0x21b738(0x522),'iv':_0x987d81},_0x4a5b3e,_0x5c18d9)[_0x21b738(0x57e)](function(_0x35110a){var _0x2d63ea=_0x21b738,_0x499320=new _0x24795c(_0x35110a),_0x1691f0='';for(var _0x2c7884=0x0;_0x2c7884<_0x499320[_0x2d63ea(0xf9)];_0x2c7884++){_0x1691f0+=_0x6f9677['fromCharCode'](_0x499320[_0x2c7884]);}return _0x1691f0;},function(_0x2a9577){var _0x42ff43=_0x21b738;return _0x38e590(_0x2a9577[_0x42ff43(0x47c)]),![];});}}}try{if(_0x4dfdec(0x3ae)!==_0x4dfdec(0x3ae)){function _0xd5988(){_0x5dd19c(_0x5a269f);}}else _0x162eb3[_0x4dfdec(0x1f4)][_0x4f97d2][_0x4dfdec(0x3d0)]&&_0x162eb3[_0x4dfdec(0x1f4)][_0x4f97d2][_0x4dfdec(0x3d0)][_0x4dfdec(0x472)]()[_0x4dfdec(0x204)](function(_0x81d280){var _0xa7b67=_0x4dfdec;_0x81d280['stop'](),log(_0xa7b67(0x214));});}catch(_0x4ba8b8){}if(_0x162eb3['director'])try{_0x4dfdec(0x305)in _0x162eb3[_0x4dfdec(0x1f4)][_0x4f97d2][_0x4dfdec(0x340)]&&_0x162eb3[_0x4dfdec(0x1f4)][_0x4f97d2]['videoElement'][_0x4dfdec(0x305)][_0x4dfdec(0x529)]();}catch(_0x279f2b){warnlog(_0x279f2b);}try{document[_0x4dfdec(0x367)](_0x4dfdec(0x22e)+_0x4f97d2)&&getById(_0x4dfdec(0x22e)+_0x4f97d2)[_0x4dfdec(0x23c)][_0x4dfdec(0x45f)](getById(_0x4dfdec(0x22e)+_0x4f97d2));}catch(_0x596437){if(_0x4dfdec(0x213)===_0x4dfdec(0x213))warnlog(_0x596437);else{function _0x2cd67c(){var _0x3ed36e=_0x4dfdec;_0x353ffe['queueList'][_0x3ed36e(0x21d)](_0x39e339['streamID']),_0x306cb1[_0x3ed36e(0x309)]();}}}try{if('voePV'===_0x4dfdec(0x535))_0x162eb3['rpcs'][_0x4f97d2]=null,delete _0x162eb3[_0x4dfdec(0x1f4)][_0x4f97d2];else{function _0x597c2a(){var _0x16829f=_0x4dfdec;_0x68200f(_0x5bc7f4),_0x52ce08(_0x16829f(0x4b4));}}}catch(_0x49052a){}!_0x162eb3[_0x4dfdec(0x1b6)]&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x1bf00b==_0x4dfdec(0x2bd))return;try{warnlog(_0x4dfdec(0x3dc));if(_0x1bf00b in _0x162eb3[_0x4dfdec(0x4f2)]){if(_0x4dfdec(0x48d)===_0x4dfdec(0x48d))log('watchTimeoutList:'+_0x1bf00b),clearTimeout(_0x162eb3[_0x4dfdec(0x4f2)][_0x1bf00b]);else{function _0xf63df5(){var _0x304bd8=_0x4dfdec;_0x4dde48[_0x304bd8(0x147)][_0x27c220[_0x304bd8(0x37c)]]['stats'][_0x304bd8(0x53f)]&&(_0x3c32a6[_0x304bd8(0x147)][_0x1b72ae[_0x304bd8(0x37c)]][_0x304bd8(0x14f)][_0x304bd8(0x53f)][_0x304bd8(0x1b6)]=!![]);}}}_0x162eb3[_0x4dfdec(0x4f2)][_0x1bf00b]=setTimeout(function(_0x4799d8){var _0x462c25=_0x4dfdec;delete _0x162eb3[_0x462c25(0x4f2)][_0x4799d8],log(_0x462c25(0x24c)+_0x4799d8),_0x162eb3[_0x462c25(0x39b)](_0x4799d8);},_0x162eb3['retryTimeout'],_0x1bf00b);}catch(_0x5a1b22){errorlog(_0x5a1b22);}pokeIframeAPI(_0x4dfdec(0x1d4),![],_0x4f97d2),updateUserList();};},_0x162eb3[_0x4f7b4e(0x443)]=function(_0x2a8350){var _0x32e078=_0x4f7b4e;try{var _0x47ba09=_0x162eb3[_0x32e078(0x303)]||0x0;_0x47ba09=parseFloat(_0x47ba09);if(_0x162eb3[_0x32e078(0x303)]!==![]){var _0x154206=_0x162eb3[_0x32e078(0x1f4)][_0x2a8350][_0x32e078(0x586)]()[_0x32e078(0x44b)](),_0x3b32c6=0x0;_0x154206[_0x32e078(0x204)](function(_0x131dce){var _0x2bb969=_0x32e078;try{if('aGAzt'===_0x2bb969(0x1d9))for(var _0x306d13 in _0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)]){if(typeof _0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13]==_0x2bb969(0x1b1)&&_0x2bb969(0x180)in _0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13]&&_0x162eb3['rpcs'][_0x2a8350][_0x2bb969(0x14f)][_0x306d13][_0x2bb969(0x180)]===_0x131dce[_0x2bb969(0x2ac)]['id']&&_0x2bb969(0x4b3)in _0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13]){var _0x2c4a72=0x0;_0x162eb3['rpcs'][_0x2a8350][_0x2bb969(0x14f)][_0x306d13]['_sync_offset']?_0x2c4a72=_0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13][_0x2bb969(0x1bd)]:_0x162eb3['rpcs'][_0x2a8350][_0x2bb969(0x14f)][_0x306d13][_0x2bb969(0x1bd)]=0x0;_0x2c4a72+=_0x47ba09-_0x162eb3['rpcs'][_0x2a8350][_0x2bb969(0x14f)][_0x306d13]['Buffer_Delay_in_ms'];_0x2c4a72>_0x47ba09&&(_0x2c4a72=_0x47ba09);if(_0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13][_0x2bb969(0x1c0)]==_0x2bb969(0x25f)){if(_0x131dce[_0x2bb969(0x2ac)]['id']in _0x162eb3['rpcs'][_0x2a8350][_0x2bb969(0x2d0)]){log('updating\x20audio\x20delay');var _0x43bbb7=_0x3b32c6-_0x162eb3[_0x2bb969(0x1f4)][_0x2a8350]['stats'][_0x306d13][_0x2bb969(0x4b3)]+_0x162eb3[_0x2bb969(0x19b)];_0x43bbb7<0x0&&(_0x43bbb7=0x0),log(_0x2bb969(0x4ee)+_0x43bbb7),log(_0x2bb969(0x176)+_0x162eb3[_0x2bb969(0x1fa)][_0x2bb969(0x405)]),_0x162eb3['rpcs'][_0x2a8350]['delayNode'][_0x131dce[_0x2bb969(0x2ac)]['id']]['delayTime']['setValueAtTime'](parseFloat(_0x43bbb7/0x3e8),_0x162eb3[_0x2bb969(0x1fa)][_0x2bb969(0x405)]+0x1),_0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13][_0x2bb969(0x348)]=_0x43bbb7;}}else _0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13][_0x2bb969(0x1c0)]==_0x2bb969(0x3cb)&&(_0x3b32c6=_0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13][_0x2bb969(0x4b3)],_0x2c4a72<0x0&&(_0x2c4a72=0x0),_0x162eb3[_0x2bb969(0x1f4)][_0x2a8350][_0x2bb969(0x14f)][_0x306d13][_0x2bb969(0x1bd)]=_0x2c4a72,_0x131dce[_0x2bb969(0xe7)]=parseFloat(_0x2c4a72/0x3e8));}}else{function _0x155a18(){var _0x1de9ed=_0x2bb969;if(typeof _0x504867['ws']!=='object'||_0x3ab8cd['ws'][_0x1de9ed(0x2bb)]!==0x1)_0x1e1f9c(_0x30f930,'could\x20not\x20be\x20sent;\x20queuing\x20it'),_0x426235[_0x1de9ed(0x360)][_0x1de9ed(0x21d)](_0x51d9cc);else{var _0xcd0392=_0x379657[_0x1de9ed(0x444)](_0x49c70c);if(_0xcd0392[_0x1de9ed(0x3f4)]>0x3a98){_0x576050(_0x1de9ed(0x559));return;}_0x5c25d1['ws'][_0x1de9ed(0x388)](_0xcd0392);}}}}catch(_0x2aa9c7){errorlog(_0x2aa9c7);}});}}catch(_0x30a121){errorlog('device\x20does\x20not\x20support\x20playout\x20delay');}},_0x162eb3[_0x4f7b4e(0x339)]=function(_0x25823a){var _0x542172=_0x4f7b4e;if(!(_0x25823a in _0x162eb3[_0x542172(0x1f4)]))return;try{_0x162eb3[_0x542172(0x1f4)][_0x25823a]['videoElement'][_0x542172(0x291)]&&(log(_0x542172(0x341)),_0x162eb3[_0x542172(0x1f4)][_0x25823a][_0x542172(0x340)][_0x542172(0x238)]()[_0x542172(0x57e)](_0x4423fb=>{var _0x501c4e=_0x542172;log(_0x501c4e(0x2ee)),firstPlayTriggered=!![];})[_0x542172(0x19f)](warnlog));}catch(_0x499baf){};try{_0x162eb3['rpcs'][_0x25823a]['getStats']()[_0x542172(0x57e)](function(_0x26c3ba){var _0x537bbc=_0x542172;setTimeout(_0x162eb3[_0x537bbc(0x339)],0xbb8,_0x25823a),!_0x162eb3[_0x537bbc(0x1f4)][_0x25823a][_0x537bbc(0x14f)][_0x537bbc(0x446)]&&(_0x162eb3[_0x537bbc(0x1f4)][_0x25823a][_0x537bbc(0x14f)][_0x537bbc(0x446)]={}),_0x26c3ba['forEach'](_0x2fa6d8=>{var _0x5af592=_0x537bbc;if(_0x2fa6d8[_0x5af592(0x3de)]=='candidate-pair'&&_0x2fa6d8[_0x5af592(0x474)]==!![])_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x18a)]=_0x2fa6d8[_0x5af592(0x430)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)]['_remote_ice_id']=_0x2fa6d8[_0x5af592(0x30b)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x349)]=_0x2fa6d8[_0x5af592(0x2d7)]*0x3e8;else{if(_0x2fa6d8[_0x5af592(0x3de)]==_0x5af592(0x2ac)&&_0x2fa6d8['remoteSource']==!![]){if(_0x2fa6d8['id']in _0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats']){_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']]['_trackID']=_0x2fa6d8[_0x5af592(0x42d)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']][_0x5af592(0x4b3)]=parseInt(0x3e8*(parseFloat(_0x2fa6d8[_0x5af592(0x2e4)])-_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']][_0x5af592(0x516)])/(parseInt(_0x2fa6d8[_0x5af592(0x284)])-_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']][_0x5af592(0x45b)]))||0x0,_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']][_0x5af592(0x516)]=parseFloat(_0x2fa6d8[_0x5af592(0x2e4)])||0x0,_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']][_0x5af592(0x45b)]=parseInt(_0x2fa6d8[_0x5af592(0x284)])||0x0;if(_0x5af592(0x108)in _0x2fa6d8){if('frameHeight'in _0x2fa6d8){if(_0x5af592(0x428)==='rqIAh'){function _0x4f7df1(){_0x5181ad(_0xddbf56);}}else _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']][_0x5af592(0xfa)]=_0x2fa6d8[_0x5af592(0x108)]+'\x20x\x20'+_0x2fa6d8[_0x5af592(0x297)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']][_0x5af592(0x366)]=_0x2fa6d8[_0x5af592(0x108)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x2fa6d8['id']][_0x5af592(0x4b8)]=_0x2fa6d8['frameHeight'];}}}else{var _0x238eb9={};_0x238eb9[_0x5af592(0x516)]=parseFloat(_0x2fa6d8[_0x5af592(0x2e4)])||0x0,_0x238eb9[_0x5af592(0x45b)]=parseInt(_0x2fa6d8['jitterBufferEmittedCount'])||0x0,_0x238eb9[_0x5af592(0x4b3)]=0x0,_0x238eb9[_0x5af592(0x180)]=_0x2fa6d8['trackIdentifier'],_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['id']]=_0x238eb9;}}else{if(_0x2fa6d8[_0x5af592(0x3de)]=='remote-candidate'){if(_0x5af592(0x1ad)===_0x5af592(0x1ad)){if(_0x5af592(0x22a)in _0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)]&&_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats']['RTC\x20Connection'][_0x5af592(0x22a)]!=_0x2fa6d8['id'])return;_0x5af592(0x38f)in _0x2fa6d8&&('ip'in _0x2fa6d8&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x5af592(0x446)][_0x5af592(0x21b)]=_0x2fa6d8['ip']),_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x552)]=_0x2fa6d8[_0x5af592(0x38f)]);_0x5af592(0x2f0)in _0x2fa6d8&&(_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x10d)]=_0x2fa6d8[_0x5af592(0x2f0)]);if(_0x5af592(0x3a4)in _0x2fa6d8){if('KYmPH'===_0x5af592(0x31c))_0x162eb3['rpcs'][_0x25823a]['stats']['RTC\x20Connection'][_0x5af592(0x530)]=_0x2fa6d8[_0x5af592(0x3a4)];else{function _0x3e3b7a(){_0xf8b4e3=!![];}}}}else{function _0xa0fd3e(){var _0x23b507=_0x5af592;_0x4b8b37(_0x23b507(0x53c));}}}else{if(_0x2fa6d8[_0x5af592(0x3de)]==_0x5af592(0x573)){if(_0x5af592(0x18a)in _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)]&&_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)]['_local_ice_id']!=_0x2fa6d8['id'])return;_0x5af592(0x38f)in _0x2fa6d8&&('ip'in _0x2fa6d8&&(_0x162eb3['rpcs'][_0x25823a]['stats'][_0x5af592(0x446)][_0x5af592(0x47b)]=_0x2fa6d8['ip']),_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x56d)]=_0x2fa6d8['relayProtocol']);_0x5af592(0x2f0)in _0x2fa6d8&&(_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x212)]=_0x2fa6d8[_0x5af592(0x2f0)]);if(_0x5af592(0x3a4)in _0x2fa6d8){if(_0x5af592(0x19a)!==_0x5af592(0x19a)){function _0x39cc5c(){var _0x5837de=_0x5af592;_0x4ba063(_0x28bf66[_0x5837de(0x457)]),_0x21b30c[_0x5837de(0x457)]=_0x2fb5c6[_0x5837de(0xf7)](_0x81feec['sdp']);}}else _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x530)]=_0x2fa6d8[_0x5af592(0x3a4)];}}else{if(_0x2fa6d8[_0x5af592(0x3de)]==_0x5af592(0x4ca)){_0x5af592(0xef)in _0x2fa6d8&&('_bytesReceived'in _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)]&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x233)]&&(_0x2fa6d8[_0x5af592(0x189)]&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x5af592(0x446)][_0x5af592(0x28c)]=parseInt(0x8*(_0x2fa6d8[_0x5af592(0xef)]-_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x5af592(0x446)][_0x5af592(0xfc)])/(_0x2fa6d8['timestamp']-_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)]['RTC\x20Connection']['_timestamp']))))),_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)]['_bytesReceived']=_0x2fa6d8[_0x5af592(0xef)]);if(_0x5af592(0x189)in _0x2fa6d8){_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)]['RTC\x20Connection'][_0x5af592(0x233)]=_0x2fa6d8[_0x5af592(0x189)];if(!_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x5af592(0x446)][_0x5af592(0x3ed)])_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x5af592(0x446)][_0x5af592(0x3ed)]=_0x2fa6d8[_0x5af592(0x189)];else{if(_0x5af592(0x2b0)===_0x5af592(0x1ec)){function _0x2cf164(){var _0x486454=_0x5af592;_0x5aa2b6[_0x486454(0x512)][0x0][_0x486454(0x3b0)]=![];}}else _0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x446)][_0x5af592(0x296)]=parseInt((_0x2fa6d8['timestamp']-_0x162eb3['rpcs'][_0x25823a]['stats'][_0x5af592(0x446)]['_timestampStart'])/0x258)/0x64;}}}else{if(_0x2fa6d8[_0x5af592(0x3de)]==_0x5af592(0x4ac)&&_0x5af592(0x395)in _0x2fa6d8){_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]]=_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]]||{},_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x398)]=parseInt(0x8*(_0x2fa6d8[_0x5af592(0xef)]-_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x1fe)])/(_0x2fa6d8[_0x5af592(0x189)]-_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]]['_last_time'])),_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x1fe)]=_0x2fa6d8[_0x5af592(0xef)]||_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['trackId']][_0x5af592(0x1fe)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x40a)]=_0x2fa6d8['timestamp']||_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['trackId']][_0x5af592(0x40a)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x5af592(0x346)]=_0x2fa6d8[_0x5af592(0x31e)],_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x48b)]=_0x2fa6d8['trackId'];if(_0x2fa6d8[_0x5af592(0x101)]==_0x5af592(0x3cb)){_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x3de)]=_0x5af592(0x378),_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x1c0)]='video';if(_0x162eb3[_0x5af592(0x424)]&&'codec'in _0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)]&&_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x1d2)]==_0x5af592(0x578)){_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x431)]=_0x2fa6d8[_0x5af592(0x350)]-_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['trackId']][_0x5af592(0x476)]||0x0,_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x53a)]=_0x2fa6d8[_0x5af592(0x19c)]-_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x4a4)]+_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x53a)]||0x0,log(_0x5af592(0x53e));if(_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x431)]===0x0&&_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]]['nackTrigger']>=_0x162eb3['obsfix'])_0x162eb3[_0x5af592(0x1a9)](_0x25823a),_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]]['nackTrigger']=0x0,log(_0x5af592(0x2f4));else _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]]['pliDelta']>0x0&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x53a)]=0x0);}else{if(_0x162eb3[_0x5af592(0x424)]&&_0x5af592(0x1d2)in _0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats']&&_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x1d2)]==_0x5af592(0x227)){_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x431)]=_0x2fa6d8[_0x5af592(0x350)]-_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]]['keyFramesRequested_pli']||0x0,_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x53a)]=_0x2fa6d8[_0x5af592(0x19c)]-_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x4a4)]+_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['trackId']][_0x5af592(0x53a)]||0x0,log(_0x5af592(0x53e));if(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x431)]===0x0&&_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x53a)]>=_0x162eb3[_0x5af592(0x424)]*0x4)_0x162eb3[_0x5af592(0x1a9)](_0x25823a),_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x53a)]=0x0,log(_0x5af592(0x2f4));else _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['trackId']][_0x5af592(0x431)]>0x0&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['trackId']][_0x5af592(0x53a)]=0x0);}}_0x162eb3['rpcs'][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x476)]=_0x2fa6d8[_0x5af592(0x350)]||0x0,_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x4a4)]=_0x2fa6d8[_0x5af592(0x19c)]||0x0;if(_0x5af592(0x1e4)in _0x2fa6d8){if(_0x5af592(0x49d)===_0x5af592(0x19e)){function _0x2a1d57(){var _0x1d2d87=_0x5af592;_0x361ac6[_0x1d2d87(0x53f)][_0x1d2d87(0x30a)]&&_0x1c3500(_0x4e6f77);}}else _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x435)]=parseInt(_0x2fa6d8[_0x5af592(0x1e4)]);}else{if(_0x5af592(0x432)in _0x2fa6d8&&_0x2fa6d8['timestamp']){var _0x2ef192=0x0,_0x1465a4=0x0;try{_0x2ef192=_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x4e5)],_0x1465a4=_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x233)];}catch(_0x445372){}_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x435)]=parseInt(0xa*(_0x2fa6d8[_0x5af592(0x432)]-_0x2ef192)/(_0x2fa6d8[_0x5af592(0x189)]/0x3e8-_0x1465a4))/0xa,_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8['trackId']][_0x5af592(0x4e5)]=_0x2fa6d8[_0x5af592(0x432)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]]['_timestamp']=_0x2fa6d8[_0x5af592(0x189)]/0x3e8;}}}else{if(_0x2fa6d8[_0x5af592(0x101)]==_0x5af592(0x25f)){_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x3de)]=_0x5af592(0x54a),_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x1c0)]=_0x5af592(0x25f);if(_0x5af592(0x1ce)in _0x2fa6d8){if(_0x5af592(0x3fb)==='Rpahq'){function _0x23be84(){var _0x2fb7bd=_0x5af592;_0x30fdb3[_0x2fb7bd(0x2ac)][_0x2fb7bd(0x2f1)]=![];}}else _0x162eb3['rpcs'][_0x25823a]['stats'][_0x2fa6d8['trackId']][_0x5af592(0x501)]=parseInt(parseFloat(_0x2fa6d8['audioLevel'])*0x2710)/0x2710;}}}_0x5af592(0x408)in _0x2fa6d8&&_0x5af592(0x31a)in _0x2fa6d8&&(!(_0x5af592(0x1f1)in _0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]])&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x1f1)]=_0x2fa6d8['packetsLost']),!(_0x5af592(0x4d5)in _0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]])&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x4d5)]=_0x2fa6d8['packetsReceived']),!(_0x5af592(0x486)in _0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]])&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x486)]=0x0),_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x486)]=_0x162eb3['rpcs'][_0x25823a]['stats'][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x486)]*0.35+0.65*((_0x2fa6d8[_0x5af592(0x408)]-_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x1f1)])*0x64)/(_0x2fa6d8[_0x5af592(0x31a)]-_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x4d5)]+(_0x2fa6d8[_0x5af592(0x408)]-_0x162eb3['rpcs'][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x1f1)]))||0x0,_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]]['_packetsReceived']=_0x2fa6d8[_0x5af592(0x31a)],_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x2fa6d8[_0x5af592(0x395)]][_0x5af592(0x1f1)]=_0x2fa6d8[_0x5af592(0x408)]);}else{if('_codecId'in _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)]&&_0x2fa6d8['id']==_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x346)]){_0x5af592(0x53d)in _0x2fa6d8&&(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x48b)]]?_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x5af592(0x48b)]][_0x5af592(0x1d2)]=_0x2fa6d8['mimeType']:(_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x162eb3[_0x5af592(0x1f4)][_0x25823a]['stats'][_0x5af592(0x48b)]]={},_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0x48b)]][_0x5af592(0x1d2)]=_0x2fa6d8[_0x5af592(0x53d)]));if(_0x5af592(0x297)in _0x2fa6d8){if(_0x5af592(0x108)in _0x2fa6d8){if(_0x5af592(0x3e8)!=='elUNs'){function _0x55d2bf(){var _0x51a5c1=_0x5af592;_0x458da3[_0x51a5c1(0x147)][_0x170144[_0x51a5c1(0x37c)]][_0x51a5c1(0x14f)]['info']&&(_0x48d4fd[_0x51a5c1(0x147)][_0x5e54db[_0x51a5c1(0x37c)]][_0x51a5c1(0x14f)][_0x51a5c1(0x53f)][_0x51a5c1(0x1b6)]=!![]);}}else _0x162eb3[_0x5af592(0x1f4)][_0x25823a][_0x5af592(0x14f)][_0x5af592(0xfa)]=parseInt(_0x2fa6d8[_0x5af592(0x108)])+_0x5af592(0x415)+parseInt(_0x2fa6d8[_0x5af592(0x297)]);}}}}}}}}}}),_0x162eb3[_0x537bbc(0x303)]!==![]&&_0x162eb3[_0x537bbc(0x443)](_0x25823a),setTimeout(function(){var _0x1706e2=_0x537bbc;_0x162eb3[_0x1706e2(0x4ba)](),_0x162eb3[_0x1706e2(0x51e)]();},0x0);});}catch(_0x4f7832){errorlog(_0x4f7832);}},_0x162eb3[_0x4f7b4e(0x1f4)][_0x4f97d2][_0x4f7b4e(0x25a)]=_0x195194=>{var _0x3f4ad9=_0x4f7b4e;log('New\x20ON\x20TRACK\x20event');if(_0x162eb3[_0x3f4ad9(0x303)]!==![]){if('DTlEf'!==_0x3f4ad9(0x479)){function _0x38ab12(){_0x20395c('already\x20closed\x20PCS');}}else _0x162eb3[_0x3f4ad9(0x443)](_0x4f97d2);}_0x162eb3[_0x3f4ad9(0x4ba)](),_0x162eb3[_0x3f4ad9(0x51e)]();if(_0x195194['streams']&&_0x195194[_0x3f4ad9(0x3f9)][0x0]){_0x195194[_0x3f4ad9(0x3f9)][0x0][_0x3f4ad9(0x15a)]=function(_0x3e4f4b){var _0x2bbc46=_0x3f4ad9;try{if(_0x2bbc46(0x182)===_0x2bbc46(0x20c)){function _0x3da866(){var _0x3b0fcf=_0x2bbc46;_0x2a100b(_0x3b0fcf(0x28d));}}else warnlog('Track\x20was\x20removed'),_0x162eb3[_0x2bbc46(0x1f4)][_0x4f97d2][_0x2bbc46(0x3d0)][_0x2bbc46(0x2fc)]()[_0x2bbc46(0x204)](_0x4fcf5e=>{var _0x31cd4f=_0x2bbc46;_0x4fcf5e['id']==_0x3e4f4b[_0x31cd4f(0x2ac)]['id']&&_0x162eb3[_0x31cd4f(0x1f4)][_0x4f97d2]['streamSrc']['removeTrack'](_0x4fcf5e);}),_0x162eb3[_0x2bbc46(0x1f4)][_0x4f97d2][_0x2bbc46(0x340)]['srcObject']=_0x162eb3[_0x2bbc46(0x1f4)][_0x4f97d2][_0x2bbc46(0x3d0)],setTimeout(function(){updateMixer();},0x1);}catch(_0x503d5b){}},_0x195194[_0x3f4ad9(0x3f9)][0x0][_0x3f4ad9(0x409)]=function(_0x1c2e84){var _0x4293f5=_0x3f4ad9;try{warnlog(_0x4293f5(0x1fc)),_0x162eb3[_0x4293f5(0x1f4)][_0x4f97d2][_0x4293f5(0x3d0)][_0x4293f5(0x2fc)]()[_0x4293f5(0x204)](_0x4d1d72=>{var _0x417a27=_0x4293f5;_0x4d1d72['id']==_0x1c2e84[_0x417a27(0x2ac)]['id']&&_0x162eb3[_0x417a27(0x1f4)][_0x4f97d2][_0x417a27(0x3d0)][_0x417a27(0x4dc)](_0x4d1d72);}),_0x162eb3[_0x4293f5(0x1f4)][_0x4f97d2][_0x4293f5(0x340)][_0x4293f5(0x288)]=_0x162eb3[_0x4293f5(0x1f4)][_0x4f97d2][_0x4293f5(0x3d0)];}catch(_0x1fe405){};};var _0x58321f=_0x195194['streams'][0x0][_0x3f4ad9(0x2fc)]()[_0x3f4ad9(0x3f4)];_0x58321f>0x1&&errorlog(_0x3f4ad9(0x55a));}if(_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2]['videoElement']){if(_0x195194[_0x3f4ad9(0x3f9)]&&_0x195194[_0x3f4ad9(0x3f9)][0x0]){if(!_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)]){if(_0x3f4ad9(0x234)===_0x3f4ad9(0x234))_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)]=_0x195194[_0x3f4ad9(0x3f9)][0x0];else{function _0x6054a3(){var _0x10caa2=_0x3f4ad9;_0x10eab1[_0x10caa2(0x147)][_0x239d13['directorUUID']][_0x10caa2(0x14f)][_0x10caa2(0x53f)]['director']=!![];}}}else{var _0x4d8413=![];_0x195194[_0x3f4ad9(0x3f9)][0x0]['getTracks']()[_0x3f4ad9(0x204)](_0x29ebfe=>{var _0x1da702=_0x3f4ad9;_0x4d8413&&(warnlog(_0x1da702(0x55d)),warnlog(_0x29ebfe)),_0x29ebfe[_0x1da702(0x2c3)]==_0x1da702(0x3cb)&&(_0x162eb3['rpcs'][_0x4f97d2][_0x1da702(0x3d0)][_0x1da702(0x2fc)]()[_0x1da702(0x204)](_0x135695=>{var _0x46571f=_0x1da702;_0x162eb3['rpcs'][_0x4f97d2][_0x46571f(0x3d0)][_0x46571f(0x4dc)](_0x135695);}),_0x4d8413=!![]),log(_0x1da702(0x385)),_0x162eb3['rpcs'][_0x4f97d2][_0x1da702(0x3d0)][_0x1da702(0x496)](_0x29ebfe);});}try{if(_0x3f4ad9(0x251)===_0x3f4ad9(0x1bb)){function _0x80aab0(){_0x3b3c5b(_0x427c96),_0x3d4399(_0xa0f94f);}}else _0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x340)][_0x3f4ad9(0x288)]=_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)];}catch(_0x27dea1){errorlog('4722');}log(_0x3f4ad9(0x44a));}else{if(_0x195194[_0x3f4ad9(0x2ac)]){if('oylvJ'===_0x3f4ad9(0x27a)){function _0x538e78(){_0x5f5576(_0x549eaa);}}else{warnlog(_0x3f4ad9(0x580));!_0x162eb3['rpcs'][_0x4f97d2][_0x3f4ad9(0x3d0)]?_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)]=new MediaStream():_0x195194[_0x3f4ad9(0x2ac)][_0x3f4ad9(0x2c3)]==_0x3f4ad9(0x3cb)&&_0x162eb3['rpcs'][_0x4f97d2][_0x3f4ad9(0x3d0)][_0x3f4ad9(0x2fc)]()['forEach'](_0x4ce975=>{var _0x3f9769=_0x3f4ad9;_0x162eb3[_0x3f9769(0x1f4)][_0x4f97d2][_0x3f9769(0x3d0)][_0x3f9769(0x4dc)](_0x4ce975);});_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)]['addTrack'](_0x195194[_0x3f4ad9(0x2ac)]);try{_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x340)][_0x3f4ad9(0x288)]=_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)];}catch(_0x341ba4){errorlog('4722');}}}else{if(_0x3f4ad9(0x11c)!==_0x3f4ad9(0x355))errorlog('NO\x20TRACK??\x20--\x20not\x20expected');else{function _0x102f03(){_0x60d1fd(_0x5d89bd);}}}}setTimeout(function(){updateMixer();},0x1);}else{log(_0x3f4ad9(0x1c2));var _0x39a3d1=document[_0x3f4ad9(0x4da)]('video');_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x340)]=_0x39a3d1,_0x39a3d1[_0x3f4ad9(0x4e1)][_0x3f4ad9(0x1e2)]=_0x4f97d2,_0x39a3d1['id']='videosource_'+_0x4f97d2;_0x162eb3['rpcs'][_0x4f97d2]['streamID']&&(_0x39a3d1['dataset'][_0x3f4ad9(0x1bf)]=_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x34f)]);setupIncomingVideoTracking(_0x39a3d1,_0x4f97d2);if(_0x195194['streams']&&_0x195194['streams'][0x0]){var _0x2d9d09=_0x195194[_0x3f4ad9(0x3f9)][0x0];_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)]=_0x195194[_0x3f4ad9(0x3f9)][0x0],_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x340)][_0x3f4ad9(0x288)]=_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)],log(_0x3f4ad9(0x44a));}else{if(_0x195194[_0x3f4ad9(0x2ac)]){if(_0x3f4ad9(0x3f2)!==_0x3f4ad9(0x363))warnlog(_0x3f4ad9(0x580)),!_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)]&&(_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)]=new MediaStream()),_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2]['streamSrc'][_0x3f4ad9(0x496)](_0x195194[_0x3f4ad9(0x2ac)]),_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x340)][_0x3f4ad9(0x288)]=_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x3d0)];else{function _0x16ea2a(){var _0x3971af=_0x3f4ad9;if(_0x3b17d5[_0x3971af(0x475)])return;}}}}if(_0x162eb3['scale']){var _0x40fa09={};_0x40fa09[_0x3f4ad9(0x3ea)]=parseInt(_0x162eb3[_0x3f4ad9(0x3ea)]),log(_0x40fa09),_0x162eb3[_0x3f4ad9(0x196)](_0x40fa09,_0x4f97d2);}}if(_0x162eb3['audioEffects']===!![]){var _0x574586=function(_0x1143cf){var _0x2b3453=_0x3f4ad9;if(_0x2b3453(0x497)!==_0x2b3453(0x497)){function _0x2cc3d3(){var _0x10e5fc=_0x2b3453;_0x3f13b1['webp']?(_0x2d3d28['broadcast']=!![],_0x52e8ef['video']=![]):_0x5259ac[_0x10e5fc(0x3cb)]=!![];}}else{var _0x5700a6=function(_0x2d2d1b){var _0x59f6ff=_0x2b3453;if(!_0x162eb3['rpcs'][_0x2d2d1b])return;var _0x8aa3a3=_0x162eb3['rpcs'][_0x2d2d1b][_0x59f6ff(0x340)][_0x59f6ff(0x253)];_0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b][_0x59f6ff(0x340)][_0x59f6ff(0x253)]=![],_0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b][_0x59f6ff(0x340)][_0x59f6ff(0x365)](_0x59f6ff(0x238),_0x5700a6);_0x162eb3[_0x59f6ff(0x1fa)][_0x59f6ff(0x487)]==_0x59f6ff(0x4cc)&&_0x162eb3[_0x59f6ff(0x1fa)][_0x59f6ff(0x335)]();var _0x1432d8=_0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b][_0x59f6ff(0x3d0)][_0x59f6ff(0x28e)]();if(_0x1432d8[_0x59f6ff(0x3f4)]){var _0x46c622=_0x1432d8[0x0];if(_0x46c622[_0x59f6ff(0x2fa)]!=_0x59f6ff(0x2b8)){if('jfpwe'!==_0x59f6ff(0x37e)){function _0x315050(){var _0x52ba77=_0x59f6ff;_0x252aaf[_0x31c2c4][_0x52ba77(0x2ac)]['enabled']=!_0x2ac1b3[_0x52ba77(0x30a)];}}else _0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b][_0x59f6ff(0x340)][_0x59f6ff(0x288)]=addAudioPipeline(_0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b][_0x59f6ff(0x3d0)],_0x2d2d1b,_0x46c622);}}else _0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b]['videoElement'][_0x59f6ff(0x288)]=_0x162eb3['rpcs'][_0x2d2d1b][_0x59f6ff(0x3d0)];_0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b][_0x59f6ff(0x340)][_0x59f6ff(0x253)]=_0x8aa3a3,delete _0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b][_0x59f6ff(0x1e1)],_0x59f6ff(0x1e1)in _0x162eb3[_0x59f6ff(0x1f4)][_0x2d2d1b]&&errorlog(_0x59f6ff(0x219));};return _0x5700a6(_0x1143cf);}};_0x162eb3[_0x3f4ad9(0x1fa)]['state']==_0x3f4ad9(0x4a3)&&(_0x162eb3[_0x3f4ad9(0x3ff)]=!![]);if(_0x3f4ad9(0x1e1)in _0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2]){}else _0x162eb3[_0x3f4ad9(0x3ff)]==![]?_0x162eb3['rpcs'][_0x4f97d2][_0x3f4ad9(0x1e1)]=setInterval(function(_0x2b2a5a){var _0x5daa3e=_0x3f4ad9;log('..\x20waiting\x20for\x20user\x20gesture'),_0x162eb3[_0x5daa3e(0x1f4)][_0x2b2a5a]&&(_0x162eb3[_0x5daa3e(0x3ff)]&&(clearInterval(_0x162eb3['rpcs'][_0x2b2a5a][_0x5daa3e(0x1e1)]),_0x162eb3[_0x5daa3e(0x1f4)][_0x2b2a5a][_0x5daa3e(0x340)]['addEventListener'](_0x5daa3e(0x238),_0x574586(_0x2b2a5a))));},0x3e8,_0x4f97d2):(!_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x1e1)]&&(_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2]['eventPlayActive']=!![]),_0x162eb3[_0x3f4ad9(0x1f4)][_0x4f97d2][_0x3f4ad9(0x340)][_0x3f4ad9(0x1b8)](_0x3f4ad9(0x238),_0x574586(_0x4f97d2)));}_0x162eb3[_0x3f4ad9(0x4ba)](),_0x162eb3[_0x3f4ad9(0x51e)](),updateUserList();},log(_0x4f7b4e(0x3a7));},_0x162eb3;}();
\ No newline at end of file
+/*
+* Copyright (c) 2020 Steve Seguin. All Rights Reserved.
+*
+* This file is part of VDO.Ninja, yet is not intended to be modified.
+* This file cannot be modified without the express permission of its author.
+* No warranty, explicit or implicit, provided.
+*
+*/
+var _0xb550=['ICE\x20FAILED','scaleWidth','salt','join','warn','pre\x20pixel\x20fix\x20','session','Avmdq','iSoNh','Enable\x20the\x20director\x27s\x20microphone\x20first.','CLOSED','remoteZoom','stereo','frameWidth','cleanDirector','setVideoScale','limitAudio','container_','then','maxvideobitrate','play\x20stream:\x20','charAt','pixelFix','currentTime','turns:turn.obs.ninja:443','EVENT\x20TRACK\x20instead\x20of\x20event\x20Stream','soloVideo','head4','oGFnS','Audio\x20Track','pcs','[data-action-type=\x22solo-chat\x22][data--u-u-i-d=\x22','oBIGJ','watchTimeoutList','pzamG','seeding','msg\x20size\x20error','videoMutedFlag','sensorData','UlohH','_codecId','ptime','watchStream','cursor','IitWD','substring','muted','decrypt','epPRA','speedtest','delayTime','TRYING\x20KEYFRAME','nmZax','OTWyf','receiveChannel','sceneSync','scaleResolutionDownBy\x20set\x201!','low','KPytZ','currentCameraConstraints','noREMB','outputDevice','sampleRate','[data-action-type=\x22volume\x22][data--u-u-i-d=\x22','stun:stun.l.google.com:19302','pluginVersion','send','Does\x20Local\x20Stream\x20Source\x20EXIST?','object','onclose','kvwcZ','caCFr','codec','volume','recording','encryptMessage','applySoloChat','limitTotalBitrate','Not\x20director','msg','active','allowAudio','hxFAW','RTC\x20Connection','tlHPQ','tabernac','1PbANlX','decryptMessage','gain','recording_audio_gain','importCrypto','message','RTC\x20connection\x20is\x20ALREADY\x20ready;\x20we\x20can\x20already\x20accept\x20answers','dOUQJ','vector','generateStreamID','KDsnw','_last_time','Xiejf','createOffer','steve','directorDisplayMuted','sceneList','answer','PCS\x20WINS\x20ICE','updateLocalStatsInterval','sceneType','transferred','float2','BITRATE:\x20','style','alert','VIDEO\x20TRACK;\x20already\x20one\x20added','trackIdentifier','publicKey','connectionState','Round_Trip_Time_ms','encode','height_url','iOS\x20guest\x20SCALE\x20set!','tainted','local-candidate','indexOf','rpcs','signData','CFFyO','packetsReceived','session.videoElement.srcObject\x20failed;\x20but\x20streamSrc\x20worked?','sid','rpc\x20datachannel\x20closed','showlabels','roomclaimed','227193XsJqxb','obsSourceActive','defaultPassword','BKGTe','DnEXO','watchTimeoutList:','Create\x20a\x20new\x20RTC\x20connection;\x20offering\x20SDP\x20on\x20request','setRemoteDescription','forcePLI','Couldn\x27t\x20re-connect','_jitter_delay','obs','nackCount','showDirector','HIxFv','muted_savedState','hssConnection','Firefox','EKGhp','Remote\x20peer\x20disconnected.\x20Due\x20to\x20enhanced\x20security,\x20please\x20refresh\x20to\x20create\x20a\x20new\x20connection.','You\x27ve\x20been\x20transferred','sourceActive','fadein','NSHpM','DhmAz','failed','_framesDecoded','firstPlayTriggered','raisehands','playoutdelay','VYzJp','currentAudioConstraints','pdZig','mediaDevices','ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789','requestVideoHack','videoElement','unified-plan','Setting\x20view\x20to\x20null\x20disables\x20all\x20playback','remoteControl','obsstudio','focus','maxiosbitrate','networkType','dynamicScale','udp','lowiosviewers','keyframerate','createDataChannel','constructor','audioContext','createObjectURL','streamSrc','seeding\x20blocked','director','WEBRTC\x20CONNECTION\x20OPEN','meterStyle','max','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.','joinRoom','post\x20pixel\x20fix\x20','generateCrypto','sendPeers','lvrft','someonejoined','effects','requestAudioHack','enhanceAudioEncoder','connected','location','audiobitrate','createElement','Incoming\x20Ice\x20Offer\x20does\x20not\x20match\x20Session','bhNfq','float','aec_url','running','iOS\x20devices\x20do\x20not\x20support\x20dynamic\x20bitrates\x20correctly;\x20skipping','lowcut','eFjYM','className','KroGV','stopPropagation','iframe_','maxframerate_q2','add','EMBiv','reduce','catch','[data-action-type=\x22solo-chat\x22]','getTracks','quality_ss','totalRoomBitrate','queueNotification','chatbutton','speakerMute','directorDisplayMute','firefox','LACap','RJbpk','requestChangeEQ','GOT\x20ICES!!','Someone\x20published\x20a\x20video\x20to\x20the\x20Room','framesDecoded','muteStateTemplate','ZlfPb','substr','lowerhand','gyro','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x202','mSMeW','GOT\x20ICE!!','webkitAudioContext','_trackID','\x20x\x20','mediaType','failed\x20to\x20send\x20zoom\x20change\x20request','refreshScale','starting\x20kicker','playback_audio_pipeline','total_recv_bitrate_kbps','remoteDescription','high','anyrequest','new-push-connection','slice','playback_audio_samplerate','MAKING\x20A\x20NEW\x20RTC\x20CONNECTION','stun:stun4.l.google.com:19302','iugHh','_remote_ice_id','sHkZy','XrCwn','audioCtx','New\x20ON\x20TRACK\x20event','KBvmG','getVideoSettings','byteLength','rQwNB','audioDevice','maxptime','cleanish','RTCRtpSender','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x203','iQjbj','getStats','channel','deferring\x20with\x20a\x20promise','processDescription','iceTimer','iframe','enhacing\x20audio\x20encoder','classList','audioLevel','echoCancellation','You\x27ve\x20been\x20transferred\x20to\x20a\x20different\x20room','writer','labelsize','FAIL\x20rpcs','zoom\x20success','transcript','Lowered\x20hand','quality_wb','transparent','prototype','limitaudio','kijlv','overlay','fromCharCode','connect','streams','floor','state','click','jitterBufferDelay','empty\x20ice..','request\x20rate\x20limit:\x20','zQNDG','getCapabilities','mykey','_timestamp','videoDevice','FCuvh','view_set','pcs\x20RTC\x20CLOSED','ICE:\x20','getVideoBitrates','showSettings','onconnectionstatechange','localDescription','Bitrate_in_kbps','BdBIq','JNPbp','already\x20connected','ZjfZj','addEventListener','credential','setAudioBitrate','scale','\x20-\x20Transferred','audioInputChannels','migrate','width','_timestampStart','PPyWU','rXkmK','iceServers','network_type','pointer','pcs\x20RTC\x20Failed','aXrft','kvUOY','BOviK','quality','Message\x20to\x20be\x20sent:\x20','remove','iceBundle','MbLVs','quality_url','ontrack','iframeEle','bit\x20rate\x20being\x20munged','NO\x20TRACK??\x20--\x20not\x20expected','onopen','&room=','BVlYh','relative','obsStreaming','chrome','couldn\x27t\x20set\x20rate\x20limit','uXadO','keyFramesRequested_pli','WFfvh','changeLabel','maxvb_url','queueList','opacity','Lizwr','turn:turn.obs.ninja:3478','sending\x20message\x20to\x20server','Change\x20Label','candidateType','processStats','hNtsf','atUqR','oNPjF','xAGtI','packetLoss_in_percentage','innerText','BxypY','DDyYH','ab_url','test','Someone\x20sent\x20us\x20an\x20ANSWER\x20sdp??','concat','UN-MUTED','webPquality','value','sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message;\x20RTC\x20peers\x20only','key','video','random','getAudioSettings','_local_ice_id','min','playing','pliDelta','block','remote','stopping\x20old\x20track','NetEl','noiseSuppression','adaptivePtime','exclude','stringify','audioBitrate','failed\x20to\x20send\x20focus\x20change\x20request','scaleFactor','failed\x20to\x20disconnect','close','postMessage','WyZpt','request\x20zoom\x20change:\x20','QKCeI','publishing\x20SDP\x20Offer:\x20','MORE\x20THAN\x20ONE\x20VIDEO\x20TRACK\x20IS\x20BEING\x20ADDED','done\x20replacing/adding\x20tracks','audioMeterGuest','sendMsg','pop','yrUdk','_bytesReceived','maxviewers_url','candidates','includes','disableOBS','delayNode','limitTotalBitrateGuests','codecId','directorVideoMuted','Unable\x20to\x20set\x20update\x20OBS\x20Visibility','qHMGV','setupYourOwnPlease','children','find','AGzDN','CAMERA/MIC\x20SOURCE\x20ALLOCATION\x20FAILED.\x20Cant\x27\x20share\x20media\x20streams\x20as\x20a\x20result.\x20Maybe\x20this\x20is\x20a\x20Director\x20joining?','checking','IrsBB','videoaddedtoroom','sceneDisplay','local','ICE\x20target\x20no\x20longer\x20exists?','resolve','411874FYbvuc','disableNACK','Publisher\x20is\x20being\x20sent\x20a\x20video\x20stream???\x20NOT\x20EXPECTED!','suspended','label','PMOlm','SET\x20SCALING\x20IS\x20FIRING,\x20which\x20is\x20GOOD\x20!!!!!!','exportKey','ping','Someone\x20Joined\x20the\x20Room','LROZO','packetsLost','VkYXU','directorChat','closed','vIiCT','zHJNR','eRKEu','allowmidi','reconnected','Room\x20is\x20already\x20claimed\x20by\x20someone\x20else.','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.','rampUpTime','ouUgk','listPromise','stream\x20ID\x20is\x200\x20length','JDmMZ','visible','isDirector\x20','changeMicrophone','processIceBundle','Unhandeled\x20Error\x20occured','EqhFj','KPdwS','10px','[data-action-type=\x22mute-guest\x22][data--u-u-i-d=\x22','undefined','pingTimeout','seedStream','NxAAy','4722','version','password','LOADING\x20UP\x20WAITING\x20WATCH\x20STREAM','watchTimeoutList2:','view','autoGainControl','MmDNP','mimeType','userAgent','Audio_Sync_Delay_ms','iframeSrc','vp9','FkyPX','IdHFg','juuei','hands_','HANG\x20UP\x20COMPLETE','requestZoomChange','null\x20ice\x20rpcs','screenShareElement','SWmpN','height','maxTouchPoints','cskij','getVideoTracks','onconnectionstatechange\x20pcs\x20ice\x20--\x20disconnected,\x20but\x20not\x20yet\x20closed?\x20','Transferred','hash\x20is\x20','scaleResolutionDownBy','remoteFocus','savedBitrate','muteState','no\x20audio\x20track\x20to\x20poke','eventPlayActive','stereo\x20enabled','xIqsF','timeout','browserDetails','roombitrate','directorSettings','cameraConstraints','https://reports.obs.ninja/','hanging\x20up','keyname','offsetChannel','zoomedBitrate','setScale','NISxg','focus\x20success','OhShO','NZGpR','ixPQs','acc','Add\x20a\x20label','received\x20data\x20from\x20viewer','trackId','\x20Pixel\x20','currentTarget','privacy','cleanup','RECONNECTING\x20to\x20HSS;\x20DISCONNECTING\x20FROM\x20TRANSFERRED\x20ROOM','RTC\x20already\x20connected','generateKey','KEJPA','AQAB','speakerMuted','662522zipTWD','problem','providing\x20answer','Answer\x20SDP\x20does\x20not\x20have\x20a\x20matching\x20session\x20ID','showList','zoom','WZEvc','LjFwP','changeSpeaker','target','requestStats','website','data','zhePX','zPDMn','noaudio','qybqx','srcObject','hostname','crypto','1GpXBpu','NVnfD','TFZFs','applyConstraints','requestResolution','directorSpeakerMuted','mYAPY','controlTimer','playoutDelayHint','EGPUO','send\x20channel\x20closed','\x0aPress\x20OK\x20to\x20be\x20redirected.','sendChannel','inline-block','local_relayIP','retryTimeout','screenShareState','directVideoMuted','nackTrigger','enhanceaudio','xSmiH','audioLatency','lin','sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message','position','delta','MVzLI','videoCodecs','preventDefault','cFhpP','infocus','bytesReceived','updateQueue','abs','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x204','inbound-rtp','encrypt','vb_url','ZIrXH','JCWPs','RoAwb','onremovetrack','RzrzP','keyframeTimeout','username','rxvvj','Clean\x20up','bbUwX','cbr','relayProtocol','_frameWidth','remoteCandidateId','oZmrR','eNAiQ','has','maxviewers','videosource','bqpMW','changeParams','ICE\x20DISCONNECTED','new-view-connection','audioOptions','flipped','maxpublishers','imageElement','bandwidth','focusDistance','can\x27t\x20change\x20bitrate;\x20no\x20video\x20sender\x20found','mutedState','ondatachannel','maxsamplerate','jwk','targetBandwidth','OKTPZ','getSettings','NaZrV','AudioContext','Members\x20in\x20Room','forEach','seedPlz','setParameters','optimizedBitrate','AES-CBC','top','pie','remoteStats','streamErrors_nackCount','OjTsS','wss','recorder','dataset','videosource_','HcrvA','label_','keys','local_relayProtocol','HfJTn','map','visibility','setup\x20peer\x20complete','tyaAj','RSASSA-PKCS1-v1_5','anysend','toString','encodings','OBS\x20PLI\x20FIX\x20MODE\x20ON','streaming','getAudioTracks','NWDBi','pathname','requestSceneUpdate','getSenders','GOT\x20ICEs!!','requestVideoRecord','sendRequest','charCodeAt','audioChannels','obsVisibility','LaMbV','candidate-pair','preferCodec','noPLIs','digest','platform','Mute\x20video\x20-306','room\x20rate\x20restriction\x20detected.\x20No\x20videos\x20will\x20be\x20published\x20to\x20other\x20guests','actual\x20bitrate:','manual','voiceMeter','cleanOutput','audioGain','recording_audio_pipeline','maxconnections','remote_relayProtocol','seeding\x20!!','onclick','TRYING\x20TO\x20RECONNECT\x203','Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit','sendroom','keyframe','XjLhi','importKey','Requested_resolution','rejected','chat','THIS\x20SHOULD\x20BE\x20DELETED','optimize','readyState','desaltStreamID','video/VP8','windowed','disconnected','video\x20element\x20is\x20being\x20created\x20and\x20media\x20track\x20added','timestamp','TOO\x20MANY\x20PUBLISHING\x20PEERS','getElementById','buffer','SHA-1','CYvAP','1vh','optimizeBitrate','mono','_sync_offset','DfchS','_codecIdTrackId','displayMute','return\x20/\x22\x20+\x20this\x20+\x20\x22/','replace','padStart','The\x20request\x20failed;\x20the\x20remote\x20user\x20did\x20not\x20recognize\x20you\x20as\x20the\x20director','guest','mobile','enhanceAudio','audioEffects','canvasCtx','PCS:\x20ICE\x20Disconnected;\x20wait\x20for\x20retry?\x20pcs','forceMediaSettings','description','urls','Failed\x20to\x20connect\x20to\x20service:\x20Error\x20503 Possibly\x20too\x20many\x20connections\x20from\x20the\x20same\x20address\x20tried\x20to\x20connect. Visit\x20https://discord.obs.ninja\x20for\x20support.','recordLocal','allowIframe','42055pWjrPT','Chromium-based\x20v','length','&scene','EEBMG','queuebutton','XNmhk','iMDgH','novideo','RLPco','changeCamera','ZWFyy','soloChatUUID','disconnectedTimeout','fullscreen','production','processIce','resending\x20message','directorEnabledPPT','rUTSz','**\x20connected','mNkCa','hlkHM','JLBIs','turn:www.turn.obs.ninja:3478','sink','bitrate','tWokX','getTime','vp8','startTime','OosZW','can\x27t\x20change\x20audio\x20bitrate;\x20no\x20audio\x20sender\x20found','recording_audio_ctx_latency','successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS\x20to\x20all\x20RTC\x20Peers','sensors','disableREMB','ZGemF','SDP\x20Sessions\x20Match.\x20I\x20assume\x20ADDING\x20TRACKS','totalRoomBitrate_default','left','hKzSE','Resolution','reverse','playback_audio_volume_meter','hidden','track','noNacks','Video\x20Track','RPC\x20closed','fHWIg','changeOrder','remoteMuteState','HKLOI','COluw','stats','zNvFH','red','RS1','paused','noiframe','New\x20Label:\x20','8px','turn:turn-eu2.obs.ninja:3478','addIceCandidate','mirrored','RTC\x20closed','Untitled','_packetsLost','Refreshing\x20scale','generateHash','activelySpeaking','_jitter_count','roomenc','reject','WebRTC\x20Connection\x20Closed.\x20Clean\x20up.\x20657','name','LlfbY','roDRH','metaKey','resume','Not\x20a\x20scene','ZXjND','getRandomValues','parse','jitterBufferEmittedCount','allowVideo','bitrate_set','uMIOo','ICE\x20DID\x20NOT\x20FIND\x20A\x20PC\x20OPTION?','OaReY','roomid','configuration','gridlayout','kYNkN','bitrateTimeout','from','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.','closedCaptions','iVFeh','videoOptions','_frameHeight','nbuxp','remote_networkType','interval','bandwidth\x20set!','Audio\x20processing\x20is\x20disabled\x20with\x20this\x20guest.\x20Can\x27t\x20mute\x20or\x20change\x20volume','adding\x20track','nopreview','waitingWatchList','audio_level','oniceconnectionstatechange','29381gKNbYg','localMuteElement','midiIn','Android','RTC\x20Connection\x20seems\x20to\x20be\x20dead\x20or\x20not\x20yet\x20open?\x201','ICE\x20FAILed.\x20bad?','Track\x20was\x20removed','remoteRaisedHandElement','ASKING\x20FOR\x20AUDIO\x20AND\x20VIDEO?','now','163299YdAyrI','localstats','action','security','leTQo','href','video_muted_init','setOpusAttributes','_last_bytes','Track\x20stopped','icefilter','already\x20closed\x20PCS','new','Safari','string','video/VP9','Buffer_Delay_in_ms','delay','directorVolumeState','Un-mute\x20guest','obsRecording','scale\x20set!','requestRateLimit','split','dropped\x20candidate\x20due\x20to\x20filter','onicecandidate','broadcastChannel','raw','querySelectorAll','audio','call','type','pressed','push','CONNECTEED!','sync','reportbutton','tVpdQ','scale\x20scale','storekey','value\x20there','cloneNode','tfliteModule','localCandidateId','successfully\x20requested\x20audio\x20and\x20video','codecGroupFlag','255257rchSBe','none','?view=','scaleResolutionDownBy\x20set\x202!','obsfix','directorUUID','eHmje','odofM','offerSDP','compressor','tMYUF','play','turn:turn-usw1.obs.ninja:443','ejUjs','innerHTML','SHA-256','subtle','ICE\x20Disconnected;\x20wait\x20for\x20retry?\x20rpcs','permaid','Websockets\x20timed\x20out;\x2020\x20seconds','pliCount','resolution\x20scale','disableWebAudio','networkPriority','BANBD','transport','limitAudioBitrate','audio_delay\x20:\x20','tDhfb','remoteMuteState_','does\x20any\x20audio\x20exist?','title','directorActions','hiddenSceneViewBitrate','device\x20does\x20not\x20support\x20playout\x20delay','\x20is\x20not\x20defined;\x20skipping.','sendKeyFrameScenes','successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS','nRUoE','rKQNH','GgQMd','midiHotkeys','ctrlKey','xXcoG','audioConstraints','sign','mirrorExclude','ROOMID\x20EANBLED','^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}','bJYtJ','webp','autostart','Failed\x20to\x20request\x20video\x20and\x20audio;\x20iOS\x20device\x20asking?','FORCE\x20KEYFRAME\x20FOR\x20SCENE','verifyData','enc','addTrack','getParameters','display','start','VQZjU','QYjzD','hangup','UUID','RSA','setValueAtTime','&pie','foctp','browser','stereo_url','outboundVideoBitrate','eHiCl','remote_relay_IP','request\x20focus\x20change:\x20','sdp','CtpBz','eNTJJ','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!','setResolution','info','isEyr','candidate','SiJAl','videoMuted','[data-action-type=\x22order-value\x22][data--u-u-i-d=\x22','scaleDueToBitrate','listing','SCRbI','screensharequality','image/webp','changeURL','NwxjB','offer','The\x20Director\x20has\x20disabled\x20your\x20vision\x20temporarily ','request','hash','initialPublish','outboundAudioBitrate','setBitrate','canvas','create\x20offer\x20worked','track\x20made\x20inactive;\x20removing','beepToNotify','maxframerate','obsState','remoteMuteElement','setupIncoming','statsMenu','code','time_active_minutes','laERA','HANG\x20UP\x202\x20COMPLETE','could\x20not\x20be\x20sent;\x20queuing\x20it','queue','TJmro','framesPerSecond','WqECy','host','scaleResolution','ACTION\x20REJECTED:\x20','..\x20waiting\x20for\x20user\x20gesture','Press\x20OK\x20to\x20submit\x20any\x20error\x20logs\x20to\x20OBS.Ninja.\x20Error\x20logs\x20may\x20contain\x20private\x20information.','pleaseDoNotAbuse','LhDHR','forceTcpMode','Enter\x20a\x20new\x20Display\x20Name\x20for\x20this\x20stream','right','allowMIDI','webAudios','deltaY','KxLDr','wrvve','requestAudioRateLimit','sceneMute','scaleHeight','joinroom','mute','clicked','list','parentNode','nominated','midi','requestKeyframe','YtAJs','scene','directorMutedState','minptime','broadcast','audioCtx\x20:\x20','seed','controls','session.pcs[UUID].scale\x20=\x20','ezilS','audioCodecs','taintedSession','ecaAr','getOpusBitrate','seedAttempts','Aonor','denoise_url','stop','mainmenu','canvasSource','kind','steves','span','useragent','pushLoudness','nQgLR','privateKey','apply','obsStateSync','fFZpT','TmbVG','disabled',',\x20isDirector:\x20','enabled','directorSpeakerMute','_type','URL','utf-8','onmessage','limitBitrate','done\x20clearing\x20audio','sendMessage','audio\x20bandwidth\x20set!','setVideoBitrate','order','pbQAf','enhance','directorViewBitrate','JYKuv','DKcJo','Audio_Loudness','remoteVideoMuteElement','framerate','verify','1cexfgl','removeTrack','micDelay','gHBOd','Your\x20room\x20has\x20changed ','sort','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. ','FbtSX','allowBroadcast','safari','removeChild','tpmfg','ptz','Browser','eIFKa','limitAudioEncoder','level','inboundAudioPipeline','requestFocusChange','Pinging','NTOYG','match','processIce2','cjlwu','devicePixelRatio','manualBandwidth','streamID','_packetsReceived','setLocalDescription','next\x20stream\x20loading:\x20','NJMzt','joiningRoom','EKKXt','RPCS\x20WINS\x20ICE','getReceivers','claim','controlRoomBitrate','mag','iceConnectionState','forceios','localVoiceMeter','STREAM\x20ID\x20desalted\x202:','obsninja','setVideoBitrates','wytBO','ICE\x20closed?','FPS','signature','maxBitrate','codec_url','aspectratio','1.0','PUBLISHER\x27s\x20RTC\x20Connection\x20seems\x20to\x20be\x20dead?\x20','bind','frameHeight','requestChangeLowcut','webcamonly','connectPeer','marginLeft','remote_candidateType'];var _0x50a0ea=_0x45a6;(function(_0x3aafef,_0xf11fe9){var _0x967653=_0x45a6;while(!![]){try{var _0x17fdff=-parseInt(_0x967653(0x39d))+parseInt(_0x967653(0x50a))*parseInt(_0x967653(0x12e))+parseInt(_0x967653(0x2d3))+parseInt(_0x967653(0x445))*-parseInt(_0x967653(0x2e7))+-parseInt(_0x967653(0x59c))*parseInt(_0x967653(0x268))+parseInt(_0x967653(0x40d))+parseInt(_0x967653(0x417));if(_0x17fdff===_0xf11fe9)break;else _0x3aafef['push'](_0x3aafef['shift']());}catch(_0x2f8abd){_0x3aafef['push'](_0x3aafef['shift']());}}}(_0xb550,0x5b1d9));function log(_0x4e9d31){}function warnlog(_0x52d728,_0x431d97=![],_0x464c44=![]){if(_0x464c44){}}function errorlog(_0x3db3d8,_0x2ce38f=![],_0x3891b9=![]){appendDebugLog(_0x3db3d8);if(_0x3891b9){}}window['onerror']=function backupErr(_0x34a24d,_0x438638=![],_0x2308f9=![]){var _0x2f9f77=_0x45a6;return errorlog(_0x34a24d),errorlog(_0x2308f9),errorlog(_0x2f9f77(0x287)),appendDebugLog(_0x34a24d),_0x2308f9&&appendDebugLog(_0x2308f9),![];},window[_0x50a0ea(0x333)]=window[_0x50a0ea(0x333)]||window[_0x50a0ea(0x19e)];function getById(_0x4039cc){var _0x556c48=_0x50a0ea,_0x57daa9=document[_0x556c48(0x382)](_0x4039cc);return!_0x57daa9&&(warnlog(_0x4039cc+_0x556c48(0x468)),_0x57daa9=document['createElement'](_0x556c48(0x4ea))),_0x57daa9;}var errorReport=[];function appendDebugLog(_0x138fba){var _0x206a8e=_0x50a0ea;try{var _0x1e8c11=new Date(),_0x2ca84b=_0x1e8c11[_0x206a8e(0x3b9)]();if(_0x138fba[_0x206a8e(0x5a1)])errorReport[_0x206a8e(0x438)]({'message':_0x138fba['message'],'name':_0x138fba[_0x206a8e(0x3e9)],'time':_0x2ca84b});else{if(typeof _0x138fba==='string'){if(_0x206a8e(0x1fa)===_0x206a8e(0x3ef)){function _0x2f1718(){var _0x3e734d=_0x206a8e;_0x44b85b[_0x3e734d(0x125)][_0x47b566][_0x3e734d(0x152)]['srcObject']=_0x57142e[_0x3e734d(0x125)][_0xb38fee][_0x3e734d(0x162)];}}else errorReport[_0x206a8e(0x438)]({'note':_0x138fba,'time':_0x2ca84b});}else errorReport[_0x206a8e(0x438)]({'other':_0x138fba,'time':_0x2ca84b});}errorReport=errorReport[_0x206a8e(0x1ab)](-0xc8),document[_0x206a8e(0x382)](_0x206a8e(0x43b))&&(getById('reportbutton')['style'][_0x206a8e(0x349)]=_0x206a8e(0x283));}catch(_0x52a37b){}}function submitDebugLog(_0x2b4ceb){var _0x92a3bd=_0x50a0ea;try{appendDebugLog({'connection_type':session[_0x92a3bd(0x3d4)][_0x92a3bd(0x1fd)]});if(navigator[_0x92a3bd(0x299)]){if(_0x92a3bd(0x2e9)!==_0x92a3bd(0x2e9)){function _0x1ad3d8(){var _0x865040=_0x92a3bd;_0x17a4e8[_0x865040(0x125)][_0x49ce33][_0x865040(0x20a)]=![],_0x3a6b2d=!![];}}else{var _0x1e73f5,_0x3ff503=navigator[_0x92a3bd(0x299)];appendDebugLog({'userAgent':_0x3ff503});}}navigator[_0x92a3bd(0x362)]&&appendDebugLog({'userAgent':navigator[_0x92a3bd(0x362)]});}catch(_0x1b23f5){}window[_0x92a3bd(0x157)]();var _0x413844=confirm(_0x92a3bd(0x4be));if(_0x413844){if(_0x92a3bd(0x278)!==_0x92a3bd(0x278)){function _0x37a79a(){var _0x39257d=_0x92a3bd;_0x4b5008+=_0x13c155(_0x245d63[_0x39257d(0x34f)][0x0][_0x39257d(0x53a)])/0x400,_0x2f7ac5(_0x55eb7d);}}else{var _0xb0e041=new XMLHttpRequest();_0xb0e041['open']('POST',_0x92a3bd(0x2ba)),_0xb0e041[_0x92a3bd(0x588)](JSON['stringify'](errorReport)),errorReport=[];if(document[_0x92a3bd(0x382)](_0x92a3bd(0x43b))){if(_0x92a3bd(0x1d4)!=='kijlv'){function _0x19b233(){var _0x2604eb=_0x92a3bd;_0x45a744[_0x2604eb(0x464)]=_0x218d3b[_0x2604eb(0x26c)];}}else getById(_0x92a3bd(0x43b))['style'][_0x92a3bd(0x349)]='hidden';}}}}function isAlphaNumeric(_0x234498){var _0x1880cd=_0x50a0ea,_0x4a5926,_0x5c4930,_0x48d1d2;for(_0x5c4930=0x0,_0x48d1d2=_0x234498[_0x1880cd(0x39f)];_0x5c4930<_0x48d1d2;_0x5c4930++){_0x4a5926=_0x234498[_0x1880cd(0x35a)](_0x5c4930);if(!(_0x4a5926>0x2f&&_0x4a5926<0x3a)&&!(_0x4a5926>0x40&&_0x4a5926<0x5b)&&!(_0x4a5926>0x60&&_0x4a5926<0x7b))return![];}return!![];}var iOS=!!navigator['platform']&&/iPad|iPhone|iPod/['test'](navigator[_0x50a0ea(0x362)]),iPad=navigator[_0x50a0ea(0x2a7)]&&navigator[_0x50a0ea(0x2a7)]>0x2&&/MacIntel/['test'](navigator[_0x50a0ea(0x362)]);function play(_0x7ff26d=null){var _0x50ebca=_0x50a0ea;log(_0x50ebca(0x55a)+session[_0x50ebca(0x295)]);if(session[_0x50ebca(0x295)]===''){if(_0x50ebca(0x576)===_0x50ebca(0x17f)){function _0x198021(){var _0x2c760e=_0x50ebca;_0x5d5fa2[_0x2c760e(0x1a9)](_0x44e497);}}else log(_0x50ebca(0x154));}else{if(session[_0x50ebca(0x295)]!==![]){var _0x2c3958=session[_0x50ebca(0x295)][_0x50ebca(0x42e)](',');for(var _0xf4f01f in _0x2c3958){if(_0x2c3958[_0xf4f01f]==''){}else{if(_0x7ff26d===null){if(_0x50ebca(0x3a4)!==_0x50ebca(0x3a4)){function _0x6c96d6(){var _0x11a5f3=_0x50ebca;_0x5a1982[_0x11a5f3(0x564)][_0x435e5e][_0x11a5f3(0x2f3)][_0x11a5f3(0x588)](_0x30d398);}}else session[_0x50ebca(0x570)](_0x2c3958[_0xf4f01f]);}else{if(_0x7ff26d===_0x2c3958[_0xf4f01f])session[_0x50ebca(0x570)](_0x2c3958[_0xf4f01f]);else{}}}}}else{if(session[_0x50ebca(0x23f)]!==![]){if(session[_0x50ebca(0x23f)][_0x50ebca(0x254)](_0x7ff26d)){}else session[_0x50ebca(0x570)](_0x7ff26d);}else _0x7ff26d&&session[_0x50ebca(0x570)](_0x7ff26d);}}}function showControlBar(_0x518c61){var _0x424c8a=_0x50a0ea;try{_0x518c61[_0x424c8a(0x4db)]=!![];}catch(_0xb05c00){errorlog(_0xb05c00);}}function playAllVideos(){var _0x2ac120=_0x50a0ea;for(var _0x161f7a in session[_0x2ac120(0x125)]){try{session[_0x2ac120(0x125)][_0x161f7a]['videoElement']&&(session[_0x2ac120(0x125)][_0x161f7a][_0x2ac120(0x152)][_0x2ac120(0x3d8)]&&session[_0x2ac120(0x125)][_0x161f7a][_0x2ac120(0x152)]['play']()[_0x2ac120(0x558)](_0x4204a5=>{log('playing');})[_0x2ac120(0x186)](warnlog));}catch(_0x56793c){}}}function getTURNList(){var _0x21986d=_0x50a0ea,_0x192368=[];turn={},turn[_0x21986d(0x313)]=_0x21986d(0x10e),turn[_0x21986d(0x1f2)]=_0x21986d(0x25c),turn['urls']=['turns:www.turn.obs.ninja:443'],turn['tz']=0x12c,turn[_0x21986d(0x15b)]=![],turn[_0x21986d(0x3ac)]=!![];if(session[_0x21986d(0x577)]&&turn[_0x21986d(0x15b)]==session[_0x21986d(0x4c1)]){}else{if(session[_0x21986d(0x4c1)]&&turn[_0x21986d(0x15b)]){}else{if(session[_0x21986d(0x577)]==![]&&turn[_0x21986d(0x3ac)]==![]){}else{if(_0x21986d(0x343)===_0x21986d(0x31b)){function _0x48e8c5(){return;}}else _0x192368[_0x21986d(0x438)](turn);}}}turn={},turn[_0x21986d(0x313)]=_0x21986d(0x10e),turn[_0x21986d(0x1f2)]='setupYourOwnPlease',turn[_0x21986d(0x399)]=[_0x21986d(0x3b5)],turn['tz']=0x12c,turn[_0x21986d(0x15b)]=!![],turn[_0x21986d(0x3ac)]=!![];if(session[_0x21986d(0x577)]&&turn[_0x21986d(0x15b)]==session[_0x21986d(0x4c1)]){}else{if(session['forceTcpMode']&&turn[_0x21986d(0x15b)]){}else{if(session[_0x21986d(0x577)]==![]&&turn['production']==![]){}else _0x192368['push'](turn);}}turn={},turn[_0x21986d(0x313)]=_0x21986d(0x10e),turn[_0x21986d(0x1f2)]=_0x21986d(0x25c),turn['urls']=[_0x21986d(0x55e)],turn['tz']=-0x3c,turn[_0x21986d(0x15b)]=![],turn[_0x21986d(0x3ac)]=!![];if(session[_0x21986d(0x577)]&&turn[_0x21986d(0x15b)]==session[_0x21986d(0x4c1)]){}else{if(session[_0x21986d(0x4c1)]&&turn[_0x21986d(0x15b)]){}else{if(session['speedtest']==![]&&turn[_0x21986d(0x3ac)]==![]){}else _0x192368[_0x21986d(0x438)](turn);}}turn={},turn[_0x21986d(0x313)]='steve',turn[_0x21986d(0x1f2)]=_0x21986d(0x25c),turn[_0x21986d(0x399)]=[_0x21986d(0x21c)],turn['tz']=-0x3c,turn['udp']=!![],turn['production']=![];if(session[_0x21986d(0x577)]&&turn[_0x21986d(0x15b)]==session['forceTcpMode']){}else{if(session[_0x21986d(0x4c1)]&&turn[_0x21986d(0x15b)]){}else{if(session[_0x21986d(0x577)]==![]&&turn[_0x21986d(0x3ac)]==![]){}else _0x192368[_0x21986d(0x438)](turn);}}turn={},turn[_0x21986d(0x313)]=_0x21986d(0x4e9),turn[_0x21986d(0x1f2)]=_0x21986d(0x4bf),turn[_0x21986d(0x399)]=[_0x21986d(0x451)],turn['tz']=0x1e0,turn[_0x21986d(0x15b)]=!![],turn['production']=!![];if(session['speedtest']&&turn[_0x21986d(0x15b)]==session[_0x21986d(0x4c1)]){}else{if(session[_0x21986d(0x4c1)]&&turn[_0x21986d(0x15b)]){}else{if(session['speedtest']==![]&&turn[_0x21986d(0x3ac)]==![]){}else _0x192368['push'](turn);}}turn={},turn[_0x21986d(0x313)]=_0x21986d(0x534),turn[_0x21986d(0x1f2)]=_0x21986d(0x4bf),turn[_0x21986d(0x399)]=['turn:turn-usc1.obs.ninja:3478'],turn['tz']=0x168,turn[_0x21986d(0x15b)]=!![],turn[_0x21986d(0x3ac)]=!![];if(session[_0x21986d(0x577)]&&turn[_0x21986d(0x15b)]==session[_0x21986d(0x4c1)]){}else{if(session[_0x21986d(0x4c1)]&&turn[_0x21986d(0x15b)]){}else{if(session[_0x21986d(0x577)]==![]&&turn['production']==![]){}else _0x192368[_0x21986d(0x438)](turn);}}turn={},turn[_0x21986d(0x313)]=_0x21986d(0x534),turn[_0x21986d(0x1f2)]=_0x21986d(0x59b),turn[_0x21986d(0x399)]=[_0x21986d(0x3dc)],turn['tz']=-0x3c,turn[_0x21986d(0x15b)]=!![],turn[_0x21986d(0x3ac)]=!![];if(session[_0x21986d(0x577)]&&turn[_0x21986d(0x15b)]==session[_0x21986d(0x4c1)]){}else{if(session[_0x21986d(0x4c1)]&&turn[_0x21986d(0x15b)]){}else{if(session[_0x21986d(0x577)]==![]&&turn[_0x21986d(0x3ac)]==![]){}else _0x192368[_0x21986d(0x438)](turn);}}return _0x192368;}function _0x45a6(_0x3d1a24,_0x36eb55){_0x3d1a24=_0x3d1a24-0x10e;var _0x5d8ed4=_0xb550[_0x3d1a24];return _0x5d8ed4;}function chooseBestTURN(){var _0x547fe2=_0x50a0ea;if(session[_0x547fe2(0x3f9)])return;var _0x2a3cc2=getTURNList(),_0x44a820=new Date(),_0x170409=_0x44a820['getTimezoneOffset']();for(var _0x545f17=0x0;_0x545f17<_0x2a3cc2[_0x547fe2(0x39f)];_0x545f17++){var _0x32bda4=Math[_0x547fe2(0x308)](_0x2a3cc2[_0x545f17]['tz']-_0x170409);Math[_0x547fe2(0x308)](_0x32bda4-0x3c*0x18)<_0x32bda4&&(_0x32bda4=Math[_0x547fe2(0x308)](_0x32bda4-0x3c*0x18)),_0x2a3cc2[_0x545f17][_0x547fe2(0x300)]=_0x32bda4;}_0x2a3cc2[_0x547fe2(0x50f)](compare_deltas),_0x2a3cc2=_0x2a3cc2[_0x547fe2(0x1ab)](0x0,0x3),session[_0x547fe2(0x3f9)]={'iceServers':[{'urls':[_0x547fe2(0x586),_0x547fe2(0x1ae)]}],'sdpSemantics':_0x547fe2(0x153)},session[_0x547fe2(0x3f9)]['iceServers']=session['configuration'][_0x547fe2(0x1fc)][_0x547fe2(0x22c)](_0x2a3cc2),log(session[_0x547fe2(0x3f9)]);}function compare_deltas(_0x131146,_0x52f0c0){var _0x10a024=_0x50a0ea,_0x520ddd=_0x131146[_0x10a024(0x300)]||0x0,_0x2c696f=_0x52f0c0[_0x10a024(0x300)]||0x0;if(_0x520ddd>_0x2c696f)return 0x1;if(_0x520ddd<_0x2c696f)return-0x1;return 0x0;}function compare_vids(_0x316fc3,_0x4369f2){var _0x242537=_0x50a0ea,_0x23c145=_0x316fc3[_0x242537(0x500)]||0x0,_0x3067f3=_0x4369f2[_0x242537(0x500)]||0x0;if(_0x23c145<_0x3067f3)return 0x1;if(_0x23c145>_0x3067f3)return-0x1;return 0x0;}var updateMixerTimer=null,updateMixerActive=![];function updateMixer(_0x16c853=![]){clearInterval(updateMixerTimer);if(updateMixerActive){updateMixerTimer=setTimeout(function(){updateMixer();},0x1f4);return;}updateMixerActive=!![];try{updateMixerRun(_0x16c853);}catch(_0x3a60ab){}updateMixerActive=![];}var WebRTC={};WebRTC['Media']=function(){var _0x46afd2=_0x50a0ea,_0x86f037=function(){var _0x634cd3=!![];return function(_0x49a9ec,_0x387ca7){var _0x64071b=_0x45a6;if(_0x64071b(0x470)!==_0x64071b(0x470)){function _0x511e63(){var _0x6ee5b9=_0x64071b;_0x37e6bc(_0x168dab(_0x1231f5[_0x6ee5b9(0x22f)]),_0x20e63d[_0x6ee5b9(0x3cb)]);}}else{var _0x1f294f=_0x634cd3?function(){var _0x1bc7f7=_0x64071b;if(_0x387ca7){var _0x53adae=_0x387ca7[_0x1bc7f7(0x4ef)](_0x49a9ec,arguments);return _0x387ca7=null,_0x53adae;}}:function(){};return _0x634cd3=![],_0x1f294f;}};}(),_0x11ca64=_0x86f037(this,function(){var _0x4fc4db=function(){var _0xe45652=_0x45a6;if(_0xe45652(0x227)!==_0xe45652(0x227)){function _0x259835(){var _0x37131e=_0xe45652;_0x52aa31(_0x37131e(0x2d4)),_0x4f7795[_0x37131e(0x125)][_0x4fb509[_0x37131e(0x484)]][_0x37131e(0x245)](),delete _0x50f768['rpcs'][_0x21ea78[_0x37131e(0x484)]];}}else{var _0x50fe08=_0x4fc4db['constructor'](_0xe45652(0x38d))()[_0xe45652(0x15f)](_0xe45652(0x475));return!_0x50fe08[_0xe45652(0x22a)](_0x11ca64);}};return _0x4fc4db();});_0x11ca64();var _0x51f6a2={};function _0x532105(){}function _0x36ea98(_0x439d7a){errorlog(_0x439d7a);}function _0x15dbe0(){var _0x4cd0b8=_0x45a6,_0x13130d,_0x364358,_0x25c725=new Promise((_0x43afa0,_0x588273)=>{_0x13130d=_0x43afa0,_0x364358=_0x588273;});return _0x25c725[_0x4cd0b8(0x267)]=_0x13130d,_0x25c725[_0x4cd0b8(0x3e7)]=_0x364358,_0x25c725;}_0x51f6a2[_0x46afd2(0x2e2)]=![],_0x51f6a2[_0x46afd2(0x3a5)]=![],_0x51f6a2['activeSpeaker']=![],_0x51f6a2[_0x46afd2(0x3e4)]=!![],_0x51f6a2[_0x46afd2(0x174)]=![],_0x51f6a2[_0x46afd2(0x35b)]=0x8,_0x51f6a2[_0x46afd2(0x1b9)]=![],_0x51f6a2[_0x46afd2(0x583)]=![],_0x51f6a2[_0x46afd2(0x369)]=![],_0x51f6a2[_0x46afd2(0x24d)]=!![],_0x51f6a2[_0x46afd2(0x394)]=null,_0x51f6a2[_0x46afd2(0x1f6)]=![],_0x51f6a2[_0x46afd2(0x478)]=![],_0x51f6a2[_0x46afd2(0x1b3)]=new AudioContext(),_0x51f6a2[_0x46afd2(0x53c)]=![],_0x51f6a2['audioLatency']=![],_0x51f6a2[_0x46afd2(0x1c8)]=null,_0x51f6a2[_0x46afd2(0x296)]=null,_0x51f6a2[_0x46afd2(0x23d)]=null,_0x51f6a2[_0x46afd2(0x4d8)]=![],_0x51f6a2[_0x46afd2(0x431)]=![],_0x51f6a2['bigmutebutton']=![],_0x51f6a2[_0x46afd2(0x3b7)]=![],_0x51f6a2[_0x46afd2(0x3f4)]=![],_0x51f6a2[_0x46afd2(0x383)]=![],_0x51f6a2[_0x46afd2(0x4ab)]=![],_0x51f6a2[_0x46afd2(0x4a8)]=null,_0x51f6a2['canvasSource']=null,_0x51f6a2[_0x46afd2(0x52e)]=![],_0x51f6a2[_0x46afd2(0x554)]=![],_0x51f6a2['cleanOutput']=![],_0x51f6a2[_0x46afd2(0x1bb)]=![],_0x51f6a2[_0x46afd2(0x3ff)]=![],_0x51f6a2[_0x46afd2(0x3f9)]=![],_0x51f6a2[_0x46afd2(0x44e)]=![],_0x51f6a2[_0x46afd2(0x377)]=![],_0x51f6a2[_0x46afd2(0x58e)]=![],_0x51f6a2['sticky']=![],_0x51f6a2[_0x46afd2(0x317)]=0x1,_0x51f6a2['cover']=![],_0x51f6a2[_0x46afd2(0x18c)]=null,_0x51f6a2[_0x46afd2(0x2b9)]={},_0x51f6a2[_0x46afd2(0x471)]={},_0x51f6a2[_0x46afd2(0x581)]={},_0x51f6a2[_0x46afd2(0x14d)]={},_0x51f6a2[_0x46afd2(0x275)]=![],_0x51f6a2[_0x46afd2(0x503)]=0x23,_0x51f6a2[_0x46afd2(0x466)]=0x190,_0x51f6a2[_0x46afd2(0x2be)]=0x25a,_0x51f6a2[_0x46afd2(0x444)]=![],_0x51f6a2[_0x46afd2(0x130)]=![],_0x51f6a2[_0x46afd2(0x164)]=![],_0x51f6a2[_0x46afd2(0x3af)]=![],_0x51f6a2[_0x46afd2(0x2ec)]=null,_0x51f6a2[_0x46afd2(0x10f)]=null,_0x51f6a2[_0x46afd2(0x44a)]=![],_0x51f6a2[_0x46afd2(0x255)]=![],_0x51f6a2[_0x46afd2(0x15a)]=!![],_0x51f6a2[_0x46afd2(0x16f)]=null,_0x51f6a2['equalizer']=![],_0x51f6a2[_0x46afd2(0x17c)]=![],_0x51f6a2[_0x46afd2(0x47c)]=new TextEncoder(_0x46afd2(0x4f9)),_0x51f6a2['exclude']=![],_0x51f6a2[_0x46afd2(0x1cb)]=![],_0x51f6a2['limitTotalBitrate']=![],_0x51f6a2[_0x46afd2(0x144)]=!![],_0x51f6a2['firstPlayTriggered']=![],_0x51f6a2[_0x46afd2(0x325)]=![],_0x51f6a2[_0x46afd2(0x508)]=![],_0x51f6a2[_0x46afd2(0x329)]=![],_0x51f6a2[_0x46afd2(0x531)]=![],_0x51f6a2[_0x46afd2(0x397)]=![],_0x51f6a2[_0x46afd2(0x3ab)]=![],_0x51f6a2[_0x46afd2(0x4a4)]=![],_0x51f6a2[_0x46afd2(0x2a6)]=![],_0x51f6a2[_0x46afd2(0x29b)]=![],_0x51f6a2[_0x46afd2(0x20a)]=![],_0x51f6a2[_0x46afd2(0x3d9)]=![],_0x51f6a2[_0x46afd2(0x203)]=![],_0x51f6a2[_0x46afd2(0x1d0)]=0x1,_0x51f6a2[_0x46afd2(0x189)]=0x0,_0x51f6a2[_0x46afd2(0x421)]=![],_0x51f6a2[_0x46afd2(0x305)]=![],_0x51f6a2[_0x46afd2(0x529)]=![],_0x51f6a2[_0x46afd2(0x26c)]=![],_0x51f6a2[_0x46afd2(0x15d)]=![],_0x51f6a2[_0x46afd2(0x345)]={},_0x51f6a2[_0x46afd2(0x50c)]=![],_0x51f6a2[_0x46afd2(0x31e)]=![],_0x51f6a2['maxpublishers']=![],_0x51f6a2[_0x46afd2(0x36b)]=![],_0x51f6a2[_0x46afd2(0x392)]=![],_0x51f6a2[_0x46afd2(0x4ac)]=![],_0x51f6a2[_0x46afd2(0x182)]=![],_0x51f6a2[_0x46afd2(0x559)]=![],_0x51f6a2[_0x46afd2(0x32d)]=![],_0x51f6a2[_0x46afd2(0x1ba)]=![],_0x51f6a2['minptime']=![],_0x51f6a2[_0x46afd2(0x56f)]=![],_0x51f6a2[_0x46afd2(0x158)]=0x19,_0x51f6a2[_0x46afd2(0x15c)]=0xa,_0x51f6a2[_0x46afd2(0x166)]=![],_0x51f6a2[_0x46afd2(0x366)]=![],_0x51f6a2[_0x46afd2(0x46e)]=![],_0x51f6a2['midiOut']=![],_0x51f6a2[_0x46afd2(0x40f)]=![],_0x51f6a2['minipreview']=![],_0x51f6a2[_0x46afd2(0x3de)]=![],_0x51f6a2[_0x46afd2(0x473)]=![],_0x51f6a2[_0x46afd2(0x595)]=[],_0x51f6a2[_0x46afd2(0x574)]=![],_0x51f6a2[_0x46afd2(0x13d)]=![],_0x51f6a2[_0x46afd2(0x388)]=![],_0x51f6a2[_0x46afd2(0x1e1)]={},_0x51f6a2[_0x46afd2(0x582)]=![],_0x51f6a2[_0x46afd2(0x3cc)]=![],_0x51f6a2['noPLIs']=![],_0x51f6a2['nocursor']=![],_0x51f6a2[_0x46afd2(0x449)]=![],_0x51f6a2[_0x46afd2(0x2bd)]=![],_0x51f6a2['optimize']=![],_0x51f6a2['obsState']={},_0x51f6a2[_0x46afd2(0x4ad)]['visibility']=null,_0x51f6a2[_0x46afd2(0x4ad)][_0x46afd2(0x351)]=null,_0x51f6a2[_0x46afd2(0x4ad)]['recording']=null,_0x51f6a2['obsState'][_0x46afd2(0x143)]=null,_0x51f6a2[_0x46afd2(0x4ad)][_0x46afd2(0x590)]=null,_0x51f6a2[_0x46afd2(0x48b)]=![],_0x51f6a2[_0x46afd2(0x4a6)]=![],_0x51f6a2[_0x46afd2(0x500)]=![],_0x51f6a2[_0x46afd2(0x292)]=![],_0x51f6a2['pcs']={},_0x51f6a2['pip']=![],_0x51f6a2[_0x46afd2(0x33b)]=![],_0x51f6a2['pcm']=![],_0x51f6a2[_0x46afd2(0x457)]=![],_0x51f6a2[_0x46afd2(0x2cb)]=![],_0x51f6a2['pingTimeout']=null,_0x51f6a2[_0x46afd2(0x409)]=null,_0x51f6a2['queue']=![],_0x51f6a2[_0x46afd2(0x219)]=[],_0x51f6a2[_0x46afd2(0x4ec)]=![],_0x51f6a2['randomize']=![],_0x51f6a2['recordedBlobs']=![],_0x51f6a2[_0x46afd2(0x39b)]=![],_0x51f6a2[_0x46afd2(0x23a)]=![],_0x51f6a2[_0x46afd2(0x27e)]=0xbb8,_0x51f6a2[_0x46afd2(0x14a)]=![],_0x51f6a2[_0x46afd2(0x2f6)]=0x1388,_0x51f6a2[_0x46afd2(0x3e6)]=![],_0x51f6a2['roomid']=![],_0x51f6a2[_0x46afd2(0x2b7)]=![],_0x51f6a2[_0x46afd2(0x516)]=![],_0x51f6a2[_0x46afd2(0x125)]={},_0x51f6a2[_0x46afd2(0x584)]=![],_0x51f6a2[_0x46afd2(0x548)]='',_0x51f6a2['scale']=![],_0x51f6a2['scene']=![],_0x51f6a2[_0x46afd2(0x110)]={},_0x51f6a2['screenshare']=![],_0x51f6a2[_0x46afd2(0x2a4)]=![],_0x51f6a2['screenshareid']=![],_0x51f6a2[_0x46afd2(0x49d)]=![],_0x51f6a2['screensharefps']=![],_0x51f6a2['screenShareState']=![],_0x51f6a2['security']=![],_0x51f6a2[_0x46afd2(0x569)]=![],_0x51f6a2[_0x46afd2(0x56c)]=![],_0x51f6a2[_0x46afd2(0x4e2)]=0x0,_0x51f6a2[_0x46afd2(0x522)]=![],_0x51f6a2[_0x46afd2(0x12c)]=![],_0x51f6a2[_0x46afd2(0x2d7)]=null,_0x51f6a2['labelstyle']=![],_0x51f6a2['soloChatUUID']=![],_0x51f6a2[_0x46afd2(0x1e9)]=!![],_0x51f6a2[_0x46afd2(0x13b)]=![],_0x51f6a2[_0x46afd2(0x3b6)]=![],_0x51f6a2[_0x46afd2(0x3c0)]=![],_0x51f6a2[_0x46afd2(0x2d2)]=![],_0x51f6a2[_0x46afd2(0x3d4)]={},_0x51f6a2[_0x46afd2(0x114)]=![],_0x51f6a2[_0x46afd2(0x4b0)]=![],_0x51f6a2[_0x46afd2(0x552)]=![],_0x51f6a2[_0x46afd2(0x524)]=null,_0x51f6a2[_0x46afd2(0x162)]=null,_0x51f6a2['style']=![],_0x51f6a2[_0x46afd2(0x43a)]=![],_0x51f6a2[_0x46afd2(0x4c1)]=![],_0x51f6a2['totalRoomBitrate']=![],_0x51f6a2[_0x46afd2(0x3c4)]=0x1f4,_0x51f6a2[_0x46afd2(0x464)]=_0x46afd2(0x3e0),_0x51f6a2[_0x46afd2(0x441)]=![],_0x51f6a2[_0x46afd2(0x1d1)]=![],_0x51f6a2['taintedSession']=![],_0x51f6a2[_0x46afd2(0x1ce)]=![],_0x51f6a2['transferred']=![],_0x51f6a2[_0x46afd2(0x1e3)]=![],_0x51f6a2['videoElement']=![],_0x51f6a2[_0x46afd2(0x498)]=![],_0x51f6a2[_0x46afd2(0x259)]=![],_0x51f6a2[_0x46afd2(0x56b)]=![],_0x51f6a2['view']=![],_0x51f6a2[_0x46afd2(0x1e5)]=![],_0x51f6a2[_0x46afd2(0x58f)]=0x64,_0x51f6a2[_0x46afd2(0x1f8)]=![],_0x51f6a2[_0x46afd2(0x2d8)]=![],_0x51f6a2['disableWebAudio']=![],_0x51f6a2[_0x46afd2(0x567)]={},_0x51f6a2[_0x46afd2(0x4c5)]={},_0x51f6a2[_0x46afd2(0x542)]=![],_0x51f6a2[_0x46afd2(0x37d)]=![],_0x51f6a2[_0x46afd2(0x40a)]={},_0x51f6a2[_0x46afd2(0x477)]=![],_0x51f6a2[_0x46afd2(0x22e)]=![],_0x51f6a2['ws']=null,_0x51f6a2[_0x46afd2(0x33f)]=![],_0x51f6a2[_0x46afd2(0x2de)]=![],_0x51f6a2['version']=null,_0x51f6a2[_0x46afd2(0x113)]=null,_0x51f6a2[_0x46afd2(0x484)]=![],_0x51f6a2['localMuteElement']=getById(_0x46afd2(0x196))[_0x46afd2(0x440)](!![]),_0x51f6a2['localMuteElement'][_0x46afd2(0x118)][_0x46afd2(0x33a)]=_0x46afd2(0x386),_0x51f6a2['localMuteElement'][_0x46afd2(0x118)]['right']=_0x46afd2(0x386),_0x51f6a2[_0x46afd2(0x40e)]['id']=_0x46afd2(0x40e),_0x51f6a2[_0x46afd2(0x367)]=getById('voiceMeterTemplate')[_0x46afd2(0x440)](!![]),_0x51f6a2[_0x46afd2(0x367)]['id']=_0x46afd2(0x532),_0x51f6a2['voiceMeter']['style'][_0x46afd2(0x21a)]=0x0,_0x51f6a2[_0x46afd2(0x367)][_0x46afd2(0x341)][_0x46afd2(0x51a)]=0x0,_0x51f6a2[_0x46afd2(0x367)][_0x46afd2(0x118)][_0x46afd2(0x1f8)]='10px',_0x51f6a2[_0x46afd2(0x367)][_0x46afd2(0x118)][_0x46afd2(0x2a6)]=_0x46afd2(0x28a),_0x51f6a2[_0x46afd2(0x367)][_0x46afd2(0x118)][_0x46afd2(0x33a)]=_0x46afd2(0x3db),_0x51f6a2[_0x46afd2(0x367)][_0x46afd2(0x118)][_0x46afd2(0x4c3)]=_0x46afd2(0x28a),_0x51f6a2['generateStreamID']=function(_0x33510e=0x7){var _0x3df636=_0x46afd2,_0xbb4d13='',_0x213ec1=_0x3df636(0x150);for(var _0x22dd57=0x0;_0x22dd57<_0x33510e;_0x22dd57++){_0xbb4d13+=_0x213ec1[_0x3df636(0x55b)](Math[_0x3df636(0x1d9)](Math[_0x3df636(0x233)]()*_0x213ec1[_0x3df636(0x39f)]));}return log(_0xbb4d13),_0xbb4d13;};function _0x129bad(_0x404faf){var _0x3f26fa=_0x46afd2,_0x474d46=new Uint8Array(_0x404faf[_0x3f26fa(0x39f)]);for(var _0x4965d9=0x0;_0x4965d9<_0x404faf[_0x3f26fa(0x39f)];_0x4965d9++){_0x474d46[_0x4965d9]=_0x404faf[_0x3f26fa(0x35a)](_0x4965d9);}return _0x474d46;}function _0x2df8ad(_0x439a6b){var _0x2e58d5=_0x46afd2;return Array[_0x2e58d5(0x1d2)][_0x2e58d5(0x348)][_0x2e58d5(0x435)](_0x439a6b,function(_0x2323e9){var _0xf6ac42=_0x2e58d5;return('0'+(_0x2323e9&0xff)['toString'](0x10))[_0xf6ac42(0x1ab)](-0x2);})[_0x2e58d5(0x549)]('');}function _0x1f789a(_0x1c996c){var _0x2a1838=_0x46afd2,_0x439e23=[];for(var _0x319490=0x0;_0x319490<_0x1c996c[_0x2a1838(0x39f)];_0x319490+=0x2){_0x439e23[_0x2a1838(0x438)](parseInt(_0x1c996c[_0x2a1838(0x198)](_0x319490,0x2),0x10));}return new Uint8Array(_0x439e23);}_0x51f6a2[_0x46afd2(0x3e3)]=function(_0x25978e,_0x485582=![]){var _0xe352e1=_0x46afd2,_0x37d2b9=new TextEncoder(_0xe352e1(0x4f9))[_0xe352e1(0x11f)](_0x25978e);return crypto[_0xe352e1(0x455)][_0xe352e1(0x361)](_0xe352e1(0x454),_0x37d2b9)[_0xe352e1(0x558)](function(_0x4d8564){var _0x3fa426=_0xe352e1;return _0x4d8564=new Uint8Array(_0x4d8564),_0x485582&&(_0x4d8564=_0x4d8564[_0x3fa426(0x1ab)](0x0,parseInt(parseInt(_0x485582)/0x2))),_0x4d8564=_0x2df8ad(_0x4d8564),_0x4d8564;});},_0x51f6a2['encryptMessage']=function(_0x3bd5ac){var _0x519b97=_0x46afd2,_0x4d38df=crypto[_0x519b97(0x3f0)](new Uint8Array(0x10));return crypto['subtle']['digest']({'name':_0x519b97(0x454)},_0x129bad(_0x51f6a2[_0x519b97(0x292)]+_0x51f6a2[_0x519b97(0x548)]))['then'](function(_0x76a976){var _0x5e3701=_0x519b97;return window[_0x5e3701(0x2e6)][_0x5e3701(0x455)]['importKey'](_0x5e3701(0x432),_0x76a976,{'name':_0x5e3701(0x339)},![],[_0x5e3701(0x30b),_0x5e3701(0x575)])[_0x5e3701(0x558)](function(_0x22e52e){var _0x21f6b1=_0x5e3701;return crypto[_0x21f6b1(0x455)][_0x21f6b1(0x30b)]({'name':'AES-CBC','iv':_0x4d38df},_0x22e52e,_0x129bad(_0x3bd5ac))['then'](function(_0x3f548f){return encrypted_data=new Uint8Array(_0x3f548f),encrypted_data=_0x2df8ad(encrypted_data),_0x4d38df=_0x2df8ad(_0x4d38df),[encrypted_data,_0x4d38df];},function(_0xdf2050){var _0x205e35=_0x21f6b1;return errorlog(_0xdf2050[_0x205e35(0x5a1)]),![];});},function(_0x49d5e6){return errorlog(_0x49d5e6),![];});});},_0x51f6a2[_0x46afd2(0x59d)]=function(_0x381f56,_0x769683){var _0x2349a5=_0x46afd2;if(_0x2349a5(0x262)===_0x2349a5(0x598)){function _0x1f1b5d(){_0x4ed368['forcePLI'](_0x3deec6),_0x37b045('FORCE\x20KEYFRAME\x20FOR\x20SCENE');}}else return _0x381f56=_0x1f789a(_0x381f56),_0x769683=_0x1f789a(_0x769683),crypto[_0x2349a5(0x455)][_0x2349a5(0x361)]({'name':_0x2349a5(0x454)},_0x129bad(_0x51f6a2[_0x2349a5(0x292)]+_0x51f6a2[_0x2349a5(0x548)]))['then'](function(_0xa59f88){var _0x2e454d=_0x2349a5;return window[_0x2e454d(0x2e6)][_0x2e454d(0x455)][_0x2e454d(0x374)](_0x2e454d(0x432),_0xa59f88,{'name':_0x2e454d(0x339)},![],['encrypt',_0x2e454d(0x575)])[_0x2e454d(0x558)](function(_0x4f30ea){var _0x274b24=_0x2e454d;if(_0x274b24(0x50d)!=='gHBOd'){function _0x65552a(){return;}}else return crypto[_0x274b24(0x455)][_0x274b24(0x575)]({'name':_0x274b24(0x339),'iv':_0x769683},_0x4f30ea,_0x381f56)[_0x274b24(0x558)](function(_0xf2463f){var _0x3ae645=_0x274b24,_0x3216d5=new Uint8Array(_0xf2463f),_0x5ad95a='';for(var _0xc27363=0x0;_0xc27363<_0x3216d5[_0x3ae645(0x1b7)];_0xc27363++){if(_0x3ae645(0x2e8)===_0x3ae645(0x488)){function _0x5de34f(){var _0x305871=_0x3ae645;_0x11e414[_0x305871(0x564)][_0x38621b][_0x305871(0x597)]=![],_0x112b9d[_0x305871(0x564)][_0x42e358]['allowVideo']=![],_0x5b4fc6[_0x305871(0x564)][_0x533e55][_0x305871(0x39c)]=![];}}else _0x5ad95a+=String[_0x3ae645(0x1d6)](_0x3216d5[_0xc27363]);}return _0x5ad95a;},function(_0x4fcf1c){var _0x1c433e=_0x274b24;return errorlog(_0x4fcf1c[_0x1c433e(0x5a1)]),![];});});});},_0x51f6a2[_0x46afd2(0x16b)]=function _0x2cc7ae(){var _0x2c753e=_0x46afd2;window['crypto'][_0x2c753e(0x455)][_0x2c753e(0x2cf)]({'name':_0x2c753e(0x34c),'modulusLength':0x200,'publicExponent':new Uint8Array([0x1,0x0,0x1]),'hash':{'name':_0x2c753e(0x384)}},!![],['sign',_0x2c753e(0x509)])[_0x2c753e(0x558)](function(_0x4ee5ad){var _0x363efe=_0x2c753e;log(_0x4ee5ad[_0x363efe(0x11c)]),log(_0x4ee5ad['privateKey']),_0x51f6a2[_0x363efe(0x1e1)]=_0x4ee5ad,window[_0x363efe(0x2e6)][_0x363efe(0x455)][_0x363efe(0x26f)](_0x363efe(0x32e),_0x4ee5ad['publicKey'])[_0x363efe(0x558)](function(_0x5bb4bc){var _0x509541=_0x363efe,_0x29f654={};_0x29f654['request']=_0x509541(0x43e),_0x29f654[_0x509541(0x231)]='OOO',_0x51f6a2[_0x509541(0x24e)](_0x29f654);})[_0x363efe(0x186)](errorlog);})[_0x2c753e(0x186)](errorlog);},_0x51f6a2[_0x46afd2(0x5a0)]=function(_0x3bc2b6,_0x87a1c0){var _0x33f3da=_0x46afd2;window[_0x33f3da(0x2e6)][_0x33f3da(0x455)][_0x33f3da(0x374)](_0x33f3da(0x32e),{'kty':_0x33f3da(0x485),'e':_0x33f3da(0x2d1),'n':_0x3bc2b6,'alg':_0x33f3da(0x3d7),'ext':!![]},{'name':_0x33f3da(0x34c),'hash':{'name':'SHA-1'}},!![],[_0x33f3da(0x509)])[_0x33f3da(0x558)](function(_0x3b2ae5){var _0x4a2e23=_0x33f3da;_0x51f6a2['keys'][_0x87a1c0]={},_0x51f6a2[_0x4a2e23(0x345)][_0x87a1c0][_0x4a2e23(0x11c)]=_0x3b2ae5,_0x51f6a2[_0x4a2e23(0x345)][_0x87a1c0]['privateKey']=null;})[_0x33f3da(0x186)](errorlog);},_0x51f6a2[_0x46afd2(0x4d3)]=function(_0x1006f7,_0x1dfa53=![]){var _0x1c888f=_0x46afd2,_0xa00a37={};_0xa00a37[_0x1c888f(0x372)]=!![],_0xa00a37[_0x1c888f(0x4d5)]=!![],_0x51f6a2['sendRequest'](_0xa00a37,_0x1006f7);},_0x51f6a2[_0x46afd2(0x4c9)]=function(_0xfa6cf7,_0x4f4fc7){var _0x5955ae=_0x46afd2,_0x4aa6ff={};_0x4aa6ff['audioBitrate']=_0xfa6cf7,log(_0x4aa6ff),_0x51f6a2[_0x5955ae(0x359)](_0x4aa6ff,_0x4f4fc7);},_0x51f6a2[_0x46afd2(0x42d)]=function(_0x2fd20a,_0x189b13){var _0x442e91=_0x46afd2;if(!_0x51f6a2[_0x442e91(0x125)][_0x189b13])return;if(_0x51f6a2[_0x442e91(0x125)][_0x189b13][_0x442e91(0x523)]!==![]){if(_0x51f6a2[_0x442e91(0x125)][_0x189b13][_0x442e91(0x523)]===_0x2fd20a)return;_0x51f6a2[_0x442e91(0x125)][_0x189b13][_0x442e91(0x32f)]=_0x51f6a2[_0x442e91(0x125)][_0x189b13][_0x442e91(0x523)];}else{if(_0x2fd20a===![]){if(_0x442e91(0x482)===_0x442e91(0x482)){if(_0x51f6a2[_0x442e91(0x125)][_0x189b13][_0x442e91(0x32f)]===_0x51f6a2['rpcs'][_0x189b13]['bandwidth'])return;}else{function _0x2038ca(){var _0x483f38=_0x442e91;_0x1e10d9[_0x483f38(0x125)][_0x42cdf7][_0x483f38(0x245)]();}}}else _0x51f6a2[_0x442e91(0x125)][_0x189b13][_0x442e91(0x32f)]=_0x2fd20a;}_0x2fd20a=parseInt(_0x51f6a2[_0x442e91(0x125)][_0x189b13]['targetBandwidth']);if(_0x51f6a2[_0x442e91(0x4ad)][_0x442e91(0x349)]===![]){if(_0x51f6a2[_0x442e91(0x379)]!==![]){if(window[_0x442e91(0x156)]){if('NuNoo'!=='NuNoo'){function _0x517778(){var _0xd4bc58=_0x442e91;_0x17f3f8(_0xd4bc58(0x48e)+_0x38c9bf);var _0x52c169={};_0x52c169[_0xd4bc58(0x157)]=_0x1cd3c6,_0x52c169[_0xd4bc58(0x23a)]=_0x510aa5,_0x404006[_0xd4bc58(0x359)](_0x52c169,_0x46d4d0)?_0x1e0044(_0xd4bc58(0x2c1)):_0x4314cf(_0xd4bc58(0x242));}}else return;}}}_0x2fd20a===0x0&&_0x51f6a2[_0x442e91(0x125)][_0x189b13][_0x442e91(0x3d1)]&&(_0x2fd20a=0x1);if(_0x51f6a2[_0x442e91(0x125)][_0x189b13][_0x442e91(0x328)]===_0x2fd20a)return;log(_0x442e91(0x1de)+_0x2fd20a);var _0x2168ed={};_0x2168ed[_0x442e91(0x3b7)]=_0x2fd20a,log(_0x2168ed),_0x51f6a2[_0x442e91(0x359)](_0x2168ed,_0x189b13)?_0x51f6a2[_0x442e91(0x125)][_0x189b13]['bandwidth']=_0x2fd20a:(setTimeout(function _0x378eed(){var _0x4664ee=_0x442e91;_0x51f6a2[_0x4664ee(0x42d)](![],_0x189b13);},0x1388),warnlog(_0x442e91(0x213)));},_0x51f6a2['toggleSoloChat']=function(_0x401e16){var _0x56695a=_0x46afd2;if(_0x51f6a2[_0x56695a(0x164)]){if(!_0x51f6a2['directorEnabledPPT']){warnUser('Enable\x20the\x20director\x27s\x20microphone\x20first.');return;}}_0x51f6a2[_0x56695a(0x3a9)]===_0x401e16?_0x51f6a2['soloChatUUID']=![]:_0x51f6a2[_0x56695a(0x3a9)]=_0x401e16;var _0x233320=document[_0x56695a(0x433)](_0x56695a(0x187));for(var _0x297561=0x0;_0x297561<_0x233320[_0x56695a(0x39f)];_0x297561++){if(_0x51f6a2['soloChatUUID']&&_0x233320[_0x297561][_0x56695a(0x341)]['UUID']===_0x51f6a2['soloChatUUID']){}else{if('ThTQW'===_0x56695a(0x1e4)){function _0x3d1638(){var _0x3e0283=_0x56695a;_0x3c30b4(_0x3e0283(0x406)),_0x3850be(_0x3e0283(0x4ff),_0x166336,_0x384f9e),_0x198280('setVideoScale',_0x311a06,_0x5c9670);}}else _0x233320[_0x297561][_0x56695a(0x1c6)][_0x56695a(0x205)](_0x56695a(0x437));}}_0x51f6a2[_0x56695a(0x592)](![]);},_0x51f6a2[_0x46afd2(0x592)]=function(_0xef93c8=!![]){var _0x473cc2=_0x46afd2;if(_0x51f6a2[_0x473cc2(0x164)]===![])return;else{if(!_0x51f6a2['directorEnabledPPT'])return;}if(_0x51f6a2[_0x473cc2(0x3a9)]){if(_0x51f6a2[_0x473cc2(0x3a9)]in _0x51f6a2[_0x473cc2(0x564)]){}else _0x51f6a2[_0x473cc2(0x3a9)]=![];}for(var _0x343ce7 in _0x51f6a2[_0x473cc2(0x564)]){try{var _0x5cff2e=_0x51f6a2[_0x473cc2(0x564)][_0x343ce7][_0x473cc2(0x356)]();_0x5cff2e[_0x473cc2(0x335)](_0x4f7486=>{var _0xd78a1d=_0x473cc2;if(!_0x4f7486[_0xd78a1d(0x3cb)])return;if(_0x4f7486[_0xd78a1d(0x3cb)]['kind']!=='audio')return;const _0x290007=_0x4f7486[_0xd78a1d(0x47e)]();if(!_0x290007['encodings'])_0x290007[_0xd78a1d(0x34f)]=[{}];else{if(!_0x290007[_0xd78a1d(0x34f)][_0xd78a1d(0x39f)])return;}if(_0x51f6a2[_0xd78a1d(0x3a9)]&&_0x51f6a2[_0xd78a1d(0x3a9)]===_0x343ce7)_0x290007[_0xd78a1d(0x34f)][0x0][_0xd78a1d(0x596)]=!![],setTimeout(function(_0x4cca16,_0xd47a38,_0x540c61){var _0x887f2a=_0xd78a1d;_0x540c61[_0x887f2a(0x337)](_0xd47a38)[_0x887f2a(0x558)](()=>{var _0x2b447d=_0x887f2a;document[_0x2b447d(0x433)](_0x2b447d(0x565)+_0x4cca16+'\x22]')[0x0][_0x2b447d(0x1c6)]['add'](_0x2b447d(0x437));})[_0x887f2a(0x186)](warnlog);},0x0,_0x343ce7,_0x290007,_0x4f7486);else _0x51f6a2[_0xd78a1d(0x3a9)]===![]?(_0x290007[_0xd78a1d(0x34f)][0x0]['active']=!![],_0x4f7486[_0xd78a1d(0x337)](_0x290007)[_0xd78a1d(0x558)](()=>{})[_0xd78a1d(0x186)](warnlog)):(_0x290007[_0xd78a1d(0x34f)][0x0][_0xd78a1d(0x596)]=![],setTimeout(function(_0x1c2d04,_0x57544f,_0x2c68de){var _0x26c7dc=_0xd78a1d;_0x2c68de[_0x26c7dc(0x337)](_0x57544f)[_0x26c7dc(0x558)]()[_0x26c7dc(0x186)](_0xc80858=>{var _0x56b0a1=_0x26c7dc;if('fEggE'!=='dzOgH')warnlog(_0xc80858),document[_0x56b0a1(0x433)]('[data-action-type=\x22solo-chat\x22][data--u-u-i-d=\x22'+_0x1c2d04+'\x22]')[0x0][_0x56b0a1(0x1c6)][_0x56b0a1(0x183)](_0x56b0a1(0x437));else{function _0x5d1f9(){_0x9cd4a6(function(){var _0x2a80b3=_0x45a6;_0x3ae584[_0x2a80b3(0x136)](_0x537681);},0x1388);}}});},0x0,_0x343ce7,_0x290007,_0x4f7486));});}catch(_0x29cd9c){errorlog(_0x29cd9c);}}if(_0xef93c8==![]){if(_0x51f6a2['soloChatUUID'])_0x51f6a2[_0x473cc2(0x13d)]=_0x51f6a2[_0x473cc2(0x574)],_0x51f6a2[_0x473cc2(0x574)]=![],data={},data[_0x473cc2(0x2b0)]=_0x51f6a2['muted'],_0x51f6a2['sendMessage'](data,_0x51f6a2[_0x473cc2(0x3a9)]);else{if(_0x473cc2(0x145)!==_0x473cc2(0x145)){function _0x1af828(){var _0x51829f=_0x473cc2;_0x2f78dc['pcs'][_0x424b21]['order']=_0x4638ae(_0xca11d1[_0x51829f(0x500)])||0x0;}}else _0x51f6a2[_0x473cc2(0x574)]=_0x51f6a2[_0x473cc2(0x13d)];}toggleMute(!![]);}},_0x51f6a2[_0x46afd2(0x4f6)]=function(){var _0x584774=_0x46afd2;if(_0x584774(0x13c)!==_0x584774(0x13c)){function _0x1e3162(){var _0x1cfb19=_0x584774,_0x5d23ca=_0x58b984[_0x1cfb19(0x433)](_0x1cfb19(0x585)+_0x156f10+'\x22]');_0x5d23ca[0x0]&&(_0x5d23ca[0x0][_0x1cfb19(0x22f)]=_0x4260d1,_0x383df2[_0x1cfb19(0x125)][_0x33fc81]['directorVolumeState']=_0x371026,_0x5aa688(_0x5d23ca[0x0]));}}else{if(_0x51f6a2[_0x584774(0x2ec)]===null)return;for(var _0x484e77 in _0x51f6a2[_0x584774(0x125)]){try{var _0xd16cda=_0x51f6a2[_0x584774(0x125)][_0x484e77][_0x584774(0x52c)]();for(var _0x46cc61=0x0;_0x46cc61<_0xd16cda[_0x584774(0x39f)];_0x46cc61++){_0xd16cda[_0x46cc61][_0x584774(0x3cb)][_0x584774(0x4e8)]==_0x584774(0x434)&&(_0xd16cda[_0x46cc61][_0x584774(0x3cb)]['enabled']=!_0x51f6a2[_0x584774(0x2ec)]);}}catch(_0x24b95e){}}_0x51f6a2[_0x584774(0x2ec)]&&(getById(_0x584774(0x31f))[_0x584774(0x574)]=!![]);}},_0x51f6a2[_0x46afd2(0x18e)]=function(){var _0x5a4b61=_0x46afd2;if(_0x51f6a2[_0x5a4b61(0x10f)]===null)return;if(_0x51f6a2[_0x5a4b61(0x10f)]){getById('gridlayout')['style'][_0x5a4b61(0x47f)]=_0x5a4b61(0x446);if(!_0x51f6a2[_0x5a4b61(0x368)]){if(_0x5a4b61(0x3f5)!==_0x5a4b61(0x3c6))warnUser(_0x5a4b61(0x4a2));else{function _0x14fd69(){var _0x335161=_0x5a4b61;_0x426ff2[_0x335161(0x564)][_0x5d8ceb[_0x335161(0x44a)]]['stats'][_0x335161(0x494)]['director']=!![];}}}}else getById(_0x5a4b61(0x3fa))[_0x5a4b61(0x118)]['display']='',!_0x51f6a2[_0x5a4b61(0x368)]&&closeModal();for(var _0x23c81d in _0x51f6a2[_0x5a4b61(0x125)]){try{if(_0x5a4b61(0x250)===_0x5a4b61(0x330)){function _0x4b7c2d(){_0x183e7d=_0x3fcfcc['roombitrate'];}}else{var _0xf6151f=_0x51f6a2[_0x5a4b61(0x125)][_0x23c81d]['getReceivers']();for(var _0x442d98=0x0;_0x442d98<_0xf6151f['length'];_0x442d98++){_0xf6151f[_0x442d98][_0x5a4b61(0x3cb)][_0x5a4b61(0x4e8)]==_0x5a4b61(0x232)&&(_0xf6151f[_0x442d98][_0x5a4b61(0x3cb)][_0x5a4b61(0x4f5)]=!_0x51f6a2[_0x5a4b61(0x10f)]);}}}catch(_0x4833eb){errorlog(_0x4833eb);}}_0x51f6a2[_0x5a4b61(0x10f)]&&(getById(_0x5a4b61(0x31f))[_0x5a4b61(0x574)]=!![]);},_0x51f6a2[_0x46afd2(0x155)]=function(_0x49cc84){var _0x385264=_0x46afd2;_0x49cc84[_0x385264(0x303)]();var _0x3e36b7=parseFloat(_0x49cc84[_0x385264(0x4c6)]*-0.001);log(_0x49cc84[_0x385264(0x2ca)]);if(_0x49cc84[_0x385264(0x46f)]||_0x49cc84[_0x385264(0x3ec)]){if(_0x385264(0x146)!==_0x385264(0x146)){function _0x2e6484(){var _0x1a29b3=_0x385264;_0x2cdce1(_0x1a29b3(0x537));}}else _0x51f6a2[_0x385264(0x51c)](_0x3e36b7,_0x49cc84[_0x385264(0x2ca)]['dataset'][_0x385264(0x484)]);}else _0x51f6a2[_0x385264(0x2a2)](_0x3e36b7,_0x49cc84[_0x385264(0x2ca)][_0x385264(0x341)]['UUID']);},_0x51f6a2[_0x46afd2(0x2a2)]=function(_0x40dc35,_0x3ff492,_0x2dd371=_0x51f6a2[_0x46afd2(0x23a)]){var _0x23207b=_0x46afd2;log(_0x23207b(0x248)+_0x40dc35),log(_0x3ff492);var _0x55c56a={};_0x55c56a[_0x23207b(0x2d8)]=_0x40dc35,_0x55c56a[_0x23207b(0x23a)]=_0x2dd371;if(_0x51f6a2[_0x23207b(0x359)](_0x55c56a,_0x3ff492)){if(_0x23207b(0x501)===_0x23207b(0x568)){function _0x2bf622(){_0x2e86fe=_0x40de2e,_0x11062d=_0x4321c3;}}else log(_0x23207b(0x1cd));}else errorlog(_0x23207b(0x1a2));},_0x51f6a2['requestFocusChange']=function(_0x14cef8,_0x32996f,_0x50cdf1=_0x51f6a2[_0x46afd2(0x23a)]){var _0x463bf7=_0x46afd2;log(_0x463bf7(0x48e)+_0x14cef8);var _0x5818f0={};_0x5818f0[_0x463bf7(0x157)]=_0x14cef8,_0x5818f0[_0x463bf7(0x23a)]=_0x50cdf1,_0x51f6a2['sendRequest'](_0x5818f0,_0x32996f)?log(_0x463bf7(0x2c1)):errorlog(_0x463bf7(0x242));},_0x51f6a2[_0x46afd2(0x28e)]=function(){var _0x9297ac=_0x46afd2;_0x51f6a2['connect']();if(_0x51f6a2[_0x9297ac(0x529)]!==![]){if(_0x9297ac(0x3b0)===_0x9297ac(0x3b0))_0x51f6a2[_0x9297ac(0x529)]=_0x9297ac(0x336),log(_0x9297ac(0x163));else{function _0x1227a0(){var _0x93e4a9=_0x9297ac;_0x879477[_0x93e4a9(0x149)]&&(_0x4c7919(_0x25c5b2[_0x93e4a9(0x125)][_0x3726fa][_0x93e4a9(0x2b2)]),_0x4dbd43[_0x93e4a9(0x125)][_0x2123d5]['videoElement'][_0x93e4a9(0x1f1)]('play',_0x5cdccb(_0x2fa24c)));}}}else{var _0x1b50ec={};_0x1b50ec[_0x9297ac(0x4a3)]=_0x9297ac(0x4da),_0x1b50ec[_0x9297ac(0x524)]=_0x51f6a2[_0x9297ac(0x524)],_0x51f6a2[_0x9297ac(0x24e)](_0x1b50ec),log(_0x9297ac(0x36d));}},_0x51f6a2[_0x46afd2(0x55c)]=function(_0x40e53b){var _0x26b596=_0x46afd2;try{if(navigator['userAgent'][_0x26b596(0x124)](_0x26b596(0x2c9))!=-0x1){if(!_0x51f6a2[_0x26b596(0x152)][_0x26b596(0x2e4)])return _0x40e53b;if(!_0x51f6a2[_0x26b596(0x152)]['srcObject'][_0x26b596(0x2a9)]()['length'])return _0x40e53b;if(_0x40e53b<=0x0)return _0x40e53b;var _0x2f7e68=_0x51f6a2[_0x26b596(0x152)][_0x26b596(0x2e4)][_0x26b596(0x2a9)]()[0x0]['getSettings'](),_0x370b6d=_0x2f7e68[_0x26b596(0x2a6)],_0x553be8=_0x2f7e68[_0x26b596(0x1f8)],_0x268f27=_0x370b6d*_0x40e53b/0x64,_0x4ae03f=_0x553be8*_0x40e53b/0x64;if(_0x268f27>_0x4ae03f){_0x268f27=parseInt(_0x268f27/0x10)*0x10;var _0x4dd2b6=0x64*_0x268f27/_0x370b6d;}else{_0x4ae03f=parseInt(_0x4ae03f/0x10)*0x10;var _0x4dd2b6=0x64*_0x4ae03f/_0x553be8;}return _0x4dd2b6;}else{if(navigator[_0x26b596(0x299)][_0x26b596(0x124)](_0x26b596(0x410))>-0x1){if(!_0x51f6a2['videoElement'][_0x26b596(0x2e4)]){if(_0x26b596(0x316)===_0x26b596(0x4a0)){function _0x29a4c8(){_0x57e637=_0x35b4d0;}}else return _0x40e53b;}if(!_0x51f6a2[_0x26b596(0x152)][_0x26b596(0x2e4)][_0x26b596(0x2a9)]()['length'])return _0x40e53b;if(_0x40e53b<=0x0)return _0x40e53b;var _0x2f7e68=_0x51f6a2['videoElement']['srcObject']['getVideoTracks']()[0x0][_0x26b596(0x331)](),_0x370b6d=_0x2f7e68['height'],_0x553be8=_0x2f7e68[_0x26b596(0x1f8)],_0x268f27=_0x370b6d*_0x40e53b/0x64,_0x4ae03f=_0x553be8*_0x40e53b/0x64;if(_0x268f27>_0x4ae03f){_0x268f27=parseInt(_0x268f27/0x10)*0x10;var _0x4dd2b6=0x64*_0x268f27/_0x370b6d;}else{_0x4ae03f=parseInt(_0x4ae03f/0x10)*0x10;var _0x4dd2b6=0x64*_0x4ae03f/_0x553be8;}return _0x4dd2b6;}else{if(_0x51f6a2[_0x26b596(0x58e)]===_0x26b596(0x29c)){if(!_0x51f6a2[_0x26b596(0x152)][_0x26b596(0x2e4)])return _0x40e53b;if(!_0x51f6a2['videoElement']['srcObject'][_0x26b596(0x2a9)]()[_0x26b596(0x39f)])return _0x40e53b;if(_0x40e53b<=0x0)return _0x40e53b;var _0x2f7e68=_0x51f6a2[_0x26b596(0x152)][_0x26b596(0x2e4)][_0x26b596(0x2a9)]()[0x0][_0x26b596(0x331)](),_0x370b6d=_0x2f7e68[_0x26b596(0x2a6)],_0x553be8=_0x2f7e68[_0x26b596(0x1f8)],_0x268f27=_0x370b6d*_0x40e53b/0x64,_0x4ae03f=_0x553be8*_0x40e53b/0x64;if(_0x268f27>_0x4ae03f){_0x268f27=parseInt(_0x268f27/0x10)*0x10;var _0x4dd2b6=0x64*_0x268f27/_0x370b6d;}else{_0x4ae03f=parseInt(_0x4ae03f/0x10)*0x10;var _0x4dd2b6=0x64*_0x4ae03f/_0x553be8;}return _0x4dd2b6;}else return _0x40e53b;}}}catch(_0x46ffd4){return _0x40e53b;}},_0x51f6a2[_0x46afd2(0x1a3)]=function(){var _0x51fa1c=_0x46afd2;log(_0x51fa1c(0x3e2));for(var _0x75ce43 in _0x51f6a2['pcs']){setTimeout(function(_0x29e989){var _0x24fdc8=_0x51fa1c;if(_0x51f6a2['pcs'][_0x29e989]['scaleResolution']!==![])log(_0x24fdc8(0x45a)),_0x51f6a2['setResolution'](_0x29e989,_0x51f6a2[_0x24fdc8(0x564)][_0x29e989][_0x24fdc8(0x547)],_0x51f6a2[_0x24fdc8(0x564)][_0x29e989]['scaleHeight']);else _0x51f6a2[_0x24fdc8(0x564)][_0x29e989][_0x24fdc8(0x1f4)]!==![]&&(log(_0x24fdc8(0x43d)),_0x51f6a2[_0x24fdc8(0x2bf)](_0x29e989,_0x51f6a2[_0x24fdc8(0x564)][_0x29e989]['scale']));},0x0,_0x75ce43);}},_0x51f6a2[_0x46afd2(0x2bf)]=function(_0x29d291,_0x211919){var _0x499c6b=_0x46afd2;warnlog(_0x499c6b(0x26e));if(_0x51f6a2['pcs'][_0x29d291][_0x499c6b(0x1f4)]!==_0x211919){_0x51f6a2[_0x499c6b(0x564)][_0x29d291][_0x499c6b(0x1f4)]=_0x211919;try{if(safariVersion()<=0xd&&(iOS||iPad))log(_0x499c6b(0x17b));else{if((adapter[_0x499c6b(0x2b6)][_0x499c6b(0x489)]===_0x499c6b(0x212)||adapter[_0x499c6b(0x2b6)][_0x499c6b(0x489)]===_0x499c6b(0x513)||adapter['browserDetails']['browser']===_0x499c6b(0x18f)&&adapter[_0x499c6b(0x2b6)][_0x499c6b(0x291)]>=0x40)&&_0x499c6b(0x1bc)in window&&_0x499c6b(0x337)in window[_0x499c6b(0x1bc)][_0x499c6b(0x1d2)]){var _0x29b141=_0x51f6a2['pcs'][_0x29d291][_0x499c6b(0x356)]()[_0x499c6b(0x25e)](function(_0x35a599){var _0x53d38d=_0x499c6b;return _0x35a599[_0x53d38d(0x3cb)]&&_0x35a599[_0x53d38d(0x3cb)]['kind']==_0x53d38d(0x232);});if(!_0x29b141){warnlog(_0x499c6b(0x32a));return;}var _0x5c50ed=_0x29b141[_0x499c6b(0x47e)]();(!_0x5c50ed['encodings']||_0x5c50ed[_0x499c6b(0x34f)][_0x499c6b(0x39f)]==0x0)&&(_0x5c50ed['encodings']=[{}]);_0x51f6a2[_0x499c6b(0x564)][_0x29d291][_0x499c6b(0x4bb)]&&(_0x51f6a2[_0x499c6b(0x564)][_0x29d291][_0x499c6b(0x4bb)]<_0x211919&&(_0x211919=_0x51f6a2[_0x499c6b(0x564)][_0x29d291][_0x499c6b(0x4bb)]));_0x51f6a2['pcs'][_0x29d291][_0x499c6b(0x49a)]&&_0x51f6a2[_0x499c6b(0x564)][_0x29d291]['scaleDueToBitrate']<_0x211919&&(_0x211919=_0x51f6a2['pcs'][_0x29d291][_0x499c6b(0x49a)]);_0x211919=_0x51f6a2[_0x499c6b(0x55c)](_0x211919);_0x211919<=0x0?_0x5c50ed[_0x499c6b(0x34f)][0x0][_0x499c6b(0x2ad)]=0x1:_0x5c50ed[_0x499c6b(0x34f)][0x0][_0x499c6b(0x2ad)]=0x64/_0x211919;_0x29b141[_0x499c6b(0x337)](_0x5c50ed)[_0x499c6b(0x558)](()=>{var _0x445981=_0x499c6b;log(_0x445981(0x42c)),log(_0x29b141[_0x445981(0x47e)]()),pokeIframeAPI(_0x445981(0x555),_0x211919,_0x29d291);})[_0x499c6b(0x186)](warnlog),_0x51f6a2['pcs'][_0x29d291][_0x499c6b(0x3d4)][_0x499c6b(0x243)]=parseInt(_0x211919)+'%';return;}}}catch(_0x5ba2b3){errorlog(_0x5ba2b3);}}},_0x51f6a2['requestResolution']=function(_0x29ca8c,_0x589ab6,_0x437e9d){var _0x3e81ed=_0x46afd2;if(!_0x51f6a2[_0x3e81ed(0x125)][_0x29ca8c])return;var _0x2e5090=![];_0x51f6a2[_0x3e81ed(0x125)][_0x29ca8c][_0x3e81ed(0x547)]!=_0x589ab6&&(_0x51f6a2[_0x3e81ed(0x125)][_0x29ca8c][_0x3e81ed(0x547)]=_0x589ab6,_0x2e5090=!![]);_0x51f6a2['rpcs'][_0x29ca8c][_0x3e81ed(0x4cb)]!=_0x437e9d&&(_0x51f6a2[_0x3e81ed(0x125)][_0x29ca8c]['scaleHeight']=_0x437e9d,_0x2e5090=!![]);log(_0x589ab6+'\x20'+_0x437e9d);if(_0x2e5090){var _0x50ad95={};_0x50ad95[_0x3e81ed(0x484)]=_0x29ca8c,_0x50ad95['requestResolution']={'w':_0x589ab6,'h':_0x437e9d},warnlog(_0x3e81ed(0x2eb)),warnlog(_0x50ad95),_0x51f6a2[_0x3e81ed(0x359)](_0x50ad95,_0x29ca8c);}_0x51f6a2[_0x3e81ed(0x125)][_0x29ca8c][_0x3e81ed(0x3d4)][_0x3e81ed(0x375)]=parseInt(_0x589ab6)+'\x20x\x20'+parseInt(_0x437e9d);},_0x51f6a2[_0x46afd2(0x493)]=function(_0x647ecf,_0x46d8fa,_0x2af339){var _0x1ccd28=_0x46afd2;_0x51f6a2[_0x1ccd28(0x564)][_0x647ecf][_0x1ccd28(0x547)]=_0x46d8fa,_0x51f6a2[_0x1ccd28(0x564)][_0x647ecf][_0x1ccd28(0x4cb)]=_0x2af339;if(safariVersion()<=0xd&&(iOS||iPad))return;if((adapter[_0x1ccd28(0x2b6)][_0x1ccd28(0x489)]===_0x1ccd28(0x212)||adapter[_0x1ccd28(0x2b6)][_0x1ccd28(0x489)]===_0x1ccd28(0x513)||adapter[_0x1ccd28(0x2b6)][_0x1ccd28(0x489)]===_0x1ccd28(0x18f)&&adapter[_0x1ccd28(0x2b6)][_0x1ccd28(0x291)]>=0x40)&&_0x1ccd28(0x1bc)in window&&_0x1ccd28(0x337)in window[_0x1ccd28(0x1bc)][_0x1ccd28(0x1d2)]){var _0x158f6e=_0x51f6a2['pcs'][_0x647ecf][_0x1ccd28(0x356)]()[_0x1ccd28(0x25e)](function(_0x8c0d62){var _0x359ef8=_0x1ccd28;return _0x8c0d62[_0x359ef8(0x3cb)]&&_0x8c0d62[_0x359ef8(0x3cb)]['kind']==_0x359ef8(0x232);});if(!_0x158f6e){warnlog(_0x1ccd28(0x32a));return;}var _0x35fa12=_0x158f6e[_0x1ccd28(0x47e)]();(!_0x35fa12[_0x1ccd28(0x34f)]||_0x35fa12[_0x1ccd28(0x34f)]['length']==0x0)&&(_0x35fa12['encodings']=[{}]);if(_0x51f6a2[_0x1ccd28(0x152)]){var _0x271de6=_0x51f6a2[_0x1ccd28(0x152)][_0x1ccd28(0x2e4)]['getVideoTracks']();if(_0x271de6[_0x1ccd28(0x39f)])var _0x5c632c=_0x51f6a2[_0x1ccd28(0x152)][_0x1ccd28(0x2e4)][_0x1ccd28(0x2a9)]()[0x0][_0x1ccd28(0x331)](),_0x10f696=_0x5c632c[_0x1ccd28(0x2a6)],_0xdae638=_0x5c632c[_0x1ccd28(0x1f8)];else return;}else return;var _0x106328=0x64*_0x46d8fa/_0xdae638,_0x14f00c=0x64*_0x2af339/_0x10f696;log(_0x106328+_0x1ccd28(0x1a0)+_0x14f00c);var _0x49ffd2=0x64;if(_0x106328>_0x14f00c)_0x49ffd2=_0x14f00c;else{if(_0x1ccd28(0x4b7)===_0x1ccd28(0x4b7))_0x49ffd2=_0x106328;else{function _0x4c2ea3(){var _0x32b7a1=_0x1ccd28;_0x234ff7(_0x3a581e[_0x32b7a1(0x2db)],_0x245542);}}}_0x49ffd2>0x64&&(_0x49ffd2=0x64);log('resolution\x20scale:\x20'+_0x49ffd2),_0x51f6a2[_0x1ccd28(0x564)][_0x647ecf][_0x1ccd28(0x4bb)]=_0x49ffd2;var _0x16478c=0x64;log(_0x1ccd28(0x4dc)+_0x51f6a2['pcs'][_0x647ecf][_0x1ccd28(0x1f4)]);_0x51f6a2[_0x1ccd28(0x564)][_0x647ecf][_0x1ccd28(0x1f4)]&&(_0x16478c=_0x51f6a2[_0x1ccd28(0x564)][_0x647ecf][_0x1ccd28(0x1f4)]);_0x16478c>_0x49ffd2&&(_0x16478c=_0x49ffd2);_0x51f6a2[_0x1ccd28(0x564)][_0x647ecf]['scaleResolution']&&(_0x51f6a2[_0x1ccd28(0x564)][_0x647ecf][_0x1ccd28(0x4bb)]<_0x16478c&&(_0x16478c=_0x51f6a2['pcs'][_0x647ecf][_0x1ccd28(0x4bb)]));_0x51f6a2[_0x1ccd28(0x564)][_0x647ecf][_0x1ccd28(0x49a)]&&_0x51f6a2['pcs'][_0x647ecf][_0x1ccd28(0x49a)]<_0x16478c&&(_0x16478c=_0x51f6a2['pcs'][_0x647ecf][_0x1ccd28(0x49a)]);log(_0x1ccd28(0x54b)+_0x16478c),_0x16478c=_0x51f6a2[_0x1ccd28(0x55c)](_0x16478c),log(_0x1ccd28(0x16a)+_0x16478c);if(_0x16478c<=0x0){if('rQwNB'===_0x1ccd28(0x1b8))_0x35fa12['encodings'][0x0][_0x1ccd28(0x2ad)]=0x1;else{function _0x2a7f0f(){var _0x15f3ec=_0x1ccd28;_0x180add!==_0x40a4d4&&(_0x388804[_0x15f3ec(0x125)][_0x3ecc1a][_0x15f3ec(0x152)]&&(_0x13729f[_0x15f3ec(0x125)][_0x3c9c8][_0x15f3ec(0x152)][_0x15f3ec(0x574)]=!![],_0x2e0adf[_0x15f3ec(0x125)][_0x3f05f9][_0x15f3ec(0x152)]['style'][_0x15f3ec(0x47f)]&&_0x43d6af['rpcs'][_0x3e4ba6][_0x15f3ec(0x152)][_0x15f3ec(0x118)][_0x15f3ec(0x47f)]!==_0x15f3ec(0x446)&&(_0x5067b8['rpcs'][_0x30f52f][_0x15f3ec(0x152)][_0x15f3ec(0x118)][_0x15f3ec(0x47f)]='none',_0x38e63a=!![])));}}}else{if(_0x1ccd28(0x201)===_0x1ccd28(0x201))_0x35fa12[_0x1ccd28(0x34f)][0x0][_0x1ccd28(0x2ad)]=0x64/_0x16478c;else{function _0x5913bd(){_0x1f9b86(_0x57ab4d);}}}_0x158f6e[_0x1ccd28(0x337)](_0x35fa12)[_0x1ccd28(0x558)](()=>{var _0x186ed4=_0x1ccd28;log(_0x186ed4(0x42c)),log(_0x35fa12),pokeIframeAPI(_0x186ed4(0x555),_0x16478c,_0x647ecf);})[_0x1ccd28(0x186)](warnlog),_0x51f6a2['pcs'][_0x647ecf][_0x1ccd28(0x3d4)][_0x1ccd28(0x243)]=parseInt(_0x16478c)+'%';return;}},_0x51f6a2[_0x46afd2(0x136)]=function(_0x2fbe4f=null,_0x327558=null){var _0x48115f=_0x46afd2;if('ZlfPb'!==_0x48115f(0x197)){function _0x5bd423(){var _0x278bb3=_0x48115f;_0x84e0ea(_0x278bb3(0x3bf));}}else{_0x327558&&_0x327558[_0x48115f(0x180)]();log('FORCING\x20A\x20KEY\x20FRAME:\x20'+_0x2fbe4f);if(iOS||iPad)log(_0x48115f(0x17b));else{if((adapter['browserDetails'][_0x48115f(0x489)]===_0x48115f(0x212)||adapter['browserDetails'][_0x48115f(0x489)]===_0x48115f(0x513)||adapter[_0x48115f(0x2b6)][_0x48115f(0x489)]===_0x48115f(0x18f)&&adapter[_0x48115f(0x2b6)][_0x48115f(0x291)]>=0x40)&&_0x48115f(0x1bc)in window&&_0x48115f(0x337)in window[_0x48115f(0x1bc)][_0x48115f(0x1d2)]){if(_0x2fbe4f==null){if(_0x48115f(0x311)!==_0x48115f(0x4b9)){for(_0x2fbe4f in _0x51f6a2[_0x48115f(0x564)]){_0x51f6a2[_0x48115f(0x136)](_0x2fbe4f);}return![];}else{function _0x27a4aa(){var _0x4e7ed7=_0x48115f;_0x2e0e30[_0x4e7ed7(0x564)][_0x1a9b56][_0x4e7ed7(0x500)]=_0x1033a2(_0x48a8ee['order'])||0x0;_0x463452 in _0x4389d1[_0x4e7ed7(0x125)]&&(_0x2152ff[_0x4e7ed7(0x125)][_0x59ac7e][_0x4e7ed7(0x500)]=_0x14f31f[_0x4e7ed7(0x564)][_0x323d04][_0x4e7ed7(0x500)]);if(_0x1d9918[_0x4e7ed7(0x164)]){var _0x1cb9bc=_0x8ea9e1['querySelectorAll'](_0x4e7ed7(0x499)+_0x32a243+'\x22]');_0x5d3761(_0x1cb9bc),_0x1cb9bc[0x0]&&(_0x1cb9bc[0x0][_0x4e7ed7(0x226)]=_0x4a364d(_0x4f609b['order'])||0x0);}_0x20cb54();}}}if(!(_0x2fbe4f in _0x51f6a2[_0x48115f(0x564)]))return![];_0x51f6a2['pcs'][_0x2fbe4f][_0x48115f(0x15d)]&&(_0x51f6a2['pcs'][_0x2fbe4f][_0x48115f(0x312)]&&(clearTimeout(_0x51f6a2['pcs'][_0x2fbe4f][_0x48115f(0x312)]),_0x51f6a2[_0x48115f(0x564)][_0x2fbe4f][_0x48115f(0x312)]=null),_0x51f6a2[_0x48115f(0x564)][_0x2fbe4f][_0x48115f(0x312)]=setTimeout(function(){var _0x135f01=_0x48115f;_0x51f6a2[_0x135f01(0x136)](_0x2fbe4f);},parseInt(_0x51f6a2[_0x48115f(0x564)][_0x2fbe4f][_0x48115f(0x15d)])));try{var _0x44e984=_0x51f6a2['pcs'][_0x2fbe4f][_0x48115f(0x356)]()[_0x48115f(0x25e)](function(_0x5528a6){var _0x42e044=_0x48115f;return _0x5528a6['track']&&_0x5528a6[_0x42e044(0x3cb)][_0x42e044(0x4e8)]=='video';});if(!_0x44e984)return warnlog(_0x48115f(0x32a)),![];var _0x5ac61c=_0x44e984[_0x48115f(0x47e)]();(!_0x5ac61c['encodings']||_0x5ac61c[_0x48115f(0x34f)][_0x48115f(0x39f)]==0x0)&&(_0x5ac61c[_0x48115f(0x34f)]=[{}]);var _0x2fefbe=![];_0x5ac61c[_0x48115f(0x34f)][0x0][_0x48115f(0x2ad)]=0xa,_0x44e984[_0x48115f(0x337)](_0x5ac61c)['then'](()=>{var _0x473720=_0x48115f;log(_0x473720(0x57e));var _0x32bb8d=_0x51f6a2[_0x473720(0x564)][_0x2fbe4f][_0x473720(0x4bb)],_0x17e995=0x64;if(!_0x32bb8d){if(_0x473720(0x3d3)!==_0x473720(0x353))_0x32bb8d=_0x17e995;else{function _0x5d1506(){var _0x30d92c=_0x473720;this[_0x30d92c(0x162)]['getTracks']()[_0x30d92c(0x335)](function(_0x14dc2f){_0x14dc2f['stop']();});}}}_0x51f6a2['pcs'][_0x2fbe4f][_0x473720(0x1f4)]&&(_0x17e995=_0x51f6a2['pcs'][_0x2fbe4f][_0x473720(0x1f4)]);_0x17e995>_0x32bb8d&&(_0x17e995=_0x32bb8d);_0x51f6a2[_0x473720(0x564)][_0x2fbe4f][_0x473720(0x4bb)]&&(_0x51f6a2[_0x473720(0x564)][_0x2fbe4f][_0x473720(0x4bb)]<_0x17e995&&(_0x17e995=_0x51f6a2[_0x473720(0x564)][_0x2fbe4f][_0x473720(0x4bb)]));_0x51f6a2[_0x473720(0x564)][_0x2fbe4f][_0x473720(0x49a)]&&_0x51f6a2[_0x473720(0x564)][_0x2fbe4f]['scaleDueToBitrate']<_0x17e995&&(_0x17e995=_0x51f6a2[_0x473720(0x564)][_0x2fbe4f]['scaleDueToBitrate']);log(_0x473720(0x54b)+_0x17e995),_0x17e995=_0x51f6a2[_0x473720(0x55c)](_0x17e995);var _0xf67843=_0x44e984[_0x473720(0x47e)]();_0xf67843[_0x473720(0x34f)][0x0][_0x473720(0x2ad)]=0x64/_0x17e995,log(_0x473720(0x53d)),_0x44e984[_0x473720(0x337)](_0xf67843)[_0x473720(0x558)](()=>{var _0x3758b1=_0x473720;log(_0x3758b1(0x448));})[_0x473720(0x186)](warnlog);})['catch'](warnlog);}catch(_0x49aa3d){errorlog(_0x49aa3d);}}}return![];}},_0x51f6a2[_0x46afd2(0x171)]=function(_0x2e72da){var _0x4f600a=_0x46afd2;if(_0x4f600a(0x301)==='MVzLI'){log(_0x4f600a(0x1c5));var _0x3b236f=_0x51f6a2[_0x4f600a(0x564)][_0x2e72da][_0x4f600a(0x356)]()[_0x4f600a(0x25e)](function(_0x45995b){var _0x82ee32=_0x4f600a;return _0x45995b['track']&&_0x45995b[_0x82ee32(0x3cb)][_0x82ee32(0x4e8)]==_0x82ee32(0x434);});if(!_0x3b236f){if(_0x4f600a(0x25b)!==_0x4f600a(0x25b)){function _0x35bdc0(){var _0x248e09=_0x4f600a,_0x5aa1ea={};_0x5aa1ea[_0x248e09(0x138)]=_0x22e072(_0x4015f7[_0x248e09(0x1dc)])||0x0,_0x5aa1ea[_0x248e09(0x3e5)]=_0xd2980e(_0x36703c[_0x248e09(0x3f2)])||0x0,_0x5aa1ea[_0x248e09(0x427)]=0x0,_0x5aa1ea['_trackID']=_0x531d8f[_0x248e09(0x11b)],_0x26765a[_0x248e09(0x125)][_0x271c3c]['stats'][_0x33112f['id']]=_0x5aa1ea;}}else return log(_0x4f600a(0x2b1)),![];}var _0x5a7c6=_0x3b236f[_0x4f600a(0x47e)]();(!_0x5a7c6[_0x4f600a(0x34f)]||_0x5a7c6[_0x4f600a(0x34f)][_0x4f600a(0x39f)]==0x0)&&(_0x5a7c6['encodings']=[{}]);try{_0x5a7c6['encodings'][0x0][_0x4f600a(0x45c)]=_0x4f600a(0x1a8),_0x5a7c6['encodings'][0x0]['priority']=_0x4f600a(0x1a8),_0x5a7c6[_0x4f600a(0x34f)][0x0][_0x4f600a(0x23e)]=!![],_0x3b236f[_0x4f600a(0x337)](_0x5a7c6)[_0x4f600a(0x558)](()=>{var _0x5c957d=_0x4f600a;log(_0x5c957d(0x4fc)),pokeIframeAPI(_0x5c957d(0x171),!![],_0x2e72da);});}catch(_0x4bae8b){errorlog(_0x4bae8b);}}else{function _0x463e96(){var _0x30d971=_0x4f600a;_0x123af8[_0x30d971(0x253)]=_0x3fbba2[_0x30d971(0x3f1)](_0x15b35e);var _0xb91bb7={};_0xb91bb7[_0x30d971(0x484)]=_0x251a26[_0x30d971(0x484)],_0xb91bb7[_0x30d971(0x436)]=_0x3f0a33[_0x30d971(0x436)];for(var _0x2b8e54=0x0;_0x2b8e54<_0x3d1174[_0x30d971(0x253)][_0x30d971(0x39f)];_0x2b8e54++){_0xb91bb7[_0x30d971(0x496)]=_0x3a25fc[_0x30d971(0x253)][_0x2b8e54],_0x10bd39[_0x30d971(0x520)](_0xb91bb7);}}}},_0x51f6a2[_0x46afd2(0x519)]=function(_0x393159,_0x1ef86e=0x7d00,_0x1dfd57=0x3e8){var _0x212b84=_0x46afd2;log('encodering\x20being\x20kicked');var _0x14978d=_0x51f6a2[_0x212b84(0x564)][_0x393159][_0x212b84(0x356)]()[_0x212b84(0x25e)](function(_0xedb5b5){var _0x1c3780=_0x212b84;return _0xedb5b5[_0x1c3780(0x3cb)]&&_0xedb5b5['track'][_0x1c3780(0x4e8)]==_0x1c3780(0x434);});if(!_0x14978d)return log(_0x212b84(0x2b1)),![];var _0x171de4=_0x14978d[_0x212b84(0x47e)]();(!_0x171de4[_0x212b84(0x34f)]||_0x171de4[_0x212b84(0x34f)]['length']==0x0)&&(_0x171de4['encodings']=[{}]),_0x171de4[_0x212b84(0x34f)][0x0][_0x212b84(0x53a)]=_0x1ef86e,_0x14978d[_0x212b84(0x337)](_0x171de4)[_0x212b84(0x558)](()=>{var _0x5ae253=_0x212b84;pokeIframeAPI(_0x5ae253(0x1f3),_0x1ef86e,_0x393159),_0x1dfd57>0x0&&setTimeout(function(){var _0x3d7226=_0x5ae253;try{if(_0x393159 in _0x51f6a2[_0x3d7226(0x564)])var _0x599b1f=_0x51f6a2[_0x3d7226(0x564)][_0x393159]['getSenders']()[_0x3d7226(0x25e)](function(_0x4a783b){var _0x3bfdcb=_0x3d7226;return _0x4a783b[_0x3bfdcb(0x3cb)]&&_0x4a783b[_0x3bfdcb(0x3cb)][_0x3bfdcb(0x4e8)]==_0x3bfdcb(0x434);});else return![];if(!_0x599b1f)return log(_0x3d7226(0x2b1)),![];var _0x47a07d=_0x599b1f[_0x3d7226(0x47e)]();delete _0x47a07d[_0x3d7226(0x34f)][0x0][_0x3d7226(0x53a)],_0x599b1f['setParameters'](_0x47a07d)[_0x3d7226(0x558)](()=>{log('done\x20clearing\x20audio');});}catch(_0x535850){errorlog(_0x535850);}},_0x1dfd57,_0x393159);});},_0x51f6a2['limitAudioBitrate']=function(_0x1b7df8,_0xd6f0a9){var _0x2c1996=_0x46afd2;_0xd6f0a9=parseInt(_0xd6f0a9);try{var _0x4c96a9=_0x51f6a2[_0x2c1996(0x564)][_0x1b7df8][_0x2c1996(0x356)]()[_0x2c1996(0x25e)](function(_0x16c942){var _0x514b17=_0x2c1996;return _0x16c942['track']&&_0x16c942[_0x514b17(0x3cb)]['kind']==_0x514b17(0x434);});if(!_0x4c96a9){warnlog(_0x2c1996(0x3bd));return;}var _0x1bbd97=_0x4c96a9[_0x2c1996(0x47e)]();(!_0x1bbd97[_0x2c1996(0x34f)]||_0x1bbd97[_0x2c1996(0x34f)][_0x2c1996(0x39f)]==0x0)&&(_0x1bbd97['encodings']=[{}]);if(_0xd6f0a9<0x0)_0x1bbd97['encodings'][0x0][_0x2c1996(0x596)]==![]&&(_0x1bbd97[_0x2c1996(0x34f)][0x0][_0x2c1996(0x596)]=!![]),safariVersion()<=0xd&&(iOS||iPad)?(_0xd6f0a9=0x20,_0x51f6a2[_0x2c1996(0x174)]&&(_0xd6f0a9=_0x51f6a2[_0x2c1996(0x174)]),_0x1bbd97[_0x2c1996(0x34f)][0x0][_0x2c1996(0x53a)]=_0xd6f0a9*0x400):delete _0x1bbd97[_0x2c1996(0x34f)][0x0][_0x2c1996(0x53a)];else _0xd6f0a9===0x0?_0x1bbd97[_0x2c1996(0x34f)][0x0][_0x2c1996(0x596)]=![]:(_0x1bbd97[_0x2c1996(0x34f)][0x0][_0x2c1996(0x596)]==![]&&(_0x1bbd97['encodings'][0x0][_0x2c1996(0x596)]=!![]),_0x1bbd97[_0x2c1996(0x34f)][0x0][_0x2c1996(0x53a)]=_0xd6f0a9*0x400);_0x4c96a9['setParameters'](_0x1bbd97)[_0x2c1996(0x558)](()=>{var _0x1f107e=_0x2c1996;pokeIframeAPI(_0x1f107e(0x1f3),_0xd6f0a9,_0x1b7df8),log(_0x1f107e(0x4fe));})[_0x2c1996(0x186)](warnlog);}catch(_0x356f47){errorlog(_0x356f47);}},_0x51f6a2[_0x46afd2(0x387)]=function(_0xa95484){var _0x320e91=_0x46afd2;if(_0x51f6a2[_0x320e91(0x29b)]&&_0x51f6a2['pcs'][_0xa95484]['allowIframe']===!![]){_0x51f6a2[_0x320e91(0x4fb)](_0xa95484,0x0);if(_0x51f6a2[_0x320e91(0x564)][_0xa95484][_0x320e91(0x338)]===0x0){if(_0x51f6a2[_0x320e91(0x564)][_0xa95484]['obsVisibility']===![]){if(_0x320e91(0x3d5)===_0x320e91(0x3d5))_0x51f6a2[_0x320e91(0x45f)](_0xa95484,0x0);else{function _0x24549b(){var _0x5f0b63=_0x320e91;_0x2c2549[_0x5f0b63(0x477)]?(_0x415de8[_0x5f0b63(0x232)]=![],_0x410409[_0x5f0b63(0x4d8)]=!![]):_0x1cb8f6[_0x5f0b63(0x232)]=!![];}}}else _0x51f6a2[_0x320e91(0x45f)](_0xa95484,-0x1);}}else{if(_0x51f6a2['pcs'][_0xa95484]&&_0x51f6a2[_0x320e91(0x564)][_0xa95484]['optimizedBitrate']!==![]){if(_0x51f6a2[_0x320e91(0x564)][_0xa95484]['obsVisibility']===![]){if('oNPjF'===_0x320e91(0x223)){var _0x1cc24d=_0x51f6a2[_0x320e91(0x564)][_0xa95484][_0x320e91(0x338)];_0x51f6a2[_0x320e91(0x564)][_0xa95484]['savedBitrate']&&_0x51f6a2['pcs'][_0xa95484]['savedBitrate']>0x0&&(_0x51f6a2[_0x320e91(0x564)][_0xa95484][_0x320e91(0x2af)]<_0x51f6a2[_0x320e91(0x564)][_0xa95484][_0x320e91(0x338)]&&(_0x1cc24d=_0x51f6a2[_0x320e91(0x564)][_0xa95484][_0x320e91(0x2af)])),_0x51f6a2[_0x320e91(0x4fb)](_0xa95484,_0x1cc24d),_0x51f6a2['pcs'][_0xa95484][_0x320e91(0x338)]===0x0&&_0x51f6a2[_0x320e91(0x45f)](_0xa95484,0x0);}else{function _0x303b36(){return![];}}}else _0x51f6a2[_0x320e91(0x564)][_0xa95484][_0x320e91(0x338)]===0x0&&_0x51f6a2['limitAudioBitrate'](_0xa95484,-0x1);}}},_0x51f6a2[_0x46afd2(0x257)]=function(_0x3fe5c2=0x0,_0x5a07b5=![]){var _0x3af18a=_0x46afd2;if(_0x51f6a2[_0x3af18a(0x593)]){var _0x12ee87=_0x3fe5c2;warnlog(_0x12ee87);var _0x2c3efe=0x0;for(var _0x2f931d in _0x51f6a2[_0x3af18a(0x564)]){if(_0x5a07b5===_0x2f931d)continue;var _0x1ea5a6=_0x51f6a2[_0x3af18a(0x564)][_0x2f931d][_0x3af18a(0x356)]()[_0x3af18a(0x25e)](function(_0x33fcf8){var _0x54f7f3=_0x3af18a;return _0x33fcf8[_0x54f7f3(0x3cb)]&&_0x33fcf8[_0x54f7f3(0x3cb)][_0x54f7f3(0x4e8)]=='video';});if(!_0x1ea5a6)continue;var _0x148c95=_0x1ea5a6[_0x3af18a(0x47e)]();if(!_0x148c95[_0x3af18a(0x34f)]||_0x148c95[_0x3af18a(0x34f)][_0x3af18a(0x39f)]==0x0){_0x12ee87+=_0x51f6a2[_0x3af18a(0x564)][_0x2f931d][_0x3af18a(0x4a7)]||0x9c4,warnlog(_0x12ee87),_0x2c3efe+=0x1;continue;}if(_0x148c95[_0x3af18a(0x34f)][0x0][_0x3af18a(0x596)]==![])continue;_0x148c95[_0x3af18a(0x34f)][0x0][_0x3af18a(0x53a)]?(_0x12ee87+=parseInt(_0x148c95[_0x3af18a(0x34f)][0x0][_0x3af18a(0x53a)])/0x400,warnlog(_0x12ee87)):(_0x12ee87+=_0x51f6a2[_0x3af18a(0x564)][_0x2f931d][_0x3af18a(0x4a7)]||0x9c4,warnlog(_0x12ee87)),_0x2c3efe+=0x1;}if(!_0x12ee87)return![];var _0x4b16b6=parseFloat(_0x12ee87/_0x51f6a2['limitTotalBitrate']);if(_0x4b16b6>0x1)for(var _0x2f931d in _0x51f6a2[_0x3af18a(0x564)]){if(_0x3af18a(0x52a)==='EKKXt'){if(_0x5a07b5===_0x2f931d)continue;var _0x1ea5a6=_0x51f6a2[_0x3af18a(0x564)][_0x2f931d][_0x3af18a(0x356)]()[_0x3af18a(0x25e)](function(_0x2b8736){var _0x8685e5=_0x3af18a;return _0x2b8736[_0x8685e5(0x3cb)]&&_0x2b8736[_0x8685e5(0x3cb)][_0x8685e5(0x4e8)]=='video';});if(!_0x1ea5a6)continue;var _0x148c95=_0x1ea5a6[_0x3af18a(0x47e)]();if(!_0x148c95[_0x3af18a(0x34f)]||_0x148c95[_0x3af18a(0x34f)][_0x3af18a(0x39f)]==0x0){var _0x2ccd2a=_0x51f6a2[_0x3af18a(0x564)][_0x2f931d][_0x3af18a(0x4a7)]||0x9c4;_0x51f6a2[_0x3af18a(0x4fb)](_0x2f931d,parseInt(_0x2ccd2a/_0x4b16b6),!![]),errorlog(parseInt(_0x2ccd2a/_0x4b16b6));continue;}if(_0x148c95[_0x3af18a(0x34f)][0x0][_0x3af18a(0x596)]==![])continue;if(_0x148c95[_0x3af18a(0x34f)][0x0][_0x3af18a(0x53a)])errorlog(parseInt(parseInt(_0x148c95[_0x3af18a(0x34f)][0x0][_0x3af18a(0x53a)])/0x400/_0x4b16b6)),_0x51f6a2[_0x3af18a(0x4fb)](_0x2f931d,parseInt(parseInt(_0x148c95[_0x3af18a(0x34f)][0x0][_0x3af18a(0x53a)])/0x400/_0x4b16b6),!![]);else{if(_0x3af18a(0x1b1)===_0x3af18a(0x4c7)){function _0x425e31(){var _0x5aff6e=_0x3af18a;let _0x2f978e=_0x24bc6a['view_set'][_0x5aff6e(0x124)](_0x292107[_0x5aff6e(0x125)][_0x292b74]['streamID']);_0x4ee8ed[_0x5aff6e(0x3f4)][_0x5aff6e(0x39f)]>_0x2f978e&&(_0x2cb899[_0x5aff6e(0x125)][_0x1ba843][_0x5aff6e(0x523)]=_0x23c47e(_0x567e44[_0x5aff6e(0x3f4)][_0x2f978e]),_0x3402b2[_0x5aff6e(0x125)][_0x5e57ce]['manualBandwidth']<=0x0&&(_0x28371b[_0x5aff6e(0x125)][_0xe82ea][_0x5aff6e(0x523)]=![]));}}else{var _0x2ccd2a=_0x51f6a2[_0x3af18a(0x564)][_0x2f931d][_0x3af18a(0x4a7)]||0x9c4;errorlog(parseInt(_0x2ccd2a/_0x4b16b6)),_0x51f6a2[_0x3af18a(0x4fb)](_0x2f931d,parseInt(_0x2ccd2a/_0x4b16b6),!![]);}}}else{function _0x1b8a5e(){var _0x1986f9=_0x3af18a;_0x48ee28(_0x1986f9(0x31f))[_0x1986f9(0x574)]=!![];}}}return parseInt(_0x3fe5c2/_0x4b16b6);}else return![];},_0x51f6a2[_0x46afd2(0x4fb)]=function(_0x100dd9,_0x5ef6c0,_0x43420b=![]){var _0x1ded4a=_0x46afd2;_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9]['bitrateTimeout']&&(clearInterval(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x3fc)]),_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x3fc)]=null);if(_0x5ef6c0===null){if(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x2af)]===![])return;_0x5ef6c0=_0x51f6a2['pcs'][_0x100dd9][_0x1ded4a(0x2af)];}_0x5ef6c0=parseInt(_0x5ef6c0);_0x51f6a2[_0x1ded4a(0x559)]&&(_0x5ef6c0>_0x51f6a2['maxvideobitrate']&&(_0x5ef6c0=_0x51f6a2[_0x1ded4a(0x559)]));_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9]['savedBitrate']=_0x5ef6c0;_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x338)]!==![]&&(_0x51f6a2['pcs'][_0x100dd9][_0x1ded4a(0x35c)]===![]&&(_0x5ef6c0>_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x338)]&&(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x2af)]=_0x5ef6c0,_0x5ef6c0=parseInt(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x338)])||0x0)));_0x43420b===![]&&(_0x51f6a2[_0x1ded4a(0x593)]&&(_0x5ef6c0=_0x51f6a2[_0x1ded4a(0x257)](_0x5ef6c0,_0x100dd9)));if(_0x5ef6c0==0x0){var _0x4a35a0=Date[_0x1ded4a(0x416)]()-_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x3bb)];_0x4a35a0<_0x51f6a2[_0x1ded4a(0x27e)]&&(_0x5ef6c0=0x23,_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x3fc)]=setTimeout(function(_0xab2df){var _0x4c0e9c=_0x1ded4a;if(_0x4c0e9c(0x57a)===_0x4c0e9c(0x5a8)){function _0x3d214e(){var _0x4b3c5f=_0x4c0e9c;_0xe4c570[_0x4b3c5f(0x44a)]=![];}}else _0x51f6a2[_0x4c0e9c(0x4fb)](_0xab2df,null);},_0x4a35a0,_0x100dd9));}try{if(safariVersion()<=0xd&&(iOS||iPad)){log(_0x1ded4a(0x17b));if(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x391)]==!![]&&_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x531)]==![])return;var _0x3d4afb=_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x356)]()['find'](function(_0x2765ec){var _0x3409c6=_0x1ded4a;return _0x2765ec[_0x3409c6(0x3cb)]&&_0x2765ec[_0x3409c6(0x3cb)][_0x3409c6(0x4e8)]==_0x3409c6(0x232);});if(!_0x3d4afb){warnlog(_0x1ded4a(0x32a));return;}var _0x325c31=_0x3d4afb[_0x1ded4a(0x47e)]();(!_0x325c31[_0x1ded4a(0x34f)]||_0x325c31[_0x1ded4a(0x34f)][_0x1ded4a(0x39f)]==0x0)&&(_0x325c31[_0x1ded4a(0x34f)]=[{}]);if(_0x5ef6c0<0x0){if(_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]==![]){if(_0x1ded4a(0x221)!==_0x1ded4a(0x221)){function _0x73ed19(){var _0x5ebcdc=_0x1ded4a;if(_0x25741c['track']['id']in _0x30cb58[_0x5ebcdc(0x125)][_0x3fefa2][_0x5ebcdc(0x256)]){_0x5707a4('updating\x20audio\x20delay');var _0x381657=_0x587bce-_0x42cf0b[_0x5ebcdc(0x125)][_0x475026][_0x5ebcdc(0x3d4)][_0x5c636b][_0x5ebcdc(0x427)]+_0x7d9a3c['sync'];_0x381657<0x0&&(_0x381657=0x0),_0x8b868(_0x5ebcdc(0x460)+_0x381657),_0xf1710a(_0x5ebcdc(0x4d9)+_0x166b28['audioCtx'][_0x5ebcdc(0x55d)]),_0x4cef13[_0x5ebcdc(0x125)][_0x5d4e22][_0x5ebcdc(0x256)][_0x25ba94['track']['id']][_0x5ebcdc(0x578)][_0x5ebcdc(0x486)](_0x22f86a(_0x381657/0x3e8),_0x1e804d[_0x5ebcdc(0x1b3)][_0x5ebcdc(0x55d)]+0x1),_0x4c600b[_0x5ebcdc(0x125)][_0xb7265b][_0x5ebcdc(0x3d4)][_0x545bed][_0x5ebcdc(0x29a)]=_0x381657;}}}else _0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]=!![];}_0x5ef6c0=0x9c4,_0x51f6a2['bitrate']&&(_0x5ef6c0=_0x51f6a2[_0x1ded4a(0x3b7)]),_0x51f6a2['maxvideobitrate']&&(_0x5ef6c0>_0x51f6a2[_0x1ded4a(0x559)]&&(_0x5ef6c0=_0x51f6a2[_0x1ded4a(0x559)])),_0x325c31[_0x1ded4a(0x34f)][0x0]['maxBitrate']=_0x5ef6c0*0x400;}else{if(_0x5ef6c0===0x0)_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]=![];else{if(_0x1ded4a(0x528)===_0x1ded4a(0x222)){function _0x5dd978(){_0xa0a728(_0x4a5e7d);}}else _0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]==![]&&(_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]=!![]),_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x53a)]=_0x5ef6c0*0x400;}}_0x3d4afb['setParameters'](_0x325c31)[_0x1ded4a(0x558)](()=>{var _0x4548ae=_0x1ded4a;pokeIframeAPI(_0x4548ae(0x4ff),_0x5ef6c0,_0x100dd9),log('bandwidth\x20set!');})[_0x1ded4a(0x186)](warnlog);return;}else{if((iOS||iPad)&&(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x391)]==!![]&&_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x531)]==![])){var _0x3e2bea=0x64;_0x51f6a2['pcs'][_0x100dd9][_0x1ded4a(0x1f4)]&&(_0x3e2bea=_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9]['scale']);if(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9]['scaleResolution']&&_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x4bb)]<_0x3e2bea){if(_0x1ded4a(0x385)!==_0x1ded4a(0x385)){function _0x53a1f3(){var _0x3537ed=_0x1ded4a;!(_0x4c3bc9[_0x3537ed(0x368)]||_0x80dc84[_0x3537ed(0x554)])&&_0x28fc35(_0x3537ed(0x390),0x1388);}}else _0x3e2bea=_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x4bb)];}_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9]['scaleDueToBitrate']=0x64/0x3,_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x49a)]<_0x3e2bea&&(_0x3e2bea=_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x49a)]),_0x3e2bea=_0x51f6a2[_0x1ded4a(0x55c)](_0x3e2bea),_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x2ad)]=0x64/_0x3e2bea,_0x3d4afb[_0x1ded4a(0x337)](_0x325c31)[_0x1ded4a(0x558)](()=>{var _0x2fb477=_0x1ded4a;log(_0x2fb477(0x121)),pokeIframeAPI(_0x2fb477(0x555),_0x3e2bea,_0x100dd9);})[_0x1ded4a(0x186)](warnlog),_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9]['stats']['scaleFactor']=parseInt(_0x3e2bea)+'%';}else{if((adapter[_0x1ded4a(0x2b6)][_0x1ded4a(0x489)]==='chrome'||adapter['browserDetails'][_0x1ded4a(0x489)]==='safari'||adapter[_0x1ded4a(0x2b6)]['browser']===_0x1ded4a(0x18f)&&adapter[_0x1ded4a(0x2b6)][_0x1ded4a(0x291)]>=0x40)&&_0x1ded4a(0x1bc)in window&&_0x1ded4a(0x337)in window[_0x1ded4a(0x1bc)][_0x1ded4a(0x1d2)]){var _0x3d4afb=_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x356)]()[_0x1ded4a(0x25e)](function(_0x195121){var _0x56d25e=_0x1ded4a;return _0x195121[_0x56d25e(0x3cb)]&&_0x195121['track'][_0x56d25e(0x4e8)]==_0x56d25e(0x232);});if(!_0x3d4afb){warnlog(_0x1ded4a(0x32a));return;}var _0x325c31=_0x3d4afb['getParameters']();(!_0x325c31[_0x1ded4a(0x34f)]||_0x325c31[_0x1ded4a(0x34f)]['length']==0x0)&&(_0x325c31[_0x1ded4a(0x34f)]=[{}]);if(_0x5ef6c0<0x0){if(_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]==![]){if(_0x1ded4a(0x23c)!==_0x1ded4a(0x400))_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]=!![];else{function _0x396239(){var _0x4a2323=_0x1ded4a;if(!_0x7a66a9['directorEnabledPPT']){_0x244f53(_0x4a2323(0x54f));return;}}}}delete _0x325c31[_0x1ded4a(0x34f)][0x0]['maxBitrate'];}else _0x5ef6c0===0x0?_0x325c31[_0x1ded4a(0x34f)][0x0]['active']=![]:(_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]==![]&&(_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x596)]=!![]),_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x53a)]=_0x5ef6c0*0x400);var _0x3e2bea=0x64;if(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x1f4)]){if(_0x1ded4a(0x132)!==_0x1ded4a(0x3b8))_0x3e2bea=_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x1f4)];else{function _0x534b1a(){var _0x8b2553=_0x1ded4a;_0x64f27b[_0x8b2553(0x4e5)]();}}}_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x4bb)]&&_0x51f6a2['pcs'][_0x100dd9][_0x1ded4a(0x4bb)]<_0x3e2bea&&(_0x3e2bea=_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x4bb)]);if(_0x5ef6c0<0x0)_0x51f6a2['pcs'][_0x100dd9][_0x1ded4a(0x49a)]=0x64;else{if(_0x5ef6c0>=0x259)_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x49a)]=0x64;else{if(_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x4d5)]===![]&&_0x51f6a2[_0x1ded4a(0x44a)]!==_0x100dd9&&_0x51f6a2[_0x1ded4a(0x2f7)])_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x49a)]=0x64;else{if(_0x5ef6c0>=0xc9)_0x51f6a2['mobile']?_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x49a)]=0x64/2.5:_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9]['scaleDueToBitrate']=0x64/0x2;else _0x5ef6c0>=0x51?_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x49a)]=0x64/0x3:_0x51f6a2['pcs'][_0x100dd9][_0x1ded4a(0x49a)]=0x64/0x4;}}}_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x49a)]<_0x3e2bea&&(_0x3e2bea=_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9]['scaleDueToBitrate']);_0x3e2bea=_0x51f6a2[_0x1ded4a(0x55c)](_0x3e2bea),_0x325c31[_0x1ded4a(0x34f)][0x0][_0x1ded4a(0x2ad)]=0x64/_0x3e2bea,_0x3d4afb['setParameters'](_0x325c31)['then'](()=>{var _0x28a2e7=_0x1ded4a;log('bandwidth\x20set!'),pokeIframeAPI(_0x28a2e7(0x4ff),_0x5ef6c0,_0x100dd9),pokeIframeAPI(_0x28a2e7(0x555),_0x3e2bea,_0x100dd9);})['catch'](warnlog),_0x51f6a2[_0x1ded4a(0x564)][_0x100dd9][_0x1ded4a(0x3d4)][_0x1ded4a(0x243)]=parseInt(_0x3e2bea)+'%';return;}}}}catch(_0x24ba91){errorlog(_0x24ba91);}};function _0x159ec6(_0x531bf6,_0x18191d=0x2710){var _0x1d3e00=_0x46afd2;_0x18191d=parseInt(_0x18191d);if(_0x51f6a2[_0x1d3e00(0x174)])_0x18191d+=_0x51f6a2[_0x1d3e00(0x174)];else{if(_0x51f6a2[_0x1d3e00(0x164)]&&_0x51f6a2[_0x1d3e00(0x552)]==0x5){if(_0x1d3e00(0x515)===_0x1d3e00(0x4dd)){function _0x3050f7(){var _0x3a97d2=_0x1d3e00,_0x1001eb,_0x590748=_0x414bb4[_0x3a97d2(0x299)];_0x5d966f[_0x3a97d2(0x494)]['useragent']=_0x590748;}}else _0x18191d+=0x20;}else _0x51f6a2[_0x1d3e00(0x552)]&&_0x51f6a2[_0x1d3e00(0x552)]!=0x3?_0x18191d+=0x100:_0x18191d+=0x20;}return log(_0x1d3e00(0x365)+_0x18191d),_0x18191d<0x1&&(_0x18191d=0x1),_0x531bf6=CodecsHandler['setVideoBitrates'](_0x531bf6,{'min':parseInt(_0x18191d/0xa)||0x1,'max':_0x18191d},_0x51f6a2[_0x1d3e00(0x58e)]),_0x531bf6;}return _0x51f6a2[_0x46afd2(0x126)]=function(_0x19dfae,_0x4097f7){var _0x5a4492=_0x46afd2;log(_0x19dfae),_0x51f6a2[_0x5a4492(0x1e1)]==={}&&log('Generate\x20Some\x20Crypto\x20keys\x20first'),window[_0x5a4492(0x2e6)][_0x5a4492(0x455)][_0x5a4492(0x472)]({'name':_0x5a4492(0x34c)},_0x51f6a2[_0x5a4492(0x1e1)][_0x5a4492(0x4ee)],_0x51f6a2[_0x5a4492(0x47c)][_0x5a4492(0x11f)](_0x19dfae))[_0x5a4492(0x558)](function(_0x25c156){var _0x20ee4b=_0x5a4492;_0x25c156=new Uint8Array(_0x25c156),_0x25c156=_0x25c156[_0x20ee4b(0x185)]((_0x5bae29,_0x1f4c9c)=>_0x5bae29+_0x1f4c9c[_0x20ee4b(0x34e)](0x10)[_0x20ee4b(0x38f)](0x2,'0'),''),_0x4097f7(_0x19dfae,_0x25c156),log(JSON['stringify'](_0x25c156));})[_0x5a4492(0x186)](errorlog);},_0x51f6a2[_0x46afd2(0x47b)]=function(_0x300e84,_0x4794d8){var _0x5c4bd7=_0x46afd2;_0x300e84[_0x5c4bd7(0x539)]=new Uint8Array(_0x300e84['signature'][_0x5c4bd7(0x51f)](/.{1,2}/g)[_0x5c4bd7(0x348)](_0x20b4e7=>parseInt(_0x20b4e7,0x10)));if(_0x51f6a2[_0x5c4bd7(0x345)][_0x4794d8]['publicKey'])return window['crypto'][_0x5c4bd7(0x455)][_0x5c4bd7(0x509)]({'name':_0x5c4bd7(0x34c)},_0x51f6a2[_0x5c4bd7(0x345)][_0x4794d8][_0x5c4bd7(0x11c)],_0x300e84[_0x5c4bd7(0x539)],_0x51f6a2[_0x5c4bd7(0x47c)][_0x5c4bd7(0x11f)](_0x300e84[_0x5c4bd7(0x2df)]))[_0x5c4bd7(0x558)](function(_0x519037){return log(_0x519037),_0x519037;})[_0x5c4bd7(0x186)](function(_0x11f773){return errorlog(_0x11f773),![];});},_0x51f6a2['desaltStreamID']=function(_0x14bb49){var _0x44878c=_0x46afd2;if(_0x51f6a2['password'])return _0x51f6a2[_0x44878c(0x4a4)]!==![]?(log('hash\x20is\x20not\x20false'),_0x14bb49=_0x14bb49[_0x44878c(0x1ab)](0x0,-0x1*_0x51f6a2[_0x44878c(0x4a4)][_0x44878c(0x39f)]),_0x14bb49):(log('Stream\x20ID\x20pre:'+_0x14bb49),_0x51f6a2[_0x44878c(0x3e3)](_0x51f6a2['password']+_0x51f6a2[_0x44878c(0x548)],0x6)[_0x44878c(0x558)](function(_0x446857){var _0xfb00ab=_0x44878c;if('wrvve'!==_0xfb00ab(0x4c8)){function _0x3785f3(){var _0xe6308b=_0xfb00ab;_0x53e1d0[_0xe6308b(0x564)][_0x6958b0][_0xe6308b(0x393)]=!![];}}else return _0x51f6a2['hash']=_0x446857,log(_0x14bb49),_0x14bb49=_0x14bb49[_0xfb00ab(0x1ab)](0x0,-0x1*_0x51f6a2[_0xfb00ab(0x4a4)][_0xfb00ab(0x39f)]),log('Final\x20streamID:\x20'+_0x14bb49),_0x14bb49;}));return _0x14bb49;},_0x51f6a2[_0x46afd2(0x307)]=function(){var _0x24a9c5=_0x46afd2;if(!_0x51f6a2['queue'])return;if(!_0x51f6a2[_0x24a9c5(0x164)])return;if(_0x51f6a2[_0x24a9c5(0x219)][_0x24a9c5(0x39f)]){if(_0x51f6a2[_0x24a9c5(0x219)][_0x24a9c5(0x39f)]>0xa){if(_0x24a9c5(0x29e)===_0x24a9c5(0x21b)){function _0x2ce038(){var _0x17be3e=_0x24a9c5;_0x3b7ce6[_0x17be3e(0x564)][_0x24aa1a][_0x17be3e(0x35c)]===![]?_0x5e4b60[_0x17be3e(0x45f)](_0x409fdb,0x0):_0x1dc326[_0x17be3e(0x45f)](_0x34fc4d,-0x1);}}else getById('queueNotification')[_0x24a9c5(0x453)]='‼';}else{if(_0x24a9c5(0x30e)==='JCWPs')getById(_0x24a9c5(0x18b))[_0x24a9c5(0x453)]=_0x51f6a2[_0x24a9c5(0x219)][_0x24a9c5(0x39f)];else{function _0x8fc762(){return;}}}getById(_0x24a9c5(0x18b))['classList'][_0x24a9c5(0x183)](_0x24a9c5(0x18b));}else getById('queueNotification')[_0x24a9c5(0x453)]='',getById('queueNotification')[_0x24a9c5(0x1c6)][_0x24a9c5(0x205)](_0x24a9c5(0x18b));},_0x51f6a2['nextQueue']=function(){var _0x1211ea=_0x46afd2;if(!_0x51f6a2['queue'])return;if(!_0x51f6a2[_0x1211ea(0x164)])return;if(_0x51f6a2[_0x1211ea(0x219)][_0x1211ea(0x39f)]==0x0){getById(_0x1211ea(0x3a2))[_0x1211ea(0x1c6)][_0x1211ea(0x183)](_0x1211ea(0x116)),getById('queuebutton')[_0x1211ea(0x1c6)][_0x1211ea(0x183)]('red'),getById(_0x1211ea(0x3a2))[_0x1211ea(0x1c6)][_0x1211ea(0x205)](_0x1211ea(0x178)),setTimeout(function(){var _0xd77086=_0x1211ea;getById(_0xd77086(0x3a2))[_0xd77086(0x1c6)][_0xd77086(0x183)]('float'),getById('queuebutton')[_0xd77086(0x1c6)]['remove'](_0xd77086(0x116)),getById(_0xd77086(0x3a2))[_0xd77086(0x1c6)][_0xd77086(0x205)](_0xd77086(0x3d6));},0x32);return;}var _0x7ebc40=_0x51f6a2[_0x1211ea(0x219)][_0x1211ea(0x24f)]();getById(_0x1211ea(0x3a2))[_0x1211ea(0x1c6)][_0x1211ea(0x183)]('float2'),getById(_0x1211ea(0x3a2))[_0x1211ea(0x1c6)][_0x1211ea(0x205)]('float'),setTimeout(function(){var _0x29874b=_0x1211ea;getById(_0x29874b(0x3a2))[_0x29874b(0x1c6)]['add']('float'),getById(_0x29874b(0x3a2))[_0x29874b(0x1c6)][_0x29874b(0x205)]('float2');},0xc8),_0x51f6a2[_0x1211ea(0x307)](),_0x51f6a2[_0x1211ea(0x570)](_0x7ebc40),log(_0x1211ea(0x527)+_0x7ebc40);},_0x51f6a2['ping']=function(){var _0x19fb0f=_0x46afd2;if(_0x19fb0f(0x476)===_0x19fb0f(0x214)){function _0x3a6eb1(){var _0x39373a=_0x19fb0f;_0x2d0d6d['stop'](),_0xe5252[_0x39373a(0x152)][_0x39373a(0x2e4)][_0x39373a(0x50b)](_0x8dadc2),_0x28e25e(_0x39373a(0x23b));}}else{if(_0x51f6a2[_0x19fb0f(0x33b)])return;clearTimeout(_0x51f6a2[_0x19fb0f(0x28d)]);if(!_0x51f6a2['ws']||_0x51f6a2['ws'][_0x19fb0f(0x37a)]!==0x1)return;_0x51f6a2[_0x19fb0f(0x28d)]=setTimeout(function(){var _0x110e7e=_0x19fb0f;if('tVpdQ'!==_0x110e7e(0x43c)){function _0xef4e5(){var _0x55d92e=_0x110e7e;_0x1debc6['info'][_0x55d92e(0x517)]=_0x55d92e(0x39e)+_0x954b9();}}else{log(_0x110e7e(0x51d));var _0x4b409d={};_0x4b409d[_0x110e7e(0x4a3)]=_0x110e7e(0x270),_0x51f6a2[_0x110e7e(0x24e)](_0x4b409d);}},0xbb8);}},_0x51f6a2[_0x46afd2(0x570)]=function(_0xcd8d4b){var _0x5acd85=_0x46afd2;_0x51f6a2[_0x5acd85(0x1d7)]();if(_0xcd8d4b[_0x5acd85(0x39f)]>0x0){var _0x2f263b={};_0x2f263b[_0x5acd85(0x4a3)]=_0x5acd85(0x450),_0x2f263b[_0x5acd85(0x524)]=_0xcd8d4b,_0x51f6a2[_0x5acd85(0x24e)](_0x2f263b),_0x51f6a2[_0x5acd85(0x40a)][_0xcd8d4b]=!![];}else log(_0x5acd85(0x281));},_0x51f6a2['joinRoom']=function _0x2a7120(_0x2de66e){var _0x59e071=_0x46afd2;_0x51f6a2[_0x59e071(0x1d7)]();var _0x150839={};_0x150839[_0x59e071(0x4a3)]=_0x59e071(0x4cc);_0x51f6a2['director']&&(_0x150839['claim']=!![]);if(_0x51f6a2[_0x59e071(0x33b)]){if('lGeyS'===_0x59e071(0x3cf)){function _0x27bd30(){var _0x55c621=_0x59e071;_0x10176e(_0x55c621(0x309));}}else _0x150839[_0x59e071(0x524)]=_0x51f6a2[_0x59e071(0x524)];}_0x51f6a2[_0x59e071(0x529)]===![]&&(_0x51f6a2[_0x59e071(0x529)]=!![]);if(_0x51f6a2[_0x59e071(0x292)])return _0x51f6a2[_0x59e071(0x4a4)]?_0x51f6a2[_0x59e071(0x3e3)](_0x2de66e+_0x51f6a2['password']+_0x51f6a2[_0x59e071(0x548)],0x10)[_0x59e071(0x558)](function(_0xaf8daa){var _0x1c13c2=_0x59e071;return _0x51f6a2[_0x1c13c2(0x33b)]&&(_0x51f6a2[_0x1c13c2(0x3e6)]=_0xaf8daa),_0x150839['roomid']=_0xaf8daa,_0x51f6a2[_0x1c13c2(0x24e)](_0x150839),_0x51f6a2['listPromise']=_0x15dbe0(),log('deferring\x20with\x20a\x20promise;\x20hashed\x20room'),_0x51f6a2[_0x1c13c2(0x280)];}):_0x51f6a2['generateHash'](_0x51f6a2[_0x59e071(0x292)]+_0x51f6a2['salt'],0x6)[_0x59e071(0x558)](function(_0x4a261b){var _0x1f1b8d=_0x59e071;return _0x51f6a2[_0x1f1b8d(0x4a4)]=_0x4a261b,log(_0x1f1b8d(0x2ac)+_0x4a261b),log('rejoining\x20room'),_0x51f6a2[_0x1f1b8d(0x169)](_0x2de66e);});else{if(_0x59e071(0x347)!==_0x59e071(0x282))return _0x51f6a2['pie']&&(_0x51f6a2[_0x59e071(0x3e6)]=_0x2de66e),_0x150839[_0x59e071(0x3f8)]=_0x2de66e,_0x51f6a2[_0x59e071(0x24e)](_0x150839),_0x51f6a2[_0x59e071(0x280)]=_0x15dbe0(),log(_0x59e071(0x1c1)),_0x51f6a2[_0x59e071(0x280)];else{function _0x2a9740(){var _0x370dc1=_0x59e071;_0x426581[_0x370dc1(0x464)]=_0xfe50b1[_0x370dc1(0x2e5)];}}}},_0x51f6a2[_0x46afd2(0x24e)]=function(_0x2a4672){var _0x5a86cc=_0x46afd2;if(_0x51f6a2[_0x5a86cc(0x33b)]){if(_0x51f6a2[_0x5a86cc(0x484)]){if('Fqexf'!==_0x5a86cc(0x191))_0x2a4672[_0x5a86cc(0x3fd)]=_0x51f6a2[_0x5a86cc(0x484)];else{function _0x15e397(){var _0x56ba48=_0x5a86cc;_0x402fde['noaudio'][_0x56ba48(0x254)](_0xd711b1[_0x56ba48(0x125)][_0x53055b][_0x56ba48(0x524)])?_0x49a385[_0x56ba48(0x434)]=!![]:_0x2ca9cc[_0x56ba48(0x434)]=![];}}}else _0x51f6a2[_0x5a86cc(0x484)]=_0x51f6a2[_0x5a86cc(0x5a5)](0x14),_0x2a4672['from']=_0x51f6a2[_0x5a86cc(0x484)];if(_0x51f6a2[_0x5a86cc(0x164)]){if('QKCeI'!==_0x5a86cc(0x249)){function _0x1e5328(){_0x29a65f=_0x3961fb;}}else _0x2a4672[_0x5a86cc(0x164)]=!![];}!(_0x5a86cc(0x3f8)in _0x2a4672)&&(_0x51f6a2[_0x5a86cc(0x3e6)]&&(_0x2a4672[_0x5a86cc(0x3f8)]=_0x51f6a2[_0x5a86cc(0x3e6)]));}clearTimeout(_0x51f6a2[_0x5a86cc(0x28d)]);try{if(_0x51f6a2[_0x5a86cc(0x292)]){if(_0x2a4672[_0x5a86cc(0x524)]){if(_0x51f6a2[_0x5a86cc(0x4a4)]!==![]){if(typeof _0x51f6a2['ws']!=='object'||_0x51f6a2['ws'][_0x5a86cc(0x37a)]!==0x1)log(_0x2a4672,'could\x20not\x20be\x20sent;\x20queuing\x20it'),_0x51f6a2[_0x5a86cc(0x595)]['push'](_0x2a4672);else{_0x2a4672[_0x5a86cc(0x524)]=_0x2a4672[_0x5a86cc(0x524)][_0x5a86cc(0x573)](0x0,0x18)+_0x51f6a2[_0x5a86cc(0x4a4)][_0x5a86cc(0x573)](0x0,0x6);var _0x42f90a=JSON[_0x5a86cc(0x240)](_0x2a4672);if(_0x42f90a[_0x5a86cc(0x39f)]>0x3a98){errorlog(_0x5a86cc(0x56a));return;}_0x51f6a2['ws'][_0x5a86cc(0x588)](_0x42f90a);}}else{if(_0x5a86cc(0x58c)!=='kvwcZ'){function _0x458db6(){var _0x217c1e=_0x5a86cc;return _0x183a94(_0x217c1e(0x2b1)),![];}}else return _0x51f6a2[_0x5a86cc(0x3e3)](_0x51f6a2[_0x5a86cc(0x292)]+_0x51f6a2[_0x5a86cc(0x548)],0x6)[_0x5a86cc(0x558)](function(_0x173b77){var _0x34527d=_0x5a86cc;_0x51f6a2['hash']=_0x173b77;if(typeof _0x51f6a2['ws']!==_0x34527d(0x58a)||_0x51f6a2['ws'][_0x34527d(0x37a)]!==0x1)log(_0x2a4672,_0x34527d(0x4b5)),_0x51f6a2[_0x34527d(0x595)][_0x34527d(0x438)](_0x2a4672);else{_0x2a4672[_0x34527d(0x524)]=_0x2a4672[_0x34527d(0x524)]['substring'](0x0,0x18)+_0x51f6a2[_0x34527d(0x4a4)][_0x34527d(0x573)](0x0,0x6);var _0x518789=JSON[_0x34527d(0x240)](_0x2a4672);if(_0x518789[_0x34527d(0x39f)]>0x3a98){errorlog('msg\x20size\x20error');return;}_0x51f6a2['ws'][_0x34527d(0x588)](_0x518789);}});}}else{if(_0x5a86cc(0x3bc)===_0x5a86cc(0x127)){function _0x3c1a2f(){delete _0x342003[_0x5c1bbe];}}else{if(typeof _0x51f6a2['ws']!==_0x5a86cc(0x58a)||_0x51f6a2['ws'][_0x5a86cc(0x37a)]!==0x1)log(_0x2a4672,_0x5a86cc(0x4b5)),_0x51f6a2[_0x5a86cc(0x595)][_0x5a86cc(0x438)](_0x2a4672);else{var _0x42f90a=JSON['stringify'](_0x2a4672);if(_0x42f90a[_0x5a86cc(0x39f)]>0x3a98){errorlog(_0x5a86cc(0x56a));return;}_0x51f6a2['ws'][_0x5a86cc(0x588)](_0x42f90a);}}}}else{if(typeof _0x51f6a2['ws']!=='object'||_0x51f6a2['ws'][_0x5a86cc(0x37a)]!==0x1)log(_0x2a4672,_0x5a86cc(0x4b5)),_0x51f6a2[_0x5a86cc(0x595)]['push'](_0x2a4672);else{var _0x42f90a=JSON[_0x5a86cc(0x240)](_0x2a4672);if(_0x42f90a['length']>0x3a98){errorlog(_0x5a86cc(0x56a));return;}_0x51f6a2['ws']['send'](_0x42f90a);}}}catch(_0x2145e8){errorlog(_0x2145e8);}},_0x51f6a2[_0x46afd2(0x1d7)]=function _0x474a7b(_0x2122ff=![]){var _0x1b30fe=_0x46afd2;if(_0x51f6a2[_0x1b30fe(0x4df)]===!![]){if(_0x1b30fe(0x2f0)===_0x1b30fe(0x4e0)){function _0x201f44(){var _0x194607=_0x1b30fe;_0x3cfcf4(_0x194607(0x244));}}else{log(_0x1b30fe(0x122));return;}}if(_0x51f6a2['ws']!==null){log(_0x1b30fe(0x1ef));return;}_0x51f6a2['wss']==![]&&(_0x51f6a2[_0x1b30fe(0x33f)]='wss://wss13.obs.ninja:443'),_0x51f6a2['ws']=new WebSocket(_0x51f6a2[_0x1b30fe(0x33f)]),_0x2122ff==![]&&(_0x51f6a2['timeout']=setTimeout(function(){var _0x14f7a0=_0x1b30fe;pokeIframeAPI('hssConnection',_0x14f7a0(0x2b5)),errorlog(_0x14f7a0(0x458)),!_0x51f6a2[_0x14f7a0(0x368)]&&(!window[_0x14f7a0(0x156)]&&setTimeout(function(){var _0x11a5f5=_0x14f7a0;warnUser(_0x11a5f5(0x27d));},0x1));},0x7530)),_0x51f6a2['ws'][_0x1b30fe(0x20d)]=function _0x257114(){var _0x5c090f=_0x1b30fe;clearTimeout(_0x51f6a2[_0x5c090f(0x28d)]),clearInterval(_0x51f6a2[_0x5c090f(0x2b5)]),log('connected\x20to\x20video\x20server'),checkConnection();if(_0x51f6a2[_0x5c090f(0x115)]){if(_0x5c090f(0x4b3)===_0x5c090f(0x4b3)){errorlog(_0x5c090f(0x2cd));for(_0x2d30dd in _0x51f6a2[_0x5c090f(0x125)]){try{_0x51f6a2[_0x5c090f(0x125)][_0x2d30dd][_0x5c090f(0x245)]();}catch(_0x946bf8){}}for(_0x2d30dd in _0x51f6a2[_0x5c090f(0x564)]){try{_0x51f6a2[_0x5c090f(0x564)][_0x2d30dd]['close']();}catch(_0x585cfc){}}_0x51f6a2[_0x5c090f(0x115)]=![];}else{function _0x37fe5d(){var _0x476da9=_0x5c090f;_0x4db5c4[_0x476da9(0x125)][_0x4b4e31][_0x476da9(0x4ae)]['style'][_0x476da9(0x47f)]=_0x476da9(0x446);}}}if(_0x51f6a2[_0x5c090f(0x595)]!==[])try{var _0x580b02=_0x51f6a2[_0x5c090f(0x595)]['slice'](-0xa);_0x51f6a2['msg']=[];for(var _0x10480e in _0x580b02){if(_0x5c090f(0x314)===_0x5c090f(0x314))log(_0x5c090f(0x3ae)),_0x51f6a2[_0x5c090f(0x24e)](_0x580b02[_0x10480e]);else{function _0x3d6487(){var _0xb23409=_0x5c090f;_0x1a9760('..\x20waiting\x20for\x20user\x20gesture'),_0x18b979[_0xb23409(0x125)][_0x284ee8]&&(_0x1b9b1b['firstPlayTriggered']&&(_0x3a4258(_0x47513a[_0xb23409(0x125)][_0x4c661a]['eventPlayActive']),_0x27a06a[_0xb23409(0x125)][_0x156913][_0xb23409(0x152)][_0xb23409(0x1f1)](_0xb23409(0x450),_0x96eb4a(_0x4a3948))));}}}}catch(_0x57de25){errorlog(_0x57de25);}if(_0x2122ff==!![]){pokeIframeAPI('hssConnection',_0x5c090f(0x27b));_0x51f6a2[_0x5c090f(0x569)]&&_0x51f6a2[_0x5c090f(0x28e)]();if(_0x51f6a2[_0x5c090f(0x3f8)]!==![]){if(_0x51f6a2[_0x5c090f(0x3f8)]===''&&(!_0x51f6a2[_0x5c090f(0x295)]||_0x51f6a2[_0x5c090f(0x295)]==='')){}else log(_0x5c090f(0x474)),log('Update\x20Mixer\x20Event\x20on\x20REsize\x20SET'),joinRoom(_0x51f6a2[_0x5c090f(0x3f8)]);}else{if(_0x5c090f(0x140)!==_0x5c090f(0x140)){function _0xab6813(){var _0x260950=_0x5c090f;_0x18683d[_0x260950(0x391)]==!![]&&(_0x3d666c[_0x260950(0x564)][_0x5d7e8e]['guest']=!![]);}}else{var _0x13b3cb=Object[_0x5c090f(0x345)](_0x51f6a2[_0x5c090f(0x40a)]);for(var _0x2d30dd in _0x13b3cb){if('tbojY'==='tbojY')log(_0x5c090f(0x293)+_0x13b3cb[_0x2d30dd]),_0x51f6a2[_0x5c090f(0x570)](_0x13b3cb[_0x2d30dd]);else{function _0x3d9ea5(){var _0x57733d=_0x5c090f;_0x48a0fd['encodings'][0x0][_0x57733d(0x596)]=!![];}}}}}}else pokeIframeAPI(_0x5c090f(0x13e),_0x5c090f(0x172));},_0x51f6a2[_0x1b30fe(0x16c)]=function(_0x18e69b,_0xc47a07=![]){var _0x31085a=_0x1b30fe,_0x2d4186=[];for(var _0x4e7b4b in _0x51f6a2['pcs']){if(_0xc47a07&&_0xc47a07!==_0x4e7b4b)continue;try{_0x51f6a2[_0x31085a(0x564)][_0x4e7b4b]['sendChannel'][_0x31085a(0x588)](JSON[_0x31085a(0x240)](_0x18e69b)),_0x2d4186[_0x31085a(0x438)](_0x4e7b4b);}catch(_0x1cd9e3){warnlog(_0x31085a(0x411));}if(_0xc47a07&&_0xc47a07===_0x4e7b4b)return;}for(var _0x4e7b4b in _0x51f6a2[_0x31085a(0x125)]){if(_0xc47a07&&_0xc47a07!==_0x4e7b4b){if(_0x31085a(0x20f)!==_0x31085a(0x20f)){function _0xca7283(){var _0x5e9d4b=_0x31085a;_0x45965d[_0x5e9d4b(0x564)][_0x1d8314['UUID']]['setBitrate']=_0x302299['getVideoBitrates'](_0xbb5136['description'][_0x5e9d4b(0x48f)]);}}else continue;}if(_0x2d4186[_0x31085a(0x254)](_0x4e7b4b)){if(_0x31085a(0x2b4)==='xIqsF')continue;else{function _0x546b2d(){var _0x2312e6=_0x31085a;_0x2c29bd[_0x2312e6(0x564)][_0x5b39d4][_0x2312e6(0x49a)]=0x64;}}}try{_0x51f6a2[_0x31085a(0x125)][_0x4e7b4b]['receiveChannel'][_0x31085a(0x588)](JSON['stringify'](_0x18e69b));}catch(_0x44ff93){warnlog(_0x31085a(0x19b));}}},_0x51f6a2[_0x1b30fe(0x34d)]=function(_0x266b0e,_0x55a86f=![]){var _0x40169c=_0x1b30fe,_0x1ae0a8=![];if(_0x40169c(0x484)in _0x266b0e){if('dcwuY'!==_0x40169c(0x44f))_0x1ae0a8=_0x51f6a2[_0x40169c(0x4fd)](_0x266b0e,_0x266b0e['UUID']),_0x1ae0a8?(log(_0x266b0e),log(_0x40169c(0x46a))):(log(_0x40169c(0x2fe)),_0x51f6a2['sendMsg'](_0x266b0e));else{function _0x3ad0d1(){var _0x73b8f4=_0x40169c;_0x3a2749[_0x73b8f4(0x484)]in _0x4a318b['rpcs']&&_0x5cb68d['offerSDP'](_0x471978['UUID']);}}}else{if(_0x55a86f){if(_0x40169c(0x1be)!==_0x40169c(0x26d))_0x1ae0a8=_0x51f6a2[_0x40169c(0x4fd)](_0x266b0e),_0x1ae0a8?(log(_0x266b0e),log(_0x40169c(0x3bf))):(log(_0x40169c(0x230)),_0x51f6a2[_0x40169c(0x24e)](_0x266b0e));else{function _0x2e28b7(){var _0xda7fa1=_0x40169c;_0x34cd28[_0xda7fa1(0x125)][_0x3f1240][_0xda7fa1(0x152)][_0xda7fa1(0x118)][_0xda7fa1(0x47f)]='none',_0x5e1f07=!![];}}}else _0x51f6a2[_0x40169c(0x24e)](_0x266b0e),log(_0x40169c(0x21d));}},_0x51f6a2[_0x1b30fe(0x1a9)]=function(_0x289e71,_0x34fbf6=![]){var _0x3ff0bc=_0x1b30fe,_0x1d5471=![];if(_0x3ff0bc(0x484)in _0x289e71){_0x1d5471=_0x51f6a2[_0x3ff0bc(0x359)](_0x289e71,_0x289e71[_0x3ff0bc(0x484)]);if(_0x1d5471){if(_0x3ff0bc(0x228)===_0x3ff0bc(0x228))log(_0x3ff0bc(0x46a));else{function _0x8e018(){var _0x26a9c0=_0x3ff0bc;_0x6d09de[_0x26a9c0(0x232)]=!![];}}}else log('sending\x20message\x20via\x20WSS\x20as\x20WebRTC\x20failed\x20to\x20send\x20message'),_0x51f6a2[_0x3ff0bc(0x24e)](_0x289e71);}else{if(_0x34fbf6){if('OhShO'===_0x3ff0bc(0x2c2))_0x1d5471=_0x51f6a2['sendRequest'](_0x289e71),_0x1d5471?log('successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS\x20to\x20all\x20RTC\x20Peers'):(log(_0x3ff0bc(0x230)),_0x51f6a2[_0x3ff0bc(0x24e)](_0x289e71));else{function _0x2210e6(){var _0x4ebcd1=_0x3ff0bc;try{_0x3bd926(_0x212f73),_0x5b3bea['setResolution'](_0x540bc7[_0x4ebcd1(0x484)],_0x3fd594[_0x4ebcd1(0x2eb)]['w'],_0x37b79d[_0x4ebcd1(0x2eb)]['h']);}catch(_0x1b6b0c){_0x27fada(_0x1b6b0c);}}}}else _0x51f6a2[_0x3ff0bc(0x24e)](_0x289e71),log(_0x3ff0bc(0x21d));}},_0x51f6a2[_0x1b30fe(0x4f0)]=function(){var _0x573a16=_0x1b30fe;if(_0x51f6a2[_0x573a16(0x255)]===![]){var _0xbc83a9={},_0xd2d421=![];_0x51f6a2[_0x573a16(0x4ad)][_0x573a16(0x349)]!==null&&(_0x51f6a2[_0x573a16(0x4ad)]['visibility']===![]&&(_0xd2d421=!![]),_0xbc83a9[_0x573a16(0x35c)]=_0x51f6a2[_0x573a16(0x4ad)][_0x573a16(0x349)]);_0x51f6a2[_0x573a16(0x4ad)][_0x573a16(0x143)]!==null&&(_0xbc83a9[_0x573a16(0x12f)]=_0x51f6a2[_0x573a16(0x4ad)]['sourceActive']);_0x51f6a2[_0x573a16(0x4ad)][_0x573a16(0x590)]!==null&&(_0xbc83a9[_0x573a16(0x42b)]=_0x51f6a2['obsState']['recording']);_0x51f6a2[_0x573a16(0x4ad)][_0x573a16(0x351)]!==null&&(_0xbc83a9[_0x573a16(0x211)]=_0x51f6a2[_0x573a16(0x4ad)][_0x573a16(0x351)]);for(var _0x41b2de in _0x51f6a2['rpcs']){if('AUWFo'!==_0x573a16(0x272)){if(_0x51f6a2[_0x573a16(0x379)]!==![]){var _0x12948e=parseInt(_0x51f6a2['rpcs'][_0x41b2de][_0x573a16(0x32f)]);_0xd2d421&&((_0x12948e>_0x51f6a2[_0x573a16(0x379)]||_0x12948e<0x0)&&(_0x12948e=_0x51f6a2[_0x573a16(0x379)]));if(_0x51f6a2[_0x573a16(0x125)][_0x41b2de][_0x573a16(0x328)]!==_0x12948e){if('IrgqC'==='IrgqC')_0xbc83a9[_0x573a16(0x3b7)]=_0x12948e,warnlog(_0x573a16(0x204)),warnlog(_0xbc83a9),_0x51f6a2[_0x573a16(0x359)](_0xbc83a9,_0x41b2de)?_0x51f6a2[_0x573a16(0x125)][_0x41b2de][_0x573a16(0x328)]=_0x12948e:errorlog(_0x573a16(0x25a));else{function _0x150f0e(){var _0xa95f91=_0x573a16;_0x11295b[_0xa95f91(0x125)][_0xe14543][_0xa95f91(0x152)]&&(_0x4aafc3[_0xa95f91(0x125)][_0x360271][_0xa95f91(0x152)][_0xa95f91(0x3d8)]&&_0x11fc37[_0xa95f91(0x125)][_0x12bb4f]['videoElement']['play']()[_0xa95f91(0x558)](_0x4708d7=>{_0x196510('playing');})[_0xa95f91(0x186)](_0x10d917));}}}else warnlog(_0x573a16(0x204)),warnlog(_0xbc83a9),_0x51f6a2['sendRequest'](_0xbc83a9,_0x41b2de);}else warnlog(_0x573a16(0x204)),warnlog(_0xbc83a9),_0x51f6a2[_0x573a16(0x359)](_0xbc83a9,_0x41b2de);}else{function _0x34510b(){var _0x284a64=_0x573a16;_0x13ac7e[_0x284a64(0x125)][_0x258d05][_0x284a64(0x3d4)][_0x166f49['trackId']]['packetLoss_in_percentage']=0x0;}}}}},_0x51f6a2[_0x1b30fe(0x57d)]=function(_0x48b74c){var _0x4c944b=_0x1b30fe;if(_0x4c944b(0x536)!=='ThUpp'){if(!_0x51f6a2[_0x4c944b(0x125)][_0x48b74c][_0x4c944b(0x152)])return;var _0x4ec9a0={};_0x4ec9a0[_0x4c944b(0x264)]=_0x51f6a2[_0x4c944b(0x125)][_0x48b74c]['videoElement']['style'][_0x4c944b(0x47f)]!=_0x4c944b(0x446),_0x4ec9a0[_0x4c944b(0x4ca)]=_0x51f6a2[_0x4c944b(0x125)][_0x48b74c][_0x4c944b(0x152)][_0x4c944b(0x574)];if(_0x51f6a2[_0x4c944b(0x379)]!==![]){var _0x51b457=parseInt(_0x51f6a2[_0x4c944b(0x125)][_0x48b74c][_0x4c944b(0x32f)]);if(_0x4ec9a0[_0x4c944b(0x264)]===![]){if(_0x51b457>_0x51f6a2[_0x4c944b(0x379)]||_0x51b457<0x0){if(_0x4c944b(0x2da)==='LjFwP')_0x51b457=_0x51f6a2[_0x4c944b(0x379)];else{function _0x508812(){var _0x3d977d=_0x4c944b;_0x4f4fa8(_0x3d977d(0x3bd));return;}}}}if(_0x51f6a2[_0x4c944b(0x125)][_0x48b74c]['bandwidth']!==_0x51b457)_0x4ec9a0[_0x4c944b(0x3b7)]=_0x51b457,_0x51f6a2[_0x4c944b(0x359)](_0x4ec9a0,_0x48b74c)?_0x51f6a2[_0x4c944b(0x125)][_0x48b74c][_0x4c944b(0x328)]=_0x51b457:errorlog(_0x4c944b(0x25a));else{if(_0x4c944b(0x190)===_0x4c944b(0x497)){function _0x48eeb0(){var _0x430473=_0x4c944b;_0x4b2c9d['pcs'][_0x21ba99['directorUUID']]['stats'][_0x430473(0x494)]&&(_0x43c49e[_0x430473(0x564)][_0x391df3[_0x430473(0x44a)]][_0x430473(0x3d4)]['info']['director']=!![]);}}else _0x51f6a2[_0x4c944b(0x359)](_0x4ec9a0,_0x48b74c);}}else _0x51f6a2['sendRequest'](_0x4ec9a0,_0x48b74c);}else{function _0x55a40b(){_0x1de66a=_0x41a838(_0x28bb77/0x10)*0x10;var _0x2df386=0x64*_0x5b42ac/_0x2e8633;}}},_0x51f6a2[_0x1b30fe(0x465)]=function(_0x47e7f7){var _0x52250d=_0x1b30fe;if(_0x52250d(0x419)in _0x47e7f7){if('target'in _0x47e7f7){if(_0x52250d(0x4d5)in _0x47e7f7){if(_0x52250d(0x46b)!==_0x52250d(0x41b)){if(_0x51f6a2[_0x52250d(0x4d5)]!==![]){var _0x44ebbc=![];for(var _0x53b257 in _0x51f6a2['rpcs']){if(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x524)]===_0x47e7f7[_0x52250d(0x2dc)]){if(_0x52250d(0x22f)in _0x47e7f7){if(_0x47e7f7[_0x52250d(0x419)]==_0x52250d(0x4cd))_0x47e7f7['value']==0x0?(log(_0x52250d(0x363)),_0x51f6a2[_0x52250d(0x125)][_0x53b257]['videoElement']&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x574)]=!![],_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x32b)]=!![])):(log('Unmute\x20video'),_0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)]&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]['style'][_0x52250d(0x47f)]=='none'?(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x32b)]=![],_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x574)]=!![]):(_0x51f6a2[_0x52250d(0x125)][_0x53b257]['mutedState']=![],_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]['muted']=![]))),_0x51f6a2[_0x52250d(0x57d)](_0x53b257);else{if(_0x47e7f7[_0x52250d(0x419)]=='display'){if(_0x51f6a2[_0x52250d(0x295)])return;;if(_0x51f6a2[_0x52250d(0x4d5)]===_0x47e7f7[_0x52250d(0x4d5)]){if(_0x51f6a2[_0x52250d(0x114)]==0x2){if(_0x47e7f7[_0x52250d(0x22f)]==0x0){if(_0x52250d(0x44b)===_0x52250d(0x184)){function _0x1c62ab(){_0xdce4ec(_0x12cc03);}}else _0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x574)]=!![],_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]&&_0x51f6a2[_0x52250d(0x125)][_0x53b257]['videoElement'][_0x52250d(0x118)][_0x52250d(0x47f)]!=='none'&&(_0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]='none',_0x44ebbc=!![]));}else{for(var _0x25b490 in _0x51f6a2[_0x52250d(0x125)]){_0x25b490!==_0x53b257&&(_0x51f6a2[_0x52250d(0x125)][_0x25b490][_0x52250d(0x152)]&&(_0x51f6a2[_0x52250d(0x125)][_0x25b490][_0x52250d(0x152)][_0x52250d(0x574)]=!![],_0x51f6a2['rpcs'][_0x25b490]['videoElement'][_0x52250d(0x118)]['display']&&_0x51f6a2[_0x52250d(0x125)][_0x25b490][_0x52250d(0x152)]['style'][_0x52250d(0x47f)]!==_0x52250d(0x446)&&(_0x51f6a2['rpcs'][_0x25b490][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]=_0x52250d(0x446),_0x44ebbc=!![])));}if(_0x51f6a2[_0x52250d(0x125)][_0x53b257]['videoElement']){if(_0x51f6a2[_0x52250d(0x125)][_0x53b257]['videoElement'][_0x52250d(0x118)][_0x52250d(0x47f)]&&_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]!==_0x52250d(0x239)){if(_0x52250d(0x490)==='aUWjo'){function _0xecb87d(){var _0x1503d9=_0x52250d;_0x53c8bd[_0x1503d9(0x24e)](_0x14cd71),_0x58d7a6(_0x1503d9(0x21d));}}else _0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]=_0x52250d(0x239),_0x44ebbc=!![];}_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x32b)]===null?_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x574)]=![]:_0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)][_0x52250d(0x574)]=_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x32b)],_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x2ee)]&&clearInterval(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x2ee)]),_0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)]['controls']=![],_0x51f6a2[_0x52250d(0x125)][_0x53b257]['videoElement'][_0x52250d(0x2ee)]=setTimeout(showControlBar[_0x52250d(0x53f)](null,_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]),0xbb8);}}}else{if(_0x51f6a2['sceneType']==0x1){if(_0x47e7f7['value']==0x0)_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]&&_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)]['display']!==_0x52250d(0x446)&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257]['videoElement']['style'][_0x52250d(0x47f)]=_0x52250d(0x446),_0x44ebbc=!![]));else{for(var _0x25b490 in _0x51f6a2[_0x52250d(0x125)]){_0x25b490!==_0x53b257&&(_0x51f6a2[_0x52250d(0x125)][_0x25b490][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]&&_0x51f6a2[_0x52250d(0x125)][_0x25b490][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]!==_0x52250d(0x446)&&(_0x51f6a2['rpcs'][_0x25b490][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]=_0x52250d(0x446),_0x44ebbc=!![]));}_0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)]&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]&&_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]!==_0x52250d(0x239)&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]['style']['display']=_0x52250d(0x239),_0x44ebbc=!![]),_0x51f6a2['rpcs'][_0x53b257]['videoElement'][_0x52250d(0x2ee)]&&clearInterval(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x2ee)]),_0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)][_0x52250d(0x4db)]=![],_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x2ee)]=setTimeout(showControlBar['bind'](null,_0x51f6a2['rpcs'][_0x53b257]['videoElement']),0xbb8));}}else{if(_0x47e7f7[_0x52250d(0x22f)]==0x0){if(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]){if(_0x52250d(0x29d)!=='FkyPX'){function _0x3c8808(){_0x1c3fc8=_0x394e5d;}}else _0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]&&_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]!=='none'&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]=_0x52250d(0x446),_0x44ebbc=!![]),_0x51f6a2[_0x52250d(0x125)][_0x53b257]['videoElement']['muted']=!![];}}else _0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)]&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]&&_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]!=='block'&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x118)][_0x52250d(0x47f)]=_0x52250d(0x239),_0x44ebbc=!![]),_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x32b)]===null?_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x574)]=![]:_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x574)]=_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x32b)],_0x51f6a2['rpcs'][_0x53b257][_0x52250d(0x152)][_0x52250d(0x2ee)]&&clearInterval(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x2ee)]),_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x4db)]=![],_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]['controlTimer']=setTimeout(showControlBar['bind'](null,_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]),0xbb8));}}}_0x51f6a2[_0x52250d(0x57d)](_0x53b257);}else _0x47e7f7[_0x52250d(0x419)]==_0x52250d(0x58f)&&(log(parseInt(_0x47e7f7[_0x52250d(0x22f)])/0x64),_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)]&&(_0x51f6a2[_0x52250d(0x125)][_0x53b257][_0x52250d(0x152)][_0x52250d(0x58f)]=parseInt(_0x47e7f7[_0x52250d(0x22f)])/0x64,log(_0x52250d(0x22d))));}}}}_0x44ebbc&&updateMixer();}}else{function _0x156262(){var _0x17c6c0=_0x52250d;_0x1979c0[_0x17c6c0(0x125)][_0x397d6b][_0x17c6c0(0x523)]=![];}}}else{if(_0x47e7f7[_0x52250d(0x419)]==_0x52250d(0x1f7)){}else{if(_0x47e7f7[_0x52250d(0x419)]==_0x52250d(0x483)){}}}}}},_0x51f6a2['ws'][_0x1b30fe(0x4fa)]=function(_0x4dff56){var _0x6f3b82=_0x1b30fe;clearTimeout(_0x51f6a2[_0x6f3b82(0x28d)]);var _0x4520ef=JSON[_0x6f3b82(0x3f1)](_0x4dff56[_0x6f3b82(0x2df)]);_0x6f3b82(0x524)in _0x4520ef&&(_0x4520ef[_0x6f3b82(0x524)]=_0x51f6a2['desaltStreamID'](_0x4520ef[_0x6f3b82(0x524)]));if(_0x51f6a2[_0x6f3b82(0x33b)]){if(_0x6f3b82(0x484)in _0x4520ef){if(_0x51f6a2[_0x6f3b82(0x484)]){if(_0x4520ef[_0x6f3b82(0x484)]!==_0x51f6a2['UUID'])return;}else return;delete _0x4520ef[_0x6f3b82(0x484)];}if(_0x6f3b82(0x3f8)in _0x4520ef){if(!_0x51f6a2[_0x6f3b82(0x3e6)])return;if('request'in _0x4520ef){if(_0x4520ef[_0x6f3b82(0x4a3)]===_0x6f3b82(0x1f7)){if(_0x6f3b82(0x3f8)in _0x4520ef){if(_0x6f3b82(0x2dc)in _0x4520ef){if(_0x4520ef['target']==_0x51f6a2[_0x6f3b82(0x484)]){_0x4520ef[_0x6f3b82(0x4a3)]=_0x6f3b82(0x115),_0x51f6a2[_0x6f3b82(0x3e6)]=_0x4520ef[_0x6f3b82(0x3f8)];var _0x3bea37={};_0x3bea37[_0x6f3b82(0x4a3)]=_0x6f3b82(0x4cc),_0x3bea37[_0x6f3b82(0x3f8)]=_0x51f6a2[_0x6f3b82(0x3e6)],_0x3bea37['streamID']=_0x51f6a2[_0x6f3b82(0x524)],_0x51f6a2[_0x6f3b82(0x24e)](_0x3bea37);}else return;}else return;}else return;}else{if(_0x4520ef[_0x6f3b82(0x3f8)]!==_0x51f6a2[_0x6f3b82(0x3e6)])return;}}else{if(_0x4520ef[_0x6f3b82(0x3f8)]!==_0x51f6a2[_0x6f3b82(0x3e6)])return;}delete _0x4520ef['roomid'];}if(_0x6f3b82(0x164)in _0x4520ef){if(_0x6f3b82(0x28f)===_0x6f3b82(0x33e)){function _0x40aba2(){var _0x1c1564=_0x6f3b82;_0x208a09=0x20,_0x450ef0[_0x1c1564(0x174)]&&(_0x5207d3=_0x3a4c4e[_0x1c1564(0x174)]),_0x507067[_0x1c1564(0x34f)][0x0][_0x1c1564(0x53a)]=_0x43fb5c*0x400;}}else _0x4520ef[_0x6f3b82(0x3fd)]&&(_0x51f6a2[_0x6f3b82(0x44a)]=_0x4520ef[_0x6f3b82(0x3fd)]),delete _0x4520ef[_0x6f3b82(0x164)];}_0x6f3b82(0x3fd)in _0x4520ef&&(_0x4520ef[_0x6f3b82(0x484)]=_0x4520ef[_0x6f3b82(0x3fd)],delete _0x4520ef[_0x6f3b82(0x3fd)]);if(_0x6f3b82(0x4a3)in _0x4520ef){if(_0x4520ef['request']===_0x6f3b82(0x450)){if(_0x6f3b82(0x30d)===_0x6f3b82(0x30d)){if('streamID'in _0x4520ef){if(_0x4520ef['streamID']===_0x51f6a2['streamID'])_0x4520ef[_0x6f3b82(0x4a3)]=_0x6f3b82(0x44d);else return;}}else{function _0x148f65(){var _0x533800=_0x6f3b82;'ip'in _0x380a8b&&(_0x47fe8d[_0x533800(0x125)][_0x2c327e]['stats'][_0x533800(0x599)][_0x533800(0x2f5)]=_0x27c627['ip']),_0x3e10b0[_0x533800(0x125)][_0x4f60a9]['stats']['RTC\x20Connection'][_0x533800(0x346)]=_0x42e32a[_0x533800(0x318)];}}}else{if(_0x4520ef['request']==='seed'){if(_0x51f6a2[_0x6f3b82(0x1e5)]){if(_0x51f6a2[_0x6f3b82(0x1e5)][_0x6f3b82(0x254)](_0x4520ef[_0x6f3b82(0x524)])){play(_0x4520ef[_0x6f3b82(0x524)]);return;}else return;}else{if(_0x51f6a2[_0x6f3b82(0x295)]){if(_0x51f6a2['view']!==_0x4520ef[_0x6f3b82(0x524)])return;else{play(_0x4520ef[_0x6f3b82(0x524)]);return;}}}}else{if(_0x4520ef[_0x6f3b82(0x4a3)]===_0x6f3b82(0x4cc)){if(_0x6f3b82(0x524)in _0x4520ef){if(_0x51f6a2[_0x6f3b82(0x1e5)]){if(_0x51f6a2[_0x6f3b82(0x1e5)][_0x6f3b82(0x254)](_0x4520ef[_0x6f3b82(0x524)]))play(_0x4520ef['streamID']);else{}}else{if(_0x51f6a2[_0x6f3b82(0x295)]){if(_0x6f3b82(0x2e3)===_0x6f3b82(0x2e3)){if(_0x51f6a2[_0x6f3b82(0x295)]!==_0x4520ef[_0x6f3b82(0x524)]){}else play(_0x4520ef[_0x6f3b82(0x524)]);}else{function _0x36ed4a(){_0x1d746a(function(){var _0x4171fd=_0x45a6;_0x2992dc(_0x4171fd(0x141));},0x1);}}}else play(_0x4520ef[_0x6f3b82(0x524)]);}}_0x4520ef[_0x6f3b82(0x4a3)]=_0x6f3b82(0x44d);}}}}}if(_0x4520ef[_0x6f3b82(0x4a3)]){if(_0x4520ef[_0x6f3b82(0x4a3)]=='offerSDP'){if(_0x51f6a2[_0x6f3b82(0x4b6)]){if(_0x51f6a2[_0x6f3b82(0x44a)]===_0x4520ef[_0x6f3b82(0x484)])_0x51f6a2[_0x6f3b82(0x44d)](_0x4520ef[_0x6f3b82(0x484)]);else _0x51f6a2[_0x6f3b82(0x164)]&&(_0x4520ef[_0x6f3b82(0x484)]in _0x51f6a2[_0x6f3b82(0x125)]&&_0x51f6a2[_0x6f3b82(0x44d)](_0x4520ef[_0x6f3b82(0x484)]));}else _0x51f6a2['offerSDP'](_0x4520ef[_0x6f3b82(0x484)]);}else{if(_0x4520ef['request']==_0x6f3b82(0x49b))log(_0x4520ef[_0x6f3b82(0x4cf)]),'director'in _0x4520ef?(_0x51f6a2[_0x6f3b82(0x44a)]=_0x4520ef[_0x6f3b82(0x164)],_0x51f6a2[_0x6f3b82(0x44a)]in _0x51f6a2['pcs']&&(_0x51f6a2[_0x6f3b82(0x564)][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)]&&(_0x51f6a2[_0x6f3b82(0x564)][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)]['info'][_0x6f3b82(0x164)]=!![])),_0x51f6a2[_0x6f3b82(0x44a)]in _0x51f6a2[_0x6f3b82(0x125)]&&(_0x51f6a2[_0x6f3b82(0x125)][_0x51f6a2[_0x6f3b82(0x44a)]]['stats'][_0x6f3b82(0x494)]&&(_0x51f6a2[_0x6f3b82(0x125)][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)][_0x6f3b82(0x164)]=!![]))):_0x51f6a2[_0x6f3b82(0x44a)]=![],'claim'in _0x4520ef&&(_0x4520ef[_0x6f3b82(0x52d)]==![]&&(!_0x51f6a2['cleanOutput']&&(setTimeout(function(){var _0x5c601b=_0x6f3b82;warnUser(_0x5c601b(0x3fe));},0x1),getById(_0x6f3b82(0x561))[_0x6f3b82(0x453)]=_0x6f3b82(0x510)))),_0x51f6a2[_0x6f3b82(0x280)][_0x6f3b82(0x267)](_0x4520ef[_0x6f3b82(0x4cf)]);else{if(_0x4520ef[_0x6f3b82(0x4a3)]==_0x6f3b82(0x115)){_0x51f6a2[_0x6f3b82(0x219)]=[],_0x51f6a2[_0x6f3b82(0x115)]=!![],log(_0x6f3b82(0x142));!_0x51f6a2[_0x6f3b82(0x164)]&&(_0x51f6a2[_0x6f3b82(0x4b6)]=![]);log(_0x4520ef[_0x6f3b82(0x4cf)]);if(_0x6f3b82(0x164)in _0x4520ef){_0x51f6a2[_0x6f3b82(0x44a)]=_0x4520ef[_0x6f3b82(0x164)];_0x51f6a2[_0x6f3b82(0x44a)]in _0x51f6a2[_0x6f3b82(0x564)]&&(_0x51f6a2[_0x6f3b82(0x564)][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)]['info']&&(_0x51f6a2[_0x6f3b82(0x564)][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)][_0x6f3b82(0x164)]=!![]));if(_0x51f6a2[_0x6f3b82(0x44a)]in _0x51f6a2[_0x6f3b82(0x125)]){if(_0x51f6a2['rpcs'][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)]){if(_0x6f3b82(0x1f0)!==_0x6f3b82(0x1f0)){function _0x41c7b3(){var _0x3e45e3=_0x6f3b82;_0x545318['sdp']=_0x2f05d1[_0x3e45e3(0x41e)](_0x20c836['sdp'],{'stereo':0x2,'maxaveragebitrate':(_0x4cff19['audiobitrate']||0x100)*0x400,'cbr':_0x4898c7['cbr'],'useinbandfec':0x1,'maxptime':_0xe2e637[_0x3e45e3(0x1ba)],'minptime':_0x3cf15a[_0x3e45e3(0x4d7)],'ptime':_0x48e575[_0x3e45e3(0x56f)]});}}else _0x51f6a2[_0x6f3b82(0x125)][_0x51f6a2[_0x6f3b82(0x44a)]]['stats']['info'][_0x6f3b82(0x164)]=!![];}}}else _0x51f6a2[_0x6f3b82(0x44a)]=![];for(_0x5083c2 in _0x51f6a2[_0x6f3b82(0x125)]){try{_0x51f6a2[_0x6f3b82(0x125)][_0x5083c2][_0x6f3b82(0x245)](),delete _0x51f6a2[_0x6f3b82(0x125)][_0x5083c2];}catch(_0x2559c4){}}for(_0x5083c2 in _0x51f6a2[_0x6f3b82(0x564)]){try{_0x51f6a2[_0x6f3b82(0x564)][_0x5083c2][_0x6f3b82(0x245)](),delete _0x51f6a2[_0x6f3b82(0x564)][_0x5083c2],applySceneState();}catch(_0x166a02){}}getChatMessage(_0x6f3b82(0x1c9),label=![],director=![],overlay=!![]),getById('head2')[_0x6f3b82(0x453)]=_0x6f3b82(0x50e);_0x51f6a2[_0x6f3b82(0x26c)]?document['title']=_0x51f6a2[_0x6f3b82(0x26c)]+_0x6f3b82(0x1f5):document[_0x6f3b82(0x464)]=_0x6f3b82(0x2ab);_0x51f6a2['totalRoomBitrate']=_0x51f6a2[_0x6f3b82(0x3c4)],updateMixer(),updateUserList(),log(_0x6f3b82(0x334)),log(_0x4520ef[_0x6f3b82(0x4cf)]);for(var _0x5083c2 in _0x4520ef['list']){if(_0x6f3b82(0x504)==='JYKuv'){if(_0x6f3b82(0x484)in _0x4520ef['list'][_0x5083c2]){if(_0x6f3b82(0x524)in _0x4520ef[_0x6f3b82(0x4cf)][_0x5083c2]){if(_0x4520ef[_0x6f3b82(0x4cf)][_0x5083c2][_0x6f3b82(0x484)]in _0x51f6a2[_0x6f3b82(0x125)])log(_0x6f3b82(0x2ce));else{var _0x153b37=_0x51f6a2[_0x6f3b82(0x37b)](_0x4520ef['list'][_0x5083c2][_0x6f3b82(0x524)]);log(_0x6f3b82(0x533)+_0x153b37);if(_0x51f6a2[_0x6f3b82(0x4b6)]){if(_0x51f6a2[_0x6f3b82(0x44a)]===_0x4520ef[_0x6f3b82(0x4cf)][_0x5083c2][_0x6f3b82(0x484)])play(_0x153b37);else _0x51f6a2[_0x6f3b82(0x219)][_0x6f3b82(0x39f)]<0x1388&&(!_0x51f6a2['queueList'][_0x6f3b82(0x254)](_0x153b37)&&_0x51f6a2[_0x6f3b82(0x219)][_0x6f3b82(0x438)](_0x153b37));}else play(_0x153b37);}}}}else{function _0x181002(){var _0x3d0999=_0x6f3b82;_0x1205d7[_0x3d0999(0x48f)]=_0x4b30e0['preferCodec'](_0x19d314['sdp'],_0x4ad236['codec']);}}}_0x51f6a2[_0x6f3b82(0x307)]();}else{if(_0x4520ef[_0x6f3b82(0x4a3)]==_0x6f3b82(0x12d))log(_0x4520ef),_0x6f3b82(0x164)in _0x4520ef?(_0x51f6a2[_0x6f3b82(0x44a)]=_0x4520ef['director'],_0x51f6a2[_0x6f3b82(0x44a)]in _0x51f6a2[_0x6f3b82(0x564)]&&(_0x51f6a2['pcs'][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)]&&(_0x51f6a2[_0x6f3b82(0x564)][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)]['info'][_0x6f3b82(0x164)]=!![])),_0x51f6a2['directorUUID']in _0x51f6a2[_0x6f3b82(0x125)]&&(_0x51f6a2['rpcs'][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)]&&(_0x51f6a2[_0x6f3b82(0x125)][_0x51f6a2[_0x6f3b82(0x44a)]]['stats'][_0x6f3b82(0x494)][_0x6f3b82(0x164)]=!![]))):(_0x51f6a2[_0x6f3b82(0x44a)]=![],errorlog('This\x20shouldn\x27t\x20happen')),updateUserList();else{if(_0x4520ef[_0x6f3b82(0x4a3)]==_0x6f3b82(0x371)){log('Inbound\x20User-based\x20Message\x20from\x20Room'),log(_0x4520ef);try{_0x6f3b82(0x164)in _0x4520ef&&(_0x4520ef[_0x6f3b82(0x164)]==!![]&&_0x51f6a2[_0x6f3b82(0x465)](_0x4520ef));}catch(_0x479fcf){errorlog(_0x479fcf);}}else{if(_0x4520ef[_0x6f3b82(0x4a3)]==_0x6f3b82(0x16e)){_0x4520ef[_0x6f3b82(0x164)]&&(_0x51f6a2[_0x6f3b82(0x44a)]=_0x4520ef[_0x6f3b82(0x484)],_0x51f6a2['directorUUID']in _0x51f6a2[_0x6f3b82(0x564)]&&(_0x51f6a2[_0x6f3b82(0x564)][_0x51f6a2['directorUUID']][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)]&&(_0x51f6a2[_0x6f3b82(0x564)][_0x51f6a2[_0x6f3b82(0x44a)]]['stats']['info'][_0x6f3b82(0x164)]=!![])),_0x51f6a2[_0x6f3b82(0x44a)]in _0x51f6a2[_0x6f3b82(0x125)]&&(_0x51f6a2[_0x6f3b82(0x125)][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)]&&(_0x51f6a2[_0x6f3b82(0x125)][_0x51f6a2[_0x6f3b82(0x44a)]][_0x6f3b82(0x3d4)][_0x6f3b82(0x494)][_0x6f3b82(0x164)]=!![])),updateUserList());if(_0x6f3b82(0x524)in _0x4520ef){log('Someone\x20Joined\x20the\x20Room\x20with\x20a\x20video');if(_0x51f6a2[_0x6f3b82(0x4b6)]){if(_0x51f6a2['directorUUID']===_0x4520ef[_0x6f3b82(0x484)])play(_0x153b37);else _0x51f6a2[_0x6f3b82(0x219)][_0x6f3b82(0x39f)]<0x1388&&(!_0x51f6a2[_0x6f3b82(0x219)][_0x6f3b82(0x254)](_0x4520ef[_0x6f3b82(0x524)])&&(_0x51f6a2[_0x6f3b82(0x219)][_0x6f3b82(0x438)](_0x4520ef[_0x6f3b82(0x524)]),_0x51f6a2[_0x6f3b82(0x307)]()));}else play(_0x4520ef[_0x6f3b82(0x524)]);}else log(_0x6f3b82(0x271));}else{if(_0x4520ef[_0x6f3b82(0x4a3)]==_0x6f3b82(0x263)){log(_0x6f3b82(0x194)),log(_0x4520ef);if(_0x51f6a2[_0x6f3b82(0x4b6)]){if(_0x51f6a2[_0x6f3b82(0x44a)]===_0x4520ef[_0x6f3b82(0x484)])play(_0x153b37);else _0x51f6a2[_0x6f3b82(0x219)][_0x6f3b82(0x39f)]<0x1388&&(!_0x51f6a2[_0x6f3b82(0x219)][_0x6f3b82(0x254)](_0x4520ef[_0x6f3b82(0x524)])&&(_0x51f6a2[_0x6f3b82(0x219)][_0x6f3b82(0x438)](_0x4520ef[_0x6f3b82(0x524)]),_0x51f6a2[_0x6f3b82(0x307)]()));}else play(_0x4520ef[_0x6f3b82(0x524)]);}else{if(_0x4520ef[_0x6f3b82(0x4a3)]==_0x6f3b82(0x119)){errorlog(_0x4520ef);if(_0x51f6a2[_0x6f3b82(0x4d5)]===![]){if(_0x6f3b82(0x518)!==_0x6f3b82(0x518)){function _0x5f4574(){var _0x5b6628=_0x6f3b82;_0x132881[_0x5b6628(0x173)][_0x5b6628(0x41c)]=_0x72c5c4[_0x5b6628(0x49f)];}}else{if(_0x6f3b82(0x5a1)in _0x4520ef){if(_0x4520ef[_0x6f3b82(0x5a1)]==='Stream\x20ID\x20is\x20already\x20in\x20use.'){if(_0x51f6a2[_0x6f3b82(0x4e2)]<0x2){if(_0x6f3b82(0x288)!==_0x6f3b82(0x566))_0x51f6a2[_0x6f3b82(0x4e2)]=parseInt(_0x51f6a2['seedAttempts'])+0x1,setTimeout(function(){var _0x277e07=_0x6f3b82;_0x51f6a2[_0x277e07(0x28e)]();},0x1388);else{function _0x3117cc(){var _0x28b5f2=_0x6f3b82;if(_0x13343a[_0x28b5f2(0x44a)]===_0x2e9e99[_0x28b5f2(0x484)])_0x263cd4(_0x41a337);else _0x206b5e[_0x28b5f2(0x219)][_0x28b5f2(0x39f)]<0x1388&&(!_0x443ec3['queueList'][_0x28b5f2(0x254)](_0x3eb255[_0x28b5f2(0x524)])&&(_0x5ee355['queueList']['push'](_0x361dfb[_0x28b5f2(0x524)]),_0x2d00c2[_0x28b5f2(0x307)]()));}}}else hangup(),!_0x51f6a2[_0x6f3b82(0x368)]&&setTimeout(function(){var _0x526ca3=_0x6f3b82;warnUser(_0x526ca3(0x168));},0x1);}else _0x4520ef[_0x6f3b82(0x5a1)]===_0x6f3b82(0x27c)?!_0x51f6a2[_0x6f3b82(0x368)]&&(setTimeout(function(){var _0x1a4d3e=_0x6f3b82;warnUser(_0x1a4d3e(0x3fe));},0x1),getById('head4')[_0x6f3b82(0x453)]='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. '):!_0x51f6a2[_0x6f3b82(0x368)]&&setTimeout(function(){warnUser(_0x4520ef['message']);},0x1);}}}}else _0x4520ef[_0x6f3b82(0x4a3)]==_0x6f3b82(0x54a)?_0x6f3b82(0x5a1)in _0x4520ef&&warnlog(_0x4520ef[_0x6f3b82(0x5a1)]):log(_0x4520ef);}}}}}}}}else{if(_0x4520ef['description']){if('streamID'in _0x4520ef){if(_0x4520ef[_0x6f3b82(0x524)]in _0x51f6a2[_0x6f3b82(0x567)]){if('CRCjM'===_0x6f3b82(0x29f)){function _0xf5470(){_0x56cce5('Answer\x20SDP\x20does\x20not\x20have\x20a\x20matching\x20session\x20ID');return;}}else clearTimeout(_0x51f6a2[_0x6f3b82(0x567)][_0x4520ef[_0x6f3b82(0x524)]]),delete _0x51f6a2[_0x6f3b82(0x567)][_0x4520ef['streamID']];}}_0x51f6a2[_0x6f3b82(0x1c2)](_0x4520ef);}else{if(_0x4520ef[_0x6f3b82(0x496)])log(_0x6f3b82(0x19d)),_0x51f6a2[_0x6f3b82(0x3ad)](_0x4520ef);else{if(_0x4520ef[_0x6f3b82(0x253)])log('GOT\x20ICES!!'),_0x51f6a2[_0x6f3b82(0x286)](_0x4520ef);else{if(_0x4520ef[_0x6f3b82(0x4a3)]==_0x6f3b82(0x2cc)){warnlog(_0x6f3b82(0x315));if(_0x4520ef[_0x6f3b82(0x484)]in _0x51f6a2[_0x6f3b82(0x564)]){if('IitWD'!==_0x6f3b82(0x572)){function _0x3d63fe(){var _0xf447f6=_0x6f3b82;_0xf447f6(0x340)in _0x506906[_0xf447f6(0x125)][_0x2a05f5]['videoElement']&&_0x579b1e[_0xf447f6(0x125)][_0x38c351][_0xf447f6(0x152)][_0xf447f6(0x340)][_0xf447f6(0x4e5)]();}}else warnlog(_0x6f3b82(0x2d4)),_0x51f6a2[_0x6f3b82(0x564)][_0x4520ef['UUID']][_0x6f3b82(0x245)](),delete _0x51f6a2[_0x6f3b82(0x564)][_0x4520ef['UUID']],_0x51f6a2[_0x6f3b82(0x592)](),applySceneState();}_0x4520ef[_0x6f3b82(0x484)]in _0x51f6a2[_0x6f3b82(0x125)]&&(warnlog(_0x6f3b82(0x2d4)),_0x51f6a2[_0x6f3b82(0x125)][_0x4520ef[_0x6f3b82(0x484)]]['close'](),delete _0x51f6a2[_0x6f3b82(0x125)][_0x4520ef[_0x6f3b82(0x484)]]);}else log('what\x20is\x20this?',_0x4520ef);}}}}},_0x51f6a2['ws'][_0x1b30fe(0x58b)]=function(_0x9979e7){var _0x3e413a=_0x1b30fe;clearTimeout(_0x51f6a2[_0x3e413a(0x28d)]),pokeIframeAPI(_0x3e413a(0x13e),'closed');try{if(_0x3e413a(0x4b1)in _0x9979e7){if(_0x9979e7[_0x3e413a(0x4b1)]==0x1f7){if(_0x2122ff==![]){if(_0x3e413a(0x25f)===_0x3e413a(0x57b)){function _0x442099(){var _0x4c8367=_0x3e413a,_0x24988d=_0x27a7f1[_0x4c8367(0x1e8)](_0x2290d8['description'][_0x4c8367(0x48f)])||0x9c4;_0x1c86b2(_0x4c8367(0x117)+_0x24988d);if(_0x24988d>_0x4ea9f2){var _0x1de147=_0x36c8ac[_0x4c8367(0x4e1)](_0x2caf88[_0x4c8367(0x398)][_0x4c8367(0x48f)])||0x0;_0x3f1ac0['description']['sdp']=_0x24370d[_0x4c8367(0x535)](_0xc088ec['description'][_0x4c8367(0x48f)],{'min':_0x4ae5a1(_0x3a68b2/0xa)||0x1,'max':_0xa89259(_0x70ea9e+_0x1de147/0x400)});}}}else{clearInterval(_0x51f6a2[_0x3e413a(0x2b5)]);if(!_0x51f6a2[_0x3e413a(0x368)]){if(_0x3e413a(0x3b3)!==_0x3e413a(0x3b2))warnUser(_0x3e413a(0x39a),0x7530);else{function _0x57c34a(){_0x354d58('Unable\x20to\x20set\x20update\x20OBS\x20Visibility');}}}}}}}}catch(_0x230e76){errorlog(_0x230e76);}errorlog('Connection\x20to\x20Control\x20Server\x20lost.\x0a\x0aAuto-reconnect\x20is\x20partially\x20implemented');if(_0x51f6a2[_0x3e413a(0x41a)]==![])try{_0x51f6a2['ws'][_0x3e413a(0x37a)]===WebSocket['CLOSED']&&(_0x51f6a2['ws']=null,setTimeout(()=>{var _0x294bdb=_0x3e413a;if(_0x294bdb(0x56d)!==_0x294bdb(0x56d)){function _0x22e34e(){_0xc58dac['audioCtx']['resume']();}}else _0x51f6a2[_0x294bdb(0x1d7)](!![]);},0x1388));}catch(_0x5bce3b){errorlog(_0x5bce3b);}};},_0x51f6a2['sendMessage']=function(_0x2364ca,_0xced20=null){var _0x1eb84a=_0x46afd2;_0x2364ca=JSON[_0x1eb84a(0x240)](_0x2364ca);if(_0xced20==null){for(var _0xe09480 in _0x51f6a2[_0x1eb84a(0x564)]){try{_0x51f6a2[_0x1eb84a(0x564)][_0xe09480][_0x1eb84a(0x2f3)][_0x1eb84a(0x588)](_0x2364ca);}catch(_0x348d40){warnlog(_0x1eb84a(0x309));}}return!![];}else try{if(_0x1eb84a(0x4d4)!==_0x1eb84a(0x2c4))return _0x51f6a2[_0x1eb84a(0x564)][_0xced20][_0x1eb84a(0x2f3)][_0x1eb84a(0x588)](_0x2364ca),!![];else{function _0x5b91c0(){var _0x1d4cef=_0x1eb84a;_0x2ee905['id']==_0x1aabd3[_0x1d4cef(0x3cb)]['id']&&_0x359c01['rpcs'][_0x5a2d80]['streamSrc'][_0x1d4cef(0x50b)](_0x18d0c2);}}}catch(_0x1bc33a){return warnlog(_0x1eb84a(0x1bd)),![];}return![];},_0x51f6a2[_0x46afd2(0x359)]=function(_0x4449da,_0x12749b=null){var _0x3b485e=_0x46afd2,_0x58727c=JSON[_0x3b485e(0x240)](_0x4449da);if(_0x12749b==null)for(var _0x2f18b9 in _0x51f6a2[_0x3b485e(0x125)]){try{_0x51f6a2['rpcs'][_0x2f18b9][_0x3b485e(0x57c)]['send'](_0x58727c);}catch(_0x562ff6){log('PUBLISHER\x27s\x20RTC\x20Connection\x20seems\x20to\x20be\x20dead?\x20');}}else try{return _0x51f6a2[_0x3b485e(0x125)][_0x12749b][_0x3b485e(0x57c)][_0x3b485e(0x588)](_0x58727c),!![];}catch(_0x1170c4){return log(_0x3b485e(0x53e)),![];}},_0x51f6a2[_0x46afd2(0x418)]=function(){setTimeout(function(){var _0x4a6765=_0x45a6;_0x51f6a2[_0x4a6765(0x418)];},0xbb8);},_0x51f6a2[_0x46afd2(0x551)]=function(_0x2435c2){var _0x4a8929=_0x46afd2;try{var _0x135070=_0x51f6a2[_0x4a8929(0x162)][_0x4a8929(0x2a9)]();_0x135070=_0x135070[0x0];if(_0x135070[_0x4a8929(0x1e0)]){var _0x4a5020=_0x135070['getCapabilities']();_0x51f6a2[_0x4a8929(0x2d8)]==![]&&(_0x51f6a2[_0x4a8929(0x2d8)]=_0x4a5020[_0x4a8929(0x2d8)][_0x4a8929(0x236)]);_0x51f6a2[_0x4a8929(0x2d8)]+=_0x2435c2;if(_0x51f6a2['zoom']>_0x4a5020['zoom'][_0x4a8929(0x167)])_0x51f6a2[_0x4a8929(0x2d8)]=_0x4a5020[_0x4a8929(0x2d8)][_0x4a8929(0x167)];else _0x51f6a2['zoom']<_0x4a5020[_0x4a8929(0x2d8)][_0x4a8929(0x236)]&&(_0x51f6a2['zoom']=_0x4a5020['zoom'][_0x4a8929(0x236)]);_0x135070[_0x4a8929(0x2ea)]({'advanced':[{'zoom':_0x51f6a2[_0x4a8929(0x2d8)]}]});}}catch(_0x10e791){errorlog(_0x10e791);}},_0x51f6a2[_0x46afd2(0x483)]=function(){var _0x5c2931=_0x46afd2;_0x51f6a2[_0x5c2931(0x4df)]=!![],warnlog(_0x5c2931(0x2bb));try{var _0x2377d7={};_0x2377d7[_0x5c2931(0x498)]=!![],_0x51f6a2[_0x5c2931(0x4fd)](_0x2377d7);}catch(_0x1e9535){}try{_0x51f6a2['ws']['close']();}catch(_0x155848){}try{recordLocalVideo(_0x5c2931(0x4e5));}catch(_0x3fb742){}try{if(_0x5c2931(0x373)===_0x5c2931(0x373)){_0x51f6a2[_0x5c2931(0x4e7)]&&_0x51f6a2[_0x5c2931(0x4e7)]['srcObject'][_0x5c2931(0x188)]()[_0x5c2931(0x335)](function(_0x962dea){var _0x4e46d8=_0x5c2931;_0x962dea[_0x4e46d8(0x4e5)](),_0x51f6a2[_0x4e46d8(0x152)][_0x4e46d8(0x2e4)]['removeTrack'](_0x962dea),log(_0x4e46d8(0x23b));});_0x51f6a2[_0x5c2931(0x152)]['srcObject'][_0x5c2931(0x188)]()[_0x5c2931(0x335)](function(_0x57a89c){var _0x2c3f63=_0x5c2931;_0x57a89c[_0x2c3f63(0x4e5)](),_0x51f6a2[_0x2c3f63(0x152)][_0x2c3f63(0x2e4)][_0x2c3f63(0x50b)](_0x57a89c),log(_0x2c3f63(0x23b));}),_0x51f6a2[_0x5c2931(0x162)]['getTracks']()['forEach'](function(_0x419941){var _0x1abad9=_0x5c2931;_0x419941['stop'](),_0x51f6a2['videoElement'][_0x1abad9(0x2e4)][_0x1abad9(0x50b)](_0x419941),log('stopping\x20old\x20track');});for(i in _0x51f6a2[_0x5c2931(0x125)]){_0x51f6a2['rpcs'][i][_0x5c2931(0x152)]&&(_0x51f6a2[_0x5c2931(0x125)][i][_0x5c2931(0x152)][_0x5c2931(0x590)]&&(_0x51f6a2[_0x5c2931(0x125)][i][_0x5c2931(0x152)][_0x5c2931(0x340)][_0x5c2931(0x1ca)][_0x5c2931(0x245)](),_0x51f6a2['rpcs'][i][_0x5c2931(0x152)]['recording']=![])),_0x51f6a2[_0x5c2931(0x125)][i][_0x5c2931(0x245)](),_0x51f6a2[_0x5c2931(0x125)][i]=null,delete _0x51f6a2[_0x5c2931(0x125)][i];}for(i in _0x51f6a2[_0x5c2931(0x564)]){_0x51f6a2[_0x5c2931(0x564)][i][_0x5c2931(0x245)](),_0x51f6a2[_0x5c2931(0x564)][i]=null,delete _0x51f6a2[_0x5c2931(0x564)][i],applySceneState();}}else{function _0x39c348(){var _0x48cf26=_0x5c2931;_0x41f450[_0x48cf26(0x232)]=![];}}}catch(_0x3338f8){errorlog(_0x5c2931(0x244));}setTimeout(function(){for(i in _0x51f6a2){try{delete _0x51f6a2[i];}catch(_0x131a18){}}delete _0x51f6a2;},0x4b0),hangupComplete(),log(_0x5c2931(0x2a1));},_0x51f6a2['hangupDirector']=function(){var _0x549b40=_0x46afd2;_0x51f6a2[_0x549b40(0x4df)]=!![],_0x51f6a2[_0x549b40(0x2f7)]=![],warnlog(_0x549b40(0x2bb));try{_0x51f6a2[_0x549b40(0x152)]['srcObject'][_0x549b40(0x188)]()[_0x549b40(0x335)](function(_0x1cba05){var _0x2382b8=_0x549b40;if(_0x2382b8(0x580)===_0x2382b8(0x31c)){function _0x405a25(){var _0x109b06=_0x2382b8;for(var _0x3738e8 in _0x50ccb0['directorSettings'][_0x109b06(0x4d5)]){_0x120ce2(function(_0x2a7143){_0x5f3698['directorActions'](_0x2a7143);},0x3e8,_0xed98ac[_0x109b06(0x2b8)]['scene'][_0x3738e8]);}}}else _0x1cba05[_0x2382b8(0x4e5)](),_0x51f6a2[_0x2382b8(0x152)]['srcObject'][_0x2382b8(0x50b)](_0x1cba05),log(_0x2382b8(0x23b));}),_0x51f6a2['streamSrc'][_0x549b40(0x188)]()[_0x549b40(0x335)](function(_0x31cd56){var _0x102cd2=_0x549b40;_0x31cd56['stop'](),_0x51f6a2[_0x102cd2(0x162)][_0x102cd2(0x50b)](_0x31cd56),log(_0x102cd2(0x23b));});for(UUID in _0x51f6a2[_0x549b40(0x564)]){var _0x3602e4=_0x51f6a2[_0x549b40(0x564)][UUID][_0x549b40(0x356)]();_0x3602e4[_0x549b40(0x335)](_0x516453=>{var _0x14807e=_0x549b40;_0x516453['track']&&(_0x516453[_0x14807e(0x3cb)]['enabled']=![]);});}var _0x56ce42={};_0x56ce42[_0x549b40(0x498)]=!![],_0x51f6a2['sendMessage'](_0x56ce42);}catch(_0x5575df){errorlog(_0x549b40(0x244));}log(_0x549b40(0x4b4));},_0x51f6a2[_0x46afd2(0x2ae)]=function(_0x2d119a){var _0x111e28=_0x46afd2;if('bNPaa'!==_0x111e28(0x200))try{var _0x5931ef=_0x51f6a2[_0x111e28(0x162)]['getVideoTracks']();_0x5931ef=_0x5931ef[0x0];if(_0x5931ef[_0x111e28(0x1e0)]){var _0x187be1=_0x5931ef['getCapabilities']();_0x51f6a2[_0x111e28(0x329)]==![]&&(_0x51f6a2['focusDistance']=_0x187be1[_0x111e28(0x329)]['min']);_0x51f6a2[_0x111e28(0x329)]+=_0x2d119a;if(_0x51f6a2[_0x111e28(0x329)]>_0x187be1[_0x111e28(0x329)][_0x111e28(0x167)])_0x51f6a2[_0x111e28(0x329)]=_0x187be1[_0x111e28(0x329)][_0x111e28(0x167)];else _0x51f6a2['focusDistance']<_0x187be1['focusDistance'][_0x111e28(0x236)]&&(_0x51f6a2[_0x111e28(0x329)]=_0x187be1['focusDistance'][_0x111e28(0x236)]);_0x5931ef[_0x111e28(0x2ea)]({'advanced':[{'focusMode':_0x111e28(0x366),'focusDistance':_0x51f6a2[_0x111e28(0x329)]}]});}}catch(_0xf43d8e){errorlog(_0xf43d8e);}else{function _0xa7bd54(){var _0x14f0d0=_0x111e28;_0x5b3931[_0x14f0d0(0x564)][_0x289d52][_0x14f0d0(0x4c4)]=_0x4a948a[_0x14f0d0(0x27a)];}}},_0x51f6a2[_0x46afd2(0x5a9)]=function(_0x226857){var _0x124aaf=_0x46afd2;_0x51f6a2['pcs'][_0x226857][_0x124aaf(0x5a9)]()[_0x124aaf(0x558)](_0x596046=>{var _0x1b7dda=_0x124aaf;log(_0x1b7dda(0x4a9));if(safariVersion()<=0xd&&(iOS||iPad)){}else{if(_0x51f6a2[_0x1b7dda(0x552)]==0x3||_0x51f6a2['stereo']==0x5||_0x51f6a2['stereo']==0x1)_0x596046['sdp']=CodecsHandler[_0x1b7dda(0x41e)](_0x596046[_0x1b7dda(0x48f)],{'stereo':0x1}),log(_0x1b7dda(0x2b3));else{if(iOS||iPad){}else _0x51f6a2[_0x1b7dda(0x552)]==0x4&&(_0x596046[_0x1b7dda(0x48f)]=CodecsHandler['setOpusAttributes'](_0x596046[_0x1b7dda(0x48f)],{'stereo':0x2}),log('stereo\x20enabled'));}}_0x51f6a2[_0x1b7dda(0x564)][_0x226857][_0x1b7dda(0x526)](_0x596046)[_0x1b7dda(0x558)](function(){var _0x167e36=_0x1b7dda;log(_0x167e36(0x24a)+_0x226857);var _0x316bb5={};_0x316bb5[_0x167e36(0x484)]=_0x226857,_0x316bb5[_0x167e36(0x524)]=_0x51f6a2['streamID'],_0x316bb5[_0x167e36(0x398)]=_0x51f6a2[_0x167e36(0x564)][_0x226857][_0x167e36(0x1eb)],_0x316bb5[_0x167e36(0x54c)]=_0x51f6a2[_0x167e36(0x564)][_0x226857][_0x167e36(0x54c)],_0x51f6a2['password']?_0x51f6a2[_0x167e36(0x591)](JSON[_0x167e36(0x240)](_0x316bb5[_0x167e36(0x398)]))[_0x167e36(0x558)](function(_0x1f9756){var _0x4c1d9c=_0x167e36;_0x316bb5[_0x4c1d9c(0x398)]=_0x1f9756[0x0],_0x316bb5[_0x4c1d9c(0x5a4)]=_0x1f9756[0x1],_0x51f6a2['anysend'](_0x316bb5);}):_0x51f6a2['anysend'](_0x316bb5);})['catch'](errorlog);})['catch'](errorlog);},_0x51f6a2['sendKeyFrameScenes']=function(){var _0x43769c=_0x46afd2;for(var _0x4b7103 in _0x51f6a2[_0x43769c(0x564)]){_0x51f6a2['pcs'][_0x4b7103]['scene']!==![]?(_0x51f6a2[_0x43769c(0x136)](_0x4b7103),log(_0x43769c(0x47a))):log(_0x43769c(0x3ee));}},_0x51f6a2[_0x46afd2(0x44d)]=function(_0x258640){var _0x3283d2=_0x46afd2;if(_0x258640 in _0x51f6a2[_0x3283d2(0x564)]){errorlog('PROBLEM!\x20RESENDING\x20SDP\x20OFFER\x20SHOULD\x20NOT\x20HAPPEN');try{_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x245)]();}catch(_0x23bfe3){errorlog(_0x3283d2(0x422));}_0x51f6a2[_0x3283d2(0x564)][_0x258640]=null,delete _0x51f6a2[_0x3283d2(0x564)][_0x258640],_0x51f6a2[_0x3283d2(0x592)](),applySceneState();}else log(_0x3283d2(0x134));if(_0x51f6a2['maxviewers']!==![]){if(Object[_0x3283d2(0x345)](_0x51f6a2['pcs'])['length']>_0x51f6a2[_0x3283d2(0x31e)]){delete _0x51f6a2[_0x3283d2(0x564)][_0x258640],_0x51f6a2[_0x3283d2(0x592)](),warnlog('Viewer\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit'),applySceneState();return;}}else{if(_0x51f6a2[_0x3283d2(0x36b)]!==![]){if(Object[_0x3283d2(0x345)](_0x51f6a2[_0x3283d2(0x125)])[_0x3283d2(0x39f)]+Object[_0x3283d2(0x345)](_0x51f6a2[_0x3283d2(0x564)])['length']>_0x51f6a2[_0x3283d2(0x36b)]){delete _0x51f6a2[_0x3283d2(0x564)][_0x258640],_0x51f6a2[_0x3283d2(0x592)](),warnlog('Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit'),applySceneState();return;}}}_0x51f6a2[_0x3283d2(0x564)][_0x258640]=new RTCPeerConnection(_0x51f6a2[_0x3283d2(0x3f9)]);if(_0x51f6a2[_0x3283d2(0x41a)]){if(Object[_0x3283d2(0x345)](_0x51f6a2['pcs'])[_0x3283d2(0x39f)]>0x1){delete _0x51f6a2[_0x3283d2(0x564)][_0x258640],_0x51f6a2['applySoloChat'](),applySceneState();return;}}_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x264)]=null,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x4ca)]=null,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x35c)]=null,_0x51f6a2[_0x3283d2(0x564)][_0x258640]['obsSourceActive']=null,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x211)]=null,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x42b)]=null,_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x338)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x2af)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x3fc)]=null,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x4a7)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x54c)]=_0x51f6a2['generateStreamID'](),_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x3d4)]={},_0x51f6a2['pcs'][_0x258640]['guest']=![],_0x51f6a2['pcs'][_0x258640]['limitAudio']=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x393)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640]['forceios']=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x3f3)]=!![],_0x51f6a2[_0x3283d2(0x564)][_0x258640]['allowAudio']=!![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x39c)]=!![],_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x4c4)]=![],_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x512)]=![],_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x484)]=_0x258640,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x1f4)]=![],_0x51f6a2['pcs'][_0x258640]['scaleDueToBitrate']=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x547)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x4cb)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x4bb)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x4d5)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x2f3)]=_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x15e)](_0x3283d2(0x2f3)),_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x2f3)][_0x3283d2(0x484)]=_0x258640,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x15d)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640]['keyframeTimeout']=null,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x26c)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x500)]=![],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x3bb)]=Date['now'](),_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x2f3)][_0x3283d2(0x20d)]=()=>{var _0x45959c=_0x3283d2;log('send\x20channel\x20open\x20pcs'),msg={},msg[_0x45959c(0x494)]={},msg['info'][_0x45959c(0x26c)]=_0x51f6a2[_0x45959c(0x26c)],msg[_0x45959c(0x494)][_0x45959c(0x500)]=_0x51f6a2[_0x45959c(0x500)],msg[_0x45959c(0x494)][_0x45959c(0x574)]=_0x51f6a2[_0x45959c(0x574)];_0x51f6a2[_0x45959c(0x3a9)]&&_0x51f6a2[_0x45959c(0x3a9)]!==_0x258640&&(msg[_0x45959c(0x494)][_0x45959c(0x574)]=!![]);msg[_0x45959c(0x494)][_0x45959c(0x2ec)]=_0x51f6a2[_0x45959c(0x2ec)],msg[_0x45959c(0x494)][_0x45959c(0x10f)]=_0x51f6a2[_0x45959c(0x10f)],msg[_0x45959c(0x494)][_0x45959c(0x259)]=_0x51f6a2['directorVideoMuted'],msg[_0x45959c(0x494)][_0x45959c(0x41d)]=_0x51f6a2[_0x45959c(0x498)];_0x51f6a2['director']&&(msg[_0x45959c(0x2b8)]={},msg[_0x45959c(0x2b8)][_0x45959c(0x18a)]=_0x51f6a2[_0x45959c(0x18a)]);msg[_0x45959c(0x494)]['width_url']=_0x51f6a2[_0x45959c(0x1f8)],msg[_0x45959c(0x494)][_0x45959c(0x120)]=_0x51f6a2['height'],msg[_0x45959c(0x494)][_0x45959c(0x208)]=_0x51f6a2[_0x45959c(0x203)],msg[_0x45959c(0x494)][_0x45959c(0x218)]=_0x51f6a2[_0x45959c(0x559)],msg[_0x45959c(0x494)][_0x45959c(0x252)]=_0x51f6a2['maxviewers'],msg[_0x45959c(0x494)][_0x45959c(0x48a)]=_0x51f6a2[_0x45959c(0x552)],msg[_0x45959c(0x494)][_0x45959c(0x179)]=_0x51f6a2[_0x45959c(0x1c8)],msg[_0x45959c(0x494)]['agc_url']=_0x51f6a2['autoGainControl'],msg[_0x45959c(0x494)][_0x45959c(0x4e4)]=_0x51f6a2['noiseSuppression'],msg[_0x45959c(0x494)][_0x45959c(0x291)]=_0x51f6a2[_0x45959c(0x291)],msg[_0x45959c(0x494)][_0x45959c(0x59f)]=_0x51f6a2[_0x45959c(0x369)],msg[_0x45959c(0x494)]['recording_audio_compressor_type']=_0x51f6a2[_0x45959c(0x44e)],msg[_0x45959c(0x494)][_0x45959c(0x3be)]=_0x51f6a2[_0x45959c(0x2fc)],msg[_0x45959c(0x494)][_0x45959c(0x36a)]=!_0x51f6a2[_0x45959c(0x45b)],msg['info'][_0x45959c(0x1a5)]=_0x51f6a2[_0x45959c(0x394)],msg[_0x45959c(0x494)][_0x45959c(0x1ac)]=_0x51f6a2[_0x45959c(0x584)],msg[_0x45959c(0x494)][_0x45959c(0x3c9)]=_0x51f6a2[_0x45959c(0x24d)];try{if(navigator[_0x45959c(0x299)]){var _0x2a2740,_0x7f0c16=navigator[_0x45959c(0x299)];msg['info'][_0x45959c(0x4eb)]=_0x7f0c16;}navigator[_0x45959c(0x362)]&&(msg[_0x45959c(0x494)][_0x45959c(0x362)]=navigator[_0x45959c(0x362)]);if(safariVersion())msg[_0x45959c(0x494)][_0x45959c(0x517)]=_0x45959c(0x424);else{if(getChromeVersion()>0x3c)msg['info'][_0x45959c(0x517)]='Chromium-based\x20v'+getChromeVersion();else _0x7f0c16[_0x45959c(0x124)]('Firefox')&&(msg[_0x45959c(0x494)][_0x45959c(0x517)]=_0x45959c(0x13f));}}catch(_0x209bd2){};_0x51f6a2[_0x45959c(0x4fd)](msg,_0x258640),pokeIframeAPI(_0x45959c(0x1aa),!![],_0x258640),updateUserList();},_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x2f3)]['onclose']=()=>{var _0x47f310=_0x3283d2;pokeIframeAPI(_0x47f310(0x1aa),![],_0x258640),_0x51f6a2[_0x47f310(0x270)](),warnlog(_0x47f310(0x2f1));try{_0x51f6a2[_0x47f310(0x564)][_0x258640][_0x47f310(0x245)](),_0x51f6a2[_0x47f310(0x564)][_0x258640]=null,delete _0x51f6a2[_0x47f310(0x564)][_0x258640],applySceneState();}catch(_0x11c631){}},_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x2f3)][_0x3283d2(0x4fa)]=_0x239776=>{var _0x443b10=_0x3283d2;log(_0x443b10(0x2c7));var _0x216190=JSON[_0x443b10(0x3f1)](_0x239776['data']);_0x216190[_0x443b10(0x484)]=_0x258640;if(_0x216190['description']){_0x51f6a2[_0x443b10(0x1c2)](_0x216190);return;}else{if(_0x216190[_0x443b10(0x496)]){log('GOT\x20ICE!!'),_0x51f6a2['processIce'](_0x216190);return;}else{if(_0x216190['candidates']){log(_0x443b10(0x357)),_0x51f6a2['processIceBundle'](_0x216190);return;}}}warnlog(_0x216190);if(_0x443b10(0x494)in _0x216190){_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x3d4)][_0x443b10(0x494)]=_0x216190[_0x443b10(0x494)];_0x443b10(0x26c)in _0x216190['info']&&(typeof _0x216190[_0x443b10(0x494)]['label']==_0x443b10(0x425)?_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x26c)]=sanitizeLabel(_0x216190[_0x443b10(0x494)][_0x443b10(0x26c)]):_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x26c)]=![]);if(_0x258640===_0x51f6a2[_0x443b10(0x44a)]){if(_0x443b10(0x3eb)!==_0x443b10(0x3eb)){function _0x518278(){var _0x3da339=_0x443b10;_0x3cc276[_0x3da339(0x564)][_0x5739aa['directorUUID']]['stats'][_0x3da339(0x494)]&&(_0x3fd641[_0x3da339(0x564)][_0xdee3b6[_0x3da339(0x44a)]][_0x3da339(0x3d4)][_0x3da339(0x494)][_0x3da339(0x164)]=!![]);}}else try{if(_0x443b10(0x461)===_0x443b10(0x461))_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x3d4)][_0x443b10(0x494)][_0x443b10(0x164)]=!![];else{function _0x169a31(){var _0x42c116=_0x443b10;_0x47f162['requestRateLimit'](0x0,_0x13463e),_0x2bdd8a[_0x42c116(0x125)][_0x72952]['imageElement']&&(_0x5840dc[_0x42c116(0x125)][_0x219072][_0x42c116(0x327)][_0x42c116(0x3ca)]=!![],_0x500b4c[_0x42c116(0x125)][_0x1d7c92][_0x42c116(0x327)][_0x42c116(0x118)][_0x42c116(0x349)]='hidden');}}}catch(_0x1b1bf8){}}}_0x443b10(0x338)in _0x216190&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x338)]=parseInt(_0x216190[_0x443b10(0x338)]));_0x443b10(0x241)in _0x216190&&_0x51f6a2[_0x443b10(0x45f)](_0x258640,_0x216190[_0x443b10(0x241)]);if(_0x443b10(0x2dd)in _0x216190){log(_0x216190);if(_0x51f6a2[_0x443b10(0x44a)]===_0x258640){var _0x3c0c65={};for(var _0x58efd5 in _0x51f6a2[_0x443b10(0x564)]){if(_0x58efd5===_0x258640)continue;_0x3c0c65[_0x58efd5]=_0x51f6a2[_0x443b10(0x564)][_0x58efd5][_0x443b10(0x3d4)];}var _0x2f5592={};_0x2f5592['remoteStats']=_0x3c0c65,_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x258640);}else{if(_0x443b10(0x23a)in _0x216190){if(_0x216190[_0x443b10(0x23a)]===_0x51f6a2[_0x443b10(0x23a)]&&_0x51f6a2[_0x443b10(0x23a)]){if('MjNFh'!==_0x443b10(0x562)){var _0x3c0c65={};for(var _0x58efd5 in _0x51f6a2[_0x443b10(0x564)]){if(_0x58efd5===_0x258640)continue;_0x3c0c65[_0x58efd5]=_0x51f6a2[_0x443b10(0x564)][_0x58efd5]['stats'];}var _0x2f5592={};_0x2f5592[_0x443b10(0x33c)]=_0x3c0c65,_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x258640);}else{function _0x20c7e4(){_0x35dd30(_0x155667);}}}}}}if(_0x443b10(0x2eb)in _0x216190)try{log(_0x216190),_0x51f6a2[_0x443b10(0x493)](_0x216190[_0x443b10(0x484)],_0x216190['requestResolution']['w'],_0x216190[_0x443b10(0x2eb)]['h']);}catch(_0x13602e){errorlog(_0x13602e);}_0x443b10(0x372)in _0x216190&&(_0x216190[_0x443b10(0x4d5)]?_0x51f6a2[_0x443b10(0x44a)]===_0x258640?_0x51f6a2[_0x443b10(0x469)]():errorlog(_0x443b10(0x594)):_0x51f6a2[_0x443b10(0x136)](_0x258640));if('chat'in _0x216190){var _0x4e0645=![],_0x551911=![];_0x51f6a2[_0x443b10(0x44a)]===_0x258640&&(_0x4e0645=!![],_0x443b10(0x1d5)in _0x216190&&(_0x216190[_0x443b10(0x1d5)]==!![]&&(_0x551911=!![]))),log('isDirector\x20'+_0x4e0645),getChatMessage(_0x216190['chat'],_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x26c)],_0x4e0645,_0x551911);}if(_0x443b10(0x500)in _0x216190){if(_0x443b10(0x2a8)!==_0x443b10(0x2a8)){function _0x9ee5f5(){var _0x1e2a40=_0x443b10;this[_0x1e2a40(0x162)][_0x1e2a40(0x188)]()[_0x1e2a40(0x335)](function(_0x218821){var _0x2b9186=_0x1e2a40;_0x218821['stop'](),_0x5878cb(_0x2b9186(0x420));});}}else{_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x500)]=parseInt(_0x216190[_0x443b10(0x500)])||0x0;_0x258640 in _0x51f6a2[_0x443b10(0x125)]&&(_0x51f6a2[_0x443b10(0x125)][_0x258640][_0x443b10(0x500)]=_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x500)]);if(_0x51f6a2[_0x443b10(0x164)]){var _0x885c21=document[_0x443b10(0x433)](_0x443b10(0x499)+_0x258640+'\x22]');log(_0x885c21),_0x885c21[0x0]&&(_0x885c21[0x0]['innerText']=parseInt(_0x216190[_0x443b10(0x500)])||0x0);}updateMixer();}}_0x443b10(0x1f4)in _0x216190&&_0x51f6a2['setScale'](_0x258640,_0x216190[_0x443b10(0x1f4)]);'rejected'in _0x216190&&(_0x51f6a2[_0x443b10(0x164)]&&(!(_0x51f6a2[_0x443b10(0x368)]||_0x51f6a2['cleanDirector'])&&warnUser('The\x20request\x20failed;\x20the\x20remote\x20user\x20did\x20not\x20recognize\x20you\x20as\x20the\x20director',0x1388)),errorlog(_0x443b10(0x4bc)+_0x216190[_0x443b10(0x376)]+',\x20isDirector:\x20'+_0x51f6a2[_0x443b10(0x164)]));if(_0x258640!==_0x51f6a2['directorUUID']){if(_0x443b10(0x170)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x170),_0x51f6a2['sendMessage'](_0x2f5592,_0x258640);}else{if('requestVideoRecord'in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x358),_0x51f6a2['sendMessage'](_0x2f5592,_0x258640);}else{if(_0x443b10(0x3d0)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x3d0),_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x258640);}else{if('changeURL'in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x49f),_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x258640);}else{if(_0x443b10(0x217)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x217),_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x258640);}else{if(_0x443b10(0x192)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x192),_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x258640);}else{if('lowerhand'in _0x216190){if(_0x443b10(0x34b)===_0x443b10(0x16d)){function _0x4789ff(){return;}}else{var _0x2f5592={};_0x2f5592['rejected']=_0x443b10(0x199),_0x51f6a2['sendMessage'](_0x2f5592,_0x258640);}}else{if(_0x443b10(0x483)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x483),_0x51f6a2['sendMessage'](_0x2f5592,_0x258640);}else{if(_0x443b10(0x38c)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x38c),_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x258640);}else{if(_0x443b10(0x18d)in _0x216190){var _0x2f5592={};_0x2f5592['rejected']=_0x443b10(0x18d),_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x258640);}else{if(_0x443b10(0x58f)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x376)]=_0x443b10(0x58f),_0x51f6a2['sendMessage'](_0x2f5592,_0x258640);}}}}}}}}}}}}else{if(_0x258640===_0x51f6a2['directorUUID']){if('requestAudioHack'in _0x216190){var _0x367cec=_0x51f6a2[_0x443b10(0x162)][_0x443b10(0x352)]();if(_0x367cec['length']){if(_0x443b10(0x3cb)in _0x216190){var _0x312c96=parseInt(_0x216190[_0x443b10(0x3cb)]);_0x312c96<_0x367cec[_0x443b10(0x39f)]&&(_0x367cec=_0x367cec[_0x312c96],applyAudioHack(_0x216190[_0x443b10(0x2bc)],_0x216190[_0x443b10(0x22f)]));}else{if(_0x443b10(0x2ed)===_0x443b10(0x3c2)){function _0x55a1f5(){_0x16c4b0(_0x5997f1['streamID']);}}else _0x367cec=_0x367cec[0x0],applyAudioHack(_0x216190[_0x443b10(0x2bc)],_0x216190['value']);}}}if('requestVideoRecord'in _0x216190){if(_0x443b10(0x2a5)!==_0x443b10(0x2a5)){function _0x5e10e6(){var _0x2a470f=_0x7ac2c?function(){var _0x4af7aa=_0x45a6;if(_0x57f8d1){var _0x504c95=_0x210f9c[_0x4af7aa(0x4ef)](_0x4ea804,arguments);return _0x5a1e34=null,_0x504c95;}}:function(){};return _0x3a08e6=![],_0x2a470f;}}else{if(_0x216190[_0x443b10(0x358)]){if(_0x51f6a2[_0x443b10(0x152)]){var _0x2bc76c=0x1770;_0x216190[_0x443b10(0x22f)]&&(_0x2bc76c=parseInt(_0x216190[_0x443b10(0x22f)])),recordLocalVideo(_0x443b10(0x480),_0x2bc76c);}}else _0x51f6a2[_0x443b10(0x152)]&&recordLocalVideo(_0x443b10(0x4e5));}}if(_0x443b10(0x3d0)in _0x216190){_0x51f6a2[_0x443b10(0x500)]==![]&&(_0x51f6a2[_0x443b10(0x500)]=0x0);_0x51f6a2[_0x443b10(0x500)]+=parseInt(_0x216190[_0x443b10(0x3d0)])||0x0;var _0x2f5592={};_0x2f5592={},_0x2f5592[_0x443b10(0x500)]=_0x51f6a2[_0x443b10(0x500)],_0x51f6a2[_0x443b10(0x16c)](_0x2f5592),updateMixer();}if(_0x443b10(0x49f)in _0x216190){window[_0x443b10(0x157)]();var _0x5cba69=confirm('The\x20director\x20wishes\x20to\x20redirect\x20you\x20to\x20the\x20URL:\x20'+_0x216190['changeURL']+_0x443b10(0x2f2));_0x5cba69&&(window[_0x443b10(0x173)][_0x443b10(0x41c)]=_0x216190['changeURL']);;}if(_0x443b10(0x217)in _0x216190){if(_0x443b10(0x22f)in _0x216190){if(typeof _0x216190['value']=='string'){_0x51f6a2['label']=sanitizeLabel(_0x216190[_0x443b10(0x22f)]),log(_0x443b10(0x3da)+_0x51f6a2[_0x443b10(0x26c)]);if(_0x51f6a2[_0x443b10(0x164)]){var _0x885c21=getById(_0x443b10(0x344)+_0x258640);_0x51f6a2[_0x443b10(0x26c)]?_0x885c21[_0x443b10(0x226)]=_0x51f6a2[_0x443b10(0x26c)]:_0x885c21[_0x443b10(0x226)]=_0x443b10(0x2c6);}else _0x51f6a2[_0x443b10(0x12c)]&&updateMixer();!_0x51f6a2[_0x443b10(0x164)]&&(_0x51f6a2[_0x443b10(0x26c)]?document['title']=_0x51f6a2[_0x443b10(0x26c)]:document[_0x443b10(0x464)]=location[_0x443b10(0x2e5)]);var _0x52d965=encodeURIComponent(_0x51f6a2[_0x443b10(0x26c)]);urlParams[_0x443b10(0x31d)]('l')?updateURL('l='+_0x52d965,!![],![]):updateURL('label='+_0x52d965,!![],![]);var _0x2f5592={};_0x2f5592[_0x443b10(0x217)]=!![],_0x2f5592[_0x443b10(0x22f)]=_0x51f6a2[_0x443b10(0x26c)],_0x51f6a2['sendMessage'](_0x2f5592);}else{_0x51f6a2[_0x443b10(0x26c)]=![];var _0x2f5592={};_0x2f5592['changeLabel']=!![],_0x2f5592[_0x443b10(0x22f)]=_0x51f6a2[_0x443b10(0x26c)],_0x51f6a2['sendMessage'](_0x2f5592);if(_0x51f6a2[_0x443b10(0x164)]){var _0x885c21=getById('label_'+_0x258640);_0x885c21['innerText']=_0x443b10(0x2c6);}else _0x51f6a2['showlabels']?(document[_0x443b10(0x464)]=location['hostname'],updateMixer()):document[_0x443b10(0x464)]=location[_0x443b10(0x2e5)];}}}if(_0x443b10(0x192)in _0x216190){if(_0x216190[_0x443b10(0x2bc)]==_0x443b10(0x57f))changeLowEQ(parseFloat(_0x216190[_0x443b10(0x22f)]),_0x216190['track']);else{if(_0x216190['keyname']=='mid')changeMidEQ(parseFloat(_0x216190['value']),_0x216190[_0x443b10(0x3cb)]);else{if(_0x216190[_0x443b10(0x2bc)]==_0x443b10(0x1a8)){if(_0x443b10(0x44c)!=='VURbz')changeHighEQ(parseFloat(_0x216190['value']),_0x216190[_0x443b10(0x3cb)]);else{function _0x60a244(){try{delete _0x23c3cf[_0x1c606a];}catch(_0xbfefe8){}}}}}}}_0x443b10(0x199)in _0x216190&&(_0x51f6a2[_0x443b10(0x14a)]&&lowerhand());if(_0x443b10(0x234)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x484)]=_0x258640,_0x2f5592[_0x443b10(0x324)]=listAudioSettingsPrep(),sendMediaDevices(_0x2f5592['UUID']),_0x51f6a2['sendMessage'](_0x2f5592,_0x2f5592[_0x443b10(0x484)]);}if(_0x443b10(0x1b6)in _0x216190){var _0x2f5592={};_0x2f5592[_0x443b10(0x484)]=_0x258640,_0x2f5592[_0x443b10(0x401)]=listVideoSettingsPrep(),sendMediaDevices(_0x2f5592['UUID']),_0x51f6a2[_0x443b10(0x4fd)](_0x2f5592,_0x2f5592[_0x443b10(0x484)]);}_0x443b10(0x2db)in _0x216190&&changeAudioOutputDeviceById(_0x216190['changeSpeaker'],_0x258640);if(_0x443b10(0x285)in _0x216190){if(_0x443b10(0x3a3)===_0x443b10(0x3a6)){function _0x372a50(){var _0x3de32e=_0x443b10;_0x12a8ee[_0x3de32e(0x232)]=![];}}else changeAudioDeviceById(_0x216190[_0x443b10(0x285)],_0x258640);}_0x443b10(0x3a7)in _0x216190&&changeVideoDeviceById(_0x216190['changeCamera'],_0x258640);_0x443b10(0x151)in _0x216190&&updateCameraConstraints(_0x216190[_0x443b10(0x2bc)],_0x216190[_0x443b10(0x22f)]);_0x443b10(0x541)in _0x216190&&changeLowCut(parseFloat(_0x216190['value']),_0x216190[_0x443b10(0x3cb)]);'requestChangeLowcut'in _0x216190&&changeLowCut(parseFloat(_0x216190[_0x443b10(0x22f)]),_0x216190[_0x443b10(0x3cb)]);_0x443b10(0x483)in _0x216190&&_0x51f6a2[_0x443b10(0x483)]();if(_0x443b10(0x4cd)in _0x216190){}if('volume'in _0x216190){var _0x424848=parseInt(_0x216190[_0x443b10(0x58f)])/0x64||0x0;_0x51f6a2[_0x443b10(0x369)]=parseInt(_0x216190['volume'])||0x0;for(var _0x101ac6 in _0x51f6a2['webAudios']){log('Adjusting\x20Gain;\x20only\x20track\x200\x20in\x20all\x20likely\x20hood,\x20unless\x20more\x20than\x20track\x200\x20support\x20is\x20added.'),_0x51f6a2[_0x443b10(0x4c5)][_0x101ac6]['gainNode'][_0x443b10(0x59e)]['setValueAtTime'](_0x424848,_0x51f6a2[_0x443b10(0x4c5)][_0x101ac6][_0x443b10(0x160)][_0x443b10(0x55d)]);}}if(_0x443b10(0x428)in _0x216190){var _0x31c133=parseFloat(_0x216190[_0x443b10(0x428)]/0x3e8)||0x0;_0x51f6a2[_0x443b10(0x50c)]=parseInt(_0x216190[_0x443b10(0x428)])||0x0;for(var _0x101ac6 in _0x51f6a2[_0x443b10(0x4c5)]){_0x51f6a2[_0x443b10(0x4c5)][_0x101ac6]['micDelay'][_0x443b10(0x578)][_0x443b10(0x486)](_0x31c133,_0x51f6a2[_0x443b10(0x4c5)][_0x101ac6][_0x443b10(0x160)][_0x443b10(0x55d)]);}}_0x443b10(0x18d)in _0x216190&&(_0x216190[_0x443b10(0x18d)]?(_0x51f6a2['directorSpeakerMuted']=!![],_0x51f6a2[_0x443b10(0x4f6)]()):(_0x51f6a2['directorSpeakerMuted']=![],_0x51f6a2['directorSpeakerMute']())),_0x443b10(0x38c)in _0x216190&&(_0x216190[_0x443b10(0x38c)]?(_0x51f6a2[_0x443b10(0x10f)]=!![],_0x51f6a2[_0x443b10(0x18e)]()):(_0x51f6a2['directorDisplayMuted']=![],_0x51f6a2[_0x443b10(0x18e)]())),_0x443b10(0x321)in _0x216190&&applyNewParams(_0x216190[_0x443b10(0x321)]);}}if('zoom'in _0x216190){if(_0x443b10(0x14c)!==_0x443b10(0x14c)){function _0x1b99f2(){var _0x41e1b4=_0x443b10;_0x188291[_0x41e1b4(0x125)][_0x14a5c6][_0x41e1b4(0x152)]['muted']=!![],_0x5b58ce[_0x41e1b4(0x125)][_0x4a1316][_0x41e1b4(0x32b)]=!![];}}else{if(_0x51f6a2[_0x443b10(0x23a)]){if(_0x443b10(0x23a)in _0x216190)_0x216190[_0x443b10(0x23a)]===_0x51f6a2['remote']&&_0x51f6a2[_0x443b10(0x23a)]&&_0x51f6a2[_0x443b10(0x551)](parseFloat(_0x216190[_0x443b10(0x2d8)]));else{if(_0x258640===_0x51f6a2['directorUUID'])_0x51f6a2[_0x443b10(0x551)](parseFloat(_0x216190[_0x443b10(0x2d8)]));else return;}}}}if('focus'in _0x216190){if(_0x51f6a2[_0x443b10(0x23a)]){if(_0x443b10(0x23a)in _0x216190){if(_0x443b10(0x1af)===_0x443b10(0x3ea)){function _0xaa7293(){var _0x134ab7=_0x443b10;_0x559f28[_0x134ab7(0x125)][_0xc74320]['stats'][_0x134ab7(0x3c0)][_0x134ab7(0x2fd)]=_0x2072fc[_0x134ab7(0x2fd)];}}else{if(_0x216190['remote']===_0x51f6a2[_0x443b10(0x23a)]&&_0x51f6a2['remote']){if(_0x443b10(0x216)===_0x443b10(0x216))_0x51f6a2[_0x443b10(0x2ae)](parseFloat(_0x216190[_0x443b10(0x157)]));else{function _0x566ac3(){return;}}}}}else{if(_0x258640===_0x51f6a2[_0x443b10(0x44a)])_0x51f6a2[_0x443b10(0x2ae)](parseFloat(_0x216190[_0x443b10(0x157)]));else return;}}}manageSceneState(_0x216190,_0x258640);_0x443b10(0x3b7)in _0x216190&&_0x51f6a2['limitBitrate'](_0x258640,_0x216190['bitrate']);if(_0x443b10(0x434)in _0x216190&&_0x443b10(0x232)in _0x216190){log(_0x443b10(0x415));_0x216190['audio']==![]&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x597)]=![]);_0x216190[_0x443b10(0x232)]==![]&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x3f3)]=![]);_0x443b10(0x4d8)in _0x216190&&_0x216190[_0x443b10(0x4d8)]==!![]&&(_0x51f6a2['pcs'][_0x258640][_0x443b10(0x512)]=!![],setTimeout(function(){makeImages();},0x3e8));_0x443b10(0x1c4)in _0x216190&&_0x216190[_0x443b10(0x1c4)]==![]&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x39c)]=![]);_0x443b10(0x27a)in _0x216190&&_0x216190[_0x443b10(0x4d2)]!==![]&&(_0x51f6a2['pcs'][_0x258640][_0x443b10(0x4c4)]=_0x216190[_0x443b10(0x27a)]);if(_0x443b10(0x391)in _0x216190){if('ejUjs'===_0x443b10(0x452))_0x216190[_0x443b10(0x391)]==!![]&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x391)]=!![]);else{function _0x44645b(){var _0x53abec=_0x443b10;_0x505876['rpcs'][_0x383e3a][_0x53abec(0x152)][_0x53abec(0x118)]['display']=_0x53abec(0x446),_0x2d2afc=!![];}}}_0x443b10(0x531)in _0x216190&&(_0x216190[_0x443b10(0x531)]===!![]&&(_0x51f6a2[_0x443b10(0x564)][_0x258640]['forceios']=!![]));_0x443b10(0x164)in _0x216190&&(_0x216190['director']==!![]&&((iOS||iPad)&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x531)]==!![]&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x391)]=!![]))));if(_0x443b10(0x1d3)in _0x216190){if(_0x216190[_0x443b10(0x1d3)]==!![]){if(_0x443b10(0x403)===_0x443b10(0x403))_0x51f6a2['pcs'][_0x258640][_0x443b10(0x556)]=!![];else{function _0x5de125(){var _0x4f42ed=_0x443b10;_0x4abe7e[_0x4f42ed(0x34f)]=[{}];}}}}_0x443b10(0x2fa)in _0x216190&&(_0x216190[_0x443b10(0x2fa)]==!![]&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x393)]=!![]));_0x443b10(0x15d)in _0x216190&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x15d)]=_0x216190[_0x443b10(0x15d)],_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x15d)]&&setTimeout(function(){var _0x19ba4d=_0x443b10;_0x51f6a2[_0x19ba4d(0x136)](_0x258640);},0x1388));if(_0x443b10(0x4d5)in _0x216190){if(_0x216190[_0x443b10(0x4d5)]!==![]){if(_0x443b10(0x35d)!==_0x443b10(0x35d)){function _0x21975f(){var _0x30e310=_0x443b10;_0x50a674[_0x30e310(0x1c4)]=!![];}}else{try{typeof _0x216190[_0x443b10(0x4d5)]==='string'?_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x4d5)]=_0x216190[_0x443b10(0x4d5)][_0x443b10(0x38e)](/[\W]+/g,'_'):_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x4d5)]=(parseInt(_0x216190[_0x443b10(0x4d5)])||0x0)+'',_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x3d4)][_0x443b10(0x4d5)]=_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x4d5)],updateSceneList(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x4d5)]);}catch(_0x5eb92a){errorlog(_0x5eb92a);}_0x51f6a2['director']==!![]&&_0x51f6a2[_0x443b10(0x13b)]==![]&&(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x597)]=![],_0x51f6a2['pcs'][_0x258640]['allowVideo']=![],_0x51f6a2['pcs'][_0x258640][_0x443b10(0x39c)]=![]);}}}if(_0x51f6a2['director']==!![]){if('wqPuC'!==_0x443b10(0x2e1)){if(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x4d5)])var _0x5d2e72=getDirectorSettings(_0x51f6a2[_0x443b10(0x564)][_0x258640][_0x443b10(0x4d5)]);else var _0x5d2e72=getDirectorSettings(![]);var _0x2f5592={};_0x2f5592[_0x443b10(0x2b8)]=_0x5d2e72,_0x51f6a2['sendMessage'](_0x2f5592,_0x258640);}else{function _0x28c3db(){var _0x580ef2=_0x443b10;return _0x3ebdb0[_0x580ef2(0x3e3)](_0x47a556+_0x484c93[_0x580ef2(0x292)]+_0x3f769b[_0x580ef2(0x548)],0x10)[_0x580ef2(0x558)](function(_0x159778){var _0x20e89e=_0x580ef2;return _0x2c9a1b[_0x20e89e(0x33b)]&&(_0x2a44f0[_0x20e89e(0x3e6)]=_0x159778),_0x182181[_0x20e89e(0x3f8)]=_0x159778,_0x343b57[_0x20e89e(0x24e)](_0x37906e),_0x1a212f[_0x20e89e(0x280)]=_0x27760e(),_0x2d5838('deferring\x20with\x20a\x20promise;\x20hashed\x20room'),_0x2c1c3c[_0x20e89e(0x280)];});}}}_0x51f6a2[_0x443b10(0x4a5)](_0x258640);}},_0x51f6a2['initialPublish']=function(_0x468b69){var _0x49f768=_0x3283d2;if(_0x468b69 in _0x51f6a2['pcs']){}else{errorlog('UUID\x20not\x20found\x20in\x20pcs');return;}if(_0x51f6a2[_0x49f768(0x564)][_0x468b69][_0x49f768(0x39c)]===!![]){if(_0x51f6a2[_0x49f768(0x29b)]){var _0x5869f9={};_0x5869f9[_0x49f768(0x29b)]=_0x51f6a2[_0x49f768(0x29b)],_0x51f6a2['sendMessage'](_0x5869f9,_0x468b69);}}log(_0x49f768(0x589)),log(_0x51f6a2[_0x49f768(0x162)]);var _0x3b0719=null;if(_0x51f6a2[_0x49f768(0x152)][_0x49f768(0x2e4)])_0x3b0719=_0x51f6a2[_0x49f768(0x152)][_0x49f768(0x2e4)];else{if(_0x51f6a2[_0x49f768(0x162)]&&_0x51f6a2[_0x49f768(0x162)][_0x49f768(0x188)]())errorlog(_0x49f768(0x129)),log(_0x51f6a2[_0x49f768(0x162)][_0x49f768(0x188)]()),_0x3b0719=_0x51f6a2[_0x49f768(0x162)];else{warnlog(_0x49f768(0x260));return;}}_0x3b0719[_0x49f768(0x188)]()[_0x49f768(0x335)](_0x346b18=>{var _0x8130cb=_0x49f768;if(_0x8130cb(0x2c3)===_0x8130cb(0x48c)){function _0x51d599(){var _0x551799=_0x8130cb;_0x2ef133[_0x551799(0x125)][_0x5b9bf4]['bandwidth']=_0x15b91e[_0x551799(0x338)];}}else _0x51f6a2['pcs'][_0x468b69][_0x8130cb(0x597)]==!![]&&(_0x346b18[_0x8130cb(0x4e8)]==_0x8130cb(0x434)&&_0x51f6a2['pcs'][_0x468b69][_0x8130cb(0x47d)](_0x346b18,_0x3b0719)),_0x51f6a2[_0x8130cb(0x564)][_0x468b69][_0x8130cb(0x3f3)]==!![]&&(_0x346b18[_0x8130cb(0x4e8)]==_0x8130cb(0x232)&&(_0x51f6a2[_0x8130cb(0x564)][_0x468b69]['guest']==!![]&&_0x51f6a2[_0x8130cb(0x2b7)]===0x0?log(_0x8130cb(0x364)):(_0x51f6a2[_0x8130cb(0x564)][_0x468b69][_0x8130cb(0x47d)](_0x346b18,_0x3b0719),setTimeout(function(_0x426cab){var _0x463ec6=_0x8130cb;_0x51f6a2[_0x463ec6(0x387)](_0x426cab);},_0x51f6a2['rampUpTime'],_0x468b69))));}),log(_0x49f768(0x463)),_0x3b0719['getAudioTracks']()[_0x49f768(0x39f)]&&(_0x51f6a2[_0x49f768(0x592)](),log(_0x49f768(0x1a4)),_0x51f6a2[_0x49f768(0x564)][_0x468b69][_0x49f768(0x556)]===!![]&&setTimeout(_0x51f6a2['limitAudioEncoder'],0x3e8,_0x468b69,0x7d00,0x0),_0x51f6a2[_0x49f768(0x564)][_0x468b69][_0x49f768(0x393)]===!![]&&setTimeout(_0x51f6a2['enhanceAudioEncoder'],0x3e8,_0x468b69));},_0x51f6a2[_0x3283d2(0x564)][_0x258640]['onnegotiationneeded']=function(_0x5dc853){var _0x3525b3=_0x3283d2;_0x51f6a2[_0x3525b3(0x5a9)](_0x258640);},_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x209)]=_0x164a6a=>{var _0x3ee527=_0x3283d2;errorlog(_0x3ee527(0x26a));},_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x1c3)]=null,_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x206)]=[],_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x430)]=function(_0x5e47ad){var _0x4f766d=_0x3283d2;if(_0x5e47ad[_0x4f766d(0x496)]==null){log(_0x4f766d(0x1dd));return;}try{if(_0x51f6a2['icefilter']){if(_0x5e47ad['candidate'][_0x4f766d(0x496)][_0x4f766d(0x124)](_0x51f6a2['icefilter'])===-0x1){log(_0x4f766d(0x42f));return;}else log(_0x5e47ad[_0x4f766d(0x496)]);}}catch(_0x33bf10){errorlog(_0x33bf10);}if(_0x51f6a2[_0x4f766d(0x564)][_0x258640][_0x4f766d(0x1c3)]!==null){if('NISxg'===_0x4f766d(0x2c0)){_0x51f6a2['pcs'][_0x258640][_0x4f766d(0x206)][_0x4f766d(0x438)](_0x5e47ad['candidate']);return;}else{function _0x330988(){var _0x1fbab0=_0x4f766d;if(_0x4a8b9c['keys'](_0x25c486[_0x1fbab0(0x125)])['length']>=_0x4a144d[_0x1fbab0(0x326)]){delete _0x4a203a[_0x1fbab0(0x125)][_0x3bb384],_0x3318ad(),_0x505355('Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit');return;}}}}_0x51f6a2[_0x4f766d(0x564)][_0x258640][_0x4f766d(0x206)][_0x4f766d(0x438)](_0x5e47ad[_0x4f766d(0x496)]),_0x51f6a2['pcs'][_0x258640][_0x4f766d(0x1c3)]=setTimeout(function(_0x1168f8){var _0x1f24fb=_0x4f766d;_0x51f6a2[_0x1f24fb(0x564)][_0x1168f8][_0x1f24fb(0x1c3)]=null;var _0x8dc7c9={};_0x8dc7c9['UUID']=_0x1168f8,_0x8dc7c9[_0x1f24fb(0x436)]=_0x1f24fb(0x265),_0x8dc7c9[_0x1f24fb(0x253)]=_0x51f6a2['pcs'][_0x1168f8][_0x1f24fb(0x206)],_0x8dc7c9[_0x1f24fb(0x54c)]=_0x51f6a2[_0x1f24fb(0x564)][_0x1168f8]['session'],_0x51f6a2[_0x1f24fb(0x564)][_0x1168f8][_0x1f24fb(0x206)]=[],_0x51f6a2[_0x1f24fb(0x292)]?_0x51f6a2[_0x1f24fb(0x591)](JSON[_0x1f24fb(0x240)](_0x8dc7c9[_0x1f24fb(0x253)]))[_0x1f24fb(0x558)](function(_0x24754e){var _0x6491db=_0x1f24fb;_0x8dc7c9[_0x6491db(0x253)]=_0x24754e[0x0],_0x8dc7c9[_0x6491db(0x5a4)]=_0x24754e[0x1],_0x51f6a2[_0x6491db(0x34d)](_0x8dc7c9);}):_0x51f6a2['anysend'](_0x8dc7c9);},0xc8,_0x258640);},_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x40c)]=function(_0x344c04){var _0x561878=_0x3283d2;try{if(this[_0x561878(0x530)]==_0x561878(0x276))log('ICE\x20closed?');else{if(this[_0x561878(0x530)]==_0x561878(0x37e))log(_0x561878(0x396));else{if(this[_0x561878(0x530)]==_0x561878(0x147))log(_0x561878(0x412));else{if(this[_0x561878(0x530)]==_0x561878(0x172)){if(_0x561878(0x207)===_0x561878(0x207))log('iceConnectionState\x20==\x20connected'),_0x51f6a2['pcs'][_0x258640][_0x561878(0x356)]()[_0x561878(0x335)](_0x36cf9c=>{var _0x3cfd66=_0x561878;if(!_0x36cf9c[_0x3cfd66(0x3cb)])return;if(_0x36cf9c[_0x3cfd66(0x3cb)][_0x3cfd66(0x4e8)]==='video'){_0x51f6a2[_0x3cfd66(0x564)][_0x258640][_0x3cfd66(0x302)]=_0x36cf9c[_0x3cfd66(0x47e)]()['codecs'],log(_0x51f6a2[_0x3cfd66(0x564)][_0x258640][_0x3cfd66(0x302)]);return;}else{if(_0x36cf9c[_0x3cfd66(0x3cb)][_0x3cfd66(0x4e8)]===_0x3cfd66(0x434)){_0x51f6a2[_0x3cfd66(0x564)][_0x258640][_0x3cfd66(0x4de)]=_0x36cf9c[_0x3cfd66(0x47e)]()['codecs'],log(_0x51f6a2[_0x3cfd66(0x564)][_0x258640]['audioCodecs']);return;}}});else{function _0xfea69a(){var _0x253751=_0x561878;_0x35e816[_0x253751(0x438)](_0x162b73(_0x4e964a[_0x253751(0x198)](_0xd3112c,0x2),0x10));}}}else log(this[_0x561878(0x530)]);}}}}catch(_0x298b9c){errorlog(_0x298b9c);}},_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x1ea)]=function(_0x3192c7){var _0x116ef1=_0x3283d2;switch(_0x51f6a2[_0x116ef1(0x564)][_0x258640][_0x116ef1(0x11d)]){case'connected':log(_0x116ef1(0x439));if(_0x51f6a2['security']){if(_0x51f6a2['ws']['readyState']!==0x1){_0x51f6a2['ws']['close']();break;}_0x51f6a2['ws']['close'](),setTimeout(function(){var _0x174ce7=_0x116ef1;_0x51f6a2['cleanOutput']!=!![]&&warnUser(_0x174ce7(0x492));},0x1);}break;case _0x116ef1(0x37e):log(_0x116ef1(0x2aa));break;case _0x116ef1(0x147):warnlog(_0x116ef1(0x1ff)),_0x51f6a2[_0x116ef1(0x564)][_0x258640]['close'](),_0x51f6a2[_0x116ef1(0x564)][_0x258640]=null;_0x51f6a2['security']&&(!_0x51f6a2['cleanOutput']&&setTimeout(function(){var _0x3affc4=_0x116ef1;warnUser(_0x3affc4(0x141));},0x1));delete _0x51f6a2[_0x116ef1(0x564)][_0x258640],_0x51f6a2[_0x116ef1(0x592)](),applySceneState();break;case _0x116ef1(0x276):warnlog(_0x116ef1(0x1e6)),_0x51f6a2[_0x116ef1(0x564)][_0x258640]=null;_0x51f6a2[_0x116ef1(0x41a)]&&(!_0x51f6a2[_0x116ef1(0x368)]&&setTimeout(function _0x4de03e(){var _0x47b43a=_0x116ef1;warnUser(_0x47b43a(0x141));},0x1));delete _0x51f6a2[_0x116ef1(0x564)][_0x258640],_0x51f6a2['applySoloChat'](),applySceneState();break;}},_0x51f6a2[_0x3283d2(0x564)][_0x258640][_0x3283d2(0x58b)]=function(_0x2dff15){var _0x468fa9=_0x3283d2;warnlog(_0x468fa9(0x3e8)),_0x51f6a2[_0x468fa9(0x564)][_0x258640]=null,delete _0x51f6a2['pcs'][_0x258640],_0x51f6a2['applySoloChat'](),applySceneState();},_0x51f6a2['pcs'][_0x258640][_0x3283d2(0x20d)]=function _0x4a7f57(){var _0x10a6dc=_0x3283d2;log(_0x10a6dc(0x165));};},_0x51f6a2[_0x46afd2(0x1c2)]=function(_0x149252){var _0x238db5=_0x46afd2;if(_0x51f6a2[_0x238db5(0x292)])_0x238db5(0x5a4)in _0x149252&&_0x51f6a2[_0x238db5(0x59d)](_0x149252['description'],_0x149252[_0x238db5(0x5a4)])[_0x238db5(0x558)](function(_0x52e62e){var _0x510043=_0x238db5;_0x149252[_0x510043(0x398)]=JSON[_0x510043(0x3f1)](_0x52e62e);if(_0x149252[_0x510043(0x398)][_0x510043(0x436)]==_0x510043(0x4a1))_0x51f6a2[_0x510043(0x4af)](_0x149252),_0x51f6a2[_0x510043(0x543)](_0x149252);else try{var _0x2cd6cd=_0x51f6a2[_0x510043(0x559)];if((iOS||iPad)&&_0x51f6a2[_0x510043(0x564)][_0x149252[_0x510043(0x484)]][_0x510043(0x391)]==!![]&&_0x51f6a2['pcs'][_0x149252['UUID']][_0x510043(0x531)]==![]){if(_0x510043(0x495)!==_0x510043(0x495)){function _0x33930f(){var _0x5d24a1=_0x510043;_0x2b9eb2['offerSDP'](_0x1bfde0[_0x5d24a1(0x484)]);}}else{if(_0x2cd6cd===![]||_0x2cd6cd>_0x51f6a2[_0x510043(0x158)]){var _0x1fe771=Object[_0x510043(0x345)](_0x51f6a2[_0x510043(0x564)])[_0x510043(0x39f)];_0x1fe771>0x3?_0x2cd6cd=_0x51f6a2['lowiosviewers']:_0x2cd6cd=_0x51f6a2[_0x510043(0x158)];}_0x149252[_0x510043(0x398)][_0x510043(0x48f)]=CodecsHandler[_0x510043(0x35f)](_0x149252[_0x510043(0x398)][_0x510043(0x48f)],_0x510043(0x3ba)),_0x149252[_0x510043(0x398)][_0x510043(0x48f)]=CodecsHandler[_0x510043(0x535)](_0x149252[_0x510043(0x398)][_0x510043(0x48f)],{'min':parseInt(_0x2cd6cd/0x2)||0x1,'max':_0x2cd6cd}),_0x2cd6cd=![];}}else _0x51f6a2[_0x510043(0x564)][_0x149252[_0x510043(0x484)]][_0x510043(0x391)]==!![]&&(_0x2cd6cd!==![]?_0x51f6a2['roombitrate']!==![]&&(_0x51f6a2[_0x510043(0x2b7)]<_0x2cd6cd&&(_0x2cd6cd=_0x51f6a2[_0x510043(0x2b7)])):_0x2cd6cd=_0x51f6a2[_0x510043(0x2b7)]);if(_0x2cd6cd){var _0x442e38=CodecsHandler[_0x510043(0x1e8)](_0x149252[_0x510043(0x398)]['sdp'])||0x9c4;log('BITRATE:\x20'+_0x442e38);if(_0x442e38>_0x2cd6cd){var _0x49f493=CodecsHandler[_0x510043(0x4e1)](_0x149252['description'][_0x510043(0x48f)])||0x0;_0x149252[_0x510043(0x398)][_0x510043(0x48f)]=CodecsHandler[_0x510043(0x535)](_0x149252[_0x510043(0x398)][_0x510043(0x48f)],{'min':parseInt(_0x2cd6cd/0xa)||0x1,'max':parseInt(_0x2cd6cd+_0x49f493/0x400)}),_0x51f6a2[_0x510043(0x564)][_0x149252['UUID']][_0x510043(0x4a7)]=_0x2cd6cd;}else _0x51f6a2[_0x510043(0x564)][_0x149252[_0x510043(0x484)]][_0x510043(0x4a7)]=_0x442e38;}else{if(_0x51f6a2['outboundVideoBitrate']!==![]){var _0x442e38=CodecsHandler['getVideoBitrates'](_0x149252[_0x510043(0x398)][_0x510043(0x48f)]);if(_0x442e38===![]){var _0x49f493=CodecsHandler[_0x510043(0x4e1)](_0x149252['description'][_0x510043(0x48f)])||0x0;_0x149252[_0x510043(0x398)][_0x510043(0x48f)]=CodecsHandler[_0x510043(0x535)](_0x149252[_0x510043(0x398)][_0x510043(0x48f)],{'min':parseInt(_0x51f6a2[_0x510043(0x48b)]/0xa)||0x1,'max':parseInt(_0x51f6a2[_0x510043(0x48b)]+_0x49f493/0x400)});}else _0x51f6a2[_0x510043(0x564)][_0x149252[_0x510043(0x484)]]['setBitrate']=_0x442e38;}else _0x51f6a2[_0x510043(0x564)][_0x149252[_0x510043(0x484)]]['setBitrate']=CodecsHandler[_0x510043(0x1e8)](_0x149252[_0x510043(0x398)][_0x510043(0x48f)]);}_0x51f6a2['outboundAudioBitrate']&&(_0x149252[_0x510043(0x398)]['sdp']=CodecsHandler[_0x510043(0x41e)](_0x149252[_0x510043(0x398)][_0x510043(0x48f)],{'maxaveragebitrate':_0x51f6a2[_0x510043(0x4a6)]*0x400,'cbr':_0x51f6a2[_0x510043(0x317)]}));if(_0x510043(0x54c)in _0x149252&&_0x149252[_0x510043(0x54c)]!=_0x51f6a2[_0x510043(0x564)][_0x149252[_0x510043(0x484)]]['session']){errorlog('Answer\x20SDP\x20does\x20not\x20have\x20a\x20matching\x20session\x20ID');return;}_0x51f6a2[_0x510043(0x564)][_0x149252[_0x510043(0x484)]][_0x510043(0x135)](_0x149252[_0x510043(0x398)])[_0x510043(0x558)]()['catch'](errorlog);}catch(_0x2e5dcb){errorlog(_0x2e5dcb);}});else{if(_0x149252[_0x238db5(0x398)][_0x238db5(0x436)]==_0x238db5(0x4a1))_0x51f6a2[_0x238db5(0x4af)](_0x149252),_0x51f6a2[_0x238db5(0x543)](_0x149252);else try{var _0x192faa=_0x51f6a2[_0x238db5(0x559)];if((iOS||iPad)&&_0x51f6a2[_0x238db5(0x564)][_0x149252[_0x238db5(0x484)]][_0x238db5(0x391)]==!![]&&_0x51f6a2[_0x238db5(0x564)][_0x149252[_0x238db5(0x484)]][_0x238db5(0x531)]==![]){if(_0x192faa===![]||_0x192faa>_0x51f6a2[_0x238db5(0x158)]){var _0x398418=Object[_0x238db5(0x345)](_0x51f6a2[_0x238db5(0x564)])[_0x238db5(0x39f)];if(_0x398418>0x3)_0x192faa=_0x51f6a2['lowiosviewers'];else{if(_0x238db5(0x279)==='hHrtZ'){function _0x1952d8(){var _0xf797e0=_0x238db5;_0x52cf08['rpcs'][_0x6f1057['directorUUID']]['stats'][_0xf797e0(0x494)][_0xf797e0(0x164)]=!![];}}else _0x192faa=_0x51f6a2[_0x238db5(0x158)];}}_0x149252['description'][_0x238db5(0x48f)]=CodecsHandler[_0x238db5(0x35f)](_0x149252['description']['sdp'],_0x238db5(0x3ba)),_0x149252['description'][_0x238db5(0x48f)]=CodecsHandler['setVideoBitrates'](_0x149252[_0x238db5(0x398)][_0x238db5(0x48f)],{'min':parseInt(_0x192faa/0x2)||0x1,'max':_0x192faa}),_0x192faa=![];}else{if(_0x51f6a2[_0x238db5(0x564)][_0x149252[_0x238db5(0x484)]][_0x238db5(0x391)]==!![]){if(_0x192faa!==![])_0x51f6a2[_0x238db5(0x2b7)]!==![]&&(_0x51f6a2[_0x238db5(0x2b7)]<_0x192faa&&(_0x192faa=_0x51f6a2[_0x238db5(0x2b7)]));else{if(_0x238db5(0x1ed)===_0x238db5(0x1ed))_0x192faa=_0x51f6a2[_0x238db5(0x2b7)];else{function _0x4c1780(){var _0x9ea30=_0x238db5;_0x562ea9[_0x9ea30(0x125)][_0x44ff59][_0x9ea30(0x152)]&&(_0x40d2e3[_0x9ea30(0x125)][_0xc5b169][_0x9ea30(0x152)]['muted']=!![],_0x2444ec[_0x9ea30(0x125)][_0x475231][_0x9ea30(0x152)][_0x9ea30(0x118)][_0x9ea30(0x47f)]&&_0x263ba6[_0x9ea30(0x125)][_0x21e8db]['videoElement'][_0x9ea30(0x118)]['display']!==_0x9ea30(0x446)&&(_0x4ad947[_0x9ea30(0x125)][_0x45f777][_0x9ea30(0x152)][_0x9ea30(0x118)][_0x9ea30(0x47f)]=_0x9ea30(0x446),_0x3f9e9f=!![]));}}}}}if(_0x192faa){var _0x23f55b=CodecsHandler[_0x238db5(0x1e8)](_0x149252[_0x238db5(0x398)]['sdp'])||0x9c4;log(_0x238db5(0x117)+_0x23f55b);if(_0x23f55b>_0x192faa){var _0x58d666=CodecsHandler['getOpusBitrate'](_0x149252[_0x238db5(0x398)][_0x238db5(0x48f)])||0x0;_0x149252[_0x238db5(0x398)][_0x238db5(0x48f)]=CodecsHandler[_0x238db5(0x535)](_0x149252[_0x238db5(0x398)][_0x238db5(0x48f)],{'min':parseInt(_0x192faa/0xa)||0x1,'max':parseInt(_0x192faa+_0x58d666/0x400)});}}else{if(_0x51f6a2['outboundVideoBitrate']!==![]){var _0x23f55b=CodecsHandler[_0x238db5(0x1e8)](_0x149252[_0x238db5(0x398)]['sdp']);if(_0x23f55b===![]){var _0x58d666=CodecsHandler[_0x238db5(0x4e1)](_0x149252[_0x238db5(0x398)][_0x238db5(0x48f)])||0x0;_0x149252[_0x238db5(0x398)][_0x238db5(0x48f)]=CodecsHandler[_0x238db5(0x535)](_0x149252[_0x238db5(0x398)]['sdp'],{'min':parseInt(_0x51f6a2[_0x238db5(0x48b)]/0xa)||0x1,'max':parseInt(_0x51f6a2[_0x238db5(0x48b)]+_0x58d666/0x400)});}}}_0x51f6a2[_0x238db5(0x4a6)]&&(_0x149252[_0x238db5(0x398)][_0x238db5(0x48f)]=CodecsHandler[_0x238db5(0x41e)](_0x149252[_0x238db5(0x398)][_0x238db5(0x48f)],{'maxaveragebitrate':_0x51f6a2[_0x238db5(0x4a6)]*0x400,'cbr':_0x51f6a2[_0x238db5(0x317)]}));if(_0x238db5(0x54c)in _0x149252&&_0x149252['session']!=_0x51f6a2[_0x238db5(0x564)][_0x149252[_0x238db5(0x484)]]['session']){errorlog(_0x238db5(0x2d6));return;}_0x51f6a2[_0x238db5(0x564)][_0x149252[_0x238db5(0x484)]][_0x238db5(0x135)](_0x149252[_0x238db5(0x398)])[_0x238db5(0x558)]()['catch'](errorlog);}catch(_0x43fe63){errorlog(_0x43fe63);}}},_0x51f6a2[_0x46afd2(0x3ad)]=function(_0x138874){var _0x3d660d=_0x46afd2;_0x51f6a2[_0x3d660d(0x292)]&&_0x3d660d(0x5a4)in _0x138874?_0x51f6a2['decryptMessage'](_0x138874['candidate'],_0x138874[_0x3d660d(0x5a4)])[_0x3d660d(0x558)](function(_0x41c502){var _0x55c5c0=_0x3d660d;_0x138874[_0x55c5c0(0x496)]=JSON[_0x55c5c0(0x3f1)](_0x41c502),_0x51f6a2['processIce2'](_0x138874);}):_0x51f6a2[_0x3d660d(0x520)](_0x138874);},_0x51f6a2[_0x46afd2(0x520)]=function(_0x927393){var _0x2db886=_0x46afd2;try{if(_0x51f6a2[_0x2db886(0x421)]){if(_0x927393[_0x2db886(0x496)][_0x2db886(0x496)]['indexOf'](_0x51f6a2[_0x2db886(0x421)])===-0x1){log(_0x2db886(0x42f)),log(_0x927393[_0x2db886(0x496)]);return;}else log('PASSED'),log(_0x927393['candidate']);}}catch(_0x135b40){errorlog(_0x135b40);}if(_0x927393[_0x2db886(0x496)]&&_0x2db886(0x496)in _0x927393[_0x2db886(0x496)]&&_0x927393[_0x2db886(0x496)][_0x2db886(0x496)]=='')return;if(_0x927393[_0x2db886(0x484)]in _0x51f6a2[_0x2db886(0x564)]&&_0x927393[_0x2db886(0x436)]=='remote'){log(_0x2db886(0x112));if(!(_0x927393[_0x2db886(0x484)]in _0x51f6a2[_0x2db886(0x564)])){errorlog('ICE\x20target\x20no\x20longer\x20exists?');return;}if('session'in _0x927393&&_0x51f6a2['pcs'][_0x927393[_0x2db886(0x484)]][_0x2db886(0x54c)]!=_0x927393[_0x2db886(0x54c)]){errorlog(_0x2db886(0x176));return;}_0x51f6a2[_0x2db886(0x564)][_0x927393[_0x2db886(0x484)]][_0x2db886(0x3dd)](_0x927393[_0x2db886(0x496)])[_0x2db886(0x558)]()[_0x2db886(0x186)](function(_0x38f124){errorlog(_0x38f124),errorlog(_0x927393);});}else{if(_0x927393[_0x2db886(0x484)]in _0x51f6a2['rpcs']&&_0x927393[_0x2db886(0x436)]==_0x2db886(0x265)){log(_0x2db886(0x52b));if(!(_0x927393[_0x2db886(0x484)]in _0x51f6a2[_0x2db886(0x125)])){errorlog(_0x2db886(0x266));return;}if(_0x2db886(0x54c)in _0x927393&&_0x51f6a2[_0x2db886(0x125)][_0x927393[_0x2db886(0x484)]][_0x2db886(0x54c)]!=_0x927393[_0x2db886(0x54c)]){errorlog(_0x2db886(0x176));return;}if(_0x51f6a2[_0x2db886(0x125)][_0x927393[_0x2db886(0x484)]]===null)return;_0x51f6a2['rpcs'][_0x927393[_0x2db886(0x484)]][_0x2db886(0x3dd)](_0x927393[_0x2db886(0x496)])['then']()[_0x2db886(0x186)](function(_0x3637a4){errorlog(_0x3637a4),errorlog(_0x927393);});}else errorlog(_0x927393),errorlog(_0x2db886(0x3f6));}},_0x51f6a2[_0x46afd2(0x286)]=function(_0x13ff41){var _0x3a7e61=_0x46afd2;if(_0x51f6a2[_0x3a7e61(0x292)]&&'vector'in _0x13ff41)_0x51f6a2['decryptMessage'](_0x13ff41[_0x3a7e61(0x253)],_0x13ff41[_0x3a7e61(0x5a4)])[_0x3a7e61(0x558)](function(_0x34de8c){var _0x516629=_0x3a7e61;if('zhePX'!==_0x516629(0x2e0)){function _0xa49685(){var _0x4eab79=_0x516629;_0x4eab79(0x340)in _0x2a8e3b[_0x4eab79(0x125)][this[_0x4eab79(0x484)]][_0x4eab79(0x152)]&&_0x3e88e9[_0x4eab79(0x125)][this[_0x4eab79(0x484)]][_0x4eab79(0x152)][_0x4eab79(0x340)]['stop']();}}else{_0x13ff41[_0x516629(0x253)]=JSON[_0x516629(0x3f1)](_0x34de8c);var _0x3e4d6d={};_0x3e4d6d[_0x516629(0x484)]=_0x13ff41['UUID'],_0x3e4d6d[_0x516629(0x436)]=_0x13ff41[_0x516629(0x436)];for(var _0x22a1ac=0x0;_0x22a1ac<_0x13ff41['candidates'][_0x516629(0x39f)];_0x22a1ac++){_0x3e4d6d['candidate']=_0x13ff41['candidates'][_0x22a1ac],_0x51f6a2[_0x516629(0x520)](_0x3e4d6d);}}});else{var _0x26644a={};_0x26644a[_0x3a7e61(0x484)]=_0x13ff41[_0x3a7e61(0x484)],_0x26644a[_0x3a7e61(0x436)]=_0x13ff41[_0x3a7e61(0x436)];for(var _0x8e85a7=0x0;_0x8e85a7<_0x13ff41[_0x3a7e61(0x253)][_0x3a7e61(0x39f)];_0x8e85a7++){if(_0x3a7e61(0x481)==='VQZjU')_0x26644a[_0x3a7e61(0x496)]=_0x13ff41[_0x3a7e61(0x253)][_0x8e85a7],_0x51f6a2[_0x3a7e61(0x520)](_0x26644a);else{function _0x3d89fa(){_0x6db7f4();}}}}},_0x51f6a2['connectPeer']=function(_0x173c04){var _0x4f7abf=_0x46afd2;_0x51f6a2[_0x4f7abf(0x125)][_0x173c04[_0x4f7abf(0x484)]][_0x4f7abf(0x135)](_0x173c04['description'])[_0x4f7abf(0x558)](function(){var _0x5364f5=_0x4f7abf;if(_0x51f6a2[_0x5364f5(0x125)][_0x173c04['UUID']][_0x5364f5(0x1a7)][_0x5364f5(0x436)]===_0x5364f5(0x4a1))_0x51f6a2[_0x5364f5(0x125)][_0x173c04[_0x5364f5(0x484)]]['createAnswer']()[_0x5364f5(0x558)](function(_0x4b2ec1){var _0x1bdbfc=_0x5364f5;if(!_0x51f6a2[_0x1bdbfc(0x164)]&&_0x51f6a2[_0x1bdbfc(0x552)]==0x5)_0x4b2ec1[_0x1bdbfc(0x48f)]=CodecsHandler[_0x1bdbfc(0x41e)](_0x4b2ec1['sdp'],{'stereo':0x1,'maxaveragebitrate':(_0x51f6a2['audiobitrate']||0x100)*0x400,'cbr':_0x51f6a2[_0x1bdbfc(0x317)],'useinbandfec':0x1,'maxptime':_0x51f6a2['maxptime'],'minptime':_0x51f6a2['minptime'],'ptime':_0x51f6a2[_0x1bdbfc(0x56f)]});else{if(_0x51f6a2[_0x1bdbfc(0x552)]==0x1||_0x51f6a2['stereo']==0x2||_0x51f6a2['stereo']==0x5)_0x4b2ec1[_0x1bdbfc(0x48f)]=CodecsHandler[_0x1bdbfc(0x41e)](_0x4b2ec1['sdp'],{'stereo':0x1,'maxaveragebitrate':(_0x51f6a2[_0x1bdbfc(0x174)]||0x100)*0x400,'cbr':_0x51f6a2[_0x1bdbfc(0x317)],'useinbandfec':0x1,'maxptime':_0x51f6a2[_0x1bdbfc(0x1ba)],'minptime':_0x51f6a2[_0x1bdbfc(0x4d7)],'ptime':_0x51f6a2[_0x1bdbfc(0x56f)]});else{if(_0x51f6a2[_0x1bdbfc(0x552)]==0x4)_0x4b2ec1[_0x1bdbfc(0x48f)]=CodecsHandler[_0x1bdbfc(0x41e)](_0x4b2ec1[_0x1bdbfc(0x48f)],{'stereo':0x2,'maxaveragebitrate':(_0x51f6a2[_0x1bdbfc(0x174)]||0x100)*0x400,'cbr':_0x51f6a2[_0x1bdbfc(0x317)],'useinbandfec':0x1,'maxptime':_0x51f6a2[_0x1bdbfc(0x1ba)],'minptime':_0x51f6a2[_0x1bdbfc(0x4d7)],'ptime':_0x51f6a2[_0x1bdbfc(0x56f)]});else _0x51f6a2['audiobitrate']&&(_0x4b2ec1[_0x1bdbfc(0x48f)]=CodecsHandler['setOpusAttributes'](_0x4b2ec1[_0x1bdbfc(0x48f)],{'maxaveragebitrate':_0x51f6a2[_0x1bdbfc(0x174)]*0x400,'cbr':_0x51f6a2[_0x1bdbfc(0x317)],'useinbandfec':0x1,'maxptime':_0x51f6a2['maxptime'],'minptime':_0x51f6a2[_0x1bdbfc(0x4d7)],'ptime':_0x51f6a2[_0x1bdbfc(0x56f)]}));}}_0x51f6a2[_0x1bdbfc(0x58e)]&&(_0x4b2ec1['sdp']=CodecsHandler[_0x1bdbfc(0x35f)](_0x4b2ec1['sdp'],_0x51f6a2['codec']));_0x51f6a2[_0x1bdbfc(0x3cc)]&&(log(_0x4b2ec1[_0x1bdbfc(0x48f)]),_0x4b2ec1['sdp']=CodecsHandler[_0x1bdbfc(0x269)](_0x4b2ec1[_0x1bdbfc(0x48f)]));_0x51f6a2[_0x1bdbfc(0x360)]&&(_0x4b2ec1[_0x1bdbfc(0x48f)]=CodecsHandler['disablePLI'](_0x4b2ec1[_0x1bdbfc(0x48f)]));_0x51f6a2['noREMB']&&(_0x4b2ec1[_0x1bdbfc(0x48f)]=CodecsHandler[_0x1bdbfc(0x3c1)](_0x4b2ec1['sdp']));if(_0x51f6a2[_0x1bdbfc(0x125)][_0x173c04[_0x1bdbfc(0x484)]][_0x1bdbfc(0x523)])log(_0x1bdbfc(0x20b)),_0x4b2ec1[_0x1bdbfc(0x48f)]=_0x159ec6(_0x4b2ec1['sdp'],_0x51f6a2[_0x1bdbfc(0x125)][_0x173c04[_0x1bdbfc(0x484)]][_0x1bdbfc(0x523)]);else _0x51f6a2[_0x1bdbfc(0x3b7)]&&(log(_0x1bdbfc(0x20b)),_0x4b2ec1[_0x1bdbfc(0x48f)]=_0x159ec6(_0x4b2ec1[_0x1bdbfc(0x48f)],_0x51f6a2[_0x1bdbfc(0x3b7)]));return _0x51f6a2[_0x1bdbfc(0x125)][_0x173c04['UUID']][_0x1bdbfc(0x526)](_0x4b2ec1);})[_0x5364f5(0x558)](function _0x131fb4(){var _0x57d7f4=_0x5364f5;log(_0x57d7f4(0x2d5));var _0x4c5b63={};_0x4c5b63[_0x57d7f4(0x484)]=_0x173c04[_0x57d7f4(0x484)],_0x4c5b63[_0x57d7f4(0x398)]=_0x51f6a2[_0x57d7f4(0x125)][_0x173c04[_0x57d7f4(0x484)]]['localDescription'],_0x4c5b63[_0x57d7f4(0x54c)]=_0x51f6a2[_0x57d7f4(0x125)][_0x173c04[_0x57d7f4(0x484)]][_0x57d7f4(0x54c)],_0x51f6a2[_0x57d7f4(0x292)]?_0x51f6a2[_0x57d7f4(0x591)](JSON[_0x57d7f4(0x240)](_0x4c5b63[_0x57d7f4(0x398)]))[_0x57d7f4(0x558)](function(_0x2ec204){var _0x19578c=_0x57d7f4;_0x4c5b63[_0x19578c(0x398)]=_0x2ec204[0x0],_0x4c5b63[_0x19578c(0x5a4)]=_0x2ec204[0x1],_0x51f6a2[_0x19578c(0x1a9)](_0x4c5b63);}):_0x51f6a2['anyrequest'](_0x4c5b63);})['catch'](errorlog);else _0x51f6a2['rpcs'][_0x173c04[_0x5364f5(0x484)]][_0x5364f5(0x1a7)][_0x5364f5(0x436)]===_0x5364f5(0x111)&&errorlog(_0x5364f5(0x22b));})['catch'](errorlog);},_0x51f6a2['setupIncoming']=function(_0x59a8aa){var _0x35e56d=_0x46afd2,_0x5aebb5=_0x59a8aa[_0x35e56d(0x484)];if(_0x5aebb5 in _0x51f6a2[_0x35e56d(0x125)]){log(_0x35e56d(0x5a2)),log(_0x59a8aa);if(_0x35e56d(0x54c)in _0x59a8aa){if(_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x54c)]==_0x59a8aa[_0x35e56d(0x54c)]){log(_0x35e56d(0x3c3));return;}else warnlog('SDP\x20Sessions\x20do\x20not\x20match.\x20Do\x20I\x20delete\x20an\x20accept\x20this\x20new\x20SDP?');}}else log(_0x35e56d(0x1ad));try{for(var _0x3fe803 in _0x51f6a2['rpcs']){if(_0x35e56d(0x1b5)!==_0x35e56d(0x1b5)){function _0x596aaa(){var _0x91dbca=_0x35e56d;_0x3dba25[_0x91dbca(0x125)][_0x5a547d][_0x91dbca(0x162)]=new _0x383644();}}else{if(_0x51f6a2[_0x35e56d(0x125)][_0x3fe803][_0x35e56d(0x524)]==_0x59a8aa[_0x35e56d(0x524)]){_0x51f6a2[_0x35e56d(0x125)][_0x3fe803][_0x35e56d(0x152)]&&(_0x51f6a2[_0x35e56d(0x125)][_0x3fe803][_0x35e56d(0x152)][_0x35e56d(0x118)][_0x35e56d(0x47f)]=_0x35e56d(0x446));_0x51f6a2['rpcs'][_0x3fe803]=null,delete _0x51f6a2[_0x35e56d(0x125)][_0x3fe803],warnlog(_0x35e56d(0x3ce));if(_0x51f6a2['director']){if(_0x35e56d(0x1b2)!==_0x35e56d(0x1b2)){function _0x5add60(){var _0x3c5400=_0x35e56d;_0x5ebde3+=_0x3946a6[_0x3c5400(0x1d6)](_0x109bfc[_0x232009]);}}else try{document['getElementById']('container_'+_0x3fe803)&&getById(_0x35e56d(0x557)+_0x3fe803)[_0x35e56d(0x4d0)][_0x35e56d(0x514)](getById(_0x35e56d(0x557)+_0x3fe803));}catch(_0x5506e0){errorlog(_0x5506e0);}}}}}document['getElementById'](_0x35e56d(0x4e6))&&document['getElementById'](_0x35e56d(0x4e6))['parentNode']['removeChild'](document[_0x35e56d(0x382)](_0x35e56d(0x4e6)));}catch(_0x121ddb){errorlog(_0x121ddb);}if(_0x51f6a2[_0x35e56d(0x326)]!==![]){if(Object[_0x35e56d(0x345)](_0x51f6a2[_0x35e56d(0x125)])[_0x35e56d(0x39f)]>=_0x51f6a2[_0x35e56d(0x326)]){delete _0x51f6a2[_0x35e56d(0x125)][_0x5aebb5],updateUserList(),warnlog(_0x35e56d(0x370));return;}}else{if(_0x51f6a2[_0x35e56d(0x36b)]!==![]){if(Object[_0x35e56d(0x345)](_0x51f6a2[_0x35e56d(0x125)])[_0x35e56d(0x39f)]+Object[_0x35e56d(0x345)](_0x51f6a2[_0x35e56d(0x564)])['length']>=_0x51f6a2[_0x35e56d(0x36b)]){delete _0x51f6a2[_0x35e56d(0x125)][_0x5aebb5],updateUserList(),warnlog('Publisher\x20will\x20be\x20ignored\x20due\x20to\x20max\x20connections\x20already\x20hit');return;}}}if(_0x51f6a2[_0x35e56d(0x4b6)]){if(_0x51f6a2[_0x35e56d(0x164)])!(_0x5aebb5 in _0x51f6a2['pcs'])&&_0x51f6a2[_0x35e56d(0x44d)](_0x5aebb5);else{if(_0x51f6a2[_0x35e56d(0x44a)]!==_0x5aebb5)return;}}_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5]=new RTCPeerConnection(_0x51f6a2[_0x35e56d(0x3f9)]);if(_0x51f6a2[_0x35e56d(0x41a)]){if(Object[_0x35e56d(0x345)](_0x51f6a2[_0x35e56d(0x125)])[_0x35e56d(0x39f)]>0x1){warnlog(_0x35e56d(0x381)),log(_0x51f6a2[_0x35e56d(0x125)]),delete _0x51f6a2[_0x35e56d(0x125)][_0x5aebb5],updateUserList();return;}else warnlog('CONNECTED\x20TO\x20FIRST\x20PEER');}_0x59a8aa[_0x35e56d(0x524)]in _0x51f6a2['waitingWatchList']&&delete _0x51f6a2[_0x35e56d(0x40a)][_0x59a8aa[_0x35e56d(0x524)]];_0x51f6a2['rpcs'][_0x5aebb5][_0x35e56d(0x524)]=_0x59a8aa[_0x35e56d(0x524)];_0x59a8aa[_0x35e56d(0x54c)]?_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5]['session']=_0x59a8aa[_0x35e56d(0x54c)]:_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x54c)]=null;_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x3e4)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x3d4)]={},_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x3d4)][_0x35e56d(0x506)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x328)]=-0x1,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5]['channelOffset']=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x32f)]=-0x1,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x523)]=![],_0x51f6a2['rpcs'][_0x5aebb5][_0x35e56d(0x152)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x327)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x367)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x498)]=![],_0x51f6a2['rpcs'][_0x5aebb5][_0x35e56d(0x259)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x3d1)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x4ae)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x32b)]=null,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x256)]={},_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x4cb)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x547)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5]['streamSrc']=null,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x429)]=0x64,_0x51f6a2['rpcs'][_0x5aebb5][_0x35e56d(0x4d6)]=0x0,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x13a)]=0x0,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x459)]=0x0,_0x51f6a2['rpcs'][_0x5aebb5][_0x35e56d(0x26c)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5]['order']=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x395)]=null,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x4a8)]=null,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x51b)]={},_0x51f6a2['rpcs'][_0x5aebb5][_0x35e56d(0x29b)]=![],_0x51f6a2['rpcs'][_0x5aebb5][_0x35e56d(0x20a)]=![],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5]['startTime']=Date[_0x35e56d(0x416)]();var _0x247aaf='';_0x51f6a2[_0x35e56d(0x444)]&&(_0x247aaf=_0x51f6a2[_0x35e56d(0x444)]);if(_0x51f6a2[_0x35e56d(0x164)]){var _0x41361a='';_0x51f6a2[_0x35e56d(0x33b)]&&(_0x51f6a2[_0x35e56d(0x33b)]!==!![]?_0x41361a='&pie='+_0x51f6a2['pie']:_0x41361a=_0x35e56d(0x487));var _0x5d51b1='';_0x51f6a2[_0x35e56d(0x292)]&&(_0x51f6a2[_0x35e56d(0x130)]===![]&&(_0x5d51b1='&password='+_0x51f6a2[_0x35e56d(0x292)])),createControlBox(_0x5aebb5,'https://'+location[_0x35e56d(0x4ba)]+location[_0x35e56d(0x354)]+_0x35e56d(0x447)+_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x524)]+_0x35e56d(0x3a0)+_0x247aaf+_0x35e56d(0x20e)+_0x51f6a2[_0x35e56d(0x3f8)]+_0x5d51b1+_0x41361a,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x524)]);}_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x484)]=_0x5aebb5;if(_0x35e56d(0x524)in _0x59a8aa){_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x524)]=_0x59a8aa[_0x35e56d(0x524)];try{if(_0x51f6a2[_0x35e56d(0x1e5)]){if(_0x51f6a2[_0x35e56d(0x1e5)][_0x35e56d(0x254)](_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x524)])){if(_0x51f6a2[_0x35e56d(0x3f4)]!==![]){let _0x32794f=_0x51f6a2[_0x35e56d(0x1e5)][_0x35e56d(0x124)](_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x524)]);_0x51f6a2['bitrate_set']['length']>_0x32794f&&(_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x523)]=parseInt(_0x51f6a2['bitrate_set'][_0x32794f]),_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x523)]<=0x0&&(_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x523)]=![]));}}}}catch(_0x504188){errorlog(_0x504188);}}_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x58b)]=function(_0x26ece1){var _0x286ca0=_0x35e56d;try{var _0x23684f=this['streamID'];}catch(_0x54861a){}if(!_0x51f6a2[_0x286ca0(0x164)]){if(_0x51f6a2[_0x286ca0(0x4d5)]!==![]||_0x51f6a2[_0x286ca0(0x3f8)]!==![])try{_0x51f6a2[_0x286ca0(0x125)][this[_0x286ca0(0x484)]][_0x286ca0(0x152)]&&(_0x51f6a2['rpcs'][this['UUID']][_0x286ca0(0x152)][_0x286ca0(0x118)][_0x286ca0(0x47f)]=_0x286ca0(0x446)),setTimeout(function(){updateMixer();},0x1);}catch(_0x3816c2){}}try{if(document[_0x286ca0(0x382)](_0x286ca0(0x557)+this[_0x286ca0(0x484)])){if(_0x286ca0(0x14e)!==_0x286ca0(0x58d))getById('container_'+this[_0x286ca0(0x484)])[_0x286ca0(0x4d0)][_0x286ca0(0x514)](getById(_0x286ca0(0x557)+this['UUID']));else{function _0x31412a(){_0xe5df6d();}}}}catch(_0x1b772a){errorlog(_0x1b772a);}try{if(this[_0x286ca0(0x162)]){if(_0x286ca0(0x4f1)!==_0x286ca0(0x1ee))this[_0x286ca0(0x162)][_0x286ca0(0x188)]()[_0x286ca0(0x335)](function(_0x5d79c1){var _0x4ab2e1=_0x286ca0;_0x5d79c1[_0x4ab2e1(0x4e5)]();});else{function _0x3d51c8(){var _0x59f1bf=_0x286ca0,_0x58464d=new _0x5b78a1(_0x59f1bf(0x4f9))['encode'](_0x341e3a);return _0x31f324[_0x59f1bf(0x455)][_0x59f1bf(0x361)](_0x59f1bf(0x454),_0x58464d)[_0x59f1bf(0x558)](function(_0x325ef2){var _0x3c1622=_0x59f1bf;return _0x325ef2=new _0x5aadaa(_0x325ef2),_0x1c60ea&&(_0x325ef2=_0x325ef2[_0x3c1622(0x1ab)](0x0,_0x608bb2(_0x4bed95(_0x345d1b)/0x2))),_0x325ef2=_0x5c07be(_0x325ef2),_0x325ef2;});}}}}catch(_0x3a4ea1){errorlog(_0x3a4ea1);}try{this['receiveChannel']['close']();}catch(_0x2fc1f2){errorlog(_0x2fc1f2);}try{_0x51f6a2[_0x286ca0(0x125)][this['UUID']]=null,delete _0x51f6a2[_0x286ca0(0x125)][this[_0x286ca0(0x484)]];}catch(_0x5e7038){errorlog(_0x5e7038);}warnlog(_0x286ca0(0x3ce));try{if(_0x286ca0(0x2fb)!==_0x286ca0(0x2fb)){function _0x301322(){_0x1f8ff8('successfully\x20sent\x20message\x20vis\x20WebRTC\x20instead\x20of\x20WSS');}}else _0x51f6a2[_0x286ca0(0x570)](_0x23684f);}catch(_0x4c9a28){errorlog(_0x286ca0(0x137)),errorlog(_0x4c9a28);}updateUserList();},_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x1c3)]=null,_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x206)]=[],_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5]['onicecandidate']=function(_0xee7d5e){var _0x246c64=_0x35e56d;if(_0xee7d5e[_0x246c64(0x496)]==null){log(_0x246c64(0x2a3));return;}try{if(_0x51f6a2[_0x246c64(0x421)]){if(_0xee7d5e[_0x246c64(0x496)][_0x246c64(0x496)][_0x246c64(0x124)](_0x51f6a2[_0x246c64(0x421)])===-0x1){log(_0x246c64(0x42f));return;}else log(_0xee7d5e[_0x246c64(0x496)]);}}catch(_0x3bfca0){errorlog(_0x3bfca0);}if(_0x51f6a2[_0x246c64(0x125)][_0x5aebb5][_0x246c64(0x1c3)]!==null){_0x51f6a2[_0x246c64(0x125)][_0x5aebb5][_0x246c64(0x206)]['push'](_0xee7d5e[_0x246c64(0x496)]);return;}_0x51f6a2[_0x246c64(0x125)][_0x5aebb5][_0x246c64(0x206)]['push'](_0xee7d5e[_0x246c64(0x496)]),_0x51f6a2['rpcs'][_0x5aebb5][_0x246c64(0x1c3)]=setTimeout(function(){var _0x439e22=_0x246c64;if(!(_0x5aebb5 in _0x51f6a2[_0x439e22(0x125)]))return;_0x51f6a2[_0x439e22(0x125)][_0x5aebb5][_0x439e22(0x1c3)]=null;if(_0x51f6a2['rpcs'][_0x5aebb5]['iceBundle']==[])return;var _0x2c52b1={};_0x2c52b1[_0x439e22(0x484)]=_0x5aebb5,_0x2c52b1[_0x439e22(0x436)]=_0x439e22(0x23a),_0x2c52b1[_0x439e22(0x253)]=_0x51f6a2[_0x439e22(0x125)][_0x5aebb5][_0x439e22(0x206)],_0x2c52b1['session']=_0x51f6a2[_0x439e22(0x125)][_0x5aebb5][_0x439e22(0x54c)],_0x51f6a2[_0x439e22(0x125)][_0x5aebb5]['iceBundle']=[],_0x51f6a2[_0x439e22(0x292)]?_0x51f6a2[_0x439e22(0x591)](JSON[_0x439e22(0x240)](_0x2c52b1[_0x439e22(0x253)]))[_0x439e22(0x558)](function(_0x4fbea6){var _0x372a77=_0x439e22;_0x2c52b1[_0x372a77(0x253)]=_0x4fbea6[0x0],_0x2c52b1[_0x372a77(0x5a4)]=_0x4fbea6[0x1],_0x51f6a2[_0x372a77(0x1a9)](_0x2c52b1);}):_0x51f6a2[_0x439e22(0x1a9)](_0x2c52b1);},0x190);},_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x1ea)]=function(_0x5f05a3){var _0x5a06cd=_0x35e56d;if(_0x5a06cd(0x1df)===_0x5a06cd(0x1df))switch(this[_0x5a06cd(0x11d)]){case _0x5a06cd(0x423):log(_0x5a06cd(0x423));case _0x5a06cd(0x261):log(_0x5a06cd(0x261));case _0x5a06cd(0x172):log(_0x5a06cd(0x3b1));if(_0x51f6a2[_0x5a06cd(0x41a)]){if(_0x5a06cd(0x505)!==_0x5a06cd(0x505)){function _0x5e2cff(){var _0x5cfb6a=_0x5a06cd;_0x36f13c['encodings'][0x0]['active']=!![],_0x48a4f1[_0x5cfb6a(0x337)](_0x5380a3)[_0x5cfb6a(0x558)](()=>{})[_0x5cfb6a(0x186)](_0x496aa2);}}else{if(_0x51f6a2['ws'][_0x5a06cd(0x37a)]!==0x1){_0x51f6a2['ws'][_0x5a06cd(0x245)]();break;}_0x51f6a2['ws']['close'](),setTimeout(function(){var _0x8d3902=_0x5a06cd;_0x51f6a2[_0x8d3902(0x368)]!=!![]&&warnUser(_0x8d3902(0x492));},0x1);}}break;case'disconnected':warnlog(_0x5a06cd(0x456));break;case _0x5a06cd(0x147):warnlog(_0x5a06cd(0x1cc));try{var _0x2181f7=this[_0x5a06cd(0x524)];}catch(_0x3aea91){}try{this['streamSrc']&&this[_0x5a06cd(0x162)]['getTracks']()['forEach'](function(_0x28face){var _0x20158c=_0x5a06cd;_0x28face[_0x20158c(0x4e5)](),log(_0x20158c(0x420));});}catch(_0x1fb6e6){warnlog(_0x1fb6e6);}if(_0x51f6a2[_0x5a06cd(0x164)])try{_0x5a06cd(0x340)in _0x51f6a2[_0x5a06cd(0x125)][this[_0x5a06cd(0x484)]]['videoElement']&&_0x51f6a2[_0x5a06cd(0x125)][this['UUID']][_0x5a06cd(0x152)][_0x5a06cd(0x340)][_0x5a06cd(0x4e5)]();}catch(_0xedda0c){warnlog(_0xedda0c);}try{document[_0x5a06cd(0x382)](_0x5a06cd(0x557)+this[_0x5a06cd(0x484)])&&getById(_0x5a06cd(0x557)+this[_0x5a06cd(0x484)])[_0x5a06cd(0x4d0)][_0x5a06cd(0x514)](getById(_0x5a06cd(0x557)+this[_0x5a06cd(0x484)]));}catch(_0x25a8cc){if(_0x5a06cd(0x289)===_0x5a06cd(0x202)){function _0x3b278d(){return;}}else warnlog(_0x25a8cc);}_0x51f6a2[_0x5a06cd(0x125)][this[_0x5a06cd(0x484)]][_0x5a06cd(0x245)](),_0x51f6a2[_0x5a06cd(0x125)][this[_0x5a06cd(0x484)]]=null,delete _0x51f6a2[_0x5a06cd(0x125)][this[_0x5a06cd(0x484)]];!_0x51f6a2[_0x5a06cd(0x164)]&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x2181f7=='undefined')break;try{warnlog('Trying\x20to\x20reconnect\x202'),_0x2181f7 in _0x51f6a2[_0x5a06cd(0x567)]&&clearTimeout(_0x51f6a2[_0x5a06cd(0x567)][_0x2181f7]),_0x51f6a2[_0x5a06cd(0x567)][_0x2181f7]=setTimeout(function(_0x3fcf80){var _0x587110=_0x5a06cd;if(_0x587110(0x320)==='vQtjC'){function _0x14f3f3(){var _0x226539=_0x587110;_0x226539(0x540)in _0x2984ea&&(_0x55d950[_0x226539(0x125)][_0xd5b959][_0x226539(0x3d4)][_0x162be4['id']][_0x226539(0x3c7)]=_0x3cf092[_0x226539(0x553)]+'\x20x\x20'+_0x4c0c83[_0x226539(0x540)],_0x5b1593[_0x226539(0x125)][_0x580c66]['stats'][_0x1e9b6a['id']][_0x226539(0x319)]=_0x3ff615[_0x226539(0x553)],_0x264f4f[_0x226539(0x125)][_0x1e5869][_0x226539(0x3d4)][_0x351607['id']][_0x226539(0x402)]=_0x46e308[_0x226539(0x540)]);}}else delete _0x51f6a2[_0x587110(0x567)][_0x3fcf80],_0x51f6a2[_0x587110(0x570)](_0x3fcf80);},_0x51f6a2[_0x5a06cd(0x2f6)],_0x2181f7);}catch(_0x196c91){errorlog(_0x196c91);}break;case'closed':warnlog(_0x5a06cd(0x3df));try{var _0x2181f7=this[_0x5a06cd(0x524)];}catch(_0x186745){};try{this[_0x5a06cd(0x162)]&&this[_0x5a06cd(0x162)][_0x5a06cd(0x188)]()[_0x5a06cd(0x335)](function(_0xbc245a){var _0x35cd88=_0x5a06cd;_0xbc245a['stop'](),log(_0x35cd88(0x420));});}catch(_0x429547){}if(_0x51f6a2[_0x5a06cd(0x164)])try{_0x5a06cd(0x340)in _0x51f6a2['rpcs'][this[_0x5a06cd(0x484)]]['videoElement']&&_0x51f6a2[_0x5a06cd(0x125)][this['UUID']][_0x5a06cd(0x152)][_0x5a06cd(0x340)]['stop']();}catch(_0x2ec81c){errorlog(_0x2ec81c);}try{document[_0x5a06cd(0x382)](_0x5a06cd(0x557)+this[_0x5a06cd(0x484)])&&getById('container_'+this[_0x5a06cd(0x484)])[_0x5a06cd(0x4d0)][_0x5a06cd(0x514)](getById(_0x5a06cd(0x557)+this['UUID']));}catch(_0x5c0bcb){errorlog(_0x5c0bcb);}_0x51f6a2[_0x5a06cd(0x125)][this[_0x5a06cd(0x484)]]['close'](),_0x51f6a2[_0x5a06cd(0x125)][this[_0x5a06cd(0x484)]]=null,delete _0x51f6a2['rpcs'][this[_0x5a06cd(0x484)]];!_0x51f6a2[_0x5a06cd(0x164)]&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x2181f7==_0x5a06cd(0x28c))break;try{if('kYNkN'===_0x5a06cd(0x3fb))errorlog(_0x5a06cd(0x36f)),_0x2181f7 in _0x51f6a2[_0x5a06cd(0x567)]&&clearTimeout(_0x51f6a2[_0x5a06cd(0x567)][_0x2181f7]),_0x51f6a2['watchTimeoutList'][_0x2181f7]=setTimeout(function(_0x5bbd62){var _0x350576=_0x5a06cd;delete _0x51f6a2[_0x350576(0x567)][_0x5bbd62],_0x51f6a2['watchStream'](_0x5bbd62);},_0x51f6a2[_0x5a06cd(0x2f6)],_0x2181f7);else{function _0x4ae278(){var _0x462b95=_0x5a06cd;_0x2c11ca[_0x462b95(0x125)][_0x466ab7][_0x462b95(0x328)]=_0x596f53;}}}catch(_0x5adef5){if(_0x5a06cd(0x46c)===_0x5a06cd(0x46c))errorlog(_0x5adef5);else{function _0x343d22(){var _0x59ef6a=_0x5a06cd;_0x18e915(_0x59ef6a(0x448));}}}break;}else{function _0x468eda(){var _0x4f77c7=_0x5a06cd;_0x33c189[_0x4f77c7(0x125)][_0x99aea1][_0x4f77c7(0x4ae)][_0x4f77c7(0x118)]['display']=_0x4f77c7(0x446);}}},_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x40c)]=function(){var _0x39cbaf=_0x35e56d;try{if(this['iceConnectionState']=='closed')errorlog(_0x39cbaf(0x550));else{if(this[_0x39cbaf(0x530)]==_0x39cbaf(0x37e))warnlog(_0x39cbaf(0x322)),_0x51f6a2['rpcs'][_0x5aebb5][_0x39cbaf(0x152)][_0x39cbaf(0x118)][_0x39cbaf(0x21a)]='0',_0x51f6a2[_0x39cbaf(0x125)][_0x5aebb5][_0x39cbaf(0x3aa)]=setTimeout(function(_0x33414a){updateMixer();},0x1f4,_0x5aebb5);else this[_0x39cbaf(0x530)]==_0x39cbaf(0x147)?errorlog(_0x39cbaf(0x546)):(log(_0x39cbaf(0x1e7)+this[_0x39cbaf(0x530)]),_0x39cbaf(0x21a)in _0x51f6a2['rpcs'][_0x5aebb5][_0x39cbaf(0x152)][_0x39cbaf(0x118)]?_0x51f6a2[_0x39cbaf(0x125)][_0x5aebb5]['videoElement'][_0x39cbaf(0x118)]['opacity']=='0'&&(_0x51f6a2['rpcs'][_0x5aebb5][_0x39cbaf(0x152)]['style'][_0x39cbaf(0x21a)]='1',updateMixer()):_0x51f6a2[_0x39cbaf(0x125)][_0x5aebb5][_0x39cbaf(0x152)][_0x39cbaf(0x118)][_0x39cbaf(0x21a)]='1',_0x51f6a2[_0x39cbaf(0x125)][_0x5aebb5][_0x39cbaf(0x3aa)]&&clearTimeout(_0x51f6a2[_0x39cbaf(0x125)][_0x5aebb5][_0x39cbaf(0x3aa)]));}}catch(_0xc5fd8e){}},_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x32c)]=function(_0x32f25f){var _0x568682=_0x35e56d;if('ElbfE'===_0x568682(0x54d)){function _0x20ee09(){var _0x4e2536=_0x568682;_0x21d2ae(_0x4e2536(0x3c3));return;}}else _0x51f6a2['rpcs'][_0x5aebb5][_0x568682(0x57c)]=_0x32f25f[_0x568682(0x1c0)],_0x51f6a2[_0x568682(0x125)][_0x5aebb5]['receiveChannel'][_0x568682(0x484)]=_0x5aebb5,_0x51f6a2[_0x568682(0x125)][_0x5aebb5]['receiveChannel']['onopen']=_0x51d796=>{var _0x313b1e=_0x568682,_0x1e5f25={};_0x1e5f25[_0x313b1e(0x4d8)]=![];if(_0x51f6a2[_0x313b1e(0x3a5)]!==![])_0x51f6a2['novideo'][_0x313b1e(0x254)](_0x51f6a2[_0x313b1e(0x125)][_0x5aebb5][_0x313b1e(0x524)])?_0x1e5f25[_0x313b1e(0x232)]=!![]:_0x1e5f25[_0x313b1e(0x232)]=![];else{if(_0x51f6a2[_0x313b1e(0x4d8)]!==![]){if(_0x51f6a2[_0x313b1e(0x4d8)]!==null)_0x51f6a2['rpcs'][_0x5aebb5][_0x313b1e(0x524)]===_0x51f6a2[_0x313b1e(0x4d8)]?_0x51f6a2[_0x313b1e(0x477)]?(_0x1e5f25[_0x313b1e(0x4d8)]=!![],_0x1e5f25[_0x313b1e(0x232)]=![]):_0x1e5f25[_0x313b1e(0x232)]=!![]:_0x1e5f25[_0x313b1e(0x232)]=![];else _0x51f6a2[_0x313b1e(0x44a)]&&(_0x5aebb5==_0x51f6a2['directorUUID']?_0x51f6a2['webp']?(_0x1e5f25[_0x313b1e(0x232)]=![],_0x1e5f25['broadcast']=!![]):_0x1e5f25[_0x313b1e(0x232)]=!![]:_0x1e5f25['video']=![]);}else _0x51f6a2[_0x313b1e(0x23f)]!==![]?_0x51f6a2[_0x313b1e(0x23f)][_0x313b1e(0x254)](_0x51f6a2[_0x313b1e(0x125)][_0x5aebb5][_0x313b1e(0x524)])?_0x1e5f25[_0x313b1e(0x232)]=![]:_0x1e5f25[_0x313b1e(0x232)]=!![]:_0x1e5f25[_0x313b1e(0x232)]=!![];}_0x51f6a2[_0x313b1e(0x40f)]&&(_0x1e5f25['allowmidi']=_0x51f6a2[_0x313b1e(0x40f)]);try{_0x1e5f25[_0x313b1e(0x494)]={},_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x26c)]=_0x51f6a2[_0x313b1e(0x26c)],_0x1e5f25[_0x313b1e(0x494)]['order']=_0x51f6a2['order'],_0x1e5f25['info']['stereo_url']=_0x51f6a2['stereo'],_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x30c)]=_0x51f6a2['bitrate'],_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x229)]=_0x51f6a2[_0x313b1e(0x174)],_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x53b)]=_0x51f6a2['codec'],_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x291)]=_0x51f6a2[_0x313b1e(0x291)],_0x1e5f25[_0x313b1e(0x494)]['forceios']=_0x51f6a2['forceios'],_0x1e5f25[_0x313b1e(0x494)]['enhance_audio']=_0x51f6a2[_0x313b1e(0x502)],_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x56f)]=_0x51f6a2[_0x313b1e(0x56f)],_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x4d7)]=_0x51f6a2[_0x313b1e(0x4d7)],_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x1ba)]=_0x51f6a2[_0x313b1e(0x1ba)];if(navigator[_0x313b1e(0x299)]){var _0x29c80e,_0x35e708=navigator[_0x313b1e(0x299)];_0x1e5f25[_0x313b1e(0x494)]['useragent']=_0x35e708;}navigator[_0x313b1e(0x362)]&&(_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x362)]=navigator[_0x313b1e(0x362)]);if(window['obsstudio']){_0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x139)]=window[_0x313b1e(0x156)][_0x313b1e(0x587)];if(_0x51f6a2[_0x313b1e(0x4ad)]){var _0x136807=![];_0x51f6a2[_0x313b1e(0x4ad)][_0x313b1e(0x349)]!==null&&(_0x1e5f25[_0x313b1e(0x35c)]=_0x51f6a2[_0x313b1e(0x4ad)][_0x313b1e(0x349)],_0x51f6a2['obsState'][_0x313b1e(0x349)]===![]&&(_0x136807=!![])),_0x51f6a2[_0x313b1e(0x4ad)][_0x313b1e(0x143)]!==null&&(_0x1e5f25[_0x313b1e(0x12f)]=_0x51f6a2[_0x313b1e(0x4ad)][_0x313b1e(0x143)]),_0x51f6a2[_0x313b1e(0x4ad)][_0x313b1e(0x590)]!==null&&(_0x1e5f25['obsRecording']=_0x51f6a2[_0x313b1e(0x4ad)][_0x313b1e(0x590)]),_0x51f6a2[_0x313b1e(0x4ad)][_0x313b1e(0x351)]!==null&&(_0x1e5f25[_0x313b1e(0x211)]=_0x51f6a2[_0x313b1e(0x4ad)][_0x313b1e(0x351)]);}if(_0x51f6a2[_0x313b1e(0x379)]!==![]){if(_0x313b1e(0x177)!==_0x313b1e(0x177)){function _0x2f2fc7(){var _0x183901=_0x313b1e;_0x2593d6[_0x183901(0x44d)](_0x34ceeb);}}else _0x1e5f25[_0x313b1e(0x338)]=parseInt(_0x51f6a2[_0x313b1e(0x379)]),_0x136807&&(_0x51f6a2['rpcs'][_0x5aebb5][_0x313b1e(0x328)]=_0x1e5f25[_0x313b1e(0x338)]);}}else _0x1e5f25[_0x313b1e(0x494)][_0x313b1e(0x139)]=![];}catch(_0x4e1f9b){};_0x51f6a2[_0x313b1e(0x2e2)]!==![]?_0x51f6a2[_0x313b1e(0x2e2)]['includes'](_0x51f6a2[_0x313b1e(0x125)][_0x5aebb5]['streamID'])?_0x1e5f25[_0x313b1e(0x434)]=!![]:_0x1e5f25['audio']=![]:_0x1e5f25[_0x313b1e(0x434)]=!![];_0x1e5f25[_0x313b1e(0x1c4)]=![];_0x51f6a2[_0x313b1e(0x3d9)]!==![]?_0x51f6a2[_0x313b1e(0x3d9)]['includes'](_0x51f6a2[_0x313b1e(0x125)][_0x5aebb5][_0x313b1e(0x524)])?_0x1e5f25[_0x313b1e(0x1c4)]=!![]:_0x1e5f25[_0x313b1e(0x1c4)]=![]:_0x1e5f25['iframe']=!![];_0x1e5f25[_0x313b1e(0x391)]=![],_0x1e5f25[_0x313b1e(0x4d5)]=![],_0x1e5f25[_0x313b1e(0x164)]=![],_0x1e5f25['keyframerate']=_0x51f6a2[_0x313b1e(0x15d)],_0x1e5f25['enhanceaudio']=![],_0x1e5f25[_0x313b1e(0x1d3)]=![],_0x1e5f25[_0x313b1e(0x531)]=![];_0x51f6a2[_0x313b1e(0x502)]&&(_0x1e5f25[_0x313b1e(0x2fa)]=!![]);if(_0x51f6a2['director'])_0x1e5f25[_0x313b1e(0x164)]=!![],_0x1e5f25[_0x313b1e(0x531)]=_0x51f6a2[_0x313b1e(0x531)];else{if(_0x51f6a2[_0x313b1e(0x4d5)]!==![])_0x1e5f25[_0x313b1e(0x4d5)]=_0x51f6a2[_0x313b1e(0x4d5)];else _0x51f6a2[_0x313b1e(0x3f8)]!==![]&&_0x51f6a2[_0x313b1e(0x3f8)]!==''&&(_0x1e5f25['forceios']=_0x51f6a2[_0x313b1e(0x531)],_0x1e5f25[_0x313b1e(0x391)]=!![]);}_0x51f6a2[_0x313b1e(0x359)](_0x1e5f25,_0x5aebb5)?log(_0x313b1e(0x443)):errorlog(_0x313b1e(0x479)),pokeIframeAPI(_0x313b1e(0x323),!![],_0x5aebb5);},_0x51f6a2[_0x568682(0x125)][_0x5aebb5]['receiveChannel'][_0x568682(0x4fa)]=_0x2dd8fe=>{var _0x1c3821=_0x568682;if(typeof _0x2dd8fe[_0x1c3821(0x2df)]==_0x1c3821(0x58a)){if(!_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)])_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)]=document[_0x1c3821(0x175)]('img'),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['imageElement'][_0x1c3821(0x1f8)]=0x10,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)][_0x1c3821(0x2a6)]=0x9,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['imageElement']['dataset'][_0x1c3821(0x484)]=_0x5aebb5,_0x51f6a2['rpcs'][_0x5aebb5]['imageElement'][_0x1c3821(0x3ca)]=![],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)][_0x1c3821(0x1f1)](_0x1c3821(0x1db),function(_0x22a3ba){var _0x3ea515=_0x1c3821;log(_0x3ea515(0x4ce));try{if(_0x22a3ba[_0x3ea515(0x46f)]||_0x22a3ba[_0x3ea515(0x3ec)]){if(_0x3ea515(0x3a8)===_0x3ea515(0x3a8)){_0x22a3ba[_0x3ea515(0x303)]();var _0x446d19=_0x22a3ba[_0x3ea515(0x2ca)][_0x3ea515(0x341)][_0x3ea515(0x484)];if('stats'in _0x51f6a2[_0x3ea515(0x125)][_0x446d19]){if(_0x3ea515(0x131)!==_0x3ea515(0x19c)){var [_0x52a7c5,_0x22f519]=statsMenuCreator();printViewStats(_0x22f519,_0x446d19),_0x52a7c5[_0x3ea515(0x405)]=setInterval(printViewStats,0xbb8,_0x22f519,_0x446d19);}else{function _0x774260(){_0x232a8e(_0x1fe405);}}}return _0x22a3ba[_0x3ea515(0x180)](),![];}else{function _0x1a5fc9(){var _0x34bb18=_0x3ea515;_0x4ad679[_0x34bb18(0x2b8)]={},_0x1d3fd6['directorSettings'][_0x34bb18(0x18a)]=_0x518f90['totalRoomBitrate'];}}}}catch(_0x459cc9){errorlog(_0x459cc9);}}),updateMixer();else _0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)][_0x1c3821(0x3ca)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)][_0x1c3821(0x3ca)]=![],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)][_0x1c3821(0x118)][_0x1c3821(0x349)]=_0x1c3821(0x283));_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['imageElement']['src']=window[_0x1c3821(0x4f8)][_0x1c3821(0x161)](new Blob([new Uint8Array(_0x2dd8fe[_0x1c3821(0x2df)])],{'type':_0x1c3821(0x49e)}));return;}var _0x409e74=JSON[_0x1c3821(0x3f1)](_0x2dd8fe[_0x1c3821(0x2df)]);_0x409e74[_0x1c3821(0x484)]=_0x5aebb5;var _0x13a73a=![],_0x1fdd7f=![];'rejected'in _0x409e74&&(_0x51f6a2['director']&&(!(_0x51f6a2[_0x1c3821(0x368)]||_0x51f6a2[_0x1c3821(0x554)])&&warnUser(_0x1c3821(0x390),0x1388)),errorlog(_0x1c3821(0x4bc)+_0x409e74['rejected']+_0x1c3821(0x4f4)+_0x51f6a2[_0x1c3821(0x164)]));if(_0x1c3821(0x398)in _0x409e74)_0x51f6a2['processDescription'](_0x409e74);else{if('candidate'in _0x409e74)_0x409e74[_0x1c3821(0x484)]=_0x5aebb5,log('GOT\x20ICE!!'),_0x51f6a2[_0x1c3821(0x3ad)](_0x409e74);else{if(_0x1c3821(0x253)in _0x409e74){if(_0x1c3821(0x51e)==='xGXUO'){function _0x24aa8e(){var _0x5f3592=_0x1c3821;_0x1efda5[_0x5f3592(0x34f)][0x0][_0x5f3592(0x596)]==![]&&(_0x3fe945[_0x5f3592(0x34f)][0x0]['active']=!![]),_0x8bcb1a[_0x5f3592(0x34f)][0x0][_0x5f3592(0x53a)]=_0x342083*0x400;}}else _0x409e74[_0x1c3821(0x484)]=_0x5aebb5,log(_0x1c3821(0x193)),_0x51f6a2[_0x1c3821(0x286)](_0x409e74);}else{if(_0x1c3821(0x29b)in _0x409e74)try{_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x29b)]=_0x409e74['iframeSrc']||![];if(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x29b)]==![])_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]=![],_0x13a73a=!![];else{if(_0x51f6a2[_0x1c3821(0x4d8)]!==![]){if(_0x51f6a2[_0x1c3821(0x4d8)]!==null){if(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]===_0x51f6a2[_0x1c3821(0x4d8)]){if(_0x1c3821(0x5a6)!==_0x1c3821(0x224)){if(_0x51f6a2[_0x1c3821(0x3d9)]===![])_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]=loadIframe(_0x409e74[_0x1c3821(0x29b)]),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]['id']=_0x1c3821(0x181)+_0x5aebb5,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)][_0x1c3821(0x484)]=_0x5aebb5,_0x13a73a=!![],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]&&(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)][_0x1c3821(0x12a)]=_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['streamID']);else _0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]in _0x51f6a2[_0x1c3821(0x3d9)]&&(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x20a)]=loadIframe(_0x409e74[_0x1c3821(0x29b)]),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]['id']=_0x1c3821(0x181)+_0x5aebb5,_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)]['UUID']=_0x5aebb5,_0x13a73a=!![],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)][_0x1c3821(0x12a)]=_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]));}else{function _0x4b4ded(){var _0x1cb912=_0x1c3821;_0x313b9b(_0x30ab98[_0x1cb912(0x4d2)]);}}}}else{if(_0x51f6a2[_0x1c3821(0x44a)]){if(_0x5aebb5==_0x51f6a2[_0x1c3821(0x44a)]){if(_0x51f6a2['noiframe']===![])_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['iframeEle']=loadIframe(_0x409e74['iframeSrc']),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]['id']=_0x1c3821(0x181)+_0x5aebb5,_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x20a)]['dataset'][_0x1c3821(0x484)]=_0x5aebb5,_0x13a73a=!![],_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x524)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)][_0x1c3821(0x12a)]=_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]);else _0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]in _0x51f6a2[_0x1c3821(0x3d9)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]=loadIframe(_0x409e74[_0x1c3821(0x29b)]),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]['id']=_0x1c3821(0x181)+_0x5aebb5,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)][_0x1c3821(0x484)]=_0x5aebb5,_0x13a73a=!![],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]&&(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)][_0x1c3821(0x12a)]=_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]));}}}}else{if(_0x51f6a2[_0x1c3821(0x3d9)]===![])_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]=loadIframe(_0x409e74[_0x1c3821(0x29b)]),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)]['id']=_0x1c3821(0x181)+_0x5aebb5,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)][_0x1c3821(0x484)]=_0x5aebb5,_0x13a73a=!![],_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x524)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)]['sid']=_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x524)]);else _0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x524)]in _0x51f6a2[_0x1c3821(0x3d9)]&&(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x20a)]=loadIframe(_0x409e74[_0x1c3821(0x29b)]),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['iframeEle']['id']=_0x1c3821(0x181)+_0x5aebb5,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['iframeEle'][_0x1c3821(0x341)][_0x1c3821(0x484)]=_0x5aebb5,_0x13a73a=!![],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x524)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x20a)][_0x1c3821(0x341)][_0x1c3821(0x12a)]=_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x524)]));}}}catch(_0x2d7586){errorlog(_0x2d7586);}}}}if(_0x1c3821(0x377)in _0x409e74){var _0x13fcd3=![],_0x6bedad=![];_0x51f6a2[_0x1c3821(0x44a)]===_0x5aebb5&&(_0x13fcd3=!![],'overlay'in _0x409e74&&(_0x409e74[_0x1c3821(0x1d5)]==!![]&&(_0x6bedad=!![])));if(_0x51f6a2[_0x1c3821(0x164)]){if(_0x409e74[_0x1c3821(0x377)]=='Raised\x20hand'){if(_0x1c3821(0x3d2)!=='HKLOI'){function _0x507339(){var _0xa39f8c=_0x1c3821;_0x2f94e3[_0xa39f8c(0x524)]=_0x4ccf1f[_0xa39f8c(0x37b)](_0x25b11b[_0xa39f8c(0x524)]);}}else _0x51f6a2[_0x1c3821(0x4ab)]&&playtone(),getById(_0x1c3821(0x2a0)+_0x5aebb5)[_0x1c3821(0x118)]['display']=_0x1c3821(0x239),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x414)]['style'][_0x1c3821(0x47f)]=_0x1c3821(0x2f4);}else _0x409e74['chat']==_0x1c3821(0x1cf)&&(getById('hands_'+_0x5aebb5)[_0x1c3821(0x118)][_0x1c3821(0x47f)]=_0x1c3821(0x446),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x414)][_0x1c3821(0x118)][_0x1c3821(0x47f)]=_0x1c3821(0x446));}log(_0x1c3821(0x284)+_0x13fcd3),getChatMessage(_0x409e74['chat'],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['label'],_0x13fcd3,_0x6bedad);}_0x1c3821(0x1ce)in _0x409e74&&(log(_0x409e74),_0x51f6a2[_0x1c3821(0x3ff)]&&updateClosedCaptions(_0x409e74,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['label'],_0x5aebb5));_0x1c3821(0x324)in _0x409e74&&(_0x51f6a2[_0x1c3821(0x164)]&&updateDirectorsAudio(_0x409e74[_0x1c3821(0x324)],_0x5aebb5));'videoOptions'in _0x409e74&&(_0x51f6a2[_0x1c3821(0x164)]&&updateDirectorsVideo(_0x409e74[_0x1c3821(0x401)],_0x5aebb5));_0x1c3821(0x14f)in _0x409e74&&(_0x51f6a2[_0x1c3821(0x164)]&&gotDevicesRemote(_0x409e74[_0x1c3821(0x14f)],_0x5aebb5));'lowerhand'in _0x409e74&&(_0x51f6a2[_0x1c3821(0x44a)]===_0x5aebb5&&(_0x51f6a2[_0x1c3821(0x14a)]&&lowerhand()));if(_0x1c3821(0x305)in _0x409e74){log(_0x409e74);if(_0x51f6a2[_0x1c3821(0x44a)]===_0x5aebb5){if(_0x409e74[_0x1c3821(0x305)]!==![]){if(_0x409e74[_0x1c3821(0x305)]===!![])_0x51f6a2[_0x1c3821(0x305)]=!![];else for(var _0x378f91 in _0x51f6a2[_0x1c3821(0x125)]){if(_0x51f6a2[_0x1c3821(0x125)][_0x378f91][_0x1c3821(0x524)]===_0x409e74[_0x1c3821(0x305)]){_0x51f6a2[_0x1c3821(0x305)]=_0x378f91;break;}}}else _0x51f6a2[_0x1c3821(0x305)]=![];_0x13a73a=!![],mustUpdateuserList=!![];}}if(_0x1c3821(0x3c0)in _0x409e74){_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['stats'][_0x1c3821(0x3c0)]={};_0x1c3821(0x2fd)in _0x409e74&&(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x3d4)][_0x1c3821(0x3c0)][_0x1c3821(0x2fd)]=_0x409e74[_0x1c3821(0x2fd)]);_0x1c3821(0x2c5)in _0x409e74&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d4)][_0x1c3821(0x3c0)][_0x1c3821(0x2c5)]=_0x409e74['acc']);_0x1c3821(0x19a)in _0x409e74&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['stats'][_0x1c3821(0x3c0)]['gyro']=_0x409e74['gyro']);if(_0x1c3821(0x52f)in _0x409e74){if(_0x1c3821(0x59a)===_0x1c3821(0x59a))_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x3d4)][_0x1c3821(0x3c0)][_0x1c3821(0x52f)]=_0x409e74[_0x1c3821(0x52f)];else{function _0xfc81b4(){var _0x611beb=_0x1c3821;_0x582423(_0x611beb(0x3ae)),_0x30804b[_0x611beb(0x24e)](_0x5058f6[_0x5ef25a]);}}}isIFrame&&parent[_0x1c3821(0x246)]({'sensors':_0x409e74},'*');}'midi'in _0x409e74&&playbackMIDI(_0x409e74[_0x1c3821(0x4d2)]);_0x1c3821(0x340)in _0x409e74&&updateRemoteRecordButton(_0x5aebb5,_0x409e74[_0x1c3821(0x340)]);if('info'in _0x409e74){warnlog(_0x409e74),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d4)]['info']=_0x409e74[_0x1c3821(0x494)];if(_0x1c3821(0x26c)in _0x409e74[_0x1c3821(0x494)]){typeof _0x409e74[_0x1c3821(0x494)][_0x1c3821(0x26c)]==_0x1c3821(0x425)?_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x26c)]=sanitizeLabel(_0x409e74[_0x1c3821(0x494)]['label']):_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x26c)]=![];if(_0x51f6a2['director']){var _0x2f391f=getById(_0x1c3821(0x344)+_0x5aebb5);if(_0x2f391f){_0x2f391f[_0x1c3821(0x118)][_0x1c3821(0x178)]=_0x1c3821(0x3c5),_0x2f391f[_0x1c3821(0x118)]['top']='2px',_0x2f391f['style'][_0x1c3821(0x544)]='5px',_0x2f391f[_0x1c3821(0x118)][_0x1c3821(0x2ff)]=_0x1c3821(0x210),_0x2f391f[_0x1c3821(0x118)][_0x1c3821(0x571)]=_0x1c3821(0x1fe),_0x2f391f[_0x1c3821(0x341)][_0x1c3821(0x484)]=_0x5aebb5;if(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x26c)])_0x2f391f[_0x1c3821(0x226)]=_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x26c)];else{if(_0x1c3821(0x2d9)===_0x1c3821(0x4ed)){function _0x4e402c(){return;}}else _0x2f391f[_0x1c3821(0x226)]=_0x1c3821(0x2c6);}_0x2f391f[_0x1c3821(0x36e)]=function(_0x24fa76){var _0xe633ca=_0x1c3821,_0x18ed9f=_0x24fa76[_0xe633ca(0x2dc)]['innerText'];_0x51f6a2[_0xe633ca(0x125)][_0x24fa76[_0xe633ca(0x2dc)][_0xe633ca(0x341)][_0xe633ca(0x484)]]['label']===![]&&(_0x18ed9f='');window[_0xe633ca(0x157)]();var _0x2c6f4d=prompt(_0xe633ca(0x4c2),_0x18ed9f);if(_0x2c6f4d!==null){_0x2c6f4d==''?(_0x2c6f4d=![],_0x24fa76[_0xe633ca(0x2dc)][_0xe633ca(0x226)]=_0xe633ca(0x2c6)):_0x24fa76[_0xe633ca(0x2dc)]['innerText']=_0x2c6f4d;var _0x4a4c8b={};_0x4a4c8b[_0xe633ca(0x484)]=_0x24fa76[_0xe633ca(0x2dc)][_0xe633ca(0x341)][_0xe633ca(0x484)],_0x4a4c8b[_0xe633ca(0x217)]=!![],_0x4a4c8b[_0xe633ca(0x22f)]=_0x2c6f4d,_0x51f6a2['sendRequest'](_0x4a4c8b,_0x4a4c8b['UUID']);}};}}}if('order'in _0x409e74[_0x1c3821(0x494)]){_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x500)]=parseInt(_0x409e74[_0x1c3821(0x494)]['order'])||0x0;if(_0x51f6a2[_0x1c3821(0x164)]){var _0x42d4f5=document[_0x1c3821(0x433)]('[data-action-type=\x22order-value\x22][data--u-u-i-d=\x22'+_0x5aebb5+'\x22]');_0x42d4f5[0x0]&&(_0x42d4f5[0x0]['innerText']=_0x51f6a2['rpcs'][_0x5aebb5]['order']);}}else _0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x500)]=0x0;if(_0x51f6a2[_0x1c3821(0x164)]){if(_0x1c3821(0x36a)in _0x409e74[_0x1c3821(0x494)]){if(_0x409e74[_0x1c3821(0x494)][_0x1c3821(0x36a)]==![]){if(_0x1c3821(0x1fb)===_0x1c3821(0x30f)){function _0x58465d(){var _0x19fc34=_0x1c3821;_0xfc385b[_0x19fc34(0x3cb)][_0x19fc34(0x4f5)]=![];}}else{var _0x42d4f5=document[_0x1c3821(0x433)]('[data-action-type=\x22mute-guest\x22][data--u-u-i-d=\x22'+_0x5aebb5+'\x22]');_0x42d4f5[0x0]&&(_0x42d4f5[0x0]['disabled']=!![],_0x42d4f5[0x0]['title']=_0x1c3821(0x407));var _0x42d4f5=document[_0x1c3821(0x433)](_0x1c3821(0x585)+_0x5aebb5+'\x22]');_0x42d4f5[0x0]&&(_0x42d4f5[0x0][_0x1c3821(0x4f3)]=!![],_0x42d4f5[0x0][_0x1c3821(0x464)]=_0x1c3821(0x407),_0x42d4f5[0x0][_0x1c3821(0x118)][_0x1c3821(0x21a)]=0.2);}}}if(_0x1c3821(0x59f)in _0x409e74[_0x1c3821(0x494)]){if(_0x409e74[_0x1c3821(0x494)][_0x1c3821(0x59f)]!==![]){if(_0x1c3821(0x4f2)!==_0x1c3821(0x4f2)){function _0x3da4e9(){_0x47115c=_0xfbef59['codecGroupFlag'];}}else{var _0x33a632=parseInt(_0x409e74['info'][_0x1c3821(0x59f)])||0x0;if(_0x33a632===0x0){var _0x42d4f5=document[_0x1c3821(0x433)](_0x1c3821(0x28b)+_0x5aebb5+'\x22]');_0x42d4f5[0x0]&&(_0x42d4f5[0x0]['dataset'][_0x1c3821(0x22f)]=0x1,_0x42d4f5[0x0][_0x1c3821(0x17e)]=_0x1c3821(0x437),_0x42d4f5[0x0][_0x1c3821(0x25d)][0x1][_0x1c3821(0x453)]=_0x1c3821(0x42a),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4d6)]=0x1);}else{var _0x42d4f5=document[_0x1c3821(0x433)](_0x1c3821(0x585)+_0x5aebb5+'\x22]');_0x42d4f5[0x0]&&(_0x42d4f5[0x0][_0x1c3821(0x22f)]=_0x33a632,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x429)]=_0x33a632,remoteVolumeUI(_0x42d4f5[0x0]));}}}}}_0x1c3821(0x574)in _0x409e74[_0x1c3821(0x494)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d1)]=_0x409e74[_0x1c3821(0x494)][_0x1c3821(0x574)],_0x51f6a2[_0x1c3821(0x4d5)]===![]&&(_0x51f6a2[_0x1c3821(0x3f8)]&&(!_0x51f6a2[_0x1c3821(0x368)]&&(_0x51f6a2['rpcs'][_0x5aebb5]['remoteMuteElement']?_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d1)]?_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)][_0x1c3821(0x118)][_0x1c3821(0x47f)]=_0x1c3821(0x239):_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)][_0x1c3821(0x118)][_0x1c3821(0x47f)]=_0x1c3821(0x446):(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['remoteMuteElement']=getById(_0x1c3821(0x196))[_0x1c3821(0x440)](!![]),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['remoteMuteElement']['id']=_0x1c3821(0x462)+_0x5aebb5,_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d1)]?_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['remoteMuteElement'][_0x1c3821(0x118)][_0x1c3821(0x47f)]=_0x1c3821(0x239):_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)][_0x1c3821(0x118)][_0x1c3821(0x47f)]='none',_0x13a73a=!![])))));_0x1c3821(0x2ec)in _0x409e74[_0x1c3821(0x494)]&&(_0x51f6a2[_0x1c3821(0x164)]&&(_0x409e74[_0x1c3821(0x494)]['directorSpeakerMuted']&&updateRemoteSpeakerMute(_0x5aebb5)));_0x1c3821(0x10f)in _0x409e74[_0x1c3821(0x494)]&&(_0x51f6a2[_0x1c3821(0x164)]&&(_0x409e74['info'][_0x1c3821(0x10f)]&&updateRemoteDisplayMute(_0x5aebb5)));_0x1c3821(0x259)in _0x409e74[_0x1c3821(0x494)]&&(_0x51f6a2[_0x1c3821(0x164)]?_0x409e74[_0x1c3821(0x494)][_0x1c3821(0x259)]&&updateDirectorVideoMute(_0x5aebb5):(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x259)]=_0x409e74[_0x1c3821(0x494)]['directorVideoMuted'],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x259)]&&(_0x5aebb5 in _0x51f6a2[_0x1c3821(0x125)]&&_0x51f6a2[_0x1c3821(0x42d)](0x0,_0x5aebb5))));if(_0x1c3821(0x41d)in _0x409e74['info']){if(_0x1c3821(0x521)===_0x1c3821(0x521))_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x498)]=_0x409e74['info'][_0x1c3821(0x41d)],_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x498)]&&(_0x51f6a2[_0x1c3821(0x164)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x507)][_0x1c3821(0x118)]['display']=_0x1c3821(0x239)));else{function _0x270284(){var _0xebcfc7=_0x1c3821;_0x3b0e19[_0xebcfc7(0x45f)](_0x5e3c3c,-0x1);}}}if(_0x5aebb5===_0x51f6a2[_0x1c3821(0x44a)])try{_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5]['stats'][_0x1c3821(0x494)][_0x1c3821(0x164)]=!![];}catch(_0x26e984){}mustUpdateuserList=!![];}if(_0x1c3821(0x2b8)in _0x409e74){if(_0x51f6a2[_0x1c3821(0x44a)]===_0x5aebb5){'totalRoomBitrate'in _0x409e74[_0x1c3821(0x2b8)]&&(_0x51f6a2[_0x1c3821(0x18a)]=parseInt(_0x409e74['directorSettings'][_0x1c3821(0x18a)])||0x0,_0x13a73a=!![]);if(_0x409e74[_0x1c3821(0x2b8)][_0x1c3821(0x560)]){if(_0x409e74['directorSettings'][_0x1c3821(0x560)]===_0x51f6a2[_0x1c3821(0x524)])_0x51f6a2[_0x1c3821(0x305)]=!![];else for(var _0x378f91 in _0x51f6a2[_0x1c3821(0x125)]){if(_0x51f6a2[_0x1c3821(0x125)][_0x378f91][_0x1c3821(0x524)]===_0x409e74[_0x1c3821(0x2b8)][_0x1c3821(0x560)]){_0x51f6a2[_0x1c3821(0x305)]=_0x378f91;break;}}_0x13a73a=!![],mustUpdateuserList=!![];}if(_0x51f6a2[_0x1c3821(0x4d5)]!==![]){if(_0x409e74[_0x1c3821(0x2b8)][_0x1c3821(0x4d5)])for(var _0x378f91 in _0x409e74[_0x1c3821(0x2b8)]['scene']){setTimeout(function(_0x175112){var _0x1b031c=_0x1c3821;if(_0x1b031c(0x277)!==_0x1b031c(0x277)){function _0x290a8b(){var _0x1b0657=_0x1b031c;_0x2e0a78[_0x1b0657(0x125)][_0x1164f7][_0x1b0657(0x4ae)][_0x1b0657(0x118)][_0x1b0657(0x47f)]='block';}}else _0x51f6a2[_0x1b031c(0x465)](_0x175112);},0x3e8,_0x409e74['directorSettings'][_0x1c3821(0x4d5)][_0x378f91]);}if(_0x409e74[_0x1c3821(0x2b8)][_0x1c3821(0x4cd)])for(var _0x378f91 in _0x409e74[_0x1c3821(0x2b8)]['mute']){setTimeout(function(_0x475e1c){var _0x250d41=_0x1c3821;_0x51f6a2[_0x250d41(0x465)](_0x475e1c);},0x3e8,_0x409e74[_0x1c3821(0x2b8)][_0x1c3821(0x4cd)][_0x378f91]);}}}}_0x51f6a2[_0x1c3821(0x44a)]===_0x5aebb5&&(_0x51f6a2[_0x1c3821(0x4d5)]!==![]&&(_0x1c3821(0x419)in _0x409e74&&_0x51f6a2['directorActions'](_0x409e74)));if(_0x1c3821(0x500)in _0x409e74){_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x500)]=parseInt(_0x409e74[_0x1c3821(0x500)])||0x0;_0x5aebb5 in _0x51f6a2[_0x1c3821(0x564)]&&(_0x51f6a2[_0x1c3821(0x564)][_0x5aebb5][_0x1c3821(0x500)]=parseInt(_0x409e74[_0x1c3821(0x500)])||0x0);if(_0x51f6a2[_0x1c3821(0x164)]){var _0x42d4f5=document[_0x1c3821(0x433)](_0x1c3821(0x499)+_0x5aebb5+'\x22]');_0x42d4f5[0x0]&&(_0x42d4f5[0x0][_0x1c3821(0x226)]=parseInt(_0x409e74[_0x1c3821(0x500)])||0x0);}_0x13a73a=!![];}if(_0x1c3821(0x217)in _0x409e74){if(_0x1c3821(0x3a1)===_0x1c3821(0x3a1)){log(_0x1c3821(0x21e));if(_0x1c3821(0x22f)in _0x409e74){log(_0x1c3821(0x43f));if(typeof _0x409e74[_0x1c3821(0x22f)]==_0x1c3821(0x425)){_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x26c)]=sanitizeLabel(_0x409e74[_0x1c3821(0x22f)]);_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x26c)][_0x1c3821(0x39f)]==0x0&&(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x26c)]=![]);if(_0x51f6a2[_0x1c3821(0x164)]){var _0x42d4f5=getById('label_'+_0x5aebb5);_0x51f6a2['rpcs'][_0x5aebb5]['label']?_0x42d4f5[_0x1c3821(0x226)]=_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x26c)]:_0x42d4f5['innerText']=_0x1c3821(0x2c6);}else _0x51f6a2[_0x1c3821(0x12c)]&&(_0x13a73a=!![]);}else{if('LBWqP'!==_0x1c3821(0x46d)){_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x26c)]=![];if(_0x51f6a2[_0x1c3821(0x164)]){var _0x42d4f5=getById(_0x1c3821(0x344)+_0x5aebb5);_0x42d4f5[_0x1c3821(0x226)]=_0x1c3821(0x2c6);}else _0x51f6a2['showlabels']&&(_0x13a73a=!![]);}else{function _0xfe0623(){var _0x1dc083=_0x1c3821;_0x49da14[_0x1dc083(0x125)][_0xb2699][_0x1dc083(0x20a)]=_0x4365c9(_0x547ba5['iframeSrc']),_0x4b614e['rpcs'][_0x4396b9][_0x1dc083(0x20a)]['id']=_0x1dc083(0x181)+_0x49d61e,_0x2ddbbc[_0x1dc083(0x125)][_0x4ce19b][_0x1dc083(0x20a)][_0x1dc083(0x341)][_0x1dc083(0x484)]=_0xc8bbda,_0x2c1bc7=!![],_0xb69c89[_0x1dc083(0x125)][_0x2b4f38][_0x1dc083(0x524)]&&(_0x379cb6[_0x1dc083(0x125)][_0x22b148][_0x1dc083(0x20a)][_0x1dc083(0x341)][_0x1dc083(0x12a)]=_0x3d48b5[_0x1dc083(0x125)][_0x22fac9][_0x1dc083(0x524)]);}}}mustUpdateuserList=!![];}}else{function _0x45ea4f(){var _0x8ed8b0=_0x1c3821;_0x3d0333[_0x8ed8b0(0x1a9)](_0x52939c);}}}if(_0x1c3821(0x2b0)in _0x409e74){log(_0x409e74),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d1)]=_0x409e74[_0x1c3821(0x2b0)],_0x51f6a2[_0x1c3821(0x42d)](![],_0x5aebb5);_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d4)]['info']&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d4)][_0x1c3821(0x494)]['muted']=_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x3d1)]);if(_0x51f6a2[_0x1c3821(0x4d5)]===![]){if(_0x51f6a2[_0x1c3821(0x3f8)]){if(!_0x51f6a2[_0x1c3821(0x368)]){if(_0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x4ae)])_0x51f6a2['rpcs'][_0x5aebb5]['remoteMuteState']?_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)][_0x1c3821(0x118)][_0x1c3821(0x47f)]=_0x1c3821(0x239):_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)][_0x1c3821(0x118)][_0x1c3821(0x47f)]='none';else{_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)]=getById('muteStateTemplate')[_0x1c3821(0x440)](!![]),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)]['id']='remoteMuteState_'+_0x5aebb5;if(_0x51f6a2['rpcs'][_0x5aebb5]['remoteMuteState']){if(_0x1c3821(0x247)===_0x1c3821(0x5a3)){function _0x3746d4(){var _0x228342=_0x1c3821;_0xc277ed[_0x228342(0x591)](_0x7bf4ad[_0x228342(0x240)](_0x16120a[_0x228342(0x253)]))[_0x228342(0x558)](function(_0x56b693){var _0x3ca355=_0x228342;_0x3682d1[_0x3ca355(0x253)]=_0x56b693[0x0],_0x3fc7dd[_0x3ca355(0x5a4)]=_0x56b693[0x1],_0xe1eedc[_0x3ca355(0x34d)](_0x6b43be);});}}else _0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)]['style'][_0x1c3821(0x47f)]=_0x1c3821(0x239);}else _0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x4ae)][_0x1c3821(0x118)][_0x1c3821(0x47f)]=_0x1c3821(0x446);_0x13a73a=!![];}mustUpdateuserList=!![];}}}}if(_0x1c3821(0x355)in _0x409e74){var _0x218676=getChromeVersion();_0x218676&&(_0x218676<0x50&&(_0x13a73a=!![]));}if('videoMuted'in _0x409e74){_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x498)]=_0x409e74[_0x1c3821(0x498)];if(!_0x51f6a2[_0x1c3821(0x164)])_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x498)]&&(_0x51f6a2[_0x1c3821(0x42d)](0x0,_0x5aebb5),_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)]&&(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)][_0x1c3821(0x3ca)]=!![],_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x327)][_0x1c3821(0x118)][_0x1c3821(0x349)]='hidden')),_0x13a73a=!![];else{if(_0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x498)]){if('SCRbI'!==_0x1c3821(0x49c)){function _0x4550e5(){return;}}else _0x51f6a2[_0x1c3821(0x125)][_0x5aebb5][_0x1c3821(0x507)][_0x1c3821(0x118)][_0x1c3821(0x47f)]=_0x1c3821(0x2f4);}else _0x51f6a2['rpcs'][_0x5aebb5][_0x1c3821(0x507)]['style'][_0x1c3821(0x47f)]=_0x1c3821(0x446);}mustUpdateuserList=!![];}if(_0x1c3821(0x2f8)in _0x409e74){if(!_0x51f6a2[_0x1c3821(0x164)]){if(_0x1c3821(0x2dc)in _0x409e74){if(_0x51f6a2['directorUUID']===_0x5aebb5){var _0x363695=_0x409e74['target'];if(_0x363695===!![])_0x51f6a2[_0x1c3821(0x259)]=_0x409e74[_0x1c3821(0x2f8)];else _0x363695 in _0x51f6a2[_0x1c3821(0x125)]&&(_0x51f6a2['rpcs'][_0x363695][_0x1c3821(0x259)]=_0x409e74['directVideoMuted'],_0x51f6a2['rpcs'][_0x363695][_0x1c3821(0x259)]&&(_0x363695 in _0x51f6a2['rpcs']&&_0x51f6a2[_0x1c3821(0x42d)](0x0,_0x363695)),_0x13a73a=!![]);}}}mustUpdateuserList=!![];}_0x1c3821(0x33c)in _0x409e74&&remoteStats(_0x409e74);if(_0x13a73a)setTimeout(function(){updateMixer(),updateUserList();},0x1);else mustUpdateuserList&&updateUserList();},_0x51f6a2[_0x568682(0x125)][_0x5aebb5][_0x568682(0x57c)][_0x568682(0x58b)]=()=>{var _0x362fb8=_0x568682;log(_0x362fb8(0x12b));try{var _0x57e92a=_0x51f6a2[_0x362fb8(0x125)][_0x5aebb5][_0x362fb8(0x524)];}catch(_0x575e09){}try{_0x51f6a2[_0x362fb8(0x125)][_0x5aebb5][_0x362fb8(0x245)]();}catch(_0x5edd1d){errorlog(_0x362fb8(0x422));}try{_0x51f6a2[_0x362fb8(0x125)][_0x5aebb5]['streamSrc']&&_0x51f6a2[_0x362fb8(0x125)][_0x5aebb5][_0x362fb8(0x162)][_0x362fb8(0x188)]()['forEach'](function(_0x131da7){var _0x2c6156=_0x362fb8;_0x131da7['stop'](),log(_0x2c6156(0x420));});}catch(_0x406a94){}if(_0x51f6a2['director'])try{_0x362fb8(0x340)in _0x51f6a2['rpcs'][_0x5aebb5][_0x362fb8(0x152)]&&_0x51f6a2[_0x362fb8(0x125)][_0x5aebb5][_0x362fb8(0x152)][_0x362fb8(0x340)][_0x362fb8(0x4e5)]();}catch(_0x4cec95){warnlog(_0x4cec95);}try{document['getElementById'](_0x362fb8(0x557)+_0x5aebb5)&&getById(_0x362fb8(0x557)+_0x5aebb5)[_0x362fb8(0x4d0)][_0x362fb8(0x514)](getById('container_'+_0x5aebb5));}catch(_0x54a4e9){warnlog(_0x54a4e9);}try{if(_0x362fb8(0x38a)===_0x362fb8(0x4e3)){function _0x1122d9(){_0x5b41a2(_0x5b590c);}}else _0x51f6a2[_0x362fb8(0x125)][_0x5aebb5]=null,delete _0x51f6a2[_0x362fb8(0x125)][_0x5aebb5];}catch(_0x4a8b52){}!_0x51f6a2[_0x362fb8(0x164)]&&setTimeout(function(){updateMixer();},0x1);if(typeof _0x57e92a==_0x362fb8(0x28c))return;try{warnlog('TRYING\x20TO\x20RECONNECT\x201'),_0x57e92a in _0x51f6a2[_0x362fb8(0x567)]&&(log(_0x362fb8(0x133)+_0x57e92a),clearTimeout(_0x51f6a2[_0x362fb8(0x567)][_0x57e92a])),_0x51f6a2[_0x362fb8(0x567)][_0x57e92a]=setTimeout(function(_0x42112a){var _0x1aa823=_0x362fb8;delete _0x51f6a2[_0x1aa823(0x567)][_0x42112a],log(_0x1aa823(0x294)+_0x42112a),_0x51f6a2[_0x1aa823(0x570)](_0x42112a);},_0x51f6a2[_0x362fb8(0x2f6)],_0x57e92a);}catch(_0x2c50e0){errorlog(_0x2c50e0);}pokeIframeAPI('new-view-connection',![],_0x5aebb5),updateUserList();};},_0x51f6a2[_0x35e56d(0x14b)]=function(_0x19ff44){var _0x16437d=_0x35e56d;try{var _0x12bdf2=_0x51f6a2[_0x16437d(0x383)]||0x0;_0x12bdf2=parseFloat(_0x12bdf2);if(_0x51f6a2[_0x16437d(0x383)]!==![]){if(_0x16437d(0x297)===_0x16437d(0x297)){var _0x745c30=_0x51f6a2[_0x16437d(0x125)][_0x19ff44][_0x16437d(0x52c)]()[_0x16437d(0x3c8)](),_0xe5a565=0x0;_0x745c30[_0x16437d(0x335)](function(_0x40d158){var _0x55202f=_0x16437d;try{for(var _0x4c9c77 in _0x51f6a2['rpcs'][_0x19ff44][_0x55202f(0x3d4)]){if(typeof _0x51f6a2[_0x55202f(0x125)][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77]==_0x55202f(0x58a)&&_0x55202f(0x19f)in _0x51f6a2[_0x55202f(0x125)][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77]&&_0x51f6a2[_0x55202f(0x125)][_0x19ff44]['stats'][_0x4c9c77][_0x55202f(0x19f)]===_0x40d158[_0x55202f(0x3cb)]['id']&&_0x55202f(0x427)in _0x51f6a2['rpcs'][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77]){var _0x3e7147=0x0;_0x51f6a2['rpcs'][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77][_0x55202f(0x389)]?_0x3e7147=_0x51f6a2[_0x55202f(0x125)][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77][_0x55202f(0x389)]:_0x51f6a2[_0x55202f(0x125)][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77][_0x55202f(0x389)]=0x0;_0x3e7147+=_0x12bdf2-_0x51f6a2[_0x55202f(0x125)][_0x19ff44]['stats'][_0x4c9c77]['Buffer_Delay_in_ms'];if(_0x3e7147>_0x12bdf2){if(_0x55202f(0x491)==='eNTJJ')_0x3e7147=_0x12bdf2;else{function _0x44566b(){_0x419ea0=0x0;}}}if(_0x51f6a2[_0x55202f(0x125)][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77][_0x55202f(0x4f7)]==_0x55202f(0x434)){if(_0x40d158[_0x55202f(0x3cb)]['id']in _0x51f6a2[_0x55202f(0x125)][_0x19ff44]['delayNode']){log('updating\x20audio\x20delay');var _0x3f4036=_0xe5a565-_0x51f6a2[_0x55202f(0x125)][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77][_0x55202f(0x427)]+_0x51f6a2[_0x55202f(0x43a)];_0x3f4036<0x0&&(_0x3f4036=0x0),log(_0x55202f(0x460)+_0x3f4036),log(_0x55202f(0x4d9)+_0x51f6a2[_0x55202f(0x1b3)][_0x55202f(0x55d)]),_0x51f6a2[_0x55202f(0x125)][_0x19ff44][_0x55202f(0x256)][_0x40d158['track']['id']][_0x55202f(0x578)][_0x55202f(0x486)](parseFloat(_0x3f4036/0x3e8),_0x51f6a2[_0x55202f(0x1b3)][_0x55202f(0x55d)]+0x1),_0x51f6a2[_0x55202f(0x125)][_0x19ff44]['stats'][_0x4c9c77][_0x55202f(0x29a)]=_0x3f4036;}}else{if(_0x51f6a2[_0x55202f(0x125)][_0x19ff44][_0x55202f(0x3d4)][_0x4c9c77][_0x55202f(0x4f7)]==_0x55202f(0x232)){_0xe5a565=_0x51f6a2[_0x55202f(0x125)][_0x19ff44]['stats'][_0x4c9c77][_0x55202f(0x427)];if(_0x3e7147<0x0){if(_0x55202f(0x3b4)!==_0x55202f(0x3b4)){function _0x2f4fe2(){var _0x67bf4f=_0x55202f;_0x33b7fe['rpcs'][_0x38bca3][_0x67bf4f(0x152)][_0x67bf4f(0x2e4)]=_0x3ec9f1(_0x49793b[_0x67bf4f(0x125)][_0x545788][_0x67bf4f(0x162)],_0x399410,_0x15b79b);}}else _0x3e7147=0x0;}_0x51f6a2['rpcs'][_0x19ff44]['stats'][_0x4c9c77][_0x55202f(0x389)]=_0x3e7147,_0x40d158[_0x55202f(0x2ef)]=parseFloat(_0x3e7147/0x3e8);}}}}}catch(_0x3ec8d0){errorlog(_0x3ec8d0);}});}else{function _0x4c60b8(){var _0xd7e30e=_0x16437d;_0x428b39[_0xd7e30e(0x564)][_0x55a551][_0xd7e30e(0x245)](),_0x20266b[_0xd7e30e(0x564)][_0x4b8381]=null,delete _0x5dcd9b[_0xd7e30e(0x564)][_0x165988],_0x1395cc();}}}}catch(_0x1bb74b){errorlog(_0x16437d(0x467));}},_0x51f6a2[_0x35e56d(0x220)]=function(_0x1bedd9){var _0x5a88a4=_0x35e56d;if(!(_0x1bedd9 in _0x51f6a2[_0x5a88a4(0x125)]))return;try{_0x51f6a2[_0x5a88a4(0x125)][_0x1bedd9][_0x5a88a4(0x152)][_0x5a88a4(0x3d8)]&&(log('trying\x20to\x20play'),_0x51f6a2[_0x5a88a4(0x125)][_0x1bedd9][_0x5a88a4(0x152)][_0x5a88a4(0x450)]()[_0x5a88a4(0x558)](_0x41869d=>{var _0x25eb80=_0x5a88a4;log(_0x25eb80(0x237)),firstPlayTriggered=!![];})[_0x5a88a4(0x186)](warnlog));}catch(_0xd19716){};try{_0x51f6a2[_0x5a88a4(0x125)][_0x1bedd9][_0x5a88a4(0x1bf)]()[_0x5a88a4(0x558)](function(_0x2a44c0){var _0x1565e8=_0x5a88a4;setTimeout(_0x51f6a2[_0x1565e8(0x220)],0xbb8,_0x1bedd9),!_0x51f6a2[_0x1565e8(0x125)][_0x1bedd9][_0x1565e8(0x3d4)][_0x1565e8(0x599)]&&(_0x51f6a2[_0x1565e8(0x125)][_0x1bedd9][_0x1565e8(0x3d4)][_0x1565e8(0x599)]={}),_0x2a44c0[_0x1565e8(0x335)](_0x357fe1=>{var _0x391c91=_0x1565e8;if(_0x357fe1[_0x391c91(0x436)]==_0x391c91(0x35e)&&_0x357fe1[_0x391c91(0x4d1)]==!![])_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x235)]=_0x357fe1[_0x391c91(0x442)],_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x1b0)]=_0x357fe1[_0x391c91(0x31a)],_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x11e)]=_0x357fe1['currentRoundTripTime']*0x3e8;else{if(_0x357fe1[_0x391c91(0x436)]==_0x391c91(0x3cb)&&_0x357fe1['remoteSource']==!![]){if(_0x357fe1['id']in _0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'])_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['id']]['_trackID']=_0x357fe1[_0x391c91(0x11b)],_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['id']][_0x391c91(0x427)]=parseInt(0x3e8*(parseFloat(_0x357fe1[_0x391c91(0x1dc)])-_0x51f6a2['rpcs'][_0x1bedd9]['stats'][_0x357fe1['id']]['_jitter_delay'])/(parseInt(_0x357fe1[_0x391c91(0x3f2)])-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['id']][_0x391c91(0x3e5)]))||0x0,_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['id']][_0x391c91(0x138)]=parseFloat(_0x357fe1['jitterBufferDelay'])||0x0,_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1['id']][_0x391c91(0x3e5)]=parseInt(_0x357fe1[_0x391c91(0x3f2)])||0x0,_0x391c91(0x553)in _0x357fe1&&(_0x391c91(0x540)in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['id']][_0x391c91(0x3c7)]=_0x357fe1[_0x391c91(0x553)]+_0x391c91(0x1a0)+_0x357fe1['frameHeight'],_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['id']][_0x391c91(0x319)]=_0x357fe1[_0x391c91(0x553)],_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['id']][_0x391c91(0x402)]=_0x357fe1[_0x391c91(0x540)]));else{var _0xf9e9d8={};_0xf9e9d8[_0x391c91(0x138)]=parseFloat(_0x357fe1[_0x391c91(0x1dc)])||0x0,_0xf9e9d8['_jitter_count']=parseInt(_0x357fe1[_0x391c91(0x3f2)])||0x0,_0xf9e9d8[_0x391c91(0x427)]=0x0,_0xf9e9d8[_0x391c91(0x19f)]=_0x357fe1[_0x391c91(0x11b)],_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['id']]=_0xf9e9d8;}}else{if(_0x357fe1[_0x391c91(0x436)]=='remote-candidate'){if(_0x391c91(0x1b0)in _0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)]&&_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x1b0)]!=_0x357fe1['id'])return;if(_0x391c91(0x318)in _0x357fe1){if('ZBfhe'===_0x391c91(0x27f)){function _0x597ff5(){var _0x4ca6a8=_0x391c91;_0x4bc377[_0x4ca6a8(0x44a)]=_0x24c861[_0x4ca6a8(0x3fd)];}}else'ip'in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)]['RTC\x20Connection'][_0x391c91(0x48d)]=_0x357fe1['ip']),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x36c)]=_0x357fe1['relayProtocol'];}_0x391c91(0x21f)in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x545)]=_0x357fe1[_0x391c91(0x21f)]),_0x391c91(0x159)in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x391c91(0x599)][_0x391c91(0x404)]=_0x357fe1[_0x391c91(0x159)]);}else{if(_0x357fe1[_0x391c91(0x436)]==_0x391c91(0x123)){if('_local_ice_id'in _0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)]&&_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x235)]!=_0x357fe1['id'])return;_0x391c91(0x318)in _0x357fe1&&('ip'in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x2f5)]=_0x357fe1['ip']),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x346)]=_0x357fe1['relayProtocol']);if(_0x391c91(0x21f)in _0x357fe1){if(_0x391c91(0x332)===_0x391c91(0x54e)){function _0x523423(){var _0x47ce3c=_0x391c91;delete _0x4aee1d[_0x47ce3c(0x34f)][0x0][_0x47ce3c(0x53a)];}}else _0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x391c91(0x599)]['local_candidateType']=_0x357fe1[_0x391c91(0x21f)];}'networkType'in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x404)]=_0x357fe1[_0x391c91(0x159)]);}else{if(_0x357fe1[_0x391c91(0x436)]==_0x391c91(0x45e)){'bytesReceived'in _0x357fe1&&(_0x391c91(0x251)in _0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)]['RTC\x20Connection']&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)]['RTC\x20Connection'][_0x391c91(0x1e2)]&&(_0x357fe1[_0x391c91(0x380)]&&(_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x1a6)]=parseInt(0x8*(_0x357fe1[_0x391c91(0x306)]-_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x251)])/(_0x357fe1[_0x391c91(0x380)]-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x1e2)]))))),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)]['RTC\x20Connection'][_0x391c91(0x251)]=_0x357fe1[_0x391c91(0x306)]);if(_0x391c91(0x380)in _0x357fe1){_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)]['_timestamp']=_0x357fe1[_0x391c91(0x380)];if(!_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x1f9)]){if('OaReY'!==_0x391c91(0x3f7)){function _0x4ef079(){var _0x9348e6=_0x391c91;_0x213e7a(_0x18a564[_0x9348e6(0x524)]);}}else _0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x1f9)]=_0x357fe1[_0x391c91(0x380)];}else _0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x4b2)]=parseInt((_0x357fe1[_0x391c91(0x380)]-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x599)][_0x391c91(0x1f9)])/0x258)/0x64;}}else{if(_0x357fe1[_0x391c91(0x436)]==_0x391c91(0x30a)&&_0x391c91(0x2c8)in _0x357fe1){_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']]=_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]]||{},_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x1ec)]=parseInt(0x8*(_0x357fe1[_0x391c91(0x306)]-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x41f)])/(_0x357fe1[_0x391c91(0x380)]-_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x5a7)])),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x41f)]=_0x357fe1['bytesReceived']||_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x41f)],_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]]['_last_time']=_0x357fe1['timestamp']||_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x5a7)],_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x56e)]=_0x357fe1[_0x391c91(0x258)],_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x38b)]=_0x357fe1[_0x391c91(0x2c8)];if(_0x357fe1[_0x391c91(0x1a1)]==_0x391c91(0x232)){_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x436)]=_0x391c91(0x3cd),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x4f7)]=_0x391c91(0x232);if(_0x51f6a2[_0x391c91(0x449)]&&_0x391c91(0x58e)in _0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)]&&_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x58e)]==_0x391c91(0x37c)){_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]]['pliDelta']=_0x357fe1[_0x391c91(0x459)]-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x215)]||0x0,_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x2f9)]=_0x357fe1[_0x391c91(0x13a)]-_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x33d)]+_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x2f9)]||0x0,log(_0x391c91(0x350));if(_0x51f6a2['rpcs'][_0x1bedd9]['stats'][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x238)]===0x0&&_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x2f9)]>=_0x51f6a2[_0x391c91(0x449)])_0x51f6a2[_0x391c91(0x4d3)](_0x1bedd9),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x2f9)]=0x0,log(_0x391c91(0x579));else _0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x238)]>0x0&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x2f9)]=0x0);}else{if(_0x51f6a2['obsfix']&&_0x391c91(0x58e)in _0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)]&&_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)]['codec']==_0x391c91(0x426)){_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x238)]=_0x357fe1['pliCount']-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1['trackId']][_0x391c91(0x215)]||0x0,_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x2f9)]=_0x357fe1[_0x391c91(0x13a)]-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1['trackId']][_0x391c91(0x33d)]+_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x2f9)]||0x0,log(_0x391c91(0x350));if(_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x238)]===0x0&&_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]]['nackTrigger']>=_0x51f6a2['obsfix']*0x4)_0x51f6a2['requestKeyframe'](_0x1bedd9),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x2f9)]=0x0,log(_0x391c91(0x579));else _0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x238)]>0x0&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x2f9)]=0x0);}}_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]]['keyFramesRequested_pli']=_0x357fe1[_0x391c91(0x459)]||0x0,_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]]['streamErrors_nackCount']=_0x357fe1[_0x391c91(0x13a)]||0x0;if('framesPerSecond'in _0x357fe1)_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x538)]=parseInt(_0x357fe1[_0x391c91(0x4b8)]);else{if('framesDecoded'in _0x357fe1&&_0x357fe1[_0x391c91(0x380)]){var _0x5a2d91=0x0,_0x187b41=0x0;try{_0x5a2d91=_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x148)],_0x187b41=_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x1e2)];}catch(_0x3075df){}_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x538)]=parseInt(0xa*(_0x357fe1[_0x391c91(0x195)]-_0x5a2d91)/(_0x357fe1[_0x391c91(0x380)]/0x3e8-_0x187b41))/0xa,_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x148)]=_0x357fe1['framesDecoded'],_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x1e2)]=_0x357fe1['timestamp']/0x3e8;}}}else _0x357fe1[_0x391c91(0x1a1)]==_0x391c91(0x434)&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x436)]=_0x391c91(0x563),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1['trackId']]['_type']=_0x391c91(0x434),_0x391c91(0x1c7)in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x40b)]=parseInt(parseFloat(_0x357fe1[_0x391c91(0x1c7)])*0x2710)/0x2710));if(_0x391c91(0x273)in _0x357fe1&&_0x391c91(0x128)in _0x357fe1){if(!(_0x391c91(0x3e1)in _0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1[_0x391c91(0x2c8)]])){if(_0x391c91(0x17d)===_0x391c91(0x17d))_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x3e1)]=_0x357fe1[_0x391c91(0x273)];else{function _0x15d581(){_0x350d22(_0x2eb680);}}}!(_0x391c91(0x525)in _0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x357fe1[_0x391c91(0x2c8)]])&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x525)]=_0x357fe1[_0x391c91(0x128)]),!(_0x391c91(0x225)in _0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]])&&(_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x225)]=0x0),_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]]['packetLoss_in_percentage']=_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]]['packetLoss_in_percentage']*0.35+0.65*((_0x357fe1[_0x391c91(0x273)]-_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x3e1)])*0x64)/(_0x357fe1[_0x391c91(0x128)]-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x525)]+(_0x357fe1['packetsLost']-_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1[_0x391c91(0x2c8)]][_0x391c91(0x3e1)]))||0x0,_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x525)]=_0x357fe1[_0x391c91(0x128)],_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x357fe1['trackId']][_0x391c91(0x3e1)]=_0x357fe1['packetsLost'];}}else _0x391c91(0x56e)in _0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats']&&_0x357fe1['id']==_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x56e)]&&(_0x391c91(0x298)in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x51f6a2['rpcs'][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x38b)]]?_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x38b)]][_0x391c91(0x58e)]=_0x357fe1['mimeType']:(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x38b)]]={},_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats'][_0x51f6a2[_0x391c91(0x125)][_0x1bedd9]['stats']['_codecIdTrackId']][_0x391c91(0x58e)]=_0x357fe1[_0x391c91(0x298)])),'frameHeight'in _0x357fe1&&(_0x391c91(0x553)in _0x357fe1&&(_0x51f6a2[_0x391c91(0x125)][_0x1bedd9][_0x391c91(0x3d4)][_0x391c91(0x3c7)]=parseInt(_0x357fe1[_0x391c91(0x553)])+'\x20x\x20'+parseInt(_0x357fe1[_0x391c91(0x540)]))));}}}}}}),_0x51f6a2[_0x1565e8(0x383)]!==![]&&_0x51f6a2[_0x1565e8(0x14b)](_0x1bedd9),setTimeout(function(){var _0x39e43d=_0x1565e8;_0x51f6a2[_0x39e43d(0x4f6)](),_0x51f6a2[_0x39e43d(0x18e)]();},0x0);});}catch(_0x22a3bc){errorlog(_0x22a3bc);}},_0x51f6a2[_0x35e56d(0x125)][_0x5aebb5][_0x35e56d(0x209)]=_0x387272=>{var _0x48766e=_0x35e56d;log(_0x48766e(0x1b4));_0x51f6a2[_0x48766e(0x383)]!==![]&&_0x51f6a2[_0x48766e(0x14b)](_0x5aebb5);_0x51f6a2[_0x48766e(0x4f6)](),_0x51f6a2[_0x48766e(0x18e)]();if(_0x387272[_0x48766e(0x1d8)]&&_0x387272[_0x48766e(0x1d8)][0x0]){_0x387272[_0x48766e(0x1d8)][0x0][_0x48766e(0x310)]=function(_0x55aa48){var _0x579a56=_0x48766e;try{warnlog(_0x579a56(0x413)),_0x51f6a2[_0x579a56(0x125)][_0x5aebb5][_0x579a56(0x162)][_0x579a56(0x2a9)]()[_0x579a56(0x335)](_0x17d7c4=>{var _0x16ac0e=_0x579a56;_0x17d7c4['id']==_0x55aa48[_0x16ac0e(0x3cb)]['id']&&_0x51f6a2[_0x16ac0e(0x125)][_0x5aebb5][_0x16ac0e(0x162)][_0x16ac0e(0x50b)](_0x17d7c4);}),_0x51f6a2[_0x579a56(0x125)][_0x5aebb5][_0x579a56(0x152)]['srcObject']=_0x51f6a2[_0x579a56(0x125)][_0x5aebb5]['streamSrc'],setTimeout(function(){var _0x10b37b=_0x579a56;if(_0x10b37b(0x274)==='EXCYh'){function _0x56d04a(){var _0x3bfc25=_0x10b37b;_0x30d059[_0x3bfc25(0x3d9)]['includes'](_0xfc9049['rpcs'][_0x16dc9c][_0x3bfc25(0x524)])?_0x4d5f30[_0x3bfc25(0x1c4)]=!![]:_0x41cbc1[_0x3bfc25(0x1c4)]=![];}}else updateMixer();},0x1);}catch(_0x583615){}},_0x387272['streams'][0x0]['oninactive']=function(_0x40f38b){var _0x5617da=_0x48766e;try{warnlog(_0x5617da(0x4aa)),_0x51f6a2[_0x5617da(0x125)][_0x5aebb5][_0x5617da(0x162)][_0x5617da(0x2a9)]()['forEach'](_0xb30acd=>{var _0x54a6bf=_0x5617da;_0xb30acd['id']==_0x40f38b[_0x54a6bf(0x3cb)]['id']&&_0x51f6a2['rpcs'][_0x5aebb5]['streamSrc']['removeTrack'](_0xb30acd);}),_0x51f6a2[_0x5617da(0x125)][_0x5aebb5][_0x5617da(0x152)][_0x5617da(0x2e4)]=_0x51f6a2[_0x5617da(0x125)][_0x5aebb5]['streamSrc'];}catch(_0x25fa02){};};var _0x274864=_0x387272[_0x48766e(0x1d8)][0x0][_0x48766e(0x2a9)]()[_0x48766e(0x39f)];_0x274864>0x1&&errorlog(_0x48766e(0x24b));}if(_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x152)]){if(_0x387272[_0x48766e(0x1d8)]&&_0x387272['streams'][0x0]){if(!_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)])_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)]=_0x387272[_0x48766e(0x1d8)][0x0];else{var _0x47693e=![];_0x387272[_0x48766e(0x1d8)][0x0][_0x48766e(0x188)]()[_0x48766e(0x335)](_0x56d971=>{var _0x2efa40=_0x48766e;_0x47693e&&(warnlog(_0x2efa40(0x11a)),warnlog(_0x56d971));if(_0x56d971[_0x2efa40(0x4e8)]==_0x2efa40(0x232)){if(_0x2efa40(0x45d)===_0x2efa40(0x45d))_0x51f6a2[_0x2efa40(0x125)][_0x5aebb5][_0x2efa40(0x162)][_0x2efa40(0x2a9)]()[_0x2efa40(0x335)](_0x282d2a=>{var _0x49611c=_0x2efa40;_0x51f6a2[_0x49611c(0x125)][_0x5aebb5][_0x49611c(0x162)][_0x49611c(0x50b)](_0x282d2a);}),_0x47693e=!![];else{function _0x207b1e(){_0xa23f10('RTC\x20already\x20connected');}}}log(_0x2efa40(0x408)),_0x51f6a2['rpcs'][_0x5aebb5][_0x2efa40(0x162)][_0x2efa40(0x47d)](_0x56d971);});}try{_0x51f6a2[_0x48766e(0x125)][_0x5aebb5]['videoElement'][_0x48766e(0x2e4)]=_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)];}catch(_0x3b08ad){if(_0x48766e(0x511)!==_0x48766e(0x511)){function _0x5f13f4(){var _0x4df7cb=_0x48766e;_0x36317c[_0x4df7cb(0x3fd)]&&(_0x585a0b[_0x4df7cb(0x44a)]=_0x73ccfa['from']),delete _0x4feea1[_0x4df7cb(0x164)];}}else errorlog(_0x48766e(0x290));}log('done\x20replacing/adding\x20tracks');}else{if(_0x387272[_0x48766e(0x3cb)]){warnlog('EVENT\x20TRACK\x20instead\x20of\x20event\x20Stream');!_0x51f6a2[_0x48766e(0x125)][_0x5aebb5]['streamSrc']?_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)]=new MediaStream():_0x387272[_0x48766e(0x3cb)][_0x48766e(0x4e8)]==_0x48766e(0x232)&&_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)][_0x48766e(0x2a9)]()['forEach'](_0x5e9b55=>{var _0xa07f38=_0x48766e;_0x51f6a2[_0xa07f38(0x125)][_0x5aebb5][_0xa07f38(0x162)][_0xa07f38(0x50b)](_0x5e9b55);});_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)][_0x48766e(0x47d)](_0x387272['track']);try{_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x152)]['srcObject']=_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)];}catch(_0x2a3c31){errorlog(_0x48766e(0x290));}}else errorlog(_0x48766e(0x20c));}setTimeout(function(){updateMixer();},0x1);}else{log(_0x48766e(0x37f));var _0x11edb2=document[_0x48766e(0x175)](_0x48766e(0x232));_0x51f6a2['rpcs'][_0x5aebb5][_0x48766e(0x152)]=_0x11edb2,_0x11edb2[_0x48766e(0x341)][_0x48766e(0x484)]=_0x5aebb5,_0x11edb2['id']=_0x48766e(0x342)+_0x5aebb5;_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x524)]&&(_0x11edb2[_0x48766e(0x341)][_0x48766e(0x12a)]=_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x524)]);setupIncomingVideoTracking(_0x11edb2,_0x5aebb5);if(_0x387272[_0x48766e(0x1d8)]&&_0x387272['streams'][0x0]){var _0xc23c84=_0x387272[_0x48766e(0x1d8)][0x0];_0x51f6a2[_0x48766e(0x125)][_0x5aebb5]['streamSrc']=_0x387272[_0x48766e(0x1d8)][0x0],_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x152)][_0x48766e(0x2e4)]=_0x51f6a2[_0x48766e(0x125)][_0x5aebb5]['streamSrc'],log(_0x48766e(0x24c));}else{if(_0x387272[_0x48766e(0x3cb)]){if(_0x48766e(0x2d0)!==_0x48766e(0x2d0)){function _0x4eb07e(){var _0x5e0fe6=_0x48766e;_0x559312[_0x5e0fe6(0x59d)](_0x322562[_0x5e0fe6(0x253)],_0x12a21e[_0x5e0fe6(0x5a4)])[_0x5e0fe6(0x558)](function(_0x22a3f9){var _0x573652=_0x5e0fe6;_0x326201['candidates']=_0xd3892f[_0x573652(0x3f1)](_0x22a3f9);var _0x521024={};_0x521024[_0x573652(0x484)]=_0x992337['UUID'],_0x521024[_0x573652(0x436)]=_0x303644[_0x573652(0x436)];for(var _0x592016=0x0;_0x592016<_0x1af4d9['candidates']['length'];_0x592016++){_0x521024[_0x573652(0x496)]=_0x4e30d5['candidates'][_0x592016],_0x27d995[_0x573652(0x520)](_0x521024);}});}}else{warnlog(_0x48766e(0x55f));if(!_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)]){if(_0x48766e(0x304)==='cFhpP')_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)]=new MediaStream();else{function _0x33d690(){var _0x12ce36=_0x48766e;_0x32f697(_0x12ce36(0x20b)),_0x555f23['sdp']=_0x435386(_0x3d4580['sdp'],_0x4bb165[_0x12ce36(0x3b7)]);}}}_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x162)][_0x48766e(0x47d)](_0x387272['track']),_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x152)][_0x48766e(0x2e4)]=_0x51f6a2[_0x48766e(0x125)][_0x5aebb5]['streamSrc'];}}}if(_0x51f6a2[_0x48766e(0x1f4)]){var _0x56d62d={};_0x56d62d['scale']=parseInt(_0x51f6a2[_0x48766e(0x1f4)]),log(_0x56d62d),_0x51f6a2[_0x48766e(0x359)](_0x56d62d,_0x5aebb5);}}if(_0x51f6a2['audioEffects']===!![]){var _0x39708b=function(_0x21bb5a){var _0x38fb2b=function(_0x46c54b){var _0xa5a25e=_0x45a6;if(!_0x51f6a2[_0xa5a25e(0x125)][_0x46c54b])return;var _0x21d298=_0x51f6a2[_0xa5a25e(0x125)][_0x46c54b]['videoElement'][_0xa5a25e(0x574)];_0x51f6a2[_0xa5a25e(0x125)][_0x46c54b]['videoElement'][_0xa5a25e(0x574)]=![],_0x51f6a2['rpcs'][_0x46c54b]['videoElement']['removeEventListener'](_0xa5a25e(0x450),_0x38fb2b);_0x51f6a2[_0xa5a25e(0x1b3)][_0xa5a25e(0x1da)]==_0xa5a25e(0x26b)&&_0x51f6a2[_0xa5a25e(0x1b3)][_0xa5a25e(0x3ed)]();var _0x16350d=_0x51f6a2[_0xa5a25e(0x125)][_0x46c54b]['streamSrc'][_0xa5a25e(0x352)]();if(_0x16350d[_0xa5a25e(0x39f)]){var _0x29372e=_0x16350d[0x0];_0x29372e[_0xa5a25e(0x26c)]!='MediaStreamAudioDestinationNode'&&(_0x51f6a2['rpcs'][_0x46c54b][_0xa5a25e(0x152)][_0xa5a25e(0x2e4)]=addAudioPipeline(_0x51f6a2[_0xa5a25e(0x125)][_0x46c54b][_0xa5a25e(0x162)],_0x46c54b,_0x29372e));}else _0x51f6a2[_0xa5a25e(0x125)][_0x46c54b][_0xa5a25e(0x152)][_0xa5a25e(0x2e4)]=_0x51f6a2[_0xa5a25e(0x125)][_0x46c54b][_0xa5a25e(0x162)];_0x51f6a2[_0xa5a25e(0x125)][_0x46c54b][_0xa5a25e(0x152)][_0xa5a25e(0x574)]=_0x21d298,delete _0x51f6a2[_0xa5a25e(0x125)][_0x46c54b][_0xa5a25e(0x2b2)];if(_0xa5a25e(0x2b2)in _0x51f6a2[_0xa5a25e(0x125)][_0x46c54b]){if('qYyIZ'===_0xa5a25e(0x4c0)){function _0x45ca1d(){var _0x57f87b=_0xa5a25e;_0x302ce6[_0x57f87b(0x539)]=new _0x3fb864(_0x4e9b78[_0x57f87b(0x539)][_0x57f87b(0x51f)](/.{1,2}/g)[_0x57f87b(0x348)](_0x3aa269=>_0x4849a4(_0x3aa269,0x10)));if(_0x3ea5c0[_0x57f87b(0x345)][_0x4a35f9][_0x57f87b(0x11c)])return _0x39fdc9[_0x57f87b(0x2e6)][_0x57f87b(0x455)][_0x57f87b(0x509)]({'name':_0x57f87b(0x34c)},_0x3a2e78['keys'][_0x493bbe][_0x57f87b(0x11c)],_0x52b5a1['signature'],_0x41f174[_0x57f87b(0x47c)][_0x57f87b(0x11f)](_0x73fe3b['data']))['then'](function(_0x4e487d){return _0x3becbd(_0x4e487d),_0x4e487d;})['catch'](function(_0xfac9e0){return _0xd8b3c3(_0xfac9e0),![];});}}else errorlog(_0xa5a25e(0x378));}};return _0x38fb2b(_0x21bb5a);};_0x51f6a2[_0x48766e(0x1b3)][_0x48766e(0x1da)]==_0x48766e(0x17a)&&(_0x51f6a2['firstPlayTriggered']=!![]);if(_0x48766e(0x2b2)in _0x51f6a2[_0x48766e(0x125)][_0x5aebb5]){}else _0x51f6a2[_0x48766e(0x149)]==![]?_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x2b2)]=setInterval(function(_0xd1ccb4){var _0x575fc0=_0x48766e;log(_0x575fc0(0x4bd)),_0x51f6a2[_0x575fc0(0x125)][_0xd1ccb4]&&(_0x51f6a2[_0x575fc0(0x149)]&&(clearInterval(_0x51f6a2['rpcs'][_0xd1ccb4]['eventPlayActive']),_0x51f6a2[_0x575fc0(0x125)][_0xd1ccb4][_0x575fc0(0x152)][_0x575fc0(0x1f1)](_0x575fc0(0x450),_0x39708b(_0xd1ccb4))));},0x3e8,_0x5aebb5):(!_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x2b2)]&&(_0x51f6a2[_0x48766e(0x125)][_0x5aebb5][_0x48766e(0x2b2)]=!![]),_0x51f6a2[_0x48766e(0x125)][_0x5aebb5]['videoElement'][_0x48766e(0x1f1)](_0x48766e(0x450),_0x39708b(_0x5aebb5)));}_0x51f6a2[_0x48766e(0x4f6)](),_0x51f6a2[_0x48766e(0x18e)](),updateUserList();},log(_0x35e56d(0x34a));},_0x51f6a2;}();
\ No newline at end of file