mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-26 04:48:29 +00:00
Merge branch 'develop' into develop
This commit is contained in:
commit
0e4d0b7eea
@ -99,7 +99,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>WebM (or MKV/FLV) to MP4 (fixed 1280x720 resolution) <span class='warning'>(very slow!)</span></h2>
|
<h2>WebM (or MKV/FLV) to MP4 (fixed 1280x720 resolution) <span class='warning'>(very slow!)</span></h2>
|
||||||
<div>
|
<div>
|
||||||
<small>The same as: <i>fmpeg -i input.webm -vf scale="1280:720" output.mp4</i></small>
|
<small>The same as: <i>ffmpeg -i input.webm -vf scale="1280:720" output.mp4</i></small>
|
||||||
<input type="file" accept=".mkv, .flv, .webm" id="uploader" title="Convert WebM to MP4">
|
<input type="file" accept=".mkv, .flv, .webm" id="uploader" title="Convert WebM to MP4">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -113,14 +113,14 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>WebM to Audio-only files (opus or wav)</h2>
|
<h2>WebM to Audio-only files (opus or wav)</h2>
|
||||||
<div>
|
<div>
|
||||||
<small>The same as: <i>fmpeg -i input.webm -vn -acodec copy output.wav</i></small>
|
<small>The same as: <i>ffmpeg -i input.webm -vn -acodec copy output.wav</i></small>
|
||||||
<input type="file" id="uploader4" accept=".webm" title="Convert WebM to OPUS (or WAV)">
|
<input type="file" id="uploader4" accept=".webm" title="Convert WebM to OPUS (or WAV)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>MKV (or FLV/WebM) to MP4 (no transcoding)</h2>
|
<h2>MKV (or FLV/WebM) to MP4 (no transcoding)</h2>
|
||||||
<div>
|
<div>
|
||||||
<small>The same as: <i>fmpeg -i INPUTFILE -vcodec copy -acodec copy output.mp4</i></small>
|
<small>The same as: <i>ffmpeg -i INPUTFILE -vcodec copy -acodec copy output.mp4</i></small>
|
||||||
<input type="file" id="uploader2" accept=".mkv, .flv, .webm" title="Convert MKV (or FLV) to MP4">
|
<input type="file" id="uploader2" accept=".mkv, .flv, .webm" title="Convert MKV (or FLV) to MP4">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
55
index.html
55
index.html
@ -56,7 +56,7 @@
|
|||||||
<meta property="twitter:image" content="./media/vdoNinja_logo_full.png" />
|
<meta property="twitter:image" content="./media/vdoNinja_logo_full.png" />
|
||||||
<meta name="msapplication-TileColor" content="#da532c" />
|
<meta name="msapplication-TileColor" content="#da532c" />
|
||||||
<meta name="theme-color" content="#ffffff" />
|
<meta name="theme-color" content="#ffffff" />
|
||||||
<link rel="stylesheet" href="./main.css?ver=265" />
|
<link rel="stylesheet" href="./main.css?ver=269" />
|
||||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.js"></script>
|
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter.js"></script>
|
||||||
<style id="lightbox-animations" type="text/css"></style>
|
<style id="lightbox-animations" type="text/css"></style>
|
||||||
<!-- <link rel="manifest" href="manifest.json" /> -->
|
<!-- <link rel="manifest" href="manifest.json" /> -->
|
||||||
@ -83,7 +83,7 @@
|
|||||||
|
|
||||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=45"></script>
|
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=45"></script>
|
||||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/aes.js"></script>
|
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/aes.js"></script>
|
||||||
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=579"></script>
|
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=580"></script>
|
||||||
<input id="zoomSlider" type="range" style="display: none;" />
|
<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>
|
<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">
|
<div id="header">
|
||||||
@ -1372,6 +1372,7 @@
|
|||||||
<button data-action-type="hangup" class="mainonly" title="Force the user to Disconnect. They can always reconnect." onclick="directHangup(this, event);">
|
<button data-action-type="hangup" class="mainonly" title="Force the user to Disconnect. They can always reconnect." onclick="directHangup(this, event);">
|
||||||
<i class="las la-sign-out-alt" style="color:#900"></i>
|
<i class="las la-sign-out-alt" style="color:#900"></i>
|
||||||
<span data-translate="disconnect-guest">Hangup</span>
|
<span data-translate="disconnect-guest">Hangup</span>
|
||||||
|
|
||||||
</button>
|
</button>
|
||||||
<button data-action-type="solo-chat" class="mainonly advanced" title="Toggle solo voice chat or hold CTRL/CMD when selecting to make it two-way private." onclick="session.toggleSoloChat(this.dataset.UUID, event);">
|
<button data-action-type="solo-chat" class="mainonly advanced" title="Toggle solo voice chat or hold CTRL/CMD when selecting to make it two-way private." onclick="session.toggleSoloChat(this.dataset.UUID, event);">
|
||||||
<i class="las la-microphone" style="color:#090"></i>
|
<i class="las la-microphone" style="color:#090"></i>
|
||||||
@ -2039,6 +2040,7 @@
|
|||||||
<div id="roomSettings" class="customModelPopup" style="display:none; user-select: none;">
|
<div id="roomSettings" class="customModelPopup" style="display:none; user-select: none;">
|
||||||
<div class="promptModalInner">
|
<div class="promptModalInner">
|
||||||
<span class='modalClose' onclick="toggleRoomSettings();">×</span>
|
<span class='modalClose' onclick="toggleRoomSettings();">×</span>
|
||||||
|
<span class='modalClose' style="right:25px;" onclick="this.parentNode.parentNode.classList.toggle('pinToSide');getById('main').classList.toggle('makeSmallerDirectorRoom');">📌</span>
|
||||||
<span></span>
|
<span></span>
|
||||||
<h3 data-translate="change-room-settings">Change room settings</h3><br />
|
<h3 data-translate="change-room-settings">Change room settings</h3><br />
|
||||||
|
|
||||||
@ -2048,7 +2050,7 @@
|
|||||||
<input id="trbSettingInputManual" min="0" value="500" onchange="getById('trbSettingInput').value=this.value;changeTRB(this);" oninput="getById('trbSettingInputFeedback').innerHTML = this.value;" style="width:42px;display:inline-block;text-align: center;" />
|
<input id="trbSettingInputManual" min="0" value="500" onchange="getById('trbSettingInput').value=this.value;changeTRB(this);" oninput="getById('trbSettingInputFeedback').innerHTML = this.value;" style="width:42px;display:inline-block;text-align: center;" />
|
||||||
|
|
||||||
<span style="margin: 20px 0 0 0;display:block" id='highlightDirectorSpan' title="Only the director's video will be visible to guests and within group scenes">
|
<span style="margin: 20px 0 0 0;display:block" id='highlightDirectorSpan' title="Only the director's video will be visible to guests and within group scenes">
|
||||||
<input id="highlightDirector" style="width: 15px; height: 15px; margin:10px;" name="highlightDirector" data-action-type="solo-video" type="checkbox" onchange="requestInfocus(this);" />
|
<input id="highlightDirector" style="width: 15px; height: 15px; margin:10px;" name="highlightDirector" data-action-type="solo-video" type="checkbox" onchange="requestInfocus(this, event);" />
|
||||||
<label for="highlightDirector" data-translate="highlight-director-only-video-guests-will-see">Highlight Director (only video guests will see)</label>
|
<label for="highlightDirector" data-translate="highlight-director-only-video-guests-will-see">Highlight Director (only video guests will see)</label>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@ -2091,6 +2093,49 @@
|
|||||||
<input id="widgetURL" onmousedown="toggleWidgetURL(this);event.preventDefault" onclick="toggleWidgetURL(this);event.preventDefault" class="hidden" style="cursor:pointer; display:inline-block; margin: 3px 0; margin-left: 10px; min-width: 230px; padding: 4px 5px 3px 5px; border: 1px solid black;" name="widgetURL" placeholder="Enter a URL for the sidebar page" type="text" />
|
<input id="widgetURL" onmousedown="toggleWidgetURL(this);event.preventDefault" onclick="toggleWidgetURL(this);event.preventDefault" class="hidden" style="cursor:pointer; display:inline-block; margin: 3px 0; margin-left: 10px; min-width: 230px; padding: 4px 5px 3px 5px; border: 1px solid black;" name="widgetURL" placeholder="Enter a URL for the sidebar page" type="text" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
<span style="margin: 5px 0 0 0;display:block">
|
||||||
|
<button data-action-type="local-global-record" title="Record all the guests" onclick="
|
||||||
|
document.querySelectorAll('[data-action-type=\'recorder-local\']').forEach(target=>{
|
||||||
|
recordVideo(target);
|
||||||
|
});">
|
||||||
|
<i class="las la-circle"></i>
|
||||||
|
<span data-translate="local-global-record">Local record - start all</span>
|
||||||
|
</button>
|
||||||
|
<button data-action-type="local-global-record" title="Record all the guests" onclick="
|
||||||
|
document.querySelectorAll('[data-action-type=\'recorder-local\']').forEach(target=>{
|
||||||
|
recordVideo(target);
|
||||||
|
});">
|
||||||
|
<i class="las la-square"></i>
|
||||||
|
<span data-translate="local-global-record">Local record - stop all</span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
<span style="margin: 5px 0 0 0;display:block">
|
||||||
|
<button data-action-type="remote-global-record" title="Record all the guests" onclick="
|
||||||
|
window.focus();
|
||||||
|
async function jjj(){
|
||||||
|
var bitrate = await promptAlt(miscTranslations['what-bitrate'], false, false, 6000);
|
||||||
|
document.querySelectorAll('[data-action-type=\'recorder-remote\']').forEach(target=>{
|
||||||
|
requestVideoRecord(target, true, bitrate);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
jjj();
|
||||||
|
">
|
||||||
|
<i class="las la-circle"></i>
|
||||||
|
<span data-translate="remote-global-record">Remote record - start all</span>
|
||||||
|
</button>
|
||||||
|
<button data-action-type="remote-global-record" title="Record all the guests" onclick="
|
||||||
|
document.querySelectorAll('[data-action-type=\'recorder-remote\']').forEach(target=>{
|
||||||
|
if (target.classList.contains('pressed')){
|
||||||
|
requestVideoRecord(target, false);
|
||||||
|
}
|
||||||
|
});">
|
||||||
|
<i class="las la-square"></i>
|
||||||
|
<span data-translate="remote-global-record">Remote record - stop all</span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -2420,11 +2465,11 @@
|
|||||||
// session.hidehome = true; // If used, 'hide home' will make the landing page inaccessible, along with hiding a few go-home elements.
|
// session.hidehome = true; // If used, 'hide home' will make the landing page inaccessible, along with hiding a few go-home elements.
|
||||||
// session.record = false; // uncomment to block users from being able to record via vdo.ninja's built in recording function
|
// session.record = false; // uncomment to block users from being able to record via vdo.ninja's built in recording function
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=666"></script>
|
<script type="text/javascript" crossorigin="anonymous" id="lib-js" src="./lib.js?ver=671"></script>
|
||||||
<!--
|
<!--
|
||||||
// If you wish to change branding, blank offers a good clean start.
|
// 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" id="main-js" src="./main.js" data-translation="blank"></script>
|
||||||
-->
|
-->
|
||||||
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=549"></script>
|
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=551"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
182
lib.js
182
lib.js
@ -3487,11 +3487,12 @@ function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a
|
|||||||
if (session.groupView.length){
|
if (session.groupView.length){
|
||||||
groups.push(...session.groupView)
|
groups.push(...session.groupView)
|
||||||
}
|
}
|
||||||
|
var sssid = false;
|
||||||
var soloVideo = false;
|
var soloVideo = false;
|
||||||
|
|
||||||
if (session.infocus===true){
|
if (session.infocus===true){
|
||||||
soloVideo = true;
|
soloVideo = true;
|
||||||
} else if (session.infocus && (session.infocus!==true) && (session.infocus in session.rpcs)){ // if the infocus stream is connected
|
} else if (session.infocus && (session.infocus in session.rpcs)){ // if the infocus stream is connected
|
||||||
if (groups.length || session.allowNoGroup){
|
if (groups.length || session.allowNoGroup){
|
||||||
try {
|
try {
|
||||||
if (groups.some(item => session.rpcs[session.infocus].group.includes(item))){
|
if (groups.some(item => session.rpcs[session.infocus].group.includes(item))){
|
||||||
@ -3501,6 +3502,19 @@ function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a
|
|||||||
} else {
|
} else {
|
||||||
soloVideo = session.infocus;
|
soloVideo = session.infocus;
|
||||||
}
|
}
|
||||||
|
} else if (session.infocus2===true){
|
||||||
|
sssid = session.streamID;
|
||||||
|
console.log("2.");
|
||||||
|
} else if (session.infocus2 && (session.infocus2 in session.rpcs)){ // if the infocus2 stream is connected
|
||||||
|
if (groups.length || session.allowNoGroup){
|
||||||
|
try {
|
||||||
|
if (groups.some(item => session.rpcs[session.infocus2].group.includes(item))){
|
||||||
|
sssid = session.rpcs[session.infocus2].streamID;
|
||||||
|
}
|
||||||
|
} catch(e){errorlog(e);}
|
||||||
|
} else {
|
||||||
|
sssid = session.rpcs[session.infocus2].streamID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ww = w/arW;
|
var ww = w/arW;
|
||||||
@ -3571,7 +3585,7 @@ function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.screenShareElement){ // I, myself, exist
|
if (session.screenShareState && session.screenShareElement){ // I, myself, exist
|
||||||
if (!session.screenShareElementHidden){
|
if (!session.screenShareElementHidden){
|
||||||
if (session.order!==false){
|
if (session.order!==false){
|
||||||
session.screenShareElement.order=session.order;
|
session.screenShareElement.order=session.order;
|
||||||
@ -4165,8 +4179,6 @@ function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var sssid = false;
|
|
||||||
var sscount = 0;
|
var sscount = 0;
|
||||||
|
|
||||||
var skip = false;
|
var skip = false;
|
||||||
@ -4193,55 +4205,63 @@ function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var mpl = session.slots || mediaPool.length;
|
var mpl = session.slots || mediaPool.length;
|
||||||
|
|
||||||
if (mpl>1){
|
if (!sssid){
|
||||||
var BB = 0;
|
if (mpl>1){
|
||||||
var rw = 1;
|
var BB = 0;
|
||||||
var rh = 1;
|
var rw = 1;
|
||||||
var NW;
|
var rh = 1;
|
||||||
var NH;
|
var NW;
|
||||||
var current;
|
var NH;
|
||||||
for (NW=1; NW <= mpl; NW++){
|
var current;
|
||||||
NH = Math.ceil(mpl/NW);
|
for (NW=1; NW <= mpl; NW++){
|
||||||
var www = ww/NW;
|
NH = Math.ceil(mpl/NW);
|
||||||
var hhh = hh/NH;
|
var www = ww/NW;
|
||||||
if (www>hhh){
|
var hhh = hh/NH;
|
||||||
current = hhh * hhh * (mpl/(NW*NH));
|
if (www>hhh){
|
||||||
} else {
|
current = hhh * hhh * (mpl/(NW*NH));
|
||||||
current = www * www * (mpl/(NW*NH));
|
} else {
|
||||||
}
|
current = www * www * (mpl/(NW*NH));
|
||||||
|
}
|
||||||
|
|
||||||
if (current>=BB){
|
if (current>=BB){
|
||||||
BB = current;
|
BB = current;
|
||||||
rw = NW;
|
rw = NW;
|
||||||
rh = NH;
|
rh = NH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaPool[NW-1]){
|
if (mediaPool[NW-1]){
|
||||||
//if (mediaPool[NW-1].tagName == "VIDEO"){
|
//if (mediaPool[NW-1].tagName == "VIDEO"){
|
||||||
if (mediaPool[NW-1].dataset.UUID){
|
if (mediaPool[NW-1].dataset.UUID){
|
||||||
if (mediaPool[NW-1].dataset.UUID in session.rpcs){
|
if (mediaPool[NW-1].dataset.UUID in session.rpcs){
|
||||||
if (session.rpcs[mediaPool[NW-1].dataset.UUID].screenShareState){
|
if (session.rpcs[mediaPool[NW-1].dataset.UUID].screenShareState){
|
||||||
sscount+=1;
|
sscount+=1;
|
||||||
sssid = mediaPool[NW-1].dataset.sid;
|
sssid = mediaPool[NW-1].dataset.sid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (("id" in mediaPool[NW-1]) && (mediaPool[NW-1].id == "screensharesource") && session.notifyScreenShare){
|
||||||
|
sscount+=1;
|
||||||
|
sssid = mediaPool[NW-1].dataset.sid;
|
||||||
}
|
}
|
||||||
} else if (("id" in mediaPool[NW-1]) && (mediaPool[NW-1].id == "screensharesource") && session.notifyScreenShare){
|
|
||||||
sscount+=1;
|
|
||||||
sssid = mediaPool[NW-1].dataset.sid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else { var rw=1; var rh=1;}
|
||||||
|
|
||||||
|
if (sscount>1){
|
||||||
|
sssid = false; // lets not maximize if more than one screen share.
|
||||||
}
|
}
|
||||||
} else { var rw=1; var rh=1;}
|
|
||||||
if (sscount>1){
|
|
||||||
sssid = false; // lets not maximize if more than one screen share.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(e){
|
} catch(e){
|
||||||
errorlog(e);
|
errorlog(e);
|
||||||
sssid = false
|
sssid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(soloVideo);
|
||||||
|
console.log(sssid);
|
||||||
|
console.log(mediaPool);
|
||||||
|
|
||||||
var customLayout=false;
|
var customLayout=false;
|
||||||
|
|
||||||
@ -10691,7 +10711,7 @@ function reloadRequested() {
|
|||||||
location.reload(); // the main reload function call
|
location.reload(); // the main reload function call
|
||||||
}
|
}
|
||||||
function confirmUnload(event){
|
function confirmUnload(event){
|
||||||
if (!session.noExitPrompt && !session.cleanOutput && (session.permaid!==false || session.director)){
|
if (!session.noExitPrompt && !session.cleanOutput && (session.scene === false) && (session.seeding || (session.roomid!==false) || (session.permaid!==false) || session.director)){
|
||||||
(event || window.event).returnValue = "Are you sure you want to exit?"; //Gecko + IE
|
(event || window.event).returnValue = "Are you sure you want to exit?"; //Gecko + IE
|
||||||
return "Are you sure you want to exit?";
|
return "Are you sure you want to exit?";
|
||||||
} else {
|
} else {
|
||||||
@ -15190,7 +15210,7 @@ function getDirectorSettings(scene=false){
|
|||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestInfocus(ele) {
|
function requestInfocus(ele, evt=null, value=null) {
|
||||||
try{
|
try{
|
||||||
var sid = ele.dataset.sid;
|
var sid = ele.dataset.sid;
|
||||||
} catch(e){
|
} catch(e){
|
||||||
@ -15203,6 +15223,22 @@ function requestInfocus(ele) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value!==null){
|
||||||
|
if (value){
|
||||||
|
ele.value == 0; // we will toggle it in a second anyways.
|
||||||
|
} else {
|
||||||
|
ele.value == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var special = false;
|
||||||
|
if (evt){
|
||||||
|
special = evt.ctrlKey || evt.metaKey || false;
|
||||||
|
if (special){
|
||||||
|
special = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ele.value == 1) {
|
if (ele.value == 1) {
|
||||||
ele.value = 0;
|
ele.value = 0;
|
||||||
ele.classList.remove("pressed");
|
ele.classList.remove("pressed");
|
||||||
@ -15211,7 +15247,11 @@ function requestInfocus(ele) {
|
|||||||
session.sendMessage(actionMsg);
|
session.sendMessage(actionMsg);
|
||||||
} else {
|
} else {
|
||||||
var actionMsg = {};
|
var actionMsg = {};
|
||||||
actionMsg.infocus = sid;
|
if (special){
|
||||||
|
actionMsg.infocus2 = sid;
|
||||||
|
} else {
|
||||||
|
actionMsg.infocus = sid;
|
||||||
|
}
|
||||||
session.sendMessage(actionMsg);
|
session.sendMessage(actionMsg);
|
||||||
|
|
||||||
var eles = document.querySelectorAll('[data-action-type="solo-video"]');
|
var eles = document.querySelectorAll('[data-action-type="solo-video"]');
|
||||||
@ -15328,6 +15368,7 @@ async function createDirectorOnlyBox() {
|
|||||||
buttons += "<div title='Does not impact scene order.' class='shift'><i class='las la-angle-left' onclick='shiftPC(this,-1, true);'></i><i class='las la-angle-right' onclick='shiftPC(this,1, true)';></i></div>\
|
buttons += "<div title='Does not impact scene order.' class='shift'><i class='las la-angle-left' onclick='shiftPC(this,-1, true);'></i><i class='las la-angle-right' onclick='shiftPC(this,1, true)';></i></div>\
|
||||||
<div class='streamID' style='user-select: none;'>ID: <span style='user-select: text;'>" + session.streamID + "</span>\
|
<div class='streamID' style='user-select: none;'>ID: <span style='user-select: text;'>" + session.streamID + "</span>\
|
||||||
<i class='las la-copy' data-sid='" + session.streamID + "' onclick='copyFunction(this.dataset.sid,event)' title='Copy this Stream ID to the clipboard' style='cursor:pointer'></i>\
|
<i class='las la-copy' data-sid='" + session.streamID + "' onclick='copyFunction(this.dataset.sid,event)' title='Copy this Stream ID to the clipboard' style='cursor:pointer'></i>\
|
||||||
|
<i class='las la-window-minimize' onclick='minimizeMe(this, \'container_director\')' title='Minimize this control box' style='cursor:pointer'></i>\
|
||||||
<span id='label_director' class='addALabel' title='Click here to edit the label for this stream. Changes will propagate to all viewers of this stream' data-translate='add-a-label'>"+miscTranslations["add-a-label"]+"</span>\
|
<span id='label_director' class='addALabel' title='Click here to edit the label for this stream. Changes will propagate to all viewers of this stream' data-translate='add-a-label'>"+miscTranslations["add-a-label"]+"</span>\
|
||||||
</div>\
|
</div>\
|
||||||
<div id='videoContainer_director'></div>";
|
<div id='videoContainer_director'></div>";
|
||||||
@ -15490,6 +15531,7 @@ async function createDirectorScreenshareOnlyBox() { // sstype=3
|
|||||||
buttons += "<div title='Does not impact scene order.' class='shift'><i class='las la-angle-left' onclick='shiftPC(this,-1, true);'></i><i class='las la-angle-right' onclick='shiftPC(this,1, true)';></i></div>\
|
buttons += "<div title='Does not impact scene order.' class='shift'><i class='las la-angle-left' onclick='shiftPC(this,-1, true);'></i><i class='las la-angle-right' onclick='shiftPC(this,1, true)';></i></div>\
|
||||||
<div class='streamID' style='user-select: none;'>ID: <span style='user-select: text;'>" + session.streamID+":s</span>\
|
<div class='streamID' style='user-select: none;'>ID: <span style='user-select: text;'>" + session.streamID+":s</span>\
|
||||||
<i class='las la-copy' data-sid='" + session.streamID+":s' onclick='copyFunction(this.dataset.sid,event)' title='Copy this Stream ID to the clipboard' style='cursor:pointer'></i>\
|
<i class='las la-copy' data-sid='" + session.streamID+":s' onclick='copyFunction(this.dataset.sid,event)' title='Copy this Stream ID to the clipboard' style='cursor:pointer'></i>\
|
||||||
|
<i class='las la-window-minimize' onclick='minimizeMe(this, \'container_screen_director\')' title='Minimize this control box'></i>\
|
||||||
<span id='label_director' class='addALabel' title='Click here to edit the label for this stream. Changes will propagate to all viewers of this stream' data-translate='add-a-label'>"+miscTranslations["add-a-label"]+"</span>\
|
<span id='label_director' class='addALabel' title='Click here to edit the label for this stream. Changes will propagate to all viewers of this stream' data-translate='add-a-label'>"+miscTranslations["add-a-label"]+"</span>\
|
||||||
</div>\
|
</div>\
|
||||||
<div id='videoScreenContainer_director'></div>";
|
<div id='videoScreenContainer_director'></div>";
|
||||||
@ -15999,7 +16041,7 @@ function createControlBox(UUID, soloLink, streamID) {
|
|||||||
</div>";
|
</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
controls.innerHTML += "<button data-action-type=\"hand-raised\" id='" + handsID + "' class='lowerRaisedHand' title=\"This guest raised their hand. Click this to clear notification.\" onclick=\"remoteLowerhands('" + UUID + "');\">\
|
controls.innerHTML += "<button data-action-type=\"hand-raised\" id='" + handsID + "' class='hidden lowerRaisedHand' title=\"This guest raised their hand. Click this to clear notification.\" onclick=\"remoteLowerhands('" + UUID + "');\">\
|
||||||
<i class=\"las la-hand-paper\"></i>\
|
<i class=\"las la-hand-paper\"></i>\
|
||||||
<span data-translate=\"user-raised-hand\">Lower Raised Hand</span>\
|
<span data-translate=\"user-raised-hand\">Lower Raised Hand</span>\
|
||||||
</button>\
|
</button>\
|
||||||
@ -16045,6 +16087,7 @@ function createControlBox(UUID, soloLink, streamID) {
|
|||||||
}
|
}
|
||||||
buttons += "<div title='Does not impact scene order.' class='shift'><i class='las la-angle-left' data--u-u-i-d='"+UUID+"' onclick='shiftPC(this,-1);'></i><span onclick='lockPosition(this);' style='cursor:pointer;' data-locked='0' data--u-u-i-d='"+UUID+"' id='position_"+UUID+"'><i class='las la-lock-open'></i></span><i class='las la-angle-right' data--u-u-i-d='"+UUID+"' onclick='shiftPC(this,1);'></i></div><div class='streamID' style='user-select: none;'>ID: <span style='user-select: text;'>" + streamID + "</span>\
|
buttons += "<div title='Does not impact scene order.' class='shift'><i class='las la-angle-left' data--u-u-i-d='"+UUID+"' onclick='shiftPC(this,-1);'></i><span onclick='lockPosition(this);' style='cursor:pointer;' data-locked='0' data--u-u-i-d='"+UUID+"' id='position_"+UUID+"'><i class='las la-lock-open'></i></span><i class='las la-angle-right' data--u-u-i-d='"+UUID+"' onclick='shiftPC(this,1);'></i></div><div class='streamID' style='user-select: none;'>ID: <span style='user-select: text;'>" + streamID + "</span>\
|
||||||
<i class='las la-copy' data-sid='" + streamID + "' onclick='copyFunction(this.dataset.sid,event)' title='Copy this Stream ID to the clipboard' style='cursor:pointer'></i>\
|
<i class='las la-copy' data-sid='" + streamID + "' onclick='copyFunction(this.dataset.sid,event)' title='Copy this Stream ID to the clipboard' style='cursor:pointer'></i>\
|
||||||
|
<i class='las la-window-minimize' data--u-u-i-d='"+UUID+"' onclick='minimizeMe(this)' title='Minimize this control box' style='cursor:pointer'></i>\
|
||||||
<span id='label_" + UUID + "' class='addALabel' title='Click here to edit the label for this stream. Changes will propagate to all viewers of this stream'></span>\
|
<span id='label_" + UUID + "' class='addALabel' title='Click here to edit the label for this stream. Changes will propagate to all viewers of this stream'></span>\
|
||||||
</div>";
|
</div>";
|
||||||
|
|
||||||
@ -16174,6 +16217,14 @@ function createControlBox(UUID, soloLink, streamID) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function minimizeMe(button, director=false){
|
||||||
|
if (!director){
|
||||||
|
getById("container_"+button.dataset.UUID).classList.toggle("minimized");
|
||||||
|
} else {
|
||||||
|
getById(director).classList.toggle("minimized");
|
||||||
|
}
|
||||||
|
}
|
||||||
function cycleCameras(){
|
function cycleCameras(){
|
||||||
if (session.screenShareState) {
|
if (session.screenShareState) {
|
||||||
warnUser("Stop the screen-share first.");
|
warnUser("Stop the screen-share first.");
|
||||||
@ -19506,16 +19557,16 @@ function toggleBufferSettings(UUID){
|
|||||||
function toggleRoomSettings(){
|
function toggleRoomSettings(){
|
||||||
toggle(getById('roomSettings'));
|
toggle(getById('roomSettings'));
|
||||||
if (getById('roomSettings').style.display=="none"){
|
if (getById('roomSettings').style.display=="none"){
|
||||||
getById("modalBackdrop").innerHTML = ''; // Delete modal
|
//getById("modalBackdrop").innerHTML = ''; // Delete modal
|
||||||
getById("modalBackdrop").remove();
|
//getById("modalBackdrop").remove();
|
||||||
} else {
|
} else {
|
||||||
getById("modalBackdrop").innerHTML = ''; // Delete modal
|
//getById("modalBackdrop").innerHTML = ''; // Delete modal
|
||||||
getById("modalBackdrop").remove();
|
//getById("modalBackdrop").remove();
|
||||||
zindex = 25;
|
zindex = 25;
|
||||||
getById('roomSettings').style.zIndex = 25;
|
getById('roomSettings').style.zIndex = 25;
|
||||||
var modalTemplate = `<div id="modalBackdrop" style="z-index:24"></div>`;
|
var modalTemplate = `<div id="modalBackdrop" style="z-index:24"></div>`;
|
||||||
document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end
|
// document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end
|
||||||
document.getElementById("modalBackdrop").addEventListener("click", toggleRoomSettings);
|
// document.getElementById("modalBackdrop").addEventListener("click", toggleRoomSettings);
|
||||||
document.getElementById('trbSettingInput').value = session.totalRoomBitrate;
|
document.getElementById('trbSettingInput').value = session.totalRoomBitrate;
|
||||||
document.getElementById('trbSettingInputManual').value = session.totalRoomBitrate;
|
document.getElementById('trbSettingInputManual').value = session.totalRoomBitrate;
|
||||||
document.getElementById('trbSettingInputFeedback').innerHTML = session.totalRoomBitrate;
|
document.getElementById('trbSettingInputFeedback').innerHTML = session.totalRoomBitrate;
|
||||||
@ -23492,20 +23543,22 @@ function setupClosedCaptions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function requestVideoRecord(ele) {
|
async function requestVideoRecord(ele, state=null, bitrate=null) {
|
||||||
var UUID = ele.dataset.UUID
|
var UUID = ele.dataset.UUID;
|
||||||
if (ele.classList.contains("pressed")) {
|
if (!state && ele.classList.contains("pressed")) {
|
||||||
var msg = {};
|
var msg = {};
|
||||||
msg.requestVideoRecord = false;
|
msg.requestVideoRecord = false;
|
||||||
msg.UUID = UUID;
|
msg.UUID = UUID;
|
||||||
session.sendRequest(msg, msg.UUID);
|
session.sendRequest(msg, msg.UUID);
|
||||||
ele.classList.remove("pressed");
|
ele.classList.remove("pressed");
|
||||||
} else {
|
} else if (state==null || state){
|
||||||
var msg = {};
|
var msg = {};
|
||||||
msg.requestVideoRecord = true;
|
msg.requestVideoRecord = true;
|
||||||
msg.UUID = UUID;
|
msg.UUID = UUID;
|
||||||
window.focus();
|
if (bitrate===null){
|
||||||
var bitrate = await promptAlt(miscTranslations["what-bitrate"], false, false, 6000);
|
window.focus();
|
||||||
|
bitrate = await promptAlt(miscTranslations["what-bitrate"], false, false, 6000);
|
||||||
|
}
|
||||||
if (bitrate) {
|
if (bitrate) {
|
||||||
msg.value = bitrate;
|
msg.value = bitrate;
|
||||||
session.sendRequest(msg, msg.UUID);
|
session.sendRequest(msg, msg.UUID);
|
||||||
@ -32269,6 +32322,22 @@ function setupCommands(){
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
commands.soloVideo = function(value=null,value2=null){
|
||||||
|
var element = getById("highlightDirector");
|
||||||
|
if (value && (value == "toggle")){
|
||||||
|
return requestInfocus(element);
|
||||||
|
} else if (value && (value !== "null")){
|
||||||
|
return requestInfocus(element, null, true);
|
||||||
|
} else if (value && (value === "null")){
|
||||||
|
return requestInfocus(element);
|
||||||
|
} else {
|
||||||
|
return requestInfocus(element, null, false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
commands.highlight = function(value=null,value2=null){
|
||||||
|
return commands.soloVideo(value, value2);
|
||||||
|
};
|
||||||
|
|
||||||
commands.layout = function(value=null,value2=null){
|
commands.layout = function(value=null,value2=null){
|
||||||
try {
|
try {
|
||||||
@ -33721,7 +33790,7 @@ function createControlBoxScreenshare(UUID, soloLink, streamID) {
|
|||||||
</div>";
|
</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
controls.innerHTML += "<button data-action-type=\"hand-raised\" id='" + handsID + "' class='lowerRaisedHand' title=\"This guest raised their hand. Click this to clear notification.\" onclick=\"remoteLowerhands('" + UUID + "');\">\
|
controls.innerHTML += "<button data-action-type=\"hand-raised\" id='" + handsID + "' class='hidden lowerRaisedHand' title=\"This guest raised their hand. Click this to clear notification.\" onclick=\"remoteLowerhands('" + UUID + "');\">\
|
||||||
<i class=\"las la-hand-paper\"></i>\
|
<i class=\"las la-hand-paper\"></i>\
|
||||||
<span data-translate=\"user-raised-hand\">Lower Raised Hand</span>\
|
<span data-translate=\"user-raised-hand\">Lower Raised Hand</span>\
|
||||||
</button>\
|
</button>\
|
||||||
@ -33768,6 +33837,7 @@ function createControlBoxScreenshare(UUID, soloLink, streamID) {
|
|||||||
|
|
||||||
buttons += "<div title='Does not impact scene order.' class='shift'><i class='las la-angle-left' data--u-u-i-d='"+UUID+"' onclick='shiftPC(this,-1);'></i><span onclick='lockPosition(this);' style='cursor:pointer;' data-locked='0' data--u-u-i-d='"+UUID+"' id='position_"+UUID+"'><i class='las la-lock-open'></i></span><i class='las la-angle-right' data--u-u-i-d='"+UUID+"' onclick='shiftPC(this,1);'></i></div><div class='streamID' style='user-select: none;'>ID: <span style='user-select: text;'>" + streamID + "</span>\
|
buttons += "<div title='Does not impact scene order.' class='shift'><i class='las la-angle-left' data--u-u-i-d='"+UUID+"' onclick='shiftPC(this,-1);'></i><span onclick='lockPosition(this);' style='cursor:pointer;' data-locked='0' data--u-u-i-d='"+UUID+"' id='position_"+UUID+"'><i class='las la-lock-open'></i></span><i class='las la-angle-right' data--u-u-i-d='"+UUID+"' onclick='shiftPC(this,1);'></i></div><div class='streamID' style='user-select: none;'>ID: <span style='user-select: text;'>" + streamID + "</span>\
|
||||||
<i class='las la-copy' data-sid='" + streamID + "' onclick='copyFunction(this.dataset.sid,event)' title='Copy this Stream ID to the clipboard' style='cursor:pointer'></i>\
|
<i class='las la-copy' data-sid='" + streamID + "' onclick='copyFunction(this.dataset.sid,event)' title='Copy this Stream ID to the clipboard' style='cursor:pointer'></i>\
|
||||||
|
<i class='las la-window-minimize' data--u-u-i-d='"+UUID+"' onclick='minimizeMe(this)' title='Minimize this control box' style='cursor:pointer'></i>\
|
||||||
<span id='label_" + UUID + "' class='addALabel' title='Click here to edit the label for this stream. Changes will propagate to all viewers of this stream'></span>\
|
<span id='label_" + UUID + "' class='addALabel' title='Click here to edit the label for this stream. Changes will propagate to all viewers of this stream'></span>\
|
||||||
</div>";
|
</div>";
|
||||||
|
|
||||||
|
|||||||
99
main.css
99
main.css
@ -731,8 +731,59 @@ hr {
|
|||||||
animation: pulse 2s infinite;
|
animation: pulse 2s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.minimized {
|
||||||
|
float: left;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
height: 24px;
|
||||||
|
overflow:hidden;
|
||||||
|
box-shadow: inset -1px 1px white
|
||||||
|
}
|
||||||
|
|
||||||
|
.minimized:nth-child(1) {
|
||||||
|
left:0px;
|
||||||
|
z-index:10;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(2) {
|
||||||
|
left:max(100px, calc(10% - 260px));
|
||||||
|
z-index:9;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(3) {
|
||||||
|
left:max(200px, calc(20% - 260px));
|
||||||
|
z-index:8;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(4) {
|
||||||
|
left:max(250px, calc(30% - 260px));
|
||||||
|
z-index:7;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(5) {
|
||||||
|
left:max(300px, calc(40% - 260px));
|
||||||
|
z-index:6;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(6) {
|
||||||
|
left:max(450px, calc(50% - 260px));
|
||||||
|
z-index:5;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(7) {
|
||||||
|
left:max(500px, calc(60% - 260px));
|
||||||
|
z-index:4;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(8) {
|
||||||
|
left:max(650px, calc(70% - 260px));
|
||||||
|
z-index:3;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(9) {
|
||||||
|
left:max(700px, calc(80% - 260px));
|
||||||
|
z-index:2;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(10) {
|
||||||
|
left:max(850px, calc(90% - 260px));
|
||||||
|
z-index:1;
|
||||||
|
}
|
||||||
|
.minimized:nth-child(11) {
|
||||||
|
left:max(900px, calc(100% - 260px));
|
||||||
|
z-index:0;
|
||||||
|
}
|
||||||
.battery {
|
.battery {
|
||||||
border: 3px solid #4192c5;
|
border: 3px solid #4192c5;
|
||||||
width: 11px;
|
width: 11px;
|
||||||
@ -1012,7 +1063,6 @@ button.glyphicon-button.active.focus {
|
|||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow: hidden;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
@ -2119,10 +2169,19 @@ span[data-action-type="stats-graphs-details-container"]>span{
|
|||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
}
|
}
|
||||||
.soloButton{
|
.soloButton{
|
||||||
padding:5px;word-wrap: break-word; overflow:hidden; white-space: nowrap; overflow: hidden; font-size:0.7em; text-overflow: ellipsis;
|
padding:5px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow:hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size:0.7em;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lowerRaisedHand{
|
.lowerRaisedHand{
|
||||||
margin: auto;margin-bottom:10px;display:none;background-color:yellow;
|
margin: auto;
|
||||||
|
margin-bottom:10px;
|
||||||
|
background-color:yellow;
|
||||||
}
|
}
|
||||||
.float {
|
.float {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
@ -3254,6 +3313,7 @@ div#chatBody a {
|
|||||||
width:1191px;
|
width:1191px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 5px 10px 10px 10px;
|
margin: 5px 10px 10px 10px;
|
||||||
|
max-width:100%;
|
||||||
}
|
}
|
||||||
.directorContainer {
|
.directorContainer {
|
||||||
background-color: var(--container-color);
|
background-color: var(--container-color);
|
||||||
@ -3261,7 +3321,8 @@ div#chatBody a {
|
|||||||
grid-template-columns: 1fr ;
|
grid-template-columns: 1fr ;
|
||||||
margin: 10px 0px 10px 10px;
|
margin: 10px 0px 10px 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
max-width: 1191px
|
max-width: min(100%, 1191px);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#directorLinksButton{
|
#directorLinksButton{
|
||||||
@ -3272,7 +3333,7 @@ div#chatBody a {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
padding: 10px 10px;
|
padding: 10px 10px;
|
||||||
width: 591px;
|
width: min(100%, 591px);
|
||||||
}
|
}
|
||||||
.directorBlock {
|
.directorBlock {
|
||||||
padding: 10px 10px 5px 10px;
|
padding: 10px 10px 5px 10px;
|
||||||
@ -3577,7 +3638,7 @@ i.las.la-circle {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.streamID i {
|
.streamID i {
|
||||||
margin-left: 5px;
|
margin-left: 1px;
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 1px;
|
top: 1px;
|
||||||
@ -4358,8 +4419,26 @@ input:checked + .slider:before {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.makeSmallerDirectorRoom{
|
||||||
|
max-width: calc(100% - 415px);
|
||||||
|
min-width: min(calc(100% - 395px), 75%);
|
||||||
|
}
|
||||||
|
.pinToSide{
|
||||||
|
top: unset;
|
||||||
|
left: unset;
|
||||||
|
right: 0;
|
||||||
|
transform: unset;
|
||||||
|
border-radius: unset;
|
||||||
|
height: 100%;
|
||||||
|
max-width: min(25%, 415px);
|
||||||
|
min-width: 395px;
|
||||||
|
overflow-y: auto;
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
#roomSettings{
|
||||||
|
max-height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Line Awesome Free';
|
font-family: 'Line Awesome Free';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@ -4520,6 +4599,8 @@ input:checked + .slider:before {
|
|||||||
content: "\f068"; }
|
content: "\f068"; }
|
||||||
.la-minus-circle:before {
|
.la-minus-circle:before {
|
||||||
content: "\f056"; }
|
content: "\f056"; }
|
||||||
|
.la-window-minimize:before {
|
||||||
|
content: "\f2d1"; }
|
||||||
.la-hat-wizard:before {
|
.la-hat-wizard:before {
|
||||||
content: "\f6e8"; }
|
content: "\f6e8"; }
|
||||||
.la-plus:before {
|
.la-plus:before {
|
||||||
|
|||||||
@ -270,7 +270,7 @@
|
|||||||
"share-website-iframe": "Website teilen",
|
"share-website-iframe": "Website teilen",
|
||||||
"run-a-speed-test": "Speed-Test",
|
"run-a-speed-test": "Speed-Test",
|
||||||
"read-the-guides": "Guides",
|
"read-the-guides": "Guides",
|
||||||
"info-blob": "\n<h2>Was ist VDO.Ninja</h2>\n<br>\n<li>100% <b>umsonst</b>; keine Downloads; keine persönliche Daten übertragen; keine Anmeldung</li>\n<li>Bring live-Videos von deinem Smartphone, remote Computer, oder Freunden direkt in OBS oder andere Studio Software.</li>\n<li>Wir verwenden die neuste Peer-to-Peer forwarding technology die Datenschutz und ultra-low latency bietet</li>\n<br>\n<li>Youtube video \n<i class=\"lab la-youtube\"></i>\n<a href=\"https://www.youtube.com/watch?v=QaA_6aOP9z8&list=PLWodc2tCfAH1WHjl4WAOOoRSscJ8CHACe&index=1\" alt=\"Youtube Video Demo VDO.Ninja\">Demo hier</a>\n</li>\n<br>\n<h3>\n🛠 Für Support, schau in den <a href=\"https://www.reddit.com/r/VDONinja/\">Sub-Reddit <i class=\"lab la-reddit-alien\"></i></a> oder tritt dem <a href=\"https://discord.vdo.ninja/\">Discord bei<i class=\"lab la-discord\"></i></a>. Die <a href=\"https://docs.vdo.ninja/\">Dokumentation ist hier</a> und meine private E-Mail ist <i>steve@seguin.email</i>\n</h3> \n\n",
|
"info-blob": "\n<h2>Was ist VDO.Ninja</h2>\n<br>\n<li>100% <b>kostenlos</b>; keine Downloads; keine persönliche Daten übertragen; keine Anmeldung</li>\n<li>Bring live-Videos von deinem Smartphone, remote Computer, oder Freunden direkt in OBS oder andere Studio Software</li>\n<li>Wir verwenden die neuste Peer-to-Peer forwarding technology die Datenschutz und ultra-low latency bietet</li>\n<br>\n<li>Youtube video \n<i class=\"lab la-youtube\"></i>\n<a href=\"https://www.youtube.com/watch?v=QaA_6aOP9z8&list=PLWodc2tCfAH1WHjl4WAOOoRSscJ8CHACe&index=1\" alt=\"Youtube Video Demo VDO.Ninja\">Demo hier</a>\n</li>\n<br>\n<h3>\n🛠 Für Support, schau in den <a href=\"https://www.reddit.com/r/VDONinja/\">Sub-Reddit <i class=\"lab la-reddit-alien\"></i></a> oder tritt dem <a href=\"https://discord.vdo.ninja/\">Discord bei<i class=\"lab la-discord\"></i></a>. Die <a href=\"https://docs.vdo.ninja/\">Dokumentation ist hier</a> und meine private E-Mail ist <i>steve@seguin.email</i>\n</h3> \n\n",
|
||||||
"add-to-scene": "Zur Szene hinzufügen",
|
"add-to-scene": "Zur Szene hinzufügen",
|
||||||
"forward-to-room": "Transferieren",
|
"forward-to-room": "Transferieren",
|
||||||
"record": "Aufnehmen",
|
"record": "Aufnehmen",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user