MediaStreamTrack 的可插入串流

MediaStreamTrack 的內容會以串流形式公開,可供操控或用於產生新內容

背景

Media Capture and Streams API 中使用 MediaStreamTrack 介面,代表串流中的單一媒體音軌,這些音軌通常是音訊或視訊軌,但可能有其他音軌類型。MediaStream 物件由零或多個 MediaStreamTrack 物件組成,代表各種音訊或視訊軌。每個 MediaStreamTrack 都有一或多個頻道。管道代表媒體串流的最小單位,例如與指定喇叭相關聯的音訊訊號,例如立體聲音軌的左側或右側。

什麼是 MediaStreamTrack 的可插入串流?

MediaStreamTrack 的可插入串流背後的核心概念,是將 MediaStreamTrack 的內容呈現為串流集合 (如 WHATWG Streams API 定義)。您可以操控這些串流加入新元件。

授予開發人員影片 (或音訊) 串流的存取權,讓他們能直接將修改內容套用到串流。相反地,如要用傳統方法實現相同的影片操縱工作,開發人員必須使用 <canvas> 元素等中繼工作。(如要進一步瞭解這類程序,請參閱「video + 畫布 = 魔法」。)

瀏覽器支援

Chrome 第 94 版支援可插入的 MediaStreamTrack 串流。

用途

MediaStreamTrack 的可插入串流用途包括但不限於:

  • 視訊會議小工具,例如「趣味帽子」或虛擬背景。
  • 語音處理,就像軟體 vocoder

如何使用「MediaStreamTrack」的可插入串流

功能偵測

您可以透過功能偵測可插入串流來支援 MediaStreamTrack,如下所示。

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

核心概念

MediaStreamTrack 的可插入串流是以先前 WebCodecs 提議的概念為基礎,而從概念上將 MediaStreamTrack 分割為兩個元件:

  • MediaStreamTrackProcessor 會使用 MediaStreamTrack 物件的來源並產生媒體影格串流,特別是 VideoFrameAudioFrame 物件。您可以將此視為可以把未編碼影格顯示為 ReadableStream 的軌跡接收器。
  • MediaStreamTrackGenerator 會耗用媒體影格串流並公開 MediaStreamTrack 介面。而且可以提供給任何接收器,就像來自 getUserMedia() 的曲目一樣。系統會以媒體影格做為輸入內容。

MediaStreamTrackProcessor

MediaStreamTrackProcessor 物件會顯示一個屬性 readable。可讓您從 MediaStreamTrack 讀取影格。如果曲目是影片軌,從 readable 讀取的區塊會是 VideoFrame 物件。如果音軌是音軌,從 readable 讀取的區塊會是 AudioFrame 物件。

MediaStreamTrackGenerator

MediaStreamTrackGenerator 物件同樣會公開一個屬性 writable,這是一種 WritableStream,可讓您將媒體影格寫入 MediaStreamTrackGenerator,也就是其本身是 MediaStreamTrack。如果 kind 屬性為 "audio",串流會接受 AudioFrame 物件,且會因為任何其他類型而失敗。如果種類是 "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 code 掃描器示範。將 QR code 對準相機,應用程式就會偵測並醒目顯示該 QR code。您可以在 Glitch 上查看應用程式的原始碼。

在電腦瀏覽器分頁中執行的 QR code 掃描器,顯示使用者將手機拿在筆電相機前,手機上偵測到的 QR code 並醒目顯示。

安全性和隱私權注意事項

這個 API 的安全性取決於網路平台中的現有機制。由於資料是透過 VideoFrameAudioFrame 介面公開,因此適用這些介面處理來源保留資料的規則。例如,由於存取相關資源的現有限制 (例如,無法存取跨來源圖片或影片元素的像素),因此無法存取跨來源資源的資料。此外,存取相機、麥克風或螢幕中的媒體資料時,必須取得使用者授權。這個 API 公開的媒體資料已透過其他 API 取得。

意見回饋:

Chromium 團隊想瞭解您在 MediaStreamTrack 的可插入串流使用體驗。

告訴我們 API 設計

有什麼 API 功能不如您預期嗎?或者您需要實作提案的方法或屬性嗎?您對於安全性模型有任何疑問或意見嗎?在對應的 GitHub 存放區上提交規格問題,或是將您的想法新增至現有問題。

回報導入問題

你在 Chromium 的實作方式中發現錯誤嗎?或者,實作項目是否與規格不同? 前往 new.crbug.com 回報錯誤。請務必盡可能提供詳細的細節與重現簡易操作說明,並在「元件」方塊中輸入 Blink>MediaStreamGlitch 適合用來快速分享簡單快速的提案,

展現對 API 的支援

您打算為「MediaStreamTrack」使用可插入的串流嗎?您的公開支援可協助 Chromium 團隊排定功能的優先順序,並向其他瀏覽器廠商說明這項功能有多重要。

請使用主題標記 #InsertableStreams 將 Tweet 訊息傳送至 @ChromiumDev,告訴我們您的使用地點和方式。

特別銘謝

MediaStreamTrack 規格的可插入串流是由 Harald AlvestrandGuido Urdaneta 編寫。本文由 Harald Alvestrand、Joe MedleyBen WagnerHuib KleinhoutFrançois Beaufort 審查。Chris MontgomeryUnsplash 上提供主頁橫幅。