前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WebRTC Insertable Stream 初探与 WebRTC"管道化"

WebRTC Insertable Stream 初探与 WebRTC"管道化"

作者头像
刘连响
发布2022-03-30 14:16:59
2.6K0
发布2022-03-30 14:16:59
举报
文章被收录于专栏:刘同学被占用了

在"WebRTC的现状与未来"(https://webrtchacks.com/webrtc-today-tomorrow-bernard-aboba-qa/)这篇文章中讲述了WebRTC要带来的一些新的特性, 这里我们重点探索一下WebRTC Insertable Streams

什么是WebRTC Insertable Streams

WebRTC Insertable Streams 提供了让用户操作WebRTC编码后数据的能力,最新的规范在这里 https://w3c.github.io/webrtc-encoded-transform/,目前已经改名叫做WebRTC Encoded Transform。 我们先看下WebRTC的视频处理流程:

发送流程:

  • (S1)从媒体设备/其他采集源中获得一帧一帧的数据
  • (S2)对原始数据进行编码(VP8 H264 AV1)
  • <- 在这里插入逻辑
  • (S3)把编码后的视频帧 RTP打包
  • (S4)加密
  • (S5)发送

接收流程:

  • (R1)接受网络RTP包
  • (R2)解密
  • (R3)RTP组包
  • <- 在这里插入逻辑
  • (R4)解码数据
  • (R5)渲染数据

WebRTC Insertable Streams 可以让我们在发送流程中的S2和S3之间,接受流程的R3和R4之间加入处理编码后的数据的能力, 起初是为了端到端加密而设计, 但他的使用场景确可以进一步的拓展。

基本使用

WebRTC Insertable Streams 在Chrome M82版本中引入,但一直是实验状态,可以在Chrome Canary版本中进行体验。基本用法如下

初始化PeerConnection的时候需要加上特殊参数:

代码语言:javascript
复制
var pc = new RTCPeerConnection({
    encodedInsertableStreams: true,  
});

上行RTCRtpSender 创建EncodedStreams:

代码语言:javascript
复制
        let transceiver = await pc.addTransceiver(stream.getVideoTracks()[0], {
            direction: "sendonly",
            streams: [stream],
        });
        
        setupSenderTransform(transceiver.sender);


        function setupSenderTransform(sender) {
            console.log('sender kind=%s', sender.track.kind);
            const senderStreams = sender.createEncodedStreams();
            const readableStream = senderStreams.readableStream;
            const writableStream = senderStreams.writableStream;

            const transformStream = new TransformStream({
                transform: encodeFunction,
            });
            readableStream
                .pipeThrough(transformStream)
                .pipeTo(writableStream);
        }


        function encodeFunction(chunk, controller) {

            const tmp = new DataView(chunk.data);
            if (tmp.getUint32(0) == 1) {  //  h264 start code '0001'
                console.log("h264 =======")
            }
            const newData = new ArrayBuffer(chunk.data.byteLength + 4);
            const newView = new DataView(newData);

            let metadata = new ArrayBuffer(4);
            let metaView = new DataView(metadata);
            metaView.setUint32(0, frames++);

            const data = new Uint8Array(newData);
            data.set(new Uint8Array(chunk.data));
            data.set(new Uint8Array(metadata), chunk.data.byteLength);
            chunk.data = newData;

            controller.enqueue(chunk);
            console.log("Send frame index ===", frames);
        }

下行RTCRtpReceiver 创建 EncodedStreams:

代码语言:javascript
复制
        const transceiver = await pc.addTransceiver("video", {
            direction: "recvonly",
        });

        setupReceiverTransform(transceiver.receiver);


        function setupReceiverTransform(receiver) {
            console.log('receiver kind=%s', receiver.track.kind);
            const receiverStreams = receiver.createEncodedStreams();
            const readableStream = receiverStreams.readableStream;
            const writableStream = receiverStreams.writableStream;

            const transformStream = new TransformStream({
                transform: decodeFunction,
            });
            readableStream
                .pipeThrough(transformStream)
                .pipeTo(writableStream);
        }

        function decodeFunction(chunk, controller) {

            const view = new DataView(chunk.data);
            //last 4 bytes
            const count = view.getUint32(chunk.data.byteLength - 4);
            chunk.data = chunk.data.slice(0, chunk.data.byteLength - 4);
            controller.enqueue(chunk);

            console.log("Receive frame index ===", count);
        }

WebRTC "管道化"

在体验完WebRTC Insertable Streams 之后让我想到的一个词是"管道化", WebRTC的音视频的采集,前处理,后处理,编解码,渲染都可以不再依赖WebRTC的默认实现, 你可以自己实现采集逻辑,使用自己的编码器方案,最后喂给WebRTC编码好的音视频数据。 WebRTC可以只用来做网络传输,重传,FEC, JitterBuffer,NetEQ,然后回调出来远端的音视频数据。WebRTC本身的协议栈可以只当做传输通道来用, 这将极大的扩展WebRTC的使用场景。

WebRTC Insertable Streams 使用场景

1,端到端的加密

这个是WebRTC Insertable Streams 本来设计出来要支持的场景,但端到端加密会为服务端的录制,以及跟现有的直播基础架构互通造成很大的困扰,目前看在国内的服务商不会太跟进端到端加密, 对于海外的场景端到端加密却是一个基本项。

2, 帧级别的信息同步

我们可以在编码后的数据中添加一些meta信息和音视频帧一起发送,在接收端收到音视频帧的时候再把这些meta信息拿出来。

教育场景的白板同步是一个很适合的场景,可以弥补在Web中无法使用SEI的遗憾。

钢琴教学场景中按键信息和音视频完全同步。

VR/AR场景中需要随着音视频同步的摄像头信息,坐标信息等。

远程音视频控制场景中也可以把控制信令打包进音视频信息中。

3,端到端的延迟的统计

WebRTC通话场景中,尤其是经过服务端多跳中转的场景,我们很难去探测端到端的延迟, 这个对我们的数据上报造成很大的困扰。 我们可以在发送端将绝对时间戳打包进帧信息中,在整个链路透传,在播放端把绝对时间戳拿出来进行统计全链路的延迟。

4, 自定义的输入和渲染

WebRTC Insertable Streams 可以让我们自定义采集和编码, 这样的话我们可以绕过WebRTC原本的限制,用WebAudio 采集音频加入自己的降噪, 回声消除的算法, 甚至增加变音的效果,然后再交给WebRTC传输。 同样视频 可以增加自己的采集和编码逻辑, 比如可以对视频增加美颜滤镜, 使用自己优化过的编码器,增加区域编码等。 渲染环节也可以增加渲染逻辑, 比如增加视频边框, 视频叠加等特效。

5,绕过WebRTC音频处理模块,传送高音质音乐音频

第五条应该是第四条的延伸,在web中我们没法关闭WebRTC的APM模块,这就导致我们采集的音频都要经过APM模块的处理, APM模块会对非人声部分进行过滤,对音乐是非常不友好的。 基于我们可以自定义采集音频以及编码,我们只需要把高音质的音乐自己做编码然后通过WebRTC Insertable Streams 的方式喂给WebRTC,我们就可以绕过APM模块的处理,让WebRTC具体传输高品质音乐的能力。(该设想理论上行,但未做进一步验证, 有兴趣的伙伴可以来验证一下。)

上面的几个场景是我立即能想到的, 相信行业内会有各种各样的创新用法出现, 非常期待看到WebRTC Insertable Streams普及之后那些创新的玩法。

还有什么问题?

  • WebRTC Insertable Streams 让我们可以对编码后的音视频的数据进行修改, 但WebRTC 在发送数据的时候是通过RTP来打包的,而RTP打包的时候对码流数据的格式是有要求的,这样就造成你不可能任意的对编码的数据修改,比如H264的码流数据需要以“0001”开始, 如果你修改这个startbit很明显会破坏RTP的分包逻辑,导致传输失败。 所以增加meta信息并不是可以随便加的, 不能破坏WebRTC本身的RTP打包逻辑。 比如H264的场景下,我们可以在整帧数据后面加上自己的一些自定数据。 在播放侧按照相反的逻辑再解析出来。
  • 添加的meta信息不能太多,太多的话有可能影响RTP的分包打包逻辑。
  • 在帧上增加自定义meta信息,会对录制,转推系统造成一定的困扰,在做录制和转推的时候需要在服务侧把相应的meta信息过滤掉。

Show me the Code

我实现了一个WebRTC Insertable stream demo, 服务端使用medooze-media-server, 推流端会把当前视频帧的index打包进编码后的数据帧, 经过服务器的中转,在拉流端把当前视频帧的index解析出来,并打印到console中, 感兴趣的同学可以自己试验一下,项目地址在 https://github.com/notedit/webrtc-insertable-stream-play

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是WebRTC Insertable Streams
  • 基本使用
  • WebRTC "管道化"
  • WebRTC Insertable Streams 使用场景
    • 1,端到端的加密
      • 2, 帧级别的信息同步
        • 3,端到端的延迟的统计
          • 4, 自定义的输入和渲染
            • 5,绕过WebRTC音频处理模块,传送高音质音乐音频
            • 还有什么问题?
            • Show me the Code
            相关产品与服务
            媒体处理
            媒体处理(Media Processing Service,MPS)是智能、强大、全面的多媒体数据处理服务,行业支持最全面的音视频编码标准,基于自研编码内核和AI算法,提供音视频转码和增强、媒体智能、质检评测等能力,帮助您提升媒体质量、降低成本,满足各类场景的音视频处理需求。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档