mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-11 21:58:35 +00:00
&hidehome and fixes
This commit is contained in:
parent
a95cc4bc4e
commit
facdbec1ab
29
index.html
29
index.html
@ -57,7 +57,7 @@
|
||||
<meta property="twitter:image" content="./media/vdoNinja_logo_full.png" />
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<link rel="stylesheet" href="./main.css?ver=223" />
|
||||
<link rel="stylesheet" href="./main.css?ver=226" />
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.js"></script>
|
||||
<style id="lightbox-animations" type="text/css"></style>
|
||||
<!-- <link rel="manifest" href="manifest.json" /> -->
|
||||
@ -81,9 +81,9 @@
|
||||
<span itemprop="thumbnail" itemscope itemtype="http://schema.org/ImageObject">
|
||||
<link itemprop="url" href="./media/vdoNinja_logo_full.png" />
|
||||
</span>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=39"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=41"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/aes.js"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=539"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=542"></script>
|
||||
<input id="zoomSlider" type="range" style="display: none;" />
|
||||
<span id="electronDragZone" style="pointer-events: none; z-index:-10; position:absolute;top:0;left:0;width:100%;height:2%;-webkit-app-region: drag;min-height:20px;"></span>
|
||||
<div id="header">
|
||||
@ -205,6 +205,9 @@
|
||||
<div id="recordLocalbutton" onmousedown="event.preventDefault(); event.stopPropagation();" data-state="0" title="Record your stream to disk" aria-label="Record your stream to disk" alt="Record your stream to disk" tabindex="25" role="button" aria-pressed="false" onkeyup="enterPressedClick(event,this);" onclick="recordLocalVideoToggle();" class="hidden float" style="cursor: pointer;">
|
||||
<i class="toggleSize my-float las la-dot-circle" style="position: relative;" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div id="recordLocalScreenbutton" onmousedown="event.preventDefault(); event.stopPropagation();" data-state="0" title="Stop screen share recording" aria-label="Stop screen share recording" alt="Stop screen recording" tabindex="25" role="button" aria-pressed="false" onkeyup="enterPressedClick(event,this);" onclick="recordLocalScreenStopRecord();" class="hidden float" style="cursor: pointer;">
|
||||
<small>Stop<br>Screen<br>Record</small>
|
||||
</div>
|
||||
<span id="miniPerformer" style="pointer-events: auto;" class="hidden"></span>
|
||||
<span id="rooms" class="hidden" style="padding-top:3px;padding-left:6px;pointer-events: auto;color:#fff;"></span>
|
||||
<span id="groups" class="hidden" style="padding-top:3px;padding-left:6px;pointer-events: auto;color:#fff;text-align: center;"></span>
|
||||
@ -594,7 +597,7 @@
|
||||
</select>
|
||||
</span>
|
||||
<br />
|
||||
<span data-translate="application-audio-capture">For application-specific audio capture, <a href='https://docs.vdo.ninja/audio' style='color: #007AC8;'>see here</a></span>
|
||||
<span id="audioScreenCaptureDocs" data-translate="application-audio-capture">For application-specific audio capture, <a href='https://docs.vdo.ninja/audio' style='color: #007AC8;'>see here</a></span>
|
||||
</div>
|
||||
<div class="outer close">
|
||||
<div class="inner">
|
||||
@ -1321,6 +1324,7 @@
|
||||
|
||||
<div id="hiddenElements"></div>
|
||||
<div id="overlayClockContainer" data-initial="600" class="hidden"><span id="overlayClock"></span></div>
|
||||
<div id="overlayClockContainer2" data-initial="600" class="hidden"><span id="overlayClock2"></span></div>
|
||||
<div id="overlayMsgs" onclick="this.innerHTML = '';" style="display:none"></div>
|
||||
<div id="bigPlayButton" onclick="this.innerHTML = '';" style="display:none"></div>
|
||||
<div id="controls_blank" style="display: none;">
|
||||
@ -1934,7 +1938,7 @@
|
||||
<span data-translate="show-video-stats">Show Stats</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="context-menu__item">
|
||||
<li class="context-menu__item" title="Using this may cause audio-issues on some systems">
|
||||
<a href="#" class="context-menu__link" data-action="OutputAudio">
|
||||
<i class="las la-external-link"></i>
|
||||
<span data-translate="custom-audio-output">Audio Destination</span>
|
||||
@ -1965,7 +1969,7 @@
|
||||
<a target="popup" id="popOutChat" style="cursor:pointer;text-align:right;color:#B3C7F9;" onclick="createPopoutChat();"><i class="las la-external-link-alt"></i></a>
|
||||
<div id="chatBody">
|
||||
<div class="inMessage" id="welcomeMsg" data-translate='welcome-to-vdo-ninja-chat'>
|
||||
Welcome to VDO.Ninja! You can send text messages directly to connected peers from here.
|
||||
Welcome to the chat! You can send text messages directly to connected peers from here.
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="chatInput" placeholder="Enter chat message to send here" onkeypress="EnterButtonChat(event)" />
|
||||
@ -1987,15 +1991,11 @@
|
||||
</span>
|
||||
|
||||
<span style="margin: 20px 0 0 0;display:block" id='globalTimerDirectorSpan'>
|
||||
<button data-action-type="create-timer-global" title="Set a countdown timer that this guest sees. CTRL (cmd) + click to pause." onclick="directTimer(this, event);">
|
||||
<button data-action-type="create-timer-global" title="Set a countdown timer that this guest sees. CTRL (cmd) + click to pause." onclick="directRoomTimer(this, event);">
|
||||
<i class="las la-clock"></i>
|
||||
<span data-translate="create-global-timer">Create Global Count-down Timer</span>
|
||||
</button>
|
||||
<button data-action-type="create-timer-up-global" title="Set a count-up timer that this guest sees. CTRL (cmd) + click to pause." onclick="directTimer(this, event);">
|
||||
<i class="las la-clock"></i>
|
||||
<span data-translate="create-global-up-timer">Create Global Count-up Timer</span>
|
||||
</button>
|
||||
<button data-action-type="create-clock-global" title="Set a count-up timer that this guest sees. CTRL (cmd) + click to pause." onclick="directTimer(this, event);">
|
||||
<button data-action-type="create-clock-global" title="Set a count-up timer that this guest sees. CTRL (cmd) + click to pause." onclick="directRoomClock(this, event);">
|
||||
<i class="las la-clock"></i>
|
||||
<span data-translate="create-clock-timer">Toggle Room Clock</span>
|
||||
</button>
|
||||
@ -2295,12 +2295,13 @@
|
||||
// session.apiserver = "wss://api.vdo.ninja:443"; // specifiy a custom websocket API URL.
|
||||
// session.darkmode = false; // enable or disable the dark style theme as the default
|
||||
// session.defaultBackgroundImages = ["./media/bg_sample1.webp", "./media/bg_sample2.webp"]; // for &effects=5 (virtual backgrounds)
|
||||
// session.hidehome = true; // If used, 'hide home' will make the landing page inaccessible, along with hiding a few go-home elements.
|
||||
</script>
|
||||
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=535"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=544"></script>
|
||||
<!--
|
||||
// If you wish to change branding, blank offers a good clean start.
|
||||
<script type="text/javascript" id="main-js" src="./main.js" data-translation="blank"></script>
|
||||
-->
|
||||
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=476"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=482"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
582
lib.js
582
lib.js
@ -1164,15 +1164,17 @@ session.obsStateSync = function(data2send=false, uid=false){
|
||||
if (session.rpcs[UUID].obsControl===false){
|
||||
msg.obsState.details = null; // we don't want to send needless data
|
||||
}
|
||||
} else if (data2send == "details"){
|
||||
if (session.rpcs[UUID].obsControl===false){
|
||||
continue; // we don't want to send needless data; this isn't a visibility update, so skip.
|
||||
} else if (data2send in session.obsState){
|
||||
if (data2send == "details"){
|
||||
if (session.rpcs[UUID].obsControl===false){
|
||||
continue; // we don't want to send needless data; this isn't a visibility update, so skip.
|
||||
}
|
||||
msg.obsState = {};
|
||||
msg.obsState[data2send] = session.obsState[data2send];
|
||||
} else {
|
||||
msg.obsState = {};
|
||||
msg.obsState[data2send] = session.obsState[data2send];
|
||||
}
|
||||
msg.obsState = {};
|
||||
msg.obsState[data2send] = session.obsState[data2send];
|
||||
} else {
|
||||
msg.obsState = {};
|
||||
msg.obsState[data2send] = session.obsState[data2send];
|
||||
}
|
||||
|
||||
if (session.optimize!==false){
|
||||
@ -2997,6 +2999,28 @@ function updateVolume(update=false){
|
||||
}
|
||||
}
|
||||
|
||||
function hideHomeCheck(){
|
||||
if (session.hidehome){
|
||||
getById("logoname").classList.add("permahide");
|
||||
getById("container-1").classList.add("permahide");
|
||||
getById("container-4").classList.add("permahide");
|
||||
getById("dropButton").classList.add("permahide");
|
||||
getById("head1").classList.add("permahide");
|
||||
if ((session.permaid === false) && (session.roomid == false)){
|
||||
getById("mainmenu").classList.add("permahide");
|
||||
} else {
|
||||
getById("mainmenu").classList.remove("permahide");
|
||||
}
|
||||
|
||||
getById("audioScreenCaptureDocs").classList.add("permahide");
|
||||
getById("translateButton").classList.add("permahide");
|
||||
getById("calendarButton").classList.add("permahide");
|
||||
getById("info").classList.add("permahide");
|
||||
getById("helpbutton").classList.add("permahide");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function switchModes(state=null){
|
||||
if (state===null){
|
||||
session.switchMode = !session.switchMode;
|
||||
@ -3037,6 +3061,7 @@ function switchModes(state=null){
|
||||
if (session.videoElement){
|
||||
session.videoElement.style = "";
|
||||
session.videoElement.alreadyAdded = false;
|
||||
|
||||
if (session.showDirector == true) {
|
||||
var target = document.querySelector("#videoContainer_director");
|
||||
if (target){
|
||||
@ -3044,7 +3069,7 @@ function switchModes(state=null){
|
||||
} else {
|
||||
getById("miniPerformer").prepend(session.videoElement);
|
||||
}
|
||||
} else {
|
||||
} else if (session.videoElement.srcObject && session.videoElement.srcObject.getTracks().length){
|
||||
getById("miniPerformer").prepend(session.videoElement);
|
||||
}
|
||||
}
|
||||
@ -7984,6 +8009,10 @@ function processStats(UUID){
|
||||
}
|
||||
});
|
||||
|
||||
if (session.buffer!==false){
|
||||
playoutdelay(UUID);
|
||||
}
|
||||
|
||||
setTimeout(function(){
|
||||
session.directorSpeakerMute();
|
||||
session.directorDisplayMute();
|
||||
@ -7991,9 +8020,6 @@ function processStats(UUID){
|
||||
});
|
||||
} catch (e){errorlog(e);}
|
||||
|
||||
if (session.buffer!==false){
|
||||
playoutdelay(UUID);
|
||||
}
|
||||
pokeIframeAPI('view-stats-updated', true, UUID);
|
||||
};
|
||||
|
||||
@ -8069,7 +8095,6 @@ function playoutdelay(UUID){ // applies a delay to all videos
|
||||
if (sync_offset<0){sync_offset=0;}
|
||||
session.rpcs[UUID].stats[tid]._sync_offset = sync_offset;
|
||||
receiver.playoutDelayHint = parseFloat(sync_offset/1000);
|
||||
|
||||
var audio_delay = session.sync || 0; // video is typically showing greater delay than video
|
||||
audio_delay += target_buffer - session.rpcs[UUID].stats[tid].Buffer_Delay_in_ms
|
||||
if (receiver.track.id in session.rpcs[UUID].inboundAudioPipeline){
|
||||
@ -8084,6 +8109,7 @@ function playoutdelay(UUID){ // applies a delay to all videos
|
||||
session.rpcs[UUID].stats[tid]._sync_offset = sync_offset;
|
||||
receiver.playoutDelayHint = parseFloat(sync_offset/1000); // only the video we are going to do the playout delay for; doesn't work well with audio.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (e){errorlog(e);}
|
||||
@ -8554,7 +8580,6 @@ function processMeshcastStats(UUID){
|
||||
}
|
||||
}
|
||||
} else if (Firefox){
|
||||
|
||||
if (("mimeType" in stat) && ("type" in stat) && ("id" in stat) && (stat.type=="codec")) {
|
||||
|
||||
if (stat.mimeType.includes("video")){
|
||||
@ -8587,6 +8612,10 @@ function processMeshcastStats(UUID){
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (session.buffer!==false){
|
||||
playoutdelay(UUID);
|
||||
}
|
||||
});
|
||||
} catch (e){errorlog(e);}
|
||||
}
|
||||
@ -9500,9 +9529,11 @@ function toggleMute(apply = false, event=false) { // TODO: I need to have this b
|
||||
track.enabled = false;
|
||||
});
|
||||
}
|
||||
//if (ptt){
|
||||
// ptt.innerHTML = "<span data-translate='Push-to-Mute'>🔇 Push to Talk</span>";
|
||||
//}
|
||||
if ((iOS || iPad) && session.videoElement && session.videoElement.srcObject) {
|
||||
session.videoElement.srcObject.getAudioTracks().forEach((track) => {
|
||||
track.enabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
session.muted = false;
|
||||
@ -9526,10 +9557,16 @@ function toggleMute(apply = false, event=false) { // TODO: I need to have this b
|
||||
track.enabled = true;
|
||||
});
|
||||
}
|
||||
if ((iOS || iPad) && session.videoElement && session.videoElement.srcObject) {
|
||||
session.videoElement.srcObject.getAudioTracks().forEach((track) => {
|
||||
track.enabled = true;
|
||||
});
|
||||
}
|
||||
//if (ptt){
|
||||
// ptt.innerHTML = "<span data-translate='Push-to-Mute'>🔴 Push to Mute</span>";
|
||||
//}
|
||||
}
|
||||
|
||||
postMessageIframe(document.getElementById("screensharesource"), {"mic":!session.muted});
|
||||
|
||||
if (!apply) { // only if they are changing states do we bother to spam.
|
||||
@ -10739,7 +10776,6 @@ async function directPageReload(ele, event) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function directTimer(ele, event=false) { // A directing room only is controlled by the Director, with the exception of MUTE.
|
||||
log("directTimer");
|
||||
var msg = {};
|
||||
@ -10756,6 +10792,7 @@ async function directTimer(ele, event=false) { // A directing room only is cont
|
||||
msg.setClock = getTime;
|
||||
msg.showClock = true;
|
||||
msg.startClock = true;
|
||||
|
||||
ele.innerHTML = '<i class="las la-clock"></i><span data-translate="create-timer"> Remove Timer</span>';
|
||||
} else if (ele.value == 3) {
|
||||
ele.value = 1;
|
||||
@ -10788,6 +10825,133 @@ async function directTimer(ele, event=false) { // A directing room only is cont
|
||||
}
|
||||
}
|
||||
|
||||
function toggleClock(){
|
||||
if (session.showTime===false){return;}
|
||||
if (session.showTime){
|
||||
clearInterval(session.showTime);
|
||||
session.showTime = null;
|
||||
getById("overlayClockContainer2").classList.add("hidden");
|
||||
} else {
|
||||
var time = new Date();
|
||||
getById("overlayClock2").innerHTML = time.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true });
|
||||
session.showTime = setInterval(function(){
|
||||
var time = new Date();
|
||||
getById("overlayClock2").innerHTML = time.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true });
|
||||
},2000);
|
||||
getById("overlayClockContainer2").classList.remove("hidden");
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
async function directRoomClock(ele, event=false) {
|
||||
if (ele.active){
|
||||
ele.active = false;
|
||||
session.showRoomTime = false;
|
||||
ele.classList.remove("pressed");
|
||||
} else {
|
||||
ele.active = true;
|
||||
session.showRoomTime = true;
|
||||
ele.classList.add("pressed");
|
||||
}
|
||||
|
||||
if (session.showTime!==false){
|
||||
if (ele.active && !session.showTime){
|
||||
toggleClock();
|
||||
} else if (!ele.active && session.showTime){
|
||||
toggleClock();
|
||||
}
|
||||
}
|
||||
var msg = {};
|
||||
msg.showTime = session.showRoomTime;
|
||||
session.sendRequest(msg);
|
||||
}
|
||||
async function directRoomTimer(ele, event=false) { // A directing room only is controlled by the Director, with the exception of MUTE.
|
||||
log("directGlobalRoomTimer");
|
||||
var msg = {};
|
||||
ele.classList.remove("blue");
|
||||
ele.classList.remove("red2");
|
||||
|
||||
getById("overlayClockContainer").style.fontSize = "50px";
|
||||
|
||||
if (!event || (!((event.ctrlKey) || (event.metaKey)))) {
|
||||
if (ele.value == 0 || ele.value == 2) {
|
||||
var getTime = await promptAlt("Time in seconds to count down", false, false, parseInt(getById("overlayClockContainer").dataset.initial));
|
||||
if (!getTime){return;}
|
||||
getTime = parseInt(getTime);
|
||||
getById("overlayClockContainer").dataset.initial = getTime || 600;
|
||||
ele.value = 1;
|
||||
ele.classList.add("pressed");
|
||||
ele.classList.remove("red2");
|
||||
|
||||
session.roomTimer = Date.now()/1000 + getTime;
|
||||
|
||||
msg.setClock = getTime;
|
||||
setClock(getTime);
|
||||
msg.showClock = true;
|
||||
showClock();
|
||||
msg.startClock = true;
|
||||
startClock();
|
||||
ele.innerHTML = '<i class="las la-clock"></i><span data-translate="create-timer"> Remove Timer</span>';
|
||||
} else if (ele.value == 3) {
|
||||
ele.value = 1;
|
||||
msg.resumeClock = true;
|
||||
|
||||
if (!session.roomTimer){
|
||||
session.roomTimer = false;
|
||||
} else if (session.roomTimer>0){
|
||||
session.roomTimer = false;
|
||||
} else {
|
||||
session.roomTimer = Date.now()/1000 - session.roomTimer;
|
||||
}
|
||||
ele.classList.add("red2");
|
||||
} else {
|
||||
ele.value = 2;
|
||||
ele.classList.remove("pressed");
|
||||
session.roomTimer = false;
|
||||
msg.stopClock = true;
|
||||
stopClock();
|
||||
msg.hideClock = true;
|
||||
hideClock();
|
||||
ele.innerHTML = '<i class="las la-clock"></i><span data-translate="create-timer"> Create Timer</span>';
|
||||
}
|
||||
//miniTranslate(ele);
|
||||
} else if (event.ctrlKey || event.metaKey){
|
||||
if (ele.value == 1) {
|
||||
ele.value = 3;
|
||||
msg.pauseClock = true;
|
||||
pauseClock();
|
||||
if (!session.roomTimer){
|
||||
session.roomTimer = false;
|
||||
} else if (session.roomTimer<Date.now()/1000){
|
||||
session.roomTimer = false;
|
||||
} else {
|
||||
session.roomTimer = Date.now()/1000 - session.roomTimer;
|
||||
}
|
||||
|
||||
ele.classList.add("blue");
|
||||
} else if (ele.value == 3) {
|
||||
ele.value = 1;
|
||||
msg.resumeClock = true;
|
||||
resumeClock();
|
||||
if (!session.roomTimer){
|
||||
session.roomTimer = false;
|
||||
} else if (session.roomTimer>0){
|
||||
session.roomTimer = false;
|
||||
} else {
|
||||
session.roomTimer = Date.now()/1000 - session.roomTimer;
|
||||
}
|
||||
|
||||
ele.classList.add("red2");
|
||||
}
|
||||
}
|
||||
if (ele.dataset.UUID){
|
||||
session.sendRequest(msg, ele.dataset.UUID);
|
||||
} else {
|
||||
session.sendRequest(msg);
|
||||
}
|
||||
}
|
||||
|
||||
function updateRemoteTimerButton(UUID, currentTime) {
|
||||
var elements = document.querySelectorAll('[data-action-type="create-timer"][data--u-u-i-d="' + UUID + '"]');
|
||||
if (elements[0]){
|
||||
@ -12493,6 +12657,8 @@ function outboundAudioPipeline(){ // this function isn't letting me change the a
|
||||
return session.streamSrc;
|
||||
}
|
||||
|
||||
var streamSrc = session.streamSrc;
|
||||
|
||||
if (iOS || iPad){
|
||||
if (session.streamSrc && session.streamSrc.clone){ // modern
|
||||
streamSrc = session.streamSrc.clone();
|
||||
@ -12513,8 +12679,6 @@ function outboundAudioPipeline(){ // this function isn't letting me change the a
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var streamSrc = session.streamSrc; // normal mode
|
||||
}
|
||||
|
||||
try {
|
||||
@ -12610,11 +12774,7 @@ function outboundAudioPipeline(){ // this function isn't letting me change the a
|
||||
|
||||
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);
|
||||
@ -12680,6 +12840,11 @@ function outboundAudioPipeline(){ // this function isn't letting me change the a
|
||||
anonNode = webAudio.compressor;
|
||||
}
|
||||
|
||||
if (session.micDelay!==false) {
|
||||
webAudio.micDelay = micDelayNode(anonNode, audioContext);
|
||||
anonNode = webAudio.micDelay;
|
||||
}
|
||||
|
||||
if (session.noisegate!==false){
|
||||
webAudio.analyser = audioMeter(anonNode, audioContext);
|
||||
anonNode = webAudio.analyser;
|
||||
@ -12831,6 +12996,17 @@ function changeHighEQ(highEQ, deviceid=null) {
|
||||
|
||||
}
|
||||
|
||||
function changeMicDelay(delay, deviceid=null) {
|
||||
log("changeMicDelay :"+delay);
|
||||
for (var waid in session.webAudios){ // add a mic delay
|
||||
if (!session.webAudios[waid].micDelay){
|
||||
errorlog("Mic Delay not setup");
|
||||
} else {
|
||||
session.webAudios[waid].micDelay.delayTime.setValueAtTime(delay/1000, session.webAudios[waid].audioContext.currentTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function changeSubGain(gain, deviceid=null) {
|
||||
if (gain !== false) {
|
||||
gain = parseFloat(gain / 100.0) || 0;
|
||||
@ -12900,13 +13076,12 @@ function changeGatingGain(gain, fadeout=0) {
|
||||
|
||||
|
||||
function micDelayNode(mediaStreamSource, audioContext) {
|
||||
|
||||
if (session.micDelay !== false) {
|
||||
var delay = parseFloat(session.micDelay/1000) || 0;
|
||||
var delayNode = audioContext.createDelay(delay);
|
||||
var delayNode = audioContext.createDelay(delay+0.5);
|
||||
} else {
|
||||
var delayNode = audioContext.createDelay();
|
||||
var delay = 0;
|
||||
var delayNode = audioContext.createDelay(0.5);
|
||||
}
|
||||
delayNode.delayTime.value = delay;
|
||||
mediaStreamSource.connect(delayNode);
|
||||
@ -15392,6 +15567,13 @@ function gotDevices(deviceInfos) {
|
||||
log('Some other kind of source/device: ', deviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (Firefox && !session.mobile){
|
||||
var option = document.createElement('option');
|
||||
option.value = "others";
|
||||
option.text = "Show more options";
|
||||
audioOutputSelect.appendChild(option);
|
||||
}
|
||||
|
||||
if (audioOutputSelect.childNodes.length == 0) {
|
||||
option = document.createElement('option');
|
||||
@ -15869,6 +16051,14 @@ function gotDevices2(deviceInfos) {
|
||||
log('Some other kind of source/device: ', deviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (Firefox && !session.mobile){
|
||||
var option = document.createElement('option');
|
||||
option.value = "others";
|
||||
option.text = "Show more options";
|
||||
audioOutputSelect.appendChild(option);
|
||||
}
|
||||
|
||||
|
||||
if (audioOutputSelect.childNodes.length == 0) {
|
||||
var option = document.createElement('option');
|
||||
@ -16101,9 +16291,47 @@ function gotDevices2(deviceInfos) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Firefox && !session.mobile){
|
||||
if (audioOutputSelect.options[audioOutputSelect.selectedIndex].value === "others"){
|
||||
|
||||
navigator.mediaDevices.selectAudioOutput().then((device) => {
|
||||
|
||||
if (device.kind == "audiooutput"){
|
||||
session.sink = device.deviceId;
|
||||
|
||||
try {
|
||||
var matched = false;
|
||||
audioOutputSelect.childNodes.forEach(ele =>{
|
||||
if (ele.value === device.deviceId){
|
||||
matched = true;
|
||||
ele.selected = true;
|
||||
}
|
||||
})
|
||||
if (!matched){
|
||||
var option = document.createElement('option');
|
||||
option.value = device.deviceId;
|
||||
option.text = device.label;
|
||||
audioOutputSelect.appendChild(option);
|
||||
option.selected = true;
|
||||
}
|
||||
|
||||
saveSettings(); // we're saving because there was an explicit action to change devices
|
||||
} catch(e){errorlog(e);}
|
||||
|
||||
if (!session.sink){return;} // Not sure this would ever happen, but whatever.
|
||||
|
||||
resetupAudioOut(); // we'll probalby use session.sink, since outputSelect3 doesn't exist.
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var outputSelect = getById('outputSource3');
|
||||
session.sink = outputSelect.options[outputSelect.selectedIndex].value;
|
||||
|
||||
session.sink = audioOutputSelect.options[audioOutputSelect.selectedIndex].value;
|
||||
saveSettings();
|
||||
} catch (e) {
|
||||
errorlog(e);
|
||||
@ -16853,7 +17081,11 @@ function resetupAudioOut(ele=false, forceReset=false) { // this re-sets ALL outp
|
||||
// TODO: If error, then see if I need to add mic support, and grab it if needed.
|
||||
});
|
||||
}).catch(error => {
|
||||
errorlog(error);
|
||||
if (Firefox){
|
||||
warnlog(error);
|
||||
} else {
|
||||
errorlog(error);
|
||||
}
|
||||
ele.setSinkId(eleSink).then(() => {
|
||||
log("New Output Device");
|
||||
}).catch(error => {
|
||||
@ -21348,6 +21580,7 @@ function listAudioSettingsPrep() {
|
||||
if ((i==0) && !session.disableWebAudio){ // if web audio is disabled, don't show them
|
||||
trackSet.gating = session.noisegate;
|
||||
trackSet.compressor = session.compressor;
|
||||
trackSet.micDelay = session.micDelay;
|
||||
}
|
||||
|
||||
data.push(trackSet);
|
||||
@ -21566,7 +21799,7 @@ function requestVideoHack(keyname, value, UUID, ctrl=false) {
|
||||
pokeIframeAPI('request-video-setting', {value:value, keyname:keyname, ctrl:ctrl}, UUID);
|
||||
}
|
||||
|
||||
function requestAudioHack(keyname, value, UUID, deviceId = "default") { // updateCameraConstraints
|
||||
function requestAudioHack(keyname, value, UUID, deviceId = "default") { // updateAudioConstraints
|
||||
var msg = {};
|
||||
msg.requestAudioHack = true;
|
||||
msg.keyname = keyname;
|
||||
@ -21577,7 +21810,7 @@ function requestAudioHack(keyname, value, UUID, deviceId = "default") { // updat
|
||||
pokeIframeAPI('request-audio-setting', {value:value, keyname:keyname, deviceId:deviceId}, UUID);
|
||||
}
|
||||
|
||||
function requestChangeEQ(keyname, value, UUID, track = 0) { // updateCameraConstraints
|
||||
function requestChangeEQ(keyname, value, UUID, track = 0) { // updateAudioConstraints
|
||||
var msg = {};
|
||||
msg.requestChangeEQ = true;
|
||||
msg.keyname = keyname;
|
||||
@ -21588,7 +21821,7 @@ function requestChangeEQ(keyname, value, UUID, track = 0) { // updateCameraConst
|
||||
pokeIframeAPI('request-change-eq', {value:value, keyname:keyname, track:track}, UUID);
|
||||
}
|
||||
|
||||
function requestChangeGating(keyname, value, UUID, track = 0) { // updateCameraConstraints
|
||||
function requestChangeGating(keyname, value, UUID, track = 0) { // updateAudioConstraints
|
||||
var msg = {};
|
||||
msg.requestChangeGating = true;
|
||||
msg.keyname = keyname;
|
||||
@ -21598,7 +21831,7 @@ function requestChangeGating(keyname, value, UUID, track = 0) { // updateCameraC
|
||||
session.sendRequest(msg, msg.UUID);
|
||||
pokeIframeAPI('request-change-gating', {value:value, keyname:keyname, track:track}, UUID);
|
||||
}
|
||||
function requestChangeCompressor(keyname, value, UUID, track = 0) { // updateCameraConstraints
|
||||
function requestChangeCompressor(keyname, value, UUID, track = 0) { // updateAudioConstraints
|
||||
var msg = {};
|
||||
msg.requestChangeCompressor = true;
|
||||
msg.keyname = keyname;
|
||||
@ -21608,8 +21841,17 @@ function requestChangeCompressor(keyname, value, UUID, track = 0) { // updateCam
|
||||
session.sendRequest(msg, msg.UUID);
|
||||
pokeIframeAPI('request-change-compressor', {value:value, keyname:keyname, track:track}, UUID);
|
||||
}
|
||||
function requestChangeMicDelay(value, UUID, track = 0) { // updateAudioConstraints
|
||||
var msg = {};
|
||||
msg.requestChangeMicDelay = true;
|
||||
msg.value = value;
|
||||
msg.UUID = UUID;
|
||||
msg.track = track; // pointless atm
|
||||
session.sendRequest(msg, msg.UUID);
|
||||
pokeIframeAPI('request-change-mic-delay', {value:value, track:track}, UUID);
|
||||
}
|
||||
|
||||
function requestChangeSubGain(value, UUID, deviceId) { // updateCameraConstraints
|
||||
function requestChangeSubGain(value, UUID, deviceId) { // updateAudioConstraints
|
||||
var msg = {};
|
||||
msg.requestChangeSubGain = true;
|
||||
msg.value = value;
|
||||
@ -21620,7 +21862,7 @@ function requestChangeSubGain(value, UUID, deviceId) { // updateCameraConstraint
|
||||
pokeIframeAPI('request-sub-gain', {value:value, deviceId:deviceId}, UUID);
|
||||
}
|
||||
|
||||
function requestChangeLowcut(value, UUID, track = 0) { // updateCameraConstraints
|
||||
function requestChangeLowcut(value, UUID, track = 0) { // updateAudioConstraints
|
||||
var msg = {};
|
||||
msg.requestChangeLowcut = true;
|
||||
msg.value = value;
|
||||
@ -21676,6 +21918,65 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
//audioEle.appendChild(label);
|
||||
// continue; // remove to more than one audio device (assuming other fixes are applied)
|
||||
//}
|
||||
|
||||
if (("micDelay" in data) && n==0) {
|
||||
var label = document.createElement("label");
|
||||
var i = "micDelay";
|
||||
label.id = "label_" + i;
|
||||
label.htmlFor = "constraints_" + i;
|
||||
|
||||
var input = document.createElement("input");
|
||||
input.min = 0;
|
||||
input.max = 500;
|
||||
input.value = data.micDelay || 0;
|
||||
|
||||
input.title = "Previously was: "+input.value;
|
||||
|
||||
input.type = "range";
|
||||
input.dataset.keyname = i;
|
||||
//input.dataset.labelname = "mic delay (ms):";
|
||||
label.innerText = capitalizeFirstLetter(i).replace(/([a-z])([A-Z])/g, '$1 $2') + " (ms):";
|
||||
|
||||
|
||||
var manualInput = document.createElement("input");
|
||||
manualInput.type = "number";
|
||||
manualInput.dataset.keyname = i;
|
||||
manualInput.value = parseFloat(input.value);
|
||||
manualInput.className = "manualInput";
|
||||
manualInput.id = "constraints_manual_" + i;
|
||||
manualInput.dataset.UUID = UUID;
|
||||
manualInput.dataset.track = n;
|
||||
|
||||
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 = "10px 0";
|
||||
|
||||
manualInput.onchange = function(e) {
|
||||
getById("constraints_" + e.target.dataset.keyname).value = parseFloat(e.target.value);
|
||||
requestChangeMicDelay(parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track));
|
||||
};
|
||||
|
||||
input.onchange = function(e) {
|
||||
//e.target.title = e.target.value;
|
||||
getById("constraints_manual_" + e.target.dataset.keyname).value = parseFloat(e.target.value);
|
||||
requestChangeMicDelay(parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track));
|
||||
};
|
||||
|
||||
input.oninput = function(e) {
|
||||
getById("constraints_manual_" + e.target.dataset.keyname).value = parseFloat(e.target.value);
|
||||
if (Date.now() - remoteSliderTimeout > 100){
|
||||
remoteSliderTimeout = Date.now();
|
||||
requestChangeMicDelay(parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track));
|
||||
}
|
||||
};
|
||||
|
||||
audioEle.appendChild(label);
|
||||
audioEle.appendChild(manualInput);
|
||||
audioEle.appendChild(input);
|
||||
}
|
||||
|
||||
|
||||
if (data.lowcut!==false && n==0) {
|
||||
@ -21693,7 +21994,7 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
|
||||
input.type = "range";
|
||||
input.dataset.keyname = i;
|
||||
input.dataset.labelname = "low cut:";
|
||||
//input.dataset.labelname = "low cut:";
|
||||
label.innerText = capitalizeFirstLetter(i).replace(/([a-z])([A-Z])/g, '$1 $2') + ":";
|
||||
|
||||
|
||||
@ -21702,7 +22003,9 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
manualInput.dataset.keyname = i;
|
||||
manualInput.value = parseFloat(input.value);
|
||||
manualInput.className = "manualInput";
|
||||
|
||||
manualInput.id = "constraints_manual_" + i;
|
||||
manualInput.dataset.UUID = UUID;
|
||||
manualInput.dataset.track = n;
|
||||
|
||||
input.dataset.track = n;
|
||||
input.dataset.UUID = UUID;
|
||||
@ -21718,12 +22021,12 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
|
||||
input.onchange = function(e) {
|
||||
//e.target.title = e.target.value;
|
||||
getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value;
|
||||
getById("constraints_manual_" + e.target.dataset.keyname).value = parseFloat(e.target.value);
|
||||
requestChangeLowcut(parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track));
|
||||
};
|
||||
|
||||
input.oninput = function(e) {
|
||||
getById("label_" + e.target.dataset.keyname).innerText = e.target.dataset.labelname + " " + e.target.value;
|
||||
getById("constraints_manual_" + e.target.dataset.keyname).value = parseFloat(e.target.value);
|
||||
if (Date.now() - remoteSliderTimeout > 100){
|
||||
remoteSliderTimeout = Date.now();
|
||||
requestChangeLowcut(parseInt(e.target.value), e.target.dataset.UUID, parseInt(e.target.dataset.track));
|
||||
@ -21759,6 +22062,8 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
manualInput.value = parseFloat(input.value);
|
||||
manualInput.className = "manualInput";
|
||||
manualInput.id = "label_" + i;
|
||||
manualInput.dataset.UUID = UUID;
|
||||
manualInput.dataset.track = n;
|
||||
|
||||
input.dataset.track = n;
|
||||
input.dataset.UUID = UUID;
|
||||
@ -21813,6 +22118,8 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
manualInput.value = parseFloat(input.value);
|
||||
manualInput.className = "manualInput";
|
||||
manualInput.id = "label_" + i;
|
||||
manualInput.dataset.UUID = UUID;
|
||||
manualInput.dataset.track = n;
|
||||
|
||||
input.dataset.track = n;
|
||||
input.dataset.UUID = UUID;
|
||||
@ -21868,13 +22175,14 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
manualInput.value = parseFloat(input.value);
|
||||
manualInput.className = "manualInput";
|
||||
manualInput.id = "label_" + i;
|
||||
manualInput.dataset.UUID = UUID;
|
||||
manualInput.dataset.track = n;
|
||||
|
||||
input.dataset.track = n;
|
||||
input.dataset.UUID = UUID;
|
||||
input.id = "constraints_" + i;
|
||||
input.style = "display:block; width:100%;";
|
||||
input.style = "display:block; width:100%;margin:10px 0;";
|
||||
input.name = "constraints_" + i;
|
||||
input.style.margin = "10px 0";
|
||||
|
||||
manualInput.onchange = function(e) {
|
||||
getById("constraints_" + e.target.dataset.keyname).value = parseFloat(e.target.value);
|
||||
@ -22055,6 +22363,8 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
manualInput.id = "label_" + i + "_"+n;
|
||||
manualInput.max = data.audioConstraints[i].max;
|
||||
manualInput.min = data.audioConstraints[i].min;
|
||||
manualInput.dataset.UUID = UUID;
|
||||
manualInput.dataset.track = n;
|
||||
|
||||
if (i in data.currentAudioConstraints) {
|
||||
input.value = data.currentAudioConstraints[i];
|
||||
@ -22229,6 +22539,8 @@ function updateDirectorsAudio(dataN, UUID) {
|
||||
manualInput.value = parseFloat(input.value);
|
||||
manualInput.className = "manualInput";
|
||||
manualInput.id = "label_" + i + "_" + n;
|
||||
manualInput.dataset.UUID = UUID;
|
||||
manualInput.dataset.track = n;
|
||||
|
||||
|
||||
input.dataset.track = data.deviceId;
|
||||
@ -22632,6 +22944,63 @@ function listAudioSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
if (session.micDelay!==false && ii==0) { // ii==0 implies only track0 is supported by the web audio pipeline currently (or everything after the mixer node)
|
||||
if (getById("popupSelector_constraints_audio").style.display == "none") {
|
||||
getById("advancedOptionsAudio").style.display = "inline-block";
|
||||
}
|
||||
|
||||
var label = document.createElement("label");
|
||||
var i = "micDelay";
|
||||
label.htmlFor = "constraints_" + i;
|
||||
label.innerText = capitalizeFirstLetter(i).replace(/([a-z])([A-Z])/g, '$1 $2') + " (ms):";
|
||||
|
||||
var input = document.createElement("input");
|
||||
input.min = 0;
|
||||
input.max = 500;
|
||||
|
||||
input.dataset.deviceid = track0.id; // pointless, for now
|
||||
|
||||
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].micDelay) { // session.webAudios[waid].micDelay.delayTime.setValueAtTime
|
||||
input.value = session.webAudios[webAudio].micDelay.delayTime.value*1000;
|
||||
label.innerHTML += " " + parseInt(session.webAudios[webAudio].micDelay.delayTime.value*1000);
|
||||
input.title = input.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var manualInput = document.createElement("input");
|
||||
manualInput.type = "number";
|
||||
manualInput.dataset.keyname = i;
|
||||
manualInput.dataset.labelname = label.innerHTML;
|
||||
manualInput.value = parseFloat(input.value);
|
||||
manualInput.className = "manualInput";
|
||||
manualInput.id = "label_" + i;
|
||||
|
||||
manualInput.onchange = function(e) {
|
||||
getById("constraints_" + e.target.dataset.keyname).value = parseFloat(e.target.value);
|
||||
changeMicDelay(e.target.value, e.target.dataset.deviceid);
|
||||
e.target.title = e.target.value;
|
||||
};
|
||||
|
||||
input.oninput = function(e) {
|
||||
getById("label_" + e.target.dataset.keyname).value = parseFloat(e.target.value);
|
||||
changeMicDelay(e.target.value, e.target.dataset.deviceid);
|
||||
e.target.title = e.target.value;
|
||||
};
|
||||
|
||||
getById("popupSelector_constraints_audio").appendChild(label);
|
||||
getById("popupSelector_constraints_audio").appendChild(manualInput);
|
||||
getById("popupSelector_constraints_audio").appendChild(input);
|
||||
}
|
||||
|
||||
|
||||
if (session.lowcut && ii==0) { // ii==0 implies only track0 is supported by the web audio pipeline currently (or everything after the mixer node)
|
||||
if (getById("popupSelector_constraints_audio").style.display == "none") {
|
||||
@ -22657,7 +23026,7 @@ function listAudioSettings() {
|
||||
input.name = "constraints_" + i;
|
||||
|
||||
for (var webAudio in session.webAudios) {
|
||||
if (session.webAudios[webAudio].lowcut1.frequency) {
|
||||
if (session.webAudios[webAudio].lowcut1) {
|
||||
input.value = session.webAudios[webAudio].lowcut1.frequency.value;
|
||||
label.innerHTML += " " + session.webAudios[webAudio].lowcut1.frequency.value;
|
||||
input.title = input.value;
|
||||
@ -22715,7 +23084,7 @@ function listAudioSettings() {
|
||||
input.name = "constraints_" + i;
|
||||
|
||||
for (var webAudio in session.webAudios) {
|
||||
if (session.webAudios[webAudio].lowEQ.gain) {
|
||||
if (session.webAudios[webAudio].lowEQ) {
|
||||
input.value = session.webAudios[webAudio].lowEQ.gain.value;
|
||||
label.innerHTML += " " + session.webAudios[webAudio].lowEQ.gain.value;
|
||||
input.title = input.value;
|
||||
@ -22771,7 +23140,7 @@ function listAudioSettings() {
|
||||
|
||||
|
||||
for (var webAudio in session.webAudios) {
|
||||
if (session.webAudios[webAudio].midEQ.gain) {
|
||||
if (session.webAudios[webAudio].midEQ) {
|
||||
input.value = session.webAudios[webAudio].midEQ.gain.value;
|
||||
label.innerHTML += " " + session.webAudios[webAudio].midEQ.gain.value;
|
||||
input.title = input.value;
|
||||
@ -22826,7 +23195,7 @@ function listAudioSettings() {
|
||||
input.name = "constraints_" + i;
|
||||
|
||||
for (var webAudio in session.webAudios) {
|
||||
if (session.webAudios[webAudio].highEQ.gain) {
|
||||
if (session.webAudios[webAudio].highEQ) {
|
||||
input.value = session.webAudios[webAudio].highEQ.gain.value;
|
||||
label.innerHTML += " " + session.webAudios[webAudio].highEQ.gain.value;
|
||||
input.title = input.value;
|
||||
@ -24242,6 +24611,44 @@ function setupWebcamSelection() {
|
||||
if ((iOS) || (iPad)) {
|
||||
return;
|
||||
}
|
||||
if (Firefox && !session.mobile){
|
||||
if (outputSelect.options[outputSelect.selectedIndex].value === "others"){
|
||||
|
||||
navigator.mediaDevices.selectAudioOutput().then((device) => {
|
||||
|
||||
if (device.kind == "audiooutput"){
|
||||
|
||||
session.sink = device.deviceId;
|
||||
|
||||
try {
|
||||
var matched = false;
|
||||
outputSelect.childNodes.forEach(ele =>{
|
||||
if (ele.value === device.deviceId){
|
||||
matched = true;
|
||||
ele.selected = true;
|
||||
}
|
||||
})
|
||||
if (!matched){
|
||||
var option = document.createElement('option');
|
||||
option.value = device.deviceId;
|
||||
option.text = device.label;
|
||||
outputSelect.appendChild(option);
|
||||
option.selected = true;
|
||||
}
|
||||
|
||||
saveSettings(); // we're saving because there was an explicit action to change devices
|
||||
} catch(e){errorlog(e);}
|
||||
|
||||
if (!session.sink){return;} // Not sure this would ever happen, but whatever.
|
||||
|
||||
resetupAudioOut(); // we'll probalby use session.sink, since outputSelect3 doesn't exist.
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
try{
|
||||
session.sink = outputSelect.options[outputSelect.selectedIndex].value;
|
||||
saveSettings(); // we're saving because there was an explicit action to change devices
|
||||
@ -25792,6 +26199,10 @@ function gotDevices3(deviceInfos, vid){
|
||||
}
|
||||
audioEle.onchange = function(){
|
||||
vid.manualSink = this.options[this.selectedIndex].value;
|
||||
if (this.videoTarget && this.videoTarget.dataset.UUID){
|
||||
session.audioEffects = true;
|
||||
updateIncomingAudioElement(this.videoTarget.dataset.UUID);
|
||||
}
|
||||
resetupAudioOut(this.videoTarget);
|
||||
}
|
||||
return audioEle;
|
||||
@ -27556,7 +27967,7 @@ function updateIncomingAudioElement(UUID){ // this can be called when turning on
|
||||
session.rpcs[UUID].videoElement.srcObject = createMediaStream();
|
||||
}
|
||||
|
||||
warnlog("updateIncomingAudioElement: "+UUID);
|
||||
log("updateIncomingAudioElement: "+UUID);
|
||||
if ((session.audioEffects===true) || session.pushLoudness){
|
||||
var tracks = session.rpcs[UUID].streamSrc.getAudioTracks();
|
||||
if (tracks.length){
|
||||
@ -27643,21 +28054,21 @@ function cycleStyleOptions(){
|
||||
updateMixer();
|
||||
}
|
||||
|
||||
function addAudioPipeline(UUID, track){ // INBOUND AUDIO EFFECTS
|
||||
function addAudioPipeline(UUID, track){ // INBOUND AUDIO EFFECTS ; audio tracks only
|
||||
try{
|
||||
log("Triggered webaudio effects path");
|
||||
|
||||
for (var tid in session.rpcs[UUID].inboundAudioPipeline){
|
||||
delete session.rpcs[UUID].inboundAudioPipeline[tid]; // get rid of old nodes.
|
||||
}
|
||||
var trackid = track.id;
|
||||
var trackid = track.id; // this is an audio track, or should be.
|
||||
|
||||
session.rpcs[UUID].inboundAudioPipeline[trackid] = {};
|
||||
|
||||
session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream = createMediaStream();
|
||||
session.rpcs[UUID].inboundAudioPipeline[trackid].mediaStream.addTrack(track);
|
||||
|
||||
if (ChromeVersion){ // I'm going to deprecate this. -> re investigate this
|
||||
if (ChromeVersion && session.audioEffects){ // I'm going to deprecate this.
|
||||
session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio = createAudioElement(); // TODO: I don't know if this mutedAudio thing matters any more, in recent versions of Chrome, since it won't play even if muted.
|
||||
session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio.muted = true;
|
||||
session.rpcs[UUID].inboundAudioPipeline[trackid].mutedAudio.playsinline = true; // ## Added Oct 9th 2022. Not sure it's does anything, but might help with iPhones?
|
||||
@ -27728,16 +28139,16 @@ function addAudioPipeline(UUID, track){ // INBOUND AUDIO EFFECTS
|
||||
session.rpcs[UUID].inboundAudioPipeline[trackid].destination = session.audioCtx.createMediaStreamDestination();
|
||||
source = stereoPanning( source, UUID, trackid, session.panning);
|
||||
screwedUp = true;
|
||||
} else {
|
||||
// screwedUp = true; // added June-3-22 to allow for custom outputs to different audio output destinations.
|
||||
} else if (session.rpcs[UUID].videoElement && session.rpcs[UUID].videoElement.manualSink){
|
||||
screwedUp = true; // added June-3-22 to allow for custom outputs to different audio output destinations.
|
||||
}
|
||||
|
||||
if (screwedUp){
|
||||
|
||||
warnlog("screwedUp mode activated. dun dun");
|
||||
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);
|
||||
source.connect(session.rpcs[UUID].inboundAudioPipeline[trackid].destination);
|
||||
|
||||
try {
|
||||
if (session.firstPlayTriggered && (session.audioCtx.state == "suspended")){
|
||||
@ -30305,6 +30716,37 @@ async function createSecondStream() { ////////////////////////////
|
||||
getById("screenshare3button").classList.remove("float");
|
||||
getById("screenshare3button").classList.add("float2");
|
||||
getById("screenshare3button").title = miscTranslations["stop-screen-sharing"];
|
||||
|
||||
|
||||
if (session.autorecord || session.autorecordlocal){
|
||||
log("AUTO RECORD START SSTYPE3");
|
||||
setTimeout(function(s){
|
||||
if (!session.screenStream){return;}
|
||||
try {
|
||||
var ele = document.getElementById("recordLocalScreenbutton");
|
||||
if (ele){
|
||||
ele.classList.add("red");
|
||||
ele.classList.remove("hidden");
|
||||
if (!ele.vid){
|
||||
var v = createVideoElement();
|
||||
v.muted = true;
|
||||
v.srcObject = s;
|
||||
ele.vid = v;
|
||||
}
|
||||
if (ele.vid.recorder || ele.vid.recording){
|
||||
ele.vid.recorder.stop();
|
||||
ele.classList.remove("red");
|
||||
ele.classList.add("hidden");
|
||||
ele.vid = null;
|
||||
} else {
|
||||
recordLocalVideo(null, session.recordLocal, ele.vid)
|
||||
}
|
||||
}
|
||||
} catch(e){errorlog(e);}
|
||||
},2000, session.screenStream);
|
||||
}
|
||||
|
||||
|
||||
}).catch(function(err) {
|
||||
errorlog(err);
|
||||
});
|
||||
@ -30312,11 +30754,39 @@ async function createSecondStream() { ////////////////////////////
|
||||
stopSecondScreenshare();
|
||||
}
|
||||
}
|
||||
|
||||
function recordLocalScreenStopRecord(){
|
||||
var ele = document.getElementById("recordLocalScreenbutton");
|
||||
if (ele){
|
||||
try {
|
||||
ele.classList.remove("red");
|
||||
ele.classList.add("hidden");
|
||||
if (ele.vid){
|
||||
if (ele.vid.recorder || ele.vid.recording){
|
||||
ele.vid.recorder.stop();
|
||||
}
|
||||
ele.vid = null;
|
||||
}
|
||||
}catch(e){errorlog(e);}
|
||||
}
|
||||
}
|
||||
function stopSecondScreenshare(){
|
||||
var msg = {};
|
||||
msg.screenStopped = true;
|
||||
session.sendMessage(msg);
|
||||
|
||||
var ele = document.getElementById("recordLocalScreenbutton");
|
||||
if (ele){
|
||||
try {
|
||||
ele.classList.remove("red");
|
||||
ele.classList.add("hidden");
|
||||
if (ele.vid){
|
||||
if (ele.vid.recorder || ele.vid.recording){
|
||||
ele.vid.recorder.stop();
|
||||
}
|
||||
ele.vid = null;
|
||||
}
|
||||
}catch(e){errorlog(e);}
|
||||
}
|
||||
|
||||
session.screenStream.getTracks().forEach(function(track) { // previous video track; saving it. Must remove the track at some point.
|
||||
for (UUID in session.pcs){
|
||||
|
||||
33
main.css
33
main.css
@ -358,6 +358,27 @@ button.white:active {
|
||||
padding:2px 20px;
|
||||
background-color: #0009;
|
||||
}
|
||||
#overlayClockContainer2{
|
||||
margin: 0 auto;
|
||||
background-color: #0000;
|
||||
color: white;
|
||||
font-family: Cousine, monospace;
|
||||
font-size: calc(3vh + 3vw / 2);
|
||||
letter-spacing: 0.0em;
|
||||
text-shadow: 0.05em 0.05em 0px rgb(0 0 0);
|
||||
z-index: 6;
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
position: fixed;
|
||||
right:0;
|
||||
bottom:0;
|
||||
overflow-wrap: anywhere;
|
||||
pointer-events: none;
|
||||
}
|
||||
#overlayClock2{
|
||||
padding:0 5px;
|
||||
background-color: #0009;
|
||||
}
|
||||
#overlayMsgs{
|
||||
margin:0 auto;
|
||||
background-color: #0000;
|
||||
@ -2687,6 +2708,18 @@ button.toggleSettings{
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.permahide {
|
||||
display: none!important;
|
||||
visibility: hidden;
|
||||
width:0px;
|
||||
height:0px;
|
||||
opacity: 0;
|
||||
background: #0000;
|
||||
color: #0000;
|
||||
font-size: 0em;
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
#grabDirectorSoloLinkParent {
|
||||
text-align: left;
|
||||
margin: 17px 0 0 0;
|
||||
|
||||
27
main.js
27
main.js
@ -88,7 +88,6 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
} else { // check if automatic language translation is available
|
||||
getById("mainmenu").style.opacity = 1;
|
||||
}
|
||||
|
||||
|
||||
//// translation stuff ends ////
|
||||
|
||||
@ -100,6 +99,11 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
session.cleanViewer = true;
|
||||
}
|
||||
|
||||
if (urlParams.has('hidehome')){
|
||||
session.hidehome = true;
|
||||
}
|
||||
hideHomeCheck();
|
||||
|
||||
if (urlParams.has('previewmode')){
|
||||
session.switchMode = true;
|
||||
}
|
||||
@ -1177,7 +1181,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
} else {
|
||||
session.password = decodeURIComponent(session.password); // will be re-encoded in a moment.
|
||||
}
|
||||
} else if (urlParams.has('nopassword') || urlParams.has('nopass') || urlParams.has('nopw')) {
|
||||
} else if (urlParams.has('nopassword') || urlParams.has('nopass') || urlParams.has('nopw') || urlParams.has('p0')) {
|
||||
session.password = false;
|
||||
session.defaultPassword = false;
|
||||
}
|
||||
@ -1786,7 +1790,7 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
|
||||
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 = urlParams.get('micdelay') || urlParams.get('delay') || urlParams.get('md') || 0;
|
||||
session.micDelay = parseInt(session.micDelay) || 0;
|
||||
session.disableWebAudio = false;
|
||||
}
|
||||
@ -3514,6 +3518,17 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
session.cleanOutput = true;
|
||||
}
|
||||
}
|
||||
if (urlParams.has('clock')){
|
||||
if (urlParams.get('clock') === "false"){
|
||||
session.showTime = false;
|
||||
} else if (urlParams.get('clock') === "0"){
|
||||
session.showTime = false;
|
||||
} else {
|
||||
session.showTime = true;
|
||||
}
|
||||
} else if (session.cleanOutput){
|
||||
session.showTime = false;
|
||||
}
|
||||
|
||||
if (urlParams.has('hidescreenshare') || urlParams.has('hidess') || urlParams.has('sshide') || urlParams.has('screensharehide')) { // this way I don't need to remember what it's called. I can just guess. :D
|
||||
session.screenShareElementHidden = true;
|
||||
@ -3764,7 +3779,6 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
getById("mainmenu").style.opacity = 0;
|
||||
getById("header").style.opacity = 0;
|
||||
}
|
||||
|
||||
|
||||
if (session.view) {
|
||||
getById("main").className = "";
|
||||
@ -3879,6 +3893,9 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
hideHomeCheck();
|
||||
|
||||
setTimeout(function(){
|
||||
for (var i in delayedStartupFuncs) {
|
||||
var cb = delayedStartupFuncs[i];
|
||||
@ -4817,8 +4834,6 @@ async function main(){ // main asyncronous thread; mostly initializes the user s
|
||||
if (isIFrame) { // reduce CPU load if not needed. //iframe API
|
||||
window.onmessage = session.remoteInterfaceAPI;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (session.midiHotkeys || session.midiOut!==false) {
|
||||
|
||||
|
||||
13
thirdparty/CodecsHandler.js
vendored
13
thirdparty/CodecsHandler.js
vendored
@ -27,6 +27,7 @@ Copyright (c) 2012-2020 [Muaz Khan](https://github.com/muaz-khan)
|
||||
|
||||
var CodecsHandler = (function() {
|
||||
function preferCodec(sdp, codecName) {
|
||||
|
||||
var info = splitLines(sdp);
|
||||
if (!info.videoCodecNumbers) {
|
||||
return sdp;
|
||||
@ -35,6 +36,8 @@ var CodecsHandler = (function() {
|
||||
} else if (codecName === 'vp9' && info.vp9LineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
} else if (codecName === 'h264' && info.h264LineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
} else if (codecName === 'h265' && info.h265LineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
} else if (codecName === 'av1' && info.av1LineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
@ -69,7 +72,11 @@ var CodecsHandler = (function() {
|
||||
return sdp;
|
||||
}
|
||||
preferCodecNumber = info.h264LineNumber;
|
||||
|
||||
} else if (codec === 'h265') {
|
||||
if (!info.h265LineNumber) {
|
||||
return sdp;
|
||||
}
|
||||
preferCodecNumber = info.h265LineNumber;
|
||||
} else if (codec === 'av1') {
|
||||
if (!info.av1LineNumber) {
|
||||
return sdp;
|
||||
@ -133,6 +140,10 @@ var CodecsHandler = (function() {
|
||||
info.h264LineNumber = line.replace('a=rtpmap:', '').split(' ')[0];
|
||||
}
|
||||
|
||||
if (line.indexOf('H265/90000') !== -1 && !info.h265LineNumber) {
|
||||
info.h265LineNumber = line.replace('a=rtpmap:', '').split(' ')[0];
|
||||
}
|
||||
|
||||
if (line.indexOf('AV1X/90000') !== -1 && !info.av1LineNumber) {
|
||||
info.av1LineNumber = line.replace('a=rtpmap:', '').split(' ')[0];
|
||||
} else if (line.indexOf('AV1/90000') !== -1 && !info.av1LineNumber) {
|
||||
|
||||
@ -361,7 +361,7 @@
|
||||
"toggle-control-video": "Toggle control bar",
|
||||
"picture-in-picture": "Picture-in-picture",
|
||||
"chrome-cast": "Cast..",
|
||||
"welcome-to-vdo-ninja-chat": "\nWelcome to VDO.Ninja! You can send text messages directly to connected peers from here.\n",
|
||||
"welcome-to-vdo-ninja-chat": "\nWelcome to the chat! You can send text messages directly to connected peers from here.\n",
|
||||
"send-chat": "Send",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user