10

私が達成しようとしているのは、Chromeにビデオファイルをデータとして(Fetch API、XHRなどを介して)ロード<video>させ、同じURLに対して2つの別々のリクエストを発行せずに、ダウンロード中に使用して再生することです。ファイルが完全にダウンロードされます。

ReadableStreamFetch API ( ) から取得するのは簡単ですが、それを要素response.bodyにフィードする方法が見つかりません。これには、オブジェクトを使用して作成できる URL がvideo必要であることがわかりました。ただし、必要なように聞こえるメソッドは Chrome に実装されていないため、ストリームをオブジェクトに直接接続することはできません。blobMediaSourceSourceBuffer#appendStreamMediaSource

おそらく、ストリームをチャンクで読み取り、Uint8Arrayそれらから を作成し、 を使用できますSourceBuffer#appendBufferが、これは、チャンク サイズが非常に小さい場合を除き、再生がすぐに開始されないことを意味します。また、これらすべての API がすぐに実行できるはずのことを、手動で実行しているようにも感じます。他に解決策がなく、この方法を使用する場合、どのような注意が必要ですか?

のブロブ URL を作成する他の方法はおそらくありますReadableStreamか? または、リクエストを作成fetchして<video>共有する方法はありますか? 非常に多くの新しい API があるため、簡単に何かを見落としてしまう可能性があります。

4

1 に答える 1

3

何時間もの実験の後、半分は機能する解決策を見つけました:

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 形式でのみこれをテストしましたが、指定する限り、他の形式でも動作するはずです。

于 2021-08-13T21:34:33.917 に答える