メディア ストリーミングの基本

Derek Herman
Derek Herman
Jaroslav Polakovič
Jaroslav Polakovič

この記事では、メディア ストリーミングの高度なコンセプトについて学びます。最後まで読めば、さまざまなストリーミングのユースケース、プロトコル、拡張機能について理解できるはずです。まず、ストリーミングとは何かを説明しましょう。

メディア ストリーミングは、メディア コンテンツを部分的に配信して再生する方法です。ネットワーク用に最適化されていないと遅くなる可能性がある単一のファイルを読み込む代わりに、プレーヤーは、ターゲット メディアが個々のデータ チャンクに分割される方法を記述するマニフェスト ファイルを読み込みます。メディア チャンクは、後で実行時に動的に再結合されます。おそらく異なるビットレートで再結合されますが、これについては後で説明します。

ウェブサイトでストリーミングを提供するには、サーバーが Range HTTP リクエスト ヘッダーをサポートしている必要があります。Accept-Ranges ヘッダーについて詳しくは、<video> タグと <source> タグをご覧ください。

メディア チャンクと、ストリームを記述する必要なマニフェストを生成するのは簡単ではありませんが、ストリーミングにより、<video> 要素を静的ソースファイルのセットに指すだけでは実現できない興味深いユースケースが実現できます。ウェブページにメディアを追加する方法については、後のセクションで詳しく説明します。複数のファイルを <video> 要素に読み込むだけでなく、さらに高度な操作を行う場合は、まずマルチメディアのストリーミングのユースケースについて理解しておく必要があります。

  • アダプティブ ストリーミングでは、メディア チャンクが複数のビットレートでエンコードされ、クライアントの現在利用可能な帯域幅に適合する最高品質のメディア チャンクがメディア プレーヤーに返されます。
  • ライブ放送では、メディア チャンクがエンコードされ、リアルタイムで利用可能になります。
  • メディアの挿入は、プレーヤーがメディアソースを変更することなく、広告などの他のメディアをストリームに挿入する方法です。

ストリーミング プロトコル

ウェブで最もよく使用される 2 つのストリーミング プロトコルは、Dynamic Adaptive Streaming over HTTPDASH)と HTTP Live StreamingHLS)です。これらのプロトコルをサポートするプレーヤーは、生成されたマニフェスト ファイルを取得し、リクエストするメディア チャンクを特定して、最終的なメディア エクスペリエンスに統合します。

<video> を使用してストリームを再生する

多くのブラウザでは、ライブ配信はネイティブに再生されません。一部のブラウザでは HLS 再生がネイティブにサポートされていますが、一般的にブラウザはネイティブ DASH ストリーム再生をサポートしていません。つまり、多くの場合、<video> 要素の <source> をマニフェスト ファイルに指すだけでは不十分です。

<video controls>
  <source src="manifest.mpd" type="application/dash+xml">
</video>

欠点と思われるものが、実は隠れた強みであることもあります。ストリームは強力であり、ストリームを使用するアプリケーションのニーズは異なります。

通常、マニフェスト ファイルは 1 つのメディアの多くのバリエーションを記述します。異なるビットレート、複数のオーディオ トラック、さらには同じメディアを異なる形式でエンコードしたものなどです。

アプリケーションによっては、バッファに大量の動画を確保したい場合や、次のエピソードの最初の数秒をプリフェッチしたい場合、または独自のロジックを実装してアダプティブ ストリーミングを実現したい場合があります。ここでは、再生用のメディア ストリームを生成するブラウザの組み込み機能を必要としますが、幸いにもそのような機能が用意されています。

メディアソース拡張機能

幸い、W3C は、JavaScript でメディア ストリームを生成できる Media Source Extensions(MSE)を定義しています。簡単に説明すると、MSE を使用すると、デベロッパーは MediaSource オブジェクトを <video> 要素に接続し、MediaSource インスタンスに接続されたバッファに送信されたメディアデータを再生できます。

基本的な例

const videoEl = document.querySelector('video');
const mediaSource = new MediaSource();

video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener(
  'sourceopen',
  () => {
    const mimeString = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
    const buffer = mediaSource.addSourceBuffer(mimeString);

    buffer.appendBuffer( /* Video data as `ArrayBuffer` object. */ )
  }
);

上記の簡素化された例は、次の点を説明しています。

  • <video> は URL からメディアデータを受信します。
  • 生成された URL は、MediaSource インスタンスへのポインタにすぎません。
  • MediaSource インスタンスは、1 つ以上の SourceBuffer インスタンスを作成します。
  • 次に、fetch などを使用して、バイナリ メディア データをバッファに追加します。

これらの基本コンセプトはシンプルで、DASH と HLS に対応した動画プレーヤーをゼロから作成することは確かに可能ですが、ほとんどの人は、Shaka PlayerJW PlayerVideo.js など、すでに存在する成熟したオープンソース ソリューションのいずれかを選択します。

ただし、Kino というデモの Media PWA を作成しました。これは、シンプルな <video> 要素のみを使用してオフライン メディア再生を提供する独自の基本的なストリーミング メディア ウェブサイトを開発する方法を示しています。フレームワークやデジタル著作権管理などの機能をサポートする予定がロードマップに含まれています。随時更新情報をご確認ください。また、機能のリクエストも受け付けています。詳しくは、オフライン ストリーミングを備えた PWA の記事をご覧ください。

メディア チャンクの形式

長い間、DASH と HLS では、メディア チャンクを異なる形式でエンコードする必要がありました。ただし、2016 年に、標準の断片化された MP4(fMP4)ファイルのサポートが HLS に追加されました。この形式は DASH でもサポートされています。

fMP4 コンテナと H.264 コーデックを使用する動画チャンクは、両方のプロトコルでサポートされており、ほとんどのプレーヤーで再生できます。これにより、コンテンツ プロデューサーは動画を 1 回だけエンコードできるため、時間とディスク容量を節約できます。

品質を高め、ファイルサイズを小さくするには、VP9 などのより効率的な形式を使用して、複数のメディア チャンクのセットをエンコードすることをおすすめします。ただし、先に進む前に、ウェブ用にメディア ファイルを準備する方法を学ぶ必要があります。