蚂蚁实时视频通话技术和实践-程序员宅基地

技术标签: 5g  移动开发  数据库  

image

小叽导读:从电影、电视到电脑、手机,人们获取视频信息的方式越来越方便、快捷。时下较热门的视频通话、互动直播时长占据了当下年轻人很大一部分的生活时间,可见实时视频技术在生活中的重要性。今天,蚂蚁金服高级技术专家樟松将为我们揭秘“蚂蚁实时视频通话系统”的技术架构及特点,讲述实时视频通话的底层技术以及其运用。

引子

直播作为一种品牌推广、业务拓展的便捷运营工具,最近几年得到爆发式发展,直播技术也相应地得到快速升级,从单纯的广播式向实时互动式演进,即连麦互动直播。

ARTVCS:蚂蚁实时视频通话系统,从P2P的双人视频通话开始向多人视频通话和连麦直播方向融合、演进。

技术选型

场景和核心需求基本明确,该选择什么技术路线呢?

我们先回顾连麦互动直播场景,主播在直播过程中,(可能多位)嘉宾连线主播,进入聊天室,与主播进行视频通话,其他粉丝观看主播和嘉宾实时互动的视频画面。

显然,从技术层面来看,连麦互动直播就是对多人实时视频会议进行现场直播,可清晰地分为两个部分:视频会议系统和直播系统。两部分都要求音频和视频的质量要高,但也有不同的侧重点,连麦对接入的快捷性、视频通话的低时延比较敏感;直播要求接入容量大、可扩展。

另外,作为影响范围大的传播工具,对连麦直播的内容进行安全监控也必不可少。

连麦直播的典型场景是主播邀请其它主播,或者粉丝主动加入,一起互动。也就是说,除了主播外,其它参与者具有动态不确定性,互动多方的网络线路质量就参差不齐,有准备的主播的网络质量一般还能保证,但其它参与者的接入网络就难控制了。

为此,弱网下高效地使用带宽,确保视频质量尤其重要。众所周知,提供传输能力的协议有TCP和UDP,那么该如何选择?

在弱网环境下,TCP协议栈的超时重传算法基于丢包,在路由器丢包发生后才触发,同时拥塞避免机制将急剧降低吞吐量,传统的TCP甚至达到50%,然后再线性试探性提升发包速度,直到又出现丢包,总体耗时较长。在遇到网络抖动、瓶颈时,会呈现锯齿状的流量走势,这直接影响连麦互动的实时性和视频质量。而UDP没有拥塞控制,这给我们很大的定制优化的发挥空间。所以,对于连麦互动的场景,使用基于UDP的RTP/RTCP来传输和控制音视频流比较合适。

WebRTC是基于UDP视频通话的开源框架,在行业内得到了广泛的支持和应用,提供了音视频采集、编解码、前后处理、网络传输、渲染播放的整体框架,最重要的是它遵循BSD-style license。显然,WebRTC具备作为连麦互动的基本特性,而且在P2P音视频远程开户项目中,我们积累了许多WebRTC的经验,项目组最终决定采用WebRTC来构建连麦互动(视频会议),但将一个粗放型的框架打造成一个工业级别的技术平台,中间我们做了许多工作。

系统架构

视频会议的通信架构有两种方式:P2P网状直连和P2SP,P2SP也分为在P端混音和在S端混音,而对于多路视频流,S端也分为简单中转多路流和先拼接合并后再转发一路流。

直播推流方式也分为在P端(主播端)推流和在S端推流。

对于连麦互动直播而言,是视频会议和推流的组合,以上几种方式可以衍生出十几种架构,它们均有自己的优点和缺点,也有一定的适用范围。我们要做的是,架构要灵活支撑这种组合,以适应各种应用场景(用户规模、功能特性)和业务各发展阶段的资源规划。比如,有的业务属于创新项目,启动初期希望多使用手机端的资源,以节省成本,待业务达到规模时,再向服务端资源倾斜,同时支撑更多的连麦人数。

本文主要介绍的是一种较典型的架构:采用P2SP构建视频会议(连麦互动);再在服务端(S端)通过RTMP协议推流到直播系统。

image

连麦互动直播系统由视频会议系统、直播系统、运营支撑平台组成。

视频会议系统由手机端或web端SDK、房间信令服务、穿透辅助服务、媒体流中继服务、视频会议控制服务组成。其中视频会议控制服务是多路音频率、视频流的处理中枢。基本模块包括音视频流的传输控制、编解码、ICE、会话管理、音视频处理,增强模块包括录像,可插拔旁路模块用于在云端接入直播系统。

直播系统一般由直播房间管理、(直播推流服务)中心节点、拉流边缘节点组成。

质量监控系统主要提供服务节点健康状况监控、媒体参数控制、在线音视频质量评估、业务数据统计等能力。

架构特点

信令逻辑和信令传输通道松耦合,信令通道可以是websocket、rpc、各业务自有消息通道等。这样,我们重点关注信令本身的协议设计和端到端信令传输可靠性保障,方便与各个业务的自有账号系统、消息系统进行集成。

模块化设计,一个技术平台灵活支撑多种实时视频通话场景和直播场景,包括一对一视频通话、多对多视频会议、连麦直播。

关键技术和优化

WebRTC虽然提供了一个视频通话的基本框架,但要在国内网络环境下很好地支撑一个业务场景,仍然有许多待适配、定制、完善和增强的工作要做,下面列出我们在工程化过程中遇到的诸多问题中的几个,仅仅是冰山一角。

手机端SDK瘦身

下载WebRTC整体工程,包括基础源码、依赖库源码、编译工具,ios平台版的源码总共达到5g,android由于依赖ndk,就更大了。编译成静态库,经过strip处理后arm64平台的静态库达到20m,这是link成可执行的app之前的大小,实际link后净增量没这么多,但仍然显著的增加了TEXT段大小,遂改为framework动态库方式,为何要尝试动态库集成方式呢?主要原因是:

1.动态库不增加主二进制TEXT段大小,避免了超过60m的苹果审核风险。

2.视频通话功能一般不是启动时必须的组件,动态库可按需延后载入,不需要在启动时载入,避免拖累钱包的启动速度。

由于动态库要确保被正确调用,需要保留对外开放函数的符号信息。而且不能像静态库那样可以在link时,被主程序按需抽取被引用到的函数,实际上动态库可能包含有主程序非需要的对象或函数,理论上比静态库净增量还大,编译后果然达到5.1M,虽然未增加主程序TEXT段大小,但增加了整体app包大小,这会影响下载和升级app的速度。分析WebRTC哪些模块可以裁减,哪些模块可以替换,哪些模块可以复用主包里面的模块(就是动态库反向使用主app进程里的符号)。经过庖丁解牛,自研替换,定制优化,在不断增加新功能新特性的同时,力求让包大小进一步减少。

信令高可靠

WebRTC没有对信令进行规范化,也未考虑高可靠性,其设计和实现要我们自己根据业务场景灵活定制。信令作为视频通话的指令,信令的传输可靠性直接影响连麦的成功率和速度,要打造成工业强度的技术平台,须持续完善它。

端到端信令传输时,以下几种情况均曾碰到:

消息超时:终端a发指令到终端b,端b在较长时间后才收到。

消息丢失:终端a发指令到终端b,端b未收到。

消息乱序,终端a发送了s1、s2、s3的信令序列,手机端b收到的序列变成了s1、s3、s2

消息重复:终端a发指令到终端b,端a超时重发指令,或中间节点超时重传,b端最终收到两条相同内容的指令。

这里的端到端,是指传递消息的两个endpoint,比如ios手机用户、android手机用户、web用户、视频会议控制服务节点均是端。任何两个端之间可能要经过一个或多个中间节点,比如room服务节点、消息推送服务节点。端到端的信令可靠性,就是指信令从一个端能可靠的、尽快的传递到另外一端,另外一端能正确的处理信令。

为了解决以上列出的4种情况,我们采用了三层传输可靠性设计。

image

上层即端-端层,负责端到端信令传输可靠性,各个端具备三项基础能力:

1、超时重发。缓存已经发送的信令,当超时时间之前仍然未收到信令确认,就重新发送此信令。为了简化信令交互,信令确认尽量采用信令之间的先后关系来间接确认,缺省情况下才使用对信令的直接确认响应。比如,端a向端b发送offer指令,端b应该向端a响应answer指令,answer指令就可以看作是端b对端a的信令确认,那么端a如何确认这个来自端b的answer指令呢?由于其它指令(candidate)与answer没有强后序依赖关系,就只能采用缺省的方法:直接确认响应,即端a向端b发送一个ack answer消息,表示已经收到了answer。比较关键的,超时时间如何确定?为避免不必要的信令重发或用户长时间等待,这里采用动态超时时间。为避免引发雪崩效应,重发次数一般限定为3次。

2、过滤重复和幂等操作。端缓存已经收到的信令,当收到信令时,首先检查缓存区里面是否存在,如果存在,就直接丢弃。否则,可能导致状态参数重新复位,甚至程序crash。那么,如何界定重复?端发送任何一个新信令时,均相应产生一个唯一的signaling-message-id与之绑定,重发信令时,信令消息里的signaling-message-id保持不变。幂等操作也是对抗重播的一种方法,比较适于分布式前置无状态节点架构,在数据库层确保操作是幂等的。由于端内部有复杂的状态机,且是集中式的,数据的生命周期较短,适合使用基于缓存的过滤方法来排重。

3、乱序纠正。视频通话的各个信令之间有的是先后依赖关系,有的是并行关系,用信令关系图来描述信令的约束关系。信令关系与代码逻辑松耦合,增强可扩展性。程序启动时初始化信令关系图,端收到信令时,首先查询信令关系图,是否满足约束条件,如果违背,表明出现了乱序,暂时缓存在信令关系图里面节点的缓冲队列里面。如果满足约束条件,就看看前序节点是否有缓冲的信令,如果存在,就执行缓冲信令,标记缓冲信令为已执行状态,然后再执行此指令,执行完毕后同样标记此信令为已执行状态。

中层即节点-节点层,负责相邻节点间请求可靠性。

这个层面就是我们常使用的一问一答方式,发生在任何两个相邻节点之间,比如手机端与房间服务节点、房间服务节点与手机端、房间服务节点与视频会议控制服务节点之间。一旦相邻节点间建立tcp连接,不管是rpc还是push,或者wss,一方发出请求或消息推送,另外一方就要响应,这个响应一般隐含对请求或消息推送的确认。这样做的好处了,至少确保了这两个节点之间的请求或消息推送是尽可能可靠的,即使失败了,也能立即反馈错误,在端对端这个层面(即前面描述的上层)能更及时地发现中间节点出现的异常,如果没有这层可靠性保证,例如push消息时,消息丢失了却未发现,虽然端到端指令传输层的可靠性机制也能发现指令传输异常,但这个时间一般要更长。可见,相邻节点间请求可靠性是端到端指令传输层的可靠性的补充和增强,有利于早发现异常,也利于避免不必要的指令级的重传。

低层即通道层,负责通道里链路连接可靠性,其容错处理分三种情况,一种是socket遇到链路异常,主动抛出异常事件,通道层捕获该类事件,然后进行重新连接;一种是收发数据包时socket返回错误,比如EPIPE、ECONNRESET;一种是socket未抛出异常事件,发包也正常,但对方节点未收到包,连接处于僵死状态,一般发生在中间设备( NAT服务器)出现了异常,这种情况,需要采用心跳机制来主动探测。对于以上三种情况,通道层都要重新建立连接,以尝试恢复链路,力求对上层提供一个透明的链路可靠的通道。

负载均衡和网络加速

WebRTC设计的初衷是通过NAT穿透技术,让通信的双方直接传输音视频流或数据流,技术栈主要驻留在终端里,服务端的能力非常薄弱。但事实上,连麦的用户可能属于不同的网络运营商(移动、联通、电信),不同的网络运营商的用户彼此直连时,网络质量会受到网络运营商间网关瓶颈影响,为了加速各个用户之间的音视频数据传输,另外,还有安全监管要求录像存档,均需要通过中继服务集群进行中转。

中继服务集群可以看作一个软件定义的网络,通过路由策略配置、负载均衡策略、内外网权限配置、专线代理配置,中继服务负载均衡模块根据网络类型、距离,为端选择一个接入速度最优的中继服务节点,音视频数据进入中继服务节点后,中继服务再根据实时连通性和测速数据,找到一条最优的链路,采用forwarding address技术,转送到下一单元(另外一个中继服务节点或视频会议控制服务节点)。

在一个视频开户项目中,我们采用中继服务集群实现了坐席和支付宝用户就近接入中继服务节点,如果中继服务节点是不同的节点,彼此之间通过内网中转音视频流。明显提升了视频见证的成功率和画面质量。

改进的拥塞控制算法

拥塞控制可定制是使用UDP的根本原因,WebRTC已经实现了基本的带宽估计算法和码率控制算法,比如基于延迟的带宽评估(delay-based estimate),和基于丢包率的带宽评估(lossrate-based estimate),特别是基于延迟的带宽评估算法比较合适音视频流传输,此算法通过分析数据包之间的延时来预测拥塞情况,尝试在拥塞严重到了路由器开始丢弃数据包之前就检测出来,可以在丢包发生前就能评估当前可用的带宽,这比TCP基于实际丢包发生后,再紧急降速再逐步试探性恢复的机制作用下的网速更平滑。

用网络损伤仪模拟各种网络环境,发现在正常网络环境下总体运行的很好,但在弱网环境下欠佳,主要有:

1.带宽评估有时不准确。

2.网络恢复后,带宽评估值提速缓慢。

分析源码发现,当弱网状态下,为降低RTCP包对带宽的消耗,会降低SR包和RR包的发送频率,发送端基于SR和RR计算的丢包率lossRate更新频率就缓慢,远低于拥塞控制模块的评估发送端码率的频率,按照基于丢包率的码率评估算法,在lossRate更新之前,会持续按一定比例递减,很快降低到最小发送码率,缺省的最小发送码率却只有10kbps,而当网络正常后,delay-based BWE算法无论是加法模式还是乘法模式的增长因子均较保守,lossRate的增长速度也较慢,导致码率评估值贴近实际带宽需要40秒左右。经过优化算法和重新调整参数,恢复时间大幅降低。在新版本里,使用了TrendlineFilter算法,能够比KalmanFilter算法更快速更准确估计出实时网络带宽。

码率自适应策略

网络波动不可避免,当进入弱网状态时,确保画面清晰度,还是流畅度,不同业务场景有不同的诉求,WebRTC采用的策略是在清晰度和流畅度之间平衡,在弱网下虽然较流畅,但块效应严重,画面非常模糊。原因是编码模块,根据编码跳帧统计、编码耗时相对视频捕捉耗时比例、码率实际输出与目标码率的偏离度等指标,对输入视频进行了流量控制 ,逐步降低分辨率直到最低级别192x144,,而帧率虽也有所降低,但幅度不大,仍然维持20fps左右。既然在带宽有限的情况下,画质和流畅度不可兼得,必须有所取舍,根据业务场景要求,我们对WebRTC部分模块进行了修改,实现了画质优先策略和接口。

对于画质优先自适应策略,主要流程是这样的:码率评估模块实时评估到网络变化时,如果是网速降低了,立即将评估的目标带宽码率反馈给码率分配模块,预留应分配给冗余保护的带宽,剩下的就是编码器的目标码率,并反馈给视频编码器,而将目标带宽码率反馈RTP平滑发送模块,为了从管线的源头就自适应带宽,我们也将目标带宽码率反馈至视频采集模块,视频采集模块根据实时目标带宽码率动态调整帧率,将VideoFrame输出给编码器, 编码器再根据目标编码码率微调帧率,极端情况下,输出的帧率只有1fps,甚至几秒1帧,把宝贵的带宽让给音频流。但确保分辨率不要降到底挡,保证画质清晰,经过图像实验室专项测试,可以看到即使在弱网环境下清晰度指标SRF可稳定在350。

image

未来展望

音视频质量提升:支持H265编码,OPUS FEC增强,对实时视频进行超分辨率处理。

跨界融合:与AR/VR/AI/IoT技术融合,创造更好玩的应用场景。

网络传输QoS:网络波动模型识别,建立网络波动模型,评估到网络带宽变化时,按照波动数学模型进行更精准地加速或降速。

场景落地

ARTVCS:蚂蚁实时视频通话系统,作为一个融合了P2P视频通话、多人视频会议、连麦互动的实时通信开放技术平台,面向的业务场景非常广泛。

首先在闲鱼app里得到应用,在闲鱼上,卖家在进行二手物品转让时,买家通过实时视频通话了解二手物品的实物外观、功能、成色,进行远程识货,避免货不对板。视频通话技术还应用到闲鱼app里的英语在线陪练场景,付费后,学生可以与英语老师通过远程视频直接对话,练习英语口语。

image

ARTVCS上线后,得益于平台化程度的进一步提高,多个业务场景已经在快捷地接入中。

未来,还有较多其它潜在的应用场景:

金融行业里的远程业务办理

证券行业里的远程开户、面签

保险行业里的事故车辆远程视频勘查和理赔

物联网领域里远程视频实时操控

游戏场景里玩家组队实时对讲

企业里的视频会议

教育培训领域里的直播、连麦

医疗领域里的远程诊断

电商领域里的连麦互动直播

智慧家居行业里的远程监控

自动驾驶物流车里的平行驾驶

游乐行业里的在线娃娃机
……

结尾压轴

如果你对最前沿的实时多媒体通信技术充满热情,希望一起来开发牛逼的P2P视频通话引擎和牛逼的服务端视频会议控制引擎,请联系[email protected]

未来,我们打算将此视频通话能力以支付宝小程序接口方式输出,欢迎生态小伙伴们接入,助力实时视频通话类场景的快速落地。

原文发布时间为:2018-11-14
本文作者:樟松
本文来自云栖社区合作伙伴“阿里巴巴机器智能”,了解相关信息可以关注“ 阿里巴巴机器智能”。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34319374/article/details/89558338

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法