前端音视频入门详解(涵盖点播直播、封装格式、编解码等)

此篇为理论向,后续会推出 MSE 实战篇~

基本步骤

视频播放器播放一个互联网上的视频文件,需要经过以下几个步骤:解协议,解封装,解码视音频,视音频同步。

解协议

将流媒体协议的数据,解析为相应的封装格式数据。

音视频在网络上传播的时候,常常采用各种流媒体协议,例如 RTMP,RTSP 。这些协议在传输视音频数据的同时,也会传输一些信令数据。这些信令数据包括对播放的控制(播放,暂停,停止),或者对网络状态的描述等。解协议的过程中会去除掉信令数据而只保留视音频数据

解封装

解封装的作用,就是将输入的封装格式的数据,分离成为音频流压缩编码数据和视频流压缩编码数据。封装格式种类很多,例如MP4,TS,FLV,HLS 。

根据时间顺序,音频数据和视频数据会交叉存储。

音视频有轨道的概念,都可以有多个轨道,但一般只播放一个音频、视频轨道(双声道音频其实是一个轨道的音频)。轨道只是一个概念,其实是数据块中的一个 index 标记。

封装格式决定的是音视频文件的结构、数据块的大小等

解码

视频的压缩编码标准则包含 H264,H265,VC-1,音频的压缩编码标准包含AAC,MP3,AC-3 。

编码格式决定的是音视频数据压缩的算法及方式

音视频同步

音视频通过时间戳同步。每个音视频数据块中一般都含有解码时间戳 DTS 和播放时间戳 PTS

数据块根据 DTS 排列,解码时解码器需要用到 DTS,解码后每一帧数据都会含有 PTS,播放器根据 PTS 切换图像或者音频采样。

时间戳是相对时间,PTS 一般等于 DTS(也有可能不相等,如H264的B帧需要滞后解码,DTS>PTS)。时间戳需要根据时间基换算才能得到具体时间,时间基一般记录在文件信息中(通常一些封装格式时间基是固定的)。

时间基(1秒分成多少份,如1/9000)

PTS 具体时间换算 = PTS * 时间基,DTS 同理。

视频基础

像素、分辨率、帧率

位深:通常 R、G、B 各占 8 个位,也就是一个字节。8 个位能表示 256 种颜色值,我们称这种图像是 8bit 图像,而这个 8bit 就是位深。

色彩空间模型:RGB、YUV 等,是像素点记录色彩数据的方式。 RGB 不方便做图像压缩编码。跟 RGB 图像中 R、G、B 三个通道都跟色彩信息相关这种特点不同,YUV 图像将亮度信息 Y 与色彩信息 U、V 分离开来。考虑到兼容老的黑白电视机,如果使用 RGB 表示图像,那么黑白电视机就没办法播放。这是因为 R、G、B 三个通道都是彩色的 ,而 Y、U、V 就可以。因为黑白电视机可以使用 Y 分量,Y 分量就是黑白图像,而且包含了图像的总体轮廓信息,只是没有色彩信息而已。人眼对于色彩信息相比图像的轮廓信息不敏感些。我们可以缩小U、V的大小。一般来说,采集到的原始图像、给显示器渲染的最终图像都是 RGB 图像,但是视频编码一般用的是 YUV 图像。那么这中间一定少不了两者的相互转换。

PTS:播放时间戳真正影响了视频帧的播放

码率:一秒的数据量大小,实质上是限制数据量大小防止客户端带宽不足(不是码率越高,清晰度就会越高)

H264、265

对于每一帧图像,又是划分成一个个块来进行编码的,这一个个块在 H264 中叫做宏块。

图像一般都是有数据冗余的,主要包括以下 4 种:

  • 空间冗余。比如说将一帧图像划分成一个个 16x16 的块之后,相邻的块很多时候都有比较明显的相似性,这种就叫空间冗余。
  • 时间冗余。一个帧率为 25fps 的视频中前后两帧图像相差只有 40ms,两张图像的变化是比较小的,相似性很高,这种叫做时间冗余。
  • 视觉冗余。我们的眼睛是有视觉灵敏度这个东西的。人的眼睛对于图像中高频信息的敏感度是小于低频信息的。有的时候去除图像中的一些高频信息,人眼看起来跟不去除高频信息差别不大,这种叫做视觉冗余。
  • 信息熵冗余。我们一般会使用 Zip 等压缩工具去压缩文件,将文件大小减小,这个对于图像来说也是可以做的,这种冗余叫做信息熵冗余。

视频编码就是通过减少上述 4 种冗余来达到压缩视频的目的。

我们通过减少图像块的空间冗余和时间冗余来接近这个目标。刚才我们也说到,图像内部相邻宏块之间有很多相似性,并且两张图像之间也有很多相似性。因此,根据图像的这个特点,我们可以在编码的时候进行帧内预测和帧间预测

H264 算法中有运动补偿、运动补充等概念,也就是相似度较高的区间内并不需要记录所有的数据,而是根据前后图像计算得出,从而减少文件大小。

265比264拥有更高的压缩能力,但编解码消耗性能更多。H265 普及度不高。toC 场景行不通。

I 、P、B 帧,压缩相似帧的手段

I 帧:能独立播放,数据量大,采用帧内压缩技术,IDR 帧属于 I 帧

P 帧:需要根据前一个 I 或 P 帧 计算得出,数据量小

B 帧:需要根据前一个和后一个 I 或 P 帧计算,压缩率最高,但占用 CPU 且耗时最多

IDR 帧:解码器立即刷新帧,解码器遇到 IDR 帧就会清空参考 buffer 中的数据,起到防止错误传播的作用

I 帧一般出现在视频突变的位置,一些视频软件会优先处理 I 帧,B 帧需要后一帧生成所以直播流场景下一般不生成 B 帧,有利于直播流畅。

在线播放时未加载完跳转卡顿时间长可能是视频的某两个I帧相隔特别远,可以将 GOP 设置为帧率的 4-5倍,保证4-5秒必有 I 帧

直播时 GOP 设置为帧率 1-2 倍,这样理论上只有在1-2秒这个间隙中开始拉流才会出现花屏。直播一般禁止生成 B 帧,有利直播的流畅。

GOP:一组强相关的视频帧,开头必须为 I 帧(IDR 帧)。除了第一帧其他帧也可能存在I帧。GOP一般是对直播流等流媒体设置的,为了缓解网络因素导致的花屏

视频编码

帧内预测一般就是即将编码块的左边块、上边块、左上角块和右上角块,通过将这些块与编码块相邻的像素经过多种不同的算法得到多个不同的预测块。

然后我们再用编码块减去每一个预测块得到一个个残差块。最后,我们取这些算法得到的残差块中像素的绝对值加起来最小的块为预测块。而得到这个预测块的算法为帧内预测模式。

由于这个残差块中像素的绝对值之和最小,这个残差块的像素值经过扫描之后的"像素串"就比直接扫描编码块的"像素串"中的像素值更接近 0 (因为 0 在二进制中只占 1 个位就可以了)

但是我们的目标不只是将像素值变小,而是希望能出现连续的 0 像素,那怎么办呢?

这就需要利用我们人眼的视觉敏感性的特点了:DCT 变换和量化。DCT 变换又叫离散余弦变换。之后我们再通过 DCT 变换将低频和高频信息分离开来得到变换块,然后再对变换块的系数做量化。由于高频系数通常比较小,很容易量化为 0,同时人眼对高频信息不太敏感,这样我们就得到了一串含有很多个 0,大多数情况下是一串含有连续 0 的"像素串",并且人的观感还不会太明显。这样,最后熵编码就能把图像压缩成比较小的数据,以此达到视频压缩的目的。这就是视频编码的原理。

视频格式优劣

mp4

mp4 是最常见的,应用范围广,兼容性强,几乎所有的播放器都支持 mp4 格式。

mp4 文件是一个数据块相互嵌套的树状结构,基本单位是 Box

  • ftyp:存放文件类型、版本号
  • moov:存放元数据(MP4 文件的创建时间、时间基、总时长)、轨道信息、mdat 数据块中的映射关系
  • mdat:具体的音视频数据(没有时间戳),依赖 moov 信息才能推算音视频帧的播放时间戳

moov 没有获取到的话无法计算出播放时间所以无法播放,所以在线播放时需要将 moov 放在mdat数据块之前,所以 mp4 首帧播放所需时间较长

使用场景:网站视频不是主营业务,短视频为主视频文件不大

mp4 CDN 加速效果不佳,二是MP4长时间播放可能会出现播放中断等情况

flv

flv 与直播协议中的 RTMP 、HTTP-FLV 类似

flv 文件的每个音视频数据块都可以有时间戳标识所以 flv 在首帧播放、未加载跳转等场景表现更加优秀

场景:视频网站大多都采用 flv 格式,大文件、长时间播放比 MP4 更稳定。同样大文件情况下 普通 CDN 加速效果不佳,但可以接入大文件 CDN 缓解这个问题。

hls

hls 是苹果推出的,DASH 是国际标准,两者大致相同。

hls 实质是把一整个视频文件拆分成多个 ts 碎片视频文件,另一部分是记录视频文件地址的 m3u8 索引文件。hls 观看地址实际是 m3u8 索引文件,然后播放器从索引文件获取视频碎片文件的下载路径。

m3u8 支持二级索引,就是将高清、标清等观看地址整合到一个索引文件,播放器根据带宽选择观看地址,大部分网页播放器的自动也是因为这个。

hls 切片导致它更适合长视频场景 ,视频跳转 、CDN 加速、多线程预加载等方面更优秀。

短视频场景下,ts 文件本身就是完整的视频封装格式,也是能单独播放的,所以会产生一些不必要的流量。

另外,由于 hls 由多文件组成,hls 视频需要网站系统自己转封装,这是 hls 比较麻烦的地方。

直播推流拉流

工作原理:直播流数据获取 -》 直播转码(水印,缓存 I 帧,禁止 B 帧,码率限制) -》 直播流数据输出

推流:RTMP

拉流:HTTP-FLV、HLS

RTMP、HTTP-FLV:建立在 FLV 封装之上。

  • RTMP 既可以推流也可以拉流,但是浏览器抛弃了 Flash 且 RTMP 高并发场景下不稳定,所以一般只用作直播源推流到 CDN。RTMP 延迟较低,建立在 TCP 长连接通道上,在封装音视频数据时会强制切片,限制每个数据包的大小,一定程度上保证了实时性,网络较差时数据包重新发送的成本不会太大
  • HTTP-FLV 可以理解为 RTMP 的 HTTP 版本,只用于拉流观看

流行的方案:直播源推流 RTMP,直播源观看是 HTTP-FLV 协议

直播的 HLS:只用作拉流观看,且直播的 hls 与点播时不同。直播时每生成一个 ts 碎片文件都会更新 m3u8 索引文件,且碎片视频文件个数有上限,达到上限后会删除最旧的的文件并更新索引文件。所以直播时客户端也要不断获取索引文件。HLS 直播场景需要不断生成静态文件,直播延迟很大。

RTSP 常用于摄像头、监控等硬件设备的实时视频推送与观看。RTSP 是一个控制协议,控制流媒体传输,不直接传输音视频数据,而是通过控制命令(例如 PLAY、PAUSE、TEARDOWN)来指示服务器开始、暂停、停止等操作。通常与 RTP(Real-time Transport Protocol)结合使用,RTP 用于传输音视频数据,而 RTSP 用于控制传输。协议本身泛用性不足,浏览器不支持 RTSP 播放,web 领域不常用。

webrtc 是点对点得视频/语音通话协议,基于 UDP,延迟比 RTMP 低,应用于交互性较高的场景(直播带货),理论延迟在1s内

直播延迟

协议的延迟指的是单纯的通信延迟,直播延迟包括:推流延迟,转码延迟、拉流延迟,包括很多细节:水印,缓存 I 帧,禁止 B 帧,码率限制,GPU 加速等

相关推荐
m0_748247551 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
m0_748255022 小时前
前端常用算法集合
前端·算法
真的很上进2 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203982 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2342 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
如若1233 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~4 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语4 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport4 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg4 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全