RTCRtpScriptTransformer

基線 2025 *
新推出

自 2025 年 10 月起,此功能已在最新的裝置和瀏覽器版本中可用。此功能可能不適用於較舊的裝置或瀏覽器。

* 此特性的某些部分可能存在不同級別的支援。

RTCRtpScriptTransformer 介面是 WebRTC API 的一部分,它提供了一個工作執行緒(worker)端的 Stream API 介面,WebRTC Encoded Transform 可以使用該介面來修改 WebRTC 傳入和傳出的管道中的編碼媒體幀。

注意:此功能在 專用 Web Worker 中可用。

例項屬性

RTCRtpScriptTransformer.readable 只讀

一個 ReadableStream,WebRTC 傳送者或接收者管道中的編碼幀可能會被新增到其中。

RTCRtpScriptTransformer.writable 只讀

一個 WritableStream,編碼幀應該被管道傳輸到其中。

RTCRtpScriptTransformer.options 只讀

RTCRtpScriptTransform 建構函式 傳遞的選項,用於根據正在處理的是傳入幀還是傳出幀來配置轉換程式碼。

例項方法

RTCRtpScriptTransformer.generateKeyFrame()

請求影片編碼器生成一個關鍵幀。當處理傳出幀時,可以在傳送者管道中的轉換器呼叫此方法。

RTCRtpScriptTransformer.sendKeyFrameRequest()

請求傳送者傳送一個關鍵幀。當處理傳入的編碼影片幀時,可以在接收者管道中的轉換器呼叫此方法。

描述

RTCRtpScriptTransformer 例項是在關聯的 RTCRtpScriptTransform 構建過程中建立的,該例項指定了建立轉換器的 worker 以及將傳遞給它的選項。

透過工作執行緒上的 rtctransform 事件的 transformer 屬性,轉換器對 worker 可用。當建立關聯的 RTCRtpScriptTransform 時,以及當編碼幀被新增到 RTCRtpScriptTransformer.readable(來自編解碼器(傳出)或來自打包器(傳入))時,會觸發此事件。

轉換器向 worker 公開了一個 readablewritable 流,以及一個在構建時提供給 RTCRtpScriptTransformoptions 物件。當關聯的 RTCRtpScriptTransform 被分配給 RTCRtpSenderRTCRtpReceiver 時,WebRTC 傳送者或接收者管道中的編碼媒體幀會被新增到 readable 流中。

WebRTC Encoded Transform 必須從 transformer.readable 讀取編碼幀,根據需要進行修改,然後以相同的順序寫入 transformer.writable,並且不進行任何重複。 transformer.options 允許根據編碼媒體幀是傳入還是傳出,使用適當的轉換函式。轉換通常透過將幀從 readable 管道傳輸到一個或多個 TransformStream 例項到 writable 來實現,根據需要進行轉換。

該介面還提供了方法,允許傳送者生成一個影片編碼器來生成新的關鍵幀,或者允許接收者向傳送者的編碼器請求新的關鍵幀(影片編碼器通常會發送一個包含構建影像所需全部資訊的視覺化幀,然後傳送僅包含自上一幀以來已更改資訊的可變幀)。

在接收者在收到新的關鍵幀之前無法解碼傳入幀的情況下,需要這些方法。例如,新加入會議的接收者將無法看到影片,直到他們收到一個新的關鍵幀,因為只能在擁有上一關鍵幀和所有後續可變幀的情況下才能解碼可變幀。同樣,如果幀是為接收者加密的,他們只有在收到第一個加密的關鍵幀後才能解碼幀。

示例

此示例顯示了在 worker 中執行的 WebRTC Encoded Transform 的程式碼。

該程式碼使用 addEventListener()rtctransform 事件註冊一個處理函式,該事件將 RTCRtpScriptTransformer 暴露為 event.transformer

該處理函式建立一個 TransformStream,並將幀從 event.transformer.readable 透過它管道傳輸到 event.transformer.writable。該轉換流的 transform() 實現會為流中排隊的每個編碼幀呼叫:它可以讀取幀中的資料,在本例中是反轉位元組,然後將可修改的幀排入流。

js
addEventListener("rtctransform", (event) => {
  const transform = new TransformStream({
    start() {}, // Called on startup.
    flush() {}, // Called when the stream is about to be closed.
    async transform(encodedFrame, controller) {
      // Reconstruct the original frame.
      const view = new DataView(encodedFrame.data);

      // Construct a new buffer
      const newData = new ArrayBuffer(encodedFrame.data.byteLength);
      const newView = new DataView(newData);

      // Negate all bits in the incoming frame
      for (let i = 0; i < encodedFrame.data.byteLength; ++i) {
        newView.setInt8(i, ~view.getInt8(i));
      }

      encodedFrame.data = newData;
      controller.enqueue(encodedFrame);
    },
  });
  event.transformer.readable
    .pipeThrough(transform)
    .pipeTo(event.transformer.writable);
});

上面 TransformStream 的唯一特別之處在於,它排隊的是編碼媒體幀(RTCEncodedVideoFrameRTCEncodedAudioFrame),而不是任意“塊”,並且 writableStrategyreadableStrategy 屬性未定義(因為排隊策略完全由使用者代理管理)。

轉換可以在傳入或傳出的 WebRTC 管道中執行。這在上面的程式碼中無關緊要,因為傳送者可以使用相同的演算法來反轉幀,接收者也可以用相同的演算法來恢復它們。如果傳送者和接收者管道需要應用不同的轉換演算法,則必須將當前管道的資訊從主執行緒傳遞。這可以透過在相應的 RTCRtpScriptTransform 建構函式 中設定 options 引數來實現,該引數然後可以在 RTCRtpScriptTransformer.options 中供 worker 使用。

下面我們使用 transformer.options 來選擇傳送者轉換或接收者轉換。請注意,物件的屬性是任意的(只要值可以被序列化),並且還可以傳輸 MessageChannel 並使用它在 執行時與轉換器進行通訊,例如共享加密金鑰。

js
// Code to instantiate transform and attach them to sender/receiver pipelines.
onrtctransform = (event) => {
  let transform;
  if (event.transformer.options.name === "senderTransform")
    transform = createSenderTransform();
  // returns a TransformStream (not shown)
  else if (event.transformer.options.name === "receiverTransform")
    transform = createReceiverTransform();
  // returns a TransformStream (not shown)
  else return;
  event.transformer.readable
    .pipeThrough(transform)
    .pipeTo(event.transformer.writable);
};

請注意,上面的程式碼是 使用 WebRTC Encoded Transforms 中提供的更完整示例的一部分。

規範

規範
WebRTC Encoded Transform
# rtcrtpscripttransformer

瀏覽器相容性

另見