You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.3 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function () {
const mseQueue = []
let mseSourceBuffer
let mseStreamingStarted = false
function startPlay (videoEl, url) {
const mse = new MediaSource()
videoEl.src = window.URL.createObjectURL(mse)
mse.addEventListener('sourceopen', function () {
const ws = new WebSocket(url)
ws.binaryType = 'arraybuffer'
ws.onopen = function (event) {
console.log('Connect to ws')
}
ws.onmessage = function (event) {
const data = new Uint8Array(event.data)
if (data[0] === 9) {
let mimeCodec
const decodedArr = data.slice(1)
if (window.TextDecoder) {
mimeCodec = new TextDecoder('utf-8').decode(decodedArr)
} else {
mimeCodec = Utf8ArrayToStr(decodedArr)
}
mseSourceBuffer = mse.addSourceBuffer('video/mp4; codecs="' + mimeCodec + '"')
mseSourceBuffer.mode = 'segments'
mseSourceBuffer.addEventListener('updateend', pushPacket)
} else {
readPacket(event.data)
}
}
}, false)
}
function pushPacket () {
const videoEl = document.querySelector('#mse-video')
let packet
if (!mseSourceBuffer.updating) {
if (mseQueue.length > 0) {
packet = mseQueue.shift()
mseSourceBuffer.appendBuffer(packet)
} else {
mseStreamingStarted = false
}
}
if (videoEl.buffered.length > 0) {
if (typeof document.hidden !== 'undefined' && document.hidden) {
// no sound, browser paused video without sound in background
videoEl.currentTime = videoEl.buffered.end((videoEl.buffered.length - 1)) - 0.5
}
}
}
function readPacket (packet) {
if (!mseStreamingStarted) {
mseSourceBuffer.appendBuffer(packet)
mseStreamingStarted = true
return
}
mseQueue.push(packet)
if (!mseSourceBuffer.updating) {
pushPacket()
}
}
const videoEl = document.querySelector('#mse-video')
const mseUrl = document.querySelector('#mse-url').value
// fix stalled video in safari
videoEl.addEventListener('pause', () => {
if (videoEl.currentTime > videoEl.buffered.end(videoEl.buffered.length - 1)) {
videoEl.currentTime = videoEl.buffered.end(videoEl.buffered.length - 1) - 0.1
videoEl.play()
}
})
startPlay(videoEl, mseUrl)
})