如何构建高并发高可用的剧场直播云端混流服务?

2019-07-01 16:23:27 浏览数 (1)

在LiveVideoStack线上交流分享中,爱奇艺技术研究员李晓威分享了基于爱奇艺Hydra平台的剧场直播云端混流方案,重点讲解如何提升WebRTC推流成功率并提升音视频质量,如何做到点播流在客户端和云端同步解码,以及混流服务如何做到高并发、高可用等。

文 / 李晓威

整理 / LiveVideoStack

直播回放

https://www2.tutormeetplus.com/v2/render/playback?mode=playback&token=308d66a1b64d401a9a983db51a59777d

大家好,我是来自爱奇艺的技术研究员李晓威,在爱奇艺主要负责视频通话相关业务的落地与视频混流的技术实践。接下来我将为大家分享爱奇艺的剧场直播云端混流解决方案。

我将从以下三个方面为大家分享今天的话题:

  • 剧场直播背景
  • 云端混流架构
  • 系统优化

我们通过优化提高推流成功率与音视频质量,并尝试构建高并发、高可用的混流服务架构。

1. 技术背景

剧场直播作为我们的技术背景,与主播端设备上的麦克风与摄像头采集主播音视频数据并于本地完成编码后推送至CDN而后分发给在线的观众的游戏直播略有不同,其主要应用场景是主播一边观看某视频,一边对视频内容进行评述;同时客户端用户在观看与主播端相同的视频画面的同时也会听到主播对此视频的评述。相对于游戏直播,剧场直播需要处理两路流,这里就牵扯到混流问题。混流不仅是为向观众呈现更统一的观看体验,更是为了节省带宽占用。但这两路流的类型、协议、传输时间、延迟可能都不同,并且随着网络的抖动,数据流也会发生变化。我们应该如何妥善处理混流问题?能否在客户端进行混流?

答案是可以,但在客户端混流面临许多问题。如果选择高清编码那么混流对上行带宽的要求非常高,一般的Android手机性能无法承受此性能压力;同时对一般的家用带宽而言,上行带宽资源十分有限,编码出的结果也会不尽如人意;除此之外,如果手机端没有一些现成的混流工具,单纯采用录屏方式会造成个人隐私的泄漏,这些都是我们不愿意看到的。

2. 云端混流架构

于是云端混流成为我们着力探索的最佳解决方案,我们与英特尔合作,开发了一套被称为Hydra的云端混流平台,用于构建我们公司内部的视频会议系统,支持个人或多人之间的视频会议,会议桌面投影等功能,同时结合了爱奇艺视频平台的SDK与后台服务使其能够被用于公司的其他业务如爱奇艺的秀场、直播推流等,接下来我将以剧场直播的直播推流为例。我们主要为Android与iOS开发了客户端与其相应的SDK,后台包括SIP呼叫系统、TURN P2P传输与MCU混流,硬件平台则是基于VCA加速卡构建。

来看看这个直播推流的架构,这里面有三个角色,第一个有主播,第二个是我们爱奇艺的云服务,第三个就是观众,我们看看每个角色它承受的有哪些数据,主播呢,第一,他是要去观看一个电影,他要去拉点播流,因为一般可能在移动端,他拉下来那个点播流,它可能自适应的话,它可能不是非常高清的,它可能就是一个720P的。另外一方面,这个还要做评述,评述这个我们是用WebRTC,把它推到我们的那个MCU服务器上面去,

作为Hydra平台最核心的组件,MCU混流器用于剧场直播,在接受WebRTC流的同时还会从点播CDN端拉取同样的点播流,但此点播流的质量要高于主播端点播流;成功拉取两路点播流之后MCU会对其进行混流处理,根据用户终端不同观众的观看需求采取不同的混流方案,例如以主播为主画面,以点播电影为主画面或使两种画面都以高分辨率形式播放。

MCU全称为“多点触控单元”,负责各种类型的数据接入、转码、混流与推送。MCU支持WebRTC、RTMP、F4V等各种直播流点播流与其他数据的接入,同时向外提供向外提供HTTP与SocketIO两种用于信令控制的接口。

3. 系统优化

3.1 网络优化

接下来我将为大家分享我们对于此平台所进行的系统优化,包括为了保证推流成功率、速度与画质,同时降低时延而对网络、业务框架等进行的优化,同时保证客户端与服务器端的流状态同步与高并发下的高可用。

许多用户在使用客户端访问服务时都会遇见各种各样的网络故障,其中一个很重要的原因是跨运营商问题。例如一个中国电信的网络用户访问基于中国移动网络部署的服务器,期间出现服务不稳定的情况似乎难以避免。为解决此问题,MCU集群采取了一系列策略,包括在进行数据接入时提供多种数据接入点。例如如果有一个客户端想要在MCU上推一路WebRTC流,那么他首先需要寻找到数据接入点并向节点调度器发送相应请求,随后节点调度器会分析此访问者的IP并识别这是一个电信客户端,从而在集群中寻找负载最低的电信数据接入点分配给此电信客户端,使其能够向此电信接入点上推数据,从而避免跨运营商的网络接入问题,显著提高信令连接成功的概率与WebRTC推流的质量。根据我们的实际统计,加入了多运营商可使数据连通的成功率达到99%以上,如果将那些不在我们控制之内的其他业务与其节点考虑在内,我们最终的数据连通成功率为96%。除了移动运营商接入点,我们还有针对小规模运营商设立的多线接入BGP机房与针对海外用户部署的海外虚拟机,虽然这会使成本有所提高,但相应的面向更多用户提供高品质服务也能为我们创造更多收益。

在MCU混流过程中,点播流与混合后的流都是内网推拉流。其中我们部署了内网机制与外网机制;而我们自己的服务器主要通过内网拉取这些数据,这样可在提高数据传输成功率的同时显著提升服务访问速度。

除了上述网络优化内容,我们还针对特殊网络环境采取了以下应对措施。有时我们会面临客户端数据无法上传的故障,这是由对称型延迟造成的,面对此情形我们多采用(通用的Turn Server集群也就是P2P数据中转)的解决方案;而面对IPV6的网络适配问题,我们在集群中也部署了ipv6的数据节点,从而实现对ipv6协议的兼容;RTP包的尺寸限制也是一项亟待解决的问题,我们在实际应用当中发现客户端向服务器推送数据时RTP包经常出现推送不成功的故障,其原因在于一些网络的(MTU)尺寸较小,网络中的路由器会将那些超过尺寸限制的包拆分并放弃对主包的负责,这就导致终端或者混流服务器MCU无法接收到一个完整的RTP包,继而导致服务器无法解码,这就要求我们需要有效控制RTP包的尺寸Size;我们在SDK中加入了对于弱网的优化,如断网与自动切网就是为了解决手机端wifi与4G网络切换瞬间服务无法连接MCU的状况,虽然在切换时用户并未有察觉但后台其实已经自动切换并衔接数据链路,服务的用户体验明显提高;而多层重试机制,则是为了应对SDK中的某一层的点对点数据通道出现故障,上一层或多层即可重新与MCU建立连接并恢复推流;备灾域名同样至关重要,一旦支持正式业务的某个机房出现故障或整个集群出现问题,我们即可自动且迅速切换到备灾域名以确保服务不会受到影响。

3.2 推送质量与时延

上文我向大家分享了我们对于网络优化的一些实践探索,接下来我将分享推送质量与时延也就是WebRTC流质量控制。上图展示了WebRTC中RTP传输与RTCP质量反馈的工作机制,我们根据RTCP的反馈尤其是RTCP中往返时延也就是RTP的时间与丢包率,可以估算在这之后的H.264编码器码率应当设置为多少,并根据码率调整分辨率;如果网络环境堪忧那么降低FPS与丢帧处理,或者解码器发现一段长期编码错误并强制要求编码器发送IDR编码等也需要RTCP接收端的编码器控制来实现。而在底层网络传输的另一端也就是RTP发送端存在一种被称为FEC的工作机制,也就是将丢失的包作为冗余并要求其重传。这是WebRTC的一套丢包控制策略,其中包括对码率估计算法的改进,原因是WebRTC默认的码率控制算法更适合平稳网络,而用于WiFi或者其他不稳定的网络环境时,敏感的码率控制算法会造成当出现如大量丢包等情况时估算的码率波动非常之大,我们希望调整控制算法使其预测过程更为平滑。除此之外,改进分辨率调整算法也是我们的一项目标,此项改进主要针对网络环境变差导致的估算码率下降,但分辨率却维持在较高水平,这显然是对产品体验不利的。WebRTC可根据编码器编码QP判断图像质量,QP比较大意味着图像质量较差,分辨率就会被自动降低,相应的QP也会降低;但此项工作机制在一些设备上并不可用,此时我们就需要另一套可根据当前码率估算分辨率的策略,我们已将此策略集成至我们的平台;视频自动启停主要是当网络环境非常糟糕时视频会长期卡顿在某一时间点处,此时系统可以自动暂停视频以减少对于带宽的占用,等待网络状况有所好转时迅速恢复正常播放状态;我们在直播推流的情形,尤其是面对较差网络环境时会关闭NACK,以减少时延的影响。

云端适配是一项针对推流质量与时延的重要优化,有时在一些WebRTC推流模式下会出现视频播放的音量非常小或者对某些Codec的支持不佳的情况,此时就需要我们采取云端适配措施,在SDK初始化时检查云端设备有哪些缺陷并针对不同设备预备相应解决方案。

混合流质量控制取决于WebRTC流与点播流的质量,业务后台会给点播流一个MapData,我们可根据此MapData值获得其含有很多不同分辨率与格式的点播流。对于点播流而言,系统会调用一种分辨率足够高,质量足够好且满足相应格式需求点播流作为混合流的输入,从而确保混合后数据流的质量;对于WebRTC流而言,一定程度上的弱网与低质量在可容忍的范围内,而一旦出现解码出错、大面积马赛克等,系统则会强制要求主播端重新传输IDR以确保WebRTC流能够被正确解码,从而避免混合后出现花屏等问题。混合流的质量控制,其中的混合流可以是多路输出,根据不同个体的喜好,系统后台会为每一个观众匹配合适的业务类型,相应的码率也有所不同。有时当我们面对WebRTC混流画面的分辨率不断变化或点播流的分辨率无法确定时,系统会基于画面纵横比对图像做自适应缩放与裁减;如果出现主播开始休息或切换至后台导致WebRTC流突然中断的情况,那么我们则需要在混合流中加入过场片段以提示观众主播已经下线,确保用户体验不会受到不良影响。

针对时延的优化同样必不可少。主播端采集到的WebRTC流会经过MCU混流送至CDN,最终推送至观众端,整个过程造成的画面时延可达两秒左右。其中的最主要原因是CDN的分发,而MCU混流等其他步骤只占时延的很小一部分。为妥善解决此项问题,我们首先尝试优化主播推流过程,在主播端向MCU发送连接请求之前提前预判获知IP等关键配置,同时过滤ICE中的一些不必要的IP从而加快整个点对点握手过程;除此之外,我们还尝试建立DTRS通道以传递SRTP密钥。每当进行一个DTLS握手过程就生成一个DTLS密钥,一些密钥的生成时间很长,使用效率更高的算法替换会节省许多时间。

为降低混流造成的时延,我们减小缓冲存储使得出现时延时通过丢包降低其造成的影响;除此之外我们部署了一套针对编码器的控制策略,也就是通过合理配置H.264 Codec来降低时延。

观众端对于GOP的设置十分敏感,如果GOP设置过大那么观众需要等待很长时间才能开播,因此我们建议将GOP设置为2秒左右,确保一般用户等待两秒左右即可获得第一个关键帧。

3.3 流状态同步

流进度同步主要是为了应对点播流场景下,当主播快进或者跳过视频的某一部分时,观众端也会同步接收到快进或跳过之后的流数据,还有当主播暂停视频并截图分析,或者调整音量时,观众端也可同步相应调整。而在直播流场景下,主播有时在直播过程中不想让观众看到自己的画面,会将视频流关闭,此时我们也需要在混流时用相应贴图来取代缺少的一路视频流。

流进度同步的第一项关键点在于点播流的分片下载,爱奇艺的在线视频流一般会被分为很小的片段而非一个完整的视频,这样做是为了方便在CDN分发时,不同的终端用户可就近选择CDN下载相应的片段;如果是多片段那么就意味着完成一个片段的下载需要重新建立连接,可能会由于建立连接的过程中一部分视频片段的缺失造成视频的短暂卡顿,一般情况下我们会建立一个缓冲区并保证其中预存的帧数目至少满足10分钟左右的播放需求,从而避免重新建立连接时用户观看体验受到影响。

缓存视频流之后,平台还需要按照时间戳按照一定周期取相应的帧至解码器进行解码,以确保最终视频按照25FPS的帧率解码与播放,这就是我们所说的点播流帧消费节奏控制。

在前文我们介绍了,虽然客户端与服务器的点播流在内容上完全一致,但清晰度并不相同,片源的不同导致二者的关键帧位置也不经相同,这就需要我们通过快进等方式精准同步关键帧;信令不可靠也至关重要,一些代表主播端操作的信令并非主播端的实际操作,可能是由于网络环境变差导致,此时就需要我们周期性地检查每个环节的状态并及时做出调整。

A/V Sync是流状态同步当中的一项重要内容,其包含以下三种情况:

  • 点播流A/V 同步

由于Audio流与Video流的时间戳起点都是0且都以毫秒为单位,每一帧的时间戳间隔均匀,我们只需按照时间戳同步Video与Audio 的jitter buffer。

  • 直播流A/V 同步

由于WebRTC直播流基于RTP包,而Audio与Video第一帧的RTP包时间戳一般不同,且在传输过程中第一个包开始时时间戳上就会被添加一个随机数,这这些都意味着当收到包时MCU难以将其同步处理。此时就需要借助RTCP SR,将NTP与RTP时间戳对齐以方便MCU同步处理Audio流与Video流。

  • 点播流与直播流之间的同步

针对点播流的播放,我们尝试尽可能将播放进度差异最小化;而针对直播流我们则是降低传输时延,通过以上策略尽可能减轻用户对上述操作的感知;针对混流过程,我们则采取积极的缓冲区丢帧策略与混流器匀速消费等措施尽量保证画面的平滑。

3.4 高并发、高可用

利用MCU实现高并发集群,首先需要混流服务器。这是一个分布式的集群,其中的进程都相对独立,且进程与进程之间通过IP和端口实现通讯,可随便部署于某台机器,同时支持节点的热插拔;混流服务器的另外一项特性是负载均衡,根据网络节点的调度情况实时汇报网络负载,包括上行与下行带宽、GPU与CPU状态等;节点调度器在了解每一个节点的负载情况之后就能在获得新任务请求时知道哪些节点处于空闲状态并科学分配节点负载,从而保证最终所有节点的负载均衡;对于整个视频编码行业来说,硬件加速的潜力十分巨大,所以我们使用了非常多的视频编解码卡以加快处理速度并显著降低成本。

为有效应对高并发状况并确保整个网络的高可用,我们需要此集群能够适应各种网络突发状况。客户端通过域名访问我们的业务,而此域名并非直接来自我们实际的服务器IP而是来自虚拟IP;通过虚拟IP代替真实IP,其下有一系列集群:工作集群主要用于处理一般性任务,临时集群则会在主播上线时投入使用,而备灾集群则是为了应对突发状况。其中的工作集群由于在大部分时间中都会投入使用,其掌握最丰富的资源;临时集群与备灾集群则被分配了适量的资源。假设最底层的工作集群中有关键进程出现中断,那么监控机制会立即作出反应并启动备用进程接管工作来维持服务的稳定;客户端的SDK一旦发现某一域名无法访问系统就可以自动切至备灾域名,同时触发报警以通知运维人员及时做出干预这种异常自适应可极大提高平台整体的稳定性。同时我们也进行了拨测,通过对集群的周期性波测来确保报警的及时与有效;基础监控同样必不可少,其主要职责是监控服务器的CPU、网络、磁盘等相关参数,一旦有某一参数超过我们设定的阈值,系统就会报警以通知运维人员排查相关问题;借助业务统计与日志投递,系统会定期调查业务的成功率并将相关信息通过电子邮件等形式告知我们,使我们及时获知整个平台的运行情况,并在业务成功率出现异常时第一时间作出干预。

LiveVideoStack 招募

LiveVideoStack正在招募编辑/记者/运营,与全球顶尖多媒及技术专家和LiveVideoStack年轻的伙伴一起,推动多媒体技术生态发展。了解岗位信息请在BOSS直聘上搜索“LiveVideoStack”,或通过微信“Tony_Bao_”与主编包研交流。

sdn

0 人点赞