Update OBS Studio to v26.1.2 or newer; older versions and StreamLabs OBS are not supported on macOS.\
download here: https://github.com/obsproject/obs-studio/releases\
\
Please use the Electron Capture app if there are further problems or if you wish to use StreamLabs on macOS still.
\
You can bypass this error message by refreshing,
Clicking Here, or by adding
&streamlabs to the URL, but it may still not actually work.\
\
Please report this problem to steve@seguin.email if you feel it is an error.\
";
}
}
}
//if (navigator.userAgent.indexOf('Mac OS X') != -1) {
// session.codec = "h264"; // default the codec to h264 if OBS is on macOS (that's all it supports with hardware) // oct 2021, OBS now supports vp8 and actually breaks with h264 android devices.
//}
if (session.disableOBS===false){
if (typeof document.visibilityState !== "undefined"){
session.obsState.visibility = document.visibilityState==="visible";
}
getOBSDetails();
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);
window.addEventListener("obsVirtualcamStarted", obsVirtualcamStarted);
window.addEventListener("obsVirtualcamStopped", obsVirtualcamStopped);
}
} catch (e) {
errorlog(e);
}
}
if (urlParams.has('chroma')) {
log("Chroma ENABLED");
getById("main").style.backgroundColor = "#" + (urlParams.get('chroma') || "0F0");
//try {
// document.querySelector('meta[name="theme-color"]')?.setAttribute('content', "#" + (urlParams.get('chroma') || "0F0")); .. meh
//} catch(e){}
//const ogColor = document.querySelector('meta[name="theme-color"]')?.getAttribute('content');
} // else if (window.obsstudio || (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1)){
// getById("main").style.backgroundColor = "rgba(0,0,0,0)";
//}
//if (urlParams.has('bgimg')){
//
// getById("main").style.background = "#" + (urlParams.get('chroma') || "0F0");
//}
if (urlParams.has('margin')) {
try {
session.videoMargin = urlParams.get('margin') || 10;
session.videoMargin = parseInt(session.videoMargin);
//document.querySelector(':root').style.setProperty('--video-margin', session.videoMargin+"px");
} catch(e){errorlog("variable css failed");}
}
if (urlParams.has('rounded') || urlParams.has('round')) {
try {
session.borderRadius = urlParams.get('rounded') || urlParams.get('round') || 50;
session.borderRadius = parseInt(session.borderRadius);
document.querySelector(':root').style.setProperty('--video-rounded', session.borderRadius+"px");
} catch(e){errorlog("variable css failed");}
}
if (urlParams.has('border')) {
try {
var videoBorder = urlParams.get('border') || 10;
videoBorder = parseInt(videoBorder);
session.border = videoBorder;
videoBorder+="px";
document.querySelector(':root').style.setProperty('--video-border-color', "#000");
document.querySelector(':root').style.setProperty('--video-border', videoBorder);
} catch(e){errorlog("variable css failed");}
}
if (urlParams.has('bordercolor')) {
try {
session.borderColor = urlParams.get('bordercolor') || "#000";
document.querySelector(':root').style.setProperty('--video-border-color', session.borderColor);
} catch(e){errorlog("variable css failed");}
}
if (urlParams.has('color')) {
session.colorVideosBackground = urlParams.get('color') || session.borderColor || "#000";
}
if (urlParams.has('retry')) {
session.forceRetry = parseInt(urlParams.get('retry')) || 30;
}
if (session.forceRetry){
clearInterval(session.forceRetryTimeout);
session.forceRetryTimeout = setTimeout(function(){
try {
session.retryWatchInterval();
} catch(e){
log(e);
clearTimeout(this);
}
}, session.forceRetry*1000);
}
session.dbx = false;
if (urlParams.get('dropbox')){
loadScript("https://cdnjs.cloudflare.com/ajax/libs/dropbox.js/10.34.0/Dropbox-sdk.min.js", ()=>{
log("Loaded dropbox SDK");
var accessToken = urlParams.get('dropbox');
session.dbx = new Dropbox.Dropbox({ accessToken: accessToken });
});
}
try {
if (urlParams.has("darkmode") || urlParams.has("nightmode")){
session.darkmode = urlParams.get("darkmode") || urlParams.get("nightmode") || null;
if ((session.darkmode===null) || (session.darkmode === "")){
session.darkmode=true;
} else if ((darkmode=="false") || (darkmode == "0") || (darkmode == 0) || (darkmode == "off")){
session.darkmode=false;
}
} else if (urlParams.has("lightmode") || urlParams.has("lightmode")){
session.darkmode = false;
} else if (window.obsstudio){
session.darkmode = false; // prevent OBS from defaulting to dark mode, avoiding possible overlooked bugs.
} else if (session.darkmode===null){
session.darkmode = getComputedStyle(document.querySelector(':root')).getPropertyValue('--color-mode').trim();
if (session.darkmode == "dark"){
session.darkmode = true;
} else {
session.darkmode = false;
}
}
if (session.darkmode){
document.body.classList.add("darktheme");
//document.querySelector(':root').style.setProperty('--background-color',"#02050c" );
} else {
document.body.classList.remove("darktheme");
//document.querySelector(':root').style.setProperty('--background-color',"#141926" ); // already set as default.
}
} catch(e){errorlog(e);}
if (urlParams.has("videodevice") || urlParams.has("vdevice") || urlParams.has('vd') || urlParams.has('device') || urlParams.has('d') || urlParams.has('vdo')) {
session.videoDevice = urlParams.get("videodevice") || urlParams.get("vdevice") || urlParams.get("vd") || urlParams.get("device") || urlParams.get("d") || urlParams.get("vdo");
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;
}
if (!urlParams.has('vdo')){
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(/[^-,'A-Za-z0-9]+/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 {
session.audioDevice = session.audioDevice.split(",");
}
getById("headphonesDiv").style.display = "none";
getById("headphonesDiv2").style.display = "none";
if (typeof session.audioDevice !== "object"){
getById("audioMenu").style.display = "none";
getById("audioScreenShare1").style.display = "none";
}
if (session.audioDevice){ // 0 or false, do not triger
log("requestAudioStream..()");
try {
await requestAudioStream();
} catch(e){errorlog(e);}
}
}
if (session.videoDevice === 0) {
getById("previewWebcam").classList.add("miconly");
if (session.audioDevice === 0) {
miniTranslate(getById("add_camera"), "click-start-to-join", "Click Start to Join");
getById("container-2").className = 'column columnfade hidden';
getById("container-3").classList.add("skip-animation");
getById("container-3").classList.remove('pointer');
delayedStartupFuncs.push([previewWebcam]);
session.webcamonly = true;
} else {
miniTranslate(getById("add_camera"), "share-your-mic", "Share your Microphone");
getById("container-3").classList.add("microphoneBackground");
}
getById("container-3").title = getById("add_camera").innerText;
}
if (session.mobile){
getById("shareScreenGear").style.display = "none";
getById("dropButton").style.display = "none";
//getById("container-2").className = 'column columnfade hidden'; // Hide screen share on mobile
session.screensharebutton = false;
screensharesupport = false;
if (session.audioDevice!==0){
getById("flipcamerabutton").classList.remove("hidden");
}
}
if (urlParams.has('androidfix')){
session.AndroidFix = true;
}
if (urlParams.has('consent')){
session.consent = true;
getById("consentWarning").classList.remove("hidden");
getById("consentWarning2").classList.remove("hidden");
}
if (urlParams.has('autojoin') || urlParams.has('autostart') || urlParams.has('aj') || urlParams.has('as')) {
session.autostart = true;
}
if (session.dataMode){
delayedStartupFuncs.push([joinDataMode]);
} else if (session.autostart){
if (session.screenshare!==false) {
delayedStartupFuncs.push([publishScreen]);
}
if (session.consent){
setTimeout(function(){
warnUser("⚠ Privacy warning: The director of this room can remotely switch your camera or microphone without permission.", 8000);
}, 1500);
}
}
if (urlParams.has('noiframe') || urlParams.has('noiframes') || urlParams.has('nif') || urlParams.has('nowebsite') ) {
session.noiframe = urlParams.get('noiframe') || urlParams.get('noiframes') || urlParams.get('nif') || urlParams.get('nowebsite');
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')) { // on the screen, not in screen share
session.nocursor = true;
log("DISABLE CURSOR");
var styletmp = document.createElement('style');
styletmp.innerHTML = `
video {
margin: 0;
padding: 0;
overflow: hidden;
cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=), none;
user-select: none;
}
`;
document.head.appendChild(styletmp);
}
if (urlParams.has('cursor') || urlParams.has('screensharecursor')) {
session.screensharecursor = true;
}
if (urlParams.has('distort')) {
session.voicechanger = 1;
}
if (urlParams.has('dtx') || urlParams.has('usedtx')) {
session.dtx = true;
session.cbr = 0; // no point dtx on if cbr is on, right?
}
if (urlParams.has('youtube')) { // Set with a Youtube v3 clientID + "," + API key, then run YoutubeChatInterface();
session.youtubeKey = urlParams.get('youtube') || "";
//YoutubeChatInterface(); // queries Youtube for chat messages. Forwards them to the parent IFRAME only at the moment.
}
if (urlParams.has('vbr')) {
session.cbr = 0;
getById("whipoutvbrcbr").classList.add("hidden");
} else if (urlParams.has('cbr')) {
session.cbr = 1;
getById("whipoutvbrcbr").classList.add("hidden");
}
if (urlParams.has('order')) {
session.order = parseInt(urlParams.get('order')) || 1;
}
if (urlParams.has('orderby')) {
session.orderby = urlParams.get('orderby') || "id"; // "label" also an option; the default is stream ID tho.
}
if (urlParams.has('slot')) {
session.slot = parseInt(urlParams.get('slot')) || 0;
}
if (urlParams.has('slots')) {
session.slots = parseInt(urlParams.get('slots')) || 4;
}
if (urlParams.has('alpha')) {
session.alpha = true;
}
if (urlParams.has('chunked')) {
session.chunked = parseInt(urlParams.get('chunked')) || 2500; // sender side; enables to allows.
// session.alpha = true;
}
if (urlParams.has('nochunk') || urlParams.has('nochunked')) { // viewer side
session.nochunk = true;
}
//if (urlParams.has('viewchunked') || urlParams.has('viewchunk') || urlParams.has('allowchunked') || urlParams.has('allowchunk')) { // viewer side
// session.forceChunked = true;
//}
if (urlParams.has('token')) {
session.token = urlParams.get('token') || false;
// checkToken(); // this is sycnhonous
}
if (urlParams.has('maindirectorpassword') || urlParams.has('maindirpass')) {
session.mainDirectorPassword = urlParams.get('maindirectorpassword') || urlParams.get('maindirpass') || false;
if (!session.mainDirectorPassword) {
window.focus();
session.mainDirectorPassword = await promptAlt(getTranslation("director-password"), true, true);
if (session.mainDirectorPassword){
session.mainDirectorPassword = session.mainDirectorPassword.trim();
try {
session.mainDirectorPassword = decodeURIComponent(session.mainDirectorPassword);
} catch(e){errorlog(e);}
}
}
// registerToken();
}
if (urlParams.has('debug')){
session.debug=true;
debugStart();
}
if (urlParams.has('group') || urlParams.has('groups')) {
session.group = urlParams.get('group') || urlParams.get('groups') || "";
session.group = session.group.split(",");
}
if (urlParams.has('groupview') || urlParams.has('viewgroup') || urlParams.has('gv')) {
session.groupView = urlParams.get('groupview') || urlParams.get('viewgroup') || urlParams.get('gv') || "";
session.groupView = session.groupView.split(",");
}
if (urlParams.has('groupaudio') || urlParams.has('ga')) {
session.groupAudio = true;
}
if (urlParams.has('groupmode') || urlParams.has('gm')) {
session.allowNoGroup = true;
}
if (urlParams.has('host')) {
session.roomhost = true;
}
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('sensorfilter') || urlParams.has('sensorsfilter') || urlParams.has('filtersensor') || urlParams.has('filtersensors')) {
session.sensorDataFilter = urlParams.get('sensorfilter') || urlParams.get('sensorsfilter') || urlParams.get('filtersensor') || urlParams.get('filtersensors') || "";
session.sensorDataFilter = session.sensorDataFilter.split(","); // ["pos","lin","ori","mag","gyro","acc"];
}
if (urlParams.has('ptime')) {
session.ptime = parseInt(urlParams.get('ptime')) || 20;
if (session.ptime<10){
session.ptime = 10;
}
}
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('contenthint') || urlParams.has('contenttype') || urlParams.has('content') || urlParams.has('hint')) {
session.contentHint = urlParams.get('contenthint') || urlParams.get('contenttype') || urlParams.get('content') || urlParams.get('hint') || "detail";
}
if (urlParams.has('audiocontenthint') || urlParams.has('audiocontenttype') || urlParams.has('audiocontent') || urlParams.has('audiohint')) {
session.audioContentHint = urlParams.get('audiocontenthint') || urlParams.get('audiocontenttype') || urlParams.get('audiocontent') || urlParams.get('audiohint') || "music";
}
if (urlParams.has('screensharecontenthint') || urlParams.has('sscontenthint') || urlParams.has('screensharecontenttype') || urlParams.has('sscontent') || urlParams.has('sshint')) {
session.screenshareContentHint = urlParams.get('screensharecontenthint') || urlParams.get('sscontenthint') || urlParams.get('screensharecontenttype') || urlParams.get('sscontent') || urlParams.get('sshint') || "detail";
}
if (urlParams.has('codec') || urlParams.has('codecs') || urlParams.has('videocodec')) {
log("codecs CHANGED");
session.codecs = urlParams.get('codec') || urlParams.get('codecs') || urlParams.get('videocodec') || false;
if (session.codecs){
session.codecs = session.codecs.toLowerCase();
session.codecs = session.codecs.split(",");
if (session.codecs.length){
session.codec = session.codecs.shift();
if (!session.codec){
session.codec = false;
session.codecs = false;
}
if (!session.codecs.length){
session.codecs = false;
}
} else {
session.codecs = false;
}
}
} else if (OperaGx){
session.codec = "vp8";
warnlog("Defaulting to VP8 manually, as H264 with remote iOS devices is not supported");
}
if (urlParams.has('audiocodec')) {
log("CODEC CHANGED");
session.audioCodec = urlParams.get('audiocodec') || false;
if (session.audioCodec){
session.audioCodec = session.audioCodec.toLowerCase();
}
}
if (urlParams.has('scenelinkcodec')){ // this is mainly for a niche iframe API use
log("codecGroupFlag CHANGED");
session.codecGroupFlag = urlParams.get('scenelinkcodec') || false;
if (session.codecGroupFlag){
session.codecGroupFlag = "&codec="+session.codecGroupFlag.toLowerCase();
}
}
if (urlParams.has('scenelinkbitrate')){ // this is mainly for a niche iframe API use
log("bitrateGroupFlag CHANGED");
session.bitrateGroupFlag = urlParams.get('scenelinkbitrate') || false;
if (session.bitrateGroupFlag){
session.bitrateGroupFlag = "&totalbitrate="+parseInt(session.bitrateGroupFlag);
}
}
if (urlParams.has('h264profile')) {
session.h264profile = urlParams.get('h264profile') || "42e01f"; // 42001f
session.h264profile = session.h264profile.substring(0, 6);
session.h264profile = session.h264profile.toLowerCase();
if (session.h264profile=="0"){
session.h264profile = false;
} else if (session.h264profile=="off"){
session.h264profile = false;
} else if (session.h264profile=="disabl"){
session.h264profile = false;
} else if (session.h264profile=="defaul"){
session.h264profile = false;
} else if (session.h264profile=="false"){
session.h264profile = false;
}
} else if ((session.codec==="hardware") && Android){ // same as &h264profile, but easier for me to remember. I'll try to automate this in the future.
session.codec = "h264";
session.h264profile = "42e01f";
}
if (urlParams.has('nofec')){ // disables error control / throttling -- currently on audio
session.noFEC = true;
}
if (urlParams.has('nonacks') || urlParams.has('nonack')){ // disables error control / throttling.
session.noNacks = true;
}
if (urlParams.has('nopli')){ // disables error control / throttling.
session.noPLIs = true;
}
if (urlParams.has('noremb')){ // disables Receiver Estimated Maximum Bitrate (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 = parseFloat(urlParams.get('scale')) || 100;
}
session.dynamicScale = false; // default true
} else {
if (urlParams.has('viewwidth') || urlParams.has('vw')) {
session.viewwidth = urlParams.get('viewwidth') || urlParams.get('vw') || false;
if (session.viewwidth){
session.viewwidth = parseInt(session.viewwidth);
}
session.dynamicScale = false; // default true
}
if (urlParams.has('viewheight') || urlParams.has('vh')) {
session.viewheight = urlParams.get('viewheight') || urlParams.get('vh') || false;
session.dynamicScale = false; // default true
if (session.viewheight){
session.viewheight = parseInt(session.viewheight);
}
}
}
if (urlParams.has('sharperscreen')) { // sets scale to 100 for inbound screenshares only
session.sharperScreen = true;
}
if (urlParams.has('mcscale') || urlParams.has('meshcastscale') || urlParams.has('woscale') || urlParams.has('whipoutscale')) {
session.whipOutScale = parseFloat(urlParams.get('mcscale')) || parseFloat(urlParams.get('meshcastscale')) || parseFloat(urlParams.get('woscale')) || parseFloat(urlParams.get('whipoutscale')) || 100;
}
if (isIFrame) {
getById("helpbutton").style.display = "none";
getById("helpbutton").style.opacity = 0;
getById("reportbutton").style.display = "none";
getById("reportbutton").style.opacity = 0;
getById("calendarButton").style.display = "none";
getById("calendarButton").style.opacity = 0;
getById("chatBody").innerHTML = "";
}
if (urlParams.has('beep') || urlParams.has('notify') || urlParams.has('tone')) {
session.beepToNotify = true;
var addtone = createAudioElement();
addtone.id = "jointone";
addtone.src = "./media/join.mp3";
getById("testtone").parentNode.insertBefore(addtone, getById("testtone").nextSibling)
var addtone = createAudioElement();
addtone.id = "leavetone";
addtone.src = "./media/leave.mp3";
getById("testtone").parentNode.insertBefore(addtone, getById("testtone").nextSibling)
if (!Notification) {
warnlog('Desktop notifications are not available in your browser.');
} else if (Notification.permission !== 'granted') {
Notification.requestPermission();
}
}
if (urlParams.has('r2d2')) {
/* var addtone = createAudioElement();
addtone.id = "jointone";
addtone.src = "./media/join.mp3";
getById("testtone").parentNode.insertBefore(addtone, getById("testtone").nextSibling)
var addtone = createAudioElement();
addtone.id = "leavetone";
addtone.src = "./media/leave.mp3";
getById("testtone").parentNode.insertBefore(addtone, getById("testtone").nextSibling) */
getById("testtone").innerHTML = "";
getById("testtone").src = "./media/robot.mp3";
session.beepToNotify = true;
}
if (urlParams.has('easyexit') || urlParams.has('ee')) {
session.noExitPrompt = true;
}
if (urlParams.has('entrymsg') || urlParams.has('welcome') || urlParams.has('welcomeb64')) {
session.welcomeMessage = urlParams.get('entrymsg') || urlParams.get('welcome') || urlParams.get('welcomeb64');
if (urlParams.get('welcomeb64')){
try {
session.welcomeMessage = atob(session.welcomeMessage);
} catch(e){}
}
try {
session.welcomeMessage = session.welcomeMessage.replace(/(\r\n|\n|\r)/gm, ' ');
session.welcomeMessage = decodeURIComponent(session.welcomeMessage);
} catch(e){}
}
if (urlParams.has('welcomehtml')) {
session.welcomeHTML = urlParams.get('welcomehtml');
try {
session.welcomeHTML = atob(session.welcomeHTML);
} catch(e){}
try {
session.welcomeHTML = session.welcomeHTML.replace(/(\r\n|\n|\r)/gm, ' ');
session.welcomeHTML = decodeURIComponent(session.welcomeHTML);
} catch(e){}
}
if (urlParams.has('welcomeimage') || urlParams.has('welcomeimg')) {
session.welcomeImage = urlParams.get('welcomeimage') || urlParams.get('welcomeimg');
try {
session.welcomeImage = decodeURIComponent(session.welcomeImage);
} catch(e){}
}
if (urlParams.has('mixminus')){
session.mixMinus = true;
}
if (urlParams.has('clearstorage') || urlParams.has('clear')){
clearStorage();
}
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') || urlParams.has('totalbitrate') || urlParams.has('tb')) {
session.totalRoomBitrate = urlParams.get('totalroombitrate') || urlParams.get('totalroomvideobitrate') || urlParams.get('trb') || urlParams.get('totalbitrate') || urlParams.get('tb') || 0;
session.totalRoomBitrate = parseInt(session.totalRoomBitrate);
if (session.totalRoomBitrate < 1) {
session.totalRoomBitrate = 0;
}
log("totalRoomBitrate ENABLED");
log(session.totalRoomBitrate);
}
if (session.totalRoomBitrate===false){
session.totalRoomBitrate = session.bitrate || session.totalRoomBitrate_default; // sneaky sneaky
} else {
session.totalRoomBitrate_default = session.totalRoomBitrate; // trb_default doesn't change dynamically, but trb can (per director I guess)
}
if (session.totalRoomBitrate_default>4000){
getById("trbSettingInput").max = Math.ceil(session.totalRoomBitrate_default);
}
if (urlParams.has('maxtotalscenebitrate') || urlParams.has('totalscenebitrate') || urlParams.has('mtsb') || urlParams.has('tsb') || urlParams.has('totalbitrate') || urlParams.has('tb')) {
session.totalSceneBitrate = urlParams.get('maxtotalscenebitrate') || urlParams.get('totalscenebitrate') || urlParams.get('mtsb') || urlParams.get('tsb') || urlParams.get('totalbitrate') || urlParams.get('tb') || false;
if (session.totalSceneBitrate){
session.totalSceneBitrate = parseInt(session.totalSceneBitrate);
}
}
if (urlParams.has('blur')){
session.blurBackground = urlParams.get('blur') || 10;
session.blurBackground = parseInt(session.blurBackground) || 10;
if (session.blurBackground<0){session.blurBackground=false;}
session.structure=true;
}
if (urlParams.has('limittotalbitrate') || urlParams.has('ltb')){
session.limitTotalBitrate = urlParams.get('limittotalbitrate') || urlParams.get('ltb') || 2500;
session.limitTotalBitrate = parseInt(session.limitTotalBitrate);
}
if (urlParams.has('mcscreensharebitrate') || urlParams.has('mcssbitrate') || urlParams.has('whipoutscreensharebitrate') || urlParams.has('wossbitrate')){
session.whipOutScreenShareBitrate = urlParams.get('mcscreensharebitrate') || urlParams.get('mcssbitrate') || urlParams.get('whipoutscreensharebitrate') || urlParams.get('wossbitrate') || 2500;
session.whipOutScreenShareBitrate = parseInt(session.whipOutScreenShareBitrate);
}
if (urlParams.has('mcscreensharecodec') || urlParams.has('mcsscodec') || urlParams.has('whipoutscreensharecodec') || urlParams.has('wosscodec')){
session.whipOutScreenShareCodec = urlParams.get('mcscreensharecodec') || urlParams.get('mcsscodec') || urlParams.get('whipoutscreensharecodec') || urlParams.get('wosscodec') || false;
}
if (session.whipOutScreenShareCodec){
session.whipOutScreenShareCodec = session.whipOutScreenShareCodec.toLowerCase();
}
if (urlParams.has('mccodec') || urlParams.has('meshcastcodec') || urlParams.has('whipoutcodec') || urlParams.has('woc')){
session.whipOutCodec = urlParams.get('mccodec') || urlParams.get('meshcastcodec') || urlParams.get('whipoutcodec') || urlParams.get('woc') || false;
getById("whipoutcodecGroupFlag").classList.add("hidden");
}
if (session.whipOutCodec){
session.whipOutCodec = session.whipOutCodec.toLowerCase();
if (session.whipOutCodec == "h264"){
if (Firefox){
session.whipOutCodec = false;
}
}
if (session.whipOutCodec){
session.whipOutCodec = session.whipOutCodec.split(',');
}
getById("whipoutcodecGroupFlag").classList.add("hidden");
}
if (urlParams.has('mcab') || urlParams.has('mcaudiobitrate') || urlParams.has('meshcastab') || urlParams.has('meshcastaudiobitrate ') || urlParams.has('whipoutaudiobitrate') || urlParams.has('woab')){
session.whipOutAudioBitrate = urlParams.get('mcab') || urlParams.get('mcaudiobitrate') || urlParams.get('meshcastab') || urlParams.get('meshcastaudiobitrate ') || urlParams.get('whipoutaudiobitrate') || urlParams.get('woab') || false;
if (session.whipOutAudioBitrate ){
session.whipOutAudioBitrate = parseInt(session.whipOutAudioBitrate );
}
getById("whipoutaudiobitrate").classList.add("hidden");
}
if (urlParams.has('mcb') || urlParams.has('mcbitrate') || urlParams.has('meshcastbitrate') || urlParams.has('whipoutvideobitrate') || urlParams.has('wovb')){
session.whipOutVideoBitrate = urlParams.get('mcb') || urlParams.get('mcbitrate') || urlParams.get('meshcastbitrate') || urlParams.get('whipoutvideobitrate') || urlParams.get('wovb') || false;
if (session.whipOutVideoBitrate){
session.whipOutVideoBitrate = parseInt(session.whipOutVideoBitrate);
}
getById("whipoutbitrateGroupFlag").classList.add("hidden");
getById("whipoutvbrcbr").classList.add("hidden");
}
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";
} else if (session.sink){
if (session.sink == "default"){session.sink = false;}
else {
enumerateDevices().then(function(deviceInfos) {
var matched = false;
for (let i = 0; i !== deviceInfos.length; ++i) {
if (deviceInfos[i].kind === 'audiooutput') {
if (deviceInfos[i].deviceId == session.sink) {
matched = true;
break;
}
}
}
if (!matched){
session.sink = false; // make sure any saved output device exists.
}
});
}
}
if (window.obsstudio || (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1)){
session.fullscreen = true;
} else if (urlParams.has('fullscreen')) {
session.fullscreen = true;
}
if (urlParams.has('stats')) {
if (urlParams.get('stats') == "0") {
session.statsMenu = false;
} else if (urlParams.get('stats') == "false") {
session.statsMenu = false;
} else if (urlParams.get('stats') == "off") {
session.statsMenu = false;
} else {
session.statsMenu = true;
}
} else if (urlParams.has('nostats')) {
session.statsMenu = false;
}
if (session.statsMenu === false){ // hide menu option
try {
document.queryselector('[data-action="ShowStats"]').parentNode.classList.add("hidden");
} catch(e){}
}
if (urlParams.has("statsinterval")){
session.statsInterval = parseInt(urlParams.get("statsinterval")) || 3000; // milliseconds. interval of requesting stats of remote guests
}
if (urlParams.has('cleandirector') || urlParams.has('cdv')) {
session.cleanDirector = true;
}
if (urlParams.has('hidetranslate')) {
getById("translateButton").style.display = "none";
}
if (session.cleanOutput){
session.screensharebutton = false;
getById("translateButton").style.display = "none";
getById("credits").style.display = "none";
getById("header").style.display = "none";
getById("controlButtons").classList.add("hidden");
getById("helpbutton").style.display = "none";
getById("helpbutton").style.opacity = 0;
getById("reportbutton").style.display = "none";
getById("reportbutton").style.opacity = 0;
getById("calendarButton").style.display = "none";
getById("calendarButton").style.opacity = 0;
document.documentElement.style.setProperty('--myvideo-background', '#0000');
var styleTmp = document.createElement('style');
styleTmp.innerHTML = `
video {
background-image: none;
}
`;
document.head.appendChild(styleTmp);
}
getById("credits").innerHTML = "Version: " + session.version + " - " + getById("credits").innerHTML;
if (urlParams.has('ssb') || urlParams.has('screensharebutton')) {
session.screensharebutton = true;
}
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;
} else if (urlParams.has('showheader')) { // needs to happen the room and permaid applications
getById("header").style.display = "inherit";
getById("header").style.opacity = 1;
}
if (urlParams.has('minidirector')) {
try {
var cssStylesheet = document.createElement('link');
cssStylesheet.rel = 'stylesheet';
cssStylesheet.type = 'text/css';
cssStylesheet.media = 'screen';
cssStylesheet.href = 'minidirector.css';
document.getElementsByTagName('head')[0].appendChild(cssStylesheet);
} catch (e) {
errorlog(e);
}
}
if (urlParams.has('postinterval')){ // interval to post snapimage images
session.postInterval = urlParams.get('postinterval') || session.postInterval;
session.postInterval = parseInt(session.postInterval) || 60;
if (session.postInterval<5){
session.postInterval = 5;
}
}
if (urlParams.has('postimage')){
var postURL = decodeURIComponent(urlParams.get('postimage')) || session.postURL; // default will post to https://temp.vdo.ninja/images/STREAMIDHERE.jpg
setInterval(function(postURL){
try {
uploadImageSnapshot(postURL);
} catch(e){}
}, session.postInterval*1000 , postURL);
}
if (urlParams.has('cleanish')) {
session.cleanish = true;
}
if (session.cleanish || !session.cleanOutput){
if (session.obsControls){
getById("obscontrolbutton").classList.remove("hidden");
getById("controlButtons").classList.remove("hidden");
}
}
if (urlParams.has('channels')) { // must be loaded before channelOffset
session.audioChannels = parseInt(urlParams.get('channels')); // for audio output ; not input. see: &channelcount instead.
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.get('playchannel')) { // must be loaded before channelOffset
session.playChannel = parseInt(urlParams.get('playchannel')); // for audio output ; not input. see: &channelcount instead.
session.audioEffects = true;
}
if (urlParams.has('enhance')) {
//if (parseInt(urlParams.get('enhance')>0){
session.enhance = true; //parseInt(urlParams.get('enhance'));
//}
}
if (urlParams.has('degrade')) {
session.degrade = urlParams.get('degrade') || true; // Firefox, and maybe Safari, supported I think.
// the possible values are maintain-framerate, maintain-resolution, or balanced. The default value is balanced
}
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)) {
delayedStartupFuncs.push([warnUser, "Enhanced Security Mode Enabled."]);
}
}
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('tz')){ // being depreciated, but still works with meshcast (no longer turn)
session.tz = urlParams.get('tz');
if ((session.tz === null) || (session.tz === "")){
session.tz = false;
} else {
session.tz = parseInt(session.tz);
}
}
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') || urlParams.has('buffer2')) { // needs to be before sync
if ((ChromiumVersion > 50) && (ChromiumVersion< 78)){
} else {
session.buffer = parseFloat(urlParams.get('buffer')) || parseFloat(urlParams.get('buffer2')) || 0;
log("buffer Changed: " + session.buffer);
}
if (urlParams.has('buffer2')){
session.includeRTT = true;
}
}
if (urlParams.has('panning') || urlParams.has('pan')) {
session.panning = urlParams.get('panning') || urlParams.get('pan');
if (session.panning===""){
session.panning=true
}
session.audioEffects = true;
}
if (urlParams.has('sync')) {
if ((ChromiumVersion > 50) && (ChromiumVersion< 78)){
} else {
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('nomirror')) {
session.nomirror = true;
}
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 (!(ChromiumVersion>=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 elementsTmp = document.querySelectorAll('[data-effectsNotice]');
// for (let i = 0; i < elementsTmp.length; i++) {
// elementsTmp[i].style.display = "inline-block";
// }
//}
if (urlParams.has('viewereffect') || urlParams.has('viewereffects') || urlParams.has('ve')) {
session.viewereffects = parseInt(urlParams.get('viewereffect')) || parseInt(urlParams.get('ve')) || false;
}
if (urlParams.has('activespeaker') || urlParams.has('speakerview') || urlParams.has('sas')){
session.activeSpeaker = urlParams.get('activespeaker') || urlParams.get('speakerview') || urlParams.get('sas') || 1;
session.activeSpeaker = parseInt(session.activeSpeaker);
session.style=6;
session.audioEffects = true;
//session.audioMeterGuest = true;
session.minipreview = 2;
if ((session.activeSpeaker==1) || (session.activeSpeaker==3)){
session.animatedMoves = false;
}
session.fadein=true;
document.querySelector(':root').style.setProperty('--fadein-speed', 0.5);
setInterval(function(){activeSpeaker(false);},100);
} else if (urlParams.has('noisegate') || urlParams.has('gating') || urlParams.has('gate') ||urlParams.has('ng')){
session.quietOthers = urlParams.get('noisegate') || urlParams.get('gating') || urlParams.get('gate') || urlParams.get('ng') || 1;
session.quietOthers = parseInt(session.quietOthers);
if (session.quietOthers == 1){
session.quietOthers = false;
session.noisegate = true;
session.audioEffects = true;
//session.audioMeterGuest = true;
} else if (session.quietOthers == 4){
session.quietOthers = 1;
session.audioEffects = true;
//session.audioMeterGuest = true;
setInterval(function(){activeSpeaker(false);},100);
} else if (!session.quietOthers){
session.noisegate = false;
session.quietOthers = false;
} else {
session.audioEffects = true;
//session.audioMeterGuest = true;
setInterval(function(){activeSpeaker(false);},100);
}
}
if (urlParams.has('noisegatesettings')){
session.noisegateSettings = urlParams.get('noisegatesettings');
session.noisegateSettings = session.noisegateSettings.split(",");
}
if (urlParams.has('fadein')) {
session.fadein=true;
if (urlParams.get('fadein') || 0){
try {
var fadeinspeed = parseInt(urlParams.get('fadein') || 0)/1000.0;
fadeinspeed+="s";
document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed);
} catch(e){errorlog("variable css failed");}
} else {
try {
var fadeinspeed = 0.5;
fadeinspeed+="s";
document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed);
} catch(e){errorlog("variable css failed");}
}
}
if (urlParams.has('widget')){
session.widget = urlParams.get('widget') || false;
if ((session.widget === "false") || (session.widget === "0") || (session.widget === "off")){
session.noWidget=true;
session.widget = false;
} else if (session.widget){
session.widget = decodeURI(session.widget) || false;
log(session.widget);
}
}
if (urlParams.has('animated') || urlParams.has('animate')){
session.animatedMoves = urlParams.get('animated') || urlParams.get('animate');
if (session.animatedMoves === "false") {
session.animatedMoves = false;
} else if (session.animatedMoves === "0") {
session.animatedMoves = false;
} else if (session.animatedMoves === "no") {
session.animatedMoves = false;
} else if (session.animatedMoves === "off") {
session.animatedMoves = false;
} else {
session.animatedMoves = parseInt(session.animatedMoves) || 100;
}
if (session.animatedMoves>200){
session.animatedMoves = 200;
}
} else if (session.mobile){
session.animatedMoves=false;
}
if (urlParams.has('meter') || urlParams.has('meterstyle')){ // same as also adding &style=3
session.meterStyle = urlParams.get('meter') || urlParams.get('meterstyle') || 1;
session.meterStyle = parseInt(session.meterStyle);
if (session.meterStyle<4){
session.style=3; // black canvas
} else {
session.style = -1; // no canvas
}
session.audioEffects = true;
}
if (session.meterStyle==5){
document.documentElement.style.setProperty('--video-background-image-size-talking', 'auto 35%');
document.documentElement.style.setProperty('--video-background-image-size-screaming', 'auto 45%');
}
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');
if ((parseInt(session.style) === 0) || (session.style == "controls")) { // no audio only
session.style = 0;
} else 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")) { // audio meter ; see &meterstyle , where optios include default(false), 1, and 2.
session.style = 3;
session.audioEffects = true;
} else if (parseInt(session.style) == 4) { // black background
session.style = 4;
} else if (parseInt(session.style) == 5) { // random colored background
session.style = 5;
} else if (parseInt(session.style) == 7) { // shows video elements for all connections; even those without video/audio
session.style = parseInt(session.style);
session.showall = true;
} else if (parseInt(session.style)) { // 6 is the first letter of the name, surrounded with a colored circle
session.style = parseInt(session.style);
} else {
session.style = 1;
}
}
//if (session.style){
// getById("toggleWaveformButton").classList.remove("hidden");
//}
if (urlParams.has('showall')){ // just an alternative; might be compoundable
session.showall = true;
}
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 (session.audioCodec === "lyra"){ // WIP. does not work
// try {
// var { default: Module } = await import('./thirdparty/lyra/webassembly_codec_wrapper.js');
// await Module().then((module) => {
// console.log("Initialized codec's wasmModule.");
// session.lyraCodecModule = module;
// }).catch(e => {
// console.log(`Module() error: ${e.name} message: ${e.message}`);
// });
// } catch(e){
// errorlog(e);
// }
// if (session.lyraCodecModule){
// console.log("Lyra module loaded");
// session.micSampleRate = 16000;
// session.encodedInsertableStreams = true;
// } else {
// console.log("Lyra module failed to load");
// }
// }
if (urlParams.has("insertablestreams")){
session.encodedInsertableStreams = true;
}
if (urlParams.has('micsamplerate') || urlParams.has('msr')) {
session.micSampleRate = parseInt(urlParams.get('micsamplerate')) || parseInt(urlParams.get('msr')) || 48000;
}
if (urlParams.has('micsamplesize')) {
session.micSampleSize = parseInt(urlParams.get('micsamplesize')) || 16;
}
if (urlParams.has('noaudioprocessing') || urlParams.has('noap')) {
session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers?
session.disableViewerWebAudioPipeline = true; // this has the potential to break things.
session.audioEffects = false; // disable audio inbound effects also.
session.audioMeterGuest = false;
if (session.noisegate===null){
session.noisegate = false;
}
}
// For info, see this: https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidatePairStats/availableOutgoingBitrate
if (urlParams.has('maxbandwidth')) { // limits the bitrate based on the outbound total available bandwidth; chromium-based
session.maxBandwidth = urlParams.get('maxbandwidth') || 80; // 0 to 100; will reduce bitrate as a percentage of available
session.maxBandwidth = parseInt(session.maxBandwidth);
if (session.maxBandwidth > 200){ // will over ride default 2500kbps if no bitrate is specified
session.maxBandwidth = 200;
} else if (session.maxBandwidth<0){
session.maxBandwidth = 0;
}
}
if (urlParams.has('iframetarget')) {
session.iframetarget = urlParams.get('iframetarget'); // speciifies the IFRAME Hostname target
if (session.iframetarget){
session.iframetarget = decodeURIComponent(session.iframetarget);
} else {
session.iframetarget = window.location.hostname;
}
}
if (urlParams.has('sendframes')) {
session.sendframes = urlParams.get('sendframes');
if(session.sendframes){
session.sendframes = decodeURIComponent(session.sendframes);
} else {
session.sendframes = session.iframetarget || "*";
}
}
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('stun')) {
var stunstring = urlParams.get('stun');
stunstring = stunstring.split(";");
if (stunstring[0] !== "false") { // false disables the TURN server. Useful for debuggin
var stun = {};
if (stunstring.length==3){
stun.username = stunstring[0]; // myusername
stun.credential = stunstring[1]; //mypassword
stun.urls = [stunstring[2]]; // ["turn:turn.obs.ninja:443"];
} else if (stunstring.length==1){
stun.urls = [stunstring[0]];
}
session.stunServers = [stun];
} else {
session.stunServers = [];
}
}
if (urlParams.has('addstun')) {
var stunstring = urlParams.get('addstun');
stunstring = stunstring.split(";");
var stun = {};
if (stunstring.length==3){
stun.username = stunstring[0]; // myusername
stun.credential = stunstring[1]; //mypassword
stun.urls = [stunstring[2]]; // ["turn:turn.obs.ninja:443"];
} else if (stunstring.length==1){
stun.urls = [stunstring[0]];
}
session.stunServers = session.stunServers.concat(stun);
}
if (urlParams.has('bundle')){
session.bundlePolicy = urlParams.get('bundle') || "MaxBundle"; // default is browser default.
}
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.onload = function() {
if (this.status === 200) {
try{
var res = JSON.parse(this.responseText);
} catch(e){
console.error(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://turn.example.com:443/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: session.stunServers,
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 = {};
if (turnstring.length==3){
turn.username = turnstring[0]; // myusername
turn.credential = turnstring[1]; //mypassword
turn.urls = [turnstring[2]]; // ["turn:turn.obs.ninja:443"];
} else if (turnstring.length==1){
turn.urls = [turnstring[0]];
}
session.configuration = {
iceServers: session.stunServers,
sdpSemantics: 'unified-plan' // future-proofing
};
session.configuration.iceServers.push(turn);
}
} catch (e) {
if (!(session.cleanOutput)) {
warnUser("TURN server parameters were wrong.");
}
errorlog(e);
}
}
}
if (urlParams.has('apiserver') && urlParams.get('apiserver')){ // must set this after any custom TURN / STUN settings, else it might over-ride them.
session.apiserver = urlParams.get('apiserver');
}
if (urlParams.has('speedtest')){ // must set this after any custom TURN / STUN settings, else it might over-ride them.
session.speedtest = true;
if (urlParams.get('speedtest')){ // forces essentially UDP mode, unless TCP is specified, and some other stuff
session.speedtest = urlParams.get('speedtest').toLowerCase(); // also limits bitrate
}
setupSpeedtest();
}
if (urlParams.has('privacy') || urlParams.has('private') || urlParams.has('relay')) { // please only use if you are also using your own TURN service.
session.privacy = urlParams.get('privacy') || urlParams.get('private') || urlParams.get('relay') || true;
try { // I'll re-apply this in the setupSpeedtest() promise callback, just to be case.
if (session.configuration){ // this needs to set last, otherwise it might be overridden
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){
warnlog("Bitrate being throttled to max of 6000 kbps");
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 6000 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 {
warnlog("Bitrate being throttled to max of 4000 kbps");
if (session.maxvideobitrate !== false) {
if (session.maxvideobitrate > 4000) {
session.maxvideobitrate = 4000; // Please feel free to get rid of this if using your own TURN servers...
}
} else {
session.maxvideobitrate = 4000; // don't let people pull more than 4000 from you
}
if (session.bitrate !== false) {
if (session.bitrate > 4000) {
session.bitrate = 4000; // Please feel free to get rid of this if using your own TURN servers...
}
}
}
}
if (urlParams.has('wss')) {
session.customWSS = true;
session.wssSetViaUrl = true;
if (urlParams.get('wss')) {
session.wss = urlParams.get('wss');
if (!session.wss.startsWith("wss://")){
session.wss = "wss://" + session.wss;
}
}
} else if (urlParams.has('wss2')) {
session.wssSetViaUrl = true;
if (urlParams.get('wss2')) {
session.wss = urlParams.get('wss2');
if (!session.wss.startsWith("wss://")){
session.wss = "wss://" + session.wss;
}
}
}
if (urlParams.has("bypass")){
session.bypass = true;
session.customWSS = true;
}
if (urlParams.has('osc') || urlParams.has('api')) {
if (urlParams.get('osc') || urlParams.get('api')) {
session.api = urlParams.get('osc') || urlParams.get('api') || false;
if (session.api){
setTimeout(function(){oscClient();},1000);
}
}
}
if (urlParams.has('postapi') || urlParams.has('posturl')) {
session.postApi = urlParams.get('postapi') || urlParams.get('posturl') || false; // ie: &postapi=https%3A%2F%2Fwebhook.site%2Fb190f5bf-e4f8-454a-bd51-78b5807df9c1
if (session.postApi){
try {
session.postApi = decodeURI(session.postApi) || session.postApi ; // needs to be SSL enabled.
} catch(e){
console.error(e);
}
}
}
if (urlParams.has('queue')) {
session.queue = true;
if (urlParams.get('queue') === "false"){
session.queue = false;
} else if (urlParams.get('queue') === "0"){
session.queue = false;
} else if (urlParams.get('queue') === "off"){
session.queue = false;
}
}
if (urlParams.has('push') || urlParams.has('id') || urlParams.has('permaid') ) {
session.permaid = urlParams.get('push') || urlParams.get('id') || urlParams.get('permaid');
if (session.permaid) {
session.permaid = sanitizeStreamID(session.permaid) || null;
session.streamID = session.permaid || session.streamID;
} else if (urlParams.has('permaid') && getStorage("permaid")){
session.streamID = sanitizeStreamID(getStorage("permaid")) || session.streamID;
session.permaid = null;
} else {
session.permaid = null;
}
if (urlParams.has('permaid')){
setStorage("permaid", session.streamID, 99999)
}
if (urlParams.has('push')){
updateURL("push="+session.streamID, true, false);
} else if (urlParams.has('id')){
updateURL("id="+session.streamID, true, false); // not 'officially' supporting this yet; we'll see.
} else if (urlParams.has('permaid')){
updateURL("permaid="+session.streamID, true, false);
} else {
updateURL("push="+session.streamID, true, false);
}
if (session.director) { // 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 hidden';
getById("container-4").className = 'column columnfade hidden';
getById("dropButton").className = 'column columnfade hidden';
getById("info").innerHTML = "";
if (session.videoDevice === 0) {
miniTranslate(getById("add_camera"), "share-your-mic", "Share your Microphone");
} else {
miniTranslate(getById("add_camera"), "share-your-camera", "Share your Camera");
}
miniTranslate(getById("add_screen"), "share-your-screen", "Share your Screen");
getById("container-2").title = getById("add_screen").innerText;
getById("container-3").title = getById("add_camera").innerText;
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 = '