直播技术
# 直播技术的探讨
# 一. 关键技术
- 边缘计算容器
- 智能调度
- 智能路由与多链路备份
- 虚拟组网技术
- 终端接入协议类QUIC统一等等
直播系统大都支持 RTMP 和 HLS,较大的公司也会支持 RTSP,比如抖音就兼容 RTSP 的直播 当观众端想看某个房间里的节目时,首先也要向信令服务器发消息,不过发送的不是“创建房间” 消息了,而是 “加入房间”; 服务端收到该信令后,会根据用户所在地区,分配一个与它最接近的“CDN 边缘节点”; 观众客户端 收到该地址后,就可以从该地址拉取媒体流了。 在直播系统中,一般推流都使用的 RTMP 协议,而拉流可以选择使用 RTMP 协议或者 HLS 协议。
# 二.直播协议选择
流媒体接入,也就是推流,应该使用 RTMP 协议。 流媒体系统内部分发使用 RTMP 协议。因为内网系统网络状况好,使用 RTMP 更能发挥它的高效本领。 在 PC 上,尽量使用 RTMP 协议,因为 PC 基本都安装了 Flash 播放器,直播效果要好很多。 移动端的网页播放器最好使用 HLS 协议。 iOS 要使用 HLS 协议,因为不支持 RTMP 协议。 点播系统最好使用 HLS 协议。因为点播没有实时互动需求,延迟大一些是可以接受的,并且可以在浏览器上直接观看。
综合 RTMP、HLS、HTTP-FLV 和 WebRTC 四者来看,平台适配性上,且实现效果差不多的情况下,RTMP、HLS 要比 HTTP-FLV 和 WebRTC 更优秀。其次从市场环境上来说,经过了很多年的发展和磨合,很多的 CDN 大厂已经非常完美的支持 RTMP 和 HLS 了,CDN 不会对稳定盈利的系统轻易做出变化。同样,越来越多的公司来用 RTMP 和 HLS,那么就造成 CDN 与 RTMP、CDN 与 HLS 之间的优化和兼容更强了。这是一个循环过程,一般 CDN 公司不会轻易去打破。所以目前直播还是以 RTMP 和 HLS 为主。
RTMP,全称 Real Time Messaging Protocol ,即实时消息协议。但它实际上 并不能做到真正的实时,一般情况下可以控制在 3 秒左右的延迟,底层是基于TCP协议,所以不会丢包,乱序,非常可靠。 HLS,全称 HTTP Live Streaming,是苹果公司实现的基于 HTTP 的流媒体传输协议。它可以支持流媒体的直播和点播,主要应用在 iOS 系统和 HTML5 网页播放器中。 其原理是是将多媒体文件或直接流进行切片,形成一堆的 ts 文件和 m3u8 索引文件并保存到磁盘,在我们后面的实战中将会看到。 当播放器获取 HLS 流时,它首先根据时间戳,通过 HTTP 服务,从 m3u8 索引文件获取最新的ts 视频文件切片地址,然后再通过 HTTP 协议将它们下载并缓存起来。当播放器播放 HLS 流时,播放线程会从缓冲区中读出数据并进行播放。 所以HLS延迟性会更高。
# 三. FFmpeg技术
通过 FFmpeg 命令行我们能做到的事情有很多,包括: 1)列出支持的格式 2)剪切一段媒体文件 3)提取一个视频文件中的音频文件 4)从 MP4 文件中抽取视频流导出为裸的 H264 数据 5)视频静音,即只保留视频 6)使用 AAC 音频数据和 H264 视频生成 MP4 文件 7)音频格式转换 8)从 WAV 音频文件中导出 PCM 裸数据 9)将一个 MP4 的文件转换为一个 GIF 动图 10)使用一组图片生成 gif 11)淡入效果器使用 12)淡出效果器使用 13)将两路声音合并,比如加背景音乐 14)为视频添加水印效果 15)视频提亮效果器 16)视频旋转效果器的使用 17)视频裁剪效果器的使用 18)将一段视频推送到流媒体服务器上 19)将流媒体服务器上的流 dump 到本地 20)将两个音频文件以两路流的形式封装到一个文件中
# 四. 在万人直播中的一些思考
# 1.先将直播消息类型划分
- 按照直播业务特性,大概可以这样划分: 1)按照接收方维度进行划分; 2)按照直播间消息业务类型进行划分; 3)按照消息的优先级进行划分; 4)按照消息的存储方式进行划分等等。
- 按照接收方维度,可以这样划分: 1)点对点消息(单聊消息); 2)直播间消息(群聊消息); 3)广播消息(系统消息)。
- 按照具体的业务场景,可以这样进行划分: 1)礼物消息; 2)公屏消息; 3)PK 消息; 4)业务通知类消息
# 2.要划分直播消息优先级
为什么要做消息的优先级划分呢? 如果一个直播间每秒只能渲染 15~20 个消息,一个热点直播间一秒钟产生的消息量大于 20 条或者更多,如果不做消息优先级的控制,直接实时分发消息,那么导致的结果就是直播间公屏客户端渲 染卡顿,礼物弹框渲染过快,用户观看体验大幅下降。所以我们要针对不同业务类型的消息,给出不同的消息优先级。
一般来说,礼物消息大于公屏消息,同等业务类型的消息,大额礼物的消息优先级又大于小额礼物的消息,高等级用户的公屏消息优先级高于低等级用户或者匿名用户的公屏消息,在做业务消息分发的时候,需要根据实际的消息优先级,选择性地进行消息准确地分发
# 3.直播间IM消息分发策略
消息的分发一般遵循的原则是:
- 单聊、群聊、广播消息调用 IM 长连接分发; 直播间用户行为产生的消息通过长连接分发还是短轮询分发,都是由直播业务服务器控制,由当时的系统 情况和直播间人数等一系列条件来决定
- 消息优先级 直播间中有进出场消息、文本消息、礼物消息和公屏消息等多种多样消息。 消息的重要程度不一样,需要为每个消息设定相应的优先级。 不同优先级的消息放在不同的消息队列中,高优先级的消息优先发送给客户端,消息堆积超过限制时,丢弃最早、低优先级的消息。 直播间消息发送时:根据直播间成员分片通知对应的消息发送服务,再把消息分别下发给分片中对应的每一个用户。为了实时、高效地把直播间消息下发给用户,当用户有多条未接收消息时,下发服务采用批量下发的方式将多条消息发送给用户。
- 消息压缩 分发直播间消息的时候,需要注意消息体的大小。 如果某一个时刻,分发消息的数量比较大,或者同一个消息在做群播场景 的时候,群播的用户比较多,IM 连接层的机房的出口带宽就会成为消息分发的 瓶颈。 一般的优化手段从两方面着手,一是使用序列化后体积较小的框架,比如 protobuf,另外相同类型的消息进行可以合并发送。
- 批量消息 所谓批量消息,也就是多个消息进行合并发送。举个例子每秒分发 10~20 个消息,如果每秒中,业务服务器积累到的消息大于 10~20 个,那就按照消息的优先级进行丢弃。如果这 10~20 个消息的优先级都比较高,例如都是礼物类型的消息,则将消息放在后一个消息块进行发送。 这样做的好处如下: 1)减少传输消息头:合并消息,可以减少传输多余的消息头,多个消息一 起发送,在自定义的 TCP 传输协议中,可以共用消息头,进一步减少消息字节 数大小; 2)防止消息风暴:直播业务服务器可以很方便的控制消息分发的速度,不 会无限制的分发消息到直播客户端,客户端无法处理如此多的消息;3)提升用户体验:直播间的消息因为流速正常,渲染的节奏比较均匀,会带来很好的用户直播体验,整个直播效果会很流畅。
- 消息丢弃 例如:在游戏直播中,有出现比较精彩瞬间的时候,评论公屏数会瞬间增加,同时送低价值的礼物的消息也会瞬间增加很多,用来表示对自己选手精彩操作的支持,那么服务器通过 IM 长连接或者 http 短轮询每秒分发的消息数就会数千或者上万。
一瞬间的消息突增,会导致客户端出现如下几个问题: 1)客户端通过长连接获取的消息突增,下行带宽压力突增,其他业务可能 会受到影响; 2)客户端无法快速处理渲染如此多的礼物和公屏消息,CPU 压力突增,音 视频处理也会受到影响; 3)因消息存在积压,导致会展示过期已久消息的可能,用户体验会下降。
所以:因为这些原因,消息是存在丢弃的必要的。 举一个简单的例子:礼物的优先级一定是高于公屏消息的,PK 进度条的消 息一定是高于全网广播类消息的,高价值礼物的消息又高于低价值礼物的消息。
所以在开发实践中,可以做如下的控制: 1)选择性丢弃低优先级消息、选择性丢弃“老”消息; 2)消息补偿:在业务开发中,消息的设计中,尽量地让后续到达的消息能够包含前续到达的消息。
举个例子:9 点 10 的消息,主播 A 和主播 B 的 PK 值是 20 比 10,到 9 点11 分时,主播 A 又赢下 2 分,这个时候消息的分发有两种选择;直接分发增量消息 2:0,由客户端做累加(20+2 :10+0),另一种选择是分发 PK 消息就是 22 比 10。考虑到存在消息因为网络颤抖或者前置消息丢弃,导致消息丢失,所以选择分发 22 比 10 的消息会更合适。
# 五.万人在线直播技术架构
大型直播音视频架构由直播客户端、信令服务器、支撑业务系统和 CDN 网络这几部分组成。
直播客户端主要包括音视频数据的采集、编码、推流、拉流、解码与播放这几个功能。而且要分开主播使用的客户端,包括音视频数据采集、编码和推流功能和观众使用的客户端,包括拉流、解码与渲染(播放)功能。
支撑业务系统需要完成转码录制转推,这包括整个 RTC 实时画面合成和转码的工作,CDN 转推以及云端录制保存。还包括监控、计费、接入以及增值业务四个模块。监控部分是针对线上服务运营情况的监测,方便我们与用户定位问题并优化产品。接入服务主要负责用户的就近接入以及负载均衡。
CDN 网络,主要用于媒体数据的分发。不可能所有的用户都直接访问直播服务器,一定会借助 CDN,而且是多家 CDN。在使用它们时,按照一定的比例将“节目”分配到不同的 CDN 网络上。
# 1.万人直播性能痛点
万人直播互动的难点有很多,经常遇到或普遍关注的主要问题:大流量、高并发以及用户分布。高并发的解决手段和大型网站没有太大差别。
大流量:实时互动本身就是一种大流量的数据交互活动,而万人直播则是在小规模直播互动形式的基础上进行了万级别的末端放大或中间链路的放大,因此其数据流量是非常庞大的,尤其是在拉流端。
用户分布:用户分布是多人实时活动中比较常见的一个问题。用户分布于全国各地,面对不同的运营商、不同的网络质量,就近接入该如何为每个用户提供更优质的观看体验。
比如负载均衡用来将流量分散,其次是就近接入,为用户选择最优质的节点进行调度。流量隔离以及分区保护也是应对大流量常用的手段。 流量隔离是指服务器或者用户的业务可能会受到攻击和流量暴增,此时我们需要对存在问题的区域进行流量隔离,以降低风险。分区保护是指可能存在部分用户对分区
有一定需求(如活动产生的流量暴增),此时可能造成系统的不稳定,就需要 对这一特定区域进行隔离,单独进行容量扩容,同时保证不会对其他用户服务 产生影响。
# 2. 推流接入
推流部分的流量一般不会很大,但是推流端影响的则是所有观众的体验。 因此在推流端一定要保证接入质量的稳定,以及链路容灾的备份。推流端接入 可以通过 DNS 进行分区后,分配多个接入地址,然后进行动态的 Ping 速,选择 最快的地址为主接入,其余的为备份。 多路径接入:推流的边缘节点由多个接入点作为备份,如果一个点发生故 障,推流端可以通过另外的节点继续进行推流,中断切换影响最多仅有秒级别。
# 3.拉流端
从推流端到拉流端一般会使用智能路由的路由转发系统,由多个路由节点 进行各个区域路由转发的操作,同时也可进行几个节点间的灾备。路由节点的 链路依旧要进行适当的冗余,链路一般会选择最优路径以及次优路径作为传输 路径。延时、丢包是其中比较关键的衡量指标,跳数与成本两项指标也会占有 一定权重,综合计算得出一条最优路径。所有的数据包经过路由转发后都会通 过最优路径优先到达另外的边缘。次优路径则会作为灾备或最优路径变差情况 下暂时性的链路传输
同时音视频算法也是优化的一大重点,比如阿里直播的窄带高清技术、自 研实时高性能视频编码 Ali S265