这是我参与「第四届青训营 」笔记创作活动的的第16天
Web 多媒体历史
文字、图片、音频、视频等都属于多媒体的范畴 Web 多媒体可以分为两个大的阶段:
- PC 为主的时代
- 浏览器基本上是不支持音频和视频(借助 flash 等插件)
- 移动互联网时代
- iPhone 不支持 flash 开始(HTML5 支持音频和视频)
- MSE (Media Source Extensions)为主, video 标签为辅的时代
基础知识
编码格式
图像基本概念
图像分辨率:用于确定组成一幅画像的像素数据,就是指在水平和垂直方向上图像所具有的像素个数。
图像深度:图像深度是指存储每个像素所需要的比特数。图像深度决定了图像的每个像素可能的颜色数或可能的灰度级数。例如:彩色图像每个像素用 R , G , B 三个分量表示,每个分量用8位,像素深度为24位,可以表示的颜色数目为2的24次方,既16777216个;一副单色图像存储每个像素需要8 bit ,则图像的像素深度为8位,最大灰度数目为2的8次方,既256个。
视频基本概念
分辨率:每一帧的图像分辨率。
帧率:视频单位时间内包含的视频帧的数量。
码率:视频单位时间内传输的数据量,一般用 kbps 表示,即千位每秒。
视频帧分为 I 帧、 P 帧、 B 帧 三类。
I 帧:帧内编码帧,视频的压缩不依赖任何帧,关键参考帧,它的解码也不依赖任何帧。
P 帧:前向预测编码帧,它的解码依赖于前一帧的图片。
B 帧:双向预测内插编码帧,它的解码不仅依赖前面的参考帧,也依赖后面的参考帧。
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
解码第二帧 P 帧:需要先解码第一帧 I 帧。
解码第三帧 B 帧:需要要先解码第二帧 P 帧和第四帧 P帧。
解码第四帧 P 帧:需要先解码第二帧 P 帧。
PTS :123456
DTS :124365
GOP (group of picture):两个 I 帧之间的间隔。
I 帧是不是越多越好?
不是,因为 I 帧本身是帧内压缩,所以它本身占用的存储空间是比较大的,如果 I 帧比较多相当于视频比较大,压缩比就会比较,一般情况下 GOP 间隔在2~4秒。
如果只有第一帧是 I 帧,剩下的都是 P 帧或 B 帧?
如果 seek 到第九(或一百)帧,那时要把第九(或一百)帧之前的全部解码(重复解码),那时候是比较耗时的。
为什么要编码?
分辨率:1920 × 1080
大小:1920 * 1080 * 24 / 8 = 6220800 Byte (5.9 M)
假设帧率为 30 FPS (30张图片每秒),时长90分钟,一个半小时的视频如果不压缩的话大小为 933 G 。
对视频进行编码的主要目的是为了视频的存储和传输。
空间冗余
拿一个变量存储当前 rgb 的值,然后知道当前像素是100 × 100的,然后再存储有一万次的重复,相当于可以减少很多的存储空间。
时间冗余
99%相同的数据称为时间冗余,去除时间冗余,存储1%的差值。
编码冗余
图片只有两个颜色,如果正规的去存储,那24位表示一个像素,现在用1表示蓝色,0表示白色,这样就只要一位就可以存储。
视觉冗余
左边是原图,右边是压缩后的图(去除了人眼看不到的颜色)。
视觉冗余主要针对人类视觉系统的,人眼不是对所有颜色都能看到,人眼对某个范围内的颜色可以看到也对高频的东西没有那么敏感。
编码数据处理流程
预测分为帧内预测和帧间预测,基本上 I 帧就属于帧内预测,帧内预测去除的是空间冗余;帧间预测,时间冗余。
编码格式
目前主流的标准: H262 、 H264 、 H265 、 H266。
H262 :目前主要用在了数字点数, VCD 、 DVD 光盘等上。
H264 :爱奇艺、抖音、快手等。
H265 :实现4K 的编码,比 H264 压缩还要高一倍。
H266 :主要用于现在的 VR 。
PC 端目前主要支持的编码格式 H264 , H265 的支持还不是很好。
封装格式
存储音视频、图片或者字幕信息的一种容器。
封装格式便于存储和传输。
多媒体元素和扩展 API
播放音频 video 标签,视频 audio 标签,MSE 扩展 API 。
video 标签的使用:
方式二可以添加多个 source 标签,浏览器支持第一个 source 就用第一个 source ,不支持第一个就尝试第二个 source 。
video 标签和 audio 标签用法一样:
video 标签和 audio 标签常用的方法:
video 标签和 audio 标签常用的属性:
video 标签和 audio 标签常用的事件:
video 标签和 audio 标签的缺陷:
- 不支持直接播放 hls 、 flv 等视频格式
- 视频资源的请求和加载无法通过代码控制
- 分段加载(节约流量)
- 清晰度无缝切换
- 精确预加载
媒体源扩展 API (Media Source Extensions)
- 无插件在 web 端播放流媒体
- 支持播放 hls 、 flv 、 mp4 等格式视频
- 可实现视频分段加载、清晰度无缝切换、自适应码率、精确预加载等
使用媒体源扩展 API 的步骤:
- 创建 mediaSource 实例
- 创建指向 mediaSource 的 URL
- 监听 sourceopen 事件
- 创建 sourceBuffer
- 向 sourceBuffer 中加入数据
- 监听 updateend 事件
MSE 播放流程:
播放器播放流程:
mp4 文件结构:
mdat 所有音频或视频的裸流数据。
moov 封装信息,源数据信息。
fmp4 文件结构:
因为多个 moof 和 mdat ,所以 fmp4 支持流式播放。
流媒体协议
HLS 全称是 HTTP Live Streaming ,是一个由 Apple 公司提出的基于 HTTP 的媒体流传输协议,用于实时音视频的传输。目前 HLS 协议被广泛的应用于视频点播和直播领域。
hls 播放流程:
先数据采集,然后把采集的数据上传到数据的 Server ,数据的 Server 进行编码,编码之后进行分发,分发到 CDN ,然后客户端进行拉流、进行数据的播放。
应用场景
点播:视频上传,视频上传完成之后上传到服务器,服务器进行转码(因为上传的视频一般情况下分辨率、码率都比较高导致视频比较大),然后分发到 CDN ,看到时候点开播放器,播放器回去 CDN 进行拉流。
直播:跟点播类似,视频数据实时性比较高。
图片:直接用 img 标签就搞定了。
云游戏:所有程序运行在远端的一个 port 上,打开云游戏时,其实是向远端的 port 发了一个指令, port 执行命令后会生成一个对应的视频流,把这个视频流再传回来,这个时候相当于形成了一个循环。对延时要求比较高,一般在 5ms 左右。
实时通信:视频会议。
视频编辑:一种情况是在本地编辑视频;另一种是在 web 端进行视频编辑,首先要把视频上传,然后根据需要对视频进行裁剪、拼接,最后生成视频。
展望
新技术标准
- Webassembly :大部分浏览器不支持 H265 ,但是可以通过 Webassembly 来实现,可以把 C++ 写的 H265 的解码库转成一个 wsm 格式的库, web 端就可以调用 wsm 格式的库。
- WebCodecs :在前端对音频视频实现编码和解码,相当于把底层音视频相关的能力暴露出来了。
- WebGPU :可以看成第二代的 WebGL , WebGL 绘图相关的能力 + 直接操控 GPU 底层相关的能力。
- WebVR 、 WebXR :主要针对现在提倡的元宇宙,在 web 端怎样实现 VR 视频。