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

HTML の audio 要素と video 要素を使用すると、src URL を指定するだけでメディアを読み込み、デコード、再生できます。

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

これはシンプルなユースケースでは適切ですが、アダプティブ ストリーミングなどの手法では、Media Source Extensions API(MSE)の方がより細かく制御できます。MSE を使用すると、音声または動画のセグメントから JavaScript でストリームを構築できます。

MSE は simpl.info/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 属性を使用して、メディア セグメントの再生順序を指定します。次のいずれかの値になります。

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

メディア セグメントが SourceBuffer に追加されるときにバイト ストリーム データから解析されたタイムスタンプが含まれている場合、SourceBuffermode プロパティは segments に設定されます。それ以外の場合は、modesequence に設定されます。タイムスタンプは省略できません。ほとんどのストリーミング タイプではタイムスタンプが必須ですが、他のタイプでは使用できません。インバンド タイムスタンプは、タイムスタンプを含むストリーミング タイプに固有のものです。

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

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

sourceBuffer.mode = 'sequence';

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

MSE アプリとデモ

以下は、SourceBuffer.mode の操作なしで MSE が動作している様子を示しています。

ブラウザ サポート

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

仕様

API 情報