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

Derek Herman
Derek Herman
Jaroslav Polakovič
Jaroslav Polakovič

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

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

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

ストリーミングのユースケース

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

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

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

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

<video> を使用したストリームの再生

多くのブラウザでは、ストリームをネイティブで再生できません。いくつかのネイティブ HLS 再生サポートがありますが、ブラウザは通常、ネイティブ DASH ストリーム再生をサポートしていません。つまり、<video> 要素内の <source> をマニフェスト ファイルを指すだけでは不十分です。

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

不足しているように見えるかもしれませんが、実際には偽装の強みです。ストリームは強力であり、ストリームを使用するアプリケーションにはさまざまなニーズがあります。

通常、マニフェスト ファイルには単一メディアの多数のバリエーションが記述されます。異なるビットレート、複数の音声トラック、同じメディアが異なる形式でエンコードされたものなども考えてください。

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

メディアソース拡張機能

幸いなことに、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)ファイルのサポートが DASH でもサポートされている形式である HLS に追加されました。

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

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