Chrome:播放正在通过FETCH/XHR下载的视频

我想要实现的是让Chrome将视频文件加载为数据(通过Fetch API、XHR等等),并在下载过程中使用<video>播放视频文件,而无需对同一URL发出两个单独的请求,也无需等待文件完全下载。

从FETCH API(response.body)获取ReadableStream很容易,但是我找不到将其提供给video元素的方法。我想我需要一个blobURL,它可以使用MediaSource对象创建。但是,在Chrome中没有实现SourceBuffer#appendStream方法,它听起来正是所需的,因此我不能将流直接连接到MediaSource对象。

我可以按块读取流,从中创建Uint8Array,并使用SourceBuffer#appendBuffer,但这意味着回放不会立即开始,除非块大小非常小。而且感觉像是手动做一些所有这些API都应该开箱即用就能做的事情。如果没有其他解决方案,我走这条路,我应该期待什么警告?

是否有其他方法可以为ReadableStream创建BLOB URL?或者有没有办法让fetch<video>共享一个请求?新的API太多了,我很容易错过一些东西。


解决方案

经过几个小时的试验,找到了一个半工作的解决方案:

const video = document.getElementById('audio');

const mediaSource = new MediaSource();

video.src = window.URL.createObjectURL(mediaSource);

mediaSource.addEventListener('sourceopen', async () => {

  const sourceBuffer = mediaSource.addSourceBuffer('audio/webm; codecs="opus"');

  const response = await fetch(audioSRC);

  const body = response.body

  const reader = body.getReader()

  let streamNotDone = true;

  while (streamNotDone) {

    const {value, done} = await reader.read();
    
    if (done) {streamNotDone = false; break;}
    
    await new Promise((resolve, reject) => {
      sourceBuffer.appendBuffer(value)

      sourceBuffer.onupdateend = (() => {
        resolve(true);
      })
    }) 

  }
});

它适用于https://developer.mozilla.org/en-US/docs/Web/API/MediaSource

另外,我只对WebM/opus格式进行了测试,但我相信它也可以与其他格式一起使用只要您指定它。

相关文章