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 をご覧ください。