聊聊直播
最早开始接触网络直播是 13 年英雄联盟开始火爆那会,随随便便一想这期间发生的很多事情便浮现在眼前:小学生用家长手机打赏万元刷榜、斗鱼三骚、直播造人、天价协议、王思聪创立熊猫 TV、公务员公款打赏冯提莫、炉石主播熊大弹射起步成为“铁窗后的朋友”、战旗 Lying man 一类狼人杀节目短时间内极为火爆、各平台一哥一姐座次每三个月更替一轮、身边的不少同学跻身“全民直播”浪潮,在映客、花椒、全民等平台开播,分享自己的生活,靠着与平台五五分的打赏勉强度日。
后来沉迷于技术学习,精力聚焦过于集中,对直播基本没有关注了,但时不时还是有一些新闻来打扰我学习,比如卢本伟开挂。再到后来短视频火爆大江南北,熊猫 TV 关停,我一度以为直播要凉凉,没人会在直播刷火箭了,结果 OMG 直接改卖火箭了。随着我“行业冥灯”罗老师进军直播带货,给直播行业重新拉回风口。作为罗老师的粉丝,我紧随其后,也来凑一把热闹。
在没接手直播之前,作为一个画页面的前端工程师,凭自己的认知,觉得在一个非音视频为核心技术的公司,直播搞起来应该不是什么难事,不过是给云服务商交钱、相关 SDK 引入、面向文档编程、上线开播刷火箭四步走。
现在看来这个想法太过于自信了,主要来源于对云服务商技术的信任(毕竟能搞云服务的公司名说出来就给人一种技术硬的不行感觉,值得信赖)。事实是参与一个做了几个月的半成品项目,累死累活折腾两个月才弄的基本可用,翻译过来就是体验跟人家没法比。
当了解到一些直播技术后,再点开一场直播,不再感叹于游戏主播精湛的技术,有趣的谈吐,女主播精致的妆容。震撼我的是直播画面秒开、低延时传输、高清晰度画面、高并发弹幕,其中的每一个细节,深究下去都有非常多的东西可以讲。
今天带来的是直播的一个流程(基于云服务商),科普一些概念,分享一些音/视频的基础知识。
直播流程
直播的整个流程在腾讯云的「云直播」文档中说明的非常详细,但太详细也是缺点,文档量级过于庞大,阅读者容易抓不住重点,不少文档就是给相同中心思想换了个表达方式再来一次。在「直播流程」这个章节中,我们用最少的篇幅讲明白「云直播」是怎么一回事。
在说直播之前,先来看一个词,流媒体:

直播的本质就是实时流媒体,完整的直播流程可以用这个图流描述:

我们将流程抽象成三步:
- 推流
- 云端处理
- 播放器拉流播放
两个最重要的概念(摘自云直播-基本概念):
- 推流:将本地视频源和音频源推送到腾讯视频云服务器
- 拉流:即直播播放,指已实现直播推流之后,用指定地址将腾讯视频云服务器中的视频源和音频源拉取播放的过程
这里有一个注意事项,推流与播放必须有域名,得提前注册并备案完毕。
按顺序走,咱们先来看推流。
推流
推流,推的是本地的视频和音频,通常有「推流软件」、「腾讯云直播 SDK」这两种方式,他们的过程基本一致,通常如下几个步骤:
- 采集 获取本地的硬件设备(摄像头/麦克风)采集到获取到视频/音频数据
- 前处理 可以做一些美颜
- 编码
- 传输 通过推流协议将数据传输到服务器
最常用的推流软件有「OBS」全称 Open Broadcaster Software,我们以 OBS 为例来感受一下这个流程,打开官网:

「串流」这个词不知道是谁的翻译,对照着看一下英文是「live streaming」,大概理解为「推流」就好了。
不禁感叹中华文字的博大精深,表现力极强,给 stream 这样一个如此抽象的一个概念配上了 “串”、“推” 的动作,让人想到串肉串、推门一类轻而易举的动作。可以闭上眼睛感受一下,就像门轻轻一推,流就传输过去了,生动形象的表现了流传输的便捷、高效。
除了 streaming,OBS 还可以录屏,来听个直播分享顺带收获一款录屏软件,赶紧小笔记记下来。回到推流,来看一下推流都有哪些参数配置:

光看看这配置项名称就晕了,给人感觉非常的学术

花了半天时间,给这些参数都研究了一遍,也算是对视频处理进行了一个小入门。
视频处理简介
配置的参数其实是提供个视频编码器的编码参数,为什么要进行视频编码呢,直接把从硬件设备拿到的数据推上去不行吗?让我们来看看某位掘金网友的解答:

关键词「压缩」,编码即压缩的过程,可以方便信息传输,编码背后的技术原理,跟中华文字一样博大精深,放几张入门教程的截图来给大家体会一下。


在极客时间趣谈网络协议中,摘抄到了一段对编码较为通俗的解释

编码过程大致如图所示:

看完大致过程,来介绍一些编码的核心概念,为了避免中文翻译带来的一些歧义,这里都备注上了英文
- 编码器(Encoder)
- OBS 上通常使用 x264 编码器,比较常见的还有 x265 编码器
- H.264/H.265 是视频编码的标准
以 x264 编码器为例,列举一些常见编码参数
- 比特率/码率(Bitrate)
- 是单位时间播放连续的媒体如压缩后的音频和视频的比特数量,相当于带宽消耗量,或吞吐量,3000kbps 全程就是 3000kb per second,就是 3 Mb 每秒,这就要求「上行带宽」要大于 3Mbps 才能稳定传输,又引入了新概念「上行带宽」,在这里顺带解释一下
- 我们在访问互联网的时候存在两种行为:一是上传数据,二是下载数据。上行带宽(速度)指的是上传速度,下行宽带指的是下载数据的速度,可以使用 网速测试工具 来测试网速
- 是单位时间播放连续的媒体如压缩后的音频和视频的比特数量,相当于带宽消耗量,或吞吐量,3000kbps 全程就是 3000kb per second,就是 3 Mb 每秒,这就要求「上行带宽」要大于 3Mbps 才能稳定传输,又引入了新概念「上行带宽」,在这里顺带解释一下

- 帧率
- 测量显示帧数的量度,测量单位为每秒显示帧数(Frame per Second, FPS)
- 这里再来顺带讲一讲物理,当人眼看到的画面帧率高于 10/12 帧的时候,人就会认为画面是连贯的,这个现象称为视觉暂留
- 分辨率(Resolution)
- 影像的清晰度,通常有像素密度 ppi 和 像素总数来衡量
- 常见的分辨率如 1080p,p为逐行扫描,1080则是垂直方向上有 1080 条水平扫描线,通常 1080p 的画面分辨率为 1920 * 1080
- 码率控制(Rate Control)
- 视频编码(有损)的目标是尽可能多的节省比特(码率)的同时尽量保持视频质量。码率控制是平衡码率和质量的重要工具,VBR可以使编码器在难编码的地方花费更多比特,在编码简单的地方花费更少比特
- CBR(Constant Bitrate) 恒定码率
- VBR(Variable Bit Rate) 动态码率
- 缩小方法(Downscale Filter)
- 当我们的基础(画布)分辨率和输出(缩放)分辨率不同的时候,就会用到缩小方法
- Bilinear
- Area
- Bicubic
- Lanczos
- 关键帧间隔(Keyframe Interval)
- 简单的原理解析参考下图
- 关键帧间隔即 I 帧的间隔,会直接影响到直播的延时,值越小延时越低但是越容易卡顿(请求次数多,服务器压力大),反之值越大延时越高越流畅

概念差不多先介绍到这里,推荐一个最常用的视频处理软件 FFmpeg
A complete, cross-platform solution to record, convert and stream audio and video. - FFmpeg 官网介绍
功能非常强大,格式转换,修改分辨率,提取音频的简单处理,完全可以用这个工具来实现
视频处理的知识就先介绍到这里,在编码完成后,下一步就是传输
传输
数据传输离不开协议,从「主播」到「服务器」的推流协议主要是 RTMP(Real-Time Messaging Protocol)
实时消息协议(英语:Real-Time Messaging Protocol,缩写RTMP)也称实时消息传输协议,是最初由Macromedia为通过互联网在Flash播放器与一个服务器之间传输流媒体音频、视频和数据而开发的一个专有协议。Macromedia后被Adobe Systems收购,该协议也已发布了不完整的规范供公众使用。
RTMP 这个协议的特点是既可以推送也可以用来播放,同时也是最常见的播放协议之一,这个后面的播放器环节会提到
到此,推流这个过程就说明的差不多了,「丁香直播」的推流方式略有不同,我将其称作「实时音视频旁路直播」
实时音视频旁路直播
这套架构的核心是腾讯的实时音视频(Tencent Real-Time Communication 简称 TRTC)解决方案。
先看一下整体架构:

本质是在实时音视频的同时,将 TRTC 中的音视频数据旁路到直播 CDN 中,观众通过直播 CDN 进行观看,在架构图上可以看到,实时音视频与 IM(即时通信) 协同使用,可以实现类似弹幕、消息讨论区等功能。
在 Web 端,TRTC 的 SDK 基于 WebRTC 技术,在小程序和其他终端 SDK 还未深究,暂不予以讨论。TRTC 用下来的感觉就是面向文档编程,文档中基本也没有出现 WebRTC 的字样,很好理解。如果要深入理解 RTC 技术,还是需要从底层去搭建 WebRTC,时间允许的话会去折腾一下。
回到 TRTC 直播,下面两张图摘自 实时音视频-实现 CDN 直播观看,很好的帮助我们理解这个流程:


在混合画面旁路直播中,一个重要的概念是「云端混流转码」简称「混流」,混流为了将多路画面合成一路,通过参数控制混流,比如画面的排版方式,分辨率,帧率等。
为什么观众不直接播放多路 CDN 画面?播放多路 CDN 画面很难解决多路画面的延迟对齐问题,同时拉取多路画面所消耗的下载流量也比单独画面要多,所以业内普遍采用云端混流方案。
下图非常清晰明了的解释了混流这个过程,其中的 MCU 指代的是混流转码集群。

这里是 TRTC 支持的混流参数,比起 OBS 推流方式的 x264 编码参数,精简太多了。

混流完成的下一步也是通过 RTMP 协议推流。
云端处理
推流到了云端,并不是直接进行 CDN 分发,云服务商为了多收钱,要给客户多制造一些需求,虽然有些功能不那么必要,但让你乍一看就觉得挺有用,通常有这些功能:
- 转码
- 转码是将视频码流转换成另一个视频码流的过程。通过转码,可以改变原始码流的编码格式、分辨率和码率等参数,从而适应不同终端和网络环境的播放。使用转码功能可以实现:
- 适配更多终端:将原始视频转码成拥有更强终端适配能力的格式,使视频资源能够在更多设备上播放
- 适配不同带宽:将视频转换成流畅、标清、高清或超清输出,用户可根据当前网络环境选择合适码率的视频播放
- 节省带宽:采用更先进的编码方式转码,在不损失原始画质的情况下显著降低码率,节省播放带宽
- 转码是将视频码流转换成另一个视频码流的过程。通过转码,可以改变原始码流的编码格式、分辨率和码率等参数,从而适应不同终端和网络环境的播放。使用转码功能可以实现:
- 事件消息通知
- 指推流过程中,直播触发事件通知按照配置模板信息主动发送请求到客户的服务器
- 防盗链
- 直播录制
- 在推流过程中,将直播原始流经过转音视频封装(不修改音频、视频数据以及对应的时间戳等信息)得到的视频文件存储到云点播平台
- 水印
- 在直播推流过程中,为保证视频版权不受侵犯,在转码过程中将设置好的水印合并到视频流中输出一个带有水印的视频流,水印内容可以为文字或图片
- 截图
- 以固定时间间隔将直播推流视频画面截取下来,形成图片文件存储在对象存储 COS 中
- 截图通常出现在点播的时鼠标悬浮进度条候查看缩略图
- 鉴黄
- 基于截图功能,系统通过推流域名已关联的截图鉴黄模板,鉴别直播推流过程中主播是否出现违规的直播内容
- 直播时移
- 直播时移依托云直播录制的能力,将 TS(Transport Stream)分片地址和 TS 文件单独存放,保存于云点播系统中。客户端通过时移播放域名传入时间参数,可以播放当前时间之前的精彩视频内容
- CDN
- 内容分发网络(Content Delivery Network,CDN),是在现有 Internet 中增加的一层新的网络架构,由遍布全球的高性能加速节点构成。这些高性能的服务节点都会按照一定的缓存策略存储您的业务内容,当您的用户向您的某一业务内容发起请求时,请求会被调度至最接近用户的服务节点,直接由服务节点快速响应,有效降低用户访问延迟,提升可用性
拉流播放
常见播放协议
常见的播放协议有如下几种
- RTMP(Real-Time Messaging Protocol) 基于 TCP,浏览器播放依赖 Flash
- FLV(Flash Video)
- HTTP-FLV 基于 HTTP 流式 IO 传输 FLV
- WebSocket-FLV 基于 WebSocket 传输 FLV
- HLS(HTTP Live Streaming) 苹果提出基于HTTP的流媒体传输协议
在 云直播-常见问题-直播基础相关 文档中有着非常详细的常见直播协议优劣对比

在腾讯的播放器 TCPlayerLite 介绍中,直接将 FLV 协议标注为移动端浏览器不支持

直播协议了解到这个深度已经可以做到根据场景做出合适的选择。网上相关文章不计其数,大多都是上文这个中心思想,这篇《关于直播视频格式和浏览器兼容性历史的来龙去脉》观点较独特,作者从历史的角度来讲为什么会有兼容性的问题,描述了如下一些事实:
- 以乔布斯为首的 Apple 集团对 Flash 表示强烈不满和坚决反对,安全漏洞大,功耗大(发热严重),低性能
- IOS 不支持 Flash,Apple 自研了 HLS 协议
- Apple 在移动端算是还有话语权,Android 阵营也得支持 HLS
- Flash 淘汰基本是定局,Web 标准 Media Source Extensions 出台
我们通过 flv.js 这个项目来了解一下 Media Source Extensions 是怎么回事

flv.js 是 bilibili 自研的一个播放器,目的让 Web 播放不依赖 Flash,通过流式 IO(如 fetch API)拉取 FLV 格式的音视频数据,使用 JavaScript 解码,经过 Media Source Extensions API 将数据「喂」给 <video> 标签(HTML 5 video 原生仅支持 MP4/WebM/Ogg 视频格式)。另外一个项目 hls.js 播放器也是同理,将 m3u8 文件通过 JavaScript 解码,后续流程都一致,这是 WEB 端支持 FLV、HLS 协议的原理。
结合看一下这几个 API 的兼容性,就知道为什么腾讯云文档中写着移动端不支持 FLV 协议了。

对于 Web 端直播播放协议选择,我个人给出的建议是对于支持 HTTP-FLV 的设备我们优先使用 HTTP-FLV 进行播放,否则就使用 HLS。
给 HLS 再稍微展开一下,HLS 协议规定:
HLS协议由HTTP+M3U8+TS三部分组成,其中,HTTP是传输协议,M3U8是索引文件,TS是视音频的媒体信息。视频的编码格式为H264,音频编码格式为MP3、AAC或者AC-3。

至此,整个云直播流程就介绍完了
