RTCRtpScriptTransformer
RTCRtpScriptTransformer
是 WebRTC API 的一个接口,它提供了一个工作者端 Stream API 接口, WebRTC 编码转换 可以使用它来修改 WebRTC 管道中进出编码的媒体帧。
注意:此功能在 专用 Web 工作者 中可用。
实例属性
RTCRtpScriptTransformer.readable
只读-
一个
ReadableStream
,WebRTC 发送方或接收方管道的编码帧可能会在其上排队。 RTCRtpScriptTransformer.writable
只读-
一个
WritableStream
,编码帧应该被管道化到其中。 RTCRtpScriptTransformer.options
只读-
从
RTCRtpScriptTransform
构造函数 传递的选项,用于根据处理传入或传出帧来配置转换代码。
实例方法
RTCRtpScriptTransformer.generateKeyFrame()
-
请求视频编码器生成关键帧。转换器可以在发送管道中处理传出帧时调用它。
RTCRtpScriptTransformer.sendKeyFrameRequest()
-
请求发送方发送关键帧。转换器可以在接收管道中处理传入编码视频帧时调用它。
描述
RTCRtpScriptTransformer
实例是在构建相关联的 RTCRtpScriptTransform
时创建的,它指定了创建转换器的 worker 以及传递给它的选项。
转换器通过 rtctransform
事件的 transformer
属性提供给 worker。此事件在构建关联的 RTCRtpScriptTransform
时以及当编码帧从编解码器(传出)或封包器(传入)在 RTCRtpScriptTransformer.readable
上排队时触发。
转换器向 worker 公开了一个 readable
和 writable
流,以及在构建时提供给 RTCRtpScriptTransform
的 options
对象。当关联的 RTCRtpScriptTransform
被分配给 RTCRtpSender
或 RTCRtpReceiver
时,来自 WebRTC 发送方或接收方管道的编码媒体帧将排队到 readable
流中。
WebRTC 编码转换必须从 transformer.readable
读取编码帧,根据需要修改它们,并将它们按相同顺序写入 transformer.writable
,并且不进行任何重复。 transformer.options
允许使用适当的转换函数,这取决于编码媒体帧是传入还是传出。转换通常通过将帧从 readable
通过一个或多个 TransformStream
实例管道化到 writable
来实现,并根据需要对其进行转换。
该接口还提供了一些方法,用于让发送方生成让视频编码器生成新的关键帧,或者让接收方从发送方的编码器请求新的关键帧(视频编码器通常发送包含构建图像所需完整信息的关键帧,然后发送仅包含自上一帧以来发生变化信息的增量帧)。
在接收方在收到新的关键帧之前无法解码传入帧的情况下,需要这些方法。例如,加入会议通话的新接收方在收到新的关键帧之前将无法看到视频,因为只有在您拥有最后一个关键帧和所有后续增量帧的情况下才能解码增量帧。同样,如果帧为接收方加密,它们只有在收到第一个加密的关键帧后才能解码帧。
示例
此示例显示了在工作者中运行的 WebRTC 编码转换的代码。
该代码使用 addEventListener()
为 rtctransform
事件注册一个处理程序函数,该事件将 RTCRtpScriptTransformer
作为 event.transformer
提供。
该处理程序创建了一个 TransformStream
,并将帧从 event.transformer.readable
通过它管道化到 event.transformer.writable
。转换流 transform()
实现被调用以处理在流上排队的每个编码帧:它可以读取帧中的数据,在本例中对字节进行取反,然后将可修改的帧排队到流上。
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
的唯一特别之处在于它排队编码媒体帧 (RTCEncodedVideoFrame
或 RTCEncodedAudioFrame
) 而不是任意“块”,并且 writableStrategy
和 readableStrategy
属性未定义(因为排队策略完全由用户代理管理)。
转换可以在 WebRTC 管道的传入或传出管道中运行。在上面的代码中这无关紧要,因为相同的算法可能在发送方中用于对帧进行取反,而在接收方中用于恢复它们。如果发送方和接收方管道需要应用不同的转换算法,则必须从主线程传递有关当前管道的的信息。这是通过在相应的 RTCRtpScriptTransform
构造函数 中设置 options
参数来完成的,该参数随后在 RTCRtpScriptTransformer.options
中提供给 worker。
下面,我们使用 transformer.options
来选择发送方转换或接收方转换。请注意,对象的属性是任意的(前提是值可以序列化),也可以传输 MessageChannel
并使用它来 在运行时与转换进行通信,例如,共享加密密钥。
// 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 编码转换 中提供的更完整示例的一部分。
规范
规范 |
---|
WebRTC 编码转换 # rtcrtpscripttransformer |
浏览器兼容性
BCD 表仅在启用 JavaScript 的浏览器中加载。