mirror of
https://github.com/SrIzan10/vdo.ninja.git
synced 2026-05-01 11:05:24 +00:00
tinkering -- EXPERIMENTAL 13.5-alpha branch
This commit is contained in:
24
devices.json.html
Normal file
24
devices.json.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<html>
|
||||||
|
<head><meta charset="UTF-8"></head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
var list = [];
|
||||||
|
|
||||||
|
|
||||||
|
navigator.mediaDevices.enumerateDevices()
|
||||||
|
.then(function(devices) {
|
||||||
|
devices.forEach(function(device) {
|
||||||
|
console.log(device.kind + ": " + device.label +
|
||||||
|
" id = " + device.deviceId);
|
||||||
|
list.push(device);
|
||||||
|
});
|
||||||
|
document.write(JSON.stringify(list, null, 2));
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.log(err.name + ": " + err.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
51
index.html
51
index.html
@@ -207,6 +207,9 @@
|
|||||||
<video id="previewWebcam" class="previewWebcam" oncanplay="updateStats();" disablePictureInPicture controlsList="nodownload" muted autoplay playsinline ></video>
|
<video id="previewWebcam" class="previewWebcam" oncanplay="updateStats();" disablePictureInPicture controlsList="nodownload" muted autoplay playsinline ></video>
|
||||||
</p>
|
</p>
|
||||||
<div id="infof"></div>
|
<div id="infof"></div>
|
||||||
|
<button onclick="this.disabled=true;setTimeout(function(){requestBasicPermissions();},20);" id="getPermissions" style="display:none;" data-ready="false" >
|
||||||
|
<span data-translate="ask-for-permissions">Allow Access to Camera/Microphone</span>
|
||||||
|
</button>
|
||||||
<button onclick="publishWebcam(this)" id="gowebcam" class="gowebcam" disabled data-ready="false" >
|
<button onclick="publishWebcam(this)" id="gowebcam" class="gowebcam" disabled data-ready="false" >
|
||||||
<span data-translate="waiting-for-camera">Waiting for Camera to Load</span>
|
<span data-translate="waiting-for-camera">Waiting for Camera to Load</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -463,6 +466,7 @@
|
|||||||
SELECT THE VIDEO FILE TO SHARE<br /><br />
|
SELECT THE VIDEO FILE TO SHARE<br /><br />
|
||||||
<input id="fileselector" onchange="session.publishFile(this,event);" type="file" accept="video/*,audio/*" alt="Hold CTRL (or CMD) to select multiple files" title="Hold CTRL (or CMD) to select multiple files" multiple/>
|
<input id="fileselector" onchange="session.publishFile(this,event);" type="file" accept="video/*,audio/*" alt="Hold CTRL (or CMD) to select multiple files" title="Hold CTRL (or CMD) to select multiple files" multiple/>
|
||||||
</div>
|
</div>
|
||||||
|
<p>Keep this tab visible if using Chrome, else the video playback will stop</p>
|
||||||
<div class="outer close">
|
<div class="outer close">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<label class="labelclass">
|
<label class="labelclass">
|
||||||
@@ -472,7 +476,27 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div id="container-6" class="column columnfade pointer" style=" overflow-y: auto;">
|
||||||
|
<h2><span data-translate="share-website-iframe">Share Remote Website</span></h2>
|
||||||
|
<div class="container-inner">
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
Enter the URL website you wish to share.<br /><br />
|
||||||
|
<input id="iframeURL" type="text" style="margin:10px; border:2px solid; padding:10px; width:400px;" title="Enter an HTTPS URL" multiple/><br />
|
||||||
|
<button onclick="loadIframe(getById('iframeURL').value);" >Preview</button>
|
||||||
|
<button onclick="this.innerHTML = 'Update';session.publishIFrame(getById('iframeURL').value);" >Share</button><br />
|
||||||
|
<small>Remote website must be CORS/IFrame compatible with full SSL-encryption enabled.</small>
|
||||||
|
<div id="iFramePreview" style=" width: 1280px; height: 720px; margin: auto; padding: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="outer close">
|
||||||
|
<div class="inner">
|
||||||
|
<label class="labelclass">
|
||||||
|
<span data-translate="back">Back</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
<p></p>
|
<p></p>
|
||||||
<div id="info" class="fullcolumn columnfade">
|
<div id="info" class="fullcolumn columnfade">
|
||||||
<center>
|
<center>
|
||||||
@@ -510,7 +534,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
🎈 Site Updated: <a href="https://www.reddit.com/r/OBSNinja/comments/k02enh/version_134_of_obsninja_released_change_log_here/">November 24th, 2020</a>. The previous version can be found at
|
🎈 Site Updated: <a href="https://www.reddit.com/r/OBSNinja/comments/k02enh/version_134_of_obsninja_released_change_log_here/">November 27th, 2020</a>. The previous version can be found at
|
||||||
<a href="https://obs.ninja/v12/">https://obs.ninja/v12/</a> if you are having new issues.
|
<a href="https://obs.ninja/v12/">https://obs.ninja/v12/</a> if you are having new issues.
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
@@ -577,7 +601,7 @@
|
|||||||
<button style="width: 36px" data-action-type="change-quality" title="Disable Video Preview" onclick="toggleQualityDirector(0, this.dataset.UUID, this);">
|
<button style="width: 36px" data-action-type="change-quality" title="Disable Video Preview" onclick="toggleQualityDirector(0, this.dataset.UUID, this);">
|
||||||
<span data-translate="change-to-low-quality"> <i class="las la-video-slash"></i></span>
|
<span data-translate="change-to-low-quality"> <i class="las la-video-slash"></i></span>
|
||||||
</button>
|
</button>
|
||||||
<button style="width: 36px" data-action-type="change-quality" title="Low-Quality Preview" onclick="toggleQualityDirector(50, this.dataset.UUID, this);">
|
<button class="pressed" style="width:36px;" data-action-type="change-quality" title="Low-Quality Preview" onclick="toggleQualityDirector(50, this.dataset.UUID, this);">
|
||||||
<span data-translate="change-to-medium-quality"> <i class="las la-video"></i></span>
|
<span data-translate="change-to-medium-quality"> <i class="las la-video"></i></span>
|
||||||
</button>
|
</button>
|
||||||
<button style="width: 36px" data-action-type="change-quality" title="High-Quality Preview" onclick="toggleQualityDirector(1200, this.dataset.UUID, this);">
|
<button style="width: 36px" data-action-type="change-quality" title="High-Quality Preview" onclick="toggleQualityDirector(1200, this.dataset.UUID, this);">
|
||||||
@@ -588,6 +612,15 @@
|
|||||||
<span data-translate="send-direct-chat"><i class="las la-envelope"></i> Message</span>
|
<span data-translate="send-direct-chat"><i class="las la-envelope"></i> Message</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button data-action-type="advanced-camera-settings" title="Advanced Settings and Remote Control" onclick="directorSendMessage(this);">
|
||||||
|
<span data-translate="advanced-camera-settings"><i class="las la-cog"></i> Advanced</span>
|
||||||
|
</button>
|
||||||
|
<button data-action-type="voice-chat" title="Toggle Voice Chat with this Guest" onclick="directorSendMessage(this);">
|
||||||
|
<span data-translate="voice-chat"><i class="las la-microphone"></i> Voice Chat</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="popupSelector" style="display:none;">
|
<div id="popupSelector" style="display:none;">
|
||||||
@@ -620,8 +653,13 @@
|
|||||||
<button id="shareScreenGear" style="width: 135px; padding:20px;text-align:center;" onclick="grabScreen()"><b>Share Screen</b><br /><i style="padding:5px; font-size:300%;" class="las la-desktop"></i></button><br />
|
<button id="shareScreenGear" style="width: 135px; padding:20px;text-align:center;" onclick="grabScreen()"><b>Share Screen</b><br /><i style="padding:5px; font-size:300%;" class="las la-desktop"></i></button><br />
|
||||||
<button onclick="toggleSettings()" style="width: 135px; background-color:#EFEFEF;padding:10px 12px 12px 2px;margin: 10px 0px 20px 0"><i class="chevron right" style="font-size:150%;top:3px;position:relative;"></i> <b>Close Settings</b></button>
|
<button onclick="toggleSettings()" style="width: 135px; background-color:#EFEFEF;padding:10px 12px 12px 2px;margin: 10px 0px 20px 0"><i class="chevron right" style="font-size:150%;top:3px;position:relative;"></i> <b>Close Settings</b></button>
|
||||||
|
|
||||||
<button id='advancedOptions' onclick="this.style.display = 'none'; toggle(getById('popupSelector_constraints'),false,false); " style="display:none; background-color:#EFEFEF;padding:10px 12px 12px 2px;margin: 10px 0px 0px 10px"><i class="chevron bottom" style="font-size:150%;top:3px;position:relative;"></i> <b>Show Advanced</b></button>
|
<button id='advancedOptionsCamera' onclick="this.style.display = 'none'; toggle(getById('popupSelector_constraints_camera'),false,false); " style="display:none; background-color:#EFEFEF;padding:10px 12px 12px 2px;margin: 10px 0px 0px 10px"><i class="chevron bottom" style="font-size:150%;top:3px;position:relative;"></i> <b>Advanced Video</b></button>
|
||||||
<span id="popupSelector_constraints" style="display: none;">
|
<button id='advancedOptionsAudio' onclick="this.style.display = 'none'; toggle(getById('popupSelector_constraints_audio'),false,false); " style="display:none; background-color:#EFEFEF;padding:10px 12px 12px 2px;margin: 10px 0px 0px 10px"><i class="chevron bottom" style="font-size:150%;top:3px;position:relative;"></i> <b>Advanced Audio</b></button>
|
||||||
|
|
||||||
|
<span id="popupSelector_constraints_audio" class="popupSelector_constraints" style="display: none;">
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<span id="popupSelector_constraints_video" class="popupSelector_constraints" style="display: none;">
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
@@ -687,6 +725,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="chatModule" style="display:none;">
|
<div id="chatModule" style="display:none;">
|
||||||
|
<a target="popup" style="cursor:pointer;" onclick="createPopoutChat();">💢</a>
|
||||||
<div id="chatBody">
|
<div id="chatBody">
|
||||||
<div class="inMessage" data-translate='welcome-to-obs-ninja-chat'>
|
<div class="inMessage" data-translate='welcome-to-obs-ninja-chat'>
|
||||||
Welcome to OBS.Ninja! You can send text messages directly to connected peers from here.
|
Welcome to OBS.Ninja! You can send text messages directly to connected peers from here.
|
||||||
@@ -707,6 +746,8 @@
|
|||||||
<!-- This image is used when dragging elements -->
|
<!-- This image is used when dragging elements -->
|
||||||
<img src="./images/favicon-32x32.png" id="dragImage" />
|
<img src="./images/favicon-32x32.png" id="dragImage" />
|
||||||
</div>
|
</div>
|
||||||
|
<div id="request_info_prompt" style="display:none">
|
||||||
|
</div>
|
||||||
<div id="messagePopup" class="popup-message"></div>
|
<div id="messagePopup" class="popup-message"></div>
|
||||||
<div id="languages" class="popup-message" style="display: none; right: 0; bottom: 25px; position: absolute;">
|
<div id="languages" class="popup-message" style="display: none; right: 0; bottom: 25px; position: absolute;">
|
||||||
<b data-translate='available-languages'>Available Languages:</b>
|
<b data-translate='available-languages'>Available Languages:</b>
|
||||||
@@ -745,7 +786,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
var session = WebRTC.Media; // session is a required global variable if configuring manually. Run before loading main.js but after webrtc.js.
|
var session = WebRTC.Media; // session is a required global variable if configuring manually. Run before loading main.js but after webrtc.js.
|
||||||
session.version = "13.4";
|
session.version = "13.5b";
|
||||||
session.streamID = session.generateStreamID(); // randomly generates a streamID for this session. You can set your own programmatically if needed
|
session.streamID = session.generateStreamID(); // randomly generates a streamID for this session. You can set your own programmatically if needed
|
||||||
|
|
||||||
session.defaultPassword = "someEncryptionKey123"; // Disabling improves compatibility and is helpful for debugging.
|
session.defaultPassword = "someEncryptionKey123"; // Disabling improves compatibility and is helpful for debugging.
|
||||||
|
|||||||
31
main.css
31
main.css
@@ -160,9 +160,7 @@ button.white:active {
|
|||||||
width:100%;
|
width:100%;
|
||||||
pointer-events: none
|
pointer-events: none
|
||||||
}
|
}
|
||||||
#popupSelector_constraints{
|
|
||||||
margin:30px 9% 0 7%;
|
|
||||||
}
|
|
||||||
.credits {
|
.credits {
|
||||||
color: #101020;
|
color: #101020;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -458,6 +456,16 @@ body {
|
|||||||
animation: fading 0.2s;
|
animation: fading 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#getPermissions{
|
||||||
|
font-size: 110%;
|
||||||
|
border: 3px solid #99A;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #cce0ff;
|
||||||
|
margin: 20px;
|
||||||
|
padding: 10px 50px;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
.gowebcam {
|
.gowebcam {
|
||||||
font-size: 110%;
|
font-size: 110%;
|
||||||
border: 3px solid #DDDDDD;
|
border: 3px solid #DDDDDD;
|
||||||
@@ -698,8 +706,10 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.popupSelector_constraints{
|
||||||
#popupSelector_constraints label{
|
margin:30px 9% 0 7%;
|
||||||
|
}
|
||||||
|
.popupSelector_constraints label{
|
||||||
color:white;
|
color:white;
|
||||||
text-shadow: 0px 0px 6px #000000FF;
|
text-shadow: 0px 0px 6px #000000FF;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -1128,6 +1138,17 @@ img {
|
|||||||
opacity: 1
|
opacity: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#request_info_prompt{
|
||||||
|
z-index: 20;
|
||||||
|
color: white;
|
||||||
|
font-size: 30px;
|
||||||
|
font-size: 3.5vw;
|
||||||
|
top: 0;
|
||||||
|
align-self: center;
|
||||||
|
margin: 25vh 0;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
video {
|
video {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
|||||||
574
main.js
574
main.js
@@ -196,7 +196,7 @@ sanitizeRoomName = function(roomid){
|
|||||||
sanitizePassword = function(passwrd){
|
sanitizePassword = function(passwrd){
|
||||||
if (passwrd===""){return passwrd;}
|
if (passwrd===""){return passwrd;}
|
||||||
else if (passwrd===false){return passwrd;}
|
else if (passwrd===false){return passwrd;}
|
||||||
|
else if (passwrd===null){return passwrd;}
|
||||||
passwrd = passwrd.trim();
|
passwrd = passwrd.trim();
|
||||||
if (passwrd.length < 1){
|
if (passwrd.length < 1){
|
||||||
if (!(session.cleanOutput)){
|
if (!(session.cleanOutput)){
|
||||||
@@ -423,7 +423,7 @@ if (/CriOS/i.test(navigator.userAgent) && /iphone|ipod|ipad/i.test(navigator.use
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (urlParams.has('broadcast') || urlParams.has('bc')){
|
if (urlParams.has('broadcast') || urlParams.has('bc')){
|
||||||
log("Room BITRATE SET");
|
log("Broadcast flag set");
|
||||||
session.broadcast = urlParams.get('broadcast') || urlParams.get('bc');
|
session.broadcast = urlParams.get('broadcast') || urlParams.get('bc');
|
||||||
session.nopreview=true;
|
session.nopreview=true;
|
||||||
session.style=1;
|
session.style=1;
|
||||||
@@ -490,7 +490,9 @@ if (session.password){
|
|||||||
session.defaultPassword = false;
|
session.defaultPassword = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (urlParams.has('hash') || urlParams.has('crc') || urlParams.has('check')){ // could be brute forced in theory, so not as safe as just not using a hash check.
|
if (urlParams.has('hash') || urlParams.has('crc') || urlParams.has('check')){ // could be brute forced in theory, so not as safe as just not using a hash check.
|
||||||
|
session.taintedSession=null; // waiting to see if valid or not.
|
||||||
var hash_input = urlParams.get('hash') || urlParams.get('crc') || urlParams.get('check');
|
var hash_input = urlParams.get('hash') || urlParams.get('crc') || urlParams.get('check');
|
||||||
if (session.password===false){
|
if (session.password===false){
|
||||||
session.password = prompt("Please enter the password below: \n\n(Note: Passwords are case-sensitive and you will not be alerted if it is incorrect.)");
|
session.password = prompt("Please enter the password below: \n\n(Note: Passwords are case-sensitive and you will not be alerted if it is incorrect.)");
|
||||||
@@ -502,10 +504,22 @@ if (urlParams.has('hash') || urlParams.has('crc') || urlParams.has('check')){ /
|
|||||||
session.generateHash(session.password+session.salt,6).then(function(hash){ // million to one error.
|
session.generateHash(session.password+session.salt,6).then(function(hash){ // million to one error.
|
||||||
log("hash is "+hash);
|
log("hash is "+hash);
|
||||||
if (hash.substring(0, 4) !== hash_input){ // hash crc checks are just first 4 characters.
|
if (hash.substring(0, 4) !== hash_input){ // hash crc checks are just first 4 characters.
|
||||||
|
session.taintedSession=true;
|
||||||
if (!(session.cleanOutput)){
|
if (!(session.cleanOutput)){
|
||||||
alert("The password was incorrect.\n\nRefresh and try again.");
|
getById("request_info_prompt").innerHTML = "The password was incorrect.\n\nRefresh and try again.";
|
||||||
|
getById("request_info_prompt").style.display = "block";
|
||||||
|
getById("mainmenu").style.display = "none";
|
||||||
|
getById("head1").style.display = "none";
|
||||||
|
session.cleanOutput = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
getById("request_info_prompt").innerHTML = "";
|
||||||
|
getById("request_info_prompt").style.display = "block";
|
||||||
|
getById("mainmenu").style.display = "none";
|
||||||
|
getById("head1").style.display = "none";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
session.taintedSession=false;
|
||||||
session.hash = hash;
|
session.hash = hash;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1120,8 +1134,8 @@ if (urlParams.has('quality') || urlParams.has('q')){
|
|||||||
|
|
||||||
if (urlParams.has('sink')){
|
if (urlParams.has('sink')){
|
||||||
session.sink = urlParams.get('sink');
|
session.sink = urlParams.get('sink');
|
||||||
} else if (urlParams.has('outputdevice') || urlParams.has('od')){
|
} else if (urlParams.has('outputdevice') || urlParams.has('od') || urlParams.has('audiooutput')){
|
||||||
session.outputDevice = urlParams.get('outputdevice') || urlParams.get('od');
|
session.outputDevice = urlParams.get('outputdevice') || urlParams.get('od') || urlParams.get('audiooutput');
|
||||||
if (session.outputDevice){
|
if (session.outputDevice){
|
||||||
session.outputDevice = session.outputDevice.toLowerCase().replace(/[\W]+/g,"_");
|
session.outputDevice = session.outputDevice.toLowerCase().replace(/[\W]+/g,"_");
|
||||||
} else {
|
} else {
|
||||||
@@ -1509,6 +1523,34 @@ window.onmessage = function(e){ // iFRAME support
|
|||||||
for (var i in session.rpcs){
|
for (var i in session.rpcs){
|
||||||
stats.inbound_stats[session.rpcs[i].streamID] = session.rpcs[i].stats;
|
stats.inbound_stats[session.rpcs[i].streamID] = session.rpcs[i].stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var uuid in session.pcs){
|
||||||
|
session.pcs[uuid].getStats().then(function(stats){
|
||||||
|
stats.forEach(stat=>{
|
||||||
|
if (stat.type=="outbound-rtp"){
|
||||||
|
if (stat.kind=="video"){
|
||||||
|
|
||||||
|
if ("qualityLimitationReason" in stat){
|
||||||
|
session.pcs[uuid].stats.quality_Limitation_Reason = stat.qualityLimitationReason;
|
||||||
|
}
|
||||||
|
if ("framesPerSecond" in stat){
|
||||||
|
session.pcs[uuid].stats.resolution = stat.frameWidth+" x "+ stat.frameHeight +" @ "+stat.framesPerSecond;
|
||||||
|
}
|
||||||
|
if ("encoderImplementation" in stat){
|
||||||
|
session.pcs[uuid].stats.encoder = stat.encoderImplementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.outbound_stats = {};
|
||||||
|
for (var i in session.pcs){
|
||||||
|
stats.outbound_stats[i] = session.pcs[i].stats;
|
||||||
|
}
|
||||||
parent.postMessage({"stats": stats }, "*");
|
parent.postMessage({"stats": stats }, "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1627,7 +1669,7 @@ function sleep(ms = 0){
|
|||||||
return new Promise(r => setTimeout(r, ms)); // LOLz!
|
return new Promise(r => setTimeout(r, ms)); // LOLz!
|
||||||
}
|
}
|
||||||
|
|
||||||
session.connect();
|
|
||||||
// session.volume = 100; // needs to be set after?
|
// session.volume = 100; // needs to be set after?
|
||||||
|
|
||||||
|
|
||||||
@@ -1969,6 +2011,7 @@ if (urlParams.has('hideheader') || urlParams.has('noheader') || urlParams.has('h
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkConnection(){
|
function checkConnection(){
|
||||||
|
if (session.ws===null){return;}
|
||||||
if (document.getElementById("qos")){ // true or false; null might cause problems?
|
if (document.getElementById("qos")){ // true or false; null might cause problems?
|
||||||
if ((session.ws) && (session.ws.readyState === WebSocket.OPEN)) {
|
if ((session.ws) && (session.ws.readyState === WebSocket.OPEN)) {
|
||||||
getById("qos").style.color = "white";
|
getById("qos").style.color = "white";
|
||||||
@@ -1981,9 +2024,12 @@ setInterval(function(){checkConnection();},5000);
|
|||||||
|
|
||||||
|
|
||||||
function printViewStats(menu, statsObj, streamID){ // Stats for viewing a remote video
|
function printViewStats(menu, statsObj, streamID){ // Stats for viewing a remote video
|
||||||
|
var scrollLeft = menu.scrollLeft;
|
||||||
|
var scrollTop = menu.scrollTop;
|
||||||
menu.innerHTML="StreamID: <b>"+streamID+"</b><br />";
|
menu.innerHTML="StreamID: <b>"+streamID+"</b><br />";
|
||||||
menu.innerHTML+= printValues(statsObj);
|
menu.innerHTML+= printValues(statsObj);
|
||||||
|
menu.scrollTop = scrollTop;
|
||||||
|
menu.scrollLeft = scrollLeft;
|
||||||
|
|
||||||
}
|
}
|
||||||
function printValues(obj) { // see: printViewStats
|
function printValues(obj) { // see: printViewStats
|
||||||
@@ -2025,6 +2071,10 @@ function printValues(obj) { // see: printViewStats
|
|||||||
|
|
||||||
|
|
||||||
function printMyStats(menu){ // see: setupStatsMenu
|
function printMyStats(menu){ // see: setupStatsMenu
|
||||||
|
|
||||||
|
var scrollLeft = getById("menuStatsBox").scrollLeft;
|
||||||
|
var scrollTop = getById("menuStatsBox").scrollTop;
|
||||||
|
log(scrollTop + " " + scrollLeft);
|
||||||
menu.innerHTML="";
|
menu.innerHTML="";
|
||||||
|
|
||||||
session.stats.outbound_connections = Object.keys(session.pcs).length;
|
session.stats.outbound_connections = Object.keys(session.pcs).length;
|
||||||
@@ -2061,9 +2111,17 @@ function printMyStats(menu){ // see: setupStatsMenu
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
printViewValues(session.pcs[uuid].stats);
|
printViewValues(session.pcs[uuid].stats);
|
||||||
menu.innerHTML+="<br /><br />"
|
menu.innerHTML+="<br /><br />";
|
||||||
|
try{
|
||||||
|
getById("menuStatsBox").scrollLeft = scrollLeft;
|
||||||
|
getById("menuStatsBox").scrollTop = scrollTop;
|
||||||
|
} catch(e){}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
try{
|
||||||
|
getById("menuStatsBox").scrollLeft = scrollLeft;
|
||||||
|
getById("menuStatsBox").scrollTop = scrollTop;
|
||||||
|
} catch(e){}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2183,7 +2241,7 @@ function toggleSpeakerMute(apply=false){ // TODO: I need to have this be MUTE, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function toggleChat(ele=null){ // TODO: I need to have this be MUTE, toggle, with volume not touched.
|
function toggleChat(event=null){ // TODO: I need to have this be MUTE, toggle, with volume not touched.
|
||||||
if (session.chat==false){
|
if (session.chat==false){
|
||||||
setTimeout(function(){document.addEventListener("click", toggleChat);},10);
|
setTimeout(function(){document.addEventListener("click", toggleChat);},10);
|
||||||
|
|
||||||
@@ -2649,7 +2707,6 @@ function publishScreen(){
|
|||||||
|
|
||||||
}
|
}
|
||||||
function publishWebcam(btn = false){
|
function publishWebcam(btn = false){
|
||||||
log(btn);
|
|
||||||
if (btn){
|
if (btn){
|
||||||
if (btn.dataset.ready == "false"){
|
if (btn.dataset.ready == "false"){
|
||||||
warnlog("Clicked too quickly; button not enabled yet");
|
warnlog("Clicked too quickly; button not enabled yet");
|
||||||
@@ -2714,7 +2771,6 @@ function publishWebcam(btn = false){
|
|||||||
updateURL("push="+session.streamID);
|
updateURL("push="+session.streamID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
session.publishStream(ele, title);
|
session.publishStream(ele, title);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3940,7 +3996,7 @@ function playtone(screen=false){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAudioOnly(selector, trackid=null){
|
async function getAudioOnly(selector, trackid=null, override=false){
|
||||||
var audioSelect = document.querySelector(selector).querySelectorAll("input");
|
var audioSelect = document.querySelector(selector).querySelectorAll("input");
|
||||||
var audioList = [];
|
var audioList = [];
|
||||||
var streams = [];
|
var streams = [];
|
||||||
@@ -3974,6 +4030,10 @@ async function getAudioOnly(selector, trackid=null){
|
|||||||
}
|
}
|
||||||
constraint.video = false;
|
constraint.video = false;
|
||||||
//warnlog(constraint);
|
//warnlog(constraint);
|
||||||
|
if (override!==false){
|
||||||
|
constraint = override;
|
||||||
|
}
|
||||||
|
|
||||||
var stream = await navigator.mediaDevices.getUserMedia(constraint).then(function (stream2){
|
var stream = await navigator.mediaDevices.getUserMedia(constraint).then(function (stream2){
|
||||||
log("pushing stream2");
|
log("pushing stream2");
|
||||||
return stream2;
|
return stream2;
|
||||||
@@ -4484,7 +4544,7 @@ async function grabVideo(quality=0, eleName='previewWebcam', selector="select#vi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function grabAudio(eleName="previewWebcam", selector="#audioSource", trackid = null){ // trackid is the excluded track
|
async function grabAudio(eleName="previewWebcam", selector="#audioSource", trackid = null, override=false){ // trackid is the excluded track
|
||||||
if( activatedPreview == true){log("activated preview return 2");return;}
|
if( activatedPreview == true){log("activated preview return 2");return;}
|
||||||
activatedPreview = true;
|
activatedPreview = true;
|
||||||
try {
|
try {
|
||||||
@@ -4526,7 +4586,7 @@ async function grabAudio(eleName="previewWebcam", selector="#audioSource", track
|
|||||||
errorlog(e);
|
errorlog(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
var streams = await getAudioOnly(selector, trackid); // Get audio streams
|
var streams = await getAudioOnly(selector, trackid, override); // Get audio streams
|
||||||
try {
|
try {
|
||||||
for (var i=0; i<streams.length;i++){
|
for (var i=0; i<streams.length;i++){
|
||||||
streams[i].getAudioTracks().forEach(function(track){
|
streams[i].getAudioTracks().forEach(function(track){
|
||||||
@@ -4767,11 +4827,219 @@ function dragElement(elmnt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadIframe(iframesrc){ // this is pretty important if you want to avoid camera permission popup problems. You can also call it automatically via: <body onload=>loadIframe();"> , but don't call it before the page loads.
|
||||||
|
|
||||||
|
var iframe = document.createElement("iframe");
|
||||||
|
var iframeContainer = getById("iFramePreview");
|
||||||
|
iframe.allow="autoplay;camera;microphone";
|
||||||
|
iframe.allowtransparency="true";
|
||||||
|
iframe.allowfullscreen ="true";
|
||||||
|
iframe.style.width="100%";
|
||||||
|
iframe.style.height="100%";
|
||||||
|
|
||||||
|
if (iframesrc==""){
|
||||||
|
iframesrc="./";
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe.src = iframesrc;
|
||||||
|
iframeContainer.appendChild(iframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateConstraintSliders(){
|
function updateConstraintSliders(){
|
||||||
getById("popupSelector_constraints").innerHTML = "";
|
log("updateConstraintSliders");
|
||||||
|
listAudioSettings();
|
||||||
|
listCameraSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function listAudioSettings(){
|
||||||
|
getById("popupSelector_constraints_audio").innerHTML = "";
|
||||||
|
try {
|
||||||
|
var track0 = session.streamSrc.getAudioTracks();
|
||||||
|
track0 = track0[0];
|
||||||
|
if (track0.getCapabilities){
|
||||||
|
session.cameraConstaints = track0.getCapabilities();
|
||||||
|
}
|
||||||
|
|
||||||
|
log(session.cameraConstaints);
|
||||||
|
} catch(e){
|
||||||
|
errorlog(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (track0.getSettings){
|
||||||
|
session.currentCameraConstaints = track0.getSettings();
|
||||||
|
}
|
||||||
|
} catch(e){
|
||||||
|
errorlog(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in session.cameraConstaints){
|
||||||
|
try {
|
||||||
|
log(i);
|
||||||
|
log(session.cameraConstaints[i]);
|
||||||
|
if ((typeof session.cameraConstaints[i] ==='object') && (session.cameraConstaints[i] !== null) && ("max" in session.cameraConstaints[i]) && ("min" in session.cameraConstaints[i])){
|
||||||
|
if (i==="aspectRatio"){continue;}
|
||||||
|
else if (i==="width"){continue;}
|
||||||
|
else if (i==="height"){continue;}
|
||||||
|
else if (i==="frameRate"){continue;}
|
||||||
|
|
||||||
|
var label = document.createElement("label");
|
||||||
|
label.id= "label_"+i;
|
||||||
|
label.htmlFor = "constraints_"+i;
|
||||||
|
label.innerHTML = i+":";
|
||||||
|
|
||||||
|
var input = document.createElement("input");
|
||||||
|
input.min = session.cameraConstaints[i].min;
|
||||||
|
input.max = session.cameraConstaints[i].max;
|
||||||
|
if (input.min == input.max){continue;}
|
||||||
|
|
||||||
|
if (getById("popupSelector_constraints_audio").style.display == "none"){
|
||||||
|
getById("advancedOptionsAudio").style.display="inline-block";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (i in session.currentCameraConstaints){
|
||||||
|
input.value = session.currentCameraConstaints[i];
|
||||||
|
label.innerHTML = i+": "+session.currentCameraConstaints[i];
|
||||||
|
} else {
|
||||||
|
label.innerHTML = i;
|
||||||
|
}
|
||||||
|
if ("step" in session.cameraConstaints[i]){
|
||||||
|
input.step = session.cameraConstaints[i].step;
|
||||||
|
}
|
||||||
|
input.type = "range";
|
||||||
|
input.dataset.keyname = i;
|
||||||
|
input.id = "constraints_"+i;
|
||||||
|
input.style="display:block; width:100%;";
|
||||||
|
input.name = "constraints_"+i;
|
||||||
|
|
||||||
|
|
||||||
|
input.onchange = function(e){
|
||||||
|
getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value;
|
||||||
|
//updateAudioConstraints(e.target.dataset.keyname, e.target.value);
|
||||||
|
applyAudioHack(track0,e.target.dataset.keyname, e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
getById("popupSelector_constraints_audio").appendChild(label);
|
||||||
|
getById("popupSelector_constraints_audio").appendChild(input);
|
||||||
|
} else if ((typeof session.cameraConstaints[i] ==='object') && (session.cameraConstaints[i] !== null)){
|
||||||
|
if (i == "resizeMode"){continue;}
|
||||||
|
|
||||||
|
var div = document.createElement("div");
|
||||||
|
var label = document.createElement("label");
|
||||||
|
label.id= "label_"+i;
|
||||||
|
label.htmlFor = "constraints_"+i;
|
||||||
|
label.innerHTML = i+":";
|
||||||
|
label.style="display:inline-block; padding:0;margin: 15px 0px 29px;";
|
||||||
|
label.dataset.keyname = i;
|
||||||
|
var input = document.createElement("select");
|
||||||
|
var c = document.createElement("option");
|
||||||
|
|
||||||
|
if (session.cameraConstaints[i].length>1){
|
||||||
|
for (var opts in session.cameraConstaints[i]) {
|
||||||
|
log(opts);
|
||||||
|
var opt = new Option(session.cameraConstaints[i][opts], session.cameraConstaints[i][opts]);
|
||||||
|
input.options.add(opt);
|
||||||
|
}
|
||||||
|
} else if (i.toLowerCase == "torch"){
|
||||||
|
var opt = new Option("Off", false);
|
||||||
|
input.options.add(opt);
|
||||||
|
opt = new Option("On", true);
|
||||||
|
input.options.add(opt);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.id = "constraints_"+i;
|
||||||
|
input.className="constraintCameraInput";
|
||||||
|
input.name = "constraints_"+i;
|
||||||
|
input.style = "display:inline; padding:2px; margin:0 10px;";
|
||||||
|
input.dataset.keyname = i;
|
||||||
|
input.onchange = function(e){
|
||||||
|
//getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value;
|
||||||
|
//updateAudioConstraints(e.target.dataset.keyname, e.target.value);
|
||||||
|
applyAudioHack(track0,e.target.dataset.keyname, e.target.value);
|
||||||
|
log(e.target.dataset.keyname, e.target.value);
|
||||||
|
};
|
||||||
|
getById("popupSelector_constraints_audio").appendChild(div);
|
||||||
|
div.appendChild(label);
|
||||||
|
div.appendChild(input);
|
||||||
|
} else if (typeof session.cameraConstaints[i] === 'boolean'){
|
||||||
|
|
||||||
|
var div = document.createElement("div");
|
||||||
|
var label = document.createElement("label");
|
||||||
|
label.id= "label_"+i;
|
||||||
|
label.htmlFor = "constraints_"+i;
|
||||||
|
label.innerHTML = i+":";
|
||||||
|
label.style="display:inline-block; padding:0;margin: 15px 0px 29px;";
|
||||||
|
label.dataset.keyname = i;
|
||||||
|
var input = document.createElement("select");
|
||||||
|
var c = document.createElement("option");
|
||||||
|
|
||||||
|
var opt = new Option("Off", false);
|
||||||
|
input.options.add(opt);
|
||||||
|
opt = new Option("On", true);
|
||||||
|
input.options.add(opt);
|
||||||
|
|
||||||
|
input.id = "constraints_"+i;
|
||||||
|
input.className="constraintCameraInput";
|
||||||
|
input.name = "constraints_"+i;
|
||||||
|
input.style = "display:inline; padding:2px; margin:0 10px;";
|
||||||
|
input.dataset.keyname = i;
|
||||||
|
input.onchange = function(e){
|
||||||
|
//getById("label_"+e.target.dataset.keyname).innerHTML =e.target.dataset.keyname+": "+e.target.value;
|
||||||
|
//updateAudioConstraints(e.target.dataset.keyname, e.target.value);
|
||||||
|
applyAudioHack(track0,e.target.dataset.keyname, e.target.value);
|
||||||
|
log(e.target.dataset.keyname, e.target.value);
|
||||||
|
};
|
||||||
|
getById("popupSelector_constraints_audio").appendChild(div);
|
||||||
|
div.appendChild(label);
|
||||||
|
div.appendChild(input);
|
||||||
|
}
|
||||||
|
} catch(e){errorlog(e);}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function applyAudioHack(track, constraint, value=null){
|
||||||
|
if (value == parseFloat(value)){
|
||||||
|
value = parseFloat(value);
|
||||||
|
value = {exact: value};
|
||||||
|
} else if (value == "true"){
|
||||||
|
value = true;
|
||||||
|
} else if (value == "false"){
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
log("CONTREAIT",constraint);
|
||||||
|
var new_constraints = Object.assign(track.getSettings(), {[constraint]:value}, );
|
||||||
|
new_constraints = {audio: new_constraints, video:false};
|
||||||
|
log(new_constraints);
|
||||||
|
activatedPreview=false;
|
||||||
|
grabAudio("videosource","#audioSource3", null, new_constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAudioConstraints(constraint, value=null){ // this is what it SHOULD be, but this doesn't work yet.
|
||||||
|
var track0 = session.streamSrc.getAudioTracks();
|
||||||
|
track0 = track0[0];
|
||||||
|
if (value == parseFloat(value)){
|
||||||
|
value = parseFloat(value);
|
||||||
|
} else if (value == "true"){
|
||||||
|
value = true;
|
||||||
|
} else if (value == "false"){
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
log({advanced: [ {[constraint]: value} ]});
|
||||||
|
track0.applyConstraints({advanced: [ {[constraint]: value} ]});
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function listCameraSettings(){
|
||||||
|
getById("popupSelector_constraints_video").innerHTML = "";
|
||||||
try {
|
try {
|
||||||
var track0 = session.streamSrc.getVideoTracks();
|
var track0 = session.streamSrc.getVideoTracks();
|
||||||
track0 = track0[0];
|
track0 = track0[0];
|
||||||
@@ -4804,9 +5072,7 @@ function updateConstraintSliders(){
|
|||||||
else if (i==="height"){continue;}
|
else if (i==="height"){continue;}
|
||||||
else if (i==="frameRate"){continue;}
|
else if (i==="frameRate"){continue;}
|
||||||
|
|
||||||
if (getById("popupSelector_constraints").style.display == "none"){
|
|
||||||
getById("advancedOptions").style.display="inline-block";
|
|
||||||
}
|
|
||||||
|
|
||||||
var label = document.createElement("label");
|
var label = document.createElement("label");
|
||||||
label.id= "label_"+i;
|
label.id= "label_"+i;
|
||||||
@@ -4817,6 +5083,12 @@ function updateConstraintSliders(){
|
|||||||
input.min = session.cameraConstaints[i].min;
|
input.min = session.cameraConstaints[i].min;
|
||||||
input.max = session.cameraConstaints[i].max;
|
input.max = session.cameraConstaints[i].max;
|
||||||
|
|
||||||
|
if (input.min == input.max){continue;}
|
||||||
|
|
||||||
|
if (getById("popupSelector_constraints_video").style.display == "none"){
|
||||||
|
getById("advancedOptionsCamera").style.display="inline-block";
|
||||||
|
}
|
||||||
|
|
||||||
if (i in session.currentCameraConstaints){
|
if (i in session.currentCameraConstaints){
|
||||||
input.value = session.currentCameraConstaints[i];
|
input.value = session.currentCameraConstaints[i];
|
||||||
label.innerHTML = i+": "+session.currentCameraConstaints[i];
|
label.innerHTML = i+": "+session.currentCameraConstaints[i];
|
||||||
@@ -4839,8 +5111,8 @@ function updateConstraintSliders(){
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
getById("popupSelector_constraints").appendChild(label);
|
getById("popupSelector_constraints_video").appendChild(label);
|
||||||
getById("popupSelector_constraints").appendChild(input);
|
getById("popupSelector_constraints_video").appendChild(input);
|
||||||
} else if ((typeof session.cameraConstaints[i] ==='object') && (session.cameraConstaints[i] !== null)){
|
} else if ((typeof session.cameraConstaints[i] ==='object') && (session.cameraConstaints[i] !== null)){
|
||||||
if (i == "resizeMode"){continue;}
|
if (i == "resizeMode"){continue;}
|
||||||
|
|
||||||
@@ -4879,7 +5151,7 @@ function updateConstraintSliders(){
|
|||||||
updateCameraConstraints(e.target.dataset.keyname, e.target.value);
|
updateCameraConstraints(e.target.dataset.keyname, e.target.value);
|
||||||
log(e.target.dataset.keyname, e.target.value);
|
log(e.target.dataset.keyname, e.target.value);
|
||||||
};
|
};
|
||||||
getById("popupSelector_constraints").appendChild(div);
|
getById("popupSelector_constraints_video").appendChild(div);
|
||||||
div.appendChild(label);
|
div.appendChild(label);
|
||||||
div.appendChild(input);
|
div.appendChild(input);
|
||||||
} else if (typeof session.cameraConstaints[i] === 'boolean'){
|
} else if (typeof session.cameraConstaints[i] === 'boolean'){
|
||||||
@@ -4909,7 +5181,7 @@ function updateConstraintSliders(){
|
|||||||
updateCameraConstraints(e.target.dataset.keyname, e.target.value);
|
updateCameraConstraints(e.target.dataset.keyname, e.target.value);
|
||||||
log(e.target.dataset.keyname, e.target.value);
|
log(e.target.dataset.keyname, e.target.value);
|
||||||
};
|
};
|
||||||
getById("popupSelector_constraints").appendChild(div);
|
getById("popupSelector_constraints_video").appendChild(div);
|
||||||
div.appendChild(label);
|
div.appendChild(label);
|
||||||
div.appendChild(input);
|
div.appendChild(input);
|
||||||
}
|
}
|
||||||
@@ -5099,33 +5371,24 @@ Promise.prototype.timeout = function(ms) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function previewWebcam(){
|
function previewWebcam(){
|
||||||
|
|
||||||
|
if (session.taintedSession===null){
|
||||||
|
log("STILL WAITING ON HASH TO VALIDATE")
|
||||||
|
setTimeout(function(){previewWebcam();},1000);
|
||||||
|
return;
|
||||||
|
} else if (session.taintedSession===true){
|
||||||
|
warnlog("HASH FAILED; PASSWORD NOT VALID");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
log("NOT TAINTED");
|
||||||
|
}
|
||||||
|
|
||||||
if( activatedPreview == true){
|
if( activatedPreview == true){
|
||||||
log("activeated preview return 1");
|
log("activeated preview return 1");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
activatedPreview = true;
|
activatedPreview = true;
|
||||||
|
|
||||||
try{
|
|
||||||
var oldstream = getById('previewWebcam').srcObject;
|
|
||||||
|
|
||||||
if (oldstream){
|
|
||||||
log("old stream found");
|
|
||||||
oldstream.getTracks().forEach(function(track) {
|
|
||||||
track.stop();
|
|
||||||
oldstream.removeTrack(track);
|
|
||||||
log("stopping old track");
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
getById('previewWebcam').srcObject = new MediaStream();
|
|
||||||
session.streamSrc = getById('previewWebcam').srcObject;
|
|
||||||
log("CREATE NEW STREAM");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e){
|
|
||||||
errorlog(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session.audioDevice===0){ // OFF
|
if (session.audioDevice===0){ // OFF
|
||||||
var constraint = {audio: false};
|
var constraint = {audio: false};
|
||||||
} else if ((session.echoCancellation !== false) && (session.autoGainControl !== false) && (session.noiseSuppression !== false)){ // AUTO
|
} else if ((session.echoCancellation !== false) && (session.autoGainControl !== false) && (session.noiseSuppression !== false)){ // AUTO
|
||||||
@@ -5155,104 +5418,127 @@ function previewWebcam(){
|
|||||||
constraint.video = true;
|
constraint.video = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
log("getting permission from navigator");
|
// var autoPlayAllowed = false;
|
||||||
if ("permissions" in navigator){
|
// log("trying to play video");
|
||||||
log("queried0");
|
//
|
||||||
navigator.permissions.query({name: 'camera'}).then((permissionObj) => {
|
// var vid = document.createElement('video');
|
||||||
log("queried camera permissions successfully:");
|
// vid.src = ""; // we need this.play();
|
||||||
log(permissionObj.state);
|
// playPromise = vid.play();
|
||||||
if (permissionObj.state!=="prompt"){ // trying to bypass any NDI problems
|
// // In browsers that don’t yet support this functionality,
|
||||||
|
// // playPromise won’t be defined.
|
||||||
enumerateDevices().then(function(devices){
|
// if (playPromise !== undefined) {
|
||||||
var vtrue = false;
|
// getById("getPermissions").style.display="";
|
||||||
var atrue = false;
|
// getById("gowebcam").style.display="none";
|
||||||
devices.forEach(function(device) {
|
// //activatedPreview=false;
|
||||||
if (device.kind === 'audioinput'){
|
// log("checking promise");
|
||||||
atrue=true;
|
// log(playPromise);
|
||||||
} else if (device.kind === 'videoinput'){
|
// playPromise.catch(function(error) {
|
||||||
vtrue = true;
|
// if (error.name !== 'NotAllowedError') {
|
||||||
|
// autoPlayAllowed=true;
|
||||||
|
// log("PROMISE GOOD");
|
||||||
|
// }
|
||||||
|
// }).finally(function() {
|
||||||
|
// log("FINALLY ");
|
||||||
|
// delete vid;
|
||||||
|
// if (autoPlayAllowed) { /////// GOOD //////
|
||||||
|
// log("ALLOWED TO PLAY");
|
||||||
|
// getById("gowebcam").style.display="";
|
||||||
|
// getById("getPermissions").style.display="none";
|
||||||
|
enumerateDevices().then(function(devices){
|
||||||
|
log("enumeratated");
|
||||||
|
log(devices);
|
||||||
|
var vtrue = false;
|
||||||
|
var atrue = false;
|
||||||
|
devices.forEach(function(device) {
|
||||||
|
if (device.kind === 'audioinput'){
|
||||||
|
atrue=true;
|
||||||
|
} else if (device.kind === 'videoinput'){
|
||||||
|
vtrue = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (atrue===false){
|
||||||
|
constraint.audio = false;
|
||||||
}
|
}
|
||||||
});
|
if (vtrue===false){
|
||||||
if (atrue===false){
|
constraint.video = false;
|
||||||
constraint.audio = false;
|
|
||||||
requestBasicPermissions(constraint);
|
|
||||||
} else {
|
|
||||||
constraint.video = false;
|
|
||||||
requestBasicPermissions(constraint);
|
|
||||||
}
|
|
||||||
}).catch((error)=>{
|
|
||||||
requestBasicPermissions(constraint)
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log("constraint: "+constraint);
|
|
||||||
enumerateDevices().then(function(devices){
|
|
||||||
log("enumeratated");
|
|
||||||
var vtrue = false;
|
|
||||||
var atrue = false;
|
|
||||||
devices.forEach(function(device) {
|
|
||||||
if (device.kind === 'audioinput'){
|
|
||||||
atrue=true;
|
|
||||||
} else if (device.kind === 'videoinput'){
|
|
||||||
vtrue = true;
|
|
||||||
}
|
}
|
||||||
|
setTimeout(function(constraint){requestBasicPermissions(constraint);},0,constraint);
|
||||||
|
}).catch((error)=>{
|
||||||
|
log("enumeratated failed. Seeking permissions.");
|
||||||
|
setTimeout(function(constraint){requestBasicPermissions(constraint);},0,constraint);
|
||||||
});
|
});
|
||||||
if (atrue===false){
|
// return;
|
||||||
constraint.audio = false;
|
//
|
||||||
}
|
// } else {
|
||||||
if (vtrue===false){
|
// // BUTTON.
|
||||||
constraint.video = false;
|
// log("NOT ALLOWED TO CONTINUE -");
|
||||||
}
|
// }
|
||||||
requestBasicPermissions(constraint);
|
// });
|
||||||
}).catch((error)=>{
|
// } else {
|
||||||
log("enumeratated failed. Seeking permissions.");
|
// delete vid;
|
||||||
requestBasicPermissions(constraint)
|
// enumerateDevices().then(function(devices){
|
||||||
});
|
// log("enumeratated");
|
||||||
}
|
// log(devices);
|
||||||
|
// var vtrue = false;
|
||||||
}).catch((error) => {
|
// var atrue = false;
|
||||||
log("queried camera permissions returned error");
|
// devices.forEach(function(device) {
|
||||||
|
// if (device.kind === 'audioinput'){
|
||||||
enumerateDevices().then(function(devices){
|
// atrue=true;
|
||||||
var vtrue = false;
|
// } else if (device.kind === 'videoinput'){
|
||||||
var atrue = false;
|
// vtrue = true;
|
||||||
devices.forEach(function(device) {
|
// }
|
||||||
if (device.kind === 'audioinput'){
|
// });
|
||||||
atrue=true;
|
// if (atrue===false){
|
||||||
} else if (device.kind === 'videoinput'){
|
// constraint.audio = false;
|
||||||
vtrue = true;
|
// }
|
||||||
}
|
// if (vtrue===false){
|
||||||
});
|
// constraint.video = false;
|
||||||
if (atrue===false){
|
// }
|
||||||
constraint.audio = false;
|
// setTimeout(function(constraint){requestBasicPermissions(constraint);},0,constraint);
|
||||||
}
|
// }).catch((error)=>{
|
||||||
if (vtrue===false){
|
// log("enumeratated failed. Seeking permissions.");
|
||||||
constraint.video = false;
|
// setTimeout(function(constraint){requestBasicPermissions(constraint);},0,constraint);
|
||||||
}
|
// });
|
||||||
requestBasicPermissions(constraint);
|
// }
|
||||||
}).catch((error)=>{
|
//
|
||||||
requestBasicPermissions(constraint)
|
// } catch(e){
|
||||||
});
|
// setTimeout(function(constraint){requestBasicPermissions(constraint);},0,constraint);
|
||||||
});
|
// errorlog(e);
|
||||||
} else {
|
// }
|
||||||
log("queried not supported");
|
|
||||||
requestBasicPermissions(constraint);
|
|
||||||
}
|
|
||||||
} catch(e){
|
|
||||||
requestBasicPermissions(constraint)
|
|
||||||
errorlog(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestBasicPermissions(constraint){
|
function requestBasicPermissions(constraint={video:true,audio:true}){
|
||||||
log("PreviewWebcam");
|
if (session.taintedSession===null){
|
||||||
log(constraint);
|
log("STILL WAITING ON HASH TO VALIDATE")
|
||||||
|
setTimeout(function(constraint){requestBasicPermissions(constraint);},1000,constraint);
|
||||||
|
return;
|
||||||
|
} else if (session.taintedSession===true){
|
||||||
|
warnlog("HASH FAILED; PASSWORD NOT VALID");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
log("NOT TAINTED 1");
|
||||||
|
}
|
||||||
|
setTimeout(function(){
|
||||||
|
getById("getPermissions").style.display="none";
|
||||||
|
getById("gowebcam").style.display="";
|
||||||
|
},0);
|
||||||
|
log("REQUESTING BASIC PERMISSIONS");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var timerBasicCheck = setTimeout(function(){alert("Camera Access Request Timed Out\n\nDid you accept camera permissions? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling NDI tools.\n\nPlease also double check that your camera and audio devices are correctly connected. You may also need to refresh the page.");},10000);
|
var timerBasicCheck=null;
|
||||||
|
if (!(session.cleanOutput)){
|
||||||
|
log("Setting Timer for getUserMedia");
|
||||||
|
timerBasicCheck = setTimeout(function(){
|
||||||
|
if (!(session.cleanOutput)){
|
||||||
|
alert("Camera Access Request Timed Out\n\nDid you accept camera permissions? Please do so first.\n\nOtherwise, do you have NDI Tools installed? Maybe try uninstalling NDI tools.\n\nPlease also double check that your camera and audio devices are correctly connected. You may also need to refresh the page.");
|
||||||
|
}},10000);
|
||||||
|
}
|
||||||
|
log(constraint);
|
||||||
navigator.mediaDevices.getUserMedia(constraint).then(function(stream){ // Apple needs thi to happen before I can access EnumerateDevices.
|
navigator.mediaDevices.getUserMedia(constraint).then(function(stream){ // Apple needs thi to happen before I can access EnumerateDevices.
|
||||||
|
log("got first stream");
|
||||||
clearTimeout(timerBasicCheck);
|
clearTimeout(timerBasicCheck);
|
||||||
log("got first stream");
|
|
||||||
setupWebcamSelection(stream);
|
setupWebcamSelection(stream);
|
||||||
}).catch(function(err){
|
}).catch(function(err){
|
||||||
clearTimeout(timerBasicCheck);
|
clearTimeout(timerBasicCheck);
|
||||||
@@ -5875,10 +6161,13 @@ function sendChatMessage(){ // filtered + visual
|
|||||||
document.getElementById('chatInput').value = "";
|
document.getElementById('chatInput').value = "";
|
||||||
messageList.push(data);
|
messageList.push(data);
|
||||||
messageList = messageList.slice(-100);
|
messageList = messageList.slice(-100);
|
||||||
|
if(session.broadcastChannel!==false){
|
||||||
|
session.broadcastChannel.postMessage(data);
|
||||||
|
}
|
||||||
updateMessages();
|
updateMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleQualityDirector(bitrate, UUID, ele = null){
|
function toggleQualityDirector(bitrate, UUID, ele = null){ // ele is specific to the button in the director's room
|
||||||
var eles = ele.parentNode.childNodes;
|
var eles = ele.parentNode.childNodes;
|
||||||
for (i in eles){
|
for (i in eles){
|
||||||
eles[i].className="";
|
eles[i].className="";
|
||||||
@@ -5887,6 +6176,17 @@ function toggleQualityDirector(bitrate, UUID, ele = null){
|
|||||||
session.requestRateLimit(bitrate, UUID);
|
session.requestRateLimit(bitrate, UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createPopoutChat(){
|
||||||
|
var randid = session.generateStreamID(8);
|
||||||
|
log(randid);
|
||||||
|
window.open('./popout?id='+randid,'popup','width=600,height=480,toolbar=no,menubar=no,resizable=yes');
|
||||||
|
session.broadcastChannel = new BroadcastChannel(randid);
|
||||||
|
setTimeout(function(){
|
||||||
|
session.broadcastChannel.postMessage({messageList:messageList}); /// all data. delayed to ensure it loads. Should probably have a callback instead.
|
||||||
|
},5000);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function getChatMessage(msg, label=false, director=false, overlay=false){
|
function getChatMessage(msg, label=false, director=false, overlay=false){
|
||||||
msg = sanitize(msg); // keep it clean.
|
msg = sanitize(msg); // keep it clean.
|
||||||
if (msg==""){return;}
|
if (msg==""){return;}
|
||||||
@@ -5944,6 +6244,9 @@ function getChatMessage(msg, label=false, director=false, overlay=false){
|
|||||||
if (parent){
|
if (parent){
|
||||||
parent.postMessage({"gotChat": data }, "*");
|
parent.postMessage({"gotChat": data }, "*");
|
||||||
}
|
}
|
||||||
|
if (session.broadcastChannel!==false){
|
||||||
|
session.broadcastChannel.postMessage(data); /* send */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6019,6 +6322,8 @@ function recordVideo(target, event, videoKbps = false, interval=30){ // event.c
|
|||||||
log("Record Video queued");
|
log("Record Video queued");
|
||||||
defaultRecordingBitrate=false;
|
defaultRecordingBitrate=false;
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
defaultRecordingBitrate=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log("Record Video Clicked");
|
log("Record Video Clicked");
|
||||||
@@ -6086,6 +6391,7 @@ function recordVideo(target, event, videoKbps = false, interval=30){ // event.c
|
|||||||
video.recorder.mediaRecorder = new MediaRecorder(video.srcObject, options);
|
video.recorder.mediaRecorder = new MediaRecorder(video.srcObject, options);
|
||||||
|
|
||||||
function download() {
|
function download() {
|
||||||
|
|
||||||
const blob = new Blob(recordedBlobs, { type: "video/webm" });
|
const blob = new Blob(recordedBlobs, { type: "video/webm" });
|
||||||
const url = window.URL.createObjectURL(blob);
|
const url = window.URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
|
|||||||
146
popout.html
Normal file
146
popout.html
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
<!-- <script src="//console.re/connector.js" data-channel="obsninjadev" type="text/javascript" id="consolerescript"></script>-->
|
||||||
|
<link rel="stylesheet" href="./lineawesome/css/line-awesome.min.css">
|
||||||
|
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/adapter-latest.js"></script>
|
||||||
|
<script type="text/javascript" crossorigin="anonymous" src="./thirdparty/qrcode.min.js"></script>
|
||||||
|
<script type="text/javascript" src="./thirdparty/jquery.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="./main.css?ver=22" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="chatModule" >
|
||||||
|
<div id="chatBody">
|
||||||
|
<div class="inMessage" data-translate='welcome-to-obs-ninja-chat'>
|
||||||
|
Welcome to OBS.Ninja! You can send text messages directly to connected peers from here.
|
||||||
|
</div>
|
||||||
|
<div class="outMessage" data-translate='names-and-labels-coming-soon'>
|
||||||
|
Names identifying connected peers will be a feature in an upcoming release.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input id="chatInput" placeholder="Enter chat message to send here" onkeypress="EnterButtonChat(event)" />
|
||||||
|
<button style="width:60px;background-color:#EEE;" onclick="sendChatMessage()" data-translate='send-chat'>Send</button>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
/// If you have a routing system setup, you could have just one global listener for all iframes instead.
|
||||||
|
var chatUpdateTimeout = null;
|
||||||
|
var messageList = [];
|
||||||
|
|
||||||
|
(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 (urlParams.has("id")){
|
||||||
|
var bid = urlParams.get("id");
|
||||||
|
}
|
||||||
|
var bc = new BroadcastChannel(bid);
|
||||||
|
bc.onmessage = function (e) {
|
||||||
|
//if (e.source != iframe.contentWindow){return} // reject messages send from other iframes
|
||||||
|
console.log(e);
|
||||||
|
if ("data" in e){
|
||||||
|
if ("msg" in e.data){
|
||||||
|
messageList.push(e.data);
|
||||||
|
messageList = messageList.slice(-100);
|
||||||
|
updateMessages();
|
||||||
|
} else if ("messageList" in e.data){
|
||||||
|
messageList = e.data.messageList;
|
||||||
|
updateMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function timeSince(date) {
|
||||||
|
|
||||||
|
var seconds = Math.floor((new Date() - date) / 1000);
|
||||||
|
|
||||||
|
var interval = seconds / 31536000;
|
||||||
|
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " years";
|
||||||
|
}
|
||||||
|
interval = seconds / 2592000;
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " months";
|
||||||
|
}
|
||||||
|
interval = seconds / 86400;
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " days";
|
||||||
|
}
|
||||||
|
interval = seconds / 3600;
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " hours";
|
||||||
|
}
|
||||||
|
interval = seconds / 60;
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " minutes";
|
||||||
|
}
|
||||||
|
return "Seconds ago";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function toggleQualityDirector(bitrate, UUID, ele = null){ // ele is specific to the button in the director's room
|
||||||
|
var eles = ele.parentNode.childNodes;
|
||||||
|
for (i in eles){
|
||||||
|
eles[i].className="";
|
||||||
|
}
|
||||||
|
ele.className="pressed";
|
||||||
|
session.requestRateLimit(bitrate, UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateMessages(){
|
||||||
|
document.getElementById("chatBody").innerHTML = "";
|
||||||
|
for (i in messageList){
|
||||||
|
|
||||||
|
var time = timeSince(messageList[i].time);
|
||||||
|
var msg = document.createElement("div");
|
||||||
|
////// KEEP THIS IN /////////
|
||||||
|
console.log(messageList[i].msg); // Display Recieved messages for View-Only clients.
|
||||||
|
/////////////////////////////
|
||||||
|
if (messageList[i].type == "sent"){
|
||||||
|
msg.innerHTML = messageList[i].msg + " <i><small> <small>- "+time+"</small></small></i>";
|
||||||
|
msg.classList.add("outMessage");
|
||||||
|
} else if (messageList[i].type == "recv"){
|
||||||
|
var label = "";
|
||||||
|
if (messageList[i].label){
|
||||||
|
label = messageList[i].label;
|
||||||
|
}
|
||||||
|
msg.innerHTML = label+messageList[i].msg + " <i><small> <small>- "+time+"</small></small></i>";
|
||||||
|
msg.classList.add("inMessage");
|
||||||
|
} else if (messageList[i].type == "alert"){
|
||||||
|
msg.innerHTML = messageList[i].msg + " <i><small> <small>- "+time+"</small></small></i>";
|
||||||
|
msg.classList.add("inMessage");
|
||||||
|
} else {
|
||||||
|
msg.innerHTML = messageList[i].msg + " <i><small> <small>- "+time+"</small></small></i>";
|
||||||
|
msg.classList.add("inMessage");
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("chatBody").appendChild(msg);
|
||||||
|
}
|
||||||
|
if (chatUpdateTimeout){
|
||||||
|
clearInterval(chatUpdateTimeout);
|
||||||
|
}
|
||||||
|
document.getElementById("chatBody").scrollTop = document.getElementById("chatBody").scrollHeight;
|
||||||
|
chatUpdateTimeout = setTimeout(function(){updateMessages()},60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -85,13 +85,13 @@ function loadIframe(){ // this is pretty important if you want to avoid camera p
|
|||||||
iframeContainer.appendChild(iframe);
|
iframeContainer.appendChild(iframe);
|
||||||
document.getElementById("container").appendChild(iframeContainer);
|
document.getElementById("container").appendChild(iframeContainer);
|
||||||
|
|
||||||
|
setInterval(function(){iframe.contentWindow.postMessage({"getStats":true}, '*');},5000);
|
||||||
|
|
||||||
|
|
||||||
|
var iframe2 = document.createElement("iframe");
|
||||||
var iframe = document.createElement("iframe");
|
|
||||||
var iframeContainer = document.createElement("span");
|
var iframeContainer = document.createElement("span");
|
||||||
|
|
||||||
iframe.allow="autoplay";
|
iframe2.allow="autoplay";
|
||||||
var srcString = "./?view="+streamID+"&cleanoutput&privacy&noaudio";
|
var srcString = "./?view="+streamID+"&cleanoutput&privacy&noaudio";
|
||||||
|
|
||||||
if (urlParams.has('turn')){
|
if (urlParams.has('turn')){
|
||||||
@@ -102,9 +102,9 @@ function loadIframe(){ // this is pretty important if you want to avoid camera p
|
|||||||
srcString = srcString+"&buffer="+urlParams.get("buffer");
|
srcString = srcString+"&buffer="+urlParams.get("buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe.src = srcString;
|
iframe2.src = srcString;
|
||||||
|
|
||||||
iframeContainer.appendChild(iframe);
|
iframeContainer.appendChild(iframe2);
|
||||||
document.getElementById("container").appendChild(iframeContainer);
|
document.getElementById("container").appendChild(iframeContainer);
|
||||||
|
|
||||||
var button = document.createElement("br");
|
var button = document.createElement("br");
|
||||||
@@ -112,12 +112,12 @@ function loadIframe(){ // this is pretty important if you want to avoid camera p
|
|||||||
|
|
||||||
var button = document.createElement("button");
|
var button = document.createElement("button");
|
||||||
button.innerHTML = "Disconnect";
|
button.innerHTML = "Disconnect";
|
||||||
button.onclick = function(){iframe.contentWindow.postMessage({"close":true}, '*');}
|
button.onclick = function(){iframe2.contentWindow.postMessage({"close":true}, '*');}
|
||||||
document.getElementById("container").appendChild(button);
|
document.getElementById("container").appendChild(button);
|
||||||
|
|
||||||
var button = document.createElement("button");
|
var button = document.createElement("button");
|
||||||
button.innerHTML = "Low Bitrate";
|
button.innerHTML = "Low Bitrate";
|
||||||
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":30}, '*');}
|
button.onclick = function(){iframe2.contentWindow.postMessage({"bitrate":100}, '*');}
|
||||||
document.getElementById("container").appendChild(button);
|
document.getElementById("container").appendChild(button);
|
||||||
|
|
||||||
|
|
||||||
@@ -125,15 +125,15 @@ function loadIframe(){ // this is pretty important if you want to avoid camera p
|
|||||||
|
|
||||||
var button = document.createElement("button");
|
var button = document.createElement("button");
|
||||||
button.innerHTML = "High Bitrate";
|
button.innerHTML = "High Bitrate";
|
||||||
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":6000}, '*');}
|
button.onclick = function(){iframe2.contentWindow.postMessage({"bitrate":6000}, '*');}
|
||||||
document.getElementById("container").appendChild(button);
|
document.getElementById("container").appendChild(button);
|
||||||
|
|
||||||
var button = document.createElement("button");
|
var button = document.createElement("button");
|
||||||
button.innerHTML = "Default Bitrate";
|
button.innerHTML = "Default Bitrate";
|
||||||
button.onclick = function(){iframe.contentWindow.postMessage({"bitrate":-1}, '*');}
|
button.onclick = function(){iframe2.contentWindow.postMessage({"bitrate":-1}, '*');}
|
||||||
document.getElementById("container").appendChild(button);
|
document.getElementById("container").appendChild(button);
|
||||||
|
|
||||||
setInterval(function(){iframe.contentWindow.postMessage({"getStats":true}, '*');},1000);
|
setInterval(function(){iframe2.contentWindow.postMessage({"getStats":true}, '*');},1000);
|
||||||
|
|
||||||
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
||||||
var eventer = window[eventMethod];
|
var eventer = window[eventMethod];
|
||||||
@@ -143,13 +143,20 @@ function loadIframe(){ // this is pretty important if you want to avoid camera p
|
|||||||
|
|
||||||
if ("stats" in e.data){
|
if ("stats" in e.data){
|
||||||
var out = "";
|
var out = "";
|
||||||
|
console.log( e.data.stats);
|
||||||
for (var streamID in e.data.stats.inbound_stats){
|
for (var streamID in e.data.stats.inbound_stats){
|
||||||
out += printValues(e.data.stats.inbound_stats[streamID]);
|
out += printValues(e.data.stats.inbound_stats[streamID]);
|
||||||
}
|
}
|
||||||
if (out.split("Bitrate_in_kbps").length>1){
|
if (out.split("Bitrate_in_kbps").length>1){
|
||||||
document.getElementById("statsdiv").innerHTML = "<b>Bitrate_in_kbps</b>"+out.split("Bitrate_in_kbps")[1];
|
document.getElementById("statsdiv").innerHTML = "<b>Bitrate_in_kbps</b>"+out.split("Bitrate_in_kbps")[1];
|
||||||
}
|
}
|
||||||
|
for (var i in e.data.stats.outbound_stats){
|
||||||
|
if ("quality_Limitation_Reason" in e.data.stats.outbound_stats[i]){
|
||||||
|
document.getElementById("statsdivOut").innerHTML = "<b>Quality Limitation Reasons:</b> "+e.data.stats.outbound_stats[i].quality_Limitation_Reason+"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -176,17 +183,19 @@ function printValues( obj) {
|
|||||||
<body onload="loadIframe();">
|
<body onload="loadIframe();">
|
||||||
<div id="container">
|
<div id="container">
|
||||||
</div>
|
</div>
|
||||||
<div style="width:48%;padding:0;margin:0;border:0;display:inline-block;">
|
<div style="width:48%;padding:0;margin:0 10px;border:0;display:inline-block;">
|
||||||
<h3>OBS.Ninja Speed Test - prototype version</h3>
|
<h3>OBS.Ninja Speed Test - prototype version</h3>
|
||||||
(Tests connection to TURN server and back)<br /><br />
|
(Tests connection to TURN server and back)<br /><br />
|
||||||
<li>1.Select your camera.</li>
|
<li>1.Select your camera.</li>
|
||||||
<li>2.Hit start</li>
|
<li>2.Hit start</li>
|
||||||
<li>3.Wait for the video to load side-by-side. *If it does not auto-load within 20s, refresh and try again.*</li>
|
<li>3.Wait for the video to load side-by-side. *If it does not auto-load within 20s, refresh and try again.*</li>
|
||||||
<li>4.Stats will load on the right-hand side of the page here. (or press CTRL + LeftClick on the new video to open stats that way)</li>
|
<li>4.Stats will load on the right-hand side of the page here. (or press CTRL + LeftClick on the new video to open stats)</li>
|
||||||
<li>5.Bitrate_in_kbps, Buffer_Delay_in_ms, and packetLoss_percentage are important connection quality metrics</li>
|
<li>5.Bitrate_in_kbps, Buffer_Delay_in_ms, and packetLoss_percentage are important connection quality metrics</li>
|
||||||
<li>6.Increase the video bitrate by pressing <i>High Bitrate</i>; it should approach 6000-kbps if the network allows.</li>
|
<li>6.Increase the video bitrate by pressing <i>High Bitrate</i>; it should approach 6000-kbps if the network allows.</li>
|
||||||
</div>
|
</div>
|
||||||
<div id="statsdiv" style="width:48%;padding:0;margin:0;border:0;display:inline-block;">
|
<div id="statsdiv" style="width:48%;padding:0;margin:0;border:0;display:inline-block;">
|
||||||
</div>
|
</div>
|
||||||
|
<div id="statsdivOut" style="font-size:200%;width:48%;padding:20px;margin:0;border:0;display:inline-block;">
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user