MediaStreamTrack の挿入可能なストリーム

MediaStreamTrack のコンテンツが、新しいコンテンツの生成に操作または使用が可能なストリームとして公開される

背景

Media Capture と Streams API のコンテキストでは、MediaStreamTrack インターフェースはストリーム内の単一のメディア トラックを表します。通常は音声トラックまたは動画トラックですが、他のトラックタイプが存在する場合もあります。MediaStream オブジェクトは、さまざまな音声トラックや動画トラックを表す 0 個以上の MediaStreamTrack オブジェクトで構成されます。各 MediaStreamTrack は 1 つ以上のチャネルを持つことができます。チャンネルは、メディア ストリームの最小単位を表します。たとえば、ステレオ音声トラックの左右など、特定のスピーカーに関連付けられたオーディオ信号などです。

MediaStreamTrack の挿入可能なストリームとは何ですか?

MediaStreamTrack の挿入可能なストリームの背景にある主な考え方は、MediaStreamTrack のコンテンツをストリームのコレクションとして公開することです(WHATWG Streams API で定義されているとおり)。これらのストリームを操作して、新しいコンポーネントを導入できます。

デベロッパーに動画(または音声)ストリームへのアクセス権を直接付与することで、ストリームに変更を直接適用できるようになります。一方、従来のメソッドで同じ動画操作タスクを実現するには、デベロッパーが <canvas> 要素などの中間要素を使用する必要があります。(このようなプロセスの詳細については、video + canvas = magic をご覧ください)。

ブラウザ サポート

MediaStreamTrack の挿入可能なストリームは Chrome 94 以降でサポートされます。

使用例

MediaStreamTrack の挿入可能なストリームのユースケースには次のようなものがあります(これらに限定されません)。

  • 「おもしろい帽子」やバーチャル背景などのビデオ会議用ガジェット。
  • ソフトウェア ボコーダのような音声処理。

MediaStreamTrack に挿入可能なストリームを使用する方法

機能検出

MediaStreamTrack サポートの挿入可能なストリームを特徴検出するには、次のようにします。

if ('MediaStreamTrackProcessor' in window && 'MediaStreamTrackGenerator' in window) {
  // Insertable streams for `MediaStreamTrack` is supported.
}

基本コンセプト

MediaStreamTrack の挿入可能なストリームは、以前に WebCodecs で提案されたコンセプトに基づいて構築されており、概念的には MediaStreamTrack を次の 2 つのコンポーネントに分割しています。

  • MediaStreamTrackProcessorMediaStreamTrack オブジェクトのソースを使用し、メディア フレーム(具体的には VideoFrame または AudioFrame)オブジェクトのストリームを生成します。これは、トラックからエンコードされていないフレームを ReadableStream として公開できるトラックシンクと考えることができます。
  • MediaStreamTrackGenerator。メディア フレームのストリームを使用し、MediaStreamTrack インターフェースを公開します。getUserMedia() のトラックと同様に、任意のシンクに指定できます。メディア フレームを入力として受け取ります。

MediaStreamTrackProcessor

MediaStreamTrackProcessor オブジェクトは、readable という 1 つのプロパティを公開します。これにより、MediaStreamTrack からフレームを読み取ることができます。トラックが動画トラックの場合、readable から読み取られたチャンクは VideoFrame オブジェクトになります。トラックが音声トラックの場合、readable から読み取られたチャンクは AudioFrame オブジェクトになります。

MediaStreamTrackGenerator

同様に、MediaStreamTrackGenerator オブジェクトは writable という 1 つのプロパティを公開します。これは WritableStream で、メディア フレームを MediaStreamTrackGenerator(それ自体は MediaStreamTrack)に書き込むことができます。kind 属性が "audio" の場合、ストリームは AudioFrame オブジェクトを受け入れ、他の型で失敗します。kind が "video" の場合、ストリームは VideoFrame オブジェクトを受け入れ、他の型では失敗します。フレームが writable に書き込まれると、フレームの close() メソッドが自動的に呼び出され、JavaScript からそのメディア リソースにアクセスできなくなります。

MediaStreamTrackGenerator は、メディア フレームを writable フィールドに書き込むことでカスタムソースを実装できるトラックです。

まとめ

基本的な考え方は、次のような処理チェーンを作成することです。

プラットフォーム トラック → プロセッサ → 変換 → 生成ツール → プラットフォーム シンク

以下の例は、ライブ動画ストリーム内で検出されたバーコードをハイライト表示するバーコード スキャナ アプリケーションのチェーンを示しています。

const stream = await getUserMedia({ video: true });
const videoTrack = stream.getVideoTracks()[0];

const trackProcessor = new MediaStreamTrackProcessor({ track: videoTrack });
const trackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });

const transformer = new TransformStream({
  async transform(videoFrame, controller) {
    const barcodes = await detectBarcodes(videoFrame);
    const newFrame = highlightBarcodes(videoFrame, barcodes);
    videoFrame.close();
    controller.enqueue(newFrame);
  },
});

trackProcessor.readable.pipeThrough(transformer).pipeTo(trackGenerator.writable);

const videoBefore = document.getElementById('video-before');
const videoAfter = document.getElementById('video-after');
videoBefore.srcObject = stream;
const streamAfter = new MediaStream([trackGenerator]);
videoAfter.srcObject = streamAfter;

デモ

上記のセクションの QR コードスキャナのデモをデスクトップ ブラウザまたはモバイル ブラウザでご覧になれます。カメラの前で QR コードを持つと、アプリが QR コードを検出してハイライト表示します。アプリケーションのソースコードは Glitch で確認できます。

パソコンのブラウザタブで実行されている QR コードスキャナ。ノートパソコンのカメラの前に持っているスマートフォンで検出された QR コードがハイライト表示されている。

セキュリティとプライバシーに関する考慮事項

この API のセキュリティは、ウェブ プラットフォームの既存のメカニズムに依存します。VideoFrame インターフェースと AudioFrame インターフェースを使用してデータが公開されると、送信元 taint データを処理するこれらのインターフェースのルールが適用されます。たとえば、クロスオリジン リソースへのアクセスに関する既存の制限により、クロスオリジン リソースのデータにはアクセスできません(クロスオリジンの画像や動画要素のピクセルにアクセスできないなど)。また、カメラ、マイク、画面からのメディアデータへのアクセスは、ユーザーの承認が必要です。この API が公開するメディアデータは、他の API ですでに利用できます。

フィードバック

Chromium チームでは、MediaStreamTrack の挿入可能なストリームについてご意見をお聞かせください。

API の設計についてお聞かせください

API に関して、想定したとおりに動作しない点はありますか。あるいは、アイデアを実装するために必要なメソッドやプロパティが欠落していないか?セキュリティ モデルについてご質問やご意見はありますか?対応する GitHub リポジトリで仕様の問題を提出するか、既存の問題に意見を追加します。

実装に関する問題を報告する

Chromium の実装でバグが見つかりましたか?それとも、実装が仕様と異なりますか? new.crbug.com でバグを報告します。できる限り詳細な情報と再現手順を記載し、[Components] ボックスに「Blink>MediaStream」と入力します。Glitch を使えば、再現をすばやく簡単に共有できます。

API のサポートを表示する

MediaStreamTrack に挿入可能なストリームを使用する予定はありますか?一般公開のサポートにより、Chromium チームは機能に優先順位を付け、そのサポートがいかに重要であるかを他のブラウザ ベンダーに示すことができます。

ハッシュタグ #InsertableStreams を使用して @ChromiumDev 宛てにツイートを送信し、使用場所と使用方法をお知らせください。

謝辞

MediaStreamTrack 仕様の挿入可能なストリームは、Harald AlvestrandGuido Urdaneta によって作成されました。この記事は、Harald Alvestrand、Joe MedleyBen WagnerHuib KleinhoutFrançois Beaufort によってレビューされました。ヒーロー画像(作成者: Chris MontgomeryUnsplash