HTML の audio 要素と video 要素を使用すると、src URL を指定するだけでメディアを読み込み、デコード、再生できます。
<video src='foo.webm'></video>
これはシンプルなユースケースでは適切ですが、アダプティブ ストリーミングなどの手法では、Media Source Extensions API(MSE)の方がより細かく制御できます。MSE を使用すると、音声または動画のセグメントから JavaScript でストリームを構築できます。
MSE は simpl.info/mse で試すことができます。
以下のコードはその例のものです。
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
に追加されるときにバイト ストリーム データから解析されたタイムスタンプが含まれている場合、SourceBuffer
の mode
プロパティは segments に設定されます。それ以外の場合は、mode
は sequence に設定されます。タイムスタンプは省略できません。ほとんどのストリーミング タイプではタイムスタンプが必須ですが、他のタイプでは使用できません。インバンド タイムスタンプは、タイムスタンプを含むストリーミング タイプに固有のものです。
mode
属性の設定は省略可能です。タイムスタンプを含まないストリーム(audio/mpeg と audio/aac)の場合、mode
は segments から sequence にのみ変更できます。mode
を sequence から segments に変更しようとすると、エラーがスローされます。タイムスタンプのあるストリームの場合、セグメントとシーケンスを切り替えることができますが、実際には、望ましくない動作、理解や予測が難しい動作が発生する可能性があります。
すべてのストリームタイプで、値を [セグメント] から [シーケンス] に変更できます。つまり、セグメントは追加された順序で再生され、それに応じて新しいタイムスタンプが生成されます。
sourceBuffer.mode = 'sequence';
mode
値を sequence に設定できれば、メディア セグメントのタイムスタンプが連続的でない場合でも、たとえば動画の多重化で問題が発生した場合や、(なんらかの理由で)非連続なセグメントが追加された場合にも、メディアを連続再生できます。正しいストリーム メタデータが利用可能な場合、連続再生を保証するためにアプリで timestampOffset
をポリフィルすることは可能ですが、シーケンス モードでは処理がシンプルになり、エラーが発生しにくくなります。
MSE アプリとデモ
以下は、SourceBuffer.mode
の操作なしで MSE が動作している様子を示しています。
- Media Source API
- Shaka Player: MSE を使用して、Shaka JavaScript ライブラリで DASH を実装する動画プレーヤーのデモ
ブラウザ サポート
- Chrome 50 以降(デフォルト)
- Firefox の場合、詳しくは MDN をご覧ください。