diff --git a/blarf.js b/blarf.js index 6d805cb..23e6e1d 100644 --- a/blarf.js +++ b/blarf.js @@ -18,6 +18,8 @@ var AudCtx var AudScript, AudWorklet var AudHz + var AudDejitter + var AudMuted = true function create_audio(hz, channels) { if(AudCtx) { @@ -28,6 +30,9 @@ AudHz = hz + // Fill up buffer for 1 second before playing + AudDejitter = AudHz + var DebugSine = 0 AudCtx = new AudioContext({sampleRate: hz}) @@ -52,8 +57,10 @@ while(AudioQueue.length && leftToWrite) { var amount = Math.min(leftToWrite, AudioQueue[0].left.length) - outL.set(AudioQueue[0].left.subarray(0, amount), offset) - if(outR) outR.set(AudioQueue[0].right.subarray(0, amount), offset) + if(!AudMuted) { + outL.set(AudioQueue[0].left.subarray(0, amount), offset) + if(outR) outR.set(AudioQueue[0].right.subarray(0, amount), offset) + } AudioQueue[0].left = AudioQueue[0].left.subarray(amount) if(outR) AudioQueue[0].right = AudioQueue[0].right.subarray(amount) @@ -77,11 +84,16 @@ interruptcontrols() function togglemute() { - if(AudCtx) - if(document.querySelector(".MKVSpeakerOn").style.display == "none") { - AudCtx.resume() - } else { - AudCtx.suspend() + if(!AudCtx) { + return; + } + + AudCtx.resume() + + AudMuted = !AudMuted + + if(AudWorklet) { + AudWorklet.port.postMessage(AudMuted) } document.querySelectorAll(".MKVSpeaker *").forEach(function(el) { el.style.display = el.style.display == "none" ? "" : "none" }) @@ -127,23 +139,11 @@ } else if(e.data.samples) { AudioQueue.push({left: e.data.left, right: e.data.right || e.data.left}) - // Audio may be loaded but it might not play because of autoplay permissions - // In this case the audio queue will fill up and cause ever-increasing AV desync - - if(AudCtx && AudCtx.state != "running") { + // Prevent the audio queue filling up and causing ever-increasing AV desync + if(AudCtx.state != "running") { var durationInAudioQueue = AudioQueue.length ? AudioQueue.reduce((acc, el) => acc + el.left.length, 0) : 0 - - //if(AudWorklet) { - // // With audio worklets, crop to 1024 samples max to prevent ring buffer overflow - // - // crop_audio_queue(Math.max(durationInAudioQueue - 1024, 0)) - //} else { - // // Without audio worklets we use a FIFO and can crop to the duration in the video queue - // - var durationToRemove = Math.max(durationInAudioQueue - (VideoQueue.length ? (VideoQueue[VideoQueue.length - 1].t - VideoQueue[0].t) : 0) * AudHz / 1000, 0) - // - crop_audio_queue(durationToRemove) - //} + var durationToRemove = Math.max(durationInAudioQueue - (VideoQueue.length ? (VideoQueue[VideoQueue.length - 1].t - VideoQueue[0].t) : 0) * AudHz / 1000, 0) + crop_audio_queue(durationToRemove) } } @@ -165,10 +165,6 @@ } } - Canvus.onclick = function() { - if(AudCtx) AudCtx.resume() - } - var VideoBufferingOffset = 0 function toHex(buffer) { @@ -337,7 +333,7 @@ this.currentClusterTime = EBMLParser.vi_to_i(data) if(!RenderStartTime) { - RenderStartTime = document.timeline.currentTime + 1000 + RenderStartTime = document.timeline.currentTime + 600 } if(!VideoStartTime) { VideoStartTime = this.currentClusterTime @@ -444,11 +440,16 @@ function render(timestamp) { document.querySelector(".MKVControls").style.opacity = Math.max(0, Math.min(1, 5 - (timestamp - LastControlsInterrupt) / 1000)) + var nextImg = null while(RenderStartTime && VideoQueue.length && VideoQueue[0].t + VideoBufferingOffset <= (timestamp - RenderStartTime)) { - CanvCtx.putImageData(VideoQueue[0].imgData, 0, 0) + nextImg = VideoQueue[0].imgData VideoQueue.shift() } + if(nextImg) { + CanvCtx.putImageData(nextImg, 0, 0) + } + requestAnimationFrame(render) } requestAnimationFrame(render) diff --git a/index.html b/index.html index 63332fa..0ed3813 100644 --- a/index.html +++ b/index.html @@ -122,19 +122,13 @@