mirror of
https://github.com/SrIzan10/vdo.ninja.git
synced 2026-05-01 11:05:24 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d48483f113 | ||
|
|
595b233327 | ||
|
|
e64fa5c598 | ||
|
|
40ff06c77b | ||
|
|
9d1e1d7f53 | ||
|
|
a6332b347a | ||
|
|
84e6565c01 | ||
|
|
589d0e4575 | ||
|
|
c08d707a7f | ||
|
|
115f24fe96 | ||
|
|
db522b4ba4 | ||
|
|
20b68aff06 | ||
|
|
2f0a1ba99e | ||
|
|
61883e5e54 | ||
|
|
706d19bfd4 | ||
|
|
dc63c510c0 | ||
|
|
1d4b0dd02f | ||
|
|
ac7a2d15cb | ||
|
|
12fc6e0f1f |
215
IFRAME.md
Normal file
215
IFRAME.md
Normal file
@@ -0,0 +1,215 @@
|
||||
## OBS.Ninja - iFrame API documentation
|
||||
|
||||
OBS.Ninja (OBSN) is offers here a simple and free solution to quickly enable real-time video streaming in their websites. OBSN wishes to make live video streaming development accessible to any developer, even novices, yet still remain flexible and powerful.
|
||||
|
||||
While OBS.Ninja does offer source-code to customize the application and UI at a low level, this isn't for beginners and it is rather hard to maintain. As well, due to the complexity of video streaming in the web, typical approaches for offering API access isn't quite feasible either.
|
||||
|
||||
The solution decided on isn't an SDK framework, but rather the use of embeddable *IFrames* and a corresponding bi-directional iframe API. An [iframe](https://www.w3schools.com/tags/tag_iframe.ASP) allows us to embed a webpage inside a webpage, including OBS.Ninja into your own website.
|
||||
|
||||
Modern web browsers allow the parent website to communicate with the child webpage, giving a high-level of control to a developer, while also abstracting the complex code and hosting requirements. Functionality, we can make an OBSN video stream act much like an HTML video element tag, where you can issue commands like play, pause, or change video sources with ease.
|
||||
|
||||
Creating an OBSN iframe can be done in HTML or programmatically with Javascript like so:
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.allow="autoplay;camera;microphone";
|
||||
iframe.allowtransparency="false"
|
||||
iframe.src = "https://obs.ninja/?webcam";
|
||||
|
||||
Adding that iframe to the DOM will reveal a simple page accessing for a user to select and share their webcam. For a developer wishing to access a remote guest's stream, this makes the ingestion of that stream into production software like OBS Studios very easy. The level of customization and control opens up opportunities, such as a pay-to-join audience option for a streaming interactive broadcast experience.
|
||||
|
||||
An example of how this API is used by OBS.Ninja is with its Internet Speedtest, which has two OBS.Ninja IFrames on a single page. One iframe feeds video to the other iframe, and the speed at which it does this is a measure of the system's performance. Detailed stats of the connection are made available to the parent window, which displays the results.
|
||||
https://obs.ninja/speedtest
|
||||
|
||||
A sandbox of options is available at this page, too: https://obs.ninja/iframe You can enter an OBS.Ninja URL in the input box to start using it. For developers, viewing the source of that page will reveal examples of how all the available functions work, along with a way to test and play with each of them. You can also see here for the source-code on GitHub: https://github.com/steveseguin/obsninja/blob/master/iframe.html
|
||||
|
||||
One thing to note about this iframe API is that it is a mix of URL parameters given to the iframe *src* URL, but also the postMessage and addEventListener methods of the browser. The later is used to dynamically control OBS.Ninja, while the former is used to initiate the instance to a desired state.
|
||||
|
||||
For more information on the URL parameters thare are available, please see: https://github.com/steveseguin/obsninja/wiki/Advanced-Settings
|
||||
|
||||
Some of the more interesting ones primarily for iframe users might include:
|
||||
|
||||
- &webcam
|
||||
- &screenshare
|
||||
- &videodevice=1 or 0
|
||||
- &audiodevice=1 or 0
|
||||
- &autostart
|
||||
- &chroma
|
||||
- &transparency
|
||||
-
|
||||
As for API, allow for dynamic messaging, below are examples of the options available:
|
||||
|
||||
- Mute Speaker
|
||||
- Mute Mic
|
||||
- Disconnect
|
||||
- Change Video Bitrate
|
||||
- Reload the page
|
||||
- Change the volume
|
||||
- Request detailed connection stats
|
||||
- Access the loudness level of the audio
|
||||
- Send/Recieve a chat message to other connected guests
|
||||
- Get notified when there is a video connection
|
||||
|
||||
As for the actually details for methods and options available to dynamically control child OBSN iframe, they are primarily kept up to via the iframe.html file that is mentioned previously. see: *iframe.html*. Below is a snippet from that file:
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Mute Speaker";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mute":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Un-Mute Speaker";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mute":false}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Toggle Speaker";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mute":"toggle"}, '*');}
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Mute Mic";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mic":false}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Un-Mute Mic";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mic":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Toggle Mic";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mic":"toggle"}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Disconnect";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Low Bitrate";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":30}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "High Bitrate";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":5000}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Default Bitrate";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":-1}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Reload";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"reload":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "50% Volume";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"volume":0.5}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "100% Volume";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"volume":1.0}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Request Stats";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"getStats":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Request Loudness Levels";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Stop Sending Loudness Levels";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":false}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Say Hello";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"sendChat":"Hello!"}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "previewWebcam()";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"function":"previewWebcam"}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "CLOSE IFRAME";
|
||||
button.onclick = function(){iframeContainer.parentNode.removeChild(iframeContainer);};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
As for listening events, where the parent listens for responses or events from the OBSN child frame:
|
||||
|
||||
//////////// LISTEN FOR EVENTS
|
||||
|
||||
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
||||
var eventer = window[eventMethod];
|
||||
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
|
||||
|
||||
eventer(messageEvent, function (e) {
|
||||
if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
|
||||
|
||||
if ("stats" in e.data){
|
||||
var outputWindow = document.createElement("div");
|
||||
|
||||
var out = "<br />total_inbound_connections:"+e.data.stats.total_inbound_connections;
|
||||
out += "<br />total_outbound_connections:"+e.data.stats.total_outbound_connections;
|
||||
|
||||
for (var streamID in e.data.stats.inbound_stats){
|
||||
out += "<br /><br /><b>streamID:</b> "+streamID+"<br />";
|
||||
out += printValues(e.data.stats.inbound_stats[streamID]);
|
||||
}
|
||||
|
||||
outputWindow.innerHTML = out;
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
}
|
||||
|
||||
if ("gotChat" in e.data){
|
||||
var outputWindow = document.createElement("div");
|
||||
outputWindow.innerHTML = e.data.gotChat.msg;
|
||||
outputWindow.style.border="1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
}
|
||||
|
||||
if ("action" in e.data){
|
||||
var outputWindow = document.createElement("div");
|
||||
outputWindow.innerHTML = "child-page-action: "+e.data.action+"<br />";
|
||||
outputWindow.style.border="1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
}
|
||||
|
||||
if ("loudness" in e.data){
|
||||
console.log(e.data);
|
||||
if (document.getElementById("loudness")){
|
||||
outputWindow = document.getElementById("loudness");
|
||||
} else {
|
||||
var outputWindow = document.createElement("div");
|
||||
outputWindow.style.border="1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
outputWindow.id = "loudness";
|
||||
}
|
||||
outputWindow.innerHTML = "child-page-action: loudness<br />";
|
||||
for (var key in e.data.loudness) {
|
||||
outputWindow.innerHTML += key + " Loudness: " + e.data.loudness[key] + "\n";
|
||||
}
|
||||
outputWindow.style.border="1px black";
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
This OBS.Ninja API is developed and expanded based on user feedback and requests. It is by no means complete.
|
||||
|
||||
Regarding versioning, I currently host past versions of OBS.Ninja, so using those past versions can ensure some level of consistency and expectation. https://obs.ninja/v12/ for example is the version 12 hosted version. The active and main production version of OBSN of course undergoes constant updates, and while I try to maintain backwards compatibility with changes to the API, it is still early days and changes might happen.
|
||||
|
||||
Please feel free to follow me in the OBS.Ninja Discord channel, where I post news about updates and listen to requests. The upcoming version of OBS.Ninja is also often hosted at https://obs.ninja/beta, where you can explore new features and help crush any unexpected bugs.
|
||||
|
||||
|
||||
-steve
|
||||
@@ -1,7 +1,7 @@
|
||||
The OBS.Ninja source repository is governed by the GNU AFFERO GENERAL PUBLIC LICENSE. (AGPL-3.0)
|
||||
That AGPL-3.0 licence can be found here: https://raw.githubusercontent.com/steveseguin/obsninja/master/AGPLv3.md
|
||||
|
||||
In essence, OBS.Ninja is open-source and free to use, both for commericial and non-commericial use.
|
||||
In essence, OBS.Ninja is open-source and free to use, both for commercial and non-commercial use.
|
||||
Modifications of AGPL-3.0 licenced code must be made publicly accessible. Please refer to that licence.
|
||||
|
||||
Some individual source files may contain different licencing term and perhaps different copyright holders.
|
||||
|
||||
@@ -14,9 +14,13 @@ Also check out the FAQ for more info: https://github.com/steveseguin/obsninja/wi
|
||||
## How to use:
|
||||
I demo the basic usage of OBS.Ninja on YouTube: https://www.youtube.com/watch?v=6R_sQKxFAhg
|
||||
|
||||
Here is a podcast series showing how to use different basic OBS.Ninja features, including macOS support: https://www.youtube.com/watch?v=XfSqufuoV74&list=PLWodc2tCfAH1l_LDvEyxEqFf42hOBKqQM
|
||||
|
||||
And Here is another video series touching on some more advanced settings: https://www.youtube.com/watch?v=mQ1Jdhf5aYg&list=PL8VJWj2-XLFpFu3G35Hdm1nKZ2xn9_0_8
|
||||
|
||||
Check the subreddit for added use cases, advanced features, and support. Advanced features includes high-quality audio modes, custom video resolutions, and more.
|
||||
|
||||
MacOS users will face some challenges in using OBS currently, but there are workarounds. Please see the subreddit or the Wiki.
|
||||
MacOS users will face some challenges in using OBS 25/26, but there are workarounds. Please see the subreddit or the Wiki.
|
||||
|
||||
## What's in this repo?
|
||||
This repo contains software for OBS.Ninja, including the HTML landing page for its Electron Capture app offering. A sample config file and instructions for setting up a TURN server (video relay server), is also provided. You may also find the Wiki for the project in this repo, which contains added information on how to use the software.
|
||||
@@ -48,6 +52,9 @@ If urgent, join me on discord: https://discord.gg/EksyhGA or email me at steve@s
|
||||
A better way to perform "Window Capturing" on desktop if OBS Browser Sources fails you. A downloadable tool designed to enhance OBS.Ninja.
|
||||
https://github.com/steveseguin/electroncapture
|
||||
|
||||
#### CAPTION.Ninja
|
||||
A free AI-based closed-captioning tool to add speech-to-text overlays to OBS Studio. It's browser-based with an easy OBS integration. Developed by Steve as well! https://caption.ninja
|
||||
|
||||
#### Steves.app:
|
||||
A website designed to also work with OBS.Ninja as a Broadcasting tool. Share your webcam, window, desktop, or video file with friends and family. Peer-2-peer, so privacy can be maintained, but you can also list your broadcasts for others to watch.
|
||||
https://steves.app/
|
||||
|
||||
@@ -6,11 +6,16 @@ $("body").append('<style id="lightbox-animations" type="text/css"></style>');
|
||||
$(".column").on('click', function() {
|
||||
/* The position of the container will be set to fixed, so set the top & left properties of the container */
|
||||
|
||||
if ( $(this).hasClass( "skip-animation" )){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var bounding_box = $(this).get(0).getBoundingClientRect();
|
||||
$(this).css({ top: bounding_box.top + 'px', left: bounding_box.left -20+ 'px' });
|
||||
|
||||
/* Set container to fixed position. Add animation */
|
||||
$(this).addClass('in-animation');
|
||||
$(this).addClass('in-animation').removeClass('pointer');
|
||||
|
||||
/* An empty container has to be added in place of the lightbox container so that the elements below don't come up
|
||||
Dimensions of this empty container is the same as the original container */
|
||||
@@ -91,8 +96,8 @@ if(e.originalEvent.animationName == 'inlightbox') {
|
||||
/* On animation end from full-screen to normal */
|
||||
else if(e.originalEvent.animationName == 'outlightbox') {
|
||||
/* Remove fixed positioning, remove animation rules */
|
||||
$(this).removeClass('in-animation').removeClass('out-animation').removeClass('columnfade');
|
||||
|
||||
$(this).removeClass('in-animation').removeClass('out-animation').removeClass('columnfade').addClass('pointer');
|
||||
|
||||
/* Remove the empty container that was earlier added */
|
||||
$("#empty-container").remove();
|
||||
|
||||
|
||||
28
devices.html
Normal file
28
devices.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<html>
|
||||
<head><meta charset="UTF-8"></head>
|
||||
<body>
|
||||
<pre><code id="json-container"></code></pre>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
var list = [];
|
||||
|
||||
|
||||
navigator.mediaDevices.enumerateDevices()
|
||||
.then(function(devices) {
|
||||
devices.forEach(function(device) {
|
||||
console.log(device.kind + ": " + device.label +
|
||||
" id = " + device.deviceId);
|
||||
list.push(device);
|
||||
});
|
||||
document.getElementById('json-container').innerHTML = JSON.stringify(list, null, 2);
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.log(err.name + ": " + err.message);
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
93
dock.html
93
dock.html
@@ -50,6 +50,12 @@ button{
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.gone {
|
||||
position: absolute;
|
||||
display:inline-block;
|
||||
left: -9999px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -69,17 +75,35 @@ function copyFunction(copyText) {
|
||||
|
||||
}
|
||||
function generateStreamID(){
|
||||
var text = "";
|
||||
var possible = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789";
|
||||
for (var i = 0; i < 7; i++){
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
var text = "";
|
||||
var possible = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789";
|
||||
for (var i = 0; i < 7; i++){
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
console.log(text);
|
||||
return text;
|
||||
};
|
||||
function toHexString(byteArray){
|
||||
return Array.prototype.map.call(byteArray, function(byte){
|
||||
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
|
||||
}).join('');
|
||||
}
|
||||
generateHash = function (str, length=false){
|
||||
var buffer = new TextEncoder("utf-8").encode(str);
|
||||
return crypto.subtle.digest("SHA-256", buffer).then(
|
||||
function (hash) {
|
||||
hash = new Uint8Array(hash);
|
||||
if (length){
|
||||
hash = hash.slice(0, parseInt(parseInt(length)/2));
|
||||
}
|
||||
hash = toHexString(hash);
|
||||
return hash;
|
||||
}
|
||||
console.log(text);
|
||||
return text;
|
||||
};
|
||||
);
|
||||
};
|
||||
|
||||
function generateInvite(){
|
||||
var title = encodeURI(getById("videoname").value);
|
||||
var title = encodeURI(getById("videoname").value.replace(/[\W]+/g,"_"));
|
||||
if (title.length){
|
||||
title = "&label="+title;
|
||||
}
|
||||
@@ -111,16 +135,10 @@ function generateInvite(){
|
||||
}
|
||||
|
||||
if (getById("invite_joinroom").value.trim().length){
|
||||
sendstr+="&room="+getById("invite_joinroom").value.trim();
|
||||
viewstr+="&scene=1&room="+getById("invite_joinroom").value.trim();
|
||||
sendstr+="&room="+getById("invite_joinroom").value.replace(/[\W]+/g,"_");
|
||||
viewstr+="&scene&room="+getById("invite_joinroom").value.replace(/[\W]+/g,"_");
|
||||
}
|
||||
|
||||
if (getById("invite_password").value.trim().length){
|
||||
sendstr+="&password";
|
||||
viewstr+="&password="+getById("invite_password").value.trim();
|
||||
}
|
||||
|
||||
|
||||
if (getById("invite_group_chat_type").value){ // 0 is default
|
||||
if (getById("invite_group_chat_type").value==1){ // no video
|
||||
sendstr+="&novideo";
|
||||
@@ -142,13 +160,31 @@ function generateInvite(){
|
||||
var href = window.location.href;
|
||||
var dir = href.substring(0, href.lastIndexOf('/')) + "/";
|
||||
|
||||
sendstr = dir+'?push=' + sid + sendstr;
|
||||
viewstr = dir+'?view=' + sid + viewstr + title;
|
||||
getById("container-setup").style.display="none";
|
||||
getById("container-links").style.display="block";
|
||||
var salt = location.hostname; // "obs.ninja" is the expected default. You will want to change this if hosting dock.html locally.
|
||||
|
||||
if (getById("invite_password").value.trim().length){
|
||||
generateHash(getById("invite_password").value.trim().replace(/[\W]+/g,"_")+salt,4).then(function(hash){
|
||||
sendstr+="&hash="+hash;
|
||||
viewstr+="&password="+getById("invite_password").value.trim();
|
||||
sendstr = dir+'?push=' + sid + sendstr;
|
||||
viewstr = dir+'?view=' + sid + viewstr + title;
|
||||
getById("container-setup").style.display="none";
|
||||
getById("container-links").style.display="block";
|
||||
|
||||
getById("guest-link").value = sendstr;
|
||||
getById("obs-link").value = viewstr;
|
||||
});
|
||||
} else {
|
||||
sendstr = dir+'?push=' + sid + sendstr;
|
||||
viewstr = dir+'?view=' + sid + viewstr + title;
|
||||
getById("container-setup").style.display="none";
|
||||
getById("container-links").style.display="block";
|
||||
|
||||
getById("guest-link").value = sendstr;
|
||||
getById("obs-link").value = viewstr;
|
||||
}
|
||||
|
||||
|
||||
getById("guest-link").value = sendstr;
|
||||
getById("obs-link").value = viewstr;
|
||||
}
|
||||
|
||||
function goBack(){
|
||||
@@ -158,10 +194,13 @@ function goBack(){
|
||||
|
||||
document.addEventListener("dragstart", event => {
|
||||
var url = event.target.href || event.target.value;
|
||||
|
||||
if (!url || !url.startsWith('https://')) return;
|
||||
if (event.target.dataset.drag!="1"){
|
||||
return;
|
||||
}
|
||||
//event.target.ondragend = function(){event.target.blur();}
|
||||
|
||||
var streamId = url.split('view=');
|
||||
var label = url.split('label=');
|
||||
|
||||
@@ -173,8 +212,12 @@ document.addEventListener("dragstart", event => {
|
||||
url += '&layer-width=1920'; // this isn't always 100% correct, as the resolution can fluxuate, but it is probably good enough
|
||||
url += '&layer-height=1080';
|
||||
|
||||
console.warn(url);
|
||||
event.dataTransfer.setDragImage(document.querySelector('#dragImage'), 24, 24);
|
||||
event.dataTransfer.setData("text/uri-list", encodeURI(url));
|
||||
//event.dataTransfer.setData("url", encodeURI(url));
|
||||
|
||||
//warnlog(event);
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
@@ -248,5 +291,9 @@ document.addEventListener("dragstart", event => {
|
||||
<i>(links are draggable)</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gone" >
|
||||
<!-- This image is used when dragging elements -->
|
||||
<img src="./images/favicon-32x32.png" id="dragImage" />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,5 @@
|
||||
<html>
|
||||
<meta charset="UTF-8">
|
||||
<head><style>
|
||||
html {
|
||||
border:0;
|
||||
@@ -108,11 +109,23 @@ input[type='checkbox']:checked {
|
||||
max-width:486px
|
||||
}
|
||||
}
|
||||
|
||||
#messageDiv {
|
||||
font-size: .7em;
|
||||
color: #DDD;
|
||||
transition: all 0.5s linear;
|
||||
font-style: italic;
|
||||
opacity: 0;
|
||||
text-align: center;
|
||||
margin: 10px 0;
|
||||
}
|
||||
</style></head>
|
||||
<body >
|
||||
|
||||
<div id="header" style="-webkit-app-region: drag;color:white;font-size:2em">OBS.Ninja</div>
|
||||
<div class="formcss" >
|
||||
|
||||
<div id='warning4mac' style="border:2px dotted; display:none;max-width:700px; padding:10px; margin:0 90px 20px 90px;color:white;font-size:1.3em"> 🚨 If using OBS v26 on macOS, right-click the Electron Capture app and disable <i>Always-on-Top</i> to reveal it during window-selection. You can enable it again afterwards.</div>
|
||||
|
||||
<input type="checkbox" class="check" id="prefervp9" name="prefervp9" value="false" onclick="modURL(this);">
|
||||
<label for="prefervp9">Force VP9 Codec</label>
|
||||
@@ -129,7 +142,8 @@ input[type='checkbox']:checked {
|
||||
<input type="checkbox" class="check" id="buffer" name="buffer" value="false" onclick="modURL(this);">
|
||||
<label for="buffer">Lip-sync Fix</label>
|
||||
|
||||
<br><br><br>
|
||||
<br>
|
||||
<div id="messageDiv" style='display:block'><br /></div>
|
||||
<div class="formcss"><center>
|
||||
<input type="text" id="changeText" class="inputfield" value="http://obs.ninja/?view=" onchange="modURL" onkeyup="enterPressed(event, gohere);" />
|
||||
<button onclick="gohere();" id="gobutton">GO</button>
|
||||
@@ -150,6 +164,10 @@ input[type='checkbox']:checked {
|
||||
*
|
||||
*/
|
||||
|
||||
//if (navigator.userAgent.indexOf('Mac OS X') != -1){
|
||||
// document.getElementById("warning4mac").style.display="block";
|
||||
//}
|
||||
|
||||
var audioOutputSelect = document.querySelector('select#audioOutput');
|
||||
audioOutputSelect.disabled = !('sinkId' in HTMLMediaElement.prototype);
|
||||
audioOutputSelect.onclick = getPermssions;
|
||||
@@ -178,7 +196,12 @@ function getPermssions(e=null){
|
||||
listed=true;
|
||||
audioOutputSelect.focus();
|
||||
|
||||
}).catch(function(){alert("Failed to list available output devices\n\nPlease ensure you allowed the microphone permissions.");});
|
||||
}).catch(function(){
|
||||
document.getElementById("messageDiv").innerHTML = "Failed to list available output devices\n\nPlease ensure you allowed the microphone permissions.";
|
||||
document.getElementById("messageDiv").style.display="block";
|
||||
setTimeout(function(){document.getElementById("messageDiv").style.opacity="1.0";},0);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function gotDevices(deviceInfos) {
|
||||
@@ -310,10 +333,13 @@ function modURL(ele=false){
|
||||
|
||||
if (ele.id =="stereo"){
|
||||
if (document.getElementById("stereo").checked){
|
||||
url=updateURLParameter(url, "stereo", "");
|
||||
alert('Audio bitrate increased to 256kbps.\n\nPlease note: the Video Publisher must also have the stereo flag enabled for stereo to work.');
|
||||
url=updateURLParameter(url, "proaudio", "");
|
||||
document.getElementById("messageDiv").innerHTML = "Audio bitrate increased to 256-kbps.\n\nPlease note that the Sender must also have the <b>&proaudio</b> flag added for full-effect";
|
||||
document.getElementById("messageDiv").style.display="block";
|
||||
setTimeout(function(){document.getElementById("messageDiv").style.opacity="1.0";},0);
|
||||
} else {
|
||||
url=updateURLParameter(url, "stereo", false);
|
||||
url=updateURLParameter(url, "proaudio", false);
|
||||
setTimeout(function(){document.getElementById("messageDiv").style.opacity="0";},0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
119
iframe.html
119
iframe.html
@@ -4,7 +4,7 @@
|
||||
body{
|
||||
padding:0;
|
||||
margin:0;
|
||||
background-color: rgb(253,253,253);
|
||||
background-color: rgb(222,242,253);
|
||||
}
|
||||
iframe {
|
||||
border:0;
|
||||
@@ -33,13 +33,14 @@ button{
|
||||
</style>
|
||||
<script>
|
||||
|
||||
function loadIframe(){
|
||||
function loadIframe(){ // this is pretty important if you want to avoid camera permission popup problems. You can also call it automatically via: <body onload=>loadIframe();"> , but don't call it before the page loads.
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
var iframeContainer = document.createElement("div");
|
||||
var iframesrc = document.getElementById("viewlink").value;
|
||||
iframe.allow="autoplay;camera;microphone";
|
||||
iframe.allowtransparency="true"
|
||||
iframe.allowtransparency="true";
|
||||
iframe.allowfullscreen ="true";
|
||||
|
||||
if (iframesrc==""){
|
||||
iframesrc="./";
|
||||
@@ -80,7 +81,7 @@ function loadIframe(){
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Mute Speaker";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mute":true}, '*');};
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mute":true}, '*');}; // "speaker" also works in the same way.
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
@@ -90,7 +91,7 @@ function loadIframe(){
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Toggle Speaker";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mute":"toggle"}, '*');}
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mute":"toggle"}, '*');}; // open to a better suggestion here.
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
@@ -108,6 +109,24 @@ function loadIframe(){
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"mic":"toggle"}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Mute Camera";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"camera":false}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Unmute Camera";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"camera":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Toggle Camera";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"camera":"toggle"}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Disconnect";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');};
|
||||
@@ -148,23 +167,71 @@ function loadIframe(){
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"getStats":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Request Loudness Levels";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Stop Sending Loudness Levels";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":false}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Say Hello";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"sendChat":"Hello!"}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Insert Style Sheet";
|
||||
var stylesheet = "#main { zoom: 0.5;} video {float: left; margin: 0; padding: 0; } #info {display:none;}";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"style":stylesheet}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "get StreamIDs and labels";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"getStreamIDs":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Start AutoMixer";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"automixer":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Stop AutoMixer";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"automixer":false}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Add Target Video";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"target":"*", "add":true, "settings":{"style":{"width":"640px", "height":"360px", "float":"left", "border":"10px solid red", "display":"block"}}}, '*');}; // target can be a stream ID or * for all.
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Remove Target Video";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"target":"*", "remove": true}, '*');}; // target can be a stream ID or * for all.
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "previewWebcam()";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"function":"previewWebcam"}, '*');}; // publishScreen
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Change Add Camera text";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"function":"changeHTML", "target":"add_camera", "value":"NEW CAMERA TEXT"}, '*');}; // change text of add camera button
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "CLOSE IFRAME";
|
||||
button.onclick = function(){iframeContainer.parentNode.removeChild(iframeContainer);};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////// LISTEN FOR EVENTS
|
||||
|
||||
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
||||
@@ -178,7 +245,7 @@ function loadIframe(){
|
||||
if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
|
||||
|
||||
if ("stats" in e.data){
|
||||
var outputWindow = document.createElement("outputWindow");
|
||||
var outputWindow = document.createElement("div");
|
||||
console.log(e.data.stats);
|
||||
|
||||
|
||||
@@ -195,11 +262,49 @@ function loadIframe(){
|
||||
}
|
||||
|
||||
if ("gotChat" in e.data){
|
||||
var outputWindow = document.createElement("outputWindow");
|
||||
var outputWindow = document.createElement("div");
|
||||
outputWindow.innerHTML = e.data.gotChat.msg;
|
||||
outputWindow.style.border="1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
}
|
||||
|
||||
if ("action" in e.data){
|
||||
var outputWindow = document.createElement("div");
|
||||
outputWindow.innerHTML = "child-page-action: "+e.data.action+"<br />";
|
||||
outputWindow.style.border="1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
}
|
||||
|
||||
|
||||
if ("streamIDs" in e.data){
|
||||
var outputWindow = document.createElement("div");
|
||||
outputWindow.innerHTML = "child-page-action: streamIDs<br />";
|
||||
for (var key in e.data.streamIDs) {
|
||||
outputWindow.innerHTML += "streamID: " + key + ", label:"+e.data.streamIDs[key] + "\n";
|
||||
}
|
||||
outputWindow.style.border="1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
}
|
||||
|
||||
if ("loudness" in e.data){
|
||||
console.log(e.data);
|
||||
if (document.getElementById("loudness")){
|
||||
outputWindow = document.getElementById("loudness");
|
||||
} else {
|
||||
var outputWindow = document.createElement("div");
|
||||
outputWindow.style.border="1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
outputWindow.id = "loudness";
|
||||
}
|
||||
outputWindow.innerHTML = "child-page-action: loudness<br />";
|
||||
for (var key in e.data.loudness) {
|
||||
outputWindow.innerHTML += key + " Loudness: " + e.data.loudness[key] + "\n";
|
||||
}
|
||||
outputWindow.style.border="1px black";
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
305
index.html
305
index.html
@@ -5,9 +5,9 @@
|
||||
try {
|
||||
var msie = window.navigator.userAgent.indexOf("MSIE ");
|
||||
if (msie>0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)){ // If MSIE or IE 11
|
||||
alert("Internet Explorer is not supported.\n\nPlease consider using Google Chrome instead\n\nYou will be forwarded to the download page for Google Chrome now.");
|
||||
alert("Internet Explorer is not supported.\n\nPlease consider using Microsoft Edge or Google Chrome instead\n\nYou will be forwarded to the download page for MS Edge now.");
|
||||
console.error("INTERNET EXPLORER IS EVIL");
|
||||
window.location = "https://www.google.com/chrome/";
|
||||
window.location = "https://www.microsoft.com/edge";
|
||||
}
|
||||
} catch(e){
|
||||
console.error(e);
|
||||
@@ -47,14 +47,14 @@
|
||||
<meta property="twitter:image" content="./images/obsNinja_logo_full.png" />
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<!-- <script src="//console.re/connector.js" data-channel="obsninjaalpha" type="text/javascript" id="consolerescript"></script>-->
|
||||
<!-- <script src="//console.re/connector.js" data-channel="obsninjadev" type="text/javascript" id="consolerescript"></script>-->
|
||||
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css">
|
||||
<script type="text/javascript" crossorigin="anonymous" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter-latest.js"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/qrcode.min.js"></script>
|
||||
<script type="text/javascript" src="./thirdparty/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="./main.css?ver=11" />
|
||||
<link rel="stylesheet" href="./main.css?ver=22" />
|
||||
</head>
|
||||
<body id="main" >
|
||||
<body id="main" class="hidden">
|
||||
<span itemprop="image" itemscope itemtype="image/png">
|
||||
<link itemprop="url" href="./images/obsNinja_logo_full.png" />
|
||||
</span>
|
||||
@@ -62,10 +62,10 @@
|
||||
<span itemprop="thumbnail" itemscope itemtype="http://schema.org/ImageObject">
|
||||
<link itemprop="url" href="./images/obsNinja_logo_full.png" />
|
||||
</span>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=19"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=60"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/CodecsHandler.js?ver=22"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./webrtc.js?ver=118"></script>
|
||||
<input id="zoomSlider" type="range" style="display: none;" />
|
||||
<div id="header"">
|
||||
<div id="header">
|
||||
<a id="logoname" href="./" style="text-decoration: none; color: white; margin: 2px;">
|
||||
<span data-translate="logo-header">
|
||||
<font id="qos">O</font>BS.Ninja
|
||||
@@ -73,26 +73,26 @@
|
||||
</a>
|
||||
<div id="head1" style="display: inline-block; padding:1px; position: relative;">
|
||||
<input id="joinroomID" name="joinroomID" size="22" placeholder="Join by Room Name here" />
|
||||
<button style="padding:1px;margin:0;" onclick="jumptoroom();">GO</button>
|
||||
<button onclick="jumptoroom();">GO</button>
|
||||
</div>
|
||||
<div id="head3" style="display: inline-block;" class="advanced">
|
||||
<font style="color: #888;" id="copythisurl">
|
||||
<span data-translate="copy-this-url">Copy this URL into an OBS "Browser Source"</span> <i style="color: #CCC;" class="las la-long-arrow-alt-right"></i>
|
||||
</font>
|
||||
<input
|
||||
<a
|
||||
id="reshare"
|
||||
data-drag="1"
|
||||
onclick="popupMessage(event);copyFunction(this)"
|
||||
class="task"
|
||||
class="task grabLinks"
|
||||
onmousedown="copyFunction(this)"
|
||||
style="font-weight: bold; color: #afa; cursor: grab; background-color: #0000; font-size: 115%; min-width: 335px; max-width: 800px;"
|
||||
/>
|
||||
<i class="las la-paperclip task" style="color: #DDD;" onclick="popupMessage(event);copyFunction(document.getElementById('reshare'));" onmouseover="this.style.cursor='pointer'"></i>
|
||||
style="font-weight: bold; color: #afa !important; cursor: grab; background-color: #0000; font-size: 115%; min-width: 335px; max-width: 800px;"
|
||||
></a>
|
||||
<i class="las la-paperclip" style="color: #DDD;" onclick="popupMessage(event);copyFunction(document.getElementById('reshare'));" onmouseover="this.style.cursor='pointer'"></i>
|
||||
</div>
|
||||
<div id="head4" style="display: inline-block;" class="advanced">
|
||||
<font style="font-size: 68%; color: white;">
|
||||
|
||||
<span data-translate="you-are-in-the-control-center">You are in the room's control center</span>:
|
||||
<span data-translate="you-are-in-the-control-center">Control center for room:</span>
|
||||
|
||||
<div id="dirroomid" style="font-size: 140%; color: #99c; display: inline-block;"></div>
|
||||
</font>
|
||||
@@ -109,6 +109,9 @@
|
||||
<i id="chattoggle" class="toggleSize las la-comment-alt my-float"></i>
|
||||
<div id="chatNotification"></div>
|
||||
</div>
|
||||
<div id="mutespeakerbutton" title="Mute the Speaker" onclick="toggleSpeakerMute()" class="advanced float" style="cursor: pointer;" alt="Toggle the speaker output">
|
||||
<i id="mutespeakertoggle" class="toggleSize las la-volume-up my-float" style="position: relative; top: 0.5px;"></i>
|
||||
</div>
|
||||
<div id="mutebutton" title="Mute the Mic" onclick="toggleMute()" class="advanced float" style="cursor: pointer;" alt="Toggle the mic">
|
||||
<i id="mutetoggle" class="toggleSize las la-microphone my-float" style="position: relative; top: 0.5px;"></i>
|
||||
</div>
|
||||
@@ -126,58 +129,62 @@
|
||||
<span
|
||||
id="helpbutton"
|
||||
title="Show Help Info"
|
||||
onclick="alert('Email steve@seguin.email if the system breaks or check https://reddit.com/r/obsninja for support.\n\nThere are some advanced options hidden away, such as persistent stream links and custom resolutions; see the Wiki.')"
|
||||
onclick="alert('Email steve@seguin.email if the system breaks or check https://reddit.com/r/obsninja for support.\n\nThe Wiki contains many help guides and advanced settings.\n\nAccess the debug menu by pressing CTRL (command) and Left-Clicking on a video.\n\nMost issues can be fixed by using Wired Internet instead of Wi-Fi.')"
|
||||
style="cursor: pointer; display:none;"
|
||||
alt="How to Use This with OBS"
|
||||
>
|
||||
<i class="las la-question-circle " style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 24px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;"></i>
|
||||
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 24px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-question-circle" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span title="Language Options" onclick="toggle(document.getElementById('languages'));" id="translateButton">
|
||||
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 2px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-language" aria-hidden="true"></i>
|
||||
<i style="float: right; bottom: 0px; cursor: pointer; position: fixed; right: 2px; color: #d9e4eb; padding: 2px; margin: 2px 2px 0 0; font-size: 140%;" class="las la-language" aria-hidden="true"></i>
|
||||
</span>
|
||||
<div id="mainmenu" class="row" style="opacity: 0; align: center;">
|
||||
<div id="container-1" class="column columnfade" style=" overflow-y: auto;">
|
||||
<div id="container-1" class="column columnfade pointer" style=" overflow-y: auto;">
|
||||
<h2>
|
||||
<span data-translate="add-group-chat">Add Group Chat to OBS</span>
|
||||
</h2>
|
||||
<div class="container-inner">
|
||||
<br />
|
||||
<br />
|
||||
<span data-translate="rooms-allow-for">Rooms allow for simplified group-chat and the advanced management of multiple streams at once.</span>
|
||||
<span data-translate="rooms-allow-for">Rooms allow for group-chat and the tools to manage multiple guests.</span>
|
||||
<br />
|
||||
<br />
|
||||
<p>
|
||||
<b>
|
||||
<table>
|
||||
<tr>
|
||||
<th><b>
|
||||
<span data-translate="room-name">Room Name</span>:
|
||||
</b>
|
||||
<input id="videoname1" placeholder="Enter a Room Name here" onkeyup="enterPressed(event, createRoom);" size="30" maxlength="50" style="font-size: 110%; padding: 5px;" />
|
||||
<br />
|
||||
<br />
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
</b></th>
|
||||
<th><input id="videoname1" placeholder="Enter a Room Name here" onkeyup="enterPressed(event, createRoom);" size="30" maxlength="30" style="font-size: 110%; padding: 5px;" /></th>
|
||||
|
||||
</tr><tr>
|
||||
|
||||
<th><b>
|
||||
<span data-translate="password-input-field">Password</span>:
|
||||
</b>
|
||||
<input id="passwordRoom" placeholder="Optional room password here" onkeyup="enterPressed(event, createRoom);" size="30" maxlength="50" style="font-size: 110%; padding: 5px;" />
|
||||
</th><th>
|
||||
<input id="passwordRoom" placeholder="Optional room password here" onkeyup="enterPressed(event, createRoom);" size="30" maxlength="30" style="font-size: 110%; padding: 5px;" />
|
||||
</th>
|
||||
|
||||
</tr><tr><th></th><th>
|
||||
<br />
|
||||
<br />
|
||||
</p>
|
||||
<button onclick="createRoom()" class="gobutton" style="float: left;">
|
||||
<span data-translate="enter-the-rooms-control">Enter the Room's Control Center</span>
|
||||
</button>
|
||||
<br /><br />
|
||||
<button class="white" style="display: block;" onclick="toggle(document.getElementById('roomnotes'),this);">
|
||||
<span data-translate="show-tips">Show me some tips..</span>
|
||||
</button>
|
||||
</th></tr>
|
||||
</table>
|
||||
<br />
|
||||
<button onclick="createRoom()" class="gobutton">
|
||||
<span data-translate="enter-the-rooms-control">Enter the Room's Control Center</span>
|
||||
</button>
|
||||
<br />
|
||||
<button onclick="toggle(document.getElementById('roomnotes'),this);">
|
||||
<span data-translate="show-tips">Show me some tips..</span>
|
||||
</button><br />
|
||||
<ul style=" margin: auto auto; max-width: 500px; display: none; text-align: left;" id="roomnotes">
|
||||
<br />
|
||||
<span data-translate="added-notes">
|
||||
<u>
|
||||
<i>Important Notes:</i><br /><br />
|
||||
<i>Important Tips:</i><br /><br />
|
||||
</u>
|
||||
<li>Invite only guests to the room that you trust.</li>
|
||||
<li>iOS devices will share just their audio with other room guests; not video. This is intended as a way to avoid a hardware limitation with iOS devices.</li>
|
||||
<li>iOS devices will share just their audio with other room guests; not video. This is intentional.</li>
|
||||
<li>The "Recording" option is considered experimental.</li>
|
||||
</span>
|
||||
</ul>
|
||||
@@ -190,7 +197,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="container-3" class="column columnfade" onclick="previewWebcam()" style=" overflow-y: auto;">
|
||||
<div id="container-3" class="column columnfade pointer" onclick="previewWebcam()" style=" overflow-y: auto;">
|
||||
<h2 id="add_camera">
|
||||
<span data-translate="add-your-camera">Add your Camera to OBS</span>
|
||||
</h2>
|
||||
@@ -200,7 +207,7 @@
|
||||
<video id="previewWebcam" class="previewWebcam" oncanplay="updateStats();" disablePictureInPicture controlsList="nodownload" muted autoplay playsinline ></video>
|
||||
</p>
|
||||
<div id="infof"></div>
|
||||
<button onclick="publishWebcam()" id="gowebcam" class="gowebcam" disabled>
|
||||
<button onclick="publishWebcam(this)" id="gowebcam" class="gowebcam" disabled data-ready="false" >
|
||||
<span data-translate="waiting-for-camera">Waiting for Camera to Load</span>
|
||||
</button>
|
||||
<br />
|
||||
@@ -255,7 +262,7 @@
|
||||
<br />
|
||||
<span id="headphonesDiv" style="text-align:left; margin:17px 0; max-width: 550px; min-width: 420px; background-color: #f3f3f3; display: none; padding: 10px 10px; border: 1px solid #ccc; vertical-align: middle;">
|
||||
<div class="audioTitle2">
|
||||
<i class="las la-headphones"></i><span data-translate="select-output-source"> Audio Output Destination: <button onclick="playtone()" style="margin:0 0 0 15px;" type="button">Test</button>
|
||||
<i class="las la-headphones"></i><span data-translate="select-output-source"> Audio Output Destination: <button onclick="playtone()" class="white" style="margin:0 0 0 15px;" type="button">Test</button>
|
||||
</span></div>
|
||||
<select id="outputSource" ></select>
|
||||
|
||||
@@ -271,7 +278,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="container-2" class="column columnfade" style=" overflow-y: auto;">
|
||||
<div id="container-2" class="column columnfade pointer" style=" overflow-y: auto;">
|
||||
<h2 id="add_screen">
|
||||
<span data-translate="remote-screenshare-obs">Remote Screenshare into OBS</span>
|
||||
</h2>
|
||||
@@ -327,7 +334,7 @@
|
||||
<span id="headphonesDiv2" style="background-color: #f3f3f3; min-width: 270px; display: none; padding: 5px 10px; border: 1px solid #ccc; vertical-align: middle;">
|
||||
<i class="las la-headphones"></i>
|
||||
|
||||
<span data-translate="select-output-source"> Audio Output Destination: <button onclick="playtone(true)" style="padding:2px 5px; margin:0;margin-left:15px; position: relative; top: -2px;" type="button">Test</button></span>
|
||||
<span data-translate="select-output-source"> Audio Output Destination: <button onclick="playtone(true)" class="white" style="padding:3px 5px 2px 5px; margin:0; margin-left:15px; position: relative; " type="button">Test</button></span>
|
||||
<br />
|
||||
<select id="outputSourceScreenshare" style="background-color: #FFF; padding:10px 5px; min-width: 268px; display:inline-block; vertical-align: middle;" onclick="requestOutputAudioStream();">
|
||||
<option value="default">
|
||||
@@ -344,7 +351,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="container-4" class="column columnfade" style=" overflow-y: auto;">
|
||||
<div id="container-4" class="column columnfade pointer" style=" overflow-y: auto;">
|
||||
<h2>
|
||||
<span data-translate="create-reusable-invite">Create Reusable Invite</span>
|
||||
</h2>
|
||||
@@ -372,19 +379,19 @@
|
||||
<div class="invite_setting_item">
|
||||
<input type="checkbox" id="invite_bitrate" />
|
||||
<label for="invite_bitrate">
|
||||
<span data-translate="unlock-video-bitrate">Unlock Video Bitrate (20mbps)</span>
|
||||
<span data-translate="unlock-video-bitrate" title="Ideal for 1080p60 gaming, if your computer and upload are up for it" >Unlock Video Bitrate (20mbps)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invite_setting_item">
|
||||
<input type="checkbox" id="invite_vp9" />
|
||||
<label for="invite_vp9">
|
||||
<span data-translate="force-vp9-video-codec">Force VP9 Video Codec (less artifacting)</span>
|
||||
<span data-translate="force-vp9-video-codec" title="Better video compression and quality at the cost of increased CPU encoding load">Force VP9 Video Codec</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invite_setting_item">
|
||||
<input type="checkbox" id="invite_stereo" />
|
||||
<label for="invite_stereo">
|
||||
<span data-translate="enable-stereo-and-pro">Enable Stereo and Pro HD Audio</span>
|
||||
<span data-translate="enable-stereo-and-pro" title="Disable digital audio-effects and increase audio bitrate">Enable Stereo and Pro HD Audio</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invite_setting_item">
|
||||
@@ -399,33 +406,33 @@
|
||||
</div>
|
||||
<div class="invite_setting_group">
|
||||
<div class="invite_setting_item">
|
||||
<input type="checkbox" id="invite_secure" />
|
||||
<label for="invite_secure">
|
||||
<span data-translate="high-security-mode">High Security Mode</span>
|
||||
<input type="checkbox" id="invite_automic" />
|
||||
<label for="invite_automic">
|
||||
<span data-translate="hide-mic-selection" title="The guest will not have a choice over audio-options">Force Default Microphone</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invite_setting_item">
|
||||
<input type="checkbox" id="invite_hidescreen" />
|
||||
<label for="invite_hidescreen">
|
||||
<span data-translate="hide-screen-share">Hide Screenshare Option</span>
|
||||
<span data-translate="hide-screen-share" title="The guest will only be able to select their webcam as an option">Hide Screenshare Option</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invite_setting_item">
|
||||
<input type="checkbox" id="invite_remotecontrol" />
|
||||
<label for="invite_remotecontrol">
|
||||
<span data-translate="allow-remote-control">Remote Control Camera Zoom (android)</span>
|
||||
<span data-translate="allow-remote-control" title="Hold CTRL and the mouse wheel to zoom in and out remotely of compatible video streams">Remote Control Camera Zoom (android)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invite_setting_item">
|
||||
<span data-translate="add-a-password-to-stream"> Add a password:</span>
|
||||
<span data-translate="add-a-password-to-stream" title="Add a password to make the stream inaccessible to those without the password"> Add a password:</span>
|
||||
<input id="invite_password" placeholder="Add an optional password" />
|
||||
</div>
|
||||
<div class="invite_setting_item">
|
||||
<span data-translate="add-the-guest-to-a-room"> Add the guest to a room:</span>
|
||||
<span data-translate="add-the-guest-to-a-room" title="Add the guest to a group-chat room; it will be created automatically if needed."> Add the guest to a room:</span>
|
||||
<input id="invite_joinroom" placeholder="Enter Room name here" oninput="document.getElementById('invitegroupchat').style.display='block';" />
|
||||
</div>
|
||||
<div class="invite_setting_item">
|
||||
<span id="invitegroupchat" style="display: none;">
|
||||
<span id="invitegroupchat" style="display: none;" title="Customize the room settings for this guest">
|
||||
<label for="invite_group_chat_type" data-translate="invite-group-chat-type">This room guest can:</label>
|
||||
<select id="invite_group_chat_type" name="invite_group_chat_type">
|
||||
<option value="0" selected data-translate="can-see-and-hear">Can see and hear the group chat</option>
|
||||
@@ -448,6 +455,24 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="container-5" class="column columnfade pointer advanced" style=" overflow-y: auto;">
|
||||
<h2><span data-translate="share-local-video-file">Stream Media File</span></h2>
|
||||
<div class="container-inner">
|
||||
|
||||
<br /><br />
|
||||
SELECT THE VIDEO FILE TO SHARE<br /><br />
|
||||
<input id="fileselector" onchange="session.publishFile(this,event);" type="file" accept="video/*,audio/*" alt="Hold CTRL (or CMD) to select multiple files" title="Hold CTRL (or CMD) to select multiple files" multiple/>
|
||||
</div>
|
||||
<div class="outer close">
|
||||
<div class="inner">
|
||||
<label class="labelclass">
|
||||
<span data-translate="back">Back</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
<div id="info" class="fullcolumn columnfade">
|
||||
<center>
|
||||
@@ -471,21 +496,23 @@
|
||||
</i>
|
||||
<br />
|
||||
<li>
|
||||
|
||||
<a href="https://github.com/steveseguin/obsninja/wiki/FAQ#mac-os">MacOS <i class="lab la-apple"></i> users</a> need to use OBS v23 or resort to
|
||||
<a href="https://github.com/steveseguin/electroncapture">Window Capturing</a> a browser with OBS v25
|
||||
<a href="https://github.com/steveseguin/obsninja/wiki/FAQ#mac-os">MacOS <i class="lab la-apple"></i> users</a> will need to use OBS v23 or resort to
|
||||
<a href="https://github.com/steveseguin/electroncapture">Window Capturing</a> with the provided Electron-Capture app for the time being.
|
||||
|
||||
</li>
|
||||
<li>Some users will have
|
||||
<a href="https://github.com/steveseguin/obsninja/wiki/FAQ#video-is-pixelated">"pixel smearing"</a> problems with videos. Avoid Wi-Fi to reduce it or add
|
||||
<b>&codec=vp9</b> to the OBS view links to prevent it.
|
||||
<li>If you have <a href="https://github.com/steveseguin/obsninja/wiki/FAQ#video-is-pixelated">"pixel smearing"</a> or corrupted video, try adding <b>&codec=vp9</b> or &codec=h264 to the OBS view link. Using Wi-Fi will make the issue worse.
|
||||
</li>
|
||||
<li>
|
||||
iOS devices may have occasional audio or camera issues, such as no sound. Fully close Safari and reopen it if nothing else seems to work.
|
||||
</li>
|
||||
<li>
|
||||
The VP9 codec on Chromium-based browsers seems to lag when screen-sharing at the moment. Use the OBS Virtual Camera as a capture source instead.
|
||||
</li>
|
||||
<br />
|
||||
|
||||
🚨 Site Recently Updated: September 12th, 2020. The previous version can be found at
|
||||
<a href="https://obs.ninja/v11/">https://obs.ninja/v11/</a> if you are having new issues.
|
||||
🎈 Site Updated: <a href="https://www.reddit.com/r/OBSNinja/comments/k02enh/version_134_of_obsninja_released_change_log_here/">November 24th, 2020</a>. The previous version can be found at
|
||||
<a href="https://obs.ninja/v12/">https://obs.ninja/v12/</a> if you are having new issues.
|
||||
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<h3>
|
||||
@@ -493,7 +520,7 @@
|
||||
Check out the
|
||||
<a href="https://www.reddit.com/r/OBSNinja/">sub-reddit
|
||||
<i class="lab la-reddit-alien"></i> </a>for help and see the <a href="https://github.com/steveseguin/obsninja/wiki/">Wiki for advanced info</a>. I'm also on
|
||||
<a href="https://discord.gg/EksyhGA">Discord</a> and you can email me at steve@seguin.email
|
||||
<a href="https://discord.gg/T4xpQVv">Discord</a> and you can email me at steve@seguin.email
|
||||
|
||||
</i>
|
||||
</h3>
|
||||
@@ -515,34 +542,58 @@
|
||||
<a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a>
|
||||
</div>
|
||||
</div>
|
||||
<span id="electronDragZone" style="pointer-events: none; z-index:-10; position:absolute;top:0;left:0;width:100%;height:20%;-webkit-app-region: drag;"></span>
|
||||
<span id="electronDragZone" style="pointer-events: none; z-index:-10; position:absolute;top:0;left:0;width:100%;height:5%;-webkit-app-region: drag;min-height:33px;"></span>
|
||||
<div id="gridlayout" ></div>
|
||||
<div id="overlayMsgs" onclick="function(e){e.target.innerHTML = '';}" style="display:none"></div>
|
||||
<div id="controls_blank" style="display: none;">
|
||||
<b>
|
||||
<button data-value="0" style="padding: 2px 10px 3px 5px;font-weight:display-block;margin: 2px 0 0 5px;" title="Add this Video to any remote '&scene=1'" onclick="directEnable(this, event);">
|
||||
<span data-translate="add-to-group" view">➕ Add to Group Scene</span>
|
||||
<div class="controlsGrid">
|
||||
|
||||
<button data-action-type="addToScene" data-value="0" title="Add this Video to any remote '&scene=1'" onclick="directEnable(this, event);">
|
||||
<i class="las la-plus-square"></i>
|
||||
<span data-translate="add-to-scene">Add to Scene</span>
|
||||
</button>
|
||||
<button style="padding: 2px 10px 3px 5px;display:inline-block;margin: 2px 0 0 5px;" title="Start Recording this stream. *experimental*' views" onclick="recordVideo(this, event)">
|
||||
<span data-translate="record">🔴 Record</span>
|
||||
<button data-action-type="forward" data-value="0" title="Forward user to another room. They can always return." onclick="directMigrate(this, event);">
|
||||
<i class="las la-paper-plane"></i>
|
||||
<span data-translate="forward-to-room">Transfer</span>
|
||||
</button>
|
||||
<br />
|
||||
<button style="padding: 2px 10px 3px 5px;display:inline-block;margin: 2px 0 0 5px;" title="Remotely Mute this Audio in all remote '&scene' views" onclick="directMute(this, event);">
|
||||
<span data-translate="mute" >🔇 Mute in all Scenes</span>
|
||||
|
||||
<button data-action-type="recorder" title="Start Recording this stream. *experimental*' views" onclick="recordVideo(this, event)">
|
||||
<i class="las la-circle"></i>
|
||||
<span data-translate="record"> Record</span>
|
||||
</button>
|
||||
<i style="font-size:2vh; position: relative; top: 3px;" title="Change this Audio's volume in all remote '&scene' views" class="las la-volume-up"></i>
|
||||
<input type="range" min="1" max="100" value="100" title="Change this Audio's volume in all remote '&scene' views" onclick="directVolume(this);" style="width: 100px; position: relative; top: 4px;"/>
|
||||
</b>
|
||||
<br />
|
||||
|
||||
<hr style="margin:5px 0 0 0;"/>
|
||||
|
||||
<button data-action-type="hangup" data-value="0" title="Force the user to Disconnect. They can always reconnect." onclick="directHangup(this, event);">
|
||||
<i class="las la-sign-out-alt"></i>
|
||||
<span data-translate="disconnect-guest" >Hangup</span>
|
||||
</button>
|
||||
|
||||
<input data-action-type="volume" class="slider" type="range" min="1" max="100" value="100" title="Change this Audio's volume in all remote '&scene' views" onclick="directVolume(this);" style="grid-column: 1; margin:5px; width: 93%; position: relative; top: 0px; background-color:#fff0;"/>
|
||||
|
||||
<button data-action-type="mute" style="grid-column: 2;" title="Remotely Mute this Audio in all remote '&scene' views" onclick="directMute(this, event);">
|
||||
<i class="las la-volume-off"></i>
|
||||
<span data-translate="mute" >Mute in Scenes</span>
|
||||
</button>
|
||||
|
||||
<span>
|
||||
<button style="width: 36px" data-action-type="change-quality" title="Disable Video Preview" onclick="toggleQualityDirector(0, this.dataset.UUID, this);">
|
||||
<span data-translate="change-to-low-quality"> <i class="las la-video-slash"></i></span>
|
||||
</button>
|
||||
<button style="width: 36px" data-action-type="change-quality" title="Low-Quality Preview" onclick="toggleQualityDirector(50, this.dataset.UUID, this);">
|
||||
<span data-translate="change-to-medium-quality"> <i class="las la-video"></i></span>
|
||||
</button>
|
||||
<button style="width: 36px" data-action-type="change-quality" title="High-Quality Preview" onclick="toggleQualityDirector(1200, this.dataset.UUID, this);">
|
||||
<span data-translate="change-to-high-quality"> <i class="las la-binoculars"></i></span>
|
||||
</button>
|
||||
</span>
|
||||
<button data-action-type="direct-chat" title="Send Direct Message" onclick="directorSendMessage(this);">
|
||||
<span data-translate="send-direct-chat"><i class="las la-envelope"></i> Message</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id="popupSelector" style="display:none;">
|
||||
<span id="videoMenu3" class="videoMenu">
|
||||
<i class="las la-video"></i><span data-translate="video-source"> Video Source </span>
|
||||
|
||||
<select id="videoSource3" ></select>
|
||||
|
||||
<select id="videoSource3" ></select>
|
||||
</span>
|
||||
<br />
|
||||
<br />
|
||||
@@ -566,8 +617,13 @@
|
||||
</div>
|
||||
<select id="outputSource3" ></select>
|
||||
</span>
|
||||
<button id="shareScreenGear" style="padding:20px;" onclick="grabScreen()"><b>Share Screen</b><br /><i style="padding:5px; font-size:300%;" class="las la-desktop"></i></button><br />
|
||||
<button onclick="toggleSettings()" style="background-color:#EFEFEF;padding:10px 12px 12px 2px;"><i class="chevron right" style="font-size:150%;top:3px;position:relative;"></i> <b>Close Settings</b></button>
|
||||
<button id="shareScreenGear" style="width: 135px; padding:20px;text-align:center;" onclick="grabScreen()"><b>Share Screen</b><br /><i style="padding:5px; font-size:300%;" class="las la-desktop"></i></button><br />
|
||||
<button onclick="toggleSettings()" style="width: 135px; background-color:#EFEFEF;padding:10px 12px 12px 2px;margin: 10px 0px 20px 0"><i class="chevron right" style="font-size:150%;top:3px;position:relative;"></i> <b>Close Settings</b></button>
|
||||
|
||||
<button id='advancedOptions' onclick="this.style.display = 'none'; toggle(getById('popupSelector_constraints'),false,false); " style="display:none; background-color:#EFEFEF;padding:10px 12px 12px 2px;margin: 10px 0px 0px 10px"><i class="chevron bottom" style="font-size:150%;top:3px;position:relative;"></i> <b>Show Advanced</b></button>
|
||||
<span id="popupSelector_constraints" style="display: none;">
|
||||
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<nav id="context-menu" class="context-menu">
|
||||
@@ -587,6 +643,49 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div id="roomTemplate" style="display:none;">
|
||||
<div class='directorContainer half'>
|
||||
<button class="grey" data-translate="click-for-quick-room-overview" onclick="toggle(getById('roomnotes2'),this,false);"><i class="las la-question-circle"></i> Click Here for a quick overview and help</button>
|
||||
<span id="miniPerformer"><button id="press2talk" class="grey" onclick="press2talk();"><i class="las la-headset"></i><span data-translate="push-to-talk-enable"> Enable Director's Push-to-Talk Mode</span></button></span>
|
||||
</div>
|
||||
|
||||
<div id='roomnotes2' style='max-width:1200px;display:none;padding:0 0 0 10px;' >
|
||||
<font style='color:#CCC;' data-translate='welcome-to-control-room'>
|
||||
<b>Welcome. This is the director's control-room for the group-chat.</b><br /><br />
|
||||
You can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.
|
||||
<br /><br />
|
||||
<font style='color:red'>Known Limitations with Group Rooms:</font><br />
|
||||
<li>A group room can handle up to around 30 guests, depending on numerous factors, including CPU and available bandwidth of all guests in the room. To achieve more than around 7-guests though, you will likely want to disable video sharing between guests. &roombitrate=0 or &novideo are options there.</li>
|
||||
|
||||
<li>Videos will appear of low quality on purpose for guests and director; this is to save bandwidth and CPU resources. It will be high-quality within OBS still though.</li>
|
||||
|
||||
<li>The state of the scenes, such as which videos are active in a scene, are lost when the director resets the control-room or the scene.</li>
|
||||
<br />
|
||||
Further Notes:<br /><br />
|
||||
<li>Links to Solo-views of each guest video are offered under videos as they load. These can be used within an OBS Browser Source.</li>
|
||||
<li>You can use the auto-mixing Group Scenes, the green links, to auto arrange multiple videos for you in OBS.</li>
|
||||
<li>You can use this control room to record isolated video or audio streams, but it is an experimental feature still.</li>
|
||||
<li>If you transfer a guest from one room to another, they won't know which room they have been transferred to.</li>
|
||||
<li>OBS will see a guest's video in high-quality; the default video bitrate is 2500kbps. Setting higher bitrates will improve motion.</li>
|
||||
<li>VP8 is typically the default video codec, but using &codec=vp9 or &codec=h264 as a URL in OBS can help to reduce corrupted video puke issues.</li>
|
||||
<li>&stereo=2 can be added to guests to turn off audio effects, such as echo cancellation and noise-reduction.</li>
|
||||
<li>https://invite.cam is a free service provided that can help obfuscuate the URL parameters of an invite link given to guests.</li>
|
||||
<li>Adding &showonly=SOME_OBS_VIRTUALCAM to the guest invite links allows for only a single video to be seen by the guests; this can be output of the OBS Virtual Camera for example</li>
|
||||
<br />
|
||||
|
||||
For advanced URL options and parameters, <a href="https://github.com/steveseguin/obsninja/wiki/Advanced-Settings">see the Wiki.</a>
|
||||
</font>
|
||||
</div>
|
||||
|
||||
<div id='guestFeeds'><div id='deleteme'>
|
||||
<div class='vidcon' style='margin: 15px 20px 0 0; min-height: 300px;text-align: center;'><h2>Guest 1</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
|
||||
<div class='vidcon' style='margin: 15px 20px 0 0; min-height: 300px;text-align: center;'><h2>Guest 2</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
|
||||
<div class='vidcon' style='margin: 15px 20px 0 0; min-height: 300px;text-align: center;'><h2>Guest 3</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
|
||||
<div class='vidcon' style='margin: 15px 20px 0 0; min-height: 300px;text-align: center;'><h2>Guest 4</h2><i class='las la-user-circle' style='font-size:8em; margin: 20px 0px;' aria-hidden='true'></i></div>
|
||||
<h4 style='color:#CCC;margin:20px 20px 0 20px;' data-translate='more-than-four-can-join' >These four guest slots are just for demonstration. More than four guests can actually join a room.</h4>
|
||||
</div></div>
|
||||
</div>
|
||||
|
||||
<div id="chatModule" style="display:none;">
|
||||
<div id="chatBody">
|
||||
<div class="inMessage" data-translate='welcome-to-obs-ninja-chat'>
|
||||
@@ -596,7 +695,7 @@
|
||||
Names identifying connected peers will be a feature in an upcoming release.
|
||||
</div>
|
||||
</div>
|
||||
<input id="chatInput" placeholder="Enter chat message to send here"onkeypress="EnterButtonChat(event)" />
|
||||
<input id="chatInput" placeholder="Enter chat message to send here" onkeypress="EnterButtonChat(event)" />
|
||||
<button style="width:60px;background-color:#EEE;" onclick="sendChatMessage()" data-translate='send-chat'>Send</button>
|
||||
</div>
|
||||
|
||||
@@ -604,7 +703,10 @@
|
||||
<source src="tone.mp3" type="audio/mpeg">
|
||||
<source src="tone.ogg" type="audio/ogg">
|
||||
</audio>
|
||||
|
||||
<div class="gone" >
|
||||
<!-- This image is used when dragging elements -->
|
||||
<img src="./images/favicon-32x32.png" id="dragImage" />
|
||||
</div>
|
||||
<div id="messagePopup" class="popup-message"></div>
|
||||
<div id="languages" class="popup-message" style="display: none; right: 0; bottom: 25px; position: absolute;">
|
||||
<b data-translate='available-languages'>Available Languages:</b>
|
||||
@@ -626,8 +728,12 @@
|
||||
<br />
|
||||
<a onclick="changeLg('nl');toggle(document.getElementById('languages'));" style="cursor: pointer;">Dutch</a>
|
||||
<br />
|
||||
<a onclick="changeLg('tr');toggle(document.getElementById('languages'));" style="cursor: pointer;">Turkish</a>
|
||||
<br />
|
||||
<a onclick="changeLg('ja');toggle(document.getElementById('languages'));" style="cursor: pointer;">Japanese</a>
|
||||
<br />
|
||||
<a onclick="changeLg('cs');toggle(document.getElementById('languages'));" style="cursor: pointer;">Czech </a>
|
||||
<br />
|
||||
<a onclick="changeLg('pig');toggle(document.getElementById('languages'));" style="cursor: pointer;">Pig Latin</a>
|
||||
<br />
|
||||
</u>
|
||||
@@ -635,12 +741,16 @@
|
||||
<a href="https://github.com/steveseguin/obsninja/tree/master/translations" data-translate='add-more-here'>Add More Here!</a>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var session = WebRTC.Media; // session is a required global variable if configuring manually. Run before loading main.js but after webrtc.js.
|
||||
|
||||
session.version = "13.4";
|
||||
session.streamID = session.generateStreamID(); // randomly generates a streamID for this session. You can set your own programmatically if needed
|
||||
|
||||
|
||||
session.defaultPassword = "someEncryptionKey123"; // Disabling improves compatibility and is helpful for debugging.
|
||||
session.salt = location.hostname; // used only if password is not == False.
|
||||
|
||||
// session.configuration = {
|
||||
// iceServers: [
|
||||
// { urls: ["stun:stun.l.google.com:19302", "stun:stun4.l.google.com:19302"] }, // more than 4 stun+turn servers may cause issues
|
||||
@@ -662,7 +772,7 @@
|
||||
|
||||
// session.configuration.iceTransportPolicy = "relay"; // uncomment to enable "&privacy" and force the TURN server
|
||||
|
||||
// session.wss = false;
|
||||
// session.wss = false; // uses default handshake wss
|
||||
|
||||
///// The following lets you set the defaults
|
||||
|
||||
@@ -680,6 +790,7 @@
|
||||
// session.codec
|
||||
// session.scale
|
||||
// session.bitrate // int in kbps
|
||||
// session.totalRoomBitrate = 500; // int, kbps
|
||||
// session.height // int
|
||||
// session.width // int
|
||||
// session.quality // int
|
||||
@@ -698,7 +809,7 @@
|
||||
// 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=41"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./animations.js?ver=10"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" id="main-js" src="./main.js?ver=87"></script>
|
||||
<script type="text/javascript" crossorigin="anonymous" src="./animations.js?ver=13"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -59,9 +59,7 @@ button{
|
||||
})(window);
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
|
||||
|
||||
function loadIframe(){
|
||||
function loadIframe(){ // this is pretty important if you want to avoid camera permission popup problems. YOu need to load the iFRAME after you load the parent body. A quick solution is like: <body onload=>loadIframe();"> !!!
|
||||
|
||||
var streamID = "";
|
||||
var possible = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789";
|
||||
@@ -74,22 +72,37 @@ function loadIframe(){
|
||||
var iframeContainer = document.createElement("span");
|
||||
|
||||
iframe.allow="autoplay";
|
||||
var srcString = "./?push="+streamID+"&cleanoutput&privacy&audiodevice=0";
|
||||
var srcString = "./?push="+streamID+"&cleanoutput&privacy&webcam&audiodevice=0&fullscreen";
|
||||
|
||||
if (urlParams.has('turn')){
|
||||
iframe.src = srcString+"&turn="+urlParams.get("turn");
|
||||
} else {
|
||||
iframe.src = srcString;
|
||||
srcString = srcString+"&turn="+urlParams.get("turn");
|
||||
}
|
||||
|
||||
// we are changing some text on page load, just to demonstrate what's possible.
|
||||
iframe.onload = function(e){e.target.contentWindow.postMessage({"function":"changeHTML", "target":"add_camera","value":"Select your Camera"}, '*');};
|
||||
iframe.src = srcString;
|
||||
|
||||
iframeContainer.appendChild(iframe);
|
||||
document.getElementById("container").appendChild(iframeContainer);
|
||||
|
||||
|
||||
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
var iframeContainer = document.createElement("span");
|
||||
|
||||
iframe.allow="autoplay";
|
||||
iframe.src = "./?view="+streamID+"&cleanoutput&privacy&noaudio";
|
||||
var srcString = "./?view="+streamID+"&cleanoutput&privacy&noaudio";
|
||||
|
||||
if (urlParams.has('turn')){
|
||||
srcString = srcString+"&turn="+urlParams.get("turn");
|
||||
}
|
||||
|
||||
if (urlParams.has('buffer')){
|
||||
srcString = srcString+"&buffer="+urlParams.get("buffer");
|
||||
}
|
||||
|
||||
iframe.src = srcString;
|
||||
|
||||
iframeContainer.appendChild(iframe);
|
||||
document.getElementById("container").appendChild(iframeContainer);
|
||||
@@ -107,6 +120,9 @@ function loadIframe(){
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":30}, '*');}
|
||||
document.getElementById("container").appendChild(button);
|
||||
|
||||
|
||||
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "High Bitrate";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":6000}, '*');}
|
||||
|
||||
2
thirdparty/CodecsHandler.js
vendored
2
thirdparty/CodecsHandler.js
vendored
@@ -335,7 +335,7 @@ var CodecsHandler = (function() {
|
||||
}
|
||||
|
||||
if (typeof params.maxaveragebitrate != 'undefined') {
|
||||
appendOpusNext += ';maxaveragebitrate=' + params.maxaveragebitrate; // default 2500 (kbps)
|
||||
appendOpusNext += ';maxaveragebitrate=' + params.maxaveragebitrate; // default 32000? (kbps)
|
||||
}
|
||||
|
||||
if (typeof params.maxplaybackrate != 'undefined') {
|
||||
|
||||
5623
thirdparty/adapter-latest.js
vendored
Normal file
5623
thirdparty/adapter-latest.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
55669
thirdparty/video.js
vendored
Normal file
55669
thirdparty/video.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52728
thirdparty/videojs-vr.js
vendored
Normal file
52728
thirdparty/videojs-vr.js
vendored
Normal file
File diff suppressed because one or more lines are too long
68
translations/cs.json
Normal file
68
translations/cs.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"GO": "Spustit",
|
||||
"add-group-chat": "Přidat skupinový chat OBS",
|
||||
"add-to-group": "Přidat do skupiny",
|
||||
"add-your-camera": "Přidat kameru do OBS",
|
||||
"added-notes": "\n\t\t\t\t<u><i>Poznámka:</i></u>\n\t\t\t\t<li>Kdokoliv se může připojit, když zná jméno místnosti</li>\n\t\t\t\t<li>Není doporučeno mít v místnosti víc než 4 lidi kvůli náročnosti na Váš počítač, ale za zkoušku nic nedáte.</li>\n\t\t\t\t<li>iOS zařízení jsou omezena pouze na dva účastníky. Toto omezení je způsobeno Applem.</li>\n\t\t\t\t<li> \"Nahrávat\" je nová a EXPERIMENTÁLNÍ funkce.</li>\n\t\t\t\t<li>Musíte \"Přidat\" zdroj video do \"Skupinová scéna\" aby se tu zobrazil.</li>\n\t\t\t\t<li>Tady je nové \"vylepšený fullscreen\" tlačítko přidané pro hostitele.</li>\n\t\t\t\t",
|
||||
"advanced-paramaters": "Pokročilé nastavení",
|
||||
"audio-sources": "Audio zdroje",
|
||||
"back": "Zpět",
|
||||
"balanced": "Vyrovnaný",
|
||||
"copy-this-url": "Zkopírujte tuhle URL do OBS \"Browser Source\"",
|
||||
"copy-to-clipboard": "Kopírovat do schránky",
|
||||
"create-reusable-invite": "Vytvořit pozvánku na více použití",
|
||||
"enable-stereo-and-pro": "Povolit Stereo a Pro HD Audio",
|
||||
"enter-the-rooms-control": "Vstoupit do administrace místnosti",
|
||||
"force-vp9-video-codec": "Vynutit VP9 Video Codec (méně artefaktů)",
|
||||
"generate-invite-link": "GENEROVAT POZVÁNKU",
|
||||
"here-you-can-pre-generate": "Zde můžete generovat linky do OBS i pozvánky na více použití.",
|
||||
"high-security-mode": "Vysoce zabezpečený mód",
|
||||
"info-blob": "\n\t\t\t\t\t\t<h2>Co je OBS.Ninja</h2><br>\n\t\t\t\t\t\t<li>100% <b>zdarma</b>; bez stahování; žádné osobní data; bez přihlašování</li>\n\t\t\t\t\t\t<li>Sdílejte video ze smartphonu, laptopu, počítače či svých kamarádů přímo do OBSka</li>\n\t\t\t\t\t\t<li>Používáme nejmodernější Peer-to-Peer forwarding technologii, která zaručuje bezpečnost a minimální lag</li>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\t<li>Youtube video <i class=\"fa fa-youtube-play\" aria-hidden=\"true\"></i> <a href=\"https://www.youtube.com/watch?v=6R_sQKxFAhg\">Demo</a> </li>\n\t\t\t\t\t\t<li>Open-source kód je dostupný zde: <i class=\"fa fa-github\" aria-hidden=\"true\"></i> <a href=\"https://github.com/steveseguin/obsninja\">https://github.com/steveseguin/obsninja</a> </li>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\t<i><font style=\"color:red\">Známé problémy:</font></i><br>\n\n\t\t\t\t\t\t<li><i class=\"fa fa-apple\" aria-hidden=\"true\"></i> Uživatelé MacOS musí používat OBS v23 nebo pozdější pro spřávné zachyceení <i>okna</i> prohlížeč Chrome s OBS v25</li>\n\t\t\t\t\t\t<li>Pokud máte problémy s \"pixelací\" videa. Prosím přidejte URL parameter <b>&codec=vp9</b> do OBS Linku pro nápravu.</li>\n\t<h3><i>Koukněte na <a href=\"https://www.reddit.com/r/OBSNinja/\">sub-reddit</a> <i class=\"fa fa-reddit-alien\" aria-hidden=\"true\"></i> for pomoc a návody. Jsem také na <a href=\"https://discord.gg/EksyhGA\">Discord</a> a můžete mi psát na steve@seguin.email. Přeložil do CZ: <a href=\"http://karelvitek.cz\">Karel Vítek</a></i></h3>\n\t\t\t\t\t",
|
||||
"joining-room": "Připojujete se",
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
"max-resolution": "MAX rozlišení",
|
||||
"mute": "Ztišit",
|
||||
"no-audio": "Žádné Audio",
|
||||
"note-share-audio": "\n\t\t\t\t\t<b>poznámka</b>: Nezapomeňte zakliknout \"Sdílet audio\" v Chromu.<br>(Firefox nepodporuje sdílení zvuku.)",
|
||||
"open-in-new-tab": "Otevřít v nové záložce",
|
||||
"record": "Nahrávat",
|
||||
"remote-control-for-obs": "Vzdálené ovládání OBS",
|
||||
"remote-screenshare-obs": "Vzdálené sdílení obrazovky do OBS",
|
||||
"room-name": "Jméno místnost",
|
||||
"rooms-allow-for": "Místnosti umožnůjí jednoduchý skupinový chat a pokročilou správu více streamů zároveň.",
|
||||
"select-audio-source": "Zvolit zdroj Audia",
|
||||
"select-audio-video": "Níže vyberte audio/video zdroj",
|
||||
"select-screen-to-share": "VYBRAT OBRAZOVKU KE SDÍLENÍ",
|
||||
"show-tips": "Zobrazit tipy..",
|
||||
"smooth-cool": "Super and Cool",
|
||||
"unlock-video-bitrate": "Rozvolnit limit Video Bitrate (20mbps)",
|
||||
"video-source": "Video zdroj",
|
||||
"volume": "Hlasitost",
|
||||
"you-are-in-the-control-center": "Jsi v administraci místnosti",
|
||||
"waiting-for-camera": "Čekám na načtení kamery",
|
||||
"video-resolution": "Rozlišení videa: ",
|
||||
"hide-screen-share": "Nezobrazovat možnost sdílet obrazovku",
|
||||
"allow-remote-control": "Vzdálené ovládání přiblížení (android)",
|
||||
"add-the-guest-to-a-room": " Přidat hosta do místosti:",
|
||||
"invite-group-chat-type": "Člen této místnosti může:",
|
||||
"can-see-and-hear": "Slyšet a vidět ostatní členy",
|
||||
"can-hear-only": "Pouze slyšet ostatní členy",
|
||||
"cant-see-or-hear": "Neslyšet ani nevidět ostatní členy",
|
||||
"password-input-field": "Heslo",
|
||||
"select-output-source": " Audio výstup: \n\t\t\t\t\t",
|
||||
"add-a-password-to-stream": " Přidat heslo:",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tVítejte na OBS.Ninja! můžete ihned poslat zprávy ostatním členům této místnosti\n\t\t\t\t",
|
||||
"names-and-labels-coming-soon": "\n\t\t\t\t\tJména členů bude jedna z budoucích funkcí OBS.ninja.\n\t\t\t\t",
|
||||
"send-chat": "Poslat",
|
||||
"available-languages": "Dostupné jazyky:",
|
||||
"add-more-here": "Přidat další!",
|
||||
"invite-users-to-join": "Pozvat členy do místnosti a sdílet jejich feed. Tito členové uvidí všechny ostatní členy a jejich feedy.",
|
||||
"link-to-invite-camera": "Pozvat členy do místnosti a sdílet jejich feed. Tito pouze sdílí avšak nic neuvidí ani neuslyší od ostatních.",
|
||||
"this-is-obs-browser-source-link": "Tohle je link do OBS Browser Source link který je ve výchozím nastavení prázdný. Členové místnosti do této scény mohou být přidáni manuálně.",
|
||||
"this-is-obs-browser-souce-link-auto": "Tohle je taky OBS Browser Source link. Všichni členové této místnosti tam jsou přidání antomaticky (vhodné např. na konference)",
|
||||
"click-for-quick-room-overview": "❔ Klidni zde pro krátký přehled o funkcích",
|
||||
"push-to-talk-enable": "🔊 Povolit administrátorovi Push-to-Talk mód",
|
||||
"welcome-to-control-room": "Welcome. This is the control-room for the group-chat. There are different things you can use this room for:<br><br>\t<li>You can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.</li>\t<li>A group room can handle around 4 to 30 guests, depending on numerous factors, including CPU and available bandwidth of all guests in the room.</li>\t<li>Solo-views of each video are offered under videos as they load. These can be used within an OBS Browser Source.</li>\t<li>You can use the auto-mixing Group Scene, the green link, to auto arrange multiple videos for you in OBS.</li>\t<li>You can use this control room to record isolated video or audio streams, but it is an experimental feature still.</li>\t<li>Videos in the Director's room will be of low quality on purpose; to save bandwidth/CPU</li>\t<li>Guest's in the room will see each other's videos at a very limited quality to conserve bandwidth/CPU.</li>\t<li>OBS will see a guest's video in high-quality; the default video bitrate is 2500kbps.</li>\t<br>\tAs guests join, their videos will appear below. You can bring their video streams into OBS as solo-scenes or you can add them to the Group Scene.\t<br>The Group Scene auto-mixes videos that have been added to the group scene. Please note that the Auto-Mixer requires guests be manually added to it for them to appear in it; they are not added automatically.<br><br>Apple mobile devices, such as iPhones and iPads, do not fully support Video Group Chat. This is a hardware constraint.<br><br>\tFor advanced options and parameters, <a href=\"https://github.com/steveseguin/obsninja/wiki/Guides-and-How-to's#urlparameters\">see the Wiki.</a>",
|
||||
"guest-will-appaer-here-on-join": "(Zde se zobrazí členové až se připojí)",
|
||||
"SOLO-LINK": "SOLO LINK pro OBS:"
|
||||
}
|
||||
@@ -64,4 +64,4 @@
|
||||
"push-to-talk-enable": "🔊 Ativar Push-to-talk do diretor",
|
||||
"welcome-to-control-room": "Bem-vindo. Esta é a sala de controlo para o chat de grupo. Há diferentes coisas que pode fazer aqui:<br><br>\t<li>Pode hospedar um chat de grupo com amigos. Partilhe o link azul para os convidados se juntarem ao chat de forma automática.</li>\t<li>Uma sala de grupo pode hospedar entre 4 a 30 4 to 30 convidados, dependendo de inúmeros factores, incluindo CPU e largura de banda de todos os convidados na sala.</li>\t<li>Visualizações individuais de cada vídeo serão mostradas quando carregam. Estas podem ser usadas em Fontes do tipo Browser no OBS.</li>\t<li>Pode usar a cena de grupo automática, o link verde, para dispôr automaticamente os vídeos por si no OBS.</li>\t<li>Pode usar esta sala de controlo para gravar streams isolados de vídeo ou áudio, mas isto é ainda experimental.</li>\t<li>Vídeos na sala de controle são de baixa qualidade propositadamente; para poupar largura de banda/CPU</li>\t<li>Convidados na sala irão ver-se numa qualidade muito reduzida para conservar largura de banda/CPU.</li>\t<li>OBS tem acesso ao vídeo do convidado em alta qualidade; o bitrate de vídeo por omissão é 2500kbps.</li>\t<br>\tÀ medida que os convidados entram, os seus vídeos são mostrados abaixo. Pode levar os seus sinais para o OBS como cenas individuais ou pode adicioná-los à cena de grupo.\t<br>A Cena de grupo auto-mistura vídeos que lhe forem adicionados. Note que a auto-mistura requer que os convidados sejam manualmente adicionados; não são adicionados automaticamente.<br><br>Dispositivos móveis Apple, como iPhones e iPads, não suportam totalmente o Chat de Grupo. Este é um constrangimento de hardware.<br><br>\tPara opções avançadas e parâmetros, <a href=\"https://github.com/steveseguin/obsninja/wiki/Guides-and-How-to's#urlparameters\">veja o Wiki.</a>", "guest-will-appaer-here-on-join": "(Aparece aqui o vídeo quando um convidado entrar)",
|
||||
"SOLO-LINK": "Link individual para OBS:"
|
||||
}
|
||||
}
|
||||
@@ -65,4 +65,4 @@
|
||||
"welcome-to-control-room": "Welcome. This is the control-room for the group-chat. There are different things you can use this room for:<br><br>\t<li>You can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.</li>\t<li>A group room can handle around 4 to 30 guests, depending on numerous factors, including CPU and available bandwidth of all guests in the room.</li>\t<li>Solo-views of each video are offered under videos as they load. These can be used within an OBS Browser Source.</li>\t<li>You can use the auto-mixing Group Scene, the green link, to auto arrange multiple videos for you in OBS.</li>\t<li>You can use this control room to record isolated video or audio streams, but it is an experimental feature still.</li>\t<li>Videos in the Director's room will be of low quality on purpose; to save bandwidth/CPU</li>\t<li>Guest's in the room will see each other's videos at a very limited quality to conserve bandwidth/CPU.</li>\t<li>OBS will see a guest's video in high-quality; the default video bitrate is 2500kbps.</li>\t<br>\tAs guests join, their videos will appear below. You can bring their video streams into OBS as solo-scenes or you can add them to the Group Scene.\t<br>The Group Scene auto-mixes videos that have been added to the group scene. Please note that the Auto-Mixer requires guests be manually added to it for them to appear in it; they are not added automatically.<br><br>Apple mobile devices, such as iPhones and iPads, do not fully support Video Group Chat. This is a hardware constraint.<br><br>\tFor advanced options and parameters, <a href=\"https://github.com/steveseguin/obsninja/wiki/Guides-and-How-to's#urlparameters\">see the Wiki.</a>",
|
||||
"guest-will-appaer-here-on-join": "(Видео появится здесь, когда гость присоединится)",
|
||||
"SOLO-LINK": "ПЕРСОНАЛЬНАЯ ССЫЛКА для OBS:"
|
||||
}
|
||||
}
|
||||
68
translations/tr.json
Normal file
68
translations/tr.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"GO": "BAŞLA",
|
||||
"add-group-chat": "OBS'ye Grup Konuşması Ekle",
|
||||
"add-to-group": "Grup Sahnesine Ekle",
|
||||
"add-your-camera": "Kamera'nı OBS'ye Ekle",
|
||||
"added-notes": "\n\t\t\t\t<u><i>Ek Notlar:</i></u>\n\t\t\t\t<li>Odanın ismini bilen herkes giriş yapabilir, bu yüzden olabildiğince özgün bir isim seçin.</li>\n\t\t\t\t<li>Performans sebeplerinden ötürü bir odada dört (4) kişiden fazla olmasını tavsiye etmiyoruz, ancak bu donanımınızla ölçeklenen bir durumdur.</li>\n\t\t\t\t<li>iOS cihazları sadece iki (2) kişilik gruplarla sınırldır, bu bir donanım sınırlamasıdır.</li>\n\t\t\t\t<li>\"Kayır\" seçeneği yeni ve deneyseldir.</li>\n\t\t\t\t<li>Görünebilmesi için \"Grup Sahnesine\" bir kamera akışı \"eklemeniz\" gerekiyor.</li>\n\t\t\t\t<li>Misafirlerin ekranlarına yeni bir \"geliştirilmiş tam ekran\" düğmesi eklendi.</li>\n\t\t\t\t",
|
||||
"advanced-paramaters": "Gelişimişi Özellikler",
|
||||
"audio-sources": "Ses Kaynakları",
|
||||
"back": "Geri",
|
||||
"balanced": "Dengeli",
|
||||
"copy-this-url": "Bu URL'yi bir OBS \"Tarayıcı Kaynağına\" kopyalayın",
|
||||
"copy-to-clipboard": "Panoya Kopyala",
|
||||
"create-reusable-invite": "Yeniden Kullanılabilir Davet Oluştur",
|
||||
"enable-stereo-and-pro": "Stereo ve Pro HD Sesi Etkinleştir",
|
||||
"enter-the-rooms-control": "Oda'nın Kontrol Merkezine Gir",
|
||||
"force-vp9-video-codec": "VP9 Codec'e Zorla (görüntüde daha az bozulma)",
|
||||
"generate-invite-link": "DAVET BAĞLANTISINI OLUŞTUR",
|
||||
"here-you-can-pre-generate": "Burada tekrar kullanılabilir bir Tarayıcı Kaynak bağlantısı ve onunla ilişkili misafir davet bağlantısı oluşturabilirsin.",
|
||||
"high-security-mode": "Yüksek Güvenlik Modu",
|
||||
"info-blob": "\n\t\t\t\t\t\t<h2>OBS.Ninja Nedir?</h2><br>\n\t\t\t\t\t\t<li>100% <b>bedava</b>; indirme yok; kişisel veri toplama yok; giriş yok</li>\n\t\t\t\t\t\t<li>Bilgisayarınızdan, dizüstünden, telefonunuzdan - hatta arkadaşlarınızdan görüntüleri OBS akışınızın içine alın</li>\n\t\t\t\t\t\t<li>Biz yeni nesil Peer-to-Peer (Kişiden-Kişiye) yönlendirme teknolojisi kullanıyoruz, bu sayede çok düşük gecikme ve gizlilik sağlayabiliyoruz</li>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\t<li>Youtube video <i class=\"fa fa-youtube-play\" aria-hidden=\"true\"></i> <a href=\"https://www.youtube.com/watch?v=6R_sQKxFAhg\">Burada demoyu görebilirsiniz (ingilizce)</a> </li>\n\t\t\t\t\t\t<li>Koda buradan erişebilirsiniz: <i class=\"fa fa-github\" aria-hidden=\"true\"></i> <a href=\"https://github.com/steveseguin/obsninja\">https://github.com/steveseguin/obsninja</a> </li>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\t<i><font style=\"color:red\">Known issues:</font></i><br>\n\n\t\t\t\t\t\t<li><i class=\"fa fa-apple\" aria-hidden=\"true\"></i> MacOS kullanıcıları OBS v23 kullanmalı, v25 kullanırlarsa Chrome ile <i>pencere yakalama</i> yöntemine baş vurmak zorunda kalabilirler.</li>\n\t\t\t\t\t\t<li>Bazı kullanıcıların videolarla ilgili \"pikselasyon\" problemleri olacaktır. Bu durumda OBS tarayıcı bağlantı URL'sine şu parametreyi ekleyin <b>&codec=vp9</b>.</li>\n\t<h3><i>Yardım ve daha fazla bilgi için Reddit'de <a href=\"https://www.reddit.com/r/OBSNinja/\">sub-reddit</a> <i class=\"fa fa-reddit-alien\" aria-hidden=\"true\"></i>'ine göz atın. Beni ayrıca <a href=\"https://discord.gg/EksyhGA\">Discord'da</a> bulabilirsiniz, e-mail ile ulaşmak için: steve@seguin.email</i></h3>\n\t\t\t\t\t",
|
||||
"joining-room": "Odaya bağlanıyorsunuz",
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
"max-resolution": "Maksimum Çözünürlük",
|
||||
"mute": "Sesi Kıs",
|
||||
"no-audio": "Sessiz",
|
||||
"note-share-audio": "\n\t\t\t\t\t<b>note</b>: Chrome'da \"Sesi paylaş\" 'ı seçmeyi unutma.<br>(Firefox ses paylaşımını desteklemiyor.)",
|
||||
"open-in-new-tab": "Yeni Sekmede Aç",
|
||||
"record": "Kaydet",
|
||||
"remote-control-for-obs": "OBS için Uzaktan Kontrol",
|
||||
"remote-screenshare-obs": "OBS'ye uzaktan ekran paylaşımı",
|
||||
"room-name": "Oda İsmi",
|
||||
"rooms-allow-for": "Odalar basit konuşma ve sohbet'in yanında çoklu video akışların gelişmiş yönetimini de sağlar.",
|
||||
"select-audio-source": "Ses Kaynaklarını Seçin",
|
||||
"select-audio-video": "Ses/Görüntü kaynağını aşağıdan seçin",
|
||||
"select-screen-to-share": "PAYLAŞILACAK EKRANI SEÇİN",
|
||||
"show-tips": "Bana ipuları göster",
|
||||
"smooth-cool": "Pürüzsüz ve Soğukkanlı",
|
||||
"unlock-video-bitrate": "Video Bitrate Sınırını Kaldır (20mbps)",
|
||||
"video-source": "Video kaynağı",
|
||||
"volume": "Ses düzeyi",
|
||||
"you-are-in-the-control-center": "Odanın kontrol merkezindesiniz",
|
||||
"waiting-for-camera": "Kameranın yüklenmesi bekleniyor",
|
||||
"video-resolution": "Video Çözünürlüğü: ",
|
||||
"hide-screen-share": "Ekran Paylaşma'yı Gizle",
|
||||
"allow-remote-control": "Kamera Zoom'una Uzaktan Kontrol (android)",
|
||||
"add-the-guest-to-a-room": " Odaya Misafiri Ekle:",
|
||||
"invite-group-chat-type": "Bu oda misafiri:",
|
||||
"can-see-and-hear": "Grup konuşmasını görebilir ve duyabilir",
|
||||
"can-hear-only": "Grup konunşmasını sadece duyabilir",
|
||||
"cant-see-or-hear": "Gup konuşmasını duyamaz ve göremez",
|
||||
"password-input-field": "Şifre",
|
||||
"select-output-source": " Ses Çıkışı: \n\t\t\t\t\t",
|
||||
"add-a-password-to-stream": " Şifre Ekle:",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tOBS.Ninja'ya hoş geldin! Bağlı olan kişilere buradan yazılı mesajlar gönderebilirsin.\n\t\t\t\t",
|
||||
"names-and-labels-coming-soon": "\n\t\t\t\t\tBağlanan kişileri tanımlayan isimler ileriki bir geliştirmede yer alacak.\n\t\t\t\t",
|
||||
"send-chat": "Gönder",
|
||||
"available-languages": "Diller:",
|
||||
"add-more-here": "Daha fazla ekle!",
|
||||
"invite-users-to-join": "Gruba katılmaları ve akışlarını yansıtmaları için misafirleri davetet. Bu kullanıcılar odada yer alan tüm akışları görebilecek.",
|
||||
"link-to-invite-camera": "Akışlarını gruba yansıtmaları için misafir bağlantısı. Bu kullanıcılar diğer akışları duyamayacak ve göremeyecek.",
|
||||
"this-is-obs-browser-source-link": "Bu boş bir OBS tarayıcı kaynak bağlantısıdır. Odada yer alan videolar el ile buraya eklenebilir.",
|
||||
"this-is-obs-browser-souce-link-auto": "Yine bir OBS tarayıcı kaynak bağlantısı. Bu odada yer alan tüm misafirler otomatik olarak bu sahneye eklenecektir.",
|
||||
"click-for-quick-room-overview": "❔ Buraya tıklayarak hızlı yardım ve genel bakışa göz atın",
|
||||
"push-to-talk-enable": "🔊 Yönetmen bas-konuş'u etkinleştir",
|
||||
"welcome-to-control-room": "Hoş geldiniz. Bu grup konuşması için kontrol odasıdır. Bu odayı farklı amaçlar için kullanabilirsiniz:<br><br>\t<li>Arkadaşlarınız ile grup konunşması yapmak için bir oda kullanabilirsiniz. Otomatik olarak gruba dahil etmek için misafirleriniz ile mavi bağlantıyı paylaşın.</li>\t<li>Bir grup odası 4 - 30 sayıda misafir ağırlayabilir. Ancak bu bir çok etkene göre değişebilir, yeterli CPU ve internet bant genişliği gibi.</li>\t<li>Her videonun tekil görüntüsü bağlantıları misafirler bağlandıkça videolarının altında yer alacak. Bunları OBS tarayıcı kaynağı olarak kullanabilirsiniz.</li>\t<li>Otomatik-karıştırma grup sahnesi (yeşil bağlantı) bir çok videoyu OBS'de otomatik ayarlamak için kullanabilirsiniz.</li>\t<li>Bu odayı kullanarak her bir video için ayrı ayrı video ve ses kaynaklarını kaydedebilirsiniz, ancak bu özellik halen deneysel aşamadadır.</li>\t<li>Yönetmen odasında yer alan videolar kasten düşük kalitede tutulmuştur; CPU ve internetbant genişliğinden tasarruf için</li>\t<li>Odada yer alan misafirler, CPU ve internetten tasarruf etmek amacıyla bir birlerinin videolarını düşük kalitede görecek.</li>\t<li>OBS misafirlerin videolarını çok yüksek kalitede alacak, varsayılan kalite 2500kbps'dir.</li>\t<br>\tMisafirler eklendikçe videoları aşağıda belirecek. OBS'ye videolarını tekil sahneler olarak ekleyebilir, ya da grup sahnelerine ekleyebilirsiniz.\t<br>Grup sahnesi, eklenmiş videoları otomatik olarak karıştırır. Otomatik karıştırmanın çalışması için misafirlerin el ile bu sahneye eklenmesi gerektiğini unutmayın; otomatik olarak sahnelere eklenmeyeceklerdir.<br><br>iPhone iPad gibi Apple mobil cihazlar, tam olarak video grup görüşmeyi desteklemiyor. Bu bir donanım sınırlamasıdır.<br><br>\tGekişmiş özellik ve parametreler için <a href=\"https://github.com/steveseguin/obsninja/wiki/Guides-and-How-to's#urlparameters\">Wiki'ye göz atın.</a>",
|
||||
"guest-will-appaer-here-on-join": "(Bir misafir bağlandığında burada bir video görünecek)",
|
||||
"SOLO-LINK": "OBS İÇİN TEKİL BAĞLANTI:"
|
||||
}
|
||||
@@ -45,7 +45,10 @@ sudo ufw allow 49152:65535/tcp
|
||||
sudo ufw allow 49152:65535/udp
|
||||
```
|
||||
|
||||
Update turnserver.conf with passwords, domain names, and whatever else that needs changing. Example contents are provided below. Once you have updated it, start the TURN server and ensure it started correctly.
|
||||
If we expect heavy usage of this server, like hundreds of connections, you might want to ensure your system supports enough open sockets. I'm not sure if this actually works or is needed, but you can see this article for example on how to increase the number of available sockets on Ubuntu: https://medium.com/@muhammadtriwibowo/set-permanently-ulimit-n-open-files-in-ubuntu-4d61064429a
|
||||
|
||||
|
||||
Next, update turnserver.conf with passwords, domain names, and whatever else that needs changing. Example contents are provided below. Once you have updated it, start the TURN server and ensure it started correctly.
|
||||
```
|
||||
sudo vi /etc/turnserver.conf
|
||||
|
||||
|
||||
Reference in New Issue
Block a user