diff --git a/index.html b/index.html index 4a23642..77614c4 100644 --- a/index.html +++ b/index.html @@ -90,9 +90,9 @@ - + - +
- - - + + - + + - @@ -368,12 +336,15 @@ - - - - + + + + +
@@ -452,6 +423,38 @@ document.querySelector("#changeText1a").value = localStorage.getItem('changeText document.querySelector("#changeText2").value = localStorage.getItem('changeText2') || ""; document.querySelector("#changeText3").value = localStorage.getItem('changeText3') || ""; +const scalabilityModes = [ + 'L1T1', + 'L1T2', + 'L1T3', + 'L2T1', + 'L2T2', + 'L2T3', + 'L3T1', + 'L3T2', + 'L3T3', + 'L2T1h', + 'L2T2h', + 'L2T3h', + 'S2T1', + 'S2T2', + 'S2T3', + 'S2T1h', + 'S2T2h', + 'S2T3h', + 'S3T1', + 'S3T2', + 'S3T3', + 'S3T1h', + 'S3T2h', + 'S3T3h', + 'L2T2_KEY', + 'L2T3_KEY', + 'L3T2_KEY', + 'L3T3_KEY' +]; + + function gohere1(){ if (document.getElementById('changeText1').value){ localStorage.setItem('changeText1', document.getElementById('changeText1').value); @@ -459,6 +462,7 @@ function gohere1(){ localStorage.setItem('bitrateGroupFlag', document.getElementById('bitrateGroupFlag').value); localStorage.setItem('codecGroupFlag', document.getElementById('codecGroupFlag').value); + localStorage.setItem('svcGroupFlag', document.getElementById('svcGroupFlag').value); localStorage.setItem('whipoutaudiobitrate', document.getElementById('whipoutaudiobitrate').value); localStorage.setItem('vbrcbr', document.getElementById('vbrcbr').value); @@ -486,15 +490,59 @@ function gohere1(){ if (document.getElementById('codecGroupFlag').value!=="default"){ codec = "&whipoutcodec="+document.getElementById('codecGroupFlag').value; } + var svc = ""; + if (document.getElementById('svcGroupFlag').value!=="0"){ + svc = "&svc="+document.getElementById('svcGroupFlag').value; + } if (document.getElementById('changeText1a').value){ - window.location = domain + "?push&whippush=" + encodeURIComponent(document.getElementById('changeText1').value) + "&whippushtoken=" + document.getElementById('changeText1a').value + codec + bitrate+whipoutaudiobitrate+vbrcbr+autogain+stereo+denoise; + window.location = domain + "?push&whippush=" + encodeURIComponent(document.getElementById('changeText1').value) + "&whippushtoken=" + document.getElementById('changeText1a').value + codec + bitrate+whipoutaudiobitrate+vbrcbr+autogain+stereo+denoise+svc; } else { - window.location = domain + "?push&whippush=" + encodeURIComponent(document.getElementById('changeText1').value) + codec + bitrate+whipoutaudiobitrate+vbrcbr+autogain+stereo+denoise; + window.location = domain + "?push&whippush=" + encodeURIComponent(document.getElementById('changeText1').value) + codec + bitrate+whipoutaudiobitrate+vbrcbr+autogain+stereo+denoise+svc;; } } } +function checkStereo(){ + if (parseInt(document.getElementById('autogain').value) || parseInt(document.getElementById('denoise').value)){ + document.getElementById('stereo').disabled = true; + document.getElementById('stereo').title = "Noise reduction and auto-gain will prevent stereo audio from working"; + } else { + document.getElementById('stereo').disabled = false; + delete document.getElementById('stereo').disabled; + document.getElementById('stereo').title = "Enable stereo 2.0 audio if available. Must be enabled on the viewer's end as well."; + } +} + +function updateSVC(){ + + var codecName = document.getElementById('codecGroupFlag').value; + var select = document.getElementById("svcGroupFlag"); + var selectedValue = "0"; + if (select.options && select.selectedIndex && select.options[select.selectedIndex]){ + selectedValue = select.options[select.selectedIndex].value; + } + select.innerHTML = ""; + + var option = document.createElement("option"); + option.text = "🎦 SVC Off"; + option.value = "0"; + select.add(option); + select.selectedIndex = 0; + + if (svcLUT[codecName]){ + svcLUT[codecName].forEach(opt=>{ + option = document.createElement("option"); + option.text = "🎦 "+opt; + option.value = opt; + select.add(option); + if (opt == selectedValue){ + select.value = opt; + } + }); + } +} + function gohere1t(){ if (document.getElementById('changeText1t').value){ localStorage.setItem('changeText1t', document.getElementById('changeText1t').value); @@ -527,6 +575,7 @@ function resetHistory(){ document.querySelector("#changeText2").value = ""; document.querySelector("#changeText3").value = ""; document.querySelector("#changeText1t").value = ""; + checkStereo(); } (function (w) { @@ -555,12 +604,86 @@ function enterPressed(event, callback){ } } +checkStereo(); 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. } +var Firefox = navigator.userAgent.indexOf("Firefox")>=0; +if (Firefox){ + Firefox = parseInt(navigator.userAgent.split("irefox/").pop()) || true; +} +var capabilityType = Firefox ? "transmission" : "webrtc"; +var codecs = RTCRtpSender.getCapabilities('video').codecs; +var svcLUT = {}; +var svcDefault = {}; + +function getCommonValues(obj) { + if (obj.default){ + delete obj.default; + } + let commonValues = []; + let firstKey = Object.keys(obj)[0]; + let firstArray = obj[firstKey]; + for (let i = 0; i < firstArray.length; i++) { + let currentValue = firstArray[i]; + let isCommonValue = true; + for (let key in obj) { + if (!obj[key].includes(currentValue)) { + isCommonValue = false; + break; + } + } + if (isCommonValue) { + commonValues.push(currentValue); + } + } + return commonValues +} + +async function processCodecs(){ + await codecs.forEach(async codec => { + var codecName = codec.mimeType.replace("video/","").toLowerCase(); + if (['video/red', 'video/ulpfec', 'video/rtx'].includes(codec.mimeType)) { + return; + } else if (svcLUT[codecName]){ // already done + return; + } + + svcLUT[codecName] = []; + var capabilityPromises = []; + for (const mode of scalabilityModes) { + capabilityPromises.push(navigator.mediaCapabilities.encodingInfo({ + type: capabilityType, + video: { + contentType: codec.mimeType, + width: 1920, + height: 1080, + bitrate: 10000, + framerate: 29.97, + scalabilityMode: mode + } + })); + } + var capabilityResults = await Promise.all(capabilityPromises); + for (var i = 0;i