JS syntax highlighting

- add syntax highlighting in IFRAME.md
- update syntax to ES6
This commit is contained in:
Filip Troníček 2021-02-08 15:40:48 +01:00 committed by GitHub
parent 5c7648d86a
commit 1934097875
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

254
IFRAME.md
View File

@ -9,12 +9,12 @@ The solution decided on isn't an SDK framework, but rather the use of embeddable
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 OBSN video stream act much like an HTML video element tag, where you can issue commands like play, pause, or change video sources with ease.
Creating an OBSN iframe can be done in HTML or programmatically with Javascript like so: Creating an OBSN iframe can be done in HTML or programmatically with Javascript like so:
```js
var iframe = document.createElement("iframe"); const iframe = document.createElement("iframe");
iframe.allow="autoplay;camera;microphone"; iframe.allow="autoplay;camera;microphone";
iframe.allowtransparency="false" iframe.allowtransparency="false"
iframe.src = "https://obs.ninja/?webcam"; iframe.src = "https://obs.ninja/?webcam";
```
Adding that iframe to the DOM will reveal a simple page accessing for a user to select and share their webcam. For a developer wishing to access a remote guest's stream, this makes the ingestion of that stream into production software like OBS Studios very easy. The level of customization and control opens up opportunities, such as a pay-to-join audience option for a streaming interactive broadcast experience. Adding that iframe to the DOM will reveal a simple page accessing for a user to select and share their webcam. For a developer wishing to access a remote guest's stream, this makes the ingestion of that stream into production software like OBS Studios very easy. The level of customization and control opens up opportunities, such as a pay-to-join audience option for a streaming interactive broadcast experience.
An example of how this API is used by OBS.Ninja is with its Internet Speedtest, which has two OBS.Ninja IFrames on a single page. One iframe feeds video to the other iframe, and the speed at which it does this is a measure of the system's performance. Detailed stats of the connection are made available to the parent window, which displays the results. 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.
@ -52,161 +52,161 @@ As for API, allow for dynamic messaging, below are examples of the options avail
- Get notified when there is a video connection - 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: 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:
```js
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"); var button = document.createElement("button");
button.innerHTML = "Mute Speaker"; button.innerHTML = "Un-Mute Speaker";
button.onclick = function(){iframe.contentWindow.postMessage({"mute":true}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"mute":false}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Un-Mute Speaker"; button.innerHTML = "Toggle Speaker";
button.onclick = function(){iframe.contentWindow.postMessage({"mute":false}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"mute":"toggle"}, '*');}
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Toggle Speaker"; button.innerHTML = "Mute Mic";
button.onclick = function(){iframe.contentWindow.postMessage({"mute":"toggle"}, '*');} button.onclick = function(){iframe.contentWindow.postMessage({"mic":false}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Mute Mic"; button.innerHTML = "Un-Mute Mic";
button.onclick = function(){iframe.contentWindow.postMessage({"mic":false}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"mic":true}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Un-Mute Mic"; button.innerHTML = "Toggle Mic";
button.onclick = function(){iframe.contentWindow.postMessage({"mic":true}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"mic":"toggle"}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Toggle Mic"; button.innerHTML = "Disconnect";
button.onclick = function(){iframe.contentWindow.postMessage({"mic":"toggle"}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Disconnect"; button.innerHTML = "Low Bitrate";
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":30}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Low Bitrate"; button.innerHTML = "High Bitrate";
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":30}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":5000}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "High Bitrate"; button.innerHTML = "Default Bitrate";
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":5000}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":-1}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Default Bitrate"; button.innerHTML = "Reload";
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":-1}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"reload":true}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Reload"; button.innerHTML = "50% Volume";
button.onclick = function(){iframe.contentWindow.postMessage({"reload":true}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"volume":0.5}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "50% Volume"; button.innerHTML = "100% Volume";
button.onclick = function(){iframe.contentWindow.postMessage({"volume":0.5}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"volume":1.0}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "100% Volume"; button.innerHTML = "Request Stats";
button.onclick = function(){iframe.contentWindow.postMessage({"volume":1.0}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"getStats":true}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Request Stats"; button.innerHTML = "Request Loudness Levels";
button.onclick = function(){iframe.contentWindow.postMessage({"getStats":true}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":true}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Request Loudness Levels"; button.innerHTML = "Stop Sending Loudness Levels";
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":true}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":false}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Stop Sending Loudness Levels"; button.innerHTML = "Say Hello";
button.onclick = function(){iframe.contentWindow.postMessage({"getLoudness":false}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"sendChat":"Hello!"}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "Say Hello"; button.innerHTML = "previewWebcam()";
button.onclick = function(){iframe.contentWindow.postMessage({"sendChat":"Hello!"}, '*');}; button.onclick = function(){iframe.contentWindow.postMessage({"function":"previewWebcam"}, '*');};
iframeContainer.appendChild(button); iframeContainer.appendChild(button);
var button = document.createElement("button"); var button = document.createElement("button");
button.innerHTML = "previewWebcam()"; button.innerHTML = "CLOSE IFRAME";
button.onclick = function(){iframe.contentWindow.postMessage({"function":"previewWebcam"}, '*');}; button.onclick = function(){iframeContainer.parentNode.removeChild(iframeContainer);};
iframeContainer.appendChild(button); 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: As for listening events, where the parent listens for responses or events from the OBSN child frame:
//////////// LISTEN FOR EVENTS //////////// LISTEN FOR EVENTS
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod]; var eventer = window[eventMethod];
var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message"; var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) { eventer(messageEvent, function (e) {
if (e.source != iframe.contentWindow){return} // reject messages send from other iframes if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
if ("stats" in e.data){ if ("stats" in e.data){
var outputWindow = document.createElement("div"); var outputWindow = document.createElement("div");
var out = "<br />total_inbound_connections:"+e.data.stats.total_inbound_connections; var out = "<br />total_inbound_connections:"+e.data.stats.total_inbound_connections;
out += "<br />total_outbound_connections:"+e.data.stats.total_outbound_connections; out += "<br />total_outbound_connections:"+e.data.stats.total_outbound_connections;
for (var streamID in e.data.stats.inbound_stats){ for (var streamID in e.data.stats.inbound_stats){
out += "<br /><br /><b>streamID:</b> "+streamID+"<br />"; out += "<br /><br /><b>streamID:</b> "+streamID+"<br />";
out += printValues(e.data.stats.inbound_stats[streamID]); out += printValues(e.data.stats.inbound_stats[streamID]);
} }
outputWindow.innerHTML = out; outputWindow.innerHTML = out;
iframeContainer.appendChild(outputWindow); iframeContainer.appendChild(outputWindow);
} }
if ("gotChat" in e.data){ if ("gotChat" in e.data){
var outputWindow = document.createElement("div"); var outputWindow = document.createElement("div");
outputWindow.innerHTML = e.data.gotChat.msg; outputWindow.innerHTML = e.data.gotChat.msg;
outputWindow.style.border="1px dotted black"; outputWindow.style.border="1px dotted black";
iframeContainer.appendChild(outputWindow); iframeContainer.appendChild(outputWindow);
} }
if ("action" in e.data){ if ("action" in e.data){
var outputWindow = document.createElement("div"); var outputWindow = document.createElement("div");
outputWindow.innerHTML = "child-page-action: "+e.data.action+"<br />"; outputWindow.innerHTML = "child-page-action: "+e.data.action+"<br />";
outputWindow.style.border="1px dotted black"; outputWindow.style.border="1px dotted black";
iframeContainer.appendChild(outputWindow); iframeContainer.appendChild(outputWindow);
} }
if ("loudness" in e.data){ if ("loudness" in e.data){
console.log(e.data); console.log(e.data);
if (document.getElementById("loudness")){ if (document.getElementById("loudness")){
outputWindow = document.getElementById("loudness"); outputWindow = document.getElementById("loudness");
} else { } else {
var outputWindow = document.createElement("div"); var outputWindow = document.createElement("div");
outputWindow.style.border="1px dotted black"; outputWindow.style.border="1px dotted black";
iframeContainer.appendChild(outputWindow); iframeContainer.appendChild(outputWindow);
outputWindow.id = "loudness"; outputWindow.id = "loudness";
} }
outputWindow.innerHTML = "child-page-action: loudness<br />"; outputWindow.innerHTML = "child-page-action: loudness<br />";
for (var key in e.data.loudness) { for (var key in e.data.loudness) {
outputWindow.innerHTML += key + " Loudness: " + e.data.loudness[key] + "\n"; outputWindow.innerHTML += key + " Loudness: " + e.data.loudness[key] + "\n";
} }
outputWindow.style.border="1px black"; 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. This OBS.Ninja API is developed and expanded based on user feedback and requests. It is by no means complete.
Regarding versioning, I currently host past versions of OBS.Ninja, so using those past versions can ensure some level of consistency and expectation. https://obs.ninja/v12/ for example is the version 12 hosted version. The active and main production version of OBSN of course undergoes constant updates, and while I try to maintain backwards compatibility with changes to the API, it is still early days and changes might happen. 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.