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

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

背景

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

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

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

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

ブラウザ サポート

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

ユースケース

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

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

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

機能検出

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

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

基本コンセプト

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

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

MediaStreamTrackProcessor

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

MediaStreamTrackGenerator

MediaStreamTrackGenerator オブジェクトも同様に、writable という 1 つのプロパティを公開します。これは、MediaStreamTrackGenerator(それ自体は MediaStreamTrack)にメディア フレームを書き込むことができる WritableStream です。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 インターフェースを使用して公開されると、オリジン テイストのデータを処理するインターフェースのルールが適用されます。たとえば、クロスオリジン リソースへのアクセスには既存の制限があるため、クロスオリジン リソースのデータにアクセスすることはできません(クロスオリジンの画像要素や動画要素のピクセルにアクセスすることはできません)。また、カメラ、マイク、画面からのメディアデータへのアクセスには、ユーザーの承認が必要です。この API が公開するメディアデータは、他の API でもすでに利用できます。

フィードバック

Chromium チームは、MediaStreamTrack の挿入可能なストリームに関するご意見をお聞かせいただきたいと考えています。

API 設計について

API に関して、想定どおりに機能していないものはありますか?または、アイデアを実装するために必要なメソッドやプロパティが不足している場合はどうすればよいですか?セキュリティモデルについて 質問やコメントがある場合は対応する GitHub リポジトリで仕様に関する問題を報告するか、既存の問題にコメントを追加してください。

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

Chromium の実装にバグが見つかりましたか?それとも、実装が仕様と異なるのでしょうか?new.crbug.com でバグを報告します。できるだけ詳細な情報を含め、再現手順を簡単に説明してください。[コンポーネント] ボックスに Blink>MediaStream を入力します。Glitch は、簡単な再現手順をすばやく共有するのに適しています。

API のサポートを表示する

MediaStreamTrack に挿入可能なストリームを使用する予定はありますか?一般公開でサポートすると、Chromium チームが機能の優先順位を決めるのに役立ち、他のブラウザ ベンダーにその機能のサポートがどれほど重要であるかを示します。

ハッシュタグ #InsertableStreams を使用して @ChromiumDev にツイートを送信し、どこでどのように使用しているかをお知らせください。

謝辞

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