Media Source API - メディア セグメントが付加順に自動でシームレスに再生される

HTML の音声要素と動画要素を使用すると、src URL を指定するだけで、メディアの読み込み、デコード、再生を行うことができます。

    <video src='foo.webm'></video>

単純なユースケースではうまく機能しますが、アダプティブ ストリーミングなどの手法では、Media Source Extensions API(MSE)を使用するとより細かく制御できます。MSE を使用すると、音声または動画のセグメントから JavaScript でストリームを作成できます。

simpl.info/mse で MSE をお試しいただけます。

MSE API を使用して再生された動画のスクリーンショット。

次のコードは、この例のものです。

MediaSource は、音声要素または動画要素のメディアのソースを表します。MediaSource オブジェクトがインスタンス化され、その open イベントが発生したら、SourceBuffer を追加できます。これらはメディア セグメントのバッファとして機能します。

var mediaSource = new MediaSource();
video.src = window.URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', function() {
    var sourceBuffer =
        mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
    // Get video segments and append them to sourceBuffer.
}

メディア セグメントを音声要素または動画要素に「ストリーミング」するには、appendBuffer() を指定して各セグメントを SourceBuffer に追加します。この例では、動画はサーバーから取得され、File API を使用して保存されます。

reader.onload = function (e) {
    sourceBuffer.appendBuffer(new Uint8Array(e.target.result));
    if (i === NUM_CHUNKS - 1) {
    mediaSource.endOfStream();
    } else {
    if (video.paused) {
        // start playing after first chunk is appended
        video.play();
    }
    readChunk(++i);
    }
};

再生順序を設定する

Chrome 50 では、SourceBuffer mode 属性のサポートが追加されています。これにより、メディア セグメントが最初に不連続のタイムスタンプであったかどうかに関係なく、追加された順序でメディア セグメントが継続的に再生されるように指定できます。

メディア セグメントの再生順序を指定するには、mode 属性を使用します。次の 2 つの値のいずれかになります。

  • segments: 各セグメントのタイムスタンプ(timestampOffset によって変更された可能性があります)によって、セグメントが追加される順序に関係なく再生順序が決まります。
  • sequence: メディア タイムラインでバッファリングされるセグメントの順序は、セグメントが SourceBuffer に付加される順序によって決まります。

メディア セグメントが SourceBuffer に追加されるときに、バイト ストリーム データから解析されたタイムスタンプが検出されたメディア セグメントは、SourceBuffermode プロパティが segments に設定されます。それ以外の場合、modesequence に設定されます。タイムスタンプは任意ではありません。ほとんどのストリーム タイプで必ず存在する必要があります。他のストリーム タイプでも使用することはできません。インバンド タイムスタンプは、タイムスタンプを含むストリーム タイプに固有のものです。

mode 属性の設定は省略可能です。タイムスタンプを含まないストリーム(audio/mpeg と audio/aac)の場合、modesegment から sequence に変更することのみ可能です。modesequence から segments に変更しようとすると、エラーが発生します。タイムスタンプを含むストリームの場合は、セグメントシーケンスを切り替えることができます。しかし実際には、望ましくない動作、理解しにくい、予測が困難な動作が発生する可能性があります。

すべてのストリーム タイプで、値を segments から sequence に変更できます。つまり、セグメントは追加された順序で再生され、それに応じて新しいタイムスタンプが生成されます。

sourceBuffer.mode = 'sequence';

mode 値を sequence に設定すると、メディア セグメントのタイムスタンプが不連続の場合(動画の多重化で問題が発生した場合や、(なんらかの理由で)不連続セグメントが追加された場合など)、メディアを継続的に再生できるようになります。正しいストリーム メタデータが使用可能な場合、アプリで timestampOffset をポリフィルして連続再生を保証することは可能ですが、シーケンス モードの方が処理が単純になり、エラーが発生しにくくなります。

MSE のアプリとデモ

これらは SourceBuffer.mode の操作がないにもかかわらず、MSE の動作を示しています。

ブラウザ サポート

  • Chrome 50 以降(デフォルト)
  • Firefox の場合: MDN をご覧ください

仕様

API 情報