Compare commits
226 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e30724e8c | ||
|
|
5e2249c8b9 | ||
|
|
b366469e59 | ||
|
|
a125421357 | ||
|
|
9db09a6278 | ||
|
|
d87d04a4d4 | ||
|
|
0154565589 | ||
|
|
6912a98867 | ||
|
|
dc26a23ff9 | ||
|
|
be28fbde1b | ||
|
|
b32d040ea2 | ||
|
|
4010bd220e | ||
|
|
b37fcf855d | ||
|
|
d798c6bd14 | ||
|
|
717c3aa7cc | ||
|
|
e424cf3c5c | ||
|
|
36a63f6155 | ||
|
|
2eff3ef88b | ||
|
|
5f77aace18 | ||
|
|
d10a08e84f | ||
|
|
c30e282c1b | ||
|
|
05d6f3d0ee | ||
|
|
d8f897b974 | ||
|
|
0a5e820801 | ||
|
|
0b8e809b2f | ||
|
|
ad79f8c452 | ||
|
|
3f7bb89b5d | ||
|
|
ef4c2e5d77 | ||
|
|
1d9da2b08e | ||
|
|
b0a55bf225 | ||
|
|
db04376a68 | ||
|
|
c701bd4f8f | ||
|
|
77df3a2ff1 | ||
|
|
ba56f40ba5 | ||
|
|
d1c980f309 | ||
|
|
27c7d5c43b | ||
|
|
56806a2186 | ||
|
|
e2e56e5f4b | ||
|
|
321f366c6b | ||
|
|
93a1813fda | ||
|
|
4adf5fbe2d | ||
|
|
cee772d031 | ||
|
|
15030fe123 | ||
|
|
0b064f7c69 | ||
|
|
6f6c7c3d97 | ||
|
|
06078ecd2b | ||
|
|
f1d60678c4 | ||
|
|
8624f5bd67 | ||
|
|
3882583d6c | ||
|
|
d66a44e57c | ||
|
|
8cbd26e34b | ||
|
|
98c293d436 | ||
|
|
14cf419e31 | ||
|
|
74670f5dd0 | ||
|
|
58e07f58d9 | ||
|
|
bc5fd78196 | ||
|
|
612949ba64 | ||
|
|
2bf59f0c2a | ||
|
|
495f508919 | ||
|
|
e8354f45c0 | ||
|
|
2de7c38d7f | ||
|
|
2be4038885 | ||
|
|
b92af980fb | ||
|
|
f734d63118 | ||
|
|
3859cb2762 | ||
|
|
9600693001 | ||
|
|
8934838954 | ||
|
|
e5f203e178 | ||
|
|
3890f28ede | ||
|
|
e4e9398853 | ||
|
|
a296ba8417 | ||
|
|
a843d3d04d | ||
|
|
bb1061f22f | ||
|
|
29458e4a87 | ||
|
|
ce97e74bea | ||
|
|
98f058594e | ||
|
|
8337a8548d | ||
|
|
be3bb3e532 | ||
|
|
82214cbb9d | ||
|
|
6ab5a338af | ||
|
|
bd9d707434 | ||
|
|
bc6f4f08fc | ||
|
|
28847040f7 | ||
|
|
5ab89d61b3 | ||
|
|
d059757f35 | ||
|
|
cae33a0b92 | ||
|
|
05d5cd1a00 | ||
|
|
137112242f | ||
|
|
2ac3ff7242 | ||
|
|
56a007725d | ||
|
|
6f3b869c6e | ||
|
|
71dac482d4 | ||
|
|
ab4582cc46 | ||
|
|
4a57a86b53 | ||
|
|
1086848f78 | ||
|
|
e91aba28bd | ||
|
|
7736e3fb6f | ||
|
|
8f292cf7d2 | ||
|
|
4a1213781d | ||
|
|
56f46bcd77 | ||
|
|
d7e2b1dc3d | ||
|
|
e926196bcc | ||
|
|
a48986b618 | ||
|
|
35fdd27f42 | ||
|
|
7692623d90 | ||
|
|
f640a9a16f | ||
|
|
1b69686288 | ||
|
|
da63ec44fe | ||
|
|
38162971ed | ||
|
|
7bd12cc4a4 | ||
|
|
53ea3ac18c | ||
|
|
c0bb8b5cad | ||
|
|
a8d2bd9c0c | ||
|
|
6b3f538da3 | ||
|
|
dd13c46be9 | ||
|
|
47d69c1b40 | ||
|
|
c4280b6c1d | ||
|
|
1511de0277 | ||
|
|
4fcdd805a2 | ||
|
|
bfb05c7581 | ||
|
|
33b2340eac | ||
|
|
a00a6af494 | ||
|
|
cd6983d75a | ||
|
|
5b70d31844 | ||
|
|
36b25b7ab7 | ||
|
|
dcd3a35682 | ||
|
|
8a13af5a1b | ||
|
|
7bf4fb7b8a | ||
|
|
c0f8ba75d0 | ||
|
|
20d209e222 | ||
|
|
bb84c95662 | ||
|
|
afad412936 | ||
|
|
fa7fa50d26 | ||
|
|
48977fe737 | ||
|
|
de99499e30 | ||
|
|
77c401f9c9 | ||
|
|
1d04fbc474 | ||
|
|
9190a4584e | ||
|
|
22f34d6b1e | ||
|
|
b973e16396 | ||
|
|
66559c72b7 | ||
|
|
b25614bd5f | ||
|
|
57ec0db1eb | ||
|
|
b113d53f15 | ||
|
|
2cb96bb133 | ||
|
|
4992858414 | ||
|
|
f43f79a6cd | ||
|
|
6284b38694 | ||
|
|
e69c5502b2 | ||
|
|
bf3c1ee97c | ||
|
|
0dbecf021d | ||
|
|
0573bb9191 | ||
|
|
a09d86d79e | ||
|
|
d1a2cc89f5 | ||
|
|
fc48814111 | ||
|
|
c7bb3f8acf | ||
|
|
e91d972753 | ||
|
|
ab1b0f2aa0 | ||
|
|
59d3b0f0fb | ||
|
|
1eb2f50605 | ||
|
|
a51d43777a | ||
|
|
cf4959c6db | ||
|
|
68923a2462 | ||
|
|
055c4652ae | ||
|
|
791aaf497e | ||
|
|
f886e485db | ||
|
|
6b56b5ea33 | ||
|
|
41e1b4dc02 | ||
|
|
a22388a24b | ||
|
|
10ef9193b0 | ||
|
|
554af144f2 | ||
|
|
36ae6c0f1e | ||
|
|
b949986182 | ||
|
|
b36b52ad8b | ||
|
|
de4f981455 | ||
|
|
eae305913f | ||
|
|
14c13b02de | ||
|
|
5bb7bbdd5c | ||
|
|
ea1895c129 | ||
|
|
80295a7a9a | ||
|
|
ec1ec458aa | ||
|
|
6b6e2b5a3f | ||
|
|
a67e585eb1 | ||
|
|
c6690fcdac | ||
|
|
1f2c193956 | ||
|
|
1ba4d61486 | ||
|
|
e1f7ccacfe | ||
|
|
e366bdfa4c | ||
|
|
62292e71ea | ||
|
|
06379c1f1f | ||
|
|
b471096842 | ||
|
|
85b336bafd | ||
|
|
fae0b094ac | ||
|
|
a028a753e8 | ||
|
|
a24e5ae667 | ||
|
|
0f7b09526d | ||
|
|
f335813c5e | ||
|
|
f62f31329d | ||
|
|
cbc7971fa5 | ||
|
|
838acf07ac | ||
|
|
864969ebae | ||
|
|
474e142908 | ||
|
|
e5a7b29a46 | ||
|
|
9cc109c254 | ||
|
|
8338573c10 | ||
|
|
46b00b1ce1 | ||
|
|
d2dd662d10 | ||
|
|
c89fcc0064 | ||
|
|
8d24e23232 | ||
|
|
474155e0d9 | ||
|
|
166f933953 | ||
|
|
43aa080bce | ||
|
|
4e273219f8 | ||
|
|
1c3d45ae6f | ||
|
|
c7a801c0e0 | ||
|
|
8c4c1cd040 | ||
|
|
c487bed906 | ||
|
|
e762910907 | ||
|
|
f0cfa1effd | ||
|
|
8ee5be2960 | ||
|
|
1934097875 | ||
|
|
4e922c13aa | ||
|
|
17403d816b | ||
|
|
944e619f0a | ||
|
|
d6d4d93dab | ||
|
|
5c7648d86a |
168
.github/ci-generateTranslations.js
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
var https = require("https");
|
||||
const jsdom = require("jsdom");
|
||||
const { JSDOM } = jsdom;
|
||||
const axios = require("axios").default;
|
||||
const fs = require("fs");
|
||||
|
||||
const dom = new JSDOM(``, {
|
||||
url: "https://obs.ninja",
|
||||
contentType: "text/html",
|
||||
includeNodeLocations: true,
|
||||
storageQuota: 10000000,
|
||||
pretendToBeVisual: true,
|
||||
});
|
||||
|
||||
global.document = new JSDOM(``, {
|
||||
url: "https://obs.ninja",
|
||||
contentType: "text/html",
|
||||
includeNodeLocations: true,
|
||||
storageQuota: 10000000,
|
||||
pretendToBeVisual: false,
|
||||
}).window.document;
|
||||
|
||||
function downloadTranslation(filename, trans = {}) {
|
||||
// downloads the current translation to a file
|
||||
console.log("Downloading translation: " + filename);
|
||||
const textDoc = JSON.stringify(trans, null, 2);
|
||||
|
||||
fs.writeFile(`translations/${filename}.json`, textDoc, (err) => {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
}
|
||||
});
|
||||
|
||||
return trans;
|
||||
}
|
||||
|
||||
async function updateTranslation(filename) {
|
||||
// updates the website with a specific translation
|
||||
let data = await axios({
|
||||
method: "get",
|
||||
url: `https://raw.githubusercontent.com/steveseguin/obsninja/master/translations/${filename}.json?${(
|
||||
Math.random() * 100
|
||||
).toString()}`,
|
||||
})
|
||||
.then((response) => {
|
||||
return response.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
const oldTransItems = data["innerHTML"];
|
||||
|
||||
// const allItems1 = document.querySelectorAll('[data-translate]');
|
||||
|
||||
allItems.forEach((ele) => {
|
||||
const key = ele.dataset.translate; //.replace(/[\W]+/g, "-").toLowerCase();
|
||||
if (key in oldTransItems) {
|
||||
ele.innerHTML = oldTransItems[key];
|
||||
}
|
||||
});
|
||||
|
||||
const oldTransTitles = data["titles"];
|
||||
//const allTitles1 = document.querySelectorAll('[title]');
|
||||
allTitles.forEach((ele) => {
|
||||
const key = ele.dataset.key;
|
||||
//const key = ele.title.replace(/[\W]+/g, "-").toLowerCase();
|
||||
if (key in oldTransTitles) {
|
||||
ele.title = oldTransTitles[key];
|
||||
}
|
||||
});
|
||||
|
||||
const oldTransPlaceholders = data.placeholders;
|
||||
//const allPlaceholders1 = document.querySelectorAll('[placeholder]');
|
||||
allPlaceholders.forEach((ele) => {
|
||||
const key = ele.dataset.key;
|
||||
//const key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase();
|
||||
if (key in oldTransPlaceholders) {
|
||||
ele.placeholder = oldTransPlaceholders[key];
|
||||
}
|
||||
});
|
||||
|
||||
return [true, data];
|
||||
}
|
||||
|
||||
const updateList = [
|
||||
"cs",
|
||||
"de",
|
||||
"en",
|
||||
"es",
|
||||
"fr",
|
||||
"it",
|
||||
"ja",
|
||||
"nl",
|
||||
"pig",
|
||||
"pt",
|
||||
"ru",
|
||||
"tr",
|
||||
"blank",
|
||||
]; // list of languages to update. Update this if you add a new language.
|
||||
|
||||
const allItems = document.querySelectorAll("[data-translate]");
|
||||
const defaultTrans = {};
|
||||
allItems.forEach((ele) => {
|
||||
const key = ele.dataset.translate; //.replace(/[\W]+/g, "-").toLowerCase();
|
||||
defaultTrans[key] = ele.innerHTML;
|
||||
});
|
||||
|
||||
const defaultTransTitles = {};
|
||||
const allTitles = document.querySelectorAll("[title]");
|
||||
allTitles.forEach((ele) => {
|
||||
const key = ele.title.replace(/[\W]+/g, "-").toLowerCase();
|
||||
ele.dataset.key = key;
|
||||
defaultTransTitles[key] = ele.title;
|
||||
});
|
||||
|
||||
const defaultTransPlaceholders = {};
|
||||
const allPlaceholders = document.querySelectorAll("[placeholder]");
|
||||
allPlaceholders.forEach((ele) => {
|
||||
const key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase();
|
||||
ele.dataset.key = key;
|
||||
defaultTransPlaceholders[key] = ele.placeholder;
|
||||
});
|
||||
|
||||
const combinedTrans = {};
|
||||
combinedTrans.titles = defaultTransTitles;
|
||||
combinedTrans.innerHTML = defaultTrans;
|
||||
combinedTrans.placeholders = defaultTransPlaceholders;
|
||||
|
||||
var counter = 0;
|
||||
for (var i = 0; i < updateList.length; i++) {
|
||||
const lang = updateList[i];
|
||||
|
||||
var translation = updateTranslation(lang); // we don't need to worry about DATA.
|
||||
updateTranslation(lang)
|
||||
.then((translation) => {
|
||||
const newTrans = translation[1]["innerHTML"];
|
||||
//const allItems = document.querySelectorAll('[data-translate]');
|
||||
allItems.forEach((ele) => {
|
||||
const key = ele.dataset.translate; //.replace(/[\W]+/g, "-").toLowerCase();
|
||||
newTrans[key] = ele.innerHTML;
|
||||
});
|
||||
|
||||
const newTransTitles = translation[1]["titles"];
|
||||
//const allTitles = document.querySelectorAll('[title]');
|
||||
allTitles.forEach((ele) => {
|
||||
const key = ele.dataset.key;
|
||||
newTransTitles[key] = ele.title;
|
||||
});
|
||||
|
||||
const newPlaceholders = translation[1]["placeholders"];
|
||||
// const allPlaceholders = document.querySelectorAll('[placeholder]');
|
||||
allPlaceholders.forEach((ele) => {
|
||||
const key = ele.dataset.key;
|
||||
newPlaceholders[key] = ele.placeholder;
|
||||
});
|
||||
|
||||
// //// DOWNLOAD UPDATED TRANSLATION
|
||||
const outputTrans = {};
|
||||
outputTrans["titles"] = newTransTitles;
|
||||
outputTrans["innerHTML"] = newTrans;
|
||||
outputTrans["placeholders"] = newPlaceholders;
|
||||
downloadTranslation(lang, outputTrans);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
21
.github/workflows/update-advanced-settings-toc.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Update Advanced Settings Markdown TOC
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 29 2 1'
|
||||
|
||||
jobs:
|
||||
update-toc:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: ${{github.repository}}.wiki
|
||||
- name: Run github-markdown-toc
|
||||
run: |
|
||||
curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc
|
||||
chmod a+x gh-md-toc
|
||||
./gh-md-toc --insert --no-backup Advanced-Settings.md
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
commit_message: "Auto update markdown TOC"
|
||||
39
.github/workflows/update_translations.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Update translations
|
||||
|
||||
# Controls when the action will run.
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the master branch
|
||||
push:
|
||||
paths:
|
||||
- 'index.html'
|
||||
- 'main.js'
|
||||
branches:
|
||||
- master
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
build:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
- run: npm install jsdom && npm install axios
|
||||
- run: node .github/ci-generateTranslations.js
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
commit-message: Generated updated translations
|
||||
branch: generated_translations
|
||||
title: "[OBSNinja Bot] Updated translations"
|
||||
labels: i18n
|
||||
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
package-lock.json
|
||||
@@ -1,8 +1,8 @@
|
||||
OBS.Ninja Contributor License Agreement (CLA)
|
||||
# OBS.Ninja Contributor License Agreement (CLA)
|
||||
|
||||
To ensure the long-term viability of the open-source OBS.Ninja project, and for the protection of its creator and its users, we request that contributors to the project first agree to some basic terms. The terms when accepted applies to all of your past, present and future contributions.
|
||||
|
||||
Contribution Policy
|
||||
# Contribution Policy
|
||||
|
||||
Contributions that only take 20 lines of code or less will have its Intellectual Property implicitly transferred to Stephen Seguin, the creator of OBS.Ninja. You agree with this rule by pushing your code or works to github, by sending the code or works to one of OBS.Ninja's core developers, or by distributing your code or works in any other way.
|
||||
|
||||
@@ -10,6 +10,7 @@ For all code contributions that take more than 20 lines, you are invited to digi
|
||||
|
||||
It is not required that you sign the CLA for every contribution. Once you execute a CLA, it is valid until the CLA agreement is meaningfully changed and requires updating.
|
||||
|
||||
Important notice: if you are contributing on behalf of your company, an officer of your company (usually a VP or higher title) must sign the CLA on behalf of the company, indicating his or her title. The company can choose to list the specific individuals authorized to make contributions on the "Full Name" line, or may cover all employees with a blanket CLA by not limiting contributors to an authorized list. If necessary, the company may provide a list of authorized contributors in an attachment. The executive signing the CLA must be the first name on such an attached list, and this executive must sign the attachment as well. It may well be the case that your company already has signed a company-wide CLA with Stephen Seguin. Please check this first.
|
||||
## Important notice
|
||||
If you are contributing on behalf of your company, an officer of your company (usually a VP or higher title) must sign the CLA on behalf of the company, indicating his or her title. The company can choose to list the specific individuals authorized to make contributions on the "Full Name" line, or may cover all employees with a blanket CLA by not limiting contributors to an authorized list. If necessary, the company may provide a list of authorized contributors in an attachment. The executive signing the CLA must be the first name on such an attached list, and this executive must sign the attachment as well. It may well be the case that your company already has signed a company-wide CLA with Stephen Seguin. Please check this first.
|
||||
|
||||
You can stop your participation in a project at any time, but you cannot rescind your assignments or grants with respect to prior contributions. This protects the whole community, allowing Stephen Seguin and downstream users of the code base to rely on it.
|
||||
|
||||
478
IFRAME.md
@@ -1,217 +1,305 @@
|
||||
## OBS.Ninja - iFrame API documentation
|
||||
## VDO.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.
|
||||
VDO.Ninja (VDON) is offers here a simple and free solution to quickly enable real-time video streaming in their websites. VDON 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.
|
||||
While VDO.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.
|
||||
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 VDO.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.
|
||||
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 VDON 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:
|
||||
Creating an VDON 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";
|
||||
```
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.allow = "autoplay;camera;microphone";
|
||||
iframe.allowtransparency = "false";
|
||||
iframe.src = "https://vdo.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.
|
||||
You can also make an VDO.Ninja without Javascript, using just HTML, like
|
||||
|
||||
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
|
||||
`<iframe allow="autoplay;camera;microphone" src="https://vdo.ninja/?view=vhX5PYg&cleanoutput&transparent"></iframe>`
|
||||
|
||||
More community-contributed IFRAME examples can be found here: https://github.com/steveseguin/obsninja/tree/master/examples
|
||||
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.
|
||||
|
||||
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
|
||||
An example of how this API is used by VDO.Ninja is with its Internet Speedtest, which has two VDO.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://vdo.ninja/speedtest
|
||||
|
||||
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.
|
||||
More community-contributed IFRAME examples can be found here: https://github.com/steveseguin/vdoninja/tree/master/examples
|
||||
|
||||
For more information on the URL parameters thare are available, please see: https://github.com/steveseguin/obsninja/wiki/Advanced-Settings
|
||||
A sandbox of options is available at this page, too: https://vdo.ninja/iframe You can enter an VDO.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/vdoninja/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 VDO.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/vdoninja/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:
|
||||
- &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
|
||||
- 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.
|
||||
As for the actually details for methods and options available to dynamically control child VDON 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:
|
||||
|
||||
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.
|
||||
```js
|
||||
let button = document.createElement("button");
|
||||
button.innerHTML = "Mute Speaker";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"mute": true
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
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.
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Un-Mute Speaker";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"mute": false
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Toggle Speaker";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"mute": "toggle"
|
||||
}, '*');
|
||||
}
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Mute Mic";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"mic": false
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Un-Mute Mic";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"mic": true
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Toggle Mic";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"mic": "toggle"
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Disconnect";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"close": true
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Low Bitrate";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"bitrate": 30
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "High Bitrate";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"bitrate": 5000
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Default Bitrate";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"bitrate": -1
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Reload";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"reload": true
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "50% Volume";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"volume": 0.5
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "100% Volume";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"volume": 1.0
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Request Stats";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"getStats": true
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Request Loudness Levels";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"getLoudness": true
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Stop Sending Loudness Levels";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"getLoudness": false
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "Say Hello";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"sendChat": "Hello!"
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "previewWebcam()";
|
||||
button.onclick = () => {
|
||||
iframe.contentWindow.postMessage({
|
||||
"function": "previewWebcam"
|
||||
}, '*');
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.innerHTML = "CLOSE IFRAME";
|
||||
button.onclick = () => {
|
||||
iframeContainer.parentNode.removeChild(iframeContainer);
|
||||
};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
// As for listening events, where the parent listens for responses or events from the VDON child frame:
|
||||
|
||||
// ////////// LISTEN FOR EVENTS
|
||||
|
||||
const eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
||||
const eventer = window[eventMethod];
|
||||
const 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) {
|
||||
const outputWindow = document.createElement("div");
|
||||
|
||||
let out = `<br />total_inbound_connections:${
|
||||
e.data.stats.total_inbound_connections
|
||||
}`;
|
||||
out += `<br />total_outbound_connections:${
|
||||
e.data.stats.total_outbound_connections
|
||||
}`;
|
||||
|
||||
for (const 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) {
|
||||
const outputWindow = document.createElement("div");
|
||||
outputWindow.innerHTML = e.data.gotChat.msg;
|
||||
outputWindow.style.border = "1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
}
|
||||
|
||||
if ("action" in e.data) {
|
||||
const 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 {
|
||||
const outputWindow = document.createElement("div");
|
||||
outputWindow.style.border = "1px dotted black";
|
||||
iframeContainer.appendChild(outputWindow);
|
||||
outputWindow.id = "loudness";
|
||||
}
|
||||
outputWindow.innerHTML = "child-page-action: loudness<br />";
|
||||
for (const key in e.data.loudness) {
|
||||
outputWindow.innerHTML += `${key} Loudness: ${
|
||||
e.data.loudness[key]
|
||||
}\n`;
|
||||
}
|
||||
outputWindow.style.border = "1px black";
|
||||
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
This VDO.Ninja API is developed and expanded based on user feedback and requests. It is by no means complete.
|
||||
|
||||
Please feel free to follow me in the VDO.Ninja Discord channel (discord.vdo.ninja) where I post news about updates and listen to requests. The upcoming version of VDO.Ninja is also often hosted at https://vdo.ninja/beta, where you can explore new features and help crush any unexpected bugs.
|
||||
|
||||
-steve
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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
|
||||
That AGPL-3.0 licence can be found here: [AGPLv3.md](https://github.com/steveseguin/obsninja/blob/master/AGPLv3.md)
|
||||
|
||||
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.
|
||||
|
||||
79
README.md
@@ -1,71 +1,78 @@
|
||||
|
||||
<img src="media/obsNinja_logo_full.png" alt="Logo by brimace" data-canonical-src="https://gyazo.com/eb5c5741b6a9a16c692170a41a49c858.png" height="150" />
|
||||
#### ⚠ Notice! We've started our rebranding from OBS.Ninja to VDO.Ninja 🎈 -- nothing else will be changing. ✨
|
||||
|
||||
## What is OBS NINJA
|
||||
OBS.Ninja uses peer-to-peer technology to bring remote cameras into OBS. In most cases, all video data is transferred directly from peer to peer, without needing to go through any video server. This results in high-quality video with super low latency. In a small number of cases, video data may go through an encrypted TURN server, which is used to facilitate peer connections when otherwise not possible.
|
||||
|
||||
OBS Ninja is not affiliated with OBS. OBS.Ninja is designed to allow content creators to produce real-time live shows with OBS Studio (or other compatible software) using remote media streams. It can also turn smartphones into wireless webcams, with additional Virtualcam software.
|
||||
<img src="media/obsNinja_logo_full.png" alt="Logo by brimace" height="150" />
|
||||
|
||||
Please see the sub-reddit added info: https://reddit.com/r/obsninja
|
||||
Also check out the FAQ for more info: https://github.com/steveseguin/obsninja/wiki
|
||||
## What is ~~OBS NINJA~~ **VDO NINJA**
|
||||
VDO.Ninja uses peer-to-peer technology to bring remote cameras into OBS or other studio software.
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/2575698/94018108-34b1de00-fd7e-11ea-8c7d-df001253b60d.png" data-canonical-src="https://gyazo.com/eb5c5741b6a9a16c692170a41a49c858.png" height="300" />
|
||||
In most cases, all video data is transferred directly from peer to peer, without needing to go through any video server. This results in high-quality video with super low latency. In a small number of cases, video data may go through an encrypted TURN server, which is used to facilitate peer connections when otherwise not possible.
|
||||
|
||||
## How to use:
|
||||
I demo the basic usage of OBS.Ninja on YouTube: https://www.youtube.com/watch?v=6R_sQKxFAhg
|
||||
VDO.Ninja is designed to allow content creators to produce real-time live shows using remote media streams. It can also turn smartphones into wireless webcams, with additional Virtualcam software.
|
||||
|
||||
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
|
||||
VDO.Ninja is freely available to use as a managed service over at https://vdo.ninja.
|
||||
|
||||
For live support, please join our discord at https://discord.obs.ninja
|
||||
Please see the sub-reddit added info: https://reddit.com/r/vdoninja
|
||||
Also check out the FAQ for more info: https://github.com/steveseguin/vdoninja/wiki
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/2575698/120865595-56de3b80-c55c-11eb-8b98-60c59ae0f904.png" height="300" />
|
||||
|
||||
## How to use
|
||||
I demo the basic usage of VDO.Ninja on YouTube: https://www.youtube.com/watch?v=6R_sQKxFAhg
|
||||
|
||||
Here is a podcast series showing how to use different basic VDO.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 25/26, but there are workarounds. Please see the subreddit or the Wiki.
|
||||
## What's in this repo
|
||||
This repo contains software for VDO.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](https://github.com/steveseguin/vdoninja/wiki) for the project in this repo, which contains added information on how to use the software.
|
||||
|
||||
## 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.
|
||||
## How to Deploy this Repo
|
||||
To use, just download and host the files on a HTTPS-enabled webserver. You may want to hide the .html extensions within your HTTP server as well, else the generated links will not work. See [here](https://github.com/steveseguin/vdoninja/blob/master/install.md) for added details and alternative install options.
|
||||
|
||||
## How to Deploy this Repo:
|
||||
To use, just download and host the files on a HTTPS-enabled webserver. You may want to hide the .html extensions within your HTTP server as well, else the generated links will not work. See [here](https://github.com/steveseguin/obsninja/blob/master/install.md) for added details and alternative install options.
|
||||
Directions on how to deploy a TURN server are listed in the turnserver.md file. You may wish to do so, although not all use cases will not need one. Only about 10% of remote guests, those often connected via 4G LTE, will require a TURN server. While VDO.Ninja does host some TURN servers, they are quite expensive to operate and not really for private deployment use. If you are deploying your own version of VDO.Ninja, I'd ask you use your own TURN servers instead.
|
||||
|
||||
Directions on how to deploy a TURN server are listed in the turnserver.md file. You may wish to do so, although not all use cases will not need one. Only about 10% of remote guests, those often connected via 4G LTE, will require a TURN server. While OBS.Ninja does host some TURN servers, they are quite expensive to operate and not really for private deployment use. If you are deploying your own version of OBS.Ninja, I'd ask you use your own TURN servers instead.
|
||||
## Server side / API software
|
||||
Since VDO.Ninja uses peer-2-peer technology, video connections are made directly between viewer and publisher in 90% of cases. Hosting a TURN server yourself may help improve performance, but less than 1% of users will see any benefit of this. Details on how to deploy a TURN server are provided. For those capable of hosting their own TURN server, that would be appreciated if possible, as TURN servers are the only real cost incurred by VDO.Ninja at present. (other than time, of course)
|
||||
|
||||
## Server side / API software?
|
||||
Since OBS.Ninja uses peer-2-peer technology, video connections are made directly between viewer and publisher in 90% of cases. Hosting a TURN server yourself may help improve performance, but less than 1% of users will see any benefit of this. Details on how to deploy a TURN server are provided. For those capable of hosting their own TURN server, that would be appreciated if possible, as TURN servers are the only real cost incurred by OBS.Ninja at present. (other than time, of course)
|
||||
Other than TURN servers, VDO.Ninja also uses public STUN servers and a hosted handshake server. These are used to facilitate the initial setup of peer connections and are generally not required after a peer connection is established. These servers are free to access and use, even for private deployments. As of Version 17.3 of VDO.Ninja, you can host your own handshake server or use a third-party managed one (such as piesocket.com); please see details here: https://github.com/steveseguin/websocket_server
|
||||
|
||||
Other than TURN servers, OBS.Ninja also uses public STUN servers and a hosted handshake server. These are used to facilitate the initial setup of peer connections and are generally not required after a peer connection is established. These servers are free to access and use, even for private deployments.
|
||||
Development builds of VDO.Ninja may include debugging software, but in-production releases have this removed. Double check to ensure "console.re" debugging is disabled before deployment, just to be safe.
|
||||
|
||||
Development builds of OBS.Ninja may include debugging software, but in-production releases have this removed. Double check to ensure "console.re" debugging is disabled before deployment, just to be safe.
|
||||
|
||||
A design goal of OBS.Ninja is to be serverless and we are 99% of the way there. This design objective ensures OBS.Ninja can be offered for free, along with providing increased levels of security and privacy.
|
||||
A design goal of VDO.Ninja is to be serverless and we are 99% of the way there. This design objective ensures VDO.Ninja can be offered for free, along with providing increased levels of security and privacy.
|
||||
|
||||
## Issues? problems? Not working?
|
||||
|
||||
Please see the sub-reddit for more support: https://reddit.com/r/obsninja
|
||||
Please see the sub-reddit for more support: https://reddit.com/r/vdoninja
|
||||
|
||||
Also check out the FAQ for common answers: https://github.com/steveseguin/obsninja/wiki
|
||||
Also check out the FAQ for common answers: https://github.com/steveseguin/vdoninja/wiki
|
||||
|
||||
If urgent, join me on discord: https://discord.gg/EksyhGA or email me at steve@seguin.email
|
||||
|
||||
## Related Projects
|
||||
#### OBS.Ninja's Electron Capture:
|
||||
A better way to perform "Window Capturing" on desktop if OBS Browser Sources fails you. A downloadable tool designed to enhance OBS.Ninja.
|
||||
### VDO.Ninja's Electron Capture:
|
||||
A better way to perform "Window Capturing" on desktop if OBS Browser Sources fails you. A downloadable tool designed to enhance VDO.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
|
||||
### 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 or VMix 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.
|
||||
### Chat.Overlay.Ninja
|
||||
A free Chrome extension that lets you select Youtube Live Chat comments, with those comments then appearing directly in OBS or VMix as an overlay. No chroma-keying needed and the styling is pretty easy to customize without needing to modify the Chrome extension itself.
|
||||
http://chat.overlay.ninja/
|
||||
|
||||
### Steves.app:
|
||||
A website designed to also work with VDO.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/
|
||||
|
||||
#### StageTEN.tv
|
||||
A browser-based studio solution and simplified alternative to OBS, with built-in OBS.Ninja functionality. It is a server-based approach to group interactions and live production. Steve Seguin is affiliated with StageTEn, yet StageTEN is not affiliated with OBS.Ninja.
|
||||
|
||||
## Privacy
|
||||
I try to avoid data collection whenever possible and video streams are generally designed to be private, but use at your own risk. It is best to not share links created with OBS.Ninja with those you do not trust. I've provided instructions on how to deploy a TURN server if IP-address privacy is an issue for you. See: turnserver.md
|
||||
I try to avoid data collection whenever possible and video streams are generally designed to be private, but use at your own risk. It is best to not share links created with VDO.Ninja with those you do not trust. I've provided instructions on how to deploy a TURN server if IP-address privacy is an issue for you. See: [turnserver.md](turnserver.md)
|
||||
|
||||
https://obs.ninja may unavoidably use cookies that are exempt from EU laws of requiring notice of their use; they are exempt as they are required and necessary for the technical functioning of the web service. Our webserver is cached by Cloudflare and it provides denial of server protection for the users of OBS.Ninja.
|
||||
https://vdo.ninja may unavoidably use cookies that are exempt from EU laws of requiring notice of their use; they are exempt as they are required and necessary for the technical functioning of the web service. Our webserver is cached by Cloudflare and it provides denial of server protection for the users of VDO.Ninja.
|
||||
|
||||
Additional security features are being added weekly on request. Please ask about these options if added security and privacy are requirements for you.
|
||||
|
||||
@@ -73,4 +80,4 @@ Additional security features are being added weekly on request. Please ask about
|
||||
Ideas, feedback, bugs, etc -- all welcomed. I'm dumping many of my ideas as issues into Github. Feedback is typically most welcomed via Email or Discord.
|
||||
|
||||
## Licence
|
||||
OBS.Ninja is available as open-source; please see the LICENCE.md file for details.
|
||||
VDO.Ninja is available as 'mostly' open-source; please see the LICENCE.md file for details.
|
||||
|
||||
159
chat.html
Normal file
@@ -0,0 +1,159 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>OBSN Chat Overlay</title>
|
||||
<style>
|
||||
|
||||
@font-face {
|
||||
font-family: 'Cousine';
|
||||
src: url('fonts/Cousine-Bold.ttf') format('truetype');
|
||||
}
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
padding:0 10px;
|
||||
height:100%;
|
||||
border: 0;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
position:absolute;
|
||||
bottom:0;
|
||||
overflow:hidden;
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
div {
|
||||
margin:0;
|
||||
background-color: black;
|
||||
padding: 8px 8px 0px 8px;
|
||||
color: white;
|
||||
font-family: Cousine, monospace;
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1em;
|
||||
letter-spacing: 0.0em;
|
||||
text-transform: uppercase;
|
||||
text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1);
|
||||
max-width:100%;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-all;
|
||||
hyphens: auto;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
|
||||
|
||||
a {
|
||||
color:white;
|
||||
font-size:1.2em;
|
||||
text-transform: none;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
hyphens: auto;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
|
||||
(function (w) {
|
||||
w.URLSearchParams =
|
||||
w.URLSearchParams ||
|
||||
function (searchString) {
|
||||
var self = this;
|
||||
self.searchString = searchString;
|
||||
self.get = function (name) {
|
||||
var results = new RegExp("[\?&]" + name + "=([^&#]*)").exec(
|
||||
self.searchString
|
||||
);
|
||||
if (results == null) {
|
||||
return null;
|
||||
} else {
|
||||
return decodeURI(results[1]) || 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
})(window);
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
|
||||
function loadIframe() {
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
|
||||
var view= "";
|
||||
if (urlParams.has("view")) {
|
||||
view = "&view="+(urlParams.get("view") || "");
|
||||
}
|
||||
var room="";
|
||||
if (urlParams.has("room")) {
|
||||
room = "&room="+urlParams.get("room");
|
||||
}
|
||||
|
||||
var password="";
|
||||
if (urlParams.has("password")) {
|
||||
password = "&password="+urlParams.get("password");
|
||||
}
|
||||
|
||||
iframe.allow = "autoplay";
|
||||
var srcString = "./?novideo&noaudio&label=chatOverlay&scene"+room+view+password;
|
||||
|
||||
iframe.src = srcString;
|
||||
iframe.style.width="0";
|
||||
iframe.style.height="0";
|
||||
iframe.style.border="0";
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
//////////// LISTEN FOR EVENTS
|
||||
|
||||
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
||||
var eventer = window[eventMethod];
|
||||
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
|
||||
|
||||
|
||||
/// If you have a routing system setup, you could have just one global listener for all iframes instead.
|
||||
|
||||
eventer(messageEvent, function (e) {
|
||||
if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
|
||||
|
||||
console.log(e);
|
||||
if ("gotChat" in e.data){
|
||||
logData(e.data.gotChat.label,e.data.gotChat.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function printValues(obj) {
|
||||
var out = "";
|
||||
for (var key in obj) {
|
||||
if (typeof obj[key] === "object") {
|
||||
out += "<br />";
|
||||
out += printValues(obj[key]);
|
||||
} else {
|
||||
if (key.startsWith("_")) {
|
||||
} else {
|
||||
out += "<b>" + key + "</b>: " + obj[key] + "<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function logData(type, data) {
|
||||
var span = document.createElement('span');
|
||||
var entry = document.createElement('div');
|
||||
if (type){
|
||||
type = "<i>"+type.replace(/_/g, ' ')+"</i>";
|
||||
}
|
||||
entry.innerHTML = type + data;
|
||||
span.appendChild(entry);
|
||||
document.body.prepend(span);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="loadIframe();">
|
||||
</body>
|
||||
</html>
|
||||
381
convert.html
@@ -1,157 +1,230 @@
|
||||
<head>
|
||||
<link rel="stylesheet" href="./main.css?ver=39" />
|
||||
<style>
|
||||
|
||||
body {
|
||||
|
||||
}
|
||||
|
||||
input {padding:10px;}
|
||||
|
||||
h3 { margin-top:10px; padding:5px;}
|
||||
|
||||
hr {
|
||||
margin: 20px 0;
|
||||
}
|
||||
video{
|
||||
max-width:640px;
|
||||
max-height:360px;
|
||||
padding:20px;
|
||||
}
|
||||
audio{
|
||||
max-width:640px;
|
||||
max-height:360px;
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body style='color:white'>
|
||||
|
||||
<video id="player" controls style="display:none"></video>
|
||||
<audio id="player2" controls style="display:none"></audio>
|
||||
<div id="info">
|
||||
<h1>Web-based Media Conversion Tools</h1>
|
||||
<hr>
|
||||
<h3>Transcodes WebM files to MP4 files with a fixed 1280x720 resolution. (very slow!)</h3><br />
|
||||
<small><p>This tool performs the following action in your browser: <i> fmpeg -i input.webm -vf scale=1280:720 output.mp4</i></p></small>
|
||||
<input type="file" id="uploader" title="Convert WebM to MP4">
|
||||
|
||||
<hr>
|
||||
<h3>Remuxes MKV files to MP4 files without transcoding.</h3> </p><br /><small><i> fmpeg -i INPUTFILE -vcodec copy -acodec copy output.mp4</i></small>
|
||||
<br /><input type="file" id="uploader2" accept=".mkv" title="Convert MKV to MP4">
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Remuxes WebM files to MP4 files without transcoding (attempts to force high resolutions, also)</h3>
|
||||
<input type="file" id="uploader3" accept=".webm" title="Convert WebM to MP4">
|
||||
|
||||
<hr>
|
||||
<h3>Remuxes WebM to Audio-only files (opus or wav)</h3>
|
||||
<input type="file" id="uploader4" accept=".webm" title="Convert WebM to OPUS">
|
||||
|
||||
<hr>
|
||||
|
||||
</div>
|
||||
<script src="https://unpkg.com/@ffmpeg/ffmpeg@0.9.6/dist/ffmpeg.min.js"></script>
|
||||
<script>
|
||||
|
||||
function download(data, filename) {
|
||||
const blob = new Blob([data.buffer]);
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
const { createFFmpeg, fetchFile } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
const transcode = async ({ target: { files } }) => {
|
||||
const { name } = files[0];
|
||||
document.getElementById('uploader').style.display="none";
|
||||
document.getElementById('uploader2').style.display="none";
|
||||
document.getElementById('uploader3').style.display="none";
|
||||
document.getElementById('info').innerText = "Transcoding file... this will take a while";
|
||||
await ffmpeg.load();
|
||||
ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
|
||||
await ffmpeg.run('-i', name, '-vf', 'scale=1280:720', 'output.mp4');
|
||||
const data = ffmpeg.FS('readFile', 'output.mp4');
|
||||
const video = document.getElementById('player');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
video.style.display="block";
|
||||
document.getElementById('info').innerText = "Operation Done. Play video or download it.";
|
||||
}
|
||||
const transmux = async ({ target: { files } }) => {
|
||||
const { name } = files[0];
|
||||
document.getElementById('uploader').style.display="none";
|
||||
document.getElementById('uploader2').style.display="none";
|
||||
document.getElementById('uploader3').style.display="none";
|
||||
document.getElementById('info').innerText = "Transcoding file... this will take a while";
|
||||
await ffmpeg.load();
|
||||
ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
|
||||
await ffmpeg.run('-i', name, '-vcodec', 'copy', '-acodec', 'copy', 'output.mp4');
|
||||
const data = ffmpeg.FS('readFile', 'output.mp4');
|
||||
const video = document.getElementById('player');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
|
||||
video.style.display="block";
|
||||
document.getElementById('info').innerText = "Operation Done. Play video or download it.";
|
||||
}
|
||||
|
||||
const force1080 = async ({ target: { files } }) => {
|
||||
const { name } = files[0];
|
||||
const sourceBuffer = await fetch("./media/cap.webm").then(r => r.arrayBuffer());
|
||||
document.getElementById('uploader').style.display="none";
|
||||
document.getElementById('uploader2').style.display="none";
|
||||
document.getElementById('uploader3').style.display="none";
|
||||
document.getElementById('info').innerText = "Tweaking file... this will take a moment";
|
||||
await ffmpeg.load();
|
||||
ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
|
||||
ffmpeg.FS("writeFile","cap.webm", new Uint8Array(sourceBuffer, 0, sourceBuffer.byteLength));
|
||||
|
||||
await ffmpeg.run("-i", "concat:cap.webm|"+name, "-safe", "0", "-c", "copy", "-avoid_negative_ts", "1", "-strict", "experimental", "output.mp4");
|
||||
const data = ffmpeg.FS('readFile', 'output.mp4');
|
||||
const video = document.getElementById('player');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
video.style.display="block";
|
||||
document.getElementById('info').innerText = "Operation Done. Play video or download it.";
|
||||
}
|
||||
|
||||
const convertToAudioOnly = async ({ target: { files } }) => {
|
||||
const { name } = files[0];
|
||||
document.getElementById('info').innerText = "Transcoding file... this will take a while";
|
||||
await ffmpeg.load();
|
||||
ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
|
||||
const video = document.getElementById('player');
|
||||
|
||||
await ffmpeg.run('-i', name, '-vn', '-acodec', 'copy', 'output.opus');
|
||||
const data = ffmpeg.FS('readFile', 'output.opus');
|
||||
|
||||
console.log(data.buffer.byteLength);
|
||||
if (data.buffer.byteLength){
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'audio/opus' }));
|
||||
download(data, name.split(".")[0]+".opus");
|
||||
} else {
|
||||
await ffmpeg.run('-i', name, '-vn', '-acodec', 'copy', 'output.wav');
|
||||
const data2 = ffmpeg.FS('readFile', 'output.wav');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'audio/pcm' }));
|
||||
download(data2, name.split(".")[0]+".wav");
|
||||
<link rel="stylesheet" href="./main.css?ver=39" />
|
||||
<style>
|
||||
.container {
|
||||
max-width: 80%;
|
||||
width: fit-content;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
video.style.display="block";
|
||||
document.getElementById('info').innerText = "Operation Done. Play audio or download it.";
|
||||
}
|
||||
|
||||
document.getElementById('uploader').addEventListener('change', transcode);
|
||||
document.getElementById('uploader2').addEventListener('change', transmux);
|
||||
document.getElementById('uploader3').addEventListener('change', force1080);
|
||||
document.getElementById('uploader4').addEventListener('change', convertToAudioOnly);
|
||||
</script>
|
||||
|
||||
h1 {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin: 10px;
|
||||
box-shadow: 0 4px 8px 0 rgb(0 0 0 / 10%);
|
||||
background-color: #ddd;
|
||||
color: black;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.card>div {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-size: 1.5em;
|
||||
padding: 10px;
|
||||
background-color: #457b9d;
|
||||
color: white;
|
||||
border-bottom: 2px solid #3b6a87;
|
||||
}
|
||||
|
||||
small {
|
||||
font-style: italic;
|
||||
display: block;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
span.warning {
|
||||
color: rgb(212, 191, 0);
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
video {
|
||||
max-width: 640px;
|
||||
max-height: 360px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
audio {
|
||||
max-width: 640px;
|
||||
max-height: 360px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
div#processing {
|
||||
display: none;
|
||||
justify-content: center;
|
||||
place-items: center;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
background: #141926;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style='color:white'>
|
||||
<div id="header">
|
||||
<a id="logoname" href="./" style="text-decoration: none; color: white; margin: 2px">
|
||||
<span data-translate="logo-header">
|
||||
<font id="qos">V</font>DO.Ninja
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div id="info">
|
||||
<h1>Web-based Media Conversion Tools</h1>
|
||||
|
||||
<div class="card">
|
||||
<h2>WebM to MP4 (fixed 1280x720 resolution) <span class='warning'>(very slow!)</span></h2>
|
||||
<div>
|
||||
<small>The same as: fmpeg -i input.webm -vf scale=1280:720 output.mp4</small>
|
||||
<input type="file" id="uploader" title="Convert WebM to MP4">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>MKV to MP4 (no transcoding)</h2>
|
||||
<div>
|
||||
<small>The same as: fmpeg -i INPUTFILE -vcodec copy -acodec copy output.mp4</small>
|
||||
<input type="file" id="uploader2" accept=".mkv" title="Convert MKV to MP4">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>WebM MP4 files (no transcoding, attempts to force high resolutions)</h2>
|
||||
<div>
|
||||
<input type="file" id="uploader3" accept=".webm" title="Convert WebM to MP4">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>WebM to Audio-only files (opus or wav)</h2>
|
||||
<div>
|
||||
<input type="file" id="uploader4" accept=".webm" title="Convert WebM to OPUS">
|
||||
</div>
|
||||
</div>
|
||||
<div id="processing">
|
||||
<span id="message"></span>
|
||||
<video id="player" controls style="display:none"></video>
|
||||
<audio id="player2" controls style="display:none"></audio>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/@ffmpeg/ffmpeg@0.9.6/dist/ffmpeg.min.js"></script>
|
||||
<script>
|
||||
|
||||
function download(data, filename) {
|
||||
const blob = new Blob([data.buffer]);
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
const { createFFmpeg, fetchFile } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
const transcode = async ({ target: { files } }) => {
|
||||
const { name } = files[0];
|
||||
document.getElementById('uploader').style.display = "none";
|
||||
document.getElementById('uploader2').style.display = "none";
|
||||
document.getElementById('uploader3').style.display = "none";
|
||||
document.getElementById('message').innerText = "Transcoding file... this will take a while";
|
||||
document.getElementById('processing').style.display = 'flex';
|
||||
await ffmpeg.load();
|
||||
ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
|
||||
await ffmpeg.run('-i', name, '-vf', 'scale=1280:720', 'output.mp4');
|
||||
const data = ffmpeg.FS('readFile', 'output.mp4');
|
||||
const video = document.getElementById('player');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
video.style.display = "block";
|
||||
document.getElementById('message').innerText = "Operation Done. Play video or download it.";
|
||||
}
|
||||
|
||||
const transmux = async ({ target: { files } }) => {
|
||||
const { name } = files[0];
|
||||
document.getElementById('uploader').style.display = "none";
|
||||
document.getElementById('uploader2').style.display = "none";
|
||||
document.getElementById('uploader3').style.display = "none";
|
||||
document.getElementById('message').innerText = "Transcoding file... this will take a while";
|
||||
document.getElementById('processing').style.display = 'flex';
|
||||
await ffmpeg.load();
|
||||
ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
|
||||
await ffmpeg.run('-i', name, '-vcodec', 'copy', '-acodec', 'copy', 'output.mp4');
|
||||
const data = ffmpeg.FS('readFile', 'output.mp4');
|
||||
const video = document.getElementById('player');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
|
||||
video.style.display = "block";
|
||||
document.getElementById('message').innerText = "Operation Done. Play video or download it.";
|
||||
}
|
||||
|
||||
const force1080 = async ({ target: { files } }) => {
|
||||
const { name } = files[0];
|
||||
const sourceBuffer = await fetch("./media/cap.webm").then(r => r.arrayBuffer());
|
||||
document.getElementById('uploader').style.display = "none";
|
||||
document.getElementById('uploader2').style.display = "none";
|
||||
document.getElementById('uploader3').style.display = "none";
|
||||
document.getElementById('message').innerText = "Tweaking file... this will take a moment";
|
||||
document.getElementById('processing').style.display = 'flex';
|
||||
await ffmpeg.load();
|
||||
ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
|
||||
ffmpeg.FS("writeFile", "cap.webm", new Uint8Array(sourceBuffer, 0, sourceBuffer.byteLength));
|
||||
|
||||
await ffmpeg.run("-i", "concat:cap.webm|" + name, "-safe", "0", "-c", "copy", "-avoid_negative_ts", "1", "-strict", "experimental", "output.mp4");
|
||||
const data = ffmpeg.FS('readFile', 'output.mp4');
|
||||
const video = document.getElementById('player');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
video.style.display = "block";
|
||||
document.getElementById('message').innerText = "Operation Done. Play video or download it.";
|
||||
document.getElementById('processing').style.display = 'flex';
|
||||
}
|
||||
|
||||
const convertToAudioOnly = async ({ target: { files } }) => {
|
||||
const { name } = files[0];
|
||||
document.getElementById('message').innerText = "Transcoding file... this will take a while";
|
||||
document.getElementById('processing').style.display = 'flex';
|
||||
await ffmpeg.load();
|
||||
ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
|
||||
const video = document.getElementById('player');
|
||||
|
||||
await ffmpeg.run('-i', name, '-vn', '-acodec', 'copy', 'output.opus');
|
||||
const data = ffmpeg.FS('readFile', 'output.opus');
|
||||
|
||||
console.log(data.buffer.byteLength);
|
||||
if (data.buffer.byteLength) {
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'audio/opus' }));
|
||||
download(data, name.split(".")[0] + ".opus");
|
||||
} else {
|
||||
await ffmpeg.run('-i', name, '-vn', '-acodec', 'copy', 'output.wav');
|
||||
const data2 = ffmpeg.FS('readFile', 'output.wav');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'audio/pcm' }));
|
||||
download(data2, name.split(".")[0] + ".wav");
|
||||
}
|
||||
|
||||
video.style.display = "block";
|
||||
document.getElementById('message').innerText = "Operation Done. Play audio or download it.";
|
||||
document.getElementById('processing').style.display = 'flex';
|
||||
}
|
||||
|
||||
document.getElementById('uploader').addEventListener('change', transcode);
|
||||
document.getElementById('uploader2').addEventListener('change', transmux);
|
||||
document.getElementById('uploader3').addEventListener('change', force1080);
|
||||
document.getElementById('uploader4').addEventListener('change', convertToAudioOnly);
|
||||
</script>
|
||||
</body>
|
||||
@@ -9,6 +9,7 @@ h1 {
|
||||
padding:10px;
|
||||
background-color:#457b9d;
|
||||
color:white;
|
||||
border-bottom: 2px solid #3b6a87;
|
||||
}
|
||||
|
||||
.device {
|
||||
@@ -18,6 +19,9 @@ h1 {
|
||||
font-size: 1rem;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
background: #d0d0d0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.device.selected {
|
||||
@@ -55,12 +59,13 @@ h1 {
|
||||
}
|
||||
|
||||
.notice {
|
||||
background-color: orange;
|
||||
background-color: #fff18c;
|
||||
margin: 10px;
|
||||
padding: 20px 20px;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.notice a {
|
||||
@@ -89,7 +94,7 @@ h1 {
|
||||
left: 10%;
|
||||
color: white;
|
||||
overflow-wrap: anywhere;
|
||||
background: #141926;
|
||||
background: #2c3754;
|
||||
padding: 20px;
|
||||
box-shadow: 0px 0px 10px 5px #00000047;
|
||||
border: 1px solid #333c52;
|
||||
|
||||
135
devices.html
@@ -22,7 +22,8 @@
|
||||
<div class="notice">
|
||||
Device IDs are bound to a combination of domain and browser. <br />If
|
||||
you want to use electron-capture, open this URL on the electron-capture
|
||||
app.
|
||||
app. <br/>
|
||||
Click device names to preset them. Select multiple audio inputs by clicking multiple devices.
|
||||
</div>
|
||||
<div class="notice">
|
||||
Check for browser and camera capabilities <a href="/supports">here</a>.
|
||||
@@ -41,51 +42,56 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="sharedDevices" style="display: none">
|
||||
<span>Click to copy. Send this to your host:</span>
|
||||
<span>Click to copy. Use this URL to preset audio/video devices.</span>
|
||||
<span id="close" onclick="this.parentNode.style.display='none'">×</span>
|
||||
<input id="devicesUrl" value="" />
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var list = [];
|
||||
var url = new URL(document.location.origin);
|
||||
var audioInputDevices = [];
|
||||
const list = [];
|
||||
const url = new URL(document.location.origin);
|
||||
const audioInputDevices = [];
|
||||
|
||||
function isAudioInput(value) {
|
||||
return value.kind == "audioinput";
|
||||
return value.kind === "audioinput";
|
||||
}
|
||||
|
||||
function isAudioOutput(value) {
|
||||
return value.kind == "audiooutput";
|
||||
return value.kind === "audiooutput";
|
||||
}
|
||||
|
||||
function isVideoInput(value) {
|
||||
return value.kind == "videoinput";
|
||||
return value.kind === "videoinput";
|
||||
}
|
||||
|
||||
function sanitizeDeviceName(deviceName) {
|
||||
return String(deviceName).toLowerCase().replace(/[\W]+/g, "_");
|
||||
}
|
||||
|
||||
function addDevice(element) {
|
||||
var info = element.getElementsByClassName("device-id")[0];
|
||||
var type = info.dataset.deviceType;
|
||||
const type = element.dataset.deviceType;
|
||||
const device = sanitizeDeviceName(element.querySelector('span').innerText);
|
||||
|
||||
if (type == "audioinput") {
|
||||
setAudioSearchParams(info);
|
||||
if (type === "audioinput") {
|
||||
setAudioSearchParams(element);
|
||||
}
|
||||
if (type == "videoinput") {
|
||||
setVideoSearchParams(info);
|
||||
if (type === "videoinput") {
|
||||
setVideoSearchParams(element);
|
||||
}
|
||||
if (type == "audiooutput") {
|
||||
return;
|
||||
if (type === "audiooutput") {
|
||||
setAudioOutputSearchParams(element);
|
||||
}
|
||||
|
||||
/*
|
||||
Allows for multiple audio devices to be selected
|
||||
Will be output as a comma separated string to &ad
|
||||
Allows for multiple audio devices to be selected
|
||||
Will be output as a comma separated string to &ad
|
||||
*/
|
||||
|
||||
function setAudioSearchParams(info) {
|
||||
// Device was already selected
|
||||
if (info.parentNode.className == "device selected") {
|
||||
if (info.className === "device selected") {
|
||||
// Remove device from list of selected devices
|
||||
var index = audioInputDevices.indexOf(info.innerText);
|
||||
const index = audioInputDevices.indexOf(device);
|
||||
if (index !== -1) {
|
||||
audioInputDevices.splice(index, 1);
|
||||
}
|
||||
@@ -95,12 +101,13 @@
|
||||
element.className = "device";
|
||||
|
||||
// If no audio devices remained, just remove the param completely
|
||||
if (audioInputDevices.length == 0) {
|
||||
if (audioInputDevices.length === 0) {
|
||||
url.searchParams.delete("ad");
|
||||
}
|
||||
} else {
|
||||
// Device is unselected
|
||||
audioInputDevices.push(info.innerText);
|
||||
|
||||
audioInputDevices.push(device);
|
||||
url.searchParams.set("ad", audioInputDevices.join(","));
|
||||
element.className = "device selected";
|
||||
}
|
||||
@@ -111,20 +118,57 @@
|
||||
*/
|
||||
function setVideoSearchParams(info) {
|
||||
// Device was already selected
|
||||
if (info.parentNode.className == "device selected") {
|
||||
info.parentNode.className = "device";
|
||||
if (info.className === "device selected") {
|
||||
element.className = "device";
|
||||
|
||||
|
||||
// Set the url param to the devices that are left
|
||||
url.searchParams.set("vd", info.innerText);
|
||||
url.searchParams.set("vd", device);
|
||||
element.className = "device";
|
||||
|
||||
// If no devices remained, just remove the param completely
|
||||
if (audioInputDevices.length == 0) {
|
||||
if (audioInputDevices.length === 0) {
|
||||
url.searchParams.delete("vd");
|
||||
}
|
||||
} else {
|
||||
// Device is unselected
|
||||
url.searchParams.set("vd", info.innerText);
|
||||
try {
|
||||
element.parentElement.querySelector('.device.selected').className = "device";
|
||||
} catch (error) {
|
||||
console.log("There was no video device already selected.");
|
||||
}
|
||||
|
||||
url.searchParams.set("vd", device);
|
||||
element.className = "device selected";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Only allows for a single audio output device to be selected
|
||||
*/
|
||||
function setAudioOutputSearchParams(info) {
|
||||
// Device was already selected
|
||||
if (info.className === "device selected") {
|
||||
element.className = "device";
|
||||
|
||||
|
||||
// Set the url param to the devices that are left
|
||||
url.searchParams.set("od", device);
|
||||
element.className = "device";
|
||||
|
||||
// If no devices remained, just remove the param completely
|
||||
if (audioInputDevices.length === 0) {
|
||||
url.searchParams.delete("od");
|
||||
}
|
||||
} else {
|
||||
// Device is unselected
|
||||
try {
|
||||
element.parentElement.querySelector('.device.selected').className = "device";
|
||||
} catch (error) {
|
||||
console.log("There was no video device already selected.");
|
||||
}
|
||||
|
||||
url.searchParams.set("od", device);
|
||||
element.className = "device selected";
|
||||
}
|
||||
}
|
||||
@@ -139,40 +183,35 @@
|
||||
}
|
||||
|
||||
function prettyPrint(json, element) {
|
||||
var output = "<div class='prettyJson two-col'>";
|
||||
var nestedObjs;
|
||||
let output = "<div class='prettyJson two-col'>";
|
||||
let nestedObjs;
|
||||
|
||||
Object.entries(json)
|
||||
.sort()
|
||||
.forEach(([key, value]) => {
|
||||
output += "<div class='device' onclick='addDevice(this)'>";
|
||||
|
||||
output +=
|
||||
"<span class='device-name'>" +
|
||||
value.label +
|
||||
"</span><span class='device-id' data-device-type='" +
|
||||
value.kind +
|
||||
"'>" +
|
||||
value.deviceId +
|
||||
"</span>";
|
||||
|
||||
output += "</div>";
|
||||
output += `
|
||||
<div class='device' onclick='addDevice(this)' data-device-type='${value.kind}'>
|
||||
<span class='device-name'>${value.label}</span>
|
||||
<span class='device-id'>
|
||||
${value.deviceId}
|
||||
</span>
|
||||
</div>`;
|
||||
});
|
||||
output += "</div>";
|
||||
document.getElementById(element).innerHTML = output;
|
||||
}
|
||||
|
||||
document.getElementById("devicesUrl").onclick = function () {
|
||||
this.select();
|
||||
document.getElementById("devicesUrl").onclick = (e) => {
|
||||
e.target.select();
|
||||
document.execCommand("copy");
|
||||
};
|
||||
|
||||
navigator.mediaDevices
|
||||
.enumerateDevices()
|
||||
.then(function (devices) {
|
||||
devices.forEach(function (device) {
|
||||
.then((devices) => {
|
||||
devices.forEach((device) => {
|
||||
console.log(
|
||||
device.kind + ": " + device.label + " id = " + device.deviceId
|
||||
`${device.kind}: ${device.label} id = ${device.deviceId}`
|
||||
);
|
||||
list.push(device);
|
||||
});
|
||||
@@ -180,8 +219,8 @@
|
||||
prettyPrint(devices.filter(isAudioOutput), "audioOutputs");
|
||||
prettyPrint(devices.filter(isVideoInput), "videoInputs");
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.log(err.name + ": " + err.message);
|
||||
.catch((err) => {
|
||||
console.log(`${err.name}: ${err.message}`);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
962
electron.html
@@ -1,390 +1,572 @@
|
||||
<html>
|
||||
<meta charset="UTF-8">
|
||||
<head><style>
|
||||
html {
|
||||
border:0;
|
||||
margin:0;
|
||||
outline:0;
|
||||
|
||||
}
|
||||
|
||||
video {
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=), none;
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
body {
|
||||
padding: 0 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #141926;
|
||||
background-color: -webkit-linear-gradient(to top, #181925, #141826, #0F2027); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background-color: linear-gradient(to top, #181825, #141926, #0F2027); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
|
||||
font-size: 2em;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
border:0;
|
||||
margin:0;
|
||||
outline:0;
|
||||
}
|
||||
|
||||
button.glyphicon-button:focus,
|
||||
button.glyphicon-button:active:focus,
|
||||
button.glyphicon-button.active:focus,
|
||||
button.glyphicon-button.focus,
|
||||
button.glyphicon-button:active.focus,
|
||||
button.glyphicon-button.active.focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
button{
|
||||
padding:10px;
|
||||
font-size: 20px;
|
||||
margin: auto auto;
|
||||
}
|
||||
#header{
|
||||
height:80px;
|
||||
width:100%;
|
||||
background-color: #101520;
|
||||
}
|
||||
.inputfield{
|
||||
font-size: 20px;
|
||||
align-self:center;
|
||||
height:30px;
|
||||
width:780px;
|
||||
margin: auto auto;
|
||||
padding:20px
|
||||
}
|
||||
|
||||
.formcss{
|
||||
font-size: 20px;
|
||||
align-self:center;
|
||||
margin: auto auto;
|
||||
}
|
||||
label {
|
||||
font: white;
|
||||
font-size: 1em;
|
||||
color: white;
|
||||
}
|
||||
input[type='checkbox'] {
|
||||
-webkit-appearance:none;
|
||||
width:30px;
|
||||
height:30px;
|
||||
background:white;
|
||||
border-radius:5px;
|
||||
border:2px solid #555;
|
||||
cursor: pointer;
|
||||
}
|
||||
input[type='checkbox']:checked {
|
||||
background: #1A1;
|
||||
}
|
||||
#audioOutput{
|
||||
font-size: calc(16px + 0.3vw);
|
||||
max-width:590px
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1030px) {
|
||||
body{
|
||||
zoom: 0.9;
|
||||
-moz-transform: scale(0.9);
|
||||
-moz-transform-origin: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 940px) {
|
||||
body{
|
||||
zoom: 0.64;
|
||||
-moz-transform: scale(0.64);
|
||||
-moz-transform-origin: 0 0;
|
||||
|
||||
}
|
||||
#audioOutput{
|
||||
font-size: calc(14px + 1.4vw);
|
||||
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:800px; padding:10px; margin:0 90px 20px 90px;color:white;font-size:1.3em"> ✨ Great News! OBS v26.1.2 <a href="https://github.com/obsproject/obs-browser/issues/209#issuecomment-748683083">now supports</a> OBS.Ninja without needing the Electron Capture app! 🥳</div>
|
||||
|
||||
<input type="checkbox" class="check" id="prefervp9" name="prefervp9" value="false" onclick="modURL(this);">
|
||||
<label for="prefervp9">Force VP9 Codec</label>
|
||||
|
||||
<input type="checkbox" class="check" id="showcursor" name="showcursor" value="false" onclick="modURL(this);">
|
||||
<label for="showcursor">Show Mouse Cursor</label>
|
||||
|
||||
<input type="checkbox" class="check" id="highbitrate" name="highbitrate" value="false" onclick="modURL(this);">
|
||||
<label for="highbitrate">High Video Bitrate</label>
|
||||
|
||||
<input type="checkbox" class="check" id="stereo" name="stereo" value="false" onclick="modURL(this);">
|
||||
<label for="stereo">Pro Audio Mode</label>
|
||||
|
||||
<input type="checkbox" class="check" id="buffer" name="buffer" value="false" onclick="modURL(this);">
|
||||
<label for="buffer">Lip-sync Fix</label>
|
||||
|
||||
<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>
|
||||
<br><br>
|
||||
<label for="audioOutput">Audio output destination: </label><select id="audioOutput"></select>
|
||||
|
||||
</center></div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
/*
|
||||
* Copyright (c) 2020 Steve Seguin. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by the APGLv3 open-source license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. Alternative licencing options can be made available on request.
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
audioOutputSelect.onchange = updateOutputTarget;
|
||||
var listed = false;
|
||||
|
||||
function updateOutputTarget(e){
|
||||
console.log("change audio: "+audioOutputSelect.value);
|
||||
var url = document.getElementById('changeText').value;
|
||||
url=updateURLParameter(url, "sink", audioOutputSelect.value);
|
||||
document.getElementById('changeText').value = url;
|
||||
}
|
||||
|
||||
function getPermssions(e=null){
|
||||
if (listed==true){
|
||||
return;
|
||||
}
|
||||
if (e!==null){
|
||||
e.currentTarget.blur();
|
||||
}
|
||||
navigator.mediaDevices.getUserMedia({audio: true,video: false}).then((stream)=>{
|
||||
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(console.error); // list all devices
|
||||
stream.getTracks().forEach(track => {
|
||||
track.stop();
|
||||
});
|
||||
listed=true;
|
||||
audioOutputSelect.focus();
|
||||
|
||||
}).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) {
|
||||
for (let i = 0; i !== deviceInfos.length; ++i) {
|
||||
const deviceInfo = deviceInfos[i];
|
||||
const option = document.createElement('option');
|
||||
option.value = deviceInfo.deviceId;
|
||||
if (deviceInfo.kind === 'audiooutput'){
|
||||
option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`;
|
||||
audioOutputSelect.appendChild(option);
|
||||
} else {
|
||||
console.log('Some other kind of source/device: ', deviceInfo);
|
||||
}
|
||||
}
|
||||
listed=true;
|
||||
}
|
||||
|
||||
function enterPressed(event, callback){
|
||||
if (event.keyCode === 13){ // Number 13 is the "Enter" key on the keyboard
|
||||
event.preventDefault(); // Cancel the default action, if needed
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
(function (w) {
|
||||
w.URLSearchParams = w.URLSearchParams || function (searchString) {
|
||||
var self = this;
|
||||
self.searchString = searchString;
|
||||
self.get = function (name) {
|
||||
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString);
|
||||
if (results == null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return decodeURI(results[1]) || 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
})(window)
|
||||
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
var isMobile = false;
|
||||
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){ // does not detect iPad Pros.
|
||||
isMobile=true; // if iOS, default to H264? meh. let's not.
|
||||
}
|
||||
// Windows can show the cursor, since it captures in a different way.
|
||||
if (navigator.platform.indexOf("Win") != -1){
|
||||
document.getElementById("showcursor").checked=true;
|
||||
}
|
||||
|
||||
function updateURLParameter(url, param, paramVal){
|
||||
var TheAnchor = null;
|
||||
var newAdditionalURL = "";
|
||||
var tempArray = url.split("?");
|
||||
var baseURL = tempArray[0];
|
||||
var additionalURL = tempArray[1];
|
||||
var temp = "";
|
||||
|
||||
if (additionalURL){
|
||||
var tmpAnchor = additionalURL.split("#");
|
||||
var TheParams = tmpAnchor[0];
|
||||
TheAnchor = tmpAnchor[1];
|
||||
if (TheAnchor){additionalURL = TheParams;}
|
||||
|
||||
tempArray = additionalURL.split("&");
|
||||
|
||||
for (var i=0; i<tempArray.length; i++){
|
||||
if(tempArray[i].split('=')[0] != param){
|
||||
newAdditionalURL += temp + tempArray[i];
|
||||
temp = "&";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var tmpAnchor = baseURL.split("#");
|
||||
var TheParams = tmpAnchor[0];
|
||||
TheAnchor = tmpAnchor[1];
|
||||
|
||||
if(TheParams){baseURL = TheParams;}
|
||||
}
|
||||
|
||||
if (paramVal===false){
|
||||
temp="";
|
||||
if(TheAnchor){temp += "#" + TheAnchor;}
|
||||
var rows_txt = temp
|
||||
} else if (paramVal===""){
|
||||
if(TheAnchor){paramVal += "#" + TheAnchor;}
|
||||
var rows_txt = temp + "" + param;
|
||||
} else {
|
||||
if(TheAnchor){paramVal += "#" + TheAnchor;}
|
||||
var rows_txt = temp + "" + param + "=" + paramVal;
|
||||
}
|
||||
return baseURL + "?" + newAdditionalURL + rows_txt;
|
||||
}
|
||||
|
||||
if (urlParams.has('name')){
|
||||
var name = urlParams.get('name');
|
||||
if (name!="OBSNinja"){
|
||||
document.getElementById('changeText').value = "https://obs.ninja/?view="+name;
|
||||
}
|
||||
}
|
||||
|
||||
function modURL(ele=false){
|
||||
var url = document.getElementById('changeText').value;
|
||||
console.log(url);
|
||||
if ((url.split("view").length>0) || (url.split("room").length>0)){
|
||||
if (!document.getElementById("showcursor").checked){
|
||||
url=updateURLParameter(url, "nocursor", "");
|
||||
} else {
|
||||
url=updateURLParameter(url, "nocursor", false);
|
||||
}
|
||||
|
||||
if (ele!=false){
|
||||
if (ele.id =="prefervp9"){
|
||||
if (document.getElementById("prefervp9").checked){
|
||||
url=updateURLParameter(url, "codec", "vp9");
|
||||
} else {
|
||||
url=updateURLParameter(url, "codec", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (ele.id =="highbitrate"){
|
||||
if (document.getElementById("highbitrate").checked){
|
||||
url=updateURLParameter(url, "bitrate", "10000");
|
||||
} else {
|
||||
url=updateURLParameter(url, "bitrate", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (ele.id =="stereo"){
|
||||
if (document.getElementById("stereo").checked){
|
||||
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, "proaudio", false);
|
||||
setTimeout(function(){document.getElementById("messageDiv").style.opacity="0";},0);
|
||||
}
|
||||
}
|
||||
|
||||
if (ele.id =="buffer"){
|
||||
if (document.getElementById("buffer").checked){
|
||||
url=updateURLParameter(url, "buffer", "");
|
||||
} else {
|
||||
url=updateURLParameter(url, "buffer", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
document.getElementById('changeText').value = url;
|
||||
console.log(url);
|
||||
return url;
|
||||
}
|
||||
function gohere(){
|
||||
var url = modURL(true);
|
||||
window.location = url;
|
||||
};
|
||||
getPermssions();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css" />
|
||||
<style>
|
||||
html {
|
||||
border:0;
|
||||
margin:0;
|
||||
outline:0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
video {
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=), none;
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
body {
|
||||
padding: 0 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: -webkit-linear-gradient(to top, #363644, 50%, #151b29); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(to top, #363644, 50%, #151b29); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
font-size: 2em;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
border:0;
|
||||
margin:0;
|
||||
outline:0;
|
||||
}
|
||||
|
||||
button.glyphicon-button:focus,
|
||||
button.glyphicon-button:active:focus,
|
||||
button.glyphicon-button.active:focus,
|
||||
button.glyphicon-button.focus,
|
||||
button.glyphicon-button:active.focus,
|
||||
button.glyphicon-button.active.focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
#gobutton {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
background: #6aab23;
|
||||
display: flex;
|
||||
border-radius: 0px;
|
||||
border-top-right-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
box-shadow: 0 12px 15px -10px #5ca70b, 0 2px 0px #6aab23;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
padding: 0 1em;
|
||||
}
|
||||
#header{
|
||||
width:100%;
|
||||
background-color: #101520;
|
||||
}
|
||||
input#changeText {
|
||||
font-size: 1em;
|
||||
align-self: center;
|
||||
width: 100%;
|
||||
padding: 1em;
|
||||
font-weight: bold;
|
||||
background: white;
|
||||
border: 4px solid white;
|
||||
box-shadow: 0px 30px 40px -32px #6aab23, 0 2px 0px #6aab23;
|
||||
border-top-left-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
transition: all 0.2s linear;
|
||||
box-sizing: border-box;
|
||||
border-bottom-right-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
input#changeText:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.container{
|
||||
font-size: 20px;
|
||||
align-self:center;
|
||||
margin: auto auto;
|
||||
}
|
||||
label {
|
||||
font: white;
|
||||
font-size: 1em;
|
||||
color: white;
|
||||
}
|
||||
input[type='checkbox'] {
|
||||
-webkit-appearance:none;
|
||||
width:30px;
|
||||
height:30px;
|
||||
background:white;
|
||||
border-radius:5px;
|
||||
border:2px solid #555;
|
||||
cursor: pointer;
|
||||
}
|
||||
input[type='checkbox']:checked {
|
||||
background: #1A1;
|
||||
}
|
||||
#audioOutput, #lastUrls {
|
||||
font-size: calc(16px + 0.3vw);
|
||||
width: 730px;
|
||||
height: 100%;
|
||||
flex: 20;
|
||||
border-radius: 10px;
|
||||
padding: 1em;
|
||||
background: #eaeaea;
|
||||
cursor:pointer;
|
||||
}
|
||||
label[for="audioOutput"] {
|
||||
font-size: 3em;
|
||||
color: #FE53BB;
|
||||
text-shadow: 0px 0px 30px #fe53bb;
|
||||
padding-right: 10px;
|
||||
}
|
||||
label[for="changeText"] {
|
||||
font-size: 3em;
|
||||
color: #00F6FF;
|
||||
text-shadow: 0px 0px 30px #00f6ff;
|
||||
padding-top: 5px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
label[for="lastUrls"] {
|
||||
font-size: 3em;
|
||||
color: #1a1;
|
||||
text-shadow: 0px 0px 30px #1a1;
|
||||
padding-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div#audioOutputContainer, #history {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
margin: 4em;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1030px) {
|
||||
body{
|
||||
zoom: 0.9;
|
||||
-moz-transform: scale(0.9);
|
||||
-moz-transform-origin: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#messageDiv {
|
||||
font-size: .7em;
|
||||
color: #DDD;
|
||||
transition: all 0.5s linear;
|
||||
font-style: italic;
|
||||
opacity: 0;
|
||||
text-align: center;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
div#urlInput {
|
||||
margin: 4em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
@media only screen and (max-width: 940px) {
|
||||
body{
|
||||
zoom: 0.74;
|
||||
-moz-transform: scale(0.74);
|
||||
-moz-transform-origin: 0 0;
|
||||
|
||||
}
|
||||
.container{
|
||||
max-width:99%;
|
||||
}
|
||||
div#urlInput {
|
||||
margin: 2em;
|
||||
}
|
||||
div#audioOutputContainer, #history {
|
||||
margin: 2em;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 840px) {
|
||||
body{
|
||||
zoom: 0.64;
|
||||
-moz-transform: scale(0.64);
|
||||
-moz-transform-origin: 0 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media only screen and (max-height: 639px) {
|
||||
div#urlInput {
|
||||
margin: 2em;
|
||||
}
|
||||
div#audioOutputContainer, #history {
|
||||
margin: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767px) {
|
||||
|
||||
div#urlInput {
|
||||
margin: 2em 1em;
|
||||
}
|
||||
div#audioOutputContainer, #history {
|
||||
margin: 2em 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-height: 380px) {
|
||||
div#urlInput {
|
||||
margin: 1em;
|
||||
}
|
||||
div#audioOutputContainer, #history {
|
||||
margin: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
label[for="audioOutput"], label[for="lastUrls"] {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
#warning4mac, #electronVersion {
|
||||
background: #8500f7;
|
||||
box-shadow: 0px 0px 50px 10px #8500f7ab, inset 0px 0px 10px 2px #8d08ffba;
|
||||
border: 2px solid #8500f7;
|
||||
border-radius: 10px;
|
||||
width: 90%;
|
||||
padding:1em;
|
||||
margin:0 auto;
|
||||
color:white;
|
||||
font-size:1.3em;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#warning4mac a, #electronVersion a {
|
||||
color:white;
|
||||
}
|
||||
|
||||
ul#lastUrls {
|
||||
list-style: none;
|
||||
background: #101520;
|
||||
color: white;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
ul#lastUrls li {
|
||||
padding: 5px 0px;
|
||||
}
|
||||
ul#lastUrls li:nth-child(even) {
|
||||
background-color: #182031;
|
||||
}
|
||||
|
||||
#inputCombo {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body >
|
||||
|
||||
<div id="header" style="-webkit-app-region: drag;color:#6f6f6f;font-size:40px; line-height: 40px; padding: 20px; letter-spacing: 3; font-weight: bold;">Electron Capture</div>
|
||||
<div class="container" >
|
||||
|
||||
<div id='warning4mac' style="display:none;"> ✨ Great News! OBS v26.1.2 <a href="https://github.com/obsproject/obs-browser/issues/209#issuecomment-748683083">now supports</a> VDO.Ninja without needing the Electron Capture app! 🥳</div>
|
||||
<div id="electronVersion" style="display:none;">✨ Great News! <a href="https://github.com/steveseguin/electroncapture/releases/latest">Electron Capture <span id="currentElectronVersion"></span></a> is now available!<br>Update yours today to stay up-to-date with security patches.</div>
|
||||
|
||||
<div id="messageDiv" style='display:block'><br /></div>
|
||||
<div class="container">
|
||||
<div id="urlInput" title="Put the link you want to load here">
|
||||
<label for="changeText">
|
||||
<i class="las la-play"></i>
|
||||
</label>
|
||||
<div id="inputCombo">
|
||||
<input type="text" id="changeText" class="inputfield" value="http://vdo.ninja/?view=" onchange="modURL" onkeyup="enterPressed(event, gohere);" />
|
||||
<button onclick="gohere();" id="gobutton">GO</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="audioOutputContainer" title="This option will only work with the official vdo.ninja domain">
|
||||
<label for="audioOutput"><i class="las la-headphones"></i></label><select id="audioOutput"></select>
|
||||
</div>
|
||||
<div id="history" title="History of past links used. You can clear this history using the button to the left">
|
||||
<label for="lastUrls" onclick="resetHistory()">
|
||||
<i class="las la-history"></i>
|
||||
</label>
|
||||
<select id="lastUrls" onchange="setUrl()"></select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
/*
|
||||
* Copyright (c) 2020 Steve Seguin. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by the APGLv3 open-source license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. Alternative licencing options can be made available on request.
|
||||
*
|
||||
*/
|
||||
var lastUrls = JSON.parse(localStorage.getItem('lastUrls'));
|
||||
if (lastUrls != undefined) {
|
||||
document.querySelector("#changeText").value = lastUrls[0];
|
||||
if (lastUrls.length>0){
|
||||
lastUrls.forEach((url)=>{
|
||||
var o = document.createElement('option');
|
||||
o.value = url;
|
||||
o.text = url;
|
||||
document.querySelector("#lastUrls").appendChild(o);
|
||||
})
|
||||
} else {
|
||||
document.querySelector("#history").style.display="none";
|
||||
}
|
||||
} else {
|
||||
document.querySelector("#history").style.display="none";
|
||||
}
|
||||
|
||||
function setUrl(){
|
||||
document.querySelector("#changeText").value = document.querySelector("#lastUrls").value;
|
||||
gohere();
|
||||
}
|
||||
|
||||
function resetHistory(){
|
||||
localStorage.clear();
|
||||
document.querySelector('#lastUrls').innerHTML = '';
|
||||
lastUrls = [];
|
||||
}
|
||||
|
||||
(function (w) {
|
||||
w.URLSearchParams = w.URLSearchParams || function (searchString) {
|
||||
var self = this;
|
||||
self.searchString = searchString;
|
||||
self.get = function (name) {
|
||||
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString);
|
||||
if (results == null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return decodeURI(results[1]) || 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
})(window)
|
||||
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
if (navigator.userAgent.indexOf('Mac OS X') != -1){
|
||||
document.getElementById("warning4mac").style.display="block";
|
||||
} else if (location.hostname.toLowerCase() == "obs.ninja"){
|
||||
try {
|
||||
if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { // for now, just PC or Linux versions only.
|
||||
function compareVersions(version){
|
||||
version = version.split(".");
|
||||
fetch('https://api.github.com/repos/steveseguin/electroncapture/releases/latest')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("recentVersion: "+data.tag_name);
|
||||
var recentVersion = data.tag_name.split(".");
|
||||
var ood = false;
|
||||
if (recentVersion[0]>version[0]){
|
||||
ood = true;
|
||||
} else if (recentVersion[0]==version[0]) {
|
||||
if (recentVersion[1]>version[1]){
|
||||
ood = true;
|
||||
} else if (recentVersion[1]==version[1]) {
|
||||
if (recentVersion[2]>version[2]){
|
||||
ood = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ood){
|
||||
document.getElementById("electronVersion").style.display = "block";
|
||||
document.getElementById("currentElectronVersion").innerText = data.tag_name;
|
||||
}
|
||||
}).catch(console.error);
|
||||
}
|
||||
if (urlParams.has('version')){
|
||||
var ver = urlParams.get('version');
|
||||
console.log("version: "+ver);
|
||||
compareVersions(ver);
|
||||
} else{
|
||||
var checkVersion = setTimeout(function(){ // pre 1.5.2
|
||||
compareVersions("0.0.0");
|
||||
},500);
|
||||
|
||||
const ipcRenderer = require('electron').ipcRenderer;
|
||||
console.log("ELECTRON DETECTED");
|
||||
ipcRenderer.on('appVersion', function(event, version) {
|
||||
clearTimeout(checkVersion);
|
||||
console.log("version: "+version);
|
||||
compareVersions(version);
|
||||
})
|
||||
ipcRenderer.send('getAppVersion');
|
||||
}
|
||||
}
|
||||
} catch(e){console.error(e);}
|
||||
}
|
||||
|
||||
var audioOutputSelect = document.querySelector('select#audioOutput');
|
||||
audioOutputSelect.disabled = !('sinkId' in HTMLMediaElement.prototype);
|
||||
audioOutputSelect.onclick = getPermssions;
|
||||
audioOutputSelect.onchange = updateOutputTarget;
|
||||
var listed = false;
|
||||
|
||||
function updateOutputTarget(e){
|
||||
console.log("change audio: "+audioOutputSelect.value);
|
||||
var url = document.getElementById('changeText').value;
|
||||
url=updateURLParameter(url, "sink", audioOutputSelect.value);
|
||||
document.getElementById('changeText').value = url;
|
||||
}
|
||||
|
||||
function getPermssions(e=null){
|
||||
if (listed==true){
|
||||
return;
|
||||
}
|
||||
if (e!==null){
|
||||
e.currentTarget.blur();
|
||||
}
|
||||
navigator.mediaDevices.getUserMedia({audio: true,video: false}).then((stream)=>{
|
||||
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(console.error); // list all devices
|
||||
stream.getTracks().forEach(track => {
|
||||
track.stop();
|
||||
});
|
||||
listed=true;
|
||||
audioOutputSelect.focus();
|
||||
|
||||
}).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) {
|
||||
for (let i = 0; i !== deviceInfos.length; ++i) {
|
||||
const deviceInfo = deviceInfos[i];
|
||||
const option = document.createElement('option');
|
||||
option.value = deviceInfo.deviceId;
|
||||
if (deviceInfo.kind === 'audiooutput'){
|
||||
option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`;
|
||||
audioOutputSelect.appendChild(option);
|
||||
} else {
|
||||
console.log('Some other kind of source/device: ', deviceInfo);
|
||||
}
|
||||
}
|
||||
listed=true;
|
||||
}
|
||||
|
||||
function enterPressed(event, callback){
|
||||
if (event.keyCode === 13){ // Number 13 is the "Enter" key on the keyboard
|
||||
event.preventDefault(); // Cancel the default action, if needed
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var isMobile = false;
|
||||
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){ // does not detect iPad Pros.
|
||||
isMobile=true; // if iOS, default to H264? meh. let's not.
|
||||
}
|
||||
// Windows can show the cursor, since it captures in a different way.
|
||||
//if (navigator.platform.indexOf("Win") != -1){
|
||||
// document.getElementById("showcursor").checked=true;
|
||||
//}
|
||||
|
||||
function updateURLParameter(url, param, paramVal){
|
||||
var TheAnchor = null;
|
||||
var newAdditionalURL = "";
|
||||
var tempArray = url.split("?");
|
||||
var baseURL = tempArray[0];
|
||||
var additionalURL = tempArray[1];
|
||||
var temp = "";
|
||||
|
||||
if (additionalURL){
|
||||
var tmpAnchor = additionalURL.split("#");
|
||||
var TheParams = tmpAnchor[0];
|
||||
TheAnchor = tmpAnchor[1];
|
||||
if (TheAnchor){additionalURL = TheParams;}
|
||||
|
||||
tempArray = additionalURL.split("&");
|
||||
|
||||
for (var i=0; i<tempArray.length; i++){
|
||||
if(tempArray[i].split('=')[0] != param){
|
||||
newAdditionalURL += temp + tempArray[i];
|
||||
temp = "&";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var tmpAnchor = baseURL.split("#");
|
||||
var TheParams = tmpAnchor[0];
|
||||
TheAnchor = tmpAnchor[1];
|
||||
|
||||
if(TheParams){baseURL = TheParams;}
|
||||
}
|
||||
|
||||
if (paramVal===false){
|
||||
temp="";
|
||||
if(TheAnchor){temp += "#" + TheAnchor;}
|
||||
var rows_txt = temp
|
||||
} else if (paramVal===""){
|
||||
if(TheAnchor){paramVal += "#" + TheAnchor;}
|
||||
var rows_txt = temp + "" + param;
|
||||
} else {
|
||||
if(TheAnchor){paramVal += "#" + TheAnchor;}
|
||||
var rows_txt = temp + "" + param + "=" + paramVal;
|
||||
}
|
||||
return baseURL + "?" + newAdditionalURL + rows_txt;
|
||||
}
|
||||
|
||||
if (urlParams.has('name')){
|
||||
var name = urlParams.get('name');
|
||||
if (name!="OBSNinja" && name!="VDONinja"){
|
||||
document.getElementById('changeText').value = "https://vdo.ninja/?view="+name;
|
||||
}
|
||||
}
|
||||
|
||||
function addUrlToHistory(url){
|
||||
if (lastUrls == undefined){
|
||||
lastUrls = [];
|
||||
}
|
||||
if ( lastUrls[0] != url ) {
|
||||
lastUrls.unshift(url);
|
||||
if (lastUrls.length == 6) {
|
||||
lastUrls.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function modURL(){
|
||||
var url = document.getElementById('changeText').value;
|
||||
if (url.startsWith("obs.ninja")){
|
||||
url = "https://"+url;
|
||||
}
|
||||
console.log(url);
|
||||
return url;
|
||||
}
|
||||
function gohere(){
|
||||
addUrlToHistory(document.getElementById('changeText').value);
|
||||
localStorage.setItem('lastUrls', JSON.stringify(lastUrls));
|
||||
var url = modURL();
|
||||
if ((document.getElementById('changeText').value.includes("obs.ninja")) && (document.getElementById('changeText').value.includes("http")) && (document.getElementById('changeText').value.includes("&sink"))){
|
||||
alert("Notice: OBS.Ninja has been replaced by VDO.Ninja.\n\nPlease update your links accordingly for audio output to work correctly.");
|
||||
} else if (!(document.getElementById('changeText').value.includes(window.location.hostname)) && (document.getElementById('changeText').value.includes("http")) && (document.getElementById('changeText').value.includes("&sink"))){
|
||||
alert("Notice: The &sink command is domain specific.\nVisit https://YOURDOMAIN.com/electron instead.");
|
||||
}
|
||||
window.location = url;
|
||||
};
|
||||
getPermssions();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
25
iframe.html
@@ -177,11 +177,26 @@ function loadIframe(){ // this is pretty important if you want to avoid camera
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":false}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Start Recording";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"record":true}, '*');};
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Stop Recording";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"record":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 = "Send Keyframe";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"keyframe":true}, '*');};
|
||||
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;}";
|
||||
@@ -228,6 +243,16 @@ function loadIframe(){ // this is pretty important if you want to avoid camera
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"function":"previewWebcam"}, '*');}; // publishScreen
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Change to Camera #2";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"changeVideoDevice":2}, '*');}; // change text of add camera button
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "Change to Microphone #4";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"changeAudioDevice":4}, '*');}; // change text of add camera button
|
||||
iframeContainer.appendChild(button);
|
||||
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = "eval('alert(\"DANGERUS\")'";
|
||||
button.onclick = function(){iframe.contentWindow.postMessage({"function":"eval", "value":'alert(\"DANGERUS\")'}, '*');}; // publishScreen
|
||||
|
||||
1123
index.html
53
install.md
@@ -13,31 +13,32 @@ For those looking for a brand-free experience already with a different domain na
|
||||
- https://chromicam.com
|
||||
- https://invite.cam (via URL obfuscation option)
|
||||
- https://ltt.ninja
|
||||
- https://obsn.me
|
||||
- https://rtc.ninja
|
||||
- https://vmix.ninja
|
||||
- https://webrtc.party
|
||||
- https://callin.ninja
|
||||
- https://auxiliary.live (backup hosted)
|
||||
- https://backup.obs.ninja (fully backup hosted)
|
||||
- https://backup.vdo.ninja (fully backup hosted)
|
||||
|
||||
There is also an isolated version specificly designed for use in mainland China, hosted at https://insecure.cam in Hong Kong AWS.
|
||||
|
||||
You can also point your domain to the OBS.Ninja IP address (provided on request), which will also rebrand the site automatically to match your domain name. (Requires Cloudflare as DNS server and proxy, Flexible SSL cert on, and HTTPs always on - all free.)
|
||||
You can also point your domain to the VDO.Ninja IP address (provided on request), which will also rebrand the site automatically to match your domain name. (Requires Cloudflare as DNS server and proxy, Flexible SSL cert on, and HTTPs always on - all free.)
|
||||
|
||||
For those wanting a private TURN server setup, you can load the settings for those via the URL parameters. If infrequently needing a private TURN, this is a great solution. You can also use URL forwarding services to load up a customized link to OBS.Ninja, with URL parameters already included, such as https://invite.mypersonaldomain.com , which might secretly resolve to https://obs.ninja/?room=myRoom&hash=3423&label or such.
|
||||
For those wanting a private TURN server setup, you can load the settings for those via the URL parameters. If infrequently needing a private TURN, this is a great solution. You can also use URL forwarding services to load up a customized link to VDO.Ninja, with URL parameters already included, such as https://invite.mypersonaldomain.com , which might secretly resolve to https://vdo.ninja/?room=myRoom&hash=3423&label or such.
|
||||
|
||||
OBS.Ninja also supports IFRAMES, so you can embed OBS.Ninja into your website and customize it via both URL parameters, but also via the IFRAME API. You can insert custom CSS styles with this method, giving OBS.Ninja quite a bit of flare.
|
||||
VDO.Ninja also supports IFRAMES, so you can embed VDO.Ninja into your website and customize it via both URL parameters, but also via the IFRAME API. You can insert custom CSS styles with this method, giving VDO.Ninja quite a bit of flare.
|
||||
|
||||
See more on IFRAMES here: https://github.com/steveseguin/obsninja/blob/master/IFRAME.md
|
||||
See more on IFRAMES here: https://github.com/steveseguin/vdo.ninja/blob/master/IFRAME.md
|
||||
|
||||
Understanding clearly why you need to deploy any code or server is important. Maintaining updated deployed code can be quite hard, as OBS.Ninja updates frequently, so there are good reasons to consider an IFRAME approach instead. Feature requests there are welcomed.
|
||||
Understanding clearly why you need to deploy any code or server is important. Maintaining updated deployed code can be quite hard, as VDO.Ninja updates frequently, so there are good reasons to consider an IFRAME approach instead. Feature requests there are welcomed.
|
||||
|
||||
That all aside, please continue:
|
||||
|
||||
### SETUP
|
||||
|
||||
I use Cloudflare with Flexible SSL enabled and HTTP Rewrites. If you do not use Cloudflare, you will need to deploy SSL certificates onto your website. You will also have to have Cloudflare or whatever DNS provider you have, point your domain name to the IP address of your webserver. OBS.Ninja REQUIRES a domain name and SSL.
|
||||
There's a community-created video tutorial on setting up here; https://youtu.be/8sDMwBIlgwE Otherwise, read on.
|
||||
|
||||
I use Cloudflare with Flexible SSL enabled and HTTP Rewrites. If you do not use Cloudflare, you will need to deploy SSL certificates onto your website. You will also have to have Cloudflare or whatever DNS provider you have, point your domain name to the IP address of your webserver. VDO.Ninja REQUIRES a domain name and SSL.
|
||||
|
||||
For webservers, I use NGINX on a Ubuntu server; smaller the better. I rely on Cloudflare to provide caching and SSL, so my installation of NGINX is pretty simple.
|
||||
```
|
||||
@@ -53,44 +54,52 @@ An example NGINX config file that "hides" the file extensions is as follows. Up
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name obs.ninja;
|
||||
server_name vdo.ninja;
|
||||
|
||||
root /var/www/html/obs.ninja;
|
||||
root /var/www/html/vdo.ninja;
|
||||
index index.html;
|
||||
|
||||
|
||||
location ~ ^/([^/]+)/([^/?]+)$ {
|
||||
root /var/www/html/obs.ninja;
|
||||
root /var/www/html/vdo.ninja;
|
||||
try_files /$1/$2 /$1/$2.html /$1/$2/ /$2 /$2/ /$1/index.html;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header 'cross-origin-resource-policy' '*';
|
||||
add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
|
||||
add_header 'Cross-Origin-Opener-Policy' 'same-origin';
|
||||
}
|
||||
|
||||
location / {
|
||||
if ($request_uri ~ ^/(.*)\.html$) {
|
||||
return 302 /$1;
|
||||
}
|
||||
try_files $uri $uri.html $uri/ /index.html;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
if ($request_uri ~ ^/(.*)\.html$) {
|
||||
return 302 /$1;
|
||||
}
|
||||
add_header 'cross-origin-resource-policy' '*';
|
||||
add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
|
||||
add_header 'Cross-Origin-Opener-Policy' 'same-origin';
|
||||
try_files $uri $uri.html $uri/ /index.html;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
}
|
||||
}
|
||||
```
|
||||
You'll want to deploy (copy/clone) the GitHub OBS.Ninja files into your NGINX web folder, that is specified in your NGINX config file. Update the NGINX config file to match your domain and and folder, etc. Restart NGINX after.
|
||||
You'll want to deploy (copy/clone) the GitHub VDO.Ninja files into your NGINX web folder, that is specified in your NGINX config file. Update the NGINX config file to match your domain and and folder, etc. Restart NGINX after.
|
||||
|
||||
|
||||
As for the TURN server, it can run on a single or dual-core computer. It doesn't take much to host many users -- it mainly just needs a good internet connection. Most users will not need a TURN server, but since OBS.Ninja handles many different types of users, the TURN server is there as a failsafe for those occasional problem users. I'm assuming you know why you need and want a TURN server -- if not, you may not actually need one.
|
||||
As for the TURN server, it can run on a single or dual-core computer. It doesn't take much to host many users -- it mainly just needs a good internet connection. Most users will not need a TURN server, but since VDO.Ninja handles many different types of users, the TURN server is there as a failsafe for those occasional problem users. I'm assuming you know why you need and want a TURN server -- if not, you may not actually need one.
|
||||
|
||||
A guide and sample config file for the turn server is here:
|
||||
https://github.com/steveseguin/obsninja/blob/master/turnserver.md
|
||||
https://github.com/steveseguin/vdo.ninja/blob/master/turnserver.md
|
||||
|
||||
If deploying to GCP or AWS, you might need to make some tweaks to the IP address values to include the internet local IP as well as the external. Please see online guides no setting up a TURN server for your particular setup. Setups will vary.
|
||||
|
||||
Once you have your TURN server setup, you can update the index.html of the OBS.Ninja code. Nightly or official releases should be fine to pull. You probably will want to uncomment the lines linked below once deployed, adjusting the default values to your liking and updating the server location address and credentials of your TURN server (if you deployed one that is). Unless your TURN server also provides STUN capabilities, you may want to also use the Google STUN servers, so uncomment that stuff too.
|
||||
Once you have your TURN server setup, you can update the index.html of the VDO.Ninja code. Nightly or official releases should be fine to pull. You probably will want to uncomment the lines linked below once deployed, adjusting the default values to your liking and updating the server location address and credentials of your TURN server (if you deployed one that is). Unless your TURN server also provides STUN capabilities, you may want to also use the Google STUN servers, so uncomment that stuff too.
|
||||
|
||||
https://github.com/steveseguin/obsninja/blob/df6c147311b9e7d19659ddbb1799d6598f59aa0d/index.html#L644
|
||||
https://github.com/steveseguin/vdo.ninja/blob/df6c147311b9e7d19659ddbb1799d6598f59aa0d/index.html#L644
|
||||
|
||||
A newly deployed code deployment should work without any changes to the index.html file. The code needs to be constantly kept up to date though, as after a few months it may become deprecated and stop working. This is the reality of deploying OBS.Ninja -- you will need to update it every few months for it to continue to function well. Keep this in mind when making changes to the OBS.Ninja source code, as heavy custom changes will make updating harder to do. The fewer the changes the better.
|
||||
A newly deployed code deployment should work without any changes to the index.html file. The code needs to be constantly kept up to date though, as after a few months it may become deprecated and stop working. This is the reality of deploying VDO.Ninja -- you will need to update it every few months for it to continue to function well. Keep this in mind when making changes to the VDO.Ninja source code, as heavy custom changes will make updating harder to do. The fewer the changes the better.
|
||||
|
||||
My suggestion? Limit changes to images and perhaps the translation files (maybe add a new one); these are good starting points. If making changes to the main.css style sheet or index.html file, you should be mostly okay too, since these files are designed to be changed; I try to keep that in mind when updating the code at least. Making changes to other files though is strongly not recommend and in some cases discouraged. If you find a bug or need to make a change to other files, it might be best to make a Pull Request with the desired changes and hope it gets adopted into the main codebase.
|
||||
|
||||
Final note: I haven't provided here instructions on deploying STUN services or a private handshake server; the VDO.Ninja handshake server code is currently not provided, but access to it as a service is freely accessible for private deployments.
|
||||
|
||||
Regards,
|
||||
Steve
|
||||
|
||||
BIN
media/bg_sample.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
media/bg_sample2.webp
Normal file
|
After Width: | Height: | Size: 28 KiB |
@@ -1,2 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="65" height="64"><style> .a{stroke-width:10;stroke:#000;}</style><title> background</title><rect height="66" width="67" y="-1" x="-1" fill="#0000"/><g height="100" width="100"><rect y="28.56" x="29.5" height="600" width="800" fill="url(#gridpattern)"/></g><title> Layer 1</title><rect height="3" width="1" y="27.02" x="302" style="fill:#0000;stroke-width:2;stroke:#0000"/><rect height="43" width="48" y="10.8" x="8.38" style="fill-opacity:null;fill:#0000;stroke-opacity:null;stroke-width:2;stroke:#FFF"/>
|
||||
<text font-family="Helvetica, Arial, sans-serif" font-size="24" y="40.49" x="15.38" style="fill:#FFF;font-weight:bold"> HQ</text></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="white" x="0px" y="0px" viewBox="0 0 122.88 122.87" style="enable-background:new 0 0 122.88 122.87" xml:space="preserve"><g><path d="M122.88,77.63v41.12c0,2.28-1.85,4.12-4.12,4.12H77.33v-9.62h35.95c0-12.34,0-23.27,0-35.62H122.88L122.88,77.63z M77.39,9.53V0h41.37c2.28,0,4.12,1.85,4.12,4.12v41.18h-9.63V9.53H77.39L77.39,9.53z M9.63,45.24H0V4.12C0,1.85,1.85,0,4.12,0h41 v9.64H9.63V45.24L9.63,45.24z M45.07,113.27v9.6H4.12c-2.28,0-4.12-1.85-4.12-4.13V77.57h9.63v35.71H45.07L45.07,113.27z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 650 B |
@@ -1,2 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="65" height="64"><style> .a{stroke-width:10;stroke:#000;}</style><title> background</title><rect height="66" width="67" y="-1" x="-1" fill="#0000"/><g height="100" width="100"><rect y="28.56" x="29.5" height="600" width="800" fill="url(#gridpattern)"/></g><title> Layer 1</title><rect height="3" width="1" y="27.02" x="302" style="fill:#0000;stroke-width:5;stroke:#0000"/><rect height="43" width="48" y="10.8" x="8.38" style="fill-opacity:null;fill:#0000;stroke-opacity:null;stroke-width:5;stroke:#FFF"/>
|
||||
<text font-family="Helvetica, Arial, sans-serif" font-size="24" y="40.49" x="15.38" style="fill:#FFF;font-weight:bold"> LQ</text></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" fill="white" width="122.88px" height="122.871px" viewBox="0 0 122.88 122.871" enable-background="new 0 0 122.88 122.871" xml:space="preserve"><g><path d="M122.88,35.775v9.529H81.515c-2.278,0-4.125-1.847-4.125-4.125V0h9.63v35.775H122.88L122.88,35.775z M35.499,0h9.63v41.118 c0,2.278-1.847,4.125-4.125,4.125H0v-9.644h35.499V0L35.499,0z M0,87.164v-9.598h40.942c2.277,0,4.125,1.846,4.125,4.125v41.18 h-9.633V87.164H0L0,87.164z M77.328,122.871V81.752c0-2.277,1.847-4.125,4.125-4.125h41.427v9.625H86.931 c0,12.338-0.003,23.271-0.003,35.619H77.328L77.328,122.871z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 733 B |
BIN
media/streamdeck.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
2
media/svg.md
Normal file
@@ -0,0 +1,2 @@
|
||||
https://uxwing.com/collapse-icon/
|
||||
https://uxwing.com/expand-icon/
|
||||
84
midi.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="https://cdn.jsdelivr.net/npm/webmidi"></script>
|
||||
</head>
|
||||
<body><br />
|
||||
check the console debug logs for output;
|
||||
<br /><br />virtual midi controller here:<br />
|
||||
http://www.tobias-erichsen.de/software/loopmidi.html
|
||||
<br /><br /> code referenced from here:<br />
|
||||
https://github.com/djipco/webmidi
|
||||
<script>
|
||||
// Enable WebMidi.js
|
||||
WebMidi.enable(function (err) {
|
||||
|
||||
if (err) {
|
||||
console.log("WebMidi could not be enabled.", err);
|
||||
}
|
||||
|
||||
// Viewing available inputs and outputs
|
||||
console.log(WebMidi.inputs);
|
||||
console.log(WebMidi.outputs);
|
||||
|
||||
// Reacting when a new device becomes available
|
||||
WebMidi.addListener("connected", function(e) {
|
||||
console.log(e);
|
||||
});
|
||||
|
||||
// Reacting when a device becomes unavailable
|
||||
WebMidi.addListener("disconnected", function(e) {
|
||||
console.log(e);
|
||||
});
|
||||
|
||||
// Display the current time
|
||||
console.log(WebMidi.time);
|
||||
|
||||
|
||||
// Retrieve an input by name, id or index
|
||||
// var input = WebMidi.getInputByName("StreamDeck2Daw");
|
||||
// input = WebMidi.getInputById("1809568182");
|
||||
var input = WebMidi.inputs[0];
|
||||
|
||||
// Listen for a 'note on' message on all channels
|
||||
input.addListener('noteon', "all",
|
||||
function (e) {
|
||||
console.log("Received 'noteon' message (" + e.note.name + e.note.octave + ").");
|
||||
}
|
||||
);
|
||||
|
||||
// Listen to pitch bend message on channel 3
|
||||
input.addListener('pitchbend', 3,
|
||||
function (e) {
|
||||
console.log("Received 'pitchbend' message.", e);
|
||||
}
|
||||
);
|
||||
|
||||
// Listen to control change message on all channels
|
||||
input.addListener('controlchange', "all",
|
||||
function (e) {
|
||||
console.log("Received 'controlchange' message.", e);
|
||||
}
|
||||
);
|
||||
|
||||
// Listen to NRPN message on all channels
|
||||
input.addListener('nrpn', "all",
|
||||
function (e) {
|
||||
if(e.controller.type === 'entry') {
|
||||
console.log("Received 'nrpn' 'entry' message.", e);
|
||||
}
|
||||
if(e.controller.type === 'decrement') {
|
||||
console.log("Received 'nrpn' 'decrement' message.", e);
|
||||
}
|
||||
if(e.controller.type === 'increment') {
|
||||
console.log("Received 'nrpn' 'increment' message.", e);
|
||||
}
|
||||
console.log("message value: " + e.controller.value + ".", e);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
572
monitor.html
Normal file
@@ -0,0 +1,572 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>OBSN Monitoring</title>
|
||||
<style>
|
||||
|
||||
body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-family: "Lato", sans-serif;
|
||||
padding: 0 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
opacity: 1;
|
||||
transition: opacity .1s linear;
|
||||
background-color: #141926;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
margin: 5px 20px;
|
||||
}
|
||||
|
||||
h1 small {
|
||||
display: block;
|
||||
margin-top: 0.5em;
|
||||
font-size: 0.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #CCC;
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
#explanation {
|
||||
color: white;
|
||||
font-family: sans-serif;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#container, #graphs, #log {
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
#explanation h2 {
|
||||
border-bottom: 1px solid #383838;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
#feeds {
|
||||
display: inline-block;
|
||||
width:100%;
|
||||
height:380px;
|
||||
|
||||
}
|
||||
|
||||
#feeds span {
|
||||
margin:auto;
|
||||
height: 100%;
|
||||
min-width:50%;
|
||||
display: inline-block;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#button_container{
|
||||
margin:auto;
|
||||
}
|
||||
#feeds h3 {
|
||||
color: whitesmoke;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
iframe {
|
||||
height: 85%;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#controls {
|
||||
margin:auto;
|
||||
}
|
||||
|
||||
#controls button {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#controls button.active {
|
||||
background-color: #70ff70;
|
||||
}
|
||||
|
||||
canvas {
|
||||
background-color: black;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
#log {
|
||||
margin-top: 10px;
|
||||
background: #313131;
|
||||
padding: 20px 0px;
|
||||
border: 1px solid #383838;
|
||||
cursor: pointer;
|
||||
max-height:300px;
|
||||
}
|
||||
|
||||
#log ul {
|
||||
margin: 20px;
|
||||
list-style: none;
|
||||
color: #cacaca;
|
||||
max-height: 20vh;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#graphs {
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
background: #313131;
|
||||
padding: 20px 0px;
|
||||
border: 1px solid #383838;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.graphContainer {
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
background: #313131;
|
||||
border: 1px solid #383838;
|
||||
}
|
||||
|
||||
.graph {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.graph h2, #log h2 {
|
||||
margin: 10px 20px 0 20px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.graph > span {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
left: 30px;
|
||||
color: #cacaca;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ol {
|
||||
margin-left: 20px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
|
||||
#container, #graphs, #log {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#graphs {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#feeds {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#feeds h3 {
|
||||
font-size:50%;
|
||||
}
|
||||
|
||||
h1{
|
||||
color: white;
|
||||
margin: 2px;
|
||||
font-size:70%
|
||||
}
|
||||
|
||||
#feeds span{
|
||||
height: 50%;
|
||||
width:100%;
|
||||
display: inline-block;
|
||||
}
|
||||
canvas {
|
||||
margin:auto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#statsdiv {display: none;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
<script>
|
||||
|
||||
function getChromeVersion() {
|
||||
var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
||||
return raw ? parseInt(raw[2], 10) : false;
|
||||
}
|
||||
if (!getChromeVersion()){
|
||||
alert("This speedtest is optimized for Chromium-based browsers; graphs will not work for Firefox or Safari browsers.");
|
||||
}
|
||||
|
||||
(function (w) {
|
||||
w.URLSearchParams =
|
||||
w.URLSearchParams ||
|
||||
function (searchString) {
|
||||
var self = this;
|
||||
self.searchString = searchString;
|
||||
self.get = function (name) {
|
||||
var results = new RegExp("[\?&]" + name + "=([^&#]*)").exec(
|
||||
self.searchString
|
||||
);
|
||||
if (results == null) {
|
||||
return null;
|
||||
} else {
|
||||
return decodeURI(results[1]) || 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
})(window);
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
var quality_reason = {};
|
||||
var video_encoder={};
|
||||
var resolution={};
|
||||
|
||||
function copyFunction(copyText) {
|
||||
try {
|
||||
copyText.select();
|
||||
copyText.setSelectionRange(0, 99999);
|
||||
document.execCommand("copy");
|
||||
} catch (e) {
|
||||
var dummy = document.createElement("input");
|
||||
document.body.appendChild(dummy);
|
||||
dummy.value = copyText;
|
||||
dummy.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(dummy);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function loadIframe() {
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
|
||||
if (urlParams.has("remote")) {
|
||||
var remote = urlParams.get("remote");
|
||||
} else {
|
||||
var remote="";
|
||||
}
|
||||
|
||||
if (urlParams.has("sid")) {
|
||||
var streamID = urlParams.get("sid");
|
||||
} else if (urlParams.has("view")) {
|
||||
var streamID = urlParams.get("view");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.getElementById("streamID_header")){
|
||||
document.getElementById("streamID_header").innerText += ": "+streamID;
|
||||
}
|
||||
|
||||
var room="";
|
||||
if (urlParams.has("room")) {
|
||||
room = "&room="+urlParams.get("room");
|
||||
}
|
||||
|
||||
var password="";
|
||||
if (urlParams.has("password")) {
|
||||
password = "&password="+urlParams.get("password");
|
||||
}
|
||||
|
||||
iframe.allow = "autoplay";
|
||||
var srcString = "./?view=" + streamID + room + password + "&vd=0&ad=0&autostart&novideo&noaudio&remote="+remote;
|
||||
|
||||
|
||||
iframe.src = srcString;
|
||||
iframe.style.width="0";
|
||||
iframe.style.height="0";
|
||||
iframe.style.border="0";
|
||||
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
setInterval(function () {
|
||||
iframe.contentWindow.postMessage({ getRemoteStats: true }, "*");
|
||||
}, 3000);
|
||||
|
||||
var eventMethod = window.addEventListener
|
||||
? "addEventListener"
|
||||
: "attachEvent";
|
||||
var eventer = window[eventMethod];
|
||||
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
|
||||
var previousResolution;
|
||||
|
||||
eventer(messageEvent, function (e) {
|
||||
if ("remoteStats" in e.data) {
|
||||
var out = "";
|
||||
console.log(e.data);
|
||||
|
||||
for (var UUID in e.data.remoteStats) {
|
||||
|
||||
if (e.data.remoteStats[UUID].quality_limitation_reason){
|
||||
if (quality_reason[UUID] != e.data.remoteStats[UUID].quality_limitation_reason) {
|
||||
quality_reason[UUID] = e.data.remoteStats[UUID].quality_limitation_reason;
|
||||
logData("Quality Limitation Reason:", quality_reason[UUID], UUID);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.data.remoteStats[UUID].video_encoder){
|
||||
if (video_encoder[UUID] != e.data.remoteStats[UUID].video_encoder) {
|
||||
video_encoder[UUID] = e.data.remoteStats[UUID].video_encoder;
|
||||
logData("Video encoder used:", video_encoder[UUID], UUID);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.data.remoteStats[UUID].resolution){
|
||||
if (resolution[UUID] != e.data.remoteStats[UUID].resolution) {
|
||||
resolution[UUID] = e.data.remoteStats[UUID].resolution;
|
||||
logData("Resolution:", resolution[UUID], UUID);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.data.remoteStats[UUID].video_bitrate_kbps){
|
||||
var video_bitrate_kbps = e.data.remoteStats[UUID].video_bitrate_kbps;
|
||||
updateData("bitrate", video_bitrate_kbps, UUID);
|
||||
} else if (document.getElementById(UUID)){
|
||||
updateData("bitrate", 0, UUID);
|
||||
}
|
||||
|
||||
if (e.data.remoteStats[UUID].nacks_per_second){
|
||||
var nacks_per_second = e.data.remoteStats[UUID].nacks_per_second;
|
||||
updateData("nackrate", nacks_per_second, UUID);
|
||||
} else if (document.getElementById(UUID)){
|
||||
updateData("nackrate", 0, UUID);
|
||||
}
|
||||
|
||||
if (e.data.remoteStats[UUID].retransmitted_kbps){
|
||||
var retransmitted_kbps = parseInt(10000*e.data.remoteStats[UUID].retransmitted_kbps/ (e.data.remoteStats[UUID].video_bitrate_kbps-e.data.remoteStats[UUID].retransmitted_kbps))/100;
|
||||
updateData("retransmit", retransmitted_kbps, UUID);
|
||||
} else if (document.getElementById(UUID)){
|
||||
updateData("retransmit", 0, UUID);
|
||||
}
|
||||
|
||||
if (e.data.remoteStats[UUID].info.label){
|
||||
if (!document.getElementById("label_"+UUID)){
|
||||
document.getElementById(UUID).innerHTML = "<h1 class='small' id='label_"+UUID+"'></h1>" + document.getElementById(UUID).innerHTML;
|
||||
}
|
||||
document.getElementById("label_"+UUID).innerText = e.data.remoteStats[UUID].info.label;
|
||||
}
|
||||
|
||||
|
||||
//updateData("buffer", buffer);
|
||||
|
||||
//if (packetloss != undefined) {
|
||||
// packetloss = packetloss.toFixed(2);
|
||||
// updateData("packetloss", packetloss);
|
||||
//}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function printValues(obj) {
|
||||
var out = "";
|
||||
for (var key in obj) {
|
||||
if (typeof obj[key] === "object") {
|
||||
out += "<br />";
|
||||
out += printValues(obj[key]);
|
||||
} else {
|
||||
if (key.startsWith("_")) {
|
||||
} else {
|
||||
out += "<b>" + key + "</b>: " + obj[key] + "<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function logData(type, data, UUID) {
|
||||
try{
|
||||
var log = document.getElementById(UUID).querySelectorAll('[data-log]')[0].getElementsByTagName("ul")[0];
|
||||
var entry = document.createElement('li');
|
||||
entry.style.color ="white";
|
||||
entry.textContent = "[" + new Date().toLocaleTimeString() + "] " + type + " : " + data;
|
||||
if (log.childElementCount>10){
|
||||
log.childNodes[0].parentNode.removeChild(log.childNodes[0]);
|
||||
}
|
||||
log.appendChild(entry);
|
||||
} catch(e){}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="loadIframe();">
|
||||
<div id="container">
|
||||
<h1 >
|
||||
<span id="streamID_header">OBS.Ninja Remote Monitor</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div id="graphs" style="display:none">
|
||||
|
||||
|
||||
|
||||
<div class="graph">
|
||||
<h2>Bitrate (kbps)</h2>
|
||||
<span>0</span>
|
||||
<canvas data-bitrate-graph="true"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="graph">
|
||||
<h2>Reported lost packets (per second)</h2>
|
||||
<span>0</span>
|
||||
<canvas data-nackrate-graph="true"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="graph">
|
||||
<h2>Retransmitted bytes (%)</h2>
|
||||
<span>0</span>
|
||||
<canvas data-retransmit-graph="true"></canvas>
|
||||
</div>
|
||||
|
||||
<div data-log="true" onclick="copyFunction(this.innerText)" style="max-height:400px;display:inline-block;">
|
||||
<ul></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
var bitrate = {
|
||||
element: "bitrate-graph",
|
||||
data: 0,
|
||||
max: 6000,
|
||||
target: 3000,
|
||||
};
|
||||
var frames;
|
||||
var nackrate = {
|
||||
element: "nackrate-graph",
|
||||
data: 0,
|
||||
max: 15,
|
||||
target: 15,
|
||||
};
|
||||
var retransmit = {
|
||||
element: "retransmit-graph",
|
||||
data: 0,
|
||||
max: 3,
|
||||
target: 2,
|
||||
};
|
||||
|
||||
function updateData(type, data, UUID) {
|
||||
if (type == "bitrate") {
|
||||
bitrate.data = data;
|
||||
plotData("bitrate", bitrate, UUID);
|
||||
}
|
||||
|
||||
if (type == "nackrate") {
|
||||
nackrate.data = data;
|
||||
plotData("nackrate", nackrate, UUID);
|
||||
}
|
||||
|
||||
if (type == "retransmit") {
|
||||
retransmit.data = data;
|
||||
plotData("retransmit", retransmit, UUID);
|
||||
}
|
||||
}
|
||||
|
||||
function plotData(type, stat, UUID) {
|
||||
var canvas;
|
||||
var context;
|
||||
var yScale;
|
||||
|
||||
var container = document.getElementById(UUID);
|
||||
if (container){
|
||||
canvas = container.querySelectorAll('[data-'+stat.element+']')[0];
|
||||
|
||||
} else {
|
||||
container = document.getElementById("graphs").cloneNode(true);
|
||||
container.id = UUID;
|
||||
container.className = "graphContainer";
|
||||
container.style.display = "block";
|
||||
document.getElementById("graphs").parentNode.insertBefore(container, document.getElementById("graphs").nextSibling);
|
||||
canvas = container.querySelectorAll('[data-'+stat.element+']')[0];
|
||||
}
|
||||
|
||||
context = canvas.getContext("2d");
|
||||
|
||||
if (isNaN(stat.data)) {
|
||||
stat.data = 0;
|
||||
}
|
||||
|
||||
var text = (canvas.previousElementSibling.innerHTML = stat.data);
|
||||
|
||||
var height = context.canvas.height;
|
||||
var width = context.canvas.width;
|
||||
|
||||
var borderWidth = 5;
|
||||
var offset = borderWidth * 2;
|
||||
|
||||
// Create gradient
|
||||
var grd = context.createLinearGradient(0, 0, 0, height);
|
||||
|
||||
if (type == "bitrate") {
|
||||
// Higher values are green
|
||||
grd.addColorStop(0, "#33C433");
|
||||
grd.addColorStop(0.7, "#F3F304");
|
||||
grd.addColorStop(0.9, "#F30404");
|
||||
} else if (type == "retransmit") {
|
||||
// Higher values are red
|
||||
grd.addColorStop(0, "#F30404");
|
||||
grd.addColorStop(0.75, "#F3F304");
|
||||
grd.addColorStop(1.0, "#33C433");
|
||||
} else {
|
||||
// Higher values are red
|
||||
grd.addColorStop(0, "#F30404");
|
||||
grd.addColorStop(0.85, "#F3F304");
|
||||
grd.addColorStop(0.95, "#33C433");
|
||||
}
|
||||
|
||||
context.strokeStyle = "white";
|
||||
context.fillStyle = grd;
|
||||
//context.fillStyle = "#009933";
|
||||
//context.imageSmoothingEnabled = true;
|
||||
|
||||
yScale = height / stat.target;
|
||||
|
||||
if (stat.data > stat.target) {
|
||||
stat.data = stat.target;
|
||||
}
|
||||
|
||||
if (type == "retransmit" && stat.data == 0.0) {
|
||||
stat.data = 0.1;
|
||||
}
|
||||
if (type == "nackrate" && stat.data == 0.0) {
|
||||
stat.data = 0.1;
|
||||
}
|
||||
|
||||
var x = width - 1;
|
||||
var y = height - stat.data * yScale;
|
||||
var w = 1;
|
||||
|
||||
context.fillStyle = grd;
|
||||
context.fillRect(x, y, w, height);
|
||||
|
||||
// shift everything to the left:
|
||||
var imageData = context.getImageData(1, 0, width - 1, height);
|
||||
context.putImageData(imageData, 0, 0);
|
||||
// now clear the right-most pixels:
|
||||
context.clearRect(width - 1, 0, 1, height);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -13,6 +13,10 @@ body {
|
||||
background-color: #141926;
|
||||
}
|
||||
|
||||
#add_screen{
|
||||
display:none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
margin: 20px 0px;
|
||||
@@ -24,6 +28,9 @@ h1 small {
|
||||
font-size: 0.5em;
|
||||
}
|
||||
|
||||
video {
|
||||
transform: translate(0px, 0%) !important;
|
||||
}
|
||||
#explanation {
|
||||
color: white;
|
||||
font-family: sans-serif;
|
||||
@@ -116,7 +123,15 @@ canvas {
|
||||
padding: 20px 0px;
|
||||
border: 1px solid #383838;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.graphContainer {
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
background: #313131;
|
||||
padding: 20px 0px;
|
||||
border: 1px solid #383838;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.graph {
|
||||
|
||||
@@ -6,6 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>OBSN Speed Test</title>
|
||||
<script>
|
||||
|
||||
function getChromeVersion() {
|
||||
var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
||||
return raw ? parseInt(raw[2], 10) : false;
|
||||
}
|
||||
if (!getChromeVersion()){
|
||||
alert("This speedtest is optimized for Chromium-based browsers; graphs will not work for Firefox or Safari browsers.");
|
||||
}
|
||||
|
||||
(function (w) {
|
||||
w.URLSearchParams =
|
||||
w.URLSearchParams ||
|
||||
@@ -45,18 +54,27 @@
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
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";
|
||||
var possible = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789";
|
||||
for (var i = 0; i < 7; i++) {
|
||||
streamID += possible.charAt(
|
||||
Math.floor(Math.random() * possible.length)
|
||||
);
|
||||
}
|
||||
|
||||
if (urlParams.has("sid")) {
|
||||
streamID = urlParams.get("sid");
|
||||
}
|
||||
|
||||
|
||||
|
||||
document.getElementById("remote").innerHTML = "<a style='color:#CCC' href='./monitor?sid="+streamID+"'>Remote Monitoring Link</a><br /><br /><br /><br />";
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
var iframeContainer = document.createElement("span");
|
||||
@@ -66,7 +84,7 @@
|
||||
iframe.allowfullscreen ="true";
|
||||
|
||||
//iframe.allow = "autoplay";
|
||||
var srcString = "./?push=" + streamID + "&cleanoutput&privacy&speedtest&webcam&audiodevice=0&fullscreen&transparent";
|
||||
var srcString = "./?push=" + streamID + "&cleanoutput&privacy&speedtest&"+testType+"&audiodevice=0&fullscreen&transparent&remote";
|
||||
|
||||
if (urlParams.has("turn")) {
|
||||
srcString = srcString + "&turn=" + urlParams.get("turn");
|
||||
@@ -106,7 +124,7 @@
|
||||
var iframeContainer = document.createElement("span");
|
||||
|
||||
iframe.allow = "autoplay";
|
||||
var srcString = "./?view=" + streamID + "&cleanoutput&privacy&noaudio&scale=0";
|
||||
var srcString = "./?view=" + streamID + "&cleanoutput&privacy&noaudio&speedtest&scale=0";
|
||||
|
||||
if (urlParams.has("turn")) {
|
||||
srcString = srcString + "&turn=" + urlParams.get("turn");
|
||||
@@ -178,13 +196,12 @@
|
||||
? "addEventListener"
|
||||
: "attachEvent";
|
||||
var eventer = window[eventMethod];
|
||||
var messageEvent =
|
||||
eventMethod === "attachEvent" ? "onmessage" : "message";
|
||||
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
|
||||
var previousResolution;
|
||||
|
||||
eventer(messageEvent, function (e) {
|
||||
if ("action" in e.data) {
|
||||
logData(e.data.action, e.data.value);
|
||||
logData(e.data.action, e.data.value || "");
|
||||
|
||||
if (e.data.action == "new-view-connection") {
|
||||
buttonContainer.querySelectorAll(
|
||||
@@ -221,9 +238,9 @@
|
||||
}
|
||||
|
||||
for (var streamID in e.data.stats.outbound_stats) {
|
||||
if (e.data.stats.outbound_stats[streamID].quality_Limitation_Reason){
|
||||
if (quality_reason != e.data.stats.outbound_stats[streamID].quality_Limitation_Reason) {
|
||||
quality_reason = e.data.stats.outbound_stats[streamID].quality_Limitation_Reason;
|
||||
if (e.data.stats.outbound_stats[streamID].quality_limitation_reason){
|
||||
if (quality_reason != e.data.stats.outbound_stats[streamID].quality_limitation_reason) {
|
||||
quality_reason = e.data.stats.outbound_stats[streamID].quality_limitation_reason;
|
||||
logData("Quality Limitation Reason:", quality_reason);
|
||||
}
|
||||
}
|
||||
@@ -251,10 +268,7 @@
|
||||
];
|
||||
updateData("buffer", buffer);
|
||||
|
||||
var packetloss =
|
||||
e.data.stats.inbound_stats[streamID][key][
|
||||
"packetLoss_in_percentage"
|
||||
];
|
||||
var packetloss = e.data.stats.inbound_stats[streamID][key]["packetLoss_in_percentage"];
|
||||
if (packetloss != undefined) {
|
||||
packetloss = packetloss.toFixed(2);
|
||||
updateData("packetloss", packetloss);
|
||||
@@ -351,10 +365,22 @@
|
||||
Change the video bitrate by pressing the buttons below the video. It
|
||||
should approach 6000-kbps if the network allows.
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
<div id="screen" style="color: #CCC; margin:10px 0;"><a href="./speedtest?screen" style="color: #CCC;">Test screen-sharing performance here</a></div>
|
||||
<div id="remote"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var testType= "webcam";
|
||||
if (urlParams.has("screen") || urlParams.has("ss") || urlParams.has("screenshare") || urlParams.has("screentest")) {
|
||||
document.getElementById("screen").innerHTML = '<a href="./speedtest" style="color: #CCC;">Test webcam-streaming performance here</a>';
|
||||
testType = "quality=0&screenshare&css=speedtest.css"
|
||||
}
|
||||
|
||||
|
||||
var bitrate = {
|
||||
element: "bitrate-graph",
|
||||
data: 0,
|
||||
|
||||
172
status.html
Normal file
@@ -0,0 +1,172 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>OBSN Chat Overlay</title>
|
||||
<style>
|
||||
|
||||
@font-face {
|
||||
font-family: 'Cousine';
|
||||
src: url('fonts/Cousine-Bold.ttf') format('truetype');
|
||||
}
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
padding:0 10px;
|
||||
height:100%;
|
||||
border: 0;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
position:absolute;
|
||||
bottom:0;
|
||||
overflow:hidden;
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin:0;
|
||||
background-color: #0000;
|
||||
color: white;
|
||||
font-family: Cousine, monospace;
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1em;
|
||||
letter-spacing: 0.0em;
|
||||
text-transform: uppercase;
|
||||
padding: 0em;
|
||||
text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1);
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
ul li {
|
||||
background-color: black;
|
||||
padding: 8px 8px 0px 8px;
|
||||
margin:0;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
hyphens: auto;
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color:white;
|
||||
font-size:1.2em;
|
||||
text-transform: none;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
hyphens: auto;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
|
||||
(function (w) {
|
||||
w.URLSearchParams =
|
||||
w.URLSearchParams ||
|
||||
function (searchString) {
|
||||
var self = this;
|
||||
self.searchString = searchString;
|
||||
self.get = function (name) {
|
||||
var results = new RegExp("[\?&]" + name + "=([^&#]*)").exec(
|
||||
self.searchString
|
||||
);
|
||||
if (results == null) {
|
||||
return null;
|
||||
} else {
|
||||
return decodeURI(results[1]) || 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
})(window);
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
|
||||
function loadIframe() {
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
|
||||
var view= "";
|
||||
if (urlParams.has("view")) {
|
||||
view = "&view="+(urlParams.get("view") || "");
|
||||
}
|
||||
var room="";
|
||||
if (urlParams.has("room")) {
|
||||
room = "&room="+urlParams.get("room");
|
||||
}
|
||||
|
||||
var password="";
|
||||
if (urlParams.has("password")) {
|
||||
password = "&password="+urlParams.get("password");
|
||||
}
|
||||
|
||||
iframe.allow = "autoplay";
|
||||
var srcString = "./?novideo&noaudio&label=chatOverlay&scene"+room+view+password;
|
||||
|
||||
iframe.src = srcString;
|
||||
iframe.style.width="0";
|
||||
iframe.style.height="0";
|
||||
iframe.style.border="0";
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
//////////// LISTEN FOR EVENTS
|
||||
|
||||
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
||||
var eventer = window[eventMethod];
|
||||
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
|
||||
|
||||
|
||||
/// If you have a routing system setup, you could have just one global listener for all iframes instead.
|
||||
|
||||
eventer(messageEvent, function (e) {
|
||||
if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
|
||||
|
||||
console.log(e);
|
||||
if ("gotChat" in e.data){
|
||||
logData(e.data.gotChat.label,e.data.gotChat.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function printValues(obj) {
|
||||
var out = "";
|
||||
for (var key in obj) {
|
||||
if (typeof obj[key] === "object") {
|
||||
out += "<br />";
|
||||
out += printValues(obj[key]);
|
||||
} else {
|
||||
if (key.startsWith("_")) {
|
||||
} else {
|
||||
out += "<b>" + key + "</b>: " + obj[key] + "<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function logData(type, data) {
|
||||
var log = document.body.getElementsByTagName("ul")[0];
|
||||
var entry = document.createElement('li');
|
||||
if (type){
|
||||
type = "<i>"+type+"</i>";
|
||||
}
|
||||
entry.innerHTML = type + data;
|
||||
|
||||
//setTimeout(function(entry){ // hide message after 60 seconds
|
||||
// entry.innerHTML="";
|
||||
// entry.remove();
|
||||
// },60000,entry);
|
||||
|
||||
log.appendChild(entry);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="loadIframe();">
|
||||
<ul></ul>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
130
supports.html
@@ -37,6 +37,16 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function getChromeVersion() {
|
||||
var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
||||
return raw ? parseInt(raw[2], 10) : false;
|
||||
}
|
||||
|
||||
if (!getChromeVersion() || getChromeVersion < 60){
|
||||
alert("This tool really only works with recent Chromium based browsers; Firefox or Safari are not supported");
|
||||
}
|
||||
|
||||
function prettyPrintJsonToId(json, element) {
|
||||
var output = "<div class='prettyJson three-col'>";
|
||||
|
||||
@@ -97,13 +107,18 @@
|
||||
function changeCamera() {
|
||||
var deviceId = document.getElementById("cameraSelector").value;
|
||||
getCameraDetails(deviceId);
|
||||
|
||||
}
|
||||
|
||||
function getCameraDetails(deviceId) {
|
||||
console.log(deviceId);
|
||||
navigator.mediaDevices
|
||||
.getUserMedia({
|
||||
video: {
|
||||
deviceId: deviceId,
|
||||
deviceId: {exact: deviceId},
|
||||
zoom: true,
|
||||
pan: true,
|
||||
tilt: true
|
||||
},
|
||||
audio: false,
|
||||
})
|
||||
@@ -111,49 +126,98 @@
|
||||
console.log("worked");
|
||||
setTimeout(function () {
|
||||
mediaStream.getVideoTracks().forEach((track) => {
|
||||
const capabilities = track.getCapabilities();
|
||||
const settings = track.getSettings();
|
||||
prettyPrintSupportedOptions(capabilities, "cameraSupportedOptions");
|
||||
document
|
||||
try{
|
||||
const capabilities = track.getCapabilities();
|
||||
const settings = track.getSettings();
|
||||
prettyPrintSupportedOptions(capabilities, "cameraSupportedOptions");
|
||||
document
|
||||
.querySelectorAll(".property")
|
||||
.forEach((el) => el.classList.remove("ok"));
|
||||
|
||||
Object.entries(capabilities)
|
||||
.sort()
|
||||
.forEach(([key, value]) => {
|
||||
document.getElementById(key).classList.add("ok");
|
||||
});
|
||||
prettyPrintJsonToId(settings, "cameraSettings");
|
||||
} catch (e){
|
||||
document
|
||||
.querySelectorAll(".property")
|
||||
.forEach((el) => el.classList.remove("ok"));
|
||||
|
||||
Object.entries(capabilities)
|
||||
.sort()
|
||||
.forEach(([key, value]) => {
|
||||
document.getElementById(key).classList.add("ok");
|
||||
});
|
||||
prettyPrintJsonToId(settings, "cameraSettings");
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}).catch(function(e){
|
||||
setTimeout(function(){getCameraDetailsFallback(deviceId)},0);
|
||||
})
|
||||
}
|
||||
|
||||
function getCameraDetailsFallback(deviceId) {
|
||||
console.log(deviceId);
|
||||
navigator.mediaDevices
|
||||
.getUserMedia({
|
||||
video: {
|
||||
deviceId: deviceId
|
||||
},
|
||||
audio: false,
|
||||
})
|
||||
.then(function (mediaStream) {
|
||||
console.log("worked");
|
||||
setTimeout(function () {
|
||||
mediaStream.getVideoTracks().forEach((track) => {
|
||||
try{
|
||||
const capabilities = track.getCapabilities();
|
||||
const settings = track.getSettings();
|
||||
prettyPrintSupportedOptions(capabilities, "cameraSupportedOptions");
|
||||
document
|
||||
.querySelectorAll(".property")
|
||||
.forEach((el) => el.classList.remove("ok"));
|
||||
|
||||
Object.entries(capabilities)
|
||||
.sort()
|
||||
.forEach(([key, value]) => {
|
||||
document.getElementById(key).classList.add("ok");
|
||||
});
|
||||
prettyPrintJsonToId(settings, "cameraSettings");
|
||||
} catch (e){
|
||||
document
|
||||
.querySelectorAll(".property")
|
||||
.forEach((el) => el.classList.remove("ok"));
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
//updateDeviceList();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var supports = navigator.mediaDevices.getSupportedConstraints();
|
||||
prettyPrintJsonToId(supports, "browserSupportedOptions");
|
||||
document.getElementById("browserSupportedOptionsTitle").innerText +=
|
||||
" (" + Object.keys(supports).length + ")";
|
||||
|
||||
navigator.mediaDevices
|
||||
.enumerateDevices()
|
||||
.then(function (devices) {
|
||||
setTimeout(function () {
|
||||
console.log("Listing devices");
|
||||
devices.forEach(function (device) {
|
||||
if (device.kind == "videoinput") {
|
||||
var element = document.createElement("option");
|
||||
element.setAttribute("value", device.deviceId);
|
||||
element.innerText = device.label;
|
||||
document.getElementById("cameraSelector").appendChild(element);
|
||||
console.log(device);
|
||||
}
|
||||
});
|
||||
getCameraDetails(devices[0]);
|
||||
}, 1000);
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.log(err.name + ": " + err.message);
|
||||
});
|
||||
function updateDeviceList(){
|
||||
navigator.mediaDevices
|
||||
.enumerateDevices()
|
||||
.then(function (devices) {
|
||||
setTimeout(function (devices) {
|
||||
console.log("Listing devices");
|
||||
devices.forEach(function (device) {
|
||||
if (device.kind == "videoinput") {
|
||||
var element = document.createElement("option");
|
||||
element.setAttribute("value", device.deviceId);
|
||||
element.innerText = device.label || "No Label Available";
|
||||
document.getElementById("cameraSelector").appendChild(element);
|
||||
console.log(device);
|
||||
}
|
||||
});
|
||||
setTimeout(function(){changeCamera();},10);
|
||||
}, 1000, devices);
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.log(err.name + ": " + err.message);
|
||||
});
|
||||
}
|
||||
updateDeviceList();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
208
thirdparty/CodecsHandler.js
vendored
@@ -31,17 +31,17 @@ var CodecsHandler = (function() {
|
||||
|
||||
if (!info.videoCodecNumbers) {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
if (codecName === 'vp8' && info.vp8LineNumber === info.videoCodecNumbers[0]) {
|
||||
} else if (codecName === 'vp8' && info.vp8LineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
if (codecName === 'vp9' && info.vp9LineNumber === info.videoCodecNumbers[0]) {
|
||||
} else if (codecName === 'vp9' && info.vp9LineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
if (codecName === 'h264' && info.h264LineNumber === info.videoCodecNumbers[0]) {
|
||||
} else if (codecName === 'h264' && info.h264LineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
} else if (codecName === 'av1' && info.av1LineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
} else if (codecName === 'red' && info.redLineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
} else if (codecName === 'fec' && info.fecLineNumber === info.videoCodecNumbers[0]) {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
@@ -58,21 +58,36 @@ var CodecsHandler = (function() {
|
||||
return sdp;
|
||||
}
|
||||
preferCodecNumber = info.vp8LineNumber;
|
||||
}
|
||||
|
||||
if (codec === 'vp9') {
|
||||
|
||||
} else if (codec === 'vp9') {
|
||||
if (!info.vp9LineNumber) {
|
||||
return sdp;
|
||||
}
|
||||
preferCodecNumber = info.vp9LineNumber;
|
||||
}
|
||||
|
||||
if (codec === 'h264') {
|
||||
|
||||
} else if (codec === 'h264') {
|
||||
if (!info.h264LineNumber) {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
preferCodecNumber = info.h264LineNumber;
|
||||
|
||||
} else if (codec === 'av1') {
|
||||
if (!info.av1LineNumber) {
|
||||
return sdp;
|
||||
}
|
||||
preferCodecNumber = info.av1LineNumber;
|
||||
|
||||
} else if (codec === 'red') {
|
||||
if (!info.redLineNumber) {
|
||||
return sdp;
|
||||
}
|
||||
preferCodecNumber = info.redLineNumber;
|
||||
|
||||
} else if (codec === 'fec') {
|
||||
if (!info.fecLineNumber) {
|
||||
return sdp;
|
||||
}
|
||||
preferCodecNumber = info.fecLineNumber;
|
||||
}
|
||||
|
||||
var newLine = info.videoCodecNumbersOriginal.split('SAVPF')[0] + 'SAVPF ';
|
||||
@@ -117,6 +132,18 @@ var CodecsHandler = (function() {
|
||||
|
||||
if (line.indexOf('H264/90000') !== -1 && !info.h264LineNumber) {
|
||||
info.h264LineNumber = line.replace('a=rtpmap:', '').split(' ')[0];
|
||||
}
|
||||
|
||||
if (line.indexOf('AV1X/90000') !== -1 && !info.av1LineNumber) {
|
||||
info.av1LineNumber = line.replace('a=rtpmap:', '').split(' ')[0];
|
||||
}
|
||||
|
||||
if (line.indexOf('red/90000') !== -1 && !info.redLineNumber) {
|
||||
info.redLineNumber = line.replace('a=rtpmap:', '').split(' ')[0];
|
||||
}
|
||||
|
||||
if (line.indexOf('ulpfec/90000') !== -1 && !info.fecLineNumber) {
|
||||
info.fecLineNumber = line.replace('a=rtpmap:', '').split(' ')[0];
|
||||
}
|
||||
});
|
||||
|
||||
@@ -133,11 +160,89 @@ var CodecsHandler = (function() {
|
||||
throw 'Invalid arguments.';
|
||||
}
|
||||
|
||||
sdp = sdp.replace('a=rtcp-fb:126 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:126 nack pli\r\n', 'a=rtcp-fb:126 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:97 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:35 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:35 nack pli\r\n', 'a=rtcp-fb:35 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:96 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:96 nack pli\r\n', 'a=rtcp-fb:96 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:97 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:97 nack pli\r\n', 'a=rtcp-fb:97 pli\r\n');
|
||||
|
||||
sdp = sdp.replace('a=rtcp-fb:98 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:98 nack pli\r\n', 'a=rtcp-fb:98 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:99 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:99 nack pli\r\n', 'a=rtcp-fb:99 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:100 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:100 nack pli\r\n', 'a=rtcp-fb:100 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:102 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:102 nack pli\r\n', 'a=rtcp-fb:102 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:108 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:108 nack pli\r\n', 'a=rtcp-fb:108 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:124 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:124 nack pli\r\n', 'a=rtcp-fb:124 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:123 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:123 nack pli\r\n', 'a=rtcp-fb:123 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:125 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:125 nack pli\r\n', 'a=rtcp-fb:125 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:126 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:126 nack pli\r\n', 'a=rtcp-fb:126 pli\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:127 nack\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:127 nack pli\r\n', 'a=rtcp-fb:127 pli\r\n');
|
||||
|
||||
return sdp;
|
||||
}
|
||||
|
||||
function disableREMB(sdp) {
|
||||
if (!sdp || typeof sdp !== 'string') {
|
||||
throw 'Invalid arguments.';
|
||||
}
|
||||
sdp = sdp.replace('a=rtcp-fb:35 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:96 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:97 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:98 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:99 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:100 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:102 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:108 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:124 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:123 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:125 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:126 goog-remb\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:127 goog-remb\r\n', '');
|
||||
|
||||
return sdp;
|
||||
}
|
||||
|
||||
function disablePLI(sdp) {
|
||||
if (!sdp || typeof sdp !== 'string') {
|
||||
throw 'Invalid arguments.';
|
||||
}
|
||||
|
||||
sdp = sdp.replace('a=rtcp-fb:35 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:35 nack pli\r\n', 'a=rtcp-fb:35 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:96 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:96 nack pli\r\n', 'a=rtcp-fb:96 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:97 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:97 nack pli\r\n', 'a=rtcp-fb:97 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:98 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:98 nack pli\r\n', 'a=rtcp-fb:98 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:99 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:99 nack pli\r\n', 'a=rtcp-fb:99 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:100 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:100 nack pli\r\n', 'a=rtcp-fb:100 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:102 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:102 nack pli\r\n', 'a=rtcp-fb:102 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:108 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:108 nack pli\r\n', 'a=rtcp-fb:108 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:124 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:124 nack pli\r\n', 'a=rtcp-fb:124 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:123 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:123 nack pli\r\n', 'a=rtcp-fb:123 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:125 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:125 nack pli\r\n', 'a=rtcp-fb:125 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:126 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:126 nack pli\r\n', 'a=rtcp-fb:126 nack\r\n');
|
||||
sdp = sdp.replace('a=rtcp-fb:127 pli\r\n', '');
|
||||
sdp = sdp.replace('a=rtcp-fb:127 nack pli\r\n', 'a=rtcp-fb:127 nack\r\n');
|
||||
|
||||
return sdp;
|
||||
}
|
||||
|
||||
@@ -172,7 +277,7 @@ var CodecsHandler = (function() {
|
||||
|
||||
function getVideoBitrates(sdp) {
|
||||
|
||||
var defaultBitrate = 2500;
|
||||
var defaultBitrate = false;
|
||||
|
||||
var sdpLines = sdp.split('\r\n');
|
||||
var mLineIndex = findLine(sdpLines, 'm=', 'video');
|
||||
@@ -346,23 +451,33 @@ var CodecsHandler = (function() {
|
||||
}
|
||||
|
||||
if (typeof params.maxaveragebitrate != 'undefined') {
|
||||
appendOpusNext += ';maxaveragebitrate=' + params.maxaveragebitrate; // default 32000? (kbps)
|
||||
if (sdpLines[opusFmtpLineIndex].split("maxaveragebitrate=").length==1){
|
||||
appendOpusNext += ';maxaveragebitrate=' + params.maxaveragebitrate; // default 32000? (kbps)
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof params.maxplaybackrate != 'undefined') {
|
||||
appendOpusNext += ';maxplaybackrate=' + params.maxplaybackrate; // Default should be 48000 (hz) , 8000 to 48000 are valid options
|
||||
if (sdpLines[opusFmtpLineIndex].split("maxplaybackrate=").length==1){
|
||||
appendOpusNext += ';maxplaybackrate=' + params.maxplaybackrate; // Default should be 48000 (hz) , 8000 to 48000 are valid options
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof params.cbr != 'undefined') {
|
||||
appendOpusNext += ';cbr=' + params.cbr; // default is 0 (vbr)
|
||||
if (sdpLines[opusFmtpLineIndex].split("cbr=").length==1){
|
||||
appendOpusNext += ';cbr=' + params.cbr; // default is 0 (vbr)
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof params.useinbandfec != 'undefined') { // useful for handling packet loss
|
||||
appendOpusNext += ';useinbandfec=' + params.useinbandfec; // Defaults to 0
|
||||
if (sdpLines[opusFmtpLineIndex].split("useinbandfec=").length==1){
|
||||
appendOpusNext += ';useinbandfec=' + params.useinbandfec; // Defaults to 0
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof params.usedtx != 'undefined') { // Default is 0
|
||||
appendOpusNext += ';usedtx=' + params.usedtx; // if decoder prefers the use of DTX.
|
||||
if (sdpLines[opusFmtpLineIndex].split("usedtx=").length==1){
|
||||
appendOpusNext += ';usedtx=' + params.usedtx; // if decoder prefers the use of DTX.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -373,10 +488,47 @@ var CodecsHandler = (function() {
|
||||
|
||||
return sdp;
|
||||
}
|
||||
|
||||
|
||||
function getOpusBitrate(sdp) {
|
||||
|
||||
var sdpLines = sdp.split('\r\n');
|
||||
|
||||
var opusIndex = findLine(sdpLines, 'a=rtpmap', 'opus/48000');
|
||||
var opusPayload;
|
||||
if (opusIndex) {
|
||||
opusPayload = getCodecPayloadType(sdpLines[opusIndex]);
|
||||
}
|
||||
|
||||
if (!opusPayload) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var opusFmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + opusPayload.toString());
|
||||
if (opusFmtpLineIndex === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var appendOpusNext = '';
|
||||
|
||||
if (sdpLines[opusFmtpLineIndex].split("maxaveragebitrate=").length>1){
|
||||
var tmp = sdpLines[opusFmtpLineIndex].split("maxaveragebitrate=")[1];
|
||||
tmp = tmp.split('\r')[0];
|
||||
tmp = tmp.split('\n')[0];
|
||||
tmp = tmp.split(';')[0];
|
||||
tmp = parseInt(tmp);
|
||||
return tmp;
|
||||
}
|
||||
return 32768;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
disableNACK: disableNACK,
|
||||
|
||||
disablePLI: disablePLI,
|
||||
|
||||
disableREMB: disableREMB,
|
||||
|
||||
getVideoBitrates: function(sdp) {
|
||||
return getVideoBitrates(sdp);
|
||||
@@ -388,6 +540,10 @@ var CodecsHandler = (function() {
|
||||
setOpusAttributes: function(sdp, params) {
|
||||
return setOpusAttributes(sdp, params);
|
||||
},
|
||||
|
||||
getOpusBitrate: function(sdp){
|
||||
return getOpusBitrate(sdp);
|
||||
},
|
||||
|
||||
preferCodec: preferCodec
|
||||
};
|
||||
|
||||
1
thirdparty/adapter.min.js
vendored
1
thirdparty/tflite/README.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
The virtual-background code was initially based on the works of Google and this repo: https://github.com/Volcomix/virtual-background ; Apache-2.0 License. The Google portion was published initially with an Apache lic, although it changed to a Google Lic at a later date.
|
||||
BIN
thirdparty/tflite/segm_full_v679.tflite
vendored
Normal file
888
thirdparty/tflite/tflite-simd.js
vendored
Normal file
@@ -0,0 +1,888 @@
|
||||
var createTFLiteSIMDModule = (function() {
|
||||
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
|
||||
return (
|
||||
function(createTFLiteSIMDModule) {
|
||||
createTFLiteSIMDModule = createTFLiteSIMDModule || {};
|
||||
|
||||
var Module = typeof createTFLiteSIMDModule !== "undefined" ? createTFLiteSIMDModule : {};
|
||||
var readyPromiseResolve, readyPromiseReject;
|
||||
Module["ready"] = new Promise(function(resolve, reject) {
|
||||
readyPromiseResolve = resolve;
|
||||
readyPromiseReject = reject
|
||||
});
|
||||
var moduleOverrides = {};
|
||||
var key;
|
||||
for (key in Module) {
|
||||
if (Module.hasOwnProperty(key)) {
|
||||
moduleOverrides[key] = Module[key]
|
||||
}
|
||||
}
|
||||
var arguments_ = [];
|
||||
var thisProgram = "./this.program";
|
||||
var quit_ = function(status, toThrow) {
|
||||
throw toThrow
|
||||
};
|
||||
|
||||
var scriptDirectory = "";
|
||||
|
||||
function locateFile(path) {
|
||||
if (Module["locateFile"]) {
|
||||
return Module["locateFile"](path, scriptDirectory)
|
||||
}
|
||||
return scriptDirectory + path
|
||||
}
|
||||
var read_, readAsync, readBinary;
|
||||
|
||||
if (typeof document !== "undefined" && document.currentScript) {
|
||||
scriptDirectory = document.currentScript.src
|
||||
}
|
||||
|
||||
if (_scriptDir) {
|
||||
scriptDirectory = _scriptDir
|
||||
}
|
||||
if (scriptDirectory.indexOf("blob:") !== 0) {
|
||||
scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf("/") + 1)
|
||||
} else {
|
||||
scriptDirectory = ""
|
||||
} {
|
||||
read_ = function(url) {
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("GET", url, false);
|
||||
xhr.send(null);
|
||||
return xhr.responseText
|
||||
};
|
||||
|
||||
readAsync = function(url, onload, onerror) {
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("GET", url, true);
|
||||
xhr.responseType = "arraybuffer";
|
||||
xhr.onload = function() {
|
||||
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
||||
onload(xhr.response);
|
||||
return
|
||||
}
|
||||
onerror()
|
||||
};
|
||||
xhr.onerror = onerror;
|
||||
xhr.send(null)
|
||||
}
|
||||
}
|
||||
|
||||
var out = Module["print"] || console.log.bind(console);
|
||||
var err = Module["printErr"] || console.warn.bind(console);
|
||||
for (key in moduleOverrides) {
|
||||
if (moduleOverrides.hasOwnProperty(key)) {
|
||||
Module[key] = moduleOverrides[key]
|
||||
}
|
||||
}
|
||||
moduleOverrides = null;
|
||||
if (Module["arguments"]) arguments_ = Module["arguments"];
|
||||
if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
|
||||
if (Module["quit"]) quit_ = Module["quit"];
|
||||
var wasmBinary;
|
||||
if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"];
|
||||
var noExitRuntime;
|
||||
if (Module["noExitRuntime"]) noExitRuntime = Module["noExitRuntime"];
|
||||
if (typeof WebAssembly !== "object") {
|
||||
abort("no native wasm support detected")
|
||||
}
|
||||
var wasmMemory;
|
||||
var ABORT = false;
|
||||
var EXITSTATUS;
|
||||
|
||||
function assert(condition, text) {
|
||||
if (!condition) {
|
||||
abort("Assertion failed: " + text)
|
||||
}
|
||||
}
|
||||
var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : undefined;
|
||||
|
||||
function UTF8ArrayToString(heap, idx, maxBytesToRead) {
|
||||
var endIdx = idx + maxBytesToRead;
|
||||
var endPtr = idx;
|
||||
while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
|
||||
if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
|
||||
return UTF8Decoder.decode(heap.subarray(idx, endPtr))
|
||||
} else {
|
||||
var str = "";
|
||||
while (idx < endPtr) {
|
||||
var u0 = heap[idx++];
|
||||
if (!(u0 & 128)) {
|
||||
str += String.fromCharCode(u0);
|
||||
continue
|
||||
}
|
||||
var u1 = heap[idx++] & 63;
|
||||
if ((u0 & 224) == 192) {
|
||||
str += String.fromCharCode((u0 & 31) << 6 | u1);
|
||||
continue
|
||||
}
|
||||
var u2 = heap[idx++] & 63;
|
||||
if ((u0 & 240) == 224) {
|
||||
u0 = (u0 & 15) << 12 | u1 << 6 | u2
|
||||
} else {
|
||||
u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63
|
||||
}
|
||||
if (u0 < 65536) {
|
||||
str += String.fromCharCode(u0)
|
||||
} else {
|
||||
var ch = u0 - 65536;
|
||||
str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023)
|
||||
}
|
||||
}
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
function UTF8ToString(ptr, maxBytesToRead) {
|
||||
return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""
|
||||
}
|
||||
|
||||
function writeAsciiToMemory(str, buffer, dontAddNull) {
|
||||
for (var i = 0; i < str.length; ++i) {
|
||||
HEAP8[buffer++ >> 0] = str.charCodeAt(i)
|
||||
}
|
||||
if (!dontAddNull) HEAP8[buffer >> 0] = 0
|
||||
}
|
||||
|
||||
function alignUp(x, multiple) {
|
||||
if (x % multiple > 0) {
|
||||
x += multiple - x % multiple
|
||||
}
|
||||
return x
|
||||
}
|
||||
var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
|
||||
|
||||
function updateGlobalBufferAndViews(buf) {
|
||||
buffer = buf;
|
||||
Module["HEAP8"] = HEAP8 = new Int8Array(buf);
|
||||
Module["HEAP16"] = HEAP16 = new Int16Array(buf);
|
||||
Module["HEAP32"] = HEAP32 = new Int32Array(buf);
|
||||
Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf);
|
||||
Module["HEAPU16"] = HEAPU16 = new Uint16Array(buf);
|
||||
Module["HEAPU32"] = HEAPU32 = new Uint32Array(buf);
|
||||
Module["HEAPF32"] = HEAPF32 = new Float32Array(buf);
|
||||
Module["HEAPF64"] = HEAPF64 = new Float64Array(buf)
|
||||
}
|
||||
var INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 16777216;
|
||||
var wasmTable;
|
||||
var __ATPRERUN__ = [];
|
||||
var __ATINIT__ = [];
|
||||
var __ATMAIN__ = [];
|
||||
var __ATPOSTRUN__ = [];
|
||||
var runtimeInitialized = false;
|
||||
var runtimeExited = false;
|
||||
__ATINIT__.push({
|
||||
func: function() {
|
||||
___wasm_call_ctors()
|
||||
}
|
||||
});
|
||||
|
||||
function preRun() {
|
||||
if (Module["preRun"]) {
|
||||
if (typeof Module["preRun"] == "function") Module["preRun"] = [Module["preRun"]];
|
||||
while (Module["preRun"].length) {
|
||||
addOnPreRun(Module["preRun"].shift())
|
||||
}
|
||||
}
|
||||
callRuntimeCallbacks(__ATPRERUN__)
|
||||
}
|
||||
|
||||
function initRuntime() {
|
||||
runtimeInitialized = true;
|
||||
callRuntimeCallbacks(__ATINIT__)
|
||||
}
|
||||
|
||||
function preMain() {
|
||||
callRuntimeCallbacks(__ATMAIN__)
|
||||
}
|
||||
|
||||
function exitRuntime() {
|
||||
runtimeExited = true
|
||||
}
|
||||
|
||||
function postRun() {
|
||||
if (Module["postRun"]) {
|
||||
if (typeof Module["postRun"] == "function") Module["postRun"] = [Module["postRun"]];
|
||||
while (Module["postRun"].length) {
|
||||
addOnPostRun(Module["postRun"].shift())
|
||||
}
|
||||
}
|
||||
callRuntimeCallbacks(__ATPOSTRUN__)
|
||||
}
|
||||
|
||||
function addOnPreRun(cb) {
|
||||
__ATPRERUN__.unshift(cb)
|
||||
}
|
||||
|
||||
function addOnPostRun(cb) {
|
||||
__ATPOSTRUN__.unshift(cb)
|
||||
}
|
||||
var runDependencies = 0;
|
||||
var runDependencyWatcher = null;
|
||||
var dependenciesFulfilled = null;
|
||||
|
||||
function addRunDependency(id) {
|
||||
runDependencies++;
|
||||
if (Module["monitorRunDependencies"]) {
|
||||
Module["monitorRunDependencies"](runDependencies)
|
||||
}
|
||||
}
|
||||
|
||||
function removeRunDependency(id) {
|
||||
runDependencies--;
|
||||
if (Module["monitorRunDependencies"]) {
|
||||
Module["monitorRunDependencies"](runDependencies)
|
||||
}
|
||||
if (runDependencies == 0) {
|
||||
if (runDependencyWatcher !== null) {
|
||||
clearInterval(runDependencyWatcher);
|
||||
runDependencyWatcher = null
|
||||
}
|
||||
if (dependenciesFulfilled) {
|
||||
var callback = dependenciesFulfilled;
|
||||
dependenciesFulfilled = null;
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
Module["preloadedImages"] = {};
|
||||
Module["preloadedAudios"] = {};
|
||||
|
||||
function abort(what) {
|
||||
if (Module["onAbort"]) {
|
||||
Module["onAbort"](what)
|
||||
}
|
||||
what += "";
|
||||
err(what);
|
||||
ABORT = true;
|
||||
EXITSTATUS = 1;
|
||||
what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info.";
|
||||
var e = new WebAssembly.RuntimeError(what);
|
||||
readyPromiseReject(e);
|
||||
throw e
|
||||
}
|
||||
|
||||
function hasPrefix(str, prefix) {
|
||||
return String.prototype.startsWith ? str.startsWith(prefix) : str.indexOf(prefix) === 0
|
||||
}
|
||||
var dataURIPrefix = "data:application/octet-stream;base64,";
|
||||
|
||||
function isDataURI(filename) {
|
||||
return hasPrefix(filename, dataURIPrefix)
|
||||
}
|
||||
var fileURIPrefix = "file://";
|
||||
|
||||
function isFileURI(filename) {
|
||||
return hasPrefix(filename, fileURIPrefix)
|
||||
}
|
||||
var wasmBinaryFile = "tflite-simd.wasm";
|
||||
createTFLiteSIMDModule.simd = true;
|
||||
|
||||
if (!isDataURI(wasmBinaryFile)) {
|
||||
wasmBinaryFile = locateFile(wasmBinaryFile)
|
||||
}
|
||||
|
||||
function getBinary(file) {
|
||||
try {
|
||||
if (file == wasmBinaryFile && wasmBinary) {
|
||||
return new Uint8Array(wasmBinary)
|
||||
}
|
||||
if (readBinary) {
|
||||
return readBinary(file)
|
||||
} else {
|
||||
throw "both async and sync fetching of the wasm failed"
|
||||
}
|
||||
} catch (err) {
|
||||
abort(err)
|
||||
}
|
||||
}
|
||||
|
||||
function getBinaryPromise() {
|
||||
if (!wasmBinary) {
|
||||
if (typeof fetch === "function" && !isFileURI(wasmBinaryFile)) {
|
||||
return fetch(wasmBinaryFile, {
|
||||
credentials: "same-origin"
|
||||
}).then(function(response) {
|
||||
if (!response["ok"]) {
|
||||
throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"
|
||||
}
|
||||
return response["arrayBuffer"]()
|
||||
}).catch(function() {
|
||||
return getBinary(wasmBinaryFile)
|
||||
})
|
||||
} else {
|
||||
if (readAsync) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
readAsync(wasmBinaryFile, function(response) {
|
||||
resolve(new Uint8Array(response))
|
||||
}, reject)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return Promise.resolve().then(function() {
|
||||
return getBinary(wasmBinaryFile)
|
||||
})
|
||||
}
|
||||
|
||||
function createWasm() {
|
||||
var info = {
|
||||
"a": asmLibraryArg
|
||||
};
|
||||
|
||||
function receiveInstance(instance, module) {
|
||||
var exports = instance.exports;
|
||||
Module["asm"] = exports;
|
||||
wasmMemory = Module["asm"]["q"];
|
||||
updateGlobalBufferAndViews(wasmMemory.buffer);
|
||||
wasmTable = Module["asm"]["D"];
|
||||
removeRunDependency("wasm-instantiate")
|
||||
}
|
||||
addRunDependency("wasm-instantiate");
|
||||
|
||||
function receiveInstantiatedSource(output) {
|
||||
receiveInstance(output["instance"])
|
||||
}
|
||||
|
||||
function instantiateArrayBuffer(receiver) {
|
||||
return getBinaryPromise().then(function(binary) {
|
||||
return WebAssembly.instantiate(binary, info)
|
||||
}).then(receiver, function(reason) {
|
||||
if (createTFLiteSIMDModule.simd){
|
||||
wasmBinaryFile = "tflite.wasm";
|
||||
createTFLiteSIMDModule.simd = false;
|
||||
if (!isDataURI(wasmBinaryFile)) {
|
||||
wasmBinaryFile = locateFile(wasmBinaryFile)
|
||||
}
|
||||
instantiateAsync();
|
||||
} else {
|
||||
console.error("FAILED LOADING WASM TFLITE MODEL");
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function instantiateAsync() {
|
||||
return instantiateArrayBuffer(receiveInstantiatedSource)
|
||||
}
|
||||
if (Module["instantiateWasm"]) {
|
||||
try {
|
||||
var exports = Module["instantiateWasm"](info, receiveInstance);
|
||||
return exports
|
||||
} catch (e) {
|
||||
err("Module.instantiateWasm callback failed with error: " + e);
|
||||
return false
|
||||
}
|
||||
}
|
||||
instantiateAsync().catch(readyPromiseReject);
|
||||
return {}
|
||||
}
|
||||
|
||||
function callRuntimeCallbacks(callbacks) {
|
||||
while (callbacks.length > 0) {
|
||||
var callback = callbacks.shift();
|
||||
if (typeof callback == "function") {
|
||||
callback(Module);
|
||||
continue
|
||||
}
|
||||
var func = callback.func;
|
||||
if (typeof func === "number") {
|
||||
if (callback.arg === undefined) {
|
||||
wasmTable.get(func)()
|
||||
} else {
|
||||
wasmTable.get(func)(callback.arg)
|
||||
}
|
||||
} else {
|
||||
func(callback.arg === undefined ? null : callback.arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _abort() {
|
||||
abort()
|
||||
}
|
||||
var _emscripten_get_now;
|
||||
if (typeof dateNow !== "undefined") {
|
||||
_emscripten_get_now = dateNow
|
||||
} else _emscripten_get_now = function() {
|
||||
return performance.now()
|
||||
};
|
||||
var _emscripten_get_now_is_monotonic = true;
|
||||
|
||||
function setErrNo(value) {
|
||||
HEAP32[___errno_location() >> 2] = value;
|
||||
return value
|
||||
}
|
||||
|
||||
function _clock_gettime(clk_id, tp) {
|
||||
var now;
|
||||
if (clk_id === 0) {
|
||||
now = Date.now()
|
||||
} else if ((clk_id === 1 || clk_id === 4) && _emscripten_get_now_is_monotonic) {
|
||||
now = _emscripten_get_now()
|
||||
} else {
|
||||
setErrNo(28);
|
||||
return -1
|
||||
}
|
||||
HEAP32[tp >> 2] = now / 1e3 | 0;
|
||||
HEAP32[tp + 4 >> 2] = now % 1e3 * 1e3 * 1e3 | 0;
|
||||
return 0
|
||||
}
|
||||
|
||||
function _dlopen(filename, flag) {
|
||||
abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking")
|
||||
}
|
||||
|
||||
function _dlsym(handle, symbol) {
|
||||
abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking")
|
||||
}
|
||||
|
||||
function _emscripten_memcpy_big(dest, src, num) {
|
||||
HEAPU8.copyWithin(dest, src, src + num)
|
||||
}
|
||||
|
||||
function _emscripten_get_heap_size() {
|
||||
return HEAPU8.length
|
||||
}
|
||||
|
||||
function emscripten_realloc_buffer(size) {
|
||||
try {
|
||||
wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16);
|
||||
updateGlobalBufferAndViews(wasmMemory.buffer);
|
||||
return 1
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function _emscripten_resize_heap(requestedSize) {
|
||||
requestedSize = requestedSize >>> 0;
|
||||
var oldSize = _emscripten_get_heap_size();
|
||||
var maxHeapSize = 2147483648;
|
||||
if (requestedSize > maxHeapSize) {
|
||||
return false
|
||||
}
|
||||
var minHeapSize = 16777216;
|
||||
for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
|
||||
var overGrownHeapSize = oldSize * (1 + .2 / cutDown);
|
||||
overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
|
||||
var newSize = Math.min(maxHeapSize, alignUp(Math.max(minHeapSize, requestedSize, overGrownHeapSize), 65536));
|
||||
var replacement = emscripten_realloc_buffer(newSize);
|
||||
if (replacement) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function _emscripten_thread_sleep(msecs) {
|
||||
var start = _emscripten_get_now();
|
||||
while (_emscripten_get_now() - start < msecs) {}
|
||||
}
|
||||
var ENV = {};
|
||||
|
||||
function getExecutableName() {
|
||||
return thisProgram || "./this.program"
|
||||
}
|
||||
|
||||
function getEnvStrings() {
|
||||
if (!getEnvStrings.strings) {
|
||||
var lang = (typeof navigator === "object" && navigator.languages && navigator.languages[0] || "C").replace("-", "_") + ".UTF-8";
|
||||
var env = {
|
||||
"USER": "web_user",
|
||||
"LOGNAME": "web_user",
|
||||
"PATH": "/",
|
||||
"PWD": "/",
|
||||
"HOME": "/home/web_user",
|
||||
"LANG": lang,
|
||||
"_": getExecutableName()
|
||||
};
|
||||
for (var x in ENV) {
|
||||
env[x] = ENV[x]
|
||||
}
|
||||
var strings = [];
|
||||
for (var x in env) {
|
||||
strings.push(x + "=" + env[x])
|
||||
}
|
||||
getEnvStrings.strings = strings
|
||||
}
|
||||
return getEnvStrings.strings
|
||||
}
|
||||
var SYSCALLS = {
|
||||
mappings: {},
|
||||
buffers: [null, [],
|
||||
[]
|
||||
],
|
||||
printChar: function(stream, curr) {
|
||||
var buffer = SYSCALLS.buffers[stream];
|
||||
if (curr === 0 || curr === 10) {
|
||||
(stream === 1 ? out : err)(UTF8ArrayToString(buffer, 0));
|
||||
buffer.length = 0
|
||||
} else {
|
||||
buffer.push(curr)
|
||||
}
|
||||
},
|
||||
varargs: undefined,
|
||||
get: function() {
|
||||
SYSCALLS.varargs += 4;
|
||||
var ret = HEAP32[SYSCALLS.varargs - 4 >> 2];
|
||||
return ret
|
||||
},
|
||||
getStr: function(ptr) {
|
||||
var ret = UTF8ToString(ptr);
|
||||
return ret
|
||||
},
|
||||
get64: function(low, high) {
|
||||
return low
|
||||
}
|
||||
};
|
||||
|
||||
function _environ_get(__environ, environ_buf) {
|
||||
var bufSize = 0;
|
||||
getEnvStrings().forEach(function(string, i) {
|
||||
var ptr = environ_buf + bufSize;
|
||||
HEAP32[__environ + i * 4 >> 2] = ptr;
|
||||
writeAsciiToMemory(string, ptr);
|
||||
bufSize += string.length + 1
|
||||
});
|
||||
return 0
|
||||
}
|
||||
|
||||
function _environ_sizes_get(penviron_count, penviron_buf_size) {
|
||||
var strings = getEnvStrings();
|
||||
HEAP32[penviron_count >> 2] = strings.length;
|
||||
var bufSize = 0;
|
||||
strings.forEach(function(string) {
|
||||
bufSize += string.length + 1
|
||||
});
|
||||
HEAP32[penviron_buf_size >> 2] = bufSize;
|
||||
return 0
|
||||
}
|
||||
|
||||
function _exit(status) {
|
||||
exit(status)
|
||||
}
|
||||
|
||||
function _fd_close(fd) {
|
||||
return 0
|
||||
}
|
||||
|
||||
function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {}
|
||||
|
||||
function _fd_write(fd, iov, iovcnt, pnum) {
|
||||
var num = 0;
|
||||
for (var i = 0; i < iovcnt; i++) {
|
||||
var ptr = HEAP32[iov + i * 8 >> 2];
|
||||
var len = HEAP32[iov + (i * 8 + 4) >> 2];
|
||||
for (var j = 0; j < len; j++) {
|
||||
SYSCALLS.printChar(fd, HEAPU8[ptr + j])
|
||||
}
|
||||
num += len
|
||||
}
|
||||
HEAP32[pnum >> 2] = num;
|
||||
return 0
|
||||
}
|
||||
|
||||
function _pthread_create() {
|
||||
return 6
|
||||
}
|
||||
|
||||
function _pthread_join() {
|
||||
return 28
|
||||
}
|
||||
|
||||
function _sysconf(name) {
|
||||
switch (name) {
|
||||
case 30:
|
||||
return 16384;
|
||||
case 85:
|
||||
var maxHeapSize = 2147483648;
|
||||
return maxHeapSize / 16384;
|
||||
case 132:
|
||||
case 133:
|
||||
case 12:
|
||||
case 137:
|
||||
case 138:
|
||||
case 15:
|
||||
case 235:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 149:
|
||||
case 13:
|
||||
case 10:
|
||||
case 236:
|
||||
case 153:
|
||||
case 9:
|
||||
case 21:
|
||||
case 22:
|
||||
case 159:
|
||||
case 154:
|
||||
case 14:
|
||||
case 77:
|
||||
case 78:
|
||||
case 139:
|
||||
case 82:
|
||||
case 68:
|
||||
case 67:
|
||||
case 164:
|
||||
case 11:
|
||||
case 29:
|
||||
case 47:
|
||||
case 48:
|
||||
case 95:
|
||||
case 52:
|
||||
case 51:
|
||||
case 46:
|
||||
return 200809;
|
||||
case 27:
|
||||
case 246:
|
||||
case 127:
|
||||
case 128:
|
||||
case 23:
|
||||
case 24:
|
||||
case 160:
|
||||
case 161:
|
||||
case 181:
|
||||
case 182:
|
||||
case 242:
|
||||
case 183:
|
||||
case 184:
|
||||
case 243:
|
||||
case 244:
|
||||
case 245:
|
||||
case 165:
|
||||
case 178:
|
||||
case 179:
|
||||
case 49:
|
||||
case 50:
|
||||
case 168:
|
||||
case 169:
|
||||
case 175:
|
||||
case 170:
|
||||
case 171:
|
||||
case 172:
|
||||
case 97:
|
||||
case 76:
|
||||
case 32:
|
||||
case 173:
|
||||
case 35:
|
||||
case 80:
|
||||
case 81:
|
||||
case 79:
|
||||
return -1;
|
||||
case 176:
|
||||
case 177:
|
||||
case 7:
|
||||
case 155:
|
||||
case 8:
|
||||
case 157:
|
||||
case 125:
|
||||
case 126:
|
||||
case 92:
|
||||
case 93:
|
||||
case 129:
|
||||
case 130:
|
||||
case 131:
|
||||
case 94:
|
||||
case 91:
|
||||
return 1;
|
||||
case 74:
|
||||
case 60:
|
||||
case 69:
|
||||
case 70:
|
||||
case 4:
|
||||
return 1024;
|
||||
case 31:
|
||||
case 42:
|
||||
case 72:
|
||||
return 32;
|
||||
case 87:
|
||||
case 26:
|
||||
case 33:
|
||||
return 2147483647;
|
||||
case 34:
|
||||
case 1:
|
||||
return 47839;
|
||||
case 38:
|
||||
case 36:
|
||||
return 99;
|
||||
case 43:
|
||||
case 37:
|
||||
return 2048;
|
||||
case 0:
|
||||
return 2097152;
|
||||
case 3:
|
||||
return 65536;
|
||||
case 28:
|
||||
return 32768;
|
||||
case 44:
|
||||
return 32767;
|
||||
case 75:
|
||||
return 16384;
|
||||
case 39:
|
||||
return 1e3;
|
||||
case 89:
|
||||
return 700;
|
||||
case 71:
|
||||
return 256;
|
||||
case 40:
|
||||
return 255;
|
||||
case 2:
|
||||
return 100;
|
||||
case 180:
|
||||
return 64;
|
||||
case 25:
|
||||
return 20;
|
||||
case 5:
|
||||
return 16;
|
||||
case 6:
|
||||
return 6;
|
||||
case 73:
|
||||
return 4;
|
||||
case 84: {
|
||||
if (typeof navigator === "object") return navigator["hardwareConcurrency"] || 1;
|
||||
return 1
|
||||
}
|
||||
}
|
||||
setErrNo(28);
|
||||
return -1
|
||||
}
|
||||
var asmLibraryArg = {
|
||||
"a": _abort,
|
||||
"n": _clock_gettime,
|
||||
"i": _dlopen,
|
||||
"e": _dlsym,
|
||||
"l": _emscripten_memcpy_big,
|
||||
"m": _emscripten_resize_heap,
|
||||
"o": _emscripten_thread_sleep,
|
||||
"p": _environ_get,
|
||||
"g": _environ_sizes_get,
|
||||
"j": _exit,
|
||||
"h": _fd_close,
|
||||
"k": _fd_seek,
|
||||
"c": _fd_write,
|
||||
"d": _pthread_create,
|
||||
"f": _pthread_join,
|
||||
"b": _sysconf
|
||||
};
|
||||
var asm = createWasm();
|
||||
var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
|
||||
return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["r"]).apply(null, arguments)
|
||||
};
|
||||
var _getModelBufferMemoryOffset = Module["_getModelBufferMemoryOffset"] = function() {
|
||||
return (_getModelBufferMemoryOffset = Module["_getModelBufferMemoryOffset"] = Module["asm"]["s"]).apply(null, arguments)
|
||||
};
|
||||
var _getInputMemoryOffset = Module["_getInputMemoryOffset"] = function() {
|
||||
return (_getInputMemoryOffset = Module["_getInputMemoryOffset"] = Module["asm"]["t"]).apply(null, arguments)
|
||||
};
|
||||
var _getInputHeight = Module["_getInputHeight"] = function() {
|
||||
return (_getInputHeight = Module["_getInputHeight"] = Module["asm"]["u"]).apply(null, arguments)
|
||||
};
|
||||
var _getInputWidth = Module["_getInputWidth"] = function() {
|
||||
return (_getInputWidth = Module["_getInputWidth"] = Module["asm"]["v"]).apply(null, arguments)
|
||||
};
|
||||
var _getInputChannelCount = Module["_getInputChannelCount"] = function() {
|
||||
return (_getInputChannelCount = Module["_getInputChannelCount"] = Module["asm"]["w"]).apply(null, arguments)
|
||||
};
|
||||
var _getOutputMemoryOffset = Module["_getOutputMemoryOffset"] = function() {
|
||||
return (_getOutputMemoryOffset = Module["_getOutputMemoryOffset"] = Module["asm"]["x"]).apply(null, arguments)
|
||||
};
|
||||
var _getOutputHeight = Module["_getOutputHeight"] = function() {
|
||||
return (_getOutputHeight = Module["_getOutputHeight"] = Module["asm"]["y"]).apply(null, arguments)
|
||||
};
|
||||
var _getOutputWidth = Module["_getOutputWidth"] = function() {
|
||||
return (_getOutputWidth = Module["_getOutputWidth"] = Module["asm"]["z"]).apply(null, arguments)
|
||||
};
|
||||
var _getOutputChannelCount = Module["_getOutputChannelCount"] = function() {
|
||||
return (_getOutputChannelCount = Module["_getOutputChannelCount"] = Module["asm"]["A"]).apply(null, arguments)
|
||||
};
|
||||
var _loadModel = Module["_loadModel"] = function() {
|
||||
return (_loadModel = Module["_loadModel"] = Module["asm"]["B"]).apply(null, arguments)
|
||||
};
|
||||
var _runInference = Module["_runInference"] = function() {
|
||||
return (_runInference = Module["_runInference"] = Module["asm"]["C"]).apply(null, arguments)
|
||||
};
|
||||
var ___errno_location = Module["___errno_location"] = function() {
|
||||
return (___errno_location = Module["___errno_location"] = Module["asm"]["E"]).apply(null, arguments)
|
||||
};
|
||||
var calledRun;
|
||||
|
||||
function ExitStatus(status) {
|
||||
this.name = "ExitStatus";
|
||||
this.message = "Program terminated with exit(" + status + ")";
|
||||
this.status = status
|
||||
}
|
||||
dependenciesFulfilled = function runCaller() {
|
||||
if (!calledRun) run();
|
||||
if (!calledRun) dependenciesFulfilled = runCaller
|
||||
};
|
||||
|
||||
function run(args) {
|
||||
args = args || arguments_;
|
||||
if (runDependencies > 0) {
|
||||
return
|
||||
}
|
||||
preRun();
|
||||
if (runDependencies > 0) {
|
||||
return
|
||||
}
|
||||
|
||||
function doRun() {
|
||||
if (calledRun) return;
|
||||
calledRun = true;
|
||||
Module["calledRun"] = true;
|
||||
if (ABORT) return;
|
||||
initRuntime();
|
||||
preMain();
|
||||
readyPromiseResolve(Module);
|
||||
if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"]();
|
||||
postRun()
|
||||
}
|
||||
if (Module["setStatus"]) {
|
||||
Module["setStatus"]("Running...");
|
||||
setTimeout(function() {
|
||||
setTimeout(function() {
|
||||
Module["setStatus"]("")
|
||||
}, 1);
|
||||
doRun()
|
||||
}, 1)
|
||||
} else {
|
||||
doRun()
|
||||
}
|
||||
}
|
||||
Module["run"] = run;
|
||||
|
||||
function exit(status, implicit) {
|
||||
if (implicit && noExitRuntime && status === 0) {
|
||||
return
|
||||
}
|
||||
if (noExitRuntime) {} else {
|
||||
EXITSTATUS = status;
|
||||
exitRuntime();
|
||||
if (Module["onExit"]) Module["onExit"](status);
|
||||
ABORT = true
|
||||
}
|
||||
quit_(status, new ExitStatus(status))
|
||||
}
|
||||
if (Module["preInit"]) {
|
||||
if (typeof Module["preInit"] == "function") Module["preInit"] = [Module["preInit"]];
|
||||
while (Module["preInit"].length > 0) {
|
||||
Module["preInit"].pop()()
|
||||
}
|
||||
}
|
||||
noExitRuntime = true;
|
||||
run();
|
||||
|
||||
|
||||
return createTFLiteSIMDModule.ready
|
||||
}
|
||||
);
|
||||
})();
|
||||
if (typeof exports === 'object' && typeof module === 'object')
|
||||
module.exports = createTFLiteSIMDModule;
|
||||
else if (typeof define === 'function' && define['amd'])
|
||||
define([], function() {
|
||||
return createTFLiteSIMDModule;
|
||||
});
|
||||
else if (typeof exports === 'object')
|
||||
exports["createTFLiteSIMDModule"] = createTFLiteSIMDModule;
|
||||
BIN
thirdparty/tflite/tflite-simd.wasm
vendored
Normal file
BIN
thirdparty/tflite/tflite.wasm
vendored
Normal file
@@ -2,11 +2,13 @@
|
||||
"titles": {
|
||||
"join-by-room-name-here": "Enter a room name to quick join",
|
||||
"join-room": "Join room",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"toggle-the-chat": "Toggle the Chat",
|
||||
"mute-the-speaker": "Mute the Speaker",
|
||||
"mute-the-mic": "Mute the Mic",
|
||||
"disable-the-camera": "Disable the Camera",
|
||||
"share-a-screen-with-others": "Share a Screen with others",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"settings": "Settings",
|
||||
"hangup-the-call": "Hangup the Call",
|
||||
"alert-the-host-you-want-to-speak": "Alert the host you want to speak",
|
||||
@@ -15,12 +17,17 @@
|
||||
"submit-any-error-logs": "Submit any error logs",
|
||||
"show-help-info": "Show Help Info",
|
||||
"language-options": "Language Options",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"add-group-chat-to-obs": "Add Group Chat",
|
||||
"for-large-group-rooms-this-option-can-reduce-the-load-on-remote-guests-substantially": "For large group rooms, this option can reduce the load on remote guests substantially",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"which-video-codec-would-you-want-used-by-default-": "Which video codec would you want used by default?",
|
||||
"you-ll-enter-as-the-room-s-director": "You'll enter as the room's director",
|
||||
"add-your-camera-to-obs": "Add your Camera",
|
||||
"start-streaming": "start streaming",
|
||||
"tip-hold-ctrl-command-to-select-multiple": "tip: Hold CTRL (command) to select Multiple",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"remote-screenshare-into-obs": "Remote Screenshare",
|
||||
"create-reusable-invite": "Create Reusable Invite",
|
||||
"ideal-for-1080p60-gaming-if-your-computer-and-upload-are-up-for-it": "Ideal for 1080p60 gaming, if your computer and upload are up for it",
|
||||
@@ -39,48 +46,83 @@
|
||||
"creative-commons-by-3-0": "Creative Commons BY 3.0",
|
||||
"youtube-video-demoing-how-to-do-this": "Youtube Video demoing how to do this",
|
||||
"invite-a-guest-or-camera-source-to-publish-into-the-group-room": "Invite a guest or camera source to publish into the group room",
|
||||
"if-enabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If enabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Use this link in the a Browser Source to capture the video or audio",
|
||||
"if-enabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If enabled, you must manually add a video to a scene for it to appear.",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Use this link as a browser source in your Studio software to capture the video or audio",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"disables-echo-cancellation-and-improves-audio-quality": "Disables Echo Cancellation and improves audio quality",
|
||||
"audio-only-sources-are-visually-hidden-from-scenes": "Audio-only sources are visually hidden from scenes",
|
||||
"guest-will-be-prompted-to-enter-a-display-name": "Guest will be prompted to enter a Display Name",
|
||||
"display-names-will-be-shown-in-the-bottom-left-corner-of-videos": "Display Names will be shown in the bottom-left corner of videos",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"request-1080p60-from-the-guest-instead-of-720p60-if-possible": "Request 1080p60 from the Guest instead of 720p60, if possible",
|
||||
"the-default-microphone-will-be-pre-selected-for-the-guest": "The default microphone will be pre-selected for the guest",
|
||||
"the-default-camera-device-will-selected-automatically": "The default camera device will selected automatically",
|
||||
"the-guest-won-t-have-access-to-changing-camera-settings-or-screenshare": "The guest won't have access to changing camera settings or screenshare",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-see-their-own-self-preview-after-joining": "The guest will not see their own self-preview after joining",
|
||||
"guests-will-have-an-option-to-poke-the-director-by-pressing-a-button": "Guests will have an option to poke the Director by pressing a button",
|
||||
"add-an-audio-compressor-to-the-guest-s-microphone": "Add an audio compressor to the guest's microphone",
|
||||
"add-an-equalizer-to-the-guest-s-microphone-that-the-director-can-control": "Add an Equalizer to the guest's microphone that the director can control",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-guest-can-only-see-the-director-s-video-if-provided": "The guest can only see the Director's video, if provided",
|
||||
"the-guest-s-microphone-will-be-muted-on-joining-they-can-unmute-themselves-": "The guest's microphone will be muted on joining. They can unmute themselves.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"have-the-guest-join-muted-so-only-the-director-can-unmute-the-guest-": "Have the guest join muted, so only the director can Unmute the guest.",
|
||||
"make-the-invite-url-encoded-so-parameters-are-harder-to-tinker-with-by-guests": "Make the invite URL encoded, so parameters are harder to tinker with by guests",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"move-the-user-to-another-room-controlled-by-another-director": "Move the user to another room, controlled by another director",
|
||||
"send-a-direct-message-to-this-user-": "Send a Direct Message to this user.",
|
||||
"add-this-video-to-any-remote-scene-1-": "Add this Video to any remote '&scene=1'",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Remotely Mute this Audio in all remote '&scene' views",
|
||||
"remotely-change-the-volume-of-this-guest": "Remotely change the volume of this guest",
|
||||
"mute-this-guest-everywhere": "Mute this guest everywhere",
|
||||
"disable-video-preview": "Disable Video Preview",
|
||||
"low-quality-preview": "Low-Quality Preview",
|
||||
"high-quality-preview": "High-Quality Preview",
|
||||
"force-the-user-to-disconnect-they-can-always-reconnect-": "Force the user to Disconnect. They can always reconnect.",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Start Recording this remote stream to this local drive. *experimental*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "The Remote Guest will record their local stream to their local drive. *experimental*",
|
||||
"toggle-voice-chat-with-this-guest": "Toggle Voice Chat with this Guest",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-this-video-to-any-remote-scene-1-": "Add this Video to any remote '&scene=1'",
|
||||
"mute-this-guest-everywhere": "Mute this guest everywhere",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Remotely Mute this Audio in all remote '&scene' views",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"add-to-scene-8": "Add to Scene 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"shift-this-video-down-in-order": "Shift this Video Down in Order",
|
||||
"current-index-order-of-this-video": "Current Index Order of this Video",
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Start Recording this remote stream to this local drive. *experimental*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "The Remote Guest will record their local stream to their local drive. *experimental*",
|
||||
"remotely-change-the-volume-of-this-guest": "Remotely change the volume of this guest",
|
||||
"disable-video-preview": "Disable Video Preview",
|
||||
"low-quality-preview": "Low-Quality Preview",
|
||||
"high-quality-preview": "High-Quality Preview",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\"></font>",
|
||||
"copy-this-url": "Copy this URL into a \"Browser Source\"",
|
||||
"copy-this-url": "Copy this URL into your studio's \"browser Source\"",
|
||||
"you-are-in-the-control-center": "Control center for room:",
|
||||
"joining-room": "You are in room",
|
||||
"add-group-chat": "Create a Room",
|
||||
@@ -88,6 +130,7 @@
|
||||
"room-name": "Room Name",
|
||||
"password-input-field": "Password",
|
||||
"guests-only-see-director": "Guests can only see the Director's Video",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"default-codec-select": "Preferred Video Codec: ",
|
||||
"enter-the-rooms-control": "Enter the Room's Control Center",
|
||||
"show-tips": "Show me some tips..",
|
||||
@@ -97,14 +140,20 @@
|
||||
"ask-for-permissions": "Allow Access to Camera/Microphone",
|
||||
"waiting-for-camera": "Waiting for Camera to Load",
|
||||
"video-source": " Video Source ",
|
||||
"max-resolution": "1080p (hi-def)",
|
||||
"balanced": "720p (balanced)",
|
||||
"smooth-cool": "360p (smooth)",
|
||||
"max-resolution": "Max Resolution",
|
||||
"balanced": "Balanced",
|
||||
"smooth-cool": "Smooth and Cool",
|
||||
"select-audio-source": " Audio Source(s) ",
|
||||
"no-audio": "No Audio",
|
||||
"select-output-source": " Audio Output Destination: ",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"add-a-password": " Add a Password:",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"remote-screenshare-obs": "Remote Screenshare",
|
||||
"note-share-audio": "\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<video id=\"screenshare\" autoplay=\"true\" muted=\"true\" loop=\"\" src=\"./images/screenshare.webm\"></video>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t",
|
||||
"select-screen-to-share": "SELECT SCREEN TO SHARE",
|
||||
"audio-sources": "Audio Sources",
|
||||
"create-reusable-invite": "Create Reusable Invite",
|
||||
@@ -126,47 +175,101 @@
|
||||
"can-hear-only": "Can only hear the group chat",
|
||||
"cant-see-or-hear": "Cannot hear or see the group chat",
|
||||
"share-local-video-file": "Stream Media File",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"share-website-iframe": "Share Website",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"run-a-speed-test": "Run a Speed Test",
|
||||
"read-the-guides": "Browse the Guides",
|
||||
"info-blob": "",
|
||||
"hide-the-links": " LINKS (GUEST INVITES & SCENES)",
|
||||
"click-for-quick-room-overview": "\n\t\t\t\t\t\t<i class=\"las la-question-circle\"></i> Click Here for a quick overview and help\n\t\t\t\t\t",
|
||||
"welcome-to-control-room": "\n\t\t\t\t\t\t<b>Welcome. This is the director's control-room for the group-chat.</b><br><br>\n\t\t\t\t\t\tYou can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.\n\t\t\t\t\t\t<br><br>\n\t\t\t\t\t\t",
|
||||
"click-for-quick-room-overview": "\n\t\t\t\t\t\t<i class=\"las la-question-circle\"></i> <span data-translate=\"click-here-for-help\">Click Here for a quick overview and help</span>\n\t\t\t\t\t",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"welcome-to-control-room": "\n\t\t\t\t\t\t<b>Welcome. This is the director's control-room for the group-chat.</b><br><br>\n\t\t\t\t\t\tYou can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.\n\t\t\t\t\t\t<br><br>\n\t\t\t\t\t\t<font style=\"color:red\">Known Limitations with Group Rooms:</font><br>\n\t\t\t\t\t\t<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.</li>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<li>Videos will appear of low quality on purpose for guests and director; this is to save bandwidth and CPU resources.",
|
||||
"invite-users-to-join": "Guests can use the link to join the group room",
|
||||
"this-is-obs-browser-source-link": "Use in studio software to capture the group video mix",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"this-is-obs-browser-source-link": "Use in your studio software to capture the group video mix",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"more-than-four-can-join": "These four guest slots are just for demonstration. More than four guests can actually join a room.",
|
||||
"forward-to-room": "Transfer",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Message",
|
||||
"add-to-scene": "Add to Scene",
|
||||
"mute-scene": "mute in scene",
|
||||
"disconnect-guest": "Hangup",
|
||||
"voice-chat": "<i class=\"las la-microphone\" style=\"color:#090\"></i> Solo Talk",
|
||||
"add-to-scene": "add to scene 1",
|
||||
"mute-guest": "mute guest",
|
||||
"More-scene-options": "More scene options",
|
||||
"mute-scene": "mute in scene",
|
||||
"force-keyframe": "Rainbow Puke Fix",
|
||||
"stats-remote": " Scene Stats",
|
||||
"additional-controls": "Additional controls",
|
||||
"solo-video": "Highlight guest",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"record-local": " Record",
|
||||
"record-remote": " Record Remote",
|
||||
"change-to-low-quality": " <i class=\"las la-video-slash\"></i>",
|
||||
"change-to-medium-quality": " <i class=\"las la-video\"></i>",
|
||||
"change-to-high-quality": " <i class=\"las la-binoculars\"></i>",
|
||||
"disconnect-guest": "Hangup",
|
||||
"record-local": " Record Local",
|
||||
"record-remote": " Record Remote",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Voice Chat",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"advanced-camera-settings": "<i class=\"las la-sliders-h\"></i> Video Settings",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"open-in-new-tab": "Open in new Tab",
|
||||
"copy-to-clipboard": "Copy to Clipboard",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tWelcome! You can send text messages directly to connected peers from here.\n\t\t\t\t",
|
||||
"names-and-labels-coming-soon": "\n\t\t\t\t\tNames identifying connected peers will be a feature in an upcoming release.\n\t\t\t\t",
|
||||
"send-chat": "Send",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"invisible-guests": "Not Visible",
|
||||
"available-languages": "Available Languages:",
|
||||
"add-more-here": "Add More Here!"
|
||||
"add-more-here": "Add More Here!",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Join by Room Name here",
|
||||
"enter-a-room-name-here": "Enter a Room Name here",
|
||||
"optional-room-password-here": "Optional room password here",
|
||||
"optional": "optional",
|
||||
"give-this-media-source-a-name-optional-": "Give this media source a name (optional)",
|
||||
"add-an-optional-password": "Add an optional password",
|
||||
"enter-room-name-here": "Enter Room name here",
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here"
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,56 @@
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " Record Remote",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Připojit se s názvem místnosti zde",
|
||||
@@ -187,6 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Pojmenujte tento zdroj médií (volitelné)",
|
||||
"add-an-optional-password": "Přidat volitelné heslo",
|
||||
"enter-room-name-here": "Sem zadejte název místnosti",
|
||||
"enter-chat-message-to-send-here": "Sem zadejte vaši zprávu"
|
||||
"enter-chat-message-to-send-here": "Sem zadejte vaši zprávu",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,56 @@
|
||||
"shift-this-video-up-in-order": "Anzeigepriorität/-reihenfolge für dieses Video nach oben verschieben",
|
||||
"remote-audio-settings": "Remote Audio-Einstellungen",
|
||||
"advanced-video-settings": "Erweiterte Video-Einstellungen",
|
||||
"activate-or-reload-this-video-device-": "Kamera aktivieren oder neu laden."
|
||||
"activate-or-reload-this-video-device-": "Kamera aktivieren oder neu laden.",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS Ninja",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " remote aufnehmen",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio-Einstellungen"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio-Einstellungen",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Raum über Namen betreten",
|
||||
@@ -187,6 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Namen für Quelle angeben (optional)",
|
||||
"add-an-optional-password": "Passwort hinzufügen (optional)",
|
||||
"enter-room-name-here": "Raumnamen eingeben",
|
||||
"enter-chat-message-to-send-here": "Message"
|
||||
"enter-chat-message-to-send-here": "Message",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
"GO": "GO",
|
||||
"copy-this-url": "Copy this URL into an OBS \"Browser Source\"",
|
||||
"you-are-in-the-control-center": "You are in the room's control center",
|
||||
"joining-room": "You are joining room",
|
||||
"add-group-chat": "Add Group Chat to OBS",
|
||||
"rooms-allow-for": "Rooms allow for simplified group-chat and the advanced management of multiple streams at once.",
|
||||
"room-name": "Room Name",
|
||||
"enter-the-rooms-control": "Enter the Room's Control Center",
|
||||
"show-tips": "Show me some tips..",
|
||||
"added-notes": "\n<u><i>Added Notes:</i></u>\n<li>Anyone can enter a room if they know the name, so keep it unique</li>\n<li>Invite only guests to the room you trust.</li>\n<li>iOS devices will share just their audio with other guests; this is mainly a hardware limitation</li>\n<li>The \"Recording\" option is considered experimental.</li>\n",
|
||||
"back": "Back",
|
||||
"add-your-camera": "Add your Camera to OBS",
|
||||
"waiting-for-camera": "Waiting for Camera to Load",
|
||||
"video-source": "Video source",
|
||||
"max-resolution": "1080p (hi-def)",
|
||||
"balanced": "720p (balanced)",
|
||||
"smooth-cool": "360p (smooth)",
|
||||
"select-audio-source": "Select Audio Source",
|
||||
"no-audio": "No Audio",
|
||||
"remote-screenshare-obs": "Remote Screenshare into OBS",
|
||||
"note-share-audio": "\n<b>note</b>: Do not forget to click \"Share audio\" in Chrome.<br>(Firefox does not support audio sharing.)",
|
||||
"select-screen-to-share": "SELECT SCREEN TO SHARE",
|
||||
"audio-sources": "Audio Sources",
|
||||
"create-reusable-invite": "Create Reusable Invite",
|
||||
"here-you-can-pre-generate": "Here you can pre-generate a reusable Browser Source link and a related guest invite link.",
|
||||
"generate-invite-link": "GENERATE THE INVITE LINK",
|
||||
"advanced-paramaters": "Advanced Options:",
|
||||
"unlock-video-bitrate": "Unlock Video Bitrate (20mbps)",
|
||||
"force-vp9-video-codec": "Force VP9 Video Codec (less artifacting)",
|
||||
"enable-stereo-and-pro": "Enable Stereo and Pro HD Audio",
|
||||
"video-resolution": "Video Resolution: ",
|
||||
"high-security-mode": "High Security Mode",
|
||||
"hide-screen-share": "Hide Screenshare Option",
|
||||
"allow-remote-control": "Remote Control Camera Zoom (android)",
|
||||
"add-the-guest-to-a-room": " Add the guest to a room:",
|
||||
"invite-group-chat-type": "This room guest can:",
|
||||
"can-see-and-hear": "Can see and hear the group chat",
|
||||
"can-hear-only": "Can only hear the group chat",
|
||||
"cant-see-or-hear": "Cannot hear or see the group chat",
|
||||
"info-blob": "\n<h2>What is OBS.Ninja</h2><br>\n<li>100% <b>free</b>; no downloads; no personal data collection; no sign-in</li>\n<li>Bring video from your smartphone, computer, or friends directly into your OBS video stream</li>\n<li>We use cutting edge Peer-to-Peer forwarding technology that offers privacy and ultra-low latency</li>\n<br>\n<li>Youtube video <i class=\"fa fa-youtube-play\" aria-hidden=\"true\"></i> <a href=\"https://www.youtube.com/watch?v=6R_sQKxFAhg\">Demoing it here</a> </li>\n<br>\n<i><font style=\"color:red\">Known issues:</font></i><br>\n<li><i class=\"fa fa-apple\" aria-hidden=\"true\"></i> <a href=\"https://github.com/steveseguin/obsninja/wiki/FAQ#mac-os\">MacOS 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</li>\n<li>Some users will have <a href=\"https://github.com/steveseguin/obsninja/wiki/FAQ#video-is-pixelated\">\"pixelation\" problems</a> with videos. Adding <b>&codec=vp9</b> to the OBS links will often correct it.</li>\n<br>\n",
|
||||
"remote-control-for-obs": "Remote Control for OBS",
|
||||
"add-to-group": "Add to Group Scene",
|
||||
"mute": "Mute",
|
||||
"record": "Record",
|
||||
"volume": "Volume",
|
||||
"open-in-new-tab": "Open in new Tab",
|
||||
"copy-to-clipboard": "Copy to Clipboard"
|
||||
}
|
||||
@@ -2,11 +2,13 @@
|
||||
"titles": {
|
||||
"join-by-room-name-here": "Enter a room name to quick join",
|
||||
"join-room": "Join room",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"toggle-the-chat": "Toggle the Chat",
|
||||
"mute-the-speaker": "Mute the Speaker",
|
||||
"mute-the-mic": "Mute the Mic",
|
||||
"disable-the-camera": "Disable the Camera",
|
||||
"share-a-screen-with-others": "Share a Screen with others",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"settings": "Settings",
|
||||
"hangup-the-call": "Hangup the Call",
|
||||
"alert-the-host-you-want-to-speak": "Alert the host you want to speak",
|
||||
@@ -15,13 +17,18 @@
|
||||
"submit-any-error-logs": "Submit any error logs",
|
||||
"show-help-info": "Show Help Info",
|
||||
"language-options": "Language Options",
|
||||
"add-group-chat-to-obs": "Add Group Chat to OBS",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"add-group-chat-to-obs": "Add Group Chat",
|
||||
"for-large-group-rooms-this-option-can-reduce-the-load-on-remote-guests-substantially": "For large group rooms, this option can reduce the load on remote guests substantially",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"which-video-codec-would-you-want-used-by-default-": "Which video codec would you want used by default?",
|
||||
"you-ll-enter-as-the-room-s-director": "You'll enter as the room's director",
|
||||
"add-your-camera-to-obs": "Add your Camera to OBS",
|
||||
"add-your-camera-to-obs": "Add your Camera",
|
||||
"start-streaming": "start streaming",
|
||||
"tip-hold-ctrl-command-to-select-multiple": "tip: Hold CTRL (command) to select Multiple",
|
||||
"remote-screenshare-into-obs": "Remote Screenshare into OBS",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"remote-screenshare-into-obs": "Remote Screenshare",
|
||||
"create-reusable-invite": "Create Reusable Invite",
|
||||
"ideal-for-1080p60-gaming-if-your-computer-and-upload-are-up-for-it": "Ideal for 1080p60 gaming, if your computer and upload are up for it",
|
||||
"better-video-compression-and-quality-at-the-cost-of-increased-cpu-encoding-load": "Better video compression and quality at the cost of increased CPU encoding load",
|
||||
@@ -39,48 +46,83 @@
|
||||
"creative-commons-by-3-0": "Creative Commons BY 3.0",
|
||||
"youtube-video-demoing-how-to-do-this": "Youtube Video demoing how to do this",
|
||||
"invite-a-guest-or-camera-source-to-publish-into-the-group-room": "Invite a guest or camera source to publish into the group room",
|
||||
"if-enabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If enabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Use this link in the OBS Browser Source to capture the video or audio",
|
||||
"if-enabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If enabled, you must manually add a video to a scene for it to appear.",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Use this link as a browser source in your Studio software to capture the video or audio",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"disables-echo-cancellation-and-improves-audio-quality": "Disables Echo Cancellation and improves audio quality",
|
||||
"audio-only-sources-are-visually-hidden-from-scenes": "Audio-only sources are visually hidden from scenes",
|
||||
"guest-will-be-prompted-to-enter-a-display-name": "Guest will be prompted to enter a Display Name",
|
||||
"display-names-will-be-shown-in-the-bottom-left-corner-of-videos": "Display Names will be shown in the bottom-left corner of videos",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"request-1080p60-from-the-guest-instead-of-720p60-if-possible": "Request 1080p60 from the Guest instead of 720p60, if possible",
|
||||
"the-default-microphone-will-be-pre-selected-for-the-guest": "The default microphone will be pre-selected for the guest",
|
||||
"the-default-camera-device-will-selected-automatically": "The default camera device will selected automatically",
|
||||
"the-guest-won-t-have-access-to-changing-camera-settings-or-screenshare": "The guest won't have access to changing camera settings or screenshare",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-see-their-own-self-preview-after-joining": "The guest will not see their own self-preview after joining",
|
||||
"guests-will-have-an-option-to-poke-the-director-by-pressing-a-button": "Guests will have an option to poke the Director by pressing a button",
|
||||
"add-an-audio-compressor-to-the-guest-s-microphone": "Add an audio compressor to the guest's microphone",
|
||||
"add-an-equalizer-to-the-guest-s-microphone-that-the-director-can-control": "Add an Equalizer to the guest's microphone that the director can control",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-guest-can-only-see-the-director-s-video-if-provided": "The guest can only see the Director's video, if provided",
|
||||
"the-guest-s-microphone-will-be-muted-on-joining-they-can-unmute-themselves-": "The guest's microphone will be muted on joining. They can unmute themselves.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"have-the-guest-join-muted-so-only-the-director-can-unmute-the-guest-": "Have the guest join muted, so only the director can Unmute the guest.",
|
||||
"make-the-invite-url-encoded-so-parameters-are-harder-to-tinker-with-by-guests": "Make the invite URL encoded, so parameters are harder to tinker with by guests",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"move-the-user-to-another-room-controlled-by-another-director": "Move the user to another room, controlled by another director",
|
||||
"send-a-direct-message-to-this-user-": "Send a Direct Message to this user.",
|
||||
"add-this-video-to-any-remote-scene-1-": "Add this Video to any remote '&scene=1'",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Remotely Mute this Audio in all remote '&scene' views",
|
||||
"remotely-change-the-volume-of-this-guest": "Remotely change the volume of this guest",
|
||||
"mute-this-guest-everywhere": "Mute this guest everywhere",
|
||||
"disable-video-preview": "Disable Video Preview",
|
||||
"low-quality-preview": "Low-Quality Preview",
|
||||
"high-quality-preview": "High-Quality Preview",
|
||||
"force-the-user-to-disconnect-they-can-always-reconnect-": "Force the user to Disconnect. They can always reconnect.",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Start Recording this remote stream to this local drive. *experimental*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "The Remote Guest will record their local stream to their local drive. *experimental*",
|
||||
"toggle-voice-chat-with-this-guest": "Toggle Voice Chat with this Guest",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-this-video-to-any-remote-scene-1-": "Add this Video to any remote '&scene=1'",
|
||||
"mute-this-guest-everywhere": "Mute this guest everywhere",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Remotely Mute this Audio in all remote '&scene' views",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"add-to-scene-8": "Add to Scene 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"shift-this-video-down-in-order": "Shift this Video Down in Order",
|
||||
"current-index-order-of-this-video": "Current Index Order of this Video",
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Start Recording this remote stream to this local drive. *experimental*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "The Remote Guest will record their local stream to their local drive. *experimental*",
|
||||
"remotely-change-the-volume-of-this-guest": "Remotely change the volume of this guest",
|
||||
"disable-video-preview": "Disable Video Preview",
|
||||
"low-quality-preview": "Low-Quality Preview",
|
||||
"high-quality-preview": "High-Quality Preview",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "\n\t\t\t\t\t<font id=\"qos\">O</font>BS.Ninja \n\t\t\t\t",
|
||||
"copy-this-url": "Copy this URL into an OBS \"Browser Source\"",
|
||||
"copy-this-url": "Copy this URL into your studio's \"browser Source\"",
|
||||
"you-are-in-the-control-center": "Control center for room:",
|
||||
"joining-room": "You are in room",
|
||||
"add-group-chat": "Create a Room",
|
||||
@@ -88,23 +130,30 @@
|
||||
"room-name": "Room Name",
|
||||
"password-input-field": "Password",
|
||||
"guests-only-see-director": "Guests can only see the Director's Video",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"default-codec-select": "Preferred Video Codec: ",
|
||||
"enter-the-rooms-control": "Enter the Room's Control Center",
|
||||
"show-tips": "Show me some tips..",
|
||||
"added-notes": "\n\t\t\t\t\t\t\t\t<u>\n\t\t\t\t\t\t\t\t\t<i>Important Tips:</i><br><br>\n\t\t\t\t\t\t\t\t</u>\n\t\t\t\t\t\t\t\t<li>Disabling video sharing between guests will improve performance</li>\n\t\t\t\t\t\t\t\t<li>Invite only guests to the room that you trust.</li>\n\t\t\t\t\t\t\t\t<li>The \"Recording\" option is considered experimental.</li>\n\t\t\t\t\t\t\t\t<li><a href=\"https://params.obs.ninja\" style=\"color:black;\"><u>Advanced URL parameters</u></a> are available to customize rooms.</li>\n\t\t\t\t\t\t\t",
|
||||
"added-notes": "\n\t\t\t\t\t\t\t\t<u>\n\t\t\t\t\t\t\t\t\t<i>Important Tips:</i><br><br>\n\t\t\t\t\t\t\t\t</u>\n\t\t\t\t\t\t\t\t<li>Disabling video sharing between guests will improve performance</li>\n\t\t\t\t\t\t\t\t<li>Invite only guests to the room that you trust.</li>\n\t\t\t\t\t\t\t\t<li>The \"Recording\" option is considered experimental.</li>",
|
||||
"back": "Back",
|
||||
"add-your-camera": "Add your Camera to OBS",
|
||||
"add-your-camera": "Add your Camera",
|
||||
"ask-for-permissions": "Allow Access to Camera/Microphone",
|
||||
"waiting-for-camera": "Waiting for Camera to Load",
|
||||
"video-source": " Video Source ",
|
||||
"max-resolution": "1080p (hi-def)",
|
||||
"balanced": "720p (balanced)",
|
||||
"smooth-cool": "360p (smooth)",
|
||||
"max-resolution": "Max Resolution",
|
||||
"balanced": "Balanced",
|
||||
"smooth-cool": "Smooth and Cool",
|
||||
"select-audio-source": " Audio Source(s) ",
|
||||
"no-audio": "No Audio",
|
||||
"select-output-source": " Audio Output Destination: ",
|
||||
"remote-screenshare-obs": "Remote Screenshare into OBS",
|
||||
"note-share-audio": "\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<video id=\"screenshare\" autoplay=\"true\" muted=\"true\" loop=\"\" src=\"./images/screenshare.webm\"></video>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"add-a-password": " Add a Password:",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"remote-screenshare-obs": "Remote Screenshare",
|
||||
"select-screen-to-share": "SELECT SCREEN TO SHARE",
|
||||
"audio-sources": "Audio Sources",
|
||||
"create-reusable-invite": "Create Reusable Invite",
|
||||
@@ -126,47 +175,101 @@
|
||||
"can-hear-only": "Can only hear the group chat",
|
||||
"cant-see-or-hear": "Cannot hear or see the group chat",
|
||||
"share-local-video-file": "Stream Media File",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"share-website-iframe": "Share Website",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"run-a-speed-test": "Run a Speed Test",
|
||||
"read-the-guides": "Browse the Guides",
|
||||
"info-blob": "\n\t\t\t\t\t\t\t<h2>What is OBS.Ninja</h2>\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<li>100% \n\t\t\t\t\t\t\t\t<b>free</b>; no downloads; no personal data collection; no sign-in\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>Bring video from your smartphone, computer, or friends directly into your OBS video stream</li>\n\t\t\t\t\t\t\t<li>We use cutting edge Peer-to-Peer forwarding technology that offers privacy and ultra-low latency</li>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t",
|
||||
"info-blob": "",
|
||||
"hide-the-links": " LINKS (GUEST INVITES & SCENES)",
|
||||
"click-for-quick-room-overview": "\n\t\t\t\t\t\t<i class=\"las la-question-circle\"></i> Click Here for a quick overview and help\n\t\t\t\t\t",
|
||||
"welcome-to-control-room": "\n\t\t\t\t\t\t<b>Welcome. This is the director's control-room for the group-chat.</b><br><br>\n\t\t\t\t\t\tYou can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.\n\t\t\t\t\t\t<br><br>\n\t\t\t\t\t\t<font style=\"color:red\">Known Limitations with Group Rooms:</font><br>\n\t\t\t\t\t\t<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 <a href=\"https://www.youtube.com/watch?v=bpRa8-UYCGc\" title=\"Youtube Video demoing how to do this\">disable video sharing between guests</a>. Using &broadcast, &roombitrate=0 or &novideo are options there.</li>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\tFurther Notes:<br><br>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<li>You can use the auto-mixing Group Scenes, the green links, to auto arrange multiple videos for you in OBS.</li>\n\t\t\t\t\t\t<li>You can use this control room to record isolated video or audio streams, but it is an experimental feature still.</li>\n\t\t\t\t\t\t<li>If you transfer a guest from one room to another, they won't know which room they have been transferred to.</li>\n\t\t\t\t\t\t<li>OBS will see a guest's video in high-quality; the default video bitrate is 2500kbps. Setting higher bitrates will improve motion.</li>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<li>&stereo=2 can be added to guests to turn off audio effects, such as echo cancellation and noise-reduction.</li>\n\t\t\t\t\t\t<li>https://invite.cam is a free service provided that can help obfuscuate the URL parameters of an invite link given to guests.</li>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\n\t\t\t\t\t\tFor advanced URL options and parameters, <a href=\"https://github.com/steveseguin/obsninja/wiki/Advanced-Settings\">see the Wiki.</a>\n\t\t\t\t\t",
|
||||
"click-for-quick-room-overview": "\n\t\t\t\t\t\t<i class=\"las la-question-circle\"></i> <span data-translate=\"click-here-for-help\">Click Here for a quick overview and help</span>\n\t\t\t\t\t",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"welcome-to-control-room": "\n\t\t\t\t\t\t<b>Welcome. This is the director's control-room for the group-chat.</b><br><br>\n\t\t\t\t\t\tYou can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.\n\t\t\t\t\t\t<br><br>\n\t\t\t\t\t\t<font style=\"color:red\">Known Limitations with Group Rooms:</font><br>\n\t\t\t\t\t\t<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.</li>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<li>Videos will appear of low quality on purpose for guests and director; this is to save bandwidth and CPU resources.",
|
||||
"invite-users-to-join": "Guests can use the link to join the group room",
|
||||
"this-is-obs-browser-source-link": "Use in OBS or other studio software to capture the group video mix",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"this-is-obs-browser-source-link": "Use in your studio software to capture the group video mix",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"more-than-four-can-join": "These four guest slots are just for demonstration. More than four guests can actually join a room.",
|
||||
"forward-to-room": "Transfer",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Message",
|
||||
"add-to-scene": "Add to Scene",
|
||||
"mute-scene": "mute in scene",
|
||||
"disconnect-guest": "Hangup",
|
||||
"voice-chat": "<i class=\"las la-microphone\" style=\"color:#090\"></i> Solo Talk",
|
||||
"add-to-scene": "add to scene 1",
|
||||
"mute-guest": "mute guest",
|
||||
"More-scene-options": "More scene options",
|
||||
"mute-scene": "mute in scene",
|
||||
"force-keyframe": "Rainbow Puke Fix",
|
||||
"stats-remote": " Scene Stats",
|
||||
"additional-controls": "Additional controls",
|
||||
"solo-video": "Highlight guest",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"record-local": " Record",
|
||||
"record-remote": " Record Remote",
|
||||
"change-to-low-quality": " <i class=\"las la-video-slash\"></i>",
|
||||
"change-to-medium-quality": " <i class=\"las la-video\"></i>",
|
||||
"change-to-high-quality": " <i class=\"las la-binoculars\"></i>",
|
||||
"disconnect-guest": "Hangup",
|
||||
"record-local": " Record Local",
|
||||
"record-remote": " Record Remote",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Voice Chat",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"advanced-camera-settings": "<i class=\"las la-sliders-h\"></i> Video Settings",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"open-in-new-tab": "Open in new Tab",
|
||||
"copy-to-clipboard": "Copy to Clipboard",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tWelcome to OBS.Ninja! You can send text messages directly to connected peers from here.\n\t\t\t\t",
|
||||
"names-and-labels-coming-soon": "\n\t\t\t\t\tNames identifying connected peers will be a feature in an upcoming release.\n\t\t\t\t",
|
||||
"send-chat": "Send",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"invisible-guests": "Not Visible",
|
||||
"available-languages": "Available Languages:",
|
||||
"add-more-here": "Add More Here!"
|
||||
"add-more-here": "Add More Here!",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Join by Room Name here",
|
||||
"enter-a-room-name-here": "Enter a Room Name here",
|
||||
"optional-room-password-here": "Optional room password here",
|
||||
"optional": "optional",
|
||||
"give-this-media-source-a-name-optional-": "Give this media source a name (optional)",
|
||||
"add-an-optional-password": "Add an optional password",
|
||||
"enter-room-name-here": "Enter Room name here",
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here"
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -1,103 +1,140 @@
|
||||
{
|
||||
"titles": {
|
||||
"toggle-the-chat": "Toggle the Chat",
|
||||
"mute-the-speaker": "Mute the Speaker",
|
||||
"mute-the-mic": "Mute the Mic",
|
||||
"disable-the-camera": "Disable the Camera",
|
||||
"settings": "Settings",
|
||||
"hangup-the-call": "Hangup the Call",
|
||||
"show-help-info": "Show Help Info",
|
||||
"language-options": "Language Options",
|
||||
"tip-hold-ctrl-command-to-select-multiple": "tip: Hold CTRL (command) to select Multiple",
|
||||
"ideal-for-1080p60-gaming-if-your-computer-and-upload-are-up-for-it": "Ideal for 1080p60 gaming, if your computer and upload are up for it",
|
||||
"better-video-compression-and-quality-at-the-cost-of-increased-cpu-encoding-load": "Better video compression and quality at the cost of increased CPU encoding load",
|
||||
"disable-digital-audio-effects-and-increase-audio-bitrate": "Disable digital audio-effects and increase audio bitrate",
|
||||
"the-guest-will-not-have-a-choice-over-audio-options": "The guest will not have a choice over audio-options",
|
||||
"the-guest-will-only-be-able-to-select-their-webcam-as-an-option": "The guest will only be able to select their webcam as an option",
|
||||
"hold-ctrl-and-the-mouse-wheel-to-zoom-in-and-out-remotely-of-compatible-video-streams": "Hold CTRL and the mouse wheel to zoom in and out remotely of compatible video streams",
|
||||
"add-a-password-to-make-the-stream-inaccessible-to-those-without-the-password": "Add a password to make the stream inaccessible to those without the password",
|
||||
"add-the-guest-to-a-group-chat-room-it-will-be-created-automatically-if-needed-": "Add the guest to a group-chat room; it will be created automatically if needed.",
|
||||
"customize-the-room-settings-for-this-guest": "Customize the room settings for this guest",
|
||||
"hold-ctrl-or-cmd-to-select-multiple-files": "Hold CTRL (or CMD) to select multiple files",
|
||||
"enter-an-https-url": "Enter an HTTPS URL",
|
||||
"lucy-g": "Lucy G",
|
||||
"flaticon": "Flaticon",
|
||||
"creative-commons-by-3-0": "Creative Commons BY 3.0",
|
||||
"gregor-cresnar": "Gregor Cresnar",
|
||||
"add-this-video-to-any-remote-scene-1-": "Add this Video to any remote '&scene=1'",
|
||||
"forward-user-to-another-room-they-can-always-return-": "Forward user to another room. They can always return.",
|
||||
"start-recording-this-stream-experimental-views": "Start Recording this stream. *experimental*' views",
|
||||
"force-the-user-to-disconnect-they-can-always-reconnect-": "Force the user to Disconnect. They can always reconnect.",
|
||||
"change-this-audio-s-volume-in-all-remote-scene-views": "Change this Audio's volume in all remote '&scene' views",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Remotely Mute this Audio in all remote '&scene' views",
|
||||
"disable-video-preview": "Disable Video Preview",
|
||||
"low-quality-preview": "Low-Quality Preview",
|
||||
"high-quality-preview": "High-Quality Preview",
|
||||
"send-direct-message": "Send Direct Message",
|
||||
"advanced-settings-and-remote-control": "Advanced Settings and Remote Control",
|
||||
"toggle-voice-chat-with-this-guest": "Toggle Voice Chat with this Guest",
|
||||
"join-by-room-name-here": "Enter a room name to quick join",
|
||||
"join-room": "Join room",
|
||||
"share-a-screen-with-others": "Share a Screen with others",
|
||||
"alert-the-host-you-want-to-speak": "Alert the host you want to speak",
|
||||
"record-your-stream-to-disk": "Record your stream to disk",
|
||||
"cancel-the-director-s-video-audio": "Cancel the Director's Video/Audio",
|
||||
"submit-any-error-logs": "Submit any error logs",
|
||||
"add-group-chat-to-obs": "Add Group Chat to OBS",
|
||||
"for-large-group-rooms-this-option-can-reduce-the-load-on-remote-guests-substantially": "For large group rooms, this option can reduce the load on remote guests substantially",
|
||||
"which-video-codec-would-you-want-used-by-default-": "Which video codec would you want used by default?",
|
||||
"you-ll-enter-as-the-room-s-director": "You'll enter as the room's director",
|
||||
"add-your-camera-to-obs": "Add your Camera to OBS",
|
||||
"remote-screenshare-into-obs": "Remote Screenshare into OBS",
|
||||
"join-by-room-name-here": "Introduce un nombre de sala para entrar",
|
||||
"join-room": "Unirse sala",
|
||||
"load-the-next-guest-in-queue": "Cargar el siguiente invitado en la cola",
|
||||
"toggle-the-chat": "Conmutar Chat",
|
||||
"mute-the-speaker": "Mute Orador",
|
||||
"mute-the-mic": "Mute Micro",
|
||||
"disable-the-camera": "Desactivar Cámara",
|
||||
"share-a-screen-with-others": "Compartir Pantalla con otros",
|
||||
"create-a-secondary-stream": "Crear un Stream Secundario",
|
||||
"settings": "Configuración",
|
||||
"hangup-the-call": "Colgar",
|
||||
"alert-the-host-you-want-to-speak": "Avisar Anfitrión que quieres hablar",
|
||||
"record-your-stream-to-disk": "Grabar tu stream a disco",
|
||||
"cancel-the-director-s-video-audio": "Cancelar el Video/Audio del Director",
|
||||
"submit-any-error-logs": "Enviar cualquier registro de error",
|
||||
"show-help-info": "Mostrar Ayuda",
|
||||
"language-options": "Opciones Idioma",
|
||||
"add-to-calendar": "Añadir al Calendario",
|
||||
"add-group-chat-to-obs": "Añadir Chat Grupal",
|
||||
"for-large-group-rooms-this-option-can-reduce-the-load-on-remote-guests-substantially": "Para salas de grupos grandes, esta opción reduce la carga en los clientes remotos de manera substancial",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "El director será visible en las escenas, como si fuese a actuar.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Útil si quieres actuar y dirigir al mismo tiempo",
|
||||
"which-video-codec-would-you-want-used-by-default-": "¿Qué codec de video quieres se utilice por defecto?",
|
||||
"you-ll-enter-as-the-room-s-director": "Nunca entrarás como director de sala",
|
||||
"add-your-camera-to-obs": "Añadir Cámara",
|
||||
"start-streaming": "iniciar streaming",
|
||||
"tip-hold-ctrl-command-to-select-multiple": "truco: Mantén pulsado CTRL (o CMD) para selección Múltiple",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"remote-screenshare-into-obs": "Remote Screenshare",
|
||||
"create-reusable-invite": "Create Reusable Invite",
|
||||
"ideal-for-1080p60-gaming-if-your-computer-and-upload-are-up-for-it": "Ideal para juegos 1080p60, si tu PC y conexión lo permiten",
|
||||
"better-video-compression-and-quality-at-the-cost-of-increased-cpu-encoding-load": "Mejor compresión y calidad del video pese al incremento de carga en la CPU",
|
||||
"disable-digital-audio-effects-and-increase-audio-bitrate": "Deshabilitar los efectos de sonido digital e incrementar el bitrate audio",
|
||||
"the-guest-will-not-have-a-choice-over-audio-options": "El invitado no tendrá opciones de audio a escoger",
|
||||
"the-guest-will-only-be-able-to-select-their-webcam-as-an-option": "El invitado sólo podrá seleccionar su opción de cámara",
|
||||
"hold-ctrl-and-the-mouse-wheel-to-zoom-in-and-out-remotely-of-compatible-video-streams": "Mantén CTRL y la rueda del ratón para hacer zoom en los videos",
|
||||
"encode-the-url-so-that-it-s-harder-for-a-guest-to-modify-the-settings-": "Encode the URL so that it's harder for a guest to modify the settings.",
|
||||
"more-options": "More Options",
|
||||
"add-a-password-to-make-the-stream-inaccessible-to-those-without-the-password": "Añade un password para evitar el acceso al video sin la clave",
|
||||
"add-the-guest-to-a-group-chat-room-it-will-be-created-automatically-if-needed-": "Añade al invitado a una sala de chat grupal; se creará automáticamente en caso necesario.",
|
||||
"customize-the-room-settings-for-this-guest": "Customizar la configuración de sala para este invitado",
|
||||
"more-options": "Más Opciones",
|
||||
"hold-ctrl-or-cmd-to-select-multiple-files": "Mantener CTRL (o CMD) para seleccionar varios ficheros",
|
||||
"enter-an-https-url": "Introduce una URL HTTPS",
|
||||
"creative-commons-by-3-0": "Creative Commons BY 3.0",
|
||||
"youtube-video-demoing-how-to-do-this": "Youtube Video demoing how to do this",
|
||||
"invite-a-guest-or-camera-source-to-publish-into-the-group-room": "Invite a guest or camera source to publish into the group room",
|
||||
"if-enabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If enabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Use this link in the OBS Browser Source to capture the video or audio",
|
||||
"if-enabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If enabled, you must manually add a video to a scene for it to appear.",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Use this link as a browser source in your Studio software to capture the video or audio",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"disables-echo-cancellation-and-improves-audio-quality": "Disables Echo Cancellation and improves audio quality",
|
||||
"audio-only-sources-are-visually-hidden-from-scenes": "Audio-only sources are visually hidden from scenes",
|
||||
"guest-will-be-prompted-to-enter-a-display-name": "Guest will be prompted to enter a Display Name",
|
||||
"display-names-will-be-shown-in-the-bottom-left-corner-of-videos": "Display Names will be shown in the bottom-left corner of videos",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"request-1080p60-from-the-guest-instead-of-720p60-if-possible": "Request 1080p60 from the Guest instead of 720p60, if possible",
|
||||
"the-default-microphone-will-be-pre-selected-for-the-guest": "The default microphone will be pre-selected for the guest",
|
||||
"the-default-camera-device-will-selected-automatically": "The default camera device will selected automatically",
|
||||
"the-guest-won-t-have-access-to-changing-camera-settings-or-screenshare": "The guest won't have access to changing camera settings or screenshare",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-see-their-own-self-preview-after-joining": "The guest will not see their own self-preview after joining",
|
||||
"guests-will-have-an-option-to-poke-the-director-by-pressing-a-button": "Guests will have an option to poke the Director by pressing a button",
|
||||
"add-an-audio-compressor-to-the-guest-s-microphone": "Add an audio compressor to the guest's microphone",
|
||||
"add-an-equalizer-to-the-guest-s-microphone-that-the-director-can-control": "Add an Equalizer to the guest's microphone that the director can control",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-guest-can-only-see-the-director-s-video-if-provided": "The guest can only see the Director's video, if provided",
|
||||
"the-guest-s-microphone-will-be-muted-on-joining-they-can-unmute-themselves-": "The guest's microphone will be muted on joining. They can unmute themselves.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"have-the-guest-join-muted-so-only-the-director-can-unmute-the-guest-": "Have the guest join muted, so only the director can Unmute the guest.",
|
||||
"make-the-invite-url-encoded-so-parameters-are-harder-to-tinker-with-by-guests": "Make the invite URL encoded, so parameters are harder to tinker with by guests",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"move-the-user-to-another-room-controlled-by-another-director": "Move the user to another room, controlled by another director",
|
||||
"send-a-direct-message-to-this-user-": "Send a Direct Message to this user.",
|
||||
"remotely-change-the-volume-of-this-guest": "Remotely change the volume of this guest",
|
||||
"force-the-user-to-disconnect-they-can-always-reconnect-": "Force the user to Disconnect. They can always reconnect.",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-this-video-to-any-remote-scene-1-": "Añadir este Video a '&scene=1' remoto",
|
||||
"mute-this-guest-everywhere": "Mute this guest everywhere",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Start Recording this remote stream to this local drive. *experimental*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "The Remote Guest will record their local stream to their local drive. *experimental*",
|
||||
"add-this-video-to-any-remote-scene-2-": "Añadir este Video a '&scene=2' remoto",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Remotely Mute this Audio in all remote '&scene' views",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"add-to-scene-8": "Add to Scene 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"shift-this-video-down-in-order": "Shift this Video Down in Order",
|
||||
"current-index-order-of-this-video": "Current Index Order of this Video",
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Comenzar Grabación de este stream remoto en local. *experimental*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "The Remote Guest will record their local stream to their local drive. *experimental*",
|
||||
"remotely-change-the-volume-of-this-guest": "Remotely change the volume of this guest",
|
||||
"disable-video-preview": "Deshabilitar Previsualización",
|
||||
"low-quality-preview": "Previo Baja Calidad",
|
||||
"high-quality-preview": "Previo Alta Calidad",
|
||||
"set-to-audio-channel-1": "Activar Canal Audio 1",
|
||||
"set-to-audio-channel-2": "Activar Canal Audio 2",
|
||||
"set-to-audio-channel-3": "Activar Canal Audio 3",
|
||||
"set-to-audio-channel-4": "Activar Canal Audio 4",
|
||||
"set-to-audio-channel-5": "Activar Canal Audio 5",
|
||||
"set-to-audio-channel-6": "Activar Canal Audio 6",
|
||||
"remote-audio-settings": "Configuración Audio Remoto",
|
||||
"advanced-video-settings": "Configuración Video Avanzada",
|
||||
"add-to-scene-2": "Añadir a Escena 2",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Mostrar Rótulos",
|
||||
"transfer-to-a-new-room": "Transferir a nueva Sala",
|
||||
"enable-custom-password": "Activar password personalizado"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
"copy-this-url": "Copia esta URL a una fuente \"Navegador\" de OBS",
|
||||
"you-are-in-the-control-center": "Estás en la sala de centro de control",
|
||||
"copy-this-url": "Copia esta URL como fuente \"Navegador\" de OBS",
|
||||
"you-are-in-the-control-center": "Estás en la sala del panel de control",
|
||||
"joining-room": "Estás entrado en la sala",
|
||||
"add-group-chat": "Agregar grupo de chat a OBS",
|
||||
"rooms-allow-for": "Las salas permiten un chat grupal simplificado y la administración avanzada de múltiples transmisiones a la vez.",
|
||||
"room-name": "Nombre de sala",
|
||||
"password-input-field": "Password",
|
||||
"enter-the-rooms-control": "Entrar a la sala de centro de control",
|
||||
"show-tips": "Muéstrame algunos consejos..",
|
||||
"added-notes": "\n\t\t\t\t<u><i>Notas adicionales:</i></u>\n\t\t\t\t<li>Cualquiera puede entrar en una sala si conoce el nombre, así que mantenlo único</li>\n\t\t\t\t<li>Tener más de cuatro (4) personas en una sala no es recomendable debido a razones de rendimiento, pero depende de tu hardware.</li>\n\t\t\t\t<li>Los dispositivos iOS están limitados a tamaños de grupo de no más de dos (2) personas. Esto es una limitación de hardware.</li>\n\t\t\t\t<li>La opción de \"Grabación\" es nueva y se considera experimental.</li>\n\t\t\t\t<li>Tienes que \"Añadir\" una señal de video a la \"Escena de grupo\" para que aparezca allí.</li>\n\t\t\t\t<li>Hay un botón nuevo añadido \"Pantalla completa mejorada\" a la vista de invitados.</li>\n\t\t\t\t",
|
||||
"guests-only-see-director": "Guests can only see the Director's Video",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"default-codec-select": "Preferred Video Codec: ",
|
||||
"enter-the-rooms-control": "Entrar al panel de control",
|
||||
"show-tips": "Muéstrame algunos consejos.",
|
||||
"added-notes": "\n\t\t\t\t\t\t\t\t<u>\n\t\t\t\t\t\t\t\t\t<i>Consejos Importantes:</i><br><br>\n\t\t\t\t\t\t\t\t</u>\n\t\t\t\t\t\t\t\t<li>Deshabilitar el video compartido entre invitados mejora el rendimiento</li>\n\t\t\t\t\t\t\t\t<li>Invite only guests to the room that you trust.</li>\n\t\t\t\t\t\t\t\t<li>La opción \"Recording\" se considera experimental.</li>",
|
||||
"back": "Atrás",
|
||||
"add-your-camera": "Agregar tu camara a OBS",
|
||||
"ask-for-permissions": "Allow Access to Camera/Microphone",
|
||||
@@ -108,85 +145,131 @@
|
||||
"smooth-cool": "Fluido",
|
||||
"select-audio-source": "Seleccionar fuentes de audio",
|
||||
"no-audio": "Sin Audio",
|
||||
"select-output-source": " Destino de la salida de audio: \n\t\t\t\t\t",
|
||||
"remote-screenshare-obs": "Compartir pantalla remota en OBS",
|
||||
"note-share-audio": "\n\t\t\t\t\t<b>Nota</b>: No te olvides de hacer clic \"Compartir audio\" en Chrome.<br>(Firefox no soporta compartir audio.)",
|
||||
"select-output-source": " Destino de la salida de audio: ",
|
||||
"select-digital-effect": " Efectos Video Digital: ",
|
||||
"no-effects-applied": "Sin efectos aplicados",
|
||||
"blurred-background": "Fondo Difuminado",
|
||||
"digital-greenscreen": "Pantalla Verde Digital",
|
||||
"virtual-background": "Fondo Virtual",
|
||||
"add-a-password": " Añadir un Password:",
|
||||
"use-chrome-instead": "Recomendamos utilizar un navegador basado en Chromium.<br>\n \t\t\t\t\t\tSafari puede sufrir problemas de audio",
|
||||
"remote-screenshare-obs": "Compartir pantalla",
|
||||
"select-screen-to-share": "SELECCIONAR PANTALLA PARA COMPARTIR",
|
||||
"audio-sources": "Fuentes de Audio",
|
||||
"create-reusable-invite": "Crear una invitación reutilizable",
|
||||
"here-you-can-pre-generate": "Aquí puedes pregenerar un enlace reutilizable para la fuente de navegador y un enlace para invitados.",
|
||||
"here-you-can-pre-generate": "Aquí puedes generar un enlace reutilizable como fuente del navegador e invitados.",
|
||||
"generate-invite-link": "GENERAR EL LINK DE INVITACIÓN",
|
||||
"advanced-paramaters": "Parámetros Avanzados",
|
||||
"unlock-video-bitrate": "Desbloquear Video Bitrate (20mbps)",
|
||||
"force-vp9-video-codec": "Forzar VP9 Video Codec (menos artefactos)",
|
||||
"enable-stereo-and-pro": "Habilitar Estéreo y Pro HD Audio",
|
||||
"enable-stereo-and-pro": "Habilitar Estéreo y Pro Audio HD",
|
||||
"video-resolution": "Resolución de vídeo: ",
|
||||
"hide-mic-selection": "Force Default Microphone",
|
||||
"hide-screen-share": "Ocultar opción compartir pantalla",
|
||||
"allow-remote-control": "Control remoto del zoom de la cámara (android)",
|
||||
"add-a-password-to-stream": " Añadir un password:",
|
||||
"add-the-guest-to-a-room": " Añadir al invitado a una sala:",
|
||||
"invite-group-chat-type": "Este invitado a la sala puede:",
|
||||
"obfuscate_url": "Obfuscar la URL Invitación",
|
||||
"add-a-password-to-stream": " Añadir password:",
|
||||
"add-the-guest-to-a-room": " Añadir invitado a una sala:",
|
||||
"invite-group-chat-type": "Este invitado de la sala puede:",
|
||||
"can-see-and-hear": "Puede ver y oir el chat de grupo",
|
||||
"can-hear-only": "Sólo puede oir el chat de grupo",
|
||||
"cant-see-or-hear": "No puede ni oir ni ver el chat de grupo",
|
||||
"share-local-video-file": "Stream Media File",
|
||||
"share-website-iframe": "Share Website",
|
||||
"cant-see-or-hear": "No puede oir ni ver el chat de grupo",
|
||||
"share-local-video-file": "Stream Fichero Multimedia",
|
||||
"select-the-video-files-to-share": "SELECCIONA EL FICHERO DE VIDEO A COMPARTIR",
|
||||
"share-website-iframe": "Comparte Sitio Web",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"run-a-speed-test": "Run a Speed Test",
|
||||
"read-the-guides": "Browse the Guides",
|
||||
"info-blob": "\n\t\t\t\t\t\t<h2>Qué es OBS.Ninja</h2><br>\n\t\t\t\t\t\t<li>100% <b>gratis</b>; sin descargas; sin recopilación de datos personales; sin registros</li>\n\t\t\t\t\t\t<li>Lleva video desde tu móbil, portátil, ordenador de sobremesa, o de tus amigos directamente a tu stream en OBS</li>\n\t\t\t\t\t\t<li>Utilizamos tecnología innovadora Peer-to-Peer que ofrece privacidad y ultra baja latencia</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 aquí</a> </li>\n\t\t\t\t\t\t",
|
||||
"add-to-scene": "Add to Scene",
|
||||
"forward-to-room": "Transfer",
|
||||
"record": "Grabar",
|
||||
"disconnect-guest": "Hangup",
|
||||
"mute": "Silenciar",
|
||||
"info-blob": "",
|
||||
"hide-the-links": " ENLACES (INVITACIONES & ESCENAS)",
|
||||
"click-for-quick-room-overview": "\n\t\t\t\t\t\t<i class=\"las la-question-circle\"></i> <span data-translate=\"click-here-for-help\">Pulsar aquí para un resumen rápido y ayuda</span>\n\t\t\t\t\t",
|
||||
"click-here-for-help": "Pulsar aquí para un resumen rápido y ayuda",
|
||||
"welcome-to-control-room": "\n\t\t\t\t\t\t<b>Bienvenido. Esta es la sala de control del director para el grupo de chat.</b><br><br>\n\t\t\t\t\t\tPuedes organizar un grupo de chat con amigos utilizando una sala. Comparte el enlace azul con los invitados para que puedan entrar directamente al chat.\n\t\t\t\t\t\t<br><br>\n\t\t\t\t\t\t<font style=\"color:red\">Limitaciones conocidas de las Salas:</font><br>\n\t\t\t\t\t\t<li>Una sala grupal puede gestionar hasta unos 30 invitados, dependiendo de varios factores, incluyendo CPU y ancho de banda disponible en todos los invitados en la sala.</li>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<li>El Video aparece en baja calidad a propósito en los invitados y director; esto es para reducir los recursos de ancho de banda y CPU.",
|
||||
"invite-users-to-join": "Los Invitados pueden utilizar el enlace para unirse sala grupal",
|
||||
"guests-hear-others": "Invitados escuchan a otros",
|
||||
"capture-a-group-scene": "CAPTURA UNA ESCENA DE GRUPO",
|
||||
"this-is-obs-browser-source-link": "Utilizar en OBS u otro software para capturar la mezcla de video grupal",
|
||||
"auto-add-guests": "Auto añadir invitados",
|
||||
"pro-audio-mode": "Modo Pro-audio",
|
||||
"hide-audio-only-sources": "Ocultar fuentes de sólo audio",
|
||||
"ask-for-display-name": "Preguntar nombre a mostrar",
|
||||
"show-display-names": "Mostrar nombres",
|
||||
"show-active-speaker": "Mostrar orador activo",
|
||||
"auto-select-microphone": "Auto-selección micro por defecto",
|
||||
"auto-select-camera": "Auto-selección cámara por defecto",
|
||||
"hide-setting-buttons": "Ocultar botón configuración",
|
||||
"mini-self-preview": "Mini visor propio",
|
||||
"virtual-backgrounds": "Fondo virtual",
|
||||
"powerful-computers-only": "¡Sólo utilizar con PC potente y grupo pequeño!",
|
||||
"guests-see-HD-video": "Invitados ven video HD",
|
||||
"no-self-preview": "Desactivar visualización propia",
|
||||
"raise-hand-button": "Mostrar botón de 'Levantar-mano'",
|
||||
"enable-compressor": "Activar compresor de audio",
|
||||
"enable-equalizer": "Activar ecualizador como opción",
|
||||
"low-cpu=broadcast-codec": "Codec emisión de bajo consumo CPU",
|
||||
"only-see-director-feed": "Sólo ver la fuente del director",
|
||||
"mute-microphone-by-default": "Mute del micro por defecto",
|
||||
"guest-joins-with-no-camera": "Invitados entran sin cámara",
|
||||
"unmute-by-director-only": "Quitar mute sólo director",
|
||||
"obfuscate-link": "Ofuscar enlace y parámetros",
|
||||
"this-can-reduce-packet-loss": "Esto puede reducir la corrupción de video causada por pérdida de paquetes",
|
||||
"use-h264-codec": "Usar codec H264",
|
||||
"show-active-speakers": "Mostar orador activo",
|
||||
"force-mono-audio": "Forzar audio mono",
|
||||
"learn-more-about-params": "Aprende sobre los parámetros URL en ",
|
||||
"more-than-four-can-join": "Estos espacios para invitados son sólo un ejemplo. Pueden unirse más de cuatro invitados.",
|
||||
"forward-to-room": "Enviar",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Mensaje",
|
||||
"disconnect-guest": "Colgar",
|
||||
"voice-chat": "<i class=\"las la-microphone\" style=\"color:#090\"></i> Hablar Solo",
|
||||
"add-to-scene": "añadir a escena 1",
|
||||
"mute-guest": "mute invitado",
|
||||
"More-scene-options": "Más opciones de escena",
|
||||
"mute-scene": "mute en escena",
|
||||
"force-keyframe": "Reparar Arcoiris",
|
||||
"stats-remote": " Valores Escena",
|
||||
"additional-controls": "Controles Adicionales",
|
||||
"solo-video": "Resaltar invitado",
|
||||
"hide-guest": "ocultar invitado",
|
||||
"toggle-remote-speaker": "Mutear Invitado",
|
||||
"toggle-remote-display": "Cegar Invitado",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"change-url": "Cambiar URL",
|
||||
"change-params": "Param. URL",
|
||||
"record-local": " Grabación Local",
|
||||
"record-remote": " Grabación Remota",
|
||||
"change-to-low-quality": " <i class=\"las la-video-slash\"></i>",
|
||||
"change-to-medium-quality": " <i class=\"las la-video\"></i>",
|
||||
"change-to-high-quality": " <i class=\"las la-binoculars\"></i>",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Message",
|
||||
"advanced-camera-settings": "<i class=\"las la-cog\"></i> Advanced",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Voice Chat",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Configuración Audio",
|
||||
"advanced-camera-settings": "<i class=\"las la-sliders-h\"></i> Configuración Video",
|
||||
"select-local-image": "Selecciona una Imagen local",
|
||||
"close-settings": "Cerrar Configuración",
|
||||
"advanced": "Avanzado ",
|
||||
"open-in-new-tab": "Abrir en una pestaña nueva",
|
||||
"copy-to-clipboard": "Copia al portapapeles",
|
||||
"click-for-quick-room-overview": "❔ Haz clic aquí para obtener información general rápida y ayuda",
|
||||
"push-to-talk-enable": "🔊 Habilitar pulsar para hablar en el modo director",
|
||||
"welcome-to-control-room": "Bienvenidos. Esta es la sala de control para el chat grupal. Hay diferentes cosas para las que puedes usar esta habitación:<br><br>\t<li>Puedes organizar un chat grupal con amigos usando una sala. Comparte el enlace azul para invitar a los que se unirán al chat automáticamente.</li>\t<li>Una sala de grupo puede manejar de 4 a 30 invitados, dependiendo de numerosos factores, incluida la CPU y el ancho de banda disponible de todos los invitados en la sala.</li>\t<li>Las vistas individuales de cada vídeo se ofrecen según los videos se van cargando. Estos se pueden usar dentro de una fuente de navegador de OBS.</li>\t<li>Puedes usar la escena de grupo de mezcla automática, el enlace verde, para organizar automáticamente varios videos en OBS.</li>\t<li>Puedes usar esta sala de control para grabar transmisiones de vídeo o audio aisladas, pero es una característica experimental.</li>\t<li>Los videos en la sala del Director serán de baja calidad; para ahorrar ancho de banda/CPU</li>\t<li>Los invitados en la sala verán los videos de los demás con una calidad muy limitada para ahorrar ancho de banda/CPU.</li>\t<li>OBS verá el video de un invitado en alta calidad; la bitrate predeterminado es 2500 kbps.</li>\t<br>\tA medida que los invitados se unen, sus videos aparecerán a continuación. Puedes llevar sus transmisiones de vídeo a OBS como escenas individuales o puedes agregarlas a la escena de grupo.\t<br>La escena de grupo mezcla automáticamente los videos que se han agregado a la escena. Ten en cuenta que el Auto-Mixer requiere que los invitados se agreguen manualmente para que aparezcan en él; no se agregan automáticamente.<br><br>Los dispositivos móviles de Apple, como iPhones y iPads, no son totalmente compatibles con el videochat de grupo. Esta es una restricción de hardware.<br><br>\tPara opciones y parámetros avanzados, <a href=\"https://github.com/steveseguin/obsninja/wiki/Guides-and-How-to's#urlparameters\">ver la Wiki.</a>",
|
||||
"more-than-four-can-join": "These four guest slots are just for demonstration. More than four guests can actually join a room.",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tBienvenido a OBS.Ninja! Puedes enviar mensajes de texto directamente a compañeros conectados desde aquí.\n\t\t\t\t",
|
||||
"names-and-labels-coming-soon": "\n\t\t\t\t\tNombres identificando a los compañeros conectados serán una nueva característica en una próxima versión.\n\t\t\t\t",
|
||||
"send-chat": "Enviar",
|
||||
"available-languages": "Idiomas disponibles:",
|
||||
"add-more-here": "¡Añade más aquí!",
|
||||
"waiting-for-camera-to-load": "waiting-for-camera-to-load",
|
||||
"start": "START",
|
||||
"share-your-mic": "Share your microphone",
|
||||
"share-your-camera": "Share your Camera",
|
||||
"share-your-screen": "Share your Screen",
|
||||
"join-room-with-mic": "Join room with Microphone",
|
||||
"share-screen-with-room": "Share-screen with Room",
|
||||
"join-room-with-camera": "Join room with Camera",
|
||||
"click-start-to-join": "Click Start to Join",
|
||||
"guests-only-see-director": "Guests can only see the Director's Video",
|
||||
"default-codec-select": "Preferred Video Codec: ",
|
||||
"obfuscate_url": "Obfuscate the Invite URL",
|
||||
"hide-the-links": " LINKS (GUEST INVITES & SCENES)",
|
||||
"invite-users-to-join": "Guests can use the link to join the group room",
|
||||
"this-is-obs-browser-source-link": "Use in OBS or other studio software to capture the group video mix",
|
||||
"mute-scene": "mute in scene",
|
||||
"mute-guest": "mute guest",
|
||||
"record-local": " Record Local",
|
||||
"record-remote": " Record Remote",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings"
|
||||
"apply-new-guest-settings": "Aplicar configuración",
|
||||
"cancel": "Cancelar",
|
||||
"invisible-guests": "No Visible",
|
||||
"available-languages": "Idiomas Disponibles:",
|
||||
"add-more-here": "¡Añade más Aquí!",
|
||||
"add-to-calendar": "Añadir detalles a tu Calendario:",
|
||||
"add-to-google-calendar": "Añadir a Calendario Google",
|
||||
"add-to-outlook-calendar": "Añadir a Calendario Outlook",
|
||||
"add-to-yahoo-calendar": "Añadir a Calendario Yahoo"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Join by Room Name here",
|
||||
"enter-a-room-name-here": "Enter a Room Name here",
|
||||
"optional-room-password-here": "Optional room password here",
|
||||
"give-this-media-source-a-name-optional-": "Give this media source a name (optional)",
|
||||
"add-an-optional-password": "Add an optional password",
|
||||
"enter-room-name-here": "Enter Room name here",
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here"
|
||||
"join-by-room-name-here": "Unirse por Nombre de Sala aquí",
|
||||
"enter-a-room-name-here": "Introduce un Nombre de Sala aquí",
|
||||
"optional-room-password-here": "Password de sala opcional aquí",
|
||||
"give-this-media-source-a-name-optional-": "Dar a la fuente de nedios un nombre (opcional)",
|
||||
"add-an-optional-password": "Añadir una password opcional",
|
||||
"enter-room-name-here": "Introduce el nombre de Sala aquí",
|
||||
"enter-chat-message-to-send-here": "Introduce el mensaje de chat a enviar aquí",
|
||||
"optional": "opcional",
|
||||
"enter-the-room-name-here": "Introduce el nombre de Sala aquí",
|
||||
"enter-the-room-password-here": "Introduce el password de la Sala aquí"
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,56 @@
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " Record Remote",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Rejoindre via le nom de salle ici",
|
||||
@@ -187,6 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Donner un nom à cette source média (optionnel)",
|
||||
"add-an-optional-password": "Ajouter un mot de passe optionnel",
|
||||
"enter-room-name-here": "Saisir le nom de la salle ici",
|
||||
"enter-chat-message-to-send-here": "Saisir un message ici pour l'envoyer dans le tchat"
|
||||
"enter-chat-message-to-send-here": "Saisir un message ici pour l'envoyer dans le tchat",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,36 @@
|
||||
{
|
||||
"titles": {
|
||||
"toggle-the-chat": "Toggle the Chat",
|
||||
"mute-the-speaker": "Mute the Speaker",
|
||||
"mute-the-mic": "Mute the Mic",
|
||||
"disable-the-camera": "Disable the Camera",
|
||||
"settings": "Settings",
|
||||
"hangup-the-call": "Hangup the Call",
|
||||
"show-help-info": "Show Help Info",
|
||||
"language-options": "Language Options",
|
||||
"tip-hold-ctrl-command-to-select-multiple": "tip: Hold CTRL (command) to select Multiple",
|
||||
"ideal-for-1080p60-gaming-if-your-computer-and-upload-are-up-for-it": "Ideal for 1080p60 gaming, if your computer and upload are up for it",
|
||||
"better-video-compression-and-quality-at-the-cost-of-increased-cpu-encoding-load": "Better video compression and quality at the cost of increased CPU encoding load",
|
||||
"disable-digital-audio-effects-and-increase-audio-bitrate": "Disable digital audio-effects and increase audio bitrate",
|
||||
"the-guest-will-not-have-a-choice-over-audio-options": "The guest will not have a choice over audio-options",
|
||||
"the-guest-will-only-be-able-to-select-their-webcam-as-an-option": "The guest will only be able to select their webcam as an option",
|
||||
"hold-ctrl-and-the-mouse-wheel-to-zoom-in-and-out-remotely-of-compatible-video-streams": "Hold CTRL and the mouse wheel to zoom in and out remotely of compatible video streams",
|
||||
"add-a-password-to-make-the-stream-inaccessible-to-those-without-the-password": "Add a password to make the stream inaccessible to those without the password",
|
||||
"add-the-guest-to-a-group-chat-room-it-will-be-created-automatically-if-needed-": "Add the guest to a group-chat room; it will be created automatically if needed.",
|
||||
"customize-the-room-settings-for-this-guest": "Customize the room settings for this guest",
|
||||
"hold-ctrl-or-cmd-to-select-multiple-files": "Hold CTRL (or CMD) to select multiple files",
|
||||
"enter-an-https-url": "Enter an HTTPS URL",
|
||||
"toggle-the-chat": "Attiva o disattiva la chat",
|
||||
"mute-the-speaker": "Muta lo Speaker",
|
||||
"mute-the-mic": "Disattiva il microfono",
|
||||
"disable-the-camera": "Disattiva la Camera",
|
||||
"settings": "Impostazioni",
|
||||
"hangup-the-call": "Riaggancia la chiamata",
|
||||
"show-help-info": "Mostra Info Helo",
|
||||
"language-options": "Opzioni di lingua",
|
||||
"tip-hold-ctrl-command-to-select-multiple": "tip: Tieni premut CTRL (command) per selezionare multipla ",
|
||||
"ideal-for-1080p60-gaming-if-your-computer-and-upload-are-up-for-it": "Ideale per il gioco a 1080p60 , se il tuo computer e upload lo supportano",
|
||||
"better-video-compression-and-quality-at-the-cost-of-increased-cpu-encoding-load": "Migliore compressione e qualità video al costo di un maggiore carico di codifica della CPU ",
|
||||
"disable-digital-audio-effects-and-increase-audio-bitrate": "Disattiva gli effetti audio digitali e aumenta il bitrate audio ",
|
||||
"the-guest-will-not-have-a-choice-over-audio-options": "L'ospite non avrà scelta sulle opzioni audio",
|
||||
"the-guest-will-only-be-able-to-select-their-webcam-as-an-option": "L'ospite potrà solo selezionare la propria webcam come opzione",
|
||||
"hold-ctrl-and-the-mouse-wheel-to-zoom-in-and-out-remotely-of-compatible-video-streams": "Tieni premuto CTRL e la rotellina del mouse per ingrandire e ridurre in remoto i flussi video compatibili ",
|
||||
"add-a-password-to-make-the-stream-inaccessible-to-those-without-the-password": "Aggiungi una password per rendere il flusso inaccessibile a chi non ha la password",
|
||||
"add-the-guest-to-a-group-chat-room-it-will-be-created-automatically-if-needed-": "Aggiungere l'ospite a una chat room di gruppo; verrà creato automaticamente se necessario.",
|
||||
"customize-the-room-settings-for-this-guest": "Personalizza le impostazioni della stanza per questo ospite ",
|
||||
"hold-ctrl-or-cmd-to-select-multiple-files": "Tieni premuto CTRL (or CMD) per selezionare più file",
|
||||
"enter-an-https-url": "Inserisci un URL HTTPS ",
|
||||
"lucy-g": "Lucy G",
|
||||
"flaticon": "Flaticon",
|
||||
"creative-commons-by-3-0": "Creative Commons BY 3.0",
|
||||
"gregor-cresnar": "Gregor Cresnar",
|
||||
"add-this-video-to-any-remote-scene-1-": "Add this Video to any remote '&scene=1'",
|
||||
"forward-user-to-another-room-they-can-always-return-": "Forward user to another room. They can always return.",
|
||||
"start-recording-this-stream-experimental-views": "Start Recording this stream. *experimental*' views",
|
||||
"force-the-user-to-disconnect-they-can-always-reconnect-": "Force the user to Disconnect. They can always reconnect.",
|
||||
"change-this-audio-s-volume-in-all-remote-scene-views": "Change this Audio's volume in all remote '&scene' views",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Remotely Mute this Audio in all remote '&scene' views",
|
||||
"disable-video-preview": "Disable Video Preview",
|
||||
"add-this-video-to-any-remote-scene-1-": "Aggiungi questo video a una scena in remoto '&scene=1'",
|
||||
"forward-user-to-another-room-they-can-always-return-": "Inoltra l'utente a un'altra stanza. Possono sempre tornare.",
|
||||
"start-recording-this-stream-experimental-views": "Inizia a registrare questo flusso. visualizzazioni *sperimentale*'",
|
||||
"force-the-user-to-disconnect-they-can-always-reconnect-": "Forza l'utente a disconnettersi. Possono sempre riconnettersi.",
|
||||
"change-this-audio-s-volume-in-all-remote-scene-views": "Cambia il volume di questo audio in tutte le scene in remoto '&scene'",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Disattiva l'audio in remoto '&scene'",
|
||||
"disable-video-preview": "Disattiva anteprima video",
|
||||
"low-quality-preview": "Low-Quality Preview",
|
||||
"high-quality-preview": "High-Quality Preview",
|
||||
"send-direct-message": "Send Direct Message",
|
||||
@@ -84,7 +84,56 @@
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
@@ -159,13 +208,13 @@
|
||||
"add-more-here": "Aggiungi altro qui!",
|
||||
"waiting-for-camera-to-load": "waiting-for-camera-to-load",
|
||||
"start": "START",
|
||||
"share-your-mic": "Share your microphone",
|
||||
"share-your-camera": "Share your Camera",
|
||||
"share-your-screen": "Share your Screen",
|
||||
"join-room-with-mic": "Join room with Microphone",
|
||||
"share-screen-with-room": "Share-screen with Room",
|
||||
"join-room-with-camera": "Join room with Camera",
|
||||
"click-start-to-join": "Click Start to Join",
|
||||
"share-your-mic": "Condividi il tuo microfono",
|
||||
"share-your-camera": "Condividi Camera",
|
||||
"share-your-screen": "Condividi il tuo schermo",
|
||||
"join-room-with-mic": "Entra nella stanza con il Microfono",
|
||||
"share-screen-with-room": "Condivisione dello schermo con la stanza",
|
||||
"join-room-with-camera": "Entra nella stanza con la Camera ",
|
||||
"click-start-to-join": "Fare clic su Start per partecipare",
|
||||
"guests-only-see-director": "Guests can only see the Director's Video",
|
||||
"default-codec-select": "Preferred Video Codec: ",
|
||||
"obfuscate_url": "Obfuscate the Invite URL",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " Record Remote",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Join by Room Name here",
|
||||
@@ -187,6 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Give this media source a name (optional)",
|
||||
"add-an-optional-password": "Add an optional password",
|
||||
"enter-room-name-here": "Enter Room name here",
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here"
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,56 @@
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " Record Remote",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Join by Room Name here",
|
||||
@@ -187,6 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Give this media source a name (optional)",
|
||||
"add-an-optional-password": "Add an optional password",
|
||||
"enter-room-name-here": "Enter Room name here",
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here"
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"titles": {
|
||||
"toggle-the-chat": "Chat aan/uit",
|
||||
"mute-the-speaker": "Demp de sSreker",
|
||||
"mute-the-speaker": "Demp de Spreker",
|
||||
"mute-the-mic": "Demp de Mic",
|
||||
"disable-the-camera": "Camera uitzetten",
|
||||
"settings": "Instellingen",
|
||||
@@ -24,18 +24,18 @@
|
||||
"flaticon": "Flaticon",
|
||||
"creative-commons-by-3-0": "Creative Commons BY 3.0",
|
||||
"gregor-cresnar": "Gregor Cresnar",
|
||||
"add-this-video-to-any-remote-scene-1-": "Add this Video to any remote '&scene=1'",
|
||||
"forward-user-to-another-room-they-can-always-return-": "Stuur gast door naar andere room, kan terugkeren.",
|
||||
"start-recording-this-stream-experimental-views": "Stream opnemen starten. *experimenteel*' views",
|
||||
"add-this-video-to-any-remote-scene-1-": "Voeg deze video toe aan iedereen met '&scene=1'",
|
||||
"forward-user-to-another-room-they-can-always-return-": "Stuur gast door naar andere kamer,deze kan terugkeren.",
|
||||
"start-recording-this-stream-experimental-views": "Stream opnemen starten. *experimenteel*",
|
||||
"force-the-user-to-disconnect-they-can-always-reconnect-": "Forceer einde verbinding, kan wel opnieuw verbinden.",
|
||||
"change-this-audio-s-volume-in-all-remote-scene-views": "Change this Audio's volume in all remote '&scene' views",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Remotely Mute this Audio in all remote '&scene' views",
|
||||
"change-this-audio-s-volume-in-all-remote-scene-views": "Veranderd dit audio volume in alle '&scene' weergaven",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Op afstand dempen van deze audio op alle '&scene' weergavens",
|
||||
"disable-video-preview": "Schakel Video Preview uit",
|
||||
"low-quality-preview": "Lage kwaliteit Preview",
|
||||
"high-quality-preview": "Hoge kwaliteit Preview",
|
||||
"send-direct-message": "Stuur een Direct Message",
|
||||
"advanced-settings-and-remote-control": "Geavanceerde instellingen en Remote Conntrol",
|
||||
"toggle-voice-chat-with-this-guest": "Schakel Voice chat aan/uit met deze gast",
|
||||
"send-direct-message": "Stuur een prive bericht",
|
||||
"advanced-settings-and-remote-control": "Geavanceerde instellingen en Remote Control",
|
||||
"toggle-voice-chat-with-this-guest": "Schakel geluids chat aan/uit met deze gast",
|
||||
"join-by-room-name-here": "Voer een naam in voor snelle toegang",
|
||||
"join-room": "Ga de kamer in",
|
||||
"share-a-screen-with-others": "Deel je scherm met anderen",
|
||||
@@ -50,7 +50,7 @@
|
||||
"add-your-camera-to-obs": "Voeg je camera aan OBS toe",
|
||||
"remote-screenshare-into-obs": "Schermdelen naar OBS",
|
||||
"create-reusable-invite": "creëer herbruikbaare link",
|
||||
"encode-the-url-so-that-it-s-harder-for-a-guest-to-modify-the-settings-": "Encode the URL so that it's harder for a guest to modify the settings.",
|
||||
"encode-the-url-so-that-it-s-harder-for-a-guest-to-modify-the-settings-": "Coder de link zo dat het moeilijker is voor de gast om er achter te komen welke instellingen ingesteld staan",
|
||||
"more-options": "Meer opties",
|
||||
"youtube-video-demoing-how-to-do-this": "Youtube video voorbeelden, hoe dit te doen!",
|
||||
"invite-a-guest-or-camera-source-to-publish-into-the-group-room": "Vraag een gast zijn beeld te publiceren in de kamer",
|
||||
@@ -85,22 +85,62 @@
|
||||
"remote-audio-settings": "Audio instellingen op afstand",
|
||||
"advanced-video-settings": "Geavanceerde instellingen van video",
|
||||
"activate-or-reload-this-video-device-": "Activeer of herlaadt deze video bron.",
|
||||
"create-a-seconary-stream": "Create a Seconary Stream",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"create-a-secondary-stream": "Maak een tweede stream aan",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "De director zal zichtbaar zijn in de scenes, alsof hij ook een gast is.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Handig als je de director en gast tegelijk wilt zijn.",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output"
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "Waneer uitgeschakeld, zal de uitgenodigde gast niemand kunnen horen of zien in de kamer.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "Wanneer uitgeschakeld, moet je handmatig eeen video toevoegen aan een scene voordat deze zichtbaar wordt.",
|
||||
"toggle-solo-voice-chat": "Schakel Solo Geluids Chat",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Schakel de gast's speaker uitgang",
|
||||
"toggle-the-remote-guest-s-display-output": "Schakel de gast's beeld uitgang",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS Ninja",
|
||||
"copy-this-url": "Deelbare Link naar deze video",
|
||||
"you-are-in-the-control-center": "U bent in het kamer beheers centrum",
|
||||
"joining-room": "U neemt deel aan de kamer",
|
||||
"add-group-chat": "Voeg Groepsgesprek toe",
|
||||
"add-group-chat": "Voeg groepsgesprek toe",
|
||||
"rooms-allow-for": "Kamers maken eenvoudige groepsgespreken en geavanceerd beheer van meerdere streams tegelijkertijd mogelijk.",
|
||||
"room-name": "Kamer Naam",
|
||||
"password-input-field": "Password",
|
||||
@@ -126,11 +166,11 @@
|
||||
"here-you-can-pre-generate": "Hier kan u vooraf een herbruikbare weergave link en een bijbehorende gast uitnodigingslink aanmaken.",
|
||||
"generate-invite-link": "GENEREER DE UITNODIGINGS LINK",
|
||||
"advanced-paramaters": "Geavanceerde Parameters",
|
||||
"unlock-video-bitrate": "Ontsluit Video Bitrate (20mbps)",
|
||||
"unlock-video-bitrate": "Verwijder limitatie video bitrate (20mbps)",
|
||||
"force-vp9-video-codec": "Forceer VP9 Video Codec (minder verstoring)",
|
||||
"enable-stereo-and-pro": "Activeer Stereo en Pro HD Geluid",
|
||||
"video-resolution": "Video Resolutie: ",
|
||||
"hide-mic-selection": "Force Default Microphone",
|
||||
"hide-mic-selection": "Forceer Standaard Microfoon",
|
||||
"hide-screen-share": "Verberg Scherm Delen Optie",
|
||||
"allow-remote-control": "Afstandsbediening Camera Zoom (android)",
|
||||
"add-a-password-to-stream": " Add a password:",
|
||||
@@ -139,28 +179,28 @@
|
||||
"can-see-and-hear": "Het groepsgesprek zien en horen",
|
||||
"can-hear-only": "Alleen het groepsgesprek horen",
|
||||
"cant-see-or-hear": "Het groepsgesprek niet horen en zien",
|
||||
"share-local-video-file": "Stream Media File",
|
||||
"share-website-iframe": "Share Website",
|
||||
"run-a-speed-test": "Run a Speed Test",
|
||||
"read-the-guides": "Browse the Guides",
|
||||
"share-local-video-file": "Stream Media Bestand",
|
||||
"share-website-iframe": "Deel Website",
|
||||
"run-a-speed-test": "Doe een Speed Test",
|
||||
"read-the-guides": "Blader in de handleidingen",
|
||||
"info-blob": "\n\t\t\t\t\t\t<h2>Wat is OBS.Ninja</h2><br>\n\t\t\t\t\t\t<li>100% <b>gratis</b>; geen downloads; geen persoonlijke gegevens verzamelen; niet inloggen</li>\n\t\t\t\t\t\t<li>Breng video van uw smartphone, laptop, computer, of van uw vrienden direct in uw OBS video stroom</li>\n\t\t\t\t\t\t<li>We gebruiken vooruitstrevende Peer-to-Peer technologie die privacy en ultra lage vertraging biedt</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\">Demonstratie</a> </li>\n\t\t\t\t\t\t",
|
||||
"add-to-scene": "Add to Scene",
|
||||
"forward-to-room": "Transfer",
|
||||
"add-to-scene": "Toevoegen aan Scene",
|
||||
"forward-to-room": "Doorverbinden",
|
||||
"record": "Neem op",
|
||||
"disconnect-guest": "Hangup",
|
||||
"disconnect-guest": "Ophangen",
|
||||
"mute": "Demp",
|
||||
"change-to-low-quality": " <i class=\"las la-video-slash\"></i>",
|
||||
"change-to-medium-quality": " <i class=\"las la-video\"></i>",
|
||||
"change-to-high-quality": " <i class=\"las la-binoculars\"></i>",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Message",
|
||||
"advanced-camera-settings": "<i class=\"las la-cog\"></i> Advanced",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Voice Chat",
|
||||
"open-in-new-tab": "Open in nieuwe Tab",
|
||||
"copy-to-clipboard": "Kopiëren naar Clipboard",
|
||||
"click-for-quick-room-overview": "❔ Click Here for a quick overview and help",
|
||||
"push-to-talk-enable": "🔊 Enable Director's Push-to-Talk Mode",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Bericht",
|
||||
"advanced-camera-settings": "<i class=\"las la-cog\"></i> Geavanceerd",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Geluids Chat",
|
||||
"open-in-new-tab": "Open in nieuw tabblad",
|
||||
"copy-to-clipboard": "Kopiëren naar klembord",
|
||||
"click-for-quick-room-overview": "❔ Klik hier voor een snel overzicht en hulp",
|
||||
"push-to-talk-enable": "🔊 Enable Director's Push-to-Talk Mode Zet ",
|
||||
"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>",
|
||||
"more-than-four-can-join": "These four guest slots are just for demonstration. More than four guests can actually join a room.",
|
||||
"more-than-four-can-join": "Er staan momenteel vier gasten plekken gevuld voor de demonstratie. Het is mogelijk om meer gasten te hebben in een kamer.",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tWelcome to OBS.Ninja! You can send text messages directly to connected peers from here.\n\t\t\t\t",
|
||||
"names-and-labels-coming-soon": "\n\t\t\t\t\tNames identifying connected peers will be a feature in an upcoming release.\n\t\t\t\t",
|
||||
"send-chat": "Verstuur",
|
||||
@@ -188,17 +228,78 @@
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio instellingen",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest"
|
||||
"scenes-can-see-director": "Director is ook een gast",
|
||||
"toggle-remote-speaker": "Verdoof Gast",
|
||||
"toggle-remote-display": "Verblind Gast",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Ga binnen met een kamer naam",
|
||||
"enter-a-room-name-here": "Geef hier een kamer naam op",
|
||||
"optional-room-password-here": "Optionele wachtwoord voor kamer",
|
||||
"give-this-media-source-a-name-optional-": "Geef de media bron een naam(optioneel)",
|
||||
"give-this-media-source-a-name-optional-": "Geef de media bron een naam (optioneel)",
|
||||
"add-an-optional-password": "Voeg optioneel wachtwoord toe",
|
||||
"enter-room-name-here": "Geef hier de kamer naam op",
|
||||
"enter-chat-message-to-send-here": "Type hier om te chatten"
|
||||
"enter-chat-message-to-send-here": "Type hier om te chatten",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,56 @@
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS Ninja - Pig Latin",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " Record Remote",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Erehay ouyay ancay epray-enerategay",
|
||||
@@ -187,6 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Erehay ouyay ancay epray-enerategay",
|
||||
"add-an-optional-password": "Erehay ouyay ancay epray-enerategay",
|
||||
"enter-room-name-here": "Erehay ouyay ancay epray-enerategay",
|
||||
"enter-chat-message-to-send-here": "Erehay ouyay ancay epray-enerategay"
|
||||
"enter-chat-message-to-send-here": "Erehay ouyay ancay epray-enerategay",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -36,55 +36,104 @@
|
||||
"send-direct-message": "Enviar mensagem direta",
|
||||
"advanced-settings-and-remote-control": "Opções avançadas e Controlo Remoto",
|
||||
"toggle-voice-chat-with-this-guest": "Ativar/desativar conversa de voz com este convidado",
|
||||
"join-by-room-name-here": "Enter a room name to quick join",
|
||||
"join-room": "Join room",
|
||||
"share-a-screen-with-others": "Share a Screen with others",
|
||||
"alert-the-host-you-want-to-speak": "Alert the host you want to speak",
|
||||
"record-your-stream-to-disk": "Record your stream to disk",
|
||||
"join-by-room-name-here": "Introduza o nome de uma sala",
|
||||
"join-room": "Entrar na sala",
|
||||
"share-a-screen-with-others": "Partilhar o ecrã",
|
||||
"alert-the-host-you-want-to-speak": "Avise o anfitrião que deseja falar",
|
||||
"record-your-stream-to-disk": "Guarde o seu stream para o disco",
|
||||
"cancel-the-director-s-video-audio": "Cancel the Director's Video/Audio",
|
||||
"submit-any-error-logs": "Submit any error logs",
|
||||
"add-group-chat-to-obs": "Add Group Chat to OBS",
|
||||
"submit-any-error-logs": "Submeta registos de erros",
|
||||
"add-group-chat-to-obs": "Adicionar conversa de grupo ao OBS",
|
||||
"for-large-group-rooms-this-option-can-reduce-the-load-on-remote-guests-substantially": "For large group rooms, this option can reduce the load on remote guests substantially",
|
||||
"which-video-codec-would-you-want-used-by-default-": "Which video codec would you want used by default?",
|
||||
"you-ll-enter-as-the-room-s-director": "You'll enter as the room's director",
|
||||
"add-your-camera-to-obs": "Add your Camera to OBS",
|
||||
"remote-screenshare-into-obs": "Remote Screenshare into OBS",
|
||||
"create-reusable-invite": "Create Reusable Invite",
|
||||
"encode-the-url-so-that-it-s-harder-for-a-guest-to-modify-the-settings-": "Encode the URL so that it's harder for a guest to modify the settings.",
|
||||
"more-options": "More Options",
|
||||
"youtube-video-demoing-how-to-do-this": "Youtube Video demoing how to do this",
|
||||
"invite-a-guest-or-camera-source-to-publish-into-the-group-room": "Invite a guest or camera source to publish into the group room",
|
||||
"if-enabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If enabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Use this link in the OBS Browser Source to capture the video or audio",
|
||||
"if-enabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If enabled, you must manually add a video to a scene for it to appear.",
|
||||
"disables-echo-cancellation-and-improves-audio-quality": "Disables Echo Cancellation and improves audio quality",
|
||||
"audio-only-sources-are-visually-hidden-from-scenes": "Audio-only sources are visually hidden from scenes",
|
||||
"guest-will-be-prompted-to-enter-a-display-name": "Guest will be prompted to enter a Display Name",
|
||||
"display-names-will-be-shown-in-the-bottom-left-corner-of-videos": "Display Names will be shown in the bottom-left corner of videos",
|
||||
"request-1080p60-from-the-guest-instead-of-720p60-if-possible": "Request 1080p60 from the Guest instead of 720p60, if possible",
|
||||
"the-default-microphone-will-be-pre-selected-for-the-guest": "The default microphone will be pre-selected for the guest",
|
||||
"the-default-camera-device-will-selected-automatically": "The default camera device will selected automatically",
|
||||
"the-guest-won-t-have-access-to-changing-camera-settings-or-screenshare": "The guest won't have access to changing camera settings or screenshare",
|
||||
"the-guest-will-not-see-their-own-self-preview-after-joining": "The guest will not see their own self-preview after joining",
|
||||
"guests-will-have-an-option-to-poke-the-director-by-pressing-a-button": "Guests will have an option to poke the Director by pressing a button",
|
||||
"add-an-audio-compressor-to-the-guest-s-microphone": "Add an audio compressor to the guest's microphone",
|
||||
"add-an-equalizer-to-the-guest-s-microphone-that-the-director-can-control": "Add an Equalizer to the guest's microphone that the director can control",
|
||||
"the-guest-can-only-see-the-director-s-video-if-provided": "The guest can only see the Director's video, if provided",
|
||||
"the-guest-s-microphone-will-be-muted-on-joining-they-can-unmute-themselves-": "The guest's microphone will be muted on joining. They can unmute themselves.",
|
||||
"have-the-guest-join-muted-so-only-the-director-can-unmute-the-guest-": "Have the guest join muted, so only the director can Unmute the guest.",
|
||||
"make-the-invite-url-encoded-so-parameters-are-harder-to-tinker-with-by-guests": "Make the invite URL encoded, so parameters are harder to tinker with by guests",
|
||||
"move-the-user-to-another-room-controlled-by-another-director": "Move the user to another room, controlled by another director",
|
||||
"send-a-direct-message-to-this-user-": "Send a Direct Message to this user.",
|
||||
"remotely-change-the-volume-of-this-guest": "Remotely change the volume of this guest",
|
||||
"mute-this-guest-everywhere": "Mute this guest everywhere",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Start Recording this remote stream to this local drive. *experimental*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "The Remote Guest will record their local stream to their local drive. *experimental*",
|
||||
"shift-this-video-down-in-order": "Shift this Video Down in Order",
|
||||
"current-index-order-of-this-video": "Current Index Order of this Video",
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"which-video-codec-would-you-want-used-by-default-": "Qual é o codec de vídeo que deseja usar por omissão?",
|
||||
"you-ll-enter-as-the-room-s-director": "Vai entrar como o Realizador da sala",
|
||||
"add-your-camera-to-obs": "Adicione a sua câmera ao OBS",
|
||||
"remote-screenshare-into-obs": "Partilha de ecrã remota para OBS",
|
||||
"create-reusable-invite": "Criar convite reutilizável",
|
||||
"encode-the-url-so-that-it-s-harder-for-a-guest-to-modify-the-settings-": "Obfuscar o URL para tornar mais difícil a um convidado modificar as definições.",
|
||||
"more-options": "Mais Opções",
|
||||
"youtube-video-demoing-how-to-do-this": "Vídeo de Youtube a explicar como fazer",
|
||||
"invite-a-guest-or-camera-source-to-publish-into-the-group-room": "Convide alguém para publicar a câmera no grupo",
|
||||
"if-enabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "Se ativado, o utilizador convidado não poderá ver ou ouvir ninguém na sala.",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Use este link numa fonte Browser do OBS para capturar o vídeo ou áudio",
|
||||
"if-enabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "Se ativado, deve adicionar manualmente o vídeo a uma cena para ele aparecer.",
|
||||
"disables-echo-cancellation-and-improves-audio-quality": "Desativa o Cancelamento de eco e melhora a qualidade de áudio",
|
||||
"audio-only-sources-are-visually-hidden-from-scenes": "Fontes de áudio são visualmente escondidas das cenas",
|
||||
"guest-will-be-prompted-to-enter-a-display-name": "O convidado poderá introduzir um nome que o identifique",
|
||||
"display-names-will-be-shown-in-the-bottom-left-corner-of-videos": "Os nomes serão mostrados no canto inferior esquerdo dos vídeos",
|
||||
"request-1080p60-from-the-guest-instead-of-720p60-if-possible": "Pedir 1080p60 do convidado, em vez de 720p60, se possível",
|
||||
"the-default-microphone-will-be-pre-selected-for-the-guest": "O microfone predefinido será selecionado",
|
||||
"the-default-camera-device-will-selected-automatically": "A câmera predefinida será selecionada automaticamente",
|
||||
"the-guest-won-t-have-access-to-changing-camera-settings-or-screenshare": "O convidado não terá acesso a alterar as opções de câmera ou partilha de ecrã",
|
||||
"the-guest-will-not-see-their-own-self-preview-after-joining": "O convidado não verá a sua própria imagem quando entrar",
|
||||
"guests-will-have-an-option-to-poke-the-director-by-pressing-a-button": "Os convidados terão a opção de chamar a atenção do realizador pressionando um botão",
|
||||
"add-an-audio-compressor-to-the-guest-s-microphone": "Adicionar um compressor de áudio ao microfone dos convidados",
|
||||
"add-an-equalizer-to-the-guest-s-microphone-that-the-director-can-control": "Adicionar um equalizador ao microfone dos convidados, controlável pelo realizador",
|
||||
"the-guest-can-only-see-the-director-s-video-if-provided": "O convidado apenas pode ver o vídeo do realizador, se providenciado",
|
||||
"the-guest-s-microphone-will-be-muted-on-joining-they-can-unmute-themselves-": "O microfone dos convidados começa em mute. Eles poderão remover o mute.",
|
||||
"have-the-guest-join-muted-so-only-the-director-can-unmute-the-guest-": "Os convidados começam em mute, apenas o realizador pode ativar o som.",
|
||||
"make-the-invite-url-encoded-so-parameters-are-harder-to-tinker-with-by-guests": "Obfuscar o link de convite, para dificultar a manipulação por parte dos convidados",
|
||||
"move-the-user-to-another-room-controlled-by-another-director": "Enviar o utilizador para outra sala, controlada pelo mesmo realizador",
|
||||
"send-a-direct-message-to-this-user-": "Envie uma Mensagem Direta a este utilizador.",
|
||||
"remotely-change-the-volume-of-this-guest": "Altere remotamente o volume deste utilizador",
|
||||
"mute-this-guest-everywhere": "Tire o som a este utilizador em todo o lado",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Começar a gravar este stream remoto para este disco local. *experimental*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "O convidado remoto irá gravar o seu stream local para o seu disco local. *experimental*",
|
||||
"shift-this-video-down-in-order": "Desça a posição deste vídeo",
|
||||
"current-index-order-of-this-video": "Posição atual deste vídeo",
|
||||
"shift-this-video-up-in-order": "Suba a posição deste vídeo",
|
||||
"remote-audio-settings": "Opções de áudio remoto",
|
||||
"advanced-video-settings": "Opções de vídeo avançadas",
|
||||
"activate-or-reload-this-video-device-": "Ativar ou recarregar este dispositivo de vídeo.",
|
||||
"load-the-next-guest-in-queue": "Carregar o próximo convidado da fila",
|
||||
"create-a-secondary-stream": "Criar um stream secundário",
|
||||
"add-to-calendar": "Adicionar ao calendário",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "O realizador será visível em todas as cenas, como se ele próprio fosse um convidado.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Útil se deseja realizar e participar ao mesmo tempo",
|
||||
"start-streaming": "iniciar streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "Se desativado, o convidado não poderá ver ou ouvir ninguém na sala.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "Se desativado, deve adicionar manualmente um vídeo a uma cena para ele aparecer.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Convidados que não falem serão escondidos",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Aumentar qualidade do vídeo que os convidados da sala vêem.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "Não será pedido um dispositivo de vídeo ao convidado ao ligar-se",
|
||||
"toggle-solo-voice-chat": "Ativar chat de voz solo",
|
||||
"add-to-scene-2": "Adicionar à Cena 2",
|
||||
"add-to-scene-3": "Adicionar à Cena 3",
|
||||
"add-to-scene-4": "Adicionar à Cena 4",
|
||||
"add-to-scene-5": "Adicionar à Cena 5",
|
||||
"add-to-scene-6": "Adicionar à cena 6",
|
||||
"add-to-scene-7": "Adicionar à Cena 7",
|
||||
"hide-this-guest-everywhere": "Esconder este convidado em todo o lado",
|
||||
"set-to-default-audio-channel": "Definir para Canal de áudio por omissão",
|
||||
"set-to-audio-channel-1": "Definir Canal de áudio 1",
|
||||
"set-to-audio-channel-2": "Definir Canal de áudio 2",
|
||||
"set-to-audio-channel-3": "Definir Canal de áudio 3",
|
||||
"set-to-audio-channel-4": "Definir Canal de áudio 4",
|
||||
"set-to-audio-channel-5": "Definir Canal de áudio 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Ativar/Desativar a saída de som remota do convidado",
|
||||
"toggle-the-remote-guest-s-display-output": "Ativar/Desativar a saída de imagem remota do convidado",
|
||||
"set-to-audio-channel-6": "Definir Canal de áudio 6",
|
||||
"set-to-audio-channel-7": "Definir Canal de áudio 7",
|
||||
"set-to-audio-channel-8": "Definir Canal de áudio 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Forçar o envio de uma keyframe por parte da fonte, para todas as cenas, corrigindo a imagem esborratada de pixeis.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Recarregar a página do utilizador remotamente com um novo URL",
|
||||
"change-user-parameters": "Mudar parâmetros do utilizador",
|
||||
"solo-this-video-everywhere": "Fazer solo deste vídeo em todo o lado",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Pedir estatísticas deste vídeo em qualquer Cena ativa",
|
||||
"cannot-see-videos": "Não pode ver vídeos",
|
||||
"cannot-hear-others": "Não pode ouvir outros",
|
||||
"see-director-only": "Ver apenas o realizador",
|
||||
"show-mini-preview": "Mostrar Mini previsualização",
|
||||
"raise-hand-button": "Botão de levantar a mão",
|
||||
"show-labels": "Mostrar identificadores",
|
||||
"transfer-to-a-new-room": "Transferir para uma nova Sala",
|
||||
"enable-custom-password": "Ativar password personalizada",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
@@ -145,11 +194,11 @@
|
||||
"change-to-high-quality": " <i class=\"las la-binoculars\"></i>",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Enviar mensagem",
|
||||
"advanced-camera-settings": "<i class=\"las la-cog\"></i> Avançadas",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Voice Chat",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Chat de voz",
|
||||
"open-in-new-tab": "Abrir num novo separador",
|
||||
"copy-to-clipboard": "Copiar para área de transferência",
|
||||
"click-for-quick-room-overview": "❔ Clique aqui para uma pequena apresentação e ajuda",
|
||||
"push-to-talk-enable": "🔊 Ativar Push-to-talk do diretor",
|
||||
"push-to-talk-enable": "🔊 Ativar Push-to-talk do realizador",
|
||||
"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>",
|
||||
"more-than-four-can-join": "Estes quatro convidados são apenas ilustrativos. Podem juntar-se mais de quatro convidados numa sala.",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tBem vindo ao OBS.Ninja! Pode enviar mensagens diretas a quem estiver aqui ligado a partir daqui.\n\t\t\t\t",
|
||||
@@ -166,7 +215,7 @@
|
||||
"share-screen-with-room": "Partilhar o ecrã com a sala",
|
||||
"join-room-with-camera": "Entrar na sala com câmera",
|
||||
"click-start-to-join": "Clique iniciar para se entrar",
|
||||
"guests-only-see-director": "Os convidados só podem ver o vídeo do Diretor",
|
||||
"guests-only-see-director": "Os convidados só podem ver o vídeo do Realizador",
|
||||
"default-codec-select": "Codec de Vídeo preferido: ",
|
||||
"obfuscate_url": "Obfuscar o URL do convite",
|
||||
"hide-the-links": " LINKS (CONVITES & CENAS)",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " Gravação Remota",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Definições de Áudio"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Definições de Áudio",
|
||||
"scenes-can-see-director": "O realizador também será um participante",
|
||||
"select-digital-effect": " Efeitos de Vídeo Digitais: ",
|
||||
"add-a-password": " Adicionar uma Password:",
|
||||
"hide-guest": "esconder convidado",
|
||||
"toggle-remote-speaker": "Ensurdecer convidado",
|
||||
"toggle-remote-display": "Cegar convidado",
|
||||
"force-keyframe": "Vomitado arco-íris",
|
||||
"change-url": "Mudar URL",
|
||||
"change-params": "Parâmetros de URL",
|
||||
"solo-video": "Destacar convidado",
|
||||
"stats-remote": " Estatísticas da Cena",
|
||||
"apply-new-guest-settings": "Aplicar definições",
|
||||
"cancel": "Cancelar",
|
||||
"add-to-calendar": "Adicionar detalhes ao seu calendário:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Introduza aqui numa sala pelo seu nome",
|
||||
@@ -187,86 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Dê um nome a esta fonte de mídia (opcional)",
|
||||
"add-an-optional-password": "Introduza uma password (opcional)",
|
||||
"enter-room-name-here": "Introduza nome da sala aqui",
|
||||
"enter-chat-message-to-send-here": "Introduza mensagem a enviar aqui"
|
||||
},
|
||||
"logo-header": "\n\t\t\t\t\t<font id=\"qos\">O</font>BS.Ninja \n\t\t\t\t",
|
||||
"copy-this-url": "Copie este URL para uma \"Browser Source\" do OBS",
|
||||
"you-are-in-the-control-center": "Centro de controlo da sala:",
|
||||
"joining-room": "Está na sala",
|
||||
"add-group-chat": "Criar uma Sala",
|
||||
"rooms-allow-for": "As salas permitem converesas de grupo e ferramentas para gerir múltiplos convidados.",
|
||||
"room-name": "Nome da sala",
|
||||
"password-input-field": "Password",
|
||||
"guests-only-see-director": "Convidados só podem ver o vídeo do Diretor",
|
||||
"default-codec-select": "Codec vídeo preferido: ",
|
||||
"enter-the-rooms-control": "Entrar no controlo da sala",
|
||||
"show-tips": "Mostre-me dicas..",
|
||||
"added-notes": "\n\t\t\t\t\t\t\t\t<u>\n\t\t\t\t\t\t\t\t\t<i>Important Tips:</i><br><br>\n\t\t\t\t\t\t\t\t</u>\n\t\t\t\t\t\t\t\t<li>Disabling video sharing between guests will improve performance</li>\n\t\t\t\t\t\t\t\t<li>Invite only guests to the room that you trust.</li>\n\t\t\t\t\t\t\t\t<li>The \"Recording\" option is considered experimental.</li>\n\t\t\t\t\t\t\t\t<li><a href=\"https://params.obs.ninja\" style=\"color:black;\"><u>Advanced URL parameters</u></a> are available to customize rooms.</li>\n\t\t\t\t\t\t\t",
|
||||
"back": "Voltar",
|
||||
"add-your-camera": "Adicionar câmera ao OBS",
|
||||
"ask-for-permissions": "Permitir Acesso à Câmera/Microfone",
|
||||
"waiting-for-camera": "A esperar que a câmera carregue",
|
||||
"video-source": " Fonte de vídeo ",
|
||||
"max-resolution": "1080p (hd)",
|
||||
"balanced": "720p (equilibrado)",
|
||||
"smooth-cool": "360p (suave)",
|
||||
"select-audio-source": " Fonte(s) de Áudio ",
|
||||
"no-audio": "Sem Áudio",
|
||||
"select-output-source": " Saída de áudio: ",
|
||||
"remote-screenshare-obs": "Partilha de ecrã remota no OBS",
|
||||
"note-share-audio": "\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<video id=\"screenshare\" autoplay=\"true\" muted=\"true\" loop=\"\" src=\"./images/screenshare.webm\"></video>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t",
|
||||
"select-screen-to-share": "SELECIONE ECRÃ A PARTILHAR",
|
||||
"audio-sources": "Fontes de Áudio",
|
||||
"create-reusable-invite": "Criar convite reutilizável",
|
||||
"here-you-can-pre-generate": "Aqui pode gerar um link para convidar e o respetivo link de visualização.",
|
||||
"generate-invite-link": "GERAR O LINK DO CONVITE",
|
||||
"advanced-paramaters": "Opções Avançadas",
|
||||
"unlock-video-bitrate": "Desbloquear Bitrate de Vídeo (20mbps)",
|
||||
"force-vp9-video-codec": "Forçar Codec de Vídeo VP9",
|
||||
"enable-stereo-and-pro": "Ativar som stereo e Pro HD",
|
||||
"video-resolution": "Resolução do vídeo: ",
|
||||
"hide-mic-selection": "Forçar Microfone predefinido",
|
||||
"hide-screen-share": "Esconder opção de partilha de ecrã",
|
||||
"allow-remote-control": "Controlar ao zoom da câmera remotamente (android)",
|
||||
"obfuscate_url": "Obfuscar o URL do convite",
|
||||
"add-a-password-to-stream": " Adicionar a password:",
|
||||
"add-the-guest-to-a-room": " Adicionar o convidado a uma sala:",
|
||||
"invite-group-chat-type": "Este convidado pode:",
|
||||
"can-see-and-hear": "Pode ver e ouvir o chat de grupo",
|
||||
"can-hear-only": "APenas pode ouvir o chat de grupo",
|
||||
"cant-see-or-hear": "Não pode ver nem ouvir o chat de grupo",
|
||||
"share-local-video-file": "Stream de ficheiro de mídia",
|
||||
"share-website-iframe": "Partilhar Website",
|
||||
"run-a-speed-test": "Teste de Velocidade",
|
||||
"read-the-guides": "Consultar os Guias",
|
||||
"info-blob": "\n\t\t\t\t\t\t\t<h2>O que é o OBS.Ninja</h2>\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<li>100% \n\t\t\t\t\t\t\t\t<b>gratuito</b>; sem downloads; sem recolha de dados pessoais; sem login\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>Bring video from your smartphone, computer, or friends directly into your OBS video stream</li>\n\t\t\t\t\t\t\t<li>We use cutting edge Peer-to-Peer forwarding technology that offers privacy and ultra-low latency</li>\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<li>Youtube video \n\t\t\t\t\t\t\t\t<i class=\"lab la-youtube\"></i>\n\t\t\t\t\t\t\t\t<a href=\"https://www.youtube.com/watch?v=vLpRzMjUDaE&list=PLWodc2tCfAH1WHjl4WAOOoRSscJ8CHACe&index=2\" alt=\"Youtube video demoing OBS.Ninja\">Demoing it here</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<i>\n\t\t\t\t\t\t\t\t<font style=\"color: red;\">Known issues:</font>\n\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\tMacOS users using OBS will need to update to <a href=\"https://github.com/obsproject/obs-studio/releases/tag/26.1.2\">OBS Studio 26.1.2</a> or resort to\n\t\t\t\t\t\t\t\twindow-capturing with the provided <a href=\"https://github.com/steveseguin/electroncapture\">Electron-Capture app</a>.\n \n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>If you have\t<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.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\tiOS devices may have occasional audio or camera issues, such as no sound or distorted sound. <a href=\"https://bugs.webkit.org/show_bug.cgi?id=218762\">Partially fixed in iOS 14.3</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\tThe 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.\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<br>\n\n 🥳 Site Updated: <a href=\"https://github.com/steveseguin/obsninja/wiki/v15-release-notes\">Jan 12th, 2021</a>. The previous version can be found at \n\t\t\t\t\t\t\t<a href=\"https://obs.ninja/v14/\">https://obs.ninja/v14/</a> if you are having new issues.\n\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<h3>\n\t\t\t\t\t\t\t\t<i>\n Check out the \n\t\t\t\t\t\t\t\t\t<a href=\"https://www.reddit.com/r/OBSNinja/\">sub-reddit\n\t\t\t\t\t\t\t\t\t<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\n\t\t\t\t\t\t\t\t\t<a href=\"https://discord.gg/T4xpQVv\">Discord <i class=\"lab la-discord\"></i></a> or email me at steve@seguin.email\n \n\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t",
|
||||
"hide-the-links": " LINKS (CONVITES PARA CONVIDADOS & CENAS)",
|
||||
"click-for-quick-room-overview": "\n\t\t\t\t\t\t<i class=\"las la-question-circle\"></i> Click Here for a quick overview and help\n\t\t\t\t\t",
|
||||
"welcome-to-control-room": "\n\t\t\t\t\t\t<b>Bem vindo. Esta é a sala de controlo do realizador do chat de grupo.</b><br><br>\n\t\t\t\t\t\tYou can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.\n\t\t\t\t\t\t<br><br>\n\t\t\t\t\t\t<font style=\"color:red\">Known Limitations with Group Rooms:</font><br>\n\t\t\t\t\t\t<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 <a href=\"https://www.youtube.com/watch?v=bpRa8-UYCGc\" title=\"Youtube Video demoing how to do this\">disable video sharing between guests</a>. Using &broadcast, &roombitrate=0 or &novideo are options there.</li>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\tFurther Notes:<br><br>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<li>You can use the auto-mixing Group Scenes, the green links, to auto arrange multiple videos for you in OBS.</li>\n\t\t\t\t\t\t<li>You can use this control room to record isolated video or audio streams, but it is an experimental feature still.</li>\n\t\t\t\t\t\t<li>If you transfer a guest from one room to another, they won't know which room they have been transferred to.</li>\n\t\t\t\t\t\t<li>OBS will see a guest's video in high-quality; the default video bitrate is 2500kbps. Setting higher bitrates will improve motion.</li>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<li>&stereo=2 can be added to guests to turn off audio effects, such as echo cancellation and noise-reduction.</li>\n\t\t\t\t\t\t<li>https://invite.cam is a free service provided that can help obfuscuate the URL parameters of an invite link given to guests.</li>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\n\t\t\t\t\t\tFor advanced URL options and parameters, <a href=\"https://github.com/steveseguin/obsninja/wiki/Advanced-Settings\">see the Wiki.</a>\n\t\t\t\t\t",
|
||||
"invite-users-to-join": "Os convidados podem usar o link para entrar na sala",
|
||||
"this-is-obs-browser-source-link": "Use no OBS ou outro software para capturar a mistura dos vídeos",
|
||||
"more-than-four-can-join": "Estes quatro campos são para efeitos demonstrativos. Podem entrar mais de quatro convidados numa sala.",
|
||||
"forward-to-room": "Transferir",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Mensagem",
|
||||
"add-to-scene": "Adicionar à Cena",
|
||||
"mute-scene": "mute na cena",
|
||||
"mute-guest": "mute ao convidado",
|
||||
"change-to-low-quality": " <i class=\"las la-video-slash\"></i>",
|
||||
"change-to-medium-quality": " <i class=\"las la-video\"></i>",
|
||||
"change-to-high-quality": " <i class=\"las la-binoculars\"></i>",
|
||||
"disconnect-guest": "Desligar",
|
||||
"record-local": " Gravação Local",
|
||||
"record-remote": " Gravação Remota",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Chat por voz",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Definições de Áudio",
|
||||
"advanced-camera-settings": "<i class=\"las la-sliders-h\"></i> Definições de Vídeo",
|
||||
"open-in-new-tab": "Abrir num novo separador",
|
||||
"copy-to-clipboard": "Copiar",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tWelcome to OBS.Ninja! You can send text messages directly to connected peers from here.\n\t\t\t\t",
|
||||
"names-and-labels-coming-soon": "\n\t\t\t\t\tNames identifying connected peers will be a feature in an upcoming release.\n\t\t\t\t",
|
||||
"send-chat": "Enviar",
|
||||
"available-languages": "Línguas disponíveis:",
|
||||
"add-more-here": "Adicionar mais aqui!"
|
||||
"enter-chat-message-to-send-here": "Introduza mensagem a enviar aqui",
|
||||
"optional": "opcional",
|
||||
"enter-the-room-name-here": "Introduza aqui o nome da sala",
|
||||
"enter-the-room-password-here": "Introduza aqui a password da sala"
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,56 @@
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja (RU)",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " Record Remote",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Join by Room Name here",
|
||||
@@ -187,6 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Give this media source a name (optional)",
|
||||
"add-an-optional-password": "Add an optional password",
|
||||
"enter-room-name-here": "Enter Room name here",
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here"
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,56 @@
|
||||
"shift-this-video-up-in-order": "Shift this Video Up in Order",
|
||||
"remote-audio-settings": "Remote Audio Settings",
|
||||
"advanced-video-settings": "Advanced Video Settings",
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device."
|
||||
"activate-or-reload-this-video-device-": "Activate or Reload this video device.",
|
||||
"load-the-next-guest-in-queue": "Load the next guest in queue",
|
||||
"create-a-secondary-stream": "Create a Secondary Stream",
|
||||
"add-to-calendar": "Add to Calendar",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "The director will be visible in scenes, as if a performer themselves.",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Useful if you want to perform and direct at the same time",
|
||||
"start-streaming": "start streaming",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "If disabled, the invited guest will not be able to see or hear anyone in the room.",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "If disabled, you must manually add a video to a scene for it to appear.",
|
||||
"guests-not-actively-speaking-will-be-hidden": "Guests not actively speaking will be hidden",
|
||||
"increase-video-quality-that-guests-in-room-see-": "Increase video quality that guests in room see.",
|
||||
"the-guest-will-not-be-asked-for-a-video-device-on-connection": "The guest will not be asked for a video device on connection",
|
||||
"toggle-solo-voice-chat": "Toggle Solo Voice Chat",
|
||||
"add-to-scene-2": "Add to Scene 2",
|
||||
"add-to-scene-3": "Add to Scene 3",
|
||||
"add-to-scene-4": "Add to Scene 4",
|
||||
"add-to-scene-5": "Add to Scene 5",
|
||||
"add-to-scene-6": "Add to Scene 6",
|
||||
"add-to-scene-7": "Add to Scene 7",
|
||||
"hide-this-guest-everywhere": "Hide this guest everywhere",
|
||||
"set-to-default-audio-channel": "Set to Default Audio Channel",
|
||||
"set-to-audio-channel-1": "Set to Audio Channel 1",
|
||||
"set-to-audio-channel-2": "Set to Audio Channel 2",
|
||||
"set-to-audio-channel-3": "Set to Audio Channel 3",
|
||||
"set-to-audio-channel-4": "Set to Audio Channel 4",
|
||||
"set-to-audio-channel-5": "Set to Audio Channel 5",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Toggle the remote guest's speaker output",
|
||||
"toggle-the-remote-guest-s-display-output": "Toggle the remote guest's display output",
|
||||
"set-to-audio-channel-6": "Set to Audio Channel 6",
|
||||
"set-to-audio-channel-7": "Set to Audio Channel 7",
|
||||
"set-to-audio-channel-8": "Set to Audio Channel 8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Force the remote sender to issue a keyframe to all scenes, fixing Pixel Smearing issues.",
|
||||
"remotely-reload-the-guest-s-page-with-a-new-url": "Remotely reload the guest's page with a new URL",
|
||||
"change-user-parameters": "Change user parameters",
|
||||
"solo-this-video-everywhere": "Solo this video everywhere",
|
||||
"request-the-statistics-of-this-video-in-any-active-scene": "Request the statistics of this video in any active scene",
|
||||
"cannot-see-videos": "Cannot see videos",
|
||||
"cannot-hear-others": "Cannot hear others",
|
||||
"see-director-only": "See director only",
|
||||
"show-mini-preview": "Show Mini preview",
|
||||
"raise-hand-button": "Raise hand button",
|
||||
"show-labels": "Show labels",
|
||||
"transfer-to-a-new-room": "Transfer to a new Room",
|
||||
"enable-custom-password": "Enable custom password",
|
||||
"improve-performance-and-quality-with-this-tip": "Improve performance and quality with this tip",
|
||||
"allow-the-guests-to-pick-a-virtual-backscreen-effect": "Allow the guests to pick a virtual backscreen effect",
|
||||
"this-low-fi-video-codec-uses-very-little-cpu-even-with-dozens-of-active-viewers-": "This low-fi video codec uses very little CPU, even with dozens of active viewers.",
|
||||
"the-active-speakers-are-made-visible-automatically": "The active speakers are made visible automatically",
|
||||
"add-this-video-to-any-remote-scene-2-": "Add this Video to any remote '&scene=2'",
|
||||
"add-to-scene-8": "Add to Scene 8"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "<font id=\"qos\" style=\"color: white;\">O</font>BS.Ninja ",
|
||||
@@ -178,7 +227,68 @@
|
||||
"record-remote": " Record Remote",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings"
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Audio Settings",
|
||||
"scenes-can-see-director": "Director will also be a performer",
|
||||
"select-digital-effect": " Digital Video Effects: ",
|
||||
"add-a-password": " Add a Password:",
|
||||
"hide-guest": "hide guest",
|
||||
"toggle-remote-speaker": "Deafen Guest",
|
||||
"toggle-remote-display": "Blind Guest",
|
||||
"force-keyframe": "Rainbow Puke",
|
||||
"change-url": "Change URL",
|
||||
"change-params": "URL Params",
|
||||
"solo-video": "Highlight guest",
|
||||
"stats-remote": " Scene Stats",
|
||||
"apply-new-guest-settings": "Apply settings",
|
||||
"cancel": "Cancel",
|
||||
"add-to-calendar": "Add details to your Calendar:",
|
||||
"no-effects-applied": "No effects applied",
|
||||
"blurred-background": "Blurred background",
|
||||
"digital-greenscreen": "Digital greenscreen",
|
||||
"virtual-background": "Virtual background",
|
||||
"use-chrome-instead": "Consider using a Chromium-based browser instead.<br>\n \t\t\t\t\t\tSafari is more prone to having audio issues",
|
||||
"select-the-video-files-to-share": "SELECT THE VIDEO FILES TO SHARE",
|
||||
"enter-the-website-URL-you-wish-to-share": "Enter the URL website you wish to share.",
|
||||
"click-here-for-help": "Click Here for a quick overview and help",
|
||||
"guests-hear-others": "Guests hear others",
|
||||
"capture-a-group-scene": "CAPTURE A GROUP SCENE",
|
||||
"auto-add-guests": "Auto-add guests",
|
||||
"pro-audio-mode": "Pro-audio mode",
|
||||
"hide-audio-only-sources": "Hide audio-only sources",
|
||||
"ask-for-display-name": "Ask for display name",
|
||||
"show-display-names": "Show display names",
|
||||
"show-active-speaker": "Show active speakers",
|
||||
"auto-select-microphone": "Auto-select default microphone",
|
||||
"auto-select-camera": "Auto-select default camera",
|
||||
"hide-setting-buttons": "Hide settings button",
|
||||
"mini-self-preview": "Mini self-preview",
|
||||
"virtual-backgrounds": "Virtual backgrounds",
|
||||
"powerful-computers-only": "Only use with powerful computers and small groups!!",
|
||||
"guests-see-HD-video": "Guests see HD video",
|
||||
"no-self-preview": "Disable self-preview",
|
||||
"raise-hand-button": "Display 'raise-hand' button",
|
||||
"enable-compressor": "Enable audio compressor",
|
||||
"enable-equalizer": "Enable equalizer as option",
|
||||
"low-cpu=broadcast-codec": "Low-CPU broadcast codec",
|
||||
"only-see-director-feed": "Only see the director's feed",
|
||||
"mute-microphone-by-default": "Mute microphone by default",
|
||||
"guest-joins-with-no-camera": "Guest joins with no camera",
|
||||
"unmute-by-director-only": "Unmute by director only",
|
||||
"obfuscate-link": "Obfuscate link and parameters",
|
||||
"this-can-reduce-packet-loss": "This can reduce video corruption caused by packet loss",
|
||||
"use-h264-codec": "Use H264 codec",
|
||||
"show-active-speakers": "Show active speakers",
|
||||
"force-mono-audio": "Force mono audio",
|
||||
"learn-more-about-params": "Learn more about URL parameters at ",
|
||||
"More-scene-options": "More scene options",
|
||||
"additional-controls": "Additional controls",
|
||||
"select-local-image": "Select Local Image",
|
||||
"close-settings": "Close Settings",
|
||||
"advanced": "Advanced ",
|
||||
"invisible-guests": "Not Visible",
|
||||
"add-to-google-calendar": "Add to Google Calendar",
|
||||
"add-to-outlook-calendar": "Add to Outlook Calendar",
|
||||
"add-to-yahoo-calendar": "Add to Yahoo Calendar"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "Join by Room Name here",
|
||||
@@ -187,6 +297,9 @@
|
||||
"give-this-media-source-a-name-optional-": "Give this media source a name (optional)",
|
||||
"add-an-optional-password": "Add an optional password",
|
||||
"enter-room-name-here": "Enter Room name here",
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here"
|
||||
"enter-chat-message-to-send-here": "Enter chat message to send here",
|
||||
"optional": "optional",
|
||||
"enter-the-room-name-here": "Enter the room name here",
|
||||
"enter-the-room-password-here": "Enter the room password here"
|
||||
}
|
||||
}
|
||||
204
translations/uk.json
Normal file
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"titles": {
|
||||
"join-by-room-name-here": "Швидкий вхід за назвою кімнати",
|
||||
"join-room": "Приєднатися до кімнати",
|
||||
"toggle-the-chat": "Чат",
|
||||
"mute-the-speaker": "Вимкнути динаміки",
|
||||
"mute-the-mic": "Вимкнути мікрофон",
|
||||
"disable-the-camera": "Заборонити камеру",
|
||||
"share-a-screen-with-others": "Відобразити свій екран іншим",
|
||||
"settings": "Налаштування",
|
||||
"hangup-the-call": "Перервати дзвінок",
|
||||
"alert-the-host-you-want-to-speak": "Повідомити розпорядника що бажаєте говорити",
|
||||
"record-your-stream-to-disk": "Записати ваш стрім на диск",
|
||||
"cancel-the-director-s-video-audio": "Відмінити Відео/Аудіо режисера",
|
||||
"submit-any-error-logs": "Відправити логи помилок",
|
||||
"show-help-info": "Показати допомогу",
|
||||
"language-options": "Варіанти мов",
|
||||
"add-group-chat-to-obs": "Додати груповий чат до OBS",
|
||||
"for-large-group-rooms-this-option-can-reduce-the-load-on-remote-guests-substantially": "Це опція може істотно змешнити навантаження на дистанційних гостей",
|
||||
"which-video-codec-would-you-want-used-by-default-": "Який відеокодек використовувати за замовчуванням?",
|
||||
"you-ll-enter-as-the-room-s-director": "Ви зайшли як режисер кімнати",
|
||||
"add-your-camera-to-obs": "Додайте вашу камеру в OBS",
|
||||
"tip-hold-ctrl-command-to-select-multiple": "підказка: Тримайте CTRL (COMMAND) щоб обрати декілька",
|
||||
"remote-screenshare-into-obs": "Показ віддаленого екрана в OBS",
|
||||
"create-reusable-invite": "Створити багаторазове запрошення",
|
||||
"ideal-for-1080p60-gaming-if-your-computer-and-upload-are-up-for-it": "Ідеально для ігор ( до1080p60 ), якщо ПК та швидкість аплоаду дозволяють це",
|
||||
"better-video-compression-and-quality-at-the-cost-of-increased-cpu-encoding-load": "Краща компресія та якість відео за рахунок збільшення навантаження на СPU",
|
||||
"disable-digital-audio-effects-and-increase-audio-bitrate": "Відключити цифрові аудіо ефекти та підвищити аудіо бітрейт",
|
||||
"the-guest-will-not-have-a-choice-over-audio-options": "Гість не матиме змоги обирати аудіо опції",
|
||||
"the-guest-will-only-be-able-to-select-their-webcam-as-an-option": "Гість зможе обирати тільки власну вебкамеру",
|
||||
"hold-ctrl-and-the-mouse-wheel-to-zoom-in-and-out-remotely-of-compatible-video-streams": "Тримайте CTRL and прокрутку миші для збільшення/зменшення (на сумісних віддалених потоках)",
|
||||
"encode-the-url-so-that-it-s-harder-for-a-guest-to-modify-the-settings-": "Закодувати URL щоб було важче відгадати модифікацію налаштуваннь",
|
||||
"add-a-password-to-make-the-stream-inaccessible-to-those-without-the-password": "Додати пароль для уникнення перегляду стріму сторонніми особами без пароля",
|
||||
"add-the-guest-to-a-group-chat-room-it-will-be-created-automatically-if-needed-": "Додати гостя до групового чату (буде створено автоматично за потреби)",
|
||||
"customize-the-room-settings-for-this-guest": "Індивіалізувати налаштування кімнати для цього гостя",
|
||||
"more-options": "Більше опцій",
|
||||
"hold-ctrl-or-cmd-to-select-multiple-files": "Тримайте CTRL (чи COMMAND) щоб вибрати декілька файлів",
|
||||
"enter-an-https-url": "Введіть HTTPS URL",
|
||||
"creative-commons-by-3-0": "Creative Commons BY 3.0",
|
||||
"youtube-video-demoing-how-to-do-this": "Youtube відео з демострацією як це зробити",
|
||||
"invite-a-guest-or-camera-source-to-publish-into-the-group-room": "Запросити гостя або віддалену камеру показати себе у груповій кімнаті",
|
||||
"if-enabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "Якщо вмикнути, то запрошений гість не зможе бачити чи чути будь-кого у кімнаті",
|
||||
"use-this-link-in-the-obs-browser-source-to-capture-the-video-or-audio": "Використовуйте цей лінк у OBS Browser Source для захоплення відео чи аудіо",
|
||||
"if-enabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "Якщо вмикнути, то доведеться власноруч додати відео до сцени щоб воно з`явилось там",
|
||||
"disables-echo-cancellation-and-improves-audio-quality": "Вимикає усунення луни та покращує якість аудіо",
|
||||
"audio-only-sources-are-visually-hidden-from-scenes": "Тільки-аудіо джерела віртуально приховані із сцен",
|
||||
"guest-will-be-prompted-to-enter-a-display-name": "Гостю буде запропоновано ввести , як його відображати для інших (ПІБ/Нікнеймчи інше)",
|
||||
"display-names-will-be-shown-in-the-bottom-left-corner-of-videos": "Ніки гостей відображатимуться у нижньму лівому кутку віконець",
|
||||
"request-1080p60-from-the-guest-instead-of-720p60-if-possible": "Запитувати 1080p60 замість 720p60, якщо можливо",
|
||||
"the-default-microphone-will-be-pre-selected-for-the-guest": "Мікрофон за замовчуванням буде вибрано попередньо для гостя",
|
||||
"the-default-camera-device-will-selected-automatically": "Вебкамера за замовчуванням буде обиратися автоматично",
|
||||
"the-guest-won-t-have-access-to-changing-camera-settings-or-screenshare": "Гість не зможе змінювати налаштування власної камери чи відображення екрана",
|
||||
"the-guest-will-not-see-their-own-self-preview-after-joining": "Гість не бачитиме власну камеру після приєднання",
|
||||
"guests-will-have-an-option-to-poke-the-director-by-pressing-a-button": "Гості матимуть можливість примертати увагу режисера натисканням кнопки",
|
||||
"add-an-audio-compressor-to-the-guest-s-microphone": "Додати аудіокомпресор до мікрофона гостя",
|
||||
"add-an-equalizer-to-the-guest-s-microphone-that-the-director-can-control": "Додати керований режисером еквалайзер до мікрофона гостя",
|
||||
"the-guest-can-only-see-the-director-s-video-if-provided": "Гості зможуть бачити тільки відео режисера (якщо включене)",
|
||||
"the-guest-s-microphone-will-be-muted-on-joining-they-can-unmute-themselves-": "Мікрофони гостей будуть вимкнені по приєднанню, зможуть вмикати самостійно",
|
||||
"have-the-guest-join-muted-so-only-the-director-can-unmute-the-guest-": "Мікрофон гостя буде вимкнений по приєднанню, тільки режисер може вмикнути мікрофон",
|
||||
"make-the-invite-url-encoded-so-parameters-are-harder-to-tinker-with-by-guests": "Закодувати URL запрошення щоб було важче відгадати параметри налаштувань гостей",
|
||||
"move-the-user-to-another-room-controlled-by-another-director": "Перемістити гостя у іншу кімнату з іншим режисером",
|
||||
"send-a-direct-message-to-this-user-": "Надіслати пряме повідомлення цьому користувачу",
|
||||
"add-this-video-to-any-remote-scene-1-": "Додати це відео до будь-яких віддалених '&scene=1'",
|
||||
"remotely-mute-this-audio-in-all-remote-scene-views": "Дистанційно вимкнути це аудіо для усіх віддалених '&scene' видів",
|
||||
"remotely-change-the-volume-of-this-guest": "Дистанційно змінити гучність цього гостя",
|
||||
"mute-this-guest-everywhere": "Вимкнути звук цього користувача усюди",
|
||||
"disable-video-preview": "Вимкнути Відео попередні перегляди",
|
||||
"low-quality-preview": "Попередній перегляд низької якості",
|
||||
"high-quality-preview": "Попередній перегляд високої якості",
|
||||
"force-the-user-to-disconnect-they-can-always-reconnect-": "Примусово відключити користувача.Може згодом перепідключитися",
|
||||
"start-recording-this-remote-stream-to-this-local-drive-experimental-": "Почати запис віддаленого потоку на локальний диск. *бета*'",
|
||||
"the-remote-guest-will-record-their-local-stream-to-their-local-drive-experimental-": "Віддалений гість записуватиме свої потоки у себе на диску. *бета*",
|
||||
"toggle-voice-chat-with-this-guest": "Голосовий чат з цим гостем",
|
||||
"shift-this-video-down-in-order": "Посунути це відео вниз за списком",
|
||||
"current-index-order-of-this-video": "Поточний номер відео у списку",
|
||||
"shift-this-video-up-in-order": "Посунути це відео вгору за списком",
|
||||
"remote-audio-settings": "Налаштування віддаленого аудіо",
|
||||
"advanced-video-settings": "Розширені відео налаштування",
|
||||
"activate-or-reload-this-video-device-": "Активувати чи перезапусти цей відео пристрій",
|
||||
"load-the-next-guest-in-queue": "Завантажити наступного гостя із черги",
|
||||
"create-a-secondary-stream": "Створити вторинний стрім",
|
||||
"the-director-will-be-visible-in-scenes-as-if-a-performer-themselves-": "Режисера буде видно у сценах так само як і учасників",
|
||||
"useful-if-you-want-to-perform-and-direct-at-the-same-time": "Корисно якщо ви бажаєте виступати та керувати одночасно",
|
||||
"start-streaming": "Gочати стрімінг",
|
||||
"if-disabled-the-invited-guest-will-not-be-able-to-see-or-hear-anyone-in-the-room-": "Якщо вимкнути, запрошений гість не бачитиме/чутиме нікого у кімнаті",
|
||||
"if-disabled-you-must-manually-add-a-video-to-a-scene-for-it-to-appear-": "Якщо вимкнути, то доведеться власноруч додати відео до сцени щоб воно з`явилось там",
|
||||
"add-to-scene-2": "Додати до сцени 2",
|
||||
"add-to-scene-3": "Додати до сцени 3",
|
||||
"add-to-scene-4": "Додати до сцени 4",
|
||||
"add-to-scene-5": "Додати до сцени 5",
|
||||
"add-to-scene-6": "Додати до сцени 6",
|
||||
"add-to-scene-7": "Додати до сцени 7",
|
||||
"toggle-solo-voice-chat": "Соло голосовий чат",
|
||||
"set-to-default-audio-channel": "Аудіоканал 1 за замовчуванням",
|
||||
"set-to-audio-channel-1": "Аудіоканал 1-1",
|
||||
"set-to-audio-channel-2": "Аудіоканал 1-2",
|
||||
"toggle-the-remote-guest-s-speaker-output": "Динаміки віддаленого гостя",
|
||||
"set-to-audio-channel-3": "Аудіоканал 1-3",
|
||||
"set-to-audio-channel-4": "Аудіоканал 1-4",
|
||||
"set-to-audio-channel-5": "Аудіоканал 1-5",
|
||||
"toggle-the-remote-guest-s-display-output": "Дисплейний вихід віддаленого гостя",
|
||||
"set-to-audio-channel-6": "Аудіоканал 1-6",
|
||||
"set-to-audio-channel-7": "Аудіоканал 1-7",
|
||||
"set-to-audio-channel-8": "Аудіоканал 1-8",
|
||||
"force-the-remote-sender-to-issue-a-keyframe-to-all-scenes-fixing-pixel-smearing-issues-": "Примусити відправника вставляти ключові кадри до усіх сцен (вирішує проблему розсипання картинки)"
|
||||
},
|
||||
"innerHTML": {
|
||||
"logo-header": "\n\t\t\t\t\t<font id=\"qos\">O</font>BS.Ninja \n\t\t\t\t",
|
||||
"copy-this-url": "Скопіюйте цей URL в OBS \"Browser Source\"",
|
||||
"you-are-in-the-control-center": "Контрольний центр кімнати: ",
|
||||
"joining-room": "Ви у кімнаті",
|
||||
"add-group-chat": "Створити кімнату",
|
||||
"rooms-allow-for": "Кімнати надають груповий чат та інструменти керування багатьма гостями",
|
||||
"room-name": "Назва кімнати",
|
||||
"password-input-field": "Пароль",
|
||||
"guests-only-see-director": "Гості можуть бачити тільки відео режисера",
|
||||
"default-codec-select": "Привілейований кодек відео: ",
|
||||
"enter-the-rooms-control": "Вхід у контрольний центр кімнати",
|
||||
"show-tips": "Підказки..",
|
||||
"added-notes": "\n\t\t\t\t\t\t\t\t<u>\n\t\t\t\t\t\t\t\t\t<i>Важливі підказки:</i><br><br>\n\t\t\t\t\t\t\t\t</u>\n\t\t\t\t\t\t\t\t<li>Заборона ділитися відео між гостями значно покращує продуктивність</li>\n\t\t\t\t\t\t\t\t<li>Зпрошуйте тільки тих кому довіряєте</li>\n\t\t\t\t\t\t\t\t<li> \"Запис\" опція має вважатися експериментальною</li>\n\t\t\t\t\t\t\t\t<li><a href=\"https://params.obs.ninja\" style=\"color:black;\"><u>Розширені параметри</u></a>доступні</li>\n\t\t\t\t\t\t\t",
|
||||
"back": "Назад",
|
||||
"add-your-camera": "Додати власну камеру до OBS",
|
||||
"ask-for-permissions": "Дозволити доступ до Камери/Мікрофона",
|
||||
"waiting-for-camera": "Очікуємо завантаження камери",
|
||||
"video-source": " Джерело відео ",
|
||||
"max-resolution": "1080p (HD)",
|
||||
"balanced": "720p (збалансовано)",
|
||||
"smooth-cool": "360p (плавно)",
|
||||
"select-audio-source": " Джерела аудіо ",
|
||||
"no-audio": "Без аудіо",
|
||||
"select-output-source": " Вивід аудіо: ",
|
||||
"remote-screenshare-obs": "Віддалена демонстрація екрана в OBS",
|
||||
"note-share-audio": "\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<video id=\"screenshare\" autoplay=\"true\" muted=\"true\" loop=\"\" src=\"./images/screenshare.webm\"></video>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t",
|
||||
"select-screen-to-share": "Оберіть екран для показу",
|
||||
"audio-sources": "Джерела аудіо",
|
||||
"create-reusable-invite": "Створити багаторазове запрошення",
|
||||
"here-you-can-pre-generate": "Тут можна попередньо сгенерувати багаторазове браузерне посилання та споріднене запрошення гостю",
|
||||
"generate-invite-link": "Сгенерувати запрошення-посилання",
|
||||
"advanced-paramaters": "Розширені опції",
|
||||
"unlock-video-bitrate": "Дозволити відео бітрейт (20mbps)",
|
||||
"force-vp9-video-codec": "VP9 відео кодек примусово",
|
||||
"enable-stereo-and-pro": "Вмикнути стерео та Pro HD аудіо",
|
||||
"video-resolution": "Відео розмір: ",
|
||||
"hide-mic-selection": "Мікрофон за замовчуванням примусово",
|
||||
"hide-screen-share": "Сховати опцію відобразити екран",
|
||||
"allow-remote-control": "Дистанційно керувати зумом (Android)",
|
||||
"obfuscate_url": "Зашифрувати URL запрошення",
|
||||
"add-a-password-to-stream": " Додати пароль для стріма:",
|
||||
"add-the-guest-to-a-room": " Додати гостя до кімнати:",
|
||||
"invite-group-chat-type": "Цей гість може у груповому чаті:",
|
||||
"can-see-and-hear": "читати та відповідати ",
|
||||
"can-hear-only": " тільки читати",
|
||||
"cant-see-or-hear": "не може бачити чи відповідати",
|
||||
"share-local-video-file": "Показати відео з ПК",
|
||||
"share-website-iframe": "Показати вебсайт",
|
||||
"run-a-speed-test": "Тест швидкодії",
|
||||
"read-the-guides": "Читати настанови",
|
||||
"info-blob": "\n\t\t\t\t\t\t\t<h2>Що таке OBS.Ninja</h2>\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<li>100% \n\t\t\t\t\t\t\t\t<b>free</b>; без завантажень; без збору персональних даних; без реєстрації\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t<li>Передає відео зі смартфонів,ПК напряму у ваш OBS відео стрім</li>\n\t\t\t\t\t\t\t<li>Ми використовуєму провідні технології P2P для забезпечення приватності та ультра низької затримки</li>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t",
|
||||
"hide-the-links": " LINKS (GUEST INVITES & SCENES)",
|
||||
"click-for-quick-room-overview": "\n\t\t\t\t\t\t<i class=\"las la-question-circle\"></i> Click Here for a quick overview and help\n\t\t\t\t\t",
|
||||
"welcome-to-control-room": "\n\t\t\t\t\t\t<b>Welcome. This is the director's control-room for the group-chat.</b><br><br>\n\t\t\t\t\t\tYou can host a group chat with friends using a room. Share the blue link to invite guests who will join the chat automatically.\n\t\t\t\t\t\t<br><br>\n\t\t\t\t\t\t<font style=\"color:red\">Known Limitations with Group Rooms:</font><br>\n\t\t\t\t\t\t<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 <a href=\"https://www.youtube.com/watch?v=bpRa8-UYCGc\" title=\"Youtube Video demoing how to do this\">disable video sharing between guests</a>. Using &broadcast, &roombitrate=0 or &novideo are options there.</li>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\tFurther Notes:<br><br>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<li>You can use the auto-mixing Group Scenes, the green links, to auto arrange multiple videos for you in OBS.</li>\n\t\t\t\t\t\t<li>You can use this control room to record isolated video or audio streams, but it is an experimental feature still.</li>\n\t\t\t\t\t\t<li>If you transfer a guest from one room to another, they won't know which room they have been transferred to.</li>\n\t\t\t\t\t\t<li>OBS will see a guest's video in high-quality; the default video bitrate is 2500kbps. Setting higher bitrates will improve motion.</li>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<li>&stereo=2 can be added to guests to turn off audio effects, such as echo cancellation and noise-reduction.</li>\n\t\t\t\t\t\t<li>https://invite.cam is a free service provided that can help obfuscuate the URL parameters of an invite link given to guests.</li>\n\t\t\t\t\t\t<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>\n\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\n\t\t\t\t\t\tFor advanced URL options and parameters, <a href=\"https://github.com/steveseguin/obsninja/wiki/Advanced-Settings\">see the Wiki.</a>\n\t\t\t\t\t",
|
||||
"invite-users-to-join": "Гості можуть використовувати це посилання для приєднання",
|
||||
"this-is-obs-browser-source-link": "Використовуйте OBS чи інший софт для захоплення групового чату",
|
||||
"more-than-four-can-join": "Це місця для гостей як приклад, їх може бути більше",
|
||||
"forward-to-room": "Трансфер",
|
||||
"send-direct-chat": "<i class=\"las la-envelope\"></i> Повідомлення",
|
||||
"add-to-scene": "Add to Scene",
|
||||
"mute-scene": "не давати звук у сцені",
|
||||
"mute-guest": "відключити мікрофон",
|
||||
"change-to-low-quality": " <i class=\"las la-video-slash\"></i>",
|
||||
"change-to-medium-quality": " <i class=\"las la-video\"></i>",
|
||||
"change-to-high-quality": " <i class=\"las la-binoculars\"></i>",
|
||||
"disconnect-guest": "Від`єднати",
|
||||
"record-local": " Локальний запис",
|
||||
"record-remote": " Віддалений запис",
|
||||
"voice-chat": "<i class=\"las la-microphone\"></i> Голосовий чат",
|
||||
"order-down": "<i class=\"las la-minus\"></i>",
|
||||
"order-up": "<i class=\"las la-plus\"></i>",
|
||||
"advanced-audio-settings": "<i class=\"las la-sliders-h\"></i> Аудіо налаштування",
|
||||
"advanced-camera-settings": "<i class=\"las la-sliders-h\"></i> Відео налаштування",
|
||||
"open-in-new-tab": "Відкрити у новій закладинці",
|
||||
"copy-to-clipboard": "Скопіювати у буфер",
|
||||
"welcome-to-obs-ninja-chat": "\n\t\t\t\t\tWelcome to OBS.Ninja! You can send text messages directly to connected peers from here.\n\t\t\t\t",
|
||||
"names-and-labels-coming-soon": "\n\t\t\t\t\tNames identifying connected peers will be a feature in an upcoming release.\n\t\t\t\t",
|
||||
"send-chat": "Надіслати",
|
||||
"available-languages": "Доступні мови:",
|
||||
"add-more-here": "Ще... !",
|
||||
"scenes-can-see-director": "Режисер також виступатиме",
|
||||
"add-a-password": " Додайте пароль:",
|
||||
"toggle-remote-speaker": "Віддалений звук",
|
||||
"toggle-remote-display": "Відео гістю",
|
||||
"force-keyframe": "Райдуга"
|
||||
},
|
||||
"placeholders": {
|
||||
"join-by-room-name-here": "приєднано до кімнати тут ",
|
||||
"enter-a-room-name-here": "Введіть назву кімнатиe",
|
||||
"optional-room-password-here": "Необов`язковий пароль тут",
|
||||
"give-this-media-source-a-name-optional-": "Назвіть це медіа джерело (опціонально)",
|
||||
"add-an-optional-password": "Додайте необов`язковий пароль",
|
||||
"enter-room-name-here": "Введіть назву кімнати",
|
||||
"enter-chat-message-to-send-here": "Введіть чат повідомлення тут",
|
||||
"optional": "опціонально"
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,29 @@
|
||||
## Install and setup gudie for a TURN Relay Server
|
||||
## Install and setup guide for a TURN Relay Server
|
||||
|
||||
#### why? You may want to deploy one to ensure high compatiblity with remote guests. If you try to use the official OBS.Ninja TURN servers for a private deployment, you may find yourself getting kicked off.
|
||||
|
||||
This install script and config file was used with a standard virtual machine server loaded with Ubuntu 20. GCP/AWS servers might need slightly different settings.
|
||||
|
||||
```
|
||||
sudo apt-get update
|
||||
sudo apt-get update # update package lists
|
||||
|
||||
sudo apt-get install coturn -y
|
||||
sudo add-apt-repository ppa:certbot/certbot
|
||||
sudo apt-get install certbot -y
|
||||
sudo apt-get install coturn -y # install coturn, the implementation of the TURN server
|
||||
sudo add-apt-repository ppa:certbot/certbot # Add the certbot repository
|
||||
sudo apt-get install certbot -y # Install certbot required for the HTTPS certificate
|
||||
|
||||
sudo vi /etc/default/coturn
|
||||
sudo vi /etc/default/coturn # open the coturn configuration in Vim (you can also use nano or any other editor)
|
||||
```
|
||||
...and we uncomment the line:
|
||||
```
|
||||
#TURNSERVER_ENABLED=1
|
||||
```
|
||||
….leaving it like this:
|
||||
```
|
||||
TURNSERVER_ENABLED=1
|
||||
|
||||
```
|
||||
Next make sure you have the DNS pointing to your IP address for this next step (ipv4, and ipv6 if possible). You will need to validate that in the next step.
|
||||
```
|
||||
sudo certbot certonly --standalone
|
||||
sudo certbot certonly --standalone # only generate the HTTPS certificate without actually changing any configs
|
||||
sudo apt install net-tools
|
||||
```
|
||||
note: If you run into error 701 issues with your TURN server, check that the coturn service has access to your new SSL certificates:
|
||||
@@ -37,10 +40,10 @@ sudo systemctl daemon-reload
|
||||
|
||||
Next, we are going to open up some ports... just in case they are blocked by default. Which exactly? well, these are default ports. TCP may not be needed?
|
||||
```
|
||||
sudo ufw allow 3478/tcp
|
||||
sudo ufw allow 3478/udp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw allow 443/udp
|
||||
sudo ufw allow 3478/tcp # The default coturn TCP port
|
||||
sudo ufw allow 3478/udp # The default coturn UDP port
|
||||
sudo ufw allow 443/tcp # The HTTPS TCP port
|
||||
sudo ufw allow 443/udp # The HTTPS UDP port
|
||||
sudo ufw allow 49152:65535/tcp
|
||||
sudo ufw allow 49152:65535/udp
|
||||
```
|
||||
|
||||
16
turnserver3.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
# Another TURNSERVER conf file; this one is a basic UDP-based setup. Port 3478, no SSL/TLS, and basic username/password.
|
||||
|
||||
listening-port=3478
|
||||
alt-listening-port=0
|
||||
fingerprint
|
||||
no-stun
|
||||
lt-cred-mech
|
||||
user=obsninja:somepasswordwhere
|
||||
stale-nonce=600
|
||||
realm=turn-eu2.obs.ninja
|
||||
server-name=turn-eu2.obs.ninja
|
||||
no-multicast-peers
|
||||
stale-nonce=600
|
||||
dh2066
|
||||
#verbose
|
||||
no-stdout-log
|
||||
182
zoom.html
Normal file
@@ -0,0 +1,182 @@
|
||||
|
||||
<html>
|
||||
<head><style>
|
||||
span{margin:10px 0 0 0;display:block;}
|
||||
body {
|
||||
|
||||
background-color:#cdf;
|
||||
padding:0;
|
||||
width;100%;height:100%
|
||||
}
|
||||
|
||||
input{padding:5px;}
|
||||
|
||||
button {margin:10px 3px;}
|
||||
|
||||
#stream{
|
||||
display:block;
|
||||
}
|
||||
|
||||
</style></head>
|
||||
<body id="main" style="margin:5%;"
|
||||
<meta charset="utf-8"/>
|
||||
|
||||
<video id="video" autoplay="true" muted="true" playsinline style='height:420px;background-color:black;display:block;margin:0 0 10px 0;'></video>
|
||||
<div id="devices">
|
||||
<div class="select">
|
||||
<label for="videoSource">Video source: </label><select id="videoSource"></select>
|
||||
</div>
|
||||
<div class="select">
|
||||
<label for="audioSource">Audio source: </label><select id="audioSource"></select>
|
||||
</div>
|
||||
</div>
|
||||
<button onclick="fullwindow()">FULL WINDOW</button>
|
||||
<script>
|
||||
window.onerror = function backupErr(errorMsg, url=false, lineNumber=false) {
|
||||
console.error(errorMsg);
|
||||
console.error(lineNumber);
|
||||
console.error("Unhandeled Error occured"); //or any message
|
||||
return false;
|
||||
};
|
||||
|
||||
function fullwindow(){
|
||||
videoElement.style.width="100%";
|
||||
videoElement.style.padding= "0";
|
||||
videoElement.style.margin="0";
|
||||
videoElement.style.height="100%";
|
||||
videoElement.style.zIndex="5";
|
||||
videoElement.style.position = "absolute";
|
||||
videoElement.style.top="0px";
|
||||
videoElement.style.left="0px";
|
||||
document.getElementById("main").style.overflow = "hidden";
|
||||
videoElement.style.overflow = "hidden"
|
||||
document.getElementById("main").style.backgroundColor="#000";
|
||||
videoElement.style.cursor="none";
|
||||
document.getElementById("main").style.cursor="none";
|
||||
}
|
||||
|
||||
var videoElement = document.getElementById("video");
|
||||
var gotDev = false;
|
||||
async function gotDevices() {
|
||||
if (gotDev){return;}
|
||||
gotDev=true;
|
||||
await navigator.mediaDevices.getUserMedia({audio:true, video:true}); // is needed to ask for permissinos.
|
||||
navigator.mediaDevices.enumerateDevices().then((deviceInfos)=>{
|
||||
for (let i = 0; i !== deviceInfos.length; ++i) {
|
||||
var deviceInfo = deviceInfos[i];
|
||||
var option = document.createElement("option");
|
||||
option.value = deviceInfo.deviceId;
|
||||
|
||||
if (deviceInfo.kind === "audioinput") {
|
||||
option.text = deviceInfo.label || "microphone " + (audioSelect.length + 1);
|
||||
audioSelect.appendChild(option);
|
||||
if (option.text.startsWith("CABLE")){
|
||||
option.selected =true;
|
||||
}
|
||||
} else if (deviceInfo.kind === "videoinput") {
|
||||
option.text = deviceInfo.label || "camera " + (videoSelect.length + 1);
|
||||
if (option.text.startsWith("NewTek")){
|
||||
continue;
|
||||
}
|
||||
videoSelect.appendChild(option);
|
||||
if (option.text.startsWith("OBS")){
|
||||
option.selected =true;
|
||||
}
|
||||
}
|
||||
}
|
||||
getStream();
|
||||
});
|
||||
}
|
||||
|
||||
function getStream() {
|
||||
if (window.stream) {
|
||||
window.stream.getTracks().forEach(function (track) {
|
||||
track.stop();
|
||||
log("TRack stopping");
|
||||
});
|
||||
}
|
||||
|
||||
const constraints = {
|
||||
audio: {
|
||||
deviceId: { exact: audioSelect.value },
|
||||
echoCancellation : false,
|
||||
autoGainControl : false,
|
||||
noiseSuppression : false
|
||||
},
|
||||
video: {
|
||||
deviceId: { exact: videoSelect.value },
|
||||
width: { min: 1280, ideal: 1920, max: 1920 },
|
||||
height: { min: 720, ideal: 1080, max: 1080 }
|
||||
}
|
||||
};
|
||||
return navigator.mediaDevices.getUserMedia(constraints)
|
||||
.then(gotStream)
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
|
||||
function gotStream(stream) {
|
||||
if (window.stream) {
|
||||
window.stream = stream; // make stream available to console
|
||||
videoElement.srcObject = stream;
|
||||
var senders = session.pc.getSenders();
|
||||
videoElement.srcObject.getVideoTracks().forEach((track)=>{
|
||||
var added = false;
|
||||
senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams?
|
||||
if (sender.track) {
|
||||
if (sender.track && sender.track.kind == "video") {
|
||||
sender.replaceTrack(track); // replace may not be supported by all browsers. eek.
|
||||
track.enabled = notCensored;
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (added==false){
|
||||
session.pc.addTrack(track);
|
||||
log("ADDED NOT REPLACED?");
|
||||
}
|
||||
});
|
||||
|
||||
videoElement.srcObject.getAudioTracks().forEach((track)=>{
|
||||
var added = false;
|
||||
senders.forEach((sender) => { // I suppose there could be a race condition between negotiating and updating this. if joining at the same time as changnig streams?
|
||||
if (sender.track) {
|
||||
if (sender.track && sender.track.kind == "audio") {
|
||||
sender.replaceTrack(track); // replace may not be supported by all browsers. eek.
|
||||
track.enabled = notCensored;
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (added==false){
|
||||
session.pc.addTrack(track);
|
||||
log("ADDED NOT REPLACED?");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
window.stream = stream; // make stream available to console
|
||||
videoElement.srcObject = stream;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var audioSelect = document.querySelector("select#audioSource");
|
||||
var videoSelect = document.querySelector("select#videoSource");
|
||||
audioSelect.onchange = getStream;
|
||||
videoSelect.onchange = getStream;
|
||||
gotDevices();
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||