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

Derek Herman
Derek Herman
Jaroslav Polakovič
Jaroslav Polakovič

この記事では、メディア ストリーミングのより高度なコンセプトについて説明します。最終的には、さまざまなストリーミングのユースケース、プロトコル、拡張機能を十分に理解する必要があります。まず ストリーミングとは何かという 説明から始めましょう

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

ウェブサイトでストリーミングを提供するには、サーバーが 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> 要素のみを使用してオフライン メディア再生を提供する独自の基本的なストリーミング メディア ウェブサイトを開発する方法を示しています。Google のロードマップには、フレームワークやデジタル著作権管理などの機能をサポートする計画があります。随時更新情報をご確認ください。また、機能のリクエストも受け付けています。詳しくは、オフライン ストリーミングを備えた PWA の記事をご覧ください。

メディア チャンクの形式

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

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

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