所在的位置: Web开发 >> HTNL >> WebRTC系列之视频辅流

WebRTC系列之视频辅流

导读:近几年,实时音视频领域越来越热,业界很多音视频引擎都是基于WebRTC进行实现的。本文主要介绍WebRTC在视频辅流上的需求背景以及相关技术实现。

文|陶金亮

网易云信资深客户端开发工程师

WebRTC中的SDP支持两种方案:PlanB方案和UnifiedPlan方案。早期我们使用多PeerConnection的PlanB方案中只支持一条视频流发送,这条视频流,我们称之为”主流”。目前我们使用单PeerConnection的UnifiedPlan方案,新增一条视频辅流,何为视频”辅流”?视频辅流是指第二条视频流,一般用于屏幕共享。

需求背景

随着业务的发展,一路视频流满足不了更多实际业务场景的需求,例如在多人视频聊天、网易会议以及其他在线教育场景下,需要同时发送两路视频流:一路是摄像头流,另一路是屏幕共享流。

但是,目前使用SDK分享屏幕时,采用的是从摄像头采集通道进行屏幕分享。在该方案下,分享者只有一路上行视频流,该场景中要么上行摄像头画面,要么上行屏幕画面,两者是互斥的。

除非实例一个新的SDK专门采集并发送屏幕画面,但实例两个SDK的方案在业务层处理起来十分麻烦且会存在许多问题,例如如何处理两个流间的关系等。

在WebRTC场景中,还存在一种可以单独为屏幕分享开启一路上行视频流的方案,并称之为“辅流(Substream)”。辅流分享即共享者同时发布摄像头画面和屏幕画面两路画面。

另外,有了这个辅流的通道,当设备为新版本iPhone(新版本iPhone具有同时开启前后摄像头的能力)时,也为支持前后2路摄像头发送视频数据奠定了基础。

技术背景

前期SDK的架构设计是一个多PeerConnection的模型,即:一个PeerConnection对应一路音视频流。随着新的SDP(SessionDescriptionProtocol)格式(UnifyPlan)的推出和支持,一个PeerConnection可以对应多路音视频流,即单PeerConnection模型,即基于单PC的架构,允许创建多个Transceiver,用于发送多条视频流。

技术实现

目前视频流主要分为三类:Camera流、屏幕共享流、自定义输入视频流,分别有不同属性:

将Camera流作为主流,支持Simulcast;

将自定义视频输入(非屏幕共享)作为主流,不支持Simulcast;

将屏幕共享作为辅流,不支持Simulcast,有单独的屏幕共享编码策略;

由于iOS屏幕共享的特殊性,其需要通过自定义视频输入的方式来获取视频数据,因此存在如下图所示的流程图:

综上所述:iOS的自定义输入既可以使用主流的通道发送视频(非屏幕共享),也可以使用辅流的通道发送视频(屏幕共享)。

如果是其他平台,例如Mac、Win、Aos等,则会相对简单,摄像头数据和屏幕共享的数据都来自于SDK内部,外部自定义视频输入的数据才来自于外部。

关键类图

上述提到的单PC架构,目前会有2个RtpTransceiver,一个是AudioTransceiver,一个是VideoTransceiver,而辅流的屏幕共享会在新增一个RtpTransceiver。一个VideoRtpSender会包含一个VideoMediaChannel。

辅流改动

实现辅流需要对不同层面都做一些调整以及重构,具体如下:

信令层面需要支持多路视频流,使用mediaType用于区分上述的Camera流(Video)、屏幕共享流(ScreenShare)、自定义视频输入流(externalVideo);

重构跨平台层的Capture和Source的管理;

重构用户和渲染画布的管理,从一个UID对应一个render,过渡到一个UID的sourceId对应一个render,每个UID可能会包含2个sourceId;

互动直播的服务器推流和录制需要支持主流和辅流的合流录制;

主流和辅流的拥塞控制方案的落地;

主流和辅流的码率分配方案的落地;

主流和辅流的编码器性能优化;

PacedSender发送策略、音画同步等方案的调整;

服务器Qos下行码率的分配方案的调整;

辅流相关的统计数据的汇总;

下面介绍在整个过程中,比较重要的几个技术点的实现。

带宽分配

在弱网情况下,需要视频辅流的时候,我们会优先把码率分配给音频流,其次是辅流,最后再分配给主流,整体策略为保辅流。

带宽分配的主要流程如下:

WebRTC的拥塞控制算法GCC(下文简称CC)评估出来的总带宽分配会分给音频流、主流、辅流;

主流内部再由Simulcast模块分配大小流的码率,不开Simulcast时就直接给大流;

具体过程如图所示:

辅流会在上图的基础上再新增一个VideoSendStream。

码率分配

目前关于码率分配的流程如下图所示,概括起来有一下几步:

CC的码率通过transportcontroller传递到Call中;

然后经过BitrateAllocator分配到各个注册的流中(目前就是视频模块);

视频模块拿到分配的码率,分配给fec和重传,剩下来的分配给videoencoderbitrate;

视频编码器模块拿到videoencoderbitrate,按照我们的策略,分配给大流、小流使用;

拥塞控制

为了实现视频辅流的功能,我们需要对拥塞控制进行相关的改动,主要通过以下四个方面的改动来实现:

SDP信令改动

按照RFC,使用"b=modifier:bandwidth-value"的方式来指定建议带宽,有两种modifier(修饰符):

AS:单一媒体带宽;

CT:会话总带宽,表示所有媒体的总带宽;

(RFC:


转载请注明:http://www.guyukameng.com/html/html1/13563.html