Fixes
This commit is contained in:
parent
079fd61390
commit
e929b5af1e
49
blarf.js
49
blarf.js
@ -18,6 +18,8 @@
|
|||||||
var AudCtx
|
var AudCtx
|
||||||
var AudScript, AudWorklet
|
var AudScript, AudWorklet
|
||||||
var AudHz
|
var AudHz
|
||||||
|
var AudDejitter
|
||||||
|
var AudMuted = true
|
||||||
|
|
||||||
function create_audio(hz, channels) {
|
function create_audio(hz, channels) {
|
||||||
if(AudCtx) {
|
if(AudCtx) {
|
||||||
@ -28,6 +30,9 @@
|
|||||||
|
|
||||||
AudHz = hz
|
AudHz = hz
|
||||||
|
|
||||||
|
// Fill up buffer for 1 second before playing
|
||||||
|
AudDejitter = AudHz
|
||||||
|
|
||||||
var DebugSine = 0
|
var DebugSine = 0
|
||||||
|
|
||||||
AudCtx = new AudioContext({sampleRate: hz})
|
AudCtx = new AudioContext({sampleRate: hz})
|
||||||
@ -52,8 +57,10 @@
|
|||||||
while(AudioQueue.length && leftToWrite) {
|
while(AudioQueue.length && leftToWrite) {
|
||||||
var amount = Math.min(leftToWrite, AudioQueue[0].left.length)
|
var amount = Math.min(leftToWrite, AudioQueue[0].left.length)
|
||||||
|
|
||||||
|
if(!AudMuted) {
|
||||||
outL.set(AudioQueue[0].left.subarray(0, amount), offset)
|
outL.set(AudioQueue[0].left.subarray(0, amount), offset)
|
||||||
if(outR) outR.set(AudioQueue[0].right.subarray(0, amount), offset)
|
if(outR) outR.set(AudioQueue[0].right.subarray(0, amount), offset)
|
||||||
|
}
|
||||||
|
|
||||||
AudioQueue[0].left = AudioQueue[0].left.subarray(amount)
|
AudioQueue[0].left = AudioQueue[0].left.subarray(amount)
|
||||||
if(outR) AudioQueue[0].right = AudioQueue[0].right.subarray(amount)
|
if(outR) AudioQueue[0].right = AudioQueue[0].right.subarray(amount)
|
||||||
@ -77,11 +84,16 @@
|
|||||||
interruptcontrols()
|
interruptcontrols()
|
||||||
|
|
||||||
function togglemute() {
|
function togglemute() {
|
||||||
if(AudCtx)
|
if(!AudCtx) {
|
||||||
if(document.querySelector(".MKVSpeakerOn").style.display == "none") {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AudCtx.resume()
|
AudCtx.resume()
|
||||||
} else {
|
|
||||||
AudCtx.suspend()
|
AudMuted = !AudMuted
|
||||||
|
|
||||||
|
if(AudWorklet) {
|
||||||
|
AudWorklet.port.postMessage(AudMuted)
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelectorAll(".MKVSpeaker *").forEach(function(el) { el.style.display = el.style.display == "none" ? "" : "none" })
|
document.querySelectorAll(".MKVSpeaker *").forEach(function(el) { el.style.display = el.style.display == "none" ? "" : "none" })
|
||||||
@ -127,23 +139,11 @@
|
|||||||
} else if(e.data.samples) {
|
} else if(e.data.samples) {
|
||||||
AudioQueue.push({left: e.data.left, right: e.data.right || e.data.left})
|
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
|
// Prevent the audio queue filling up and causing ever-increasing AV desync
|
||||||
// In this case the audio queue will fill up and cause ever-increasing AV desync
|
if(AudCtx.state != "running") {
|
||||||
|
|
||||||
if(AudCtx && AudCtx.state != "running") {
|
|
||||||
var durationInAudioQueue = AudioQueue.length ? AudioQueue.reduce((acc, el) => acc + el.left.length, 0) : 0
|
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)
|
var durationToRemove = Math.max(durationInAudioQueue - (VideoQueue.length ? (VideoQueue[VideoQueue.length - 1].t - VideoQueue[0].t) : 0) * AudHz / 1000, 0)
|
||||||
//
|
|
||||||
crop_audio_queue(durationToRemove)
|
crop_audio_queue(durationToRemove)
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,10 +165,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvus.onclick = function() {
|
|
||||||
if(AudCtx) AudCtx.resume()
|
|
||||||
}
|
|
||||||
|
|
||||||
var VideoBufferingOffset = 0
|
var VideoBufferingOffset = 0
|
||||||
|
|
||||||
function toHex(buffer) {
|
function toHex(buffer) {
|
||||||
@ -337,7 +333,7 @@
|
|||||||
this.currentClusterTime = EBMLParser.vi_to_i(data)
|
this.currentClusterTime = EBMLParser.vi_to_i(data)
|
||||||
|
|
||||||
if(!RenderStartTime) {
|
if(!RenderStartTime) {
|
||||||
RenderStartTime = document.timeline.currentTime + 1000
|
RenderStartTime = document.timeline.currentTime + 600
|
||||||
}
|
}
|
||||||
if(!VideoStartTime) {
|
if(!VideoStartTime) {
|
||||||
VideoStartTime = this.currentClusterTime
|
VideoStartTime = this.currentClusterTime
|
||||||
@ -444,11 +440,16 @@
|
|||||||
function render(timestamp) {
|
function render(timestamp) {
|
||||||
document.querySelector(".MKVControls").style.opacity = Math.max(0, Math.min(1, 5 - (timestamp - LastControlsInterrupt) / 1000))
|
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)) {
|
while(RenderStartTime && VideoQueue.length && VideoQueue[0].t + VideoBufferingOffset <= (timestamp - RenderStartTime)) {
|
||||||
CanvCtx.putImageData(VideoQueue[0].imgData, 0, 0)
|
nextImg = VideoQueue[0].imgData
|
||||||
VideoQueue.shift()
|
VideoQueue.shift()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(nextImg) {
|
||||||
|
CanvCtx.putImageData(nextImg, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
requestAnimationFrame(render)
|
requestAnimationFrame(render)
|
||||||
}
|
}
|
||||||
requestAnimationFrame(render)
|
requestAnimationFrame(render)
|
||||||
|
10
index.html
10
index.html
@ -122,19 +122,13 @@
|
|||||||
<script>
|
<script>
|
||||||
document.querySelector("#BLARF").setAttribute("data-target", STREAM_SOURCE_WS)
|
document.querySelector("#BLARF").setAttribute("data-target", STREAM_SOURCE_WS)
|
||||||
|
|
||||||
function randomHex(size) {
|
|
||||||
return [...self.crypto.getRandomValues(new Uint8Array(size))].map(b=>b.toString(16).padStart(2, "0")).join("")
|
|
||||||
}
|
|
||||||
const un = 'lol' + randomHex(16)
|
|
||||||
|
|
||||||
if(ENABLE_CHAT) {
|
if(ENABLE_CHAT) {
|
||||||
converse.initialize({
|
converse.initialize({
|
||||||
view_mode: 'embedded',
|
view_mode: 'embedded',
|
||||||
websocket_url: CHAT_HOST_WS_URL,
|
websocket_url: CHAT_HOST_WS_URL,
|
||||||
login: 'anonymous',
|
authentication: 'anonymous',
|
||||||
jid: un + '@' + CHAT_HOST,
|
jid: CHAT_HOST,
|
||||||
auto_login: true,
|
auto_login: true,
|
||||||
password: 'lol',
|
|
||||||
auto_join_rooms: [CHAT_MUC],
|
auto_join_rooms: [CHAT_MUC],
|
||||||
show_message_avatar: false,
|
show_message_avatar: false,
|
||||||
show_controlbox_by_default: false,
|
show_controlbox_by_default: false,
|
||||||
|
@ -14,12 +14,18 @@ class RawPCMWorklet extends AudioWorkletProcessor {
|
|||||||
this.ringR = new Float32Array(65536)
|
this.ringR = new Float32Array(65536)
|
||||||
this.ringWrite = 0
|
this.ringWrite = 0
|
||||||
this.ringRead = 0
|
this.ringRead = 0
|
||||||
|
this.mute = true
|
||||||
|
|
||||||
for(var z = 0; z < 65536; z++) {
|
for(var z = 0; z < 65536; z++) {
|
||||||
this.ringL[z] = Math.sin(z / 128 * 2 * Math.PI) * 0.3
|
this.ringL[z] = Math.sin(z / 128 * 2 * Math.PI) * 0.3
|
||||||
}
|
}
|
||||||
|
|
||||||
this.port.onmessage = (event) => {
|
this.port.onmessage = (event) => {
|
||||||
|
if(event.data === true || event.data === false) {
|
||||||
|
this.mute = event.data
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var newaudioframes = event.data
|
var newaudioframes = event.data
|
||||||
|
|
||||||
var newlen = newaudioframes.left.length
|
var newlen = newaudioframes.left.length
|
||||||
@ -60,6 +66,7 @@ class RawPCMWorklet extends AudioWorkletProcessor {
|
|||||||
|
|
||||||
var available = Math.min(left.length, Math.max(0, this.ringWrite - this.ringRead))
|
var available = Math.min(left.length, Math.max(0, this.ringWrite - this.ringRead))
|
||||||
|
|
||||||
|
if(this.mute === false) {
|
||||||
if(this.ringRead % this.ringL.length + available <= this.ringL.length) {
|
if(this.ringRead % this.ringL.length + available <= this.ringL.length) {
|
||||||
left.set(this.ringL.slice(this.ringRead % this.ringL.length, this.ringRead % this.ringL.length + available))
|
left.set(this.ringL.slice(this.ringRead % this.ringL.length, this.ringRead % this.ringL.length + available))
|
||||||
right.set(this.ringR.slice(this.ringRead % this.ringL.length, this.ringRead % this.ringL.length + available))
|
right.set(this.ringR.slice(this.ringRead % this.ringL.length, this.ringRead % this.ringL.length + available))
|
||||||
@ -72,6 +79,7 @@ class RawPCMWorklet extends AudioWorkletProcessor {
|
|||||||
left.set(this.ringL.slice(0, available - boundary), boundary)
|
left.set(this.ringL.slice(0, available - boundary), boundary)
|
||||||
right.set(this.ringR.slice(0, available - boundary), boundary)
|
right.set(this.ringR.slice(0, available - boundary), boundary)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.ringRead += left.length
|
this.ringRead += left.length
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user