Web 多媒体入门|青训营笔记

94 阅读7分钟

这是我参与「第四届青训营 」笔记创作活动的的第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):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
image.png
解码第二帧 P 帧:需要先解码第一帧 I 帧。
解码第三帧 B 帧:需要要先解码第二帧 P 帧和第四帧 P帧。
解码第四帧 P 帧:需要先解码第二帧 P 帧。
PTS :123456
DTS :124365

GOP (group of picture):两个 I 帧之间的间隔。 image.png 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 。
对视频进行编码的主要目的是为了视频的存储和传输。

空间冗余 image.png 拿一个变量存储当前 rgb 的值,然后知道当前像素是100 × 100的,然后再存储有一万次的重复,相当于可以减少很多的存储空间。

时间冗余 image.png 99%相同的数据称为时间冗余,去除时间冗余,存储1%的差值。

编码冗余 image.png 图片只有两个颜色,如果正规的去存储,那24位表示一个像素,现在用1表示蓝色,0表示白色,这样就只要一位就可以存储。

视觉冗余 image.png 左边是原图,右边是压缩后的图(去除了人眼看不到的颜色)。
视觉冗余主要针对人类视觉系统的,人眼不是对所有颜色都能看到,人眼对某个范围内的颜色可以看到也对高频的东西没有那么敏感。

编码数据处理流程 image.png 预测分为帧内预测和帧间预测,基本上 I 帧就属于帧内预测,帧内预测去除的是空间冗余;帧间预测,时间冗余。

编码格式 image.png 目前主流的标准: H262 、 H264 、 H265 、 H266。
H262 :目前主要用在了数字点数, VCD 、 DVD 光盘等上。
H264 :爱奇艺、抖音、快手等。
H265 :实现4K 的编码,比 H264 压缩还要高一倍。
H266 :主要用于现在的 VR 。
PC 端目前主要支持的编码格式 H264 , H265 的支持还不是很好。

封装格式

存储音视频、图片或者字幕信息的一种容器。 image.png 封装格式便于存储和传输。 image.png

多媒体元素和扩展 API

播放音频 video 标签,视频 audio 标签,MSE 扩展 API 。

video 标签的使用: image.png 方式二可以添加多个 source 标签,浏览器支持第一个 source 就用第一个 source ,不支持第一个就尝试第二个 source 。

video 标签和 audio 标签用法一样: image.png

video 标签和 audio 标签常用的方法: image.png image.png

video 标签和 audio 标签常用的属性: image.png image.png

video 标签和 audio 标签常用的事件: image.png image.png

video 标签和 audio 标签的缺陷:

  • 不支持直接播放 hls 、 flv 等视频格式
  • 视频资源的请求和加载无法通过代码控制
    • 分段加载(节约流量)
    • 清晰度无缝切换
    • 精确预加载

媒体源扩展 API (Media Source Extensions)

  • 无插件在 web 端播放流媒体
  • 支持播放 hls 、 flv 、 mp4 等格式视频
  • 可实现视频分段加载、清晰度无缝切换、自适应码率、精确预加载等

使用媒体源扩展 API 的步骤: image.png

  1. 创建 mediaSource 实例
  2. 创建指向 mediaSource 的 URL
  3. 监听 sourceopen 事件
  4. 创建 sourceBuffer
  5. 向 sourceBuffer 中加入数据
  6. 监听 updateend 事件

MSE 播放流程: image.png

播放器播放流程: image.png

mp4 文件结构:
image.png
mdat 所有音频或视频的裸流数据。
moov 封装信息,源数据信息。

fmp4 文件结构:
image.png
因为多个 moof 和 mdat ,所以 fmp4 支持流式播放。

流媒体协议

image.png

HLS 全称是 HTTP Live Streaming ,是一个由 Apple 公司提出的基于 HTTP 的媒体流传输协议,用于实时音视频的传输。目前 HLS 协议被广泛的应用于视频点播和直播领域。

hls 播放流程: image.png 先数据采集,然后把采集的数据上传到数据的 Server ,数据的 Server 进行编码,编码之后进行分发,分发到 CDN ,然后客户端进行拉流、进行数据的播放。


应用场景

image.png
点播:视频上传,视频上传完成之后上传到服务器,服务器进行转码(因为上传的视频一般情况下分辨率、码率都比较高导致视频比较大),然后分发到 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 视频。