问题描述
假设有一个视频被渲染成由许多块/片段组成的碎片 mp4。问题是:在 init 加载到 MediaSource 缓冲区后,有没有办法播放随机片段?
对事物规格的小规模研究对问题的了解甚少。片段似乎有一种硬编码的订单 ID。将它包含在文件中是一个相当合理的想法,以防在流式传输内容时出现不可靠的连接和异步获取,但是有没有办法使用 JavaScript 解析块并更改其 ID?
下面的代码只是根据用户的时间播放分成 12 个片段的 2 分钟视频,并且应该能够从任何块开始(不仅仅是第一个)然后重复。
let mediaSource = new MediaSource
document.getElementById('video').src = URL.createObjectURL(mediaSource)
mediaSource.addEventListener('sourceopen',() => {
let buffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E,mp4a.40.2"')
let loadToBuffer = url => {
let xhr = new XMLHttpRequest
xhr.responseType = 'arraybuffer'
xhr.open('GET',url,true)
xhr.addEventListener('loadend',() => buffer.appendBuffer(new Uint8Array(xhr.response)))
xhr.send()
}
loadToBuffer('video/init.mp4')
setInterval(() => loadToBuffer('video/video' + (Math.floor(new Date().getTime() / 1000 / 10) % 12) + '.m4s'),10 * 1000)
})
解决方法
当您在 sourceBuffer
中加载片段时,这些片段包含演示时间戳 (PTS
),这会将它们按正确的播放顺序放入缓冲区。
您可以修改片段本身,为此您必须解析原子并更改 PTS
(可能还有其他)值,或者更改视频元素 currentTime
属性,以便您可以播放视频已正确缓冲。
您可以检查视频元素对象的 buffered
属性以检查已加载的时间范围。