乐趣区

关于直播:视频直播技术干货一文读懂主流视频直播系统的推拉流架构传输协议等

本文由蘑菇街前端开发工程师“三体”分享,原题“蘑菇街云端直播摸索——启航篇”,有订正。

1、引言

随着挪动网络网速的晋升与资费的升高,视频直播作为一个新的娱乐形式曾经被越来越多的用户逐步承受。特地是最近这几年,视频直播曾经不仅仅被使用在传统的秀场、游戏类板块,更是作为电商的一种新模式失去迅速成长。

本文将通过介绍实时视频直播技术体系,包含罕用的推拉流架构、传输协定等,让你对现今支流的视频直播技术有一个根本的认知。

学习交换:

  • 挪动端 IM 开发入门文章:《新手入门一篇就够:从零开发挪动端 IM》
  • 开源 IM 框架源码:https://github.com/JackJiang2…(备用地址点此)

(本文已同步公布于:http://www.52im.net/thread-39…)

2、蘑菇街的直播架构概览

目前蘑菇街直播推拉流主流程依赖于某云直播的服务。

云直播提供的推流形式有两种:

1)一是通过集成 SDK 的形式进行推流(用于手机端开播);
2)另一种是通过 RTMP 协定向远端服务器进行推流(用于 PC 开播端或业余控台设施开播)。

除去推拉流,该云平台也提供了云通信(IM 即时通讯能力)和直播录制等云服务,组成了一套直播所须要的根底服务。

3、推拉流架构 1:厂商 SDK 推拉流

如上题所示,这一种推拉流架构形式须要依赖腾讯这类厂商提供的手机互动直播 SDK,通过在主播端 APP 和用户端 APP 都集成 SDK,使得主播端和用户端都领有推拉流的性能。

这种推拉流架构的逻辑原理是这样的:

1)主播端和用户端别离与云直播的互动直播后盾建设长连贯;
2)主播端通过 UDT 公有协定向互动直播后盾推送音视频流;
3)互动直播后盾接管到音视频流后做转发,间接下发给与之建设连贯的用户端。

这种推拉流形式有几点劣势:

1)只须要在客户端中集成 SDK:通过手机就能够开播,对于主播开播的要求比拟低,适宜直播业务疾速铺开;
2)互动直播后盾仅做转发:没有转码,上传 CDN 等额定操作,整体提早比拟低;
3)主播端和用户端都能够作为音视频上传的发起方:适宜连麦、视频会话等场景。

4、推拉流架构 2:旁路推流

之前介绍了通过手机 SDK 推拉流的直播形式,看起来在手机客户端中观看直播的场景曾经解决了。

那么问题来了:如果我想要在 H5、小程序等其余场景下观看直播,没有方法接入 SDK,须要怎么解决呢?

这个时候须要引入一个新的概念——旁路推流。

旁路推流指的是:通过协定转换将音视频流对接到规范的直播 CDN 零碎上。

目前云直播开启旁路推流后,会通过互动直播后盾将音视频流推送到云直播后盾,云直播后盾负责将收到音视频流转码成通用的协定格局并且推送到 CDN,这样 H5、小程序等端就能够通过 CDN 拉取到通用格局的音视频流进行播放了。

目前蘑菇街直播旁路开启的协定类型有 HLS、FLV、RTMP 三种,曾经能够笼罩到所有的播放场景,在后续章节会对这几种协定做具体的介绍。

5、推拉流架构 3:RTMP 推流

随着直播业务倒退,一些主播逐步不满足于手机开播的成果,并且电商直播须要高保真地将商品展现在屏幕上,须要通过更加高清业余的设施进行直播,RTMP 推流技术应运而生。

咱们通过应用 OBS 等流媒体录影程序,对业余设施录制的多路流进行合并,并且将音视频流上传到指定的推流地址。因为 OBS 推流应用了 RTMP 协定,因而咱们称这一种推流类型为 RTMP 推流。

咱们首先在云直播后盾申请到推流地址和秘钥,将推流地址和秘钥配置到 OBS 软件当中,调整推流各项参数,点击推流当前,OBS 就会通过 RTMP 协定向对应的推流地址推送音视频流。

这一种推流形式和 SDK 推流的不同之处在于音视频流是间接被推送到了云直播后盾进行转码和上传 CDN 的,没有间接将直播流转推到用户端的上行形式,因而相比 SDK 推流提早会长一些。

总结下来 RTMP 推流的劣势和劣势比拟显著。

劣势次要是:

1)能够接入业余的直播摄像头、麦克风,直播的整体成果显著优于手机开播;
2)OBS 曾经有比拟多成熟的插件,比方目前蘑菇街主播罕用 YY 助手做一些美颜的解决,并且 OBS 自身曾经反对滤镜、绿幕、多路视频合成等性能,性能比手机端弱小。
劣势次要是:

1)OBS 自身配置比较复杂,须要业余设施反对,对主播的要求显著更高,通常须要一个固定的场地进行直播;
2)RTMP 须要云端转码,并且本地上传时也会在 OBS 中配置 GOP 和缓冲,延时绝对较长。
6、高可用架构计划:云互备
业务倒退到肯定阶段后,咱们对于业务的稳定性也会有更高的要求,比方当云服务商服务呈现问题时,咱们没有备用计划就会呈现业务始终期待服务商修复进度的问题。

因而云互备计划就呈现了:云互备指的是直播业务同时对接多家云服务商,当一家云服务商呈现问题时,疾速切换到其余服务商的服务节点,保障业务不受影响。

直播业务中常常遇到服务商的 CDN 节点上行速度较慢,或者是 CDN 节点存储的直播流有问题,此类问题有地域性,很难排查,因而目前做的互备云计划,次要是备份 CDN 节点。

目前蘑菇街整体的推流流程曾经依赖了原有云平台的服务,因而咱们通过在云直播后盾直达推一路流到备份云平台上,备份云在接管到了直播流后会对流转码并且上传到备份云本身的 CDN 零碎当中。一旦主平台 CDN 节点呈现问题,咱们能够将下发的拉流地址替换成备份云拉流地址,这样就能够保障业务疾速修复并且观众无感知。

7、视频直播数据流解封装原理

介绍流协定之前,先要介绍咱们从云端拿到一份数据,要通过几个步骤能力解析出最终须要的音视频数据。

如上图所示,总体来说,从获取到数据到最终将音视频播放进去要经验四个步骤。

第一步:解协定。

协定封装的时候通常会携带一些头部形容信息或者信令数据,这一部分数据对咱们音视频播放没有作用,因而咱们须要从中提取出具体的音视频封装格局数据,咱们在直播中罕用的协定有 HTTP 和 RTMP 两种。

第二步:解封装。

获取到封装格局数据当前须要进行解封装操作,从中别离提取音频压缩流数据和视频压缩流数据,封装格局数据咱们平时常常见到的如 MP4、AVI,在直播中咱们接触比拟多的封装格局有 TS、FLV。

第三步:解码音视频。

到这里咱们曾经获取了音视频的压缩编码数据。

咱们日常常常听到的视频压缩编码数据有 H.26X 系列和 MPEG 系列等,音频编码格局有咱们相熟的 MP3、ACC 等。

之所以咱们能见到如此多的编码格局,是因为各种组织都提出了本人的编码标准,并且会相继推出一些新的议案,然而因为推广和免费问题,目前支流的编码格局也并不多。

获取压缩数据当前接下来须要将音视频压缩数据解码,获取非压缩的色彩数据和非压缩的音频抽样数据。色彩数据有咱们平时熟知的 RGB,不过在视频的中罕用的色彩数据格式是 YUV,指的是通过亮堂度、色调、饱和度确定一个像素点的色值。音频抽样数据通常应用的有 PCM。

第四步:音视频同步播放。

最初咱们须要比对音视频的时间轴,将音视频解码后的数据交给显卡声卡同步播放。

PS:如果你对上述流程还不太了解,倡议进一步浏览以下系列文章:

《挪动端实时音视频直播技术详解(一):开篇》
《挪动端实时音视频直播技术详解(二):采集》
《挪动端实时音视频直播技术详解(三):解决》
《挪动端实时音视频直播技术详解(四):编码和封装》
《挪动端实时音视频直播技术详解(五):推流和传输》
《挪动端实时音视频直播技术详解(六):提早优化》

另外:无关音视频编解码技术的文章,也能够具体学习以下文章:

视频编解码之:《实践概述》、《数字视频介绍》、《编码根底》、《预测技术介绍》
《意识支流视频编码技术 H.264》
《如何开始音频编解码技术的学习》
《音频根底及编码原理入门》
《常见的实时语音通信编码标准》
《实时视频编码 H.264 的特点与劣势》、《视频编码 H.264、VP8 的前世今生》
《详解音频编解码的原理、演进和利用选型》、《零根底,史上最艰深视频编码技术入门》

8、视频直播传输协定 1:HLS

首先介绍一下 HLS 协定。HLS 是 HTTP Live Streaming 的简写,是由苹果公司提出的流媒体网络传输协定。

从名字能够显著看出:这一套协定是基于 HTTP 协定传输的。

说到 HLS 协定:首先须要理解这一种协定是以视频切片的模式分段播放的,协定中应用的切片视频格式是 TS,也就是咱们前文提到的封装格局。

在咱们获取 TS 文件之前:协定首先要求申请一个 M3U8 格局的文件,M3U8 是一个形容索引文件,它以肯定的格局形容了 TS 地址的指向,咱们依据 M3U8 文件中形容的内容,就能够获取每一段 TS 文件的 CDN 地址,通过加载 TS 地址分段播放就能够组合出一整段残缺的视频。

应用 HLS 协定播放视频时:首先会申请一个 M3U8 文件,如果是点播只须要在初始化时获取一次就能够拿到所有的 TS 切片指向,但如果是直播的话就须要不停地轮询 M3U8 文件,获取新的 TS 切片。

获取到 M3U8 后:咱们能够看一下外面的内容。首先结尾是一些通用形容信息,比方第一个分片序列号、片段最大时长和总时长等,接下来就是具体 TS 对应的地址列表。如果是直播,那么每次申请 M3U8 文件外面的 TS 列表都会随着最新的直播切片更新,从而达到直播流播放的成果。

HLS 这种切片播放的格局在点播播放时是比拟实用的,一些大的视频网站也都有用这一种协定作为播放计划。

首先:切片播放的个性特地实用于点播播放中视频清晰度、多语种的热切换。比方咱们播放一个视频,起初抉择的是标清视频播放,当咱们看了一半感觉不够清晰,须要换成超清的,这时候只须要将标清的 M3U8 文件替换成超清的 M3U8 文件,当咱们播放到下一个 TS 节点时,视频就会主动替换成超清的 TS 文件,不须要对视频做从新初始化。

其次:切片播放的模式也能够比拟容易地在视频中插入广告等内容。

在直播场景下,HLS 也是一个比拟罕用的协定,他最大的劣势是苹果大佬的加持,对这一套协定推广的比拟好,特地是挪动端。将 M3U8 文件地址喂给 video 就能够间接播放,PC 端用 MSE 解码后大部分浏览器也都可能反对。然而因为其分片加载的个性,直播的提早绝对较长。比方咱们一个 M3U8 有 5 个 TS 文件,每个 TS 文件播放时长是 2 秒,那么一个 M3U8 文件的播放时长就是 10 秒,也就是说这个 M3U8 播放的直播进度至多是 10 秒之前的,这对于直播场景来说是一个比拟大的弊病。

HLS 中用到的 TS 封装格局,视频编码格局是通常是 H.264 或 MPEG-4,音频编码格局为 AAC 或 MP3。

一个 ts 由多个定长的 packtet 组成,通常是 188 个字节,每个 packtet 有 head 和 payload 组成,head 中蕴含一些标识符、错误信息、包地位等根底信息。payload 能够简略了解为音视频信息,但实际上上层还有还有两层封装,将封装解码后能够获取到音视频流的编码数据。

9、视频直播传输协定 2:HTTP-FLV

HTTP-FLV 协定,从名字上就能够显著看出是通过 HTTP 协定来传输 FLV 封装格局的一种协定。

FLV 是 Flash Video 的简写,是一种文件体积小,适宜在网络上传输的封包形式。FlV 的视频编码格局通常是 H.264,音频编码是 ACC 或 MP3。

HTTP-FLV 在直播中是通过走 HTTP 长连贯的形式,通过分块传输向申请端传递 FLV 封包数据。

在直播中,咱们通过 HTTP-FLV 协定的拉流地址能够拉取到一段 chunked 数据。

关上文件后能够读取到 16 进制的文件流,通过和 FLV 包构造比照,能够发现这些数据就是咱们须要的 FLV 数据。

首先结尾是头部信息:464C56 转换 ASCII 码后是 FLV 三个字符,01 指的是版本号,05 转换为 2 进制后第 6 位和第 8 位别离代表是否存在音频和视频,09 代表头部长度占了几个字节。

后续就是正式的音视频数据:是通过一个个的 FLV TAG 进行封装,每一个 TAG 也有头部信息,标注这个 TAG 是音频信息、视频信息还是脚本信息。咱们通过解析 TAG 就能够别离提取音视频的压缩编码信息。

FLV 这一种格局在 video 中并不是原生反对的,咱们要播放这一种格局的封包格局须要通过 MSE 对影视片的压缩编码信息进行解码,因而须要浏览器可能反对 MSE 这一 API。因为 HTTP-FLV 的传输是通过长连贯传输文件流的模式,须要浏览器反对 Stream IO 或者 fetch,对于浏览器的兼容性要求会比拟高。

FLV 在提早问题上相比切片播放的 HLS 会好很多,目前看来 FLV 的提早次要是受编码时设置的 GOP 长度的影响。

这边简略介绍一下 GOP:在 H.264 视频编码的过程中,会生成三种帧类型:I 帧、B 帧和 P 帧。I 帧就是咱们通常说的关键帧,关键帧内包含了残缺的帧内信息,能够间接作为其余帧的参考帧。B 帧和 P 帧为了将数据压缩得更小,须要由其余帧推断出帧内的信息。因而两个 I 帧之间的时长也能够被视作最小的视频播放片段时长。从视频推送的稳定性思考,咱们也要求主播将关键帧距离设置为定长,通常是 1 - 3 秒,因而除去其余因素,咱们的直播在播放时也会产生 1 - 3 秒的延时。

10、视频直播传输协定 3:RTMP

RTMP 协定理论能够与 HTTP-FLV 协定归做同一种类型。

他们的封包格局都是 FlV,但 HTTP-FLV 应用的传输协定是 HTTP,RTMP 拉流应用 RTMP 作为传输协定。

RTMP 是 Adobe 公司基于 TCP 做的一套实时音讯传输协定,常常与 Flash 播放器匹配应用。

RTMP 协定的优缺点非常明显。

RTMP 协定的长处次要是:

1)首先和 HTTP-FLV 一样,提早比拟低;
2)其次它的稳定性十分好,适宜长时间播放(因为播放时借用了 Flash player 弱小的性能,即便开多路流同时播放也能保障页面不呈现卡顿,很适宜监控等场景)。

然而 Flash player 目前在 web 端属于墙倒众人推的地步,支流浏览器慢慢都示意不再反对 Flash player 插件,在 MAC 上应用可能立即将电脑变成烧烤用的铁板,资源耗费很大。在挪动端 H5 根本属于齐全不反对的状态,兼容性是它最大的问题。

11、视频直播传输协定 4:MPEG-DASH

MPEG-DASH 这一协定属于新兴势力,和 HLS 一样,都是通过切片视频的形式进行播放。

他产生的背景是晚期各大公司都本人搞本人的一套协定。比方苹果搞了 HLS、微软搞了 MSS、Adobe 还搞了 HDS,这样使用者须要在多套协定封装的兼容问题上痛苦不堪。

于是大佬们凑到一起,将之前各个公司的流媒体协定计划做了一个整合,搞了一个新的协定。

因为同为切片视频播放的协定,DASH 优劣势和 HLS 相似,能够反对切片之间多视频码率、多音轨的切换,比拟适宜点播业务,在直播中还是会有延时较长的问题。

12、如何抉择最优的视频直播传输协定

视频直播协定抉择十分要害的两点,在前文都曾经有提到了,即低延时和更优的兼容性。

首先从延时角度思考:不思考云端转码以及上下行的耗费,HLS 和 MPEG-DASH 通过将切片时长减短,延时在 10 秒左右;RTMP 和 FLV 实践上延时相当,在 2 - 3 秒。因而在延时方面 HLS ≈ DASH > RTMP ≈ FLV。

从兼容性角度思考:HLS > FLV > RTMP,DASH 因为一些我的项目历史起因,并且定位和 HLS 反复了,临时没有对其兼容性做一个详尽的测试,被推出了抉择的思考范畴。

综上所述:咱们能够通过动静判断环境的形式,抉择以后环境下可用的最低提早的协定。大抵的策略就是优先应用 HTTP-FLV,应用 HLS 作为兜底,在一些非凡需要场景下通过手动配置的形式切换为 RTMP。

对于 HLS 和 HTTP-FLV:咱们能够间接应用 hls.js 和 flv.js 做做解码播放,这两个库外部都是通过 MSE 做的解码。首先依据视频封装格局提取出对应的音视频 chunk 数据,在 MediaSource 中别离对音频和视频创立 SourceBuffer,将音视频的编码数据喂给 SourceBuffer 后 SourceBuffer 外部会解决完剩下的解码和音视频对齐工作,最初 MediaSource 将 Video 标签中的 src 替换成 MediaSource 对象进行播放。

在判断播放环境时咱们能够参照 flv.js 外部的判断形式,通过调用 MSE 判断办法和模仿申请的形式判断 MSE 和 StreamIO 是否可用:

// 判断 MediaSource 是否被浏览器反对,H.264 视频编码和 Acc 音频编码是否可能被反对解码
window.MediaSource && window.MediaSource.isTypeSupported(‘video/mp4; codecs=”avc1.42E01E,mp4a.40.2″‘);

如果 FLV 播放不被反对的状况下:须要降级到 HLS,这时候须要判断浏览器环境是否在挪动端,挪动端通常不须要 hls.js 通过 MSE 解码的形式进行播放,间接将 M3U8 的地址交给 video 的 src 即可。如果是 PC 端则判断 MSE 是否可用,如果可用就应用 hls.js 解码播放。

这些判读能够在本人的逻辑里提前判断后去拉取对应解码库的 CDN,而不是期待三方库加载实现后应用三方库外部的办法判断,这样在抉择解码库时就能够不把所有的库都拉下来,进步加载速度。

13、同层播放如何解决

电商直播须要观众操作和互动的局部比起传统的直播更加多,因而产品设计的时候很多的功能模块会悬浮在直播视频上方缩小占用的空间。这个时候就会遇到一个挪动端播放器的老大难问题——同层播放。

同层播放问题:是指在挪动端 H5 页面中,一些浏览器内核为了晋升用户体验,将 video 标签被劫持替换为 native 播放器,导致其余元素无奈笼罩于播放器之上。

比方咱们想要在直播间播放器上方减少聊天窗口,将聊天窗口通过相对定位晋升 z -index 置于播放器上方,在 PC 中测试齐全失常。但在挪动端的一些浏览器中,video 被替换成了 native 播放器,native 的元素层级高于咱们的一般元素,导致聊天窗口理论显示的时候在播放器下方。

要解决这个问题,首先要分多个场景。

首先在 iOS 零碎中:失常状况下 video 标签会主动被全屏播放,但 iOS10 以上曾经原生提供了 video 的同层属性,咱们在 video 标签上减少 playsinline/webkit-playsinline 能够解决 iOS 零碎中大部分浏览器的同层问题,剩下的低零碎版本的浏览器以及一些 APP 内的 webview 容器(譬如微博),用下面提的属性并不论用,调用三方库 iphone-inline-video 能够解决大部分残余问题。

在 Android 端:大部分腾讯系的 APP 内置的 webview 容器用的都是 X5 内核,X5 内核会将 video 替换成原生定制的播放器已便于加强一些性能。X5 也提供了一套同层的计划(该计划官网文档链接已无奈关上),给 video 标签写入 X5 同层属性也能够在 X5 内核中实现内联播放。不过 X5 的同层属性在各个 X5 版本中体现都不太一样(比方低版本 X5 中须要应用 X5 全屏播放模式能力保障 MSE 播放的视频同层失效),须要留神辨别版本。

在蘑菇街 App 中,目前集成的 X5 内核版本比拟老,在应用 MSE 的状况下会导致 X5 同层参数不失效。但如果集成新版本的 X5 内核,须要对大量的线上页面做回归测试,老本比拟高,因而提供了一套折中的解决方案。通过在页面 URL 中减少一个开关参数,容器读取到参数当前会将 X5 内核降级为零碎原生的浏览器内核,这样能够在解决浏览器视频同层问题的同时也将内核变动的影响范畴管制在单个页面当中。

14、相干文章

[1] 挪动端实时音视频直播技术详解(四):编码和封装
[2] 挪动端实时音视频直播技术详解(五):推流和传输
[3] 实现提早低于 500 毫秒的 1080P 实时音视频直播的实际分享
[4] 浅谈开发实时视频直播平台的技术要点
[5] 直播零碎聊天技术(七):直播间海量聊天音讯的架构设计难点实际
[6] 从 0 到 1:万人在线的实时音视频直播技术实际分享(视频 +PPT) [附件下载]
[7] 实时视频编码 H.264 的特点与劣势
[8] 视频编码 H.264、VP8 的前世今生
[9] 零根底,史上最艰深视频编码技术入门
[10] 视频编解码之编码根底
[11] 零根底入门:实时音视频技术基础知识全面盘点
[12] 实时音视频面视必备:疾速把握 11 个视频技术相干的根底概念
[13] 写给小白的实时音视频技术入门提纲

(本文已同步公布于:http://www.52im.net/thread-39…)

退出移动版