多协议、多容器格式的media

70 阅读3分钟

「 编码 and 封装 」

media 内容的源文件都是比较大的,毕竟包含音频、视频、字幕等信息。那为了方便传输和存储,需要对原视频文件进行编码来压缩文件大小;还需要将压缩后的音频、视频、字幕等组合到一个容器内。可以用压缩饼干装袋来理解( 会有很多种不同的压缩工艺和包装规格)

「 拆装 and 解码 」

相应地,在浏览器播放端进行播放时,也需要先进行拆装解码

浏览器自带的 < video/> 标签有拆装和解码的能力,但是对 media 的格式和容器是有限制的。那遇到浏览器不会拆、不会解码的 media 源文件怎么办嘞?

「 flv.js 」

flv(flash video) 是一种新的视频格式,一般FLV文件包在SWF PLAYER的壳里,并且FLV可以很好的保护原始地址,不易下载,从而起到保护著作权的作用。

flv.js是b站开源的 HTML5 flv 播放器,基于 HTTP-FLV协议,通过纯 JS(-> MSE! MSE! MES!)实现 FLV 的封装,使得 flv 格式的文件可以在 web 上进行播放。

但是也不是所有的 flv 格式都可以播放,flv.js 也有一些限制要求:

  • 视频必须是 AVC(H.264)编码,音频必须为AAC或者MP3编码
  • 浏览器环境必须支持 MSE
  • 浏览器必须支持 video、fetch api/xhr/websocket

「 hls.js 」

随着流媒体业务的发展,出现了很多新的传输协议。以 HLS 为例:

HLS(HTTP Live Streaming) ,是苹果公司提出的基于 HTTP 的流媒体网络传输协议。它的工作原理是把整个流分成一个个小的基于 HTTP 的文件来下载,每次只下载一些。 HLS 可以穿过任何允许 HTTP 数据通过的防火墙or代理服务器,也可以使用 CDN来进行传输。

HLS 新增了 m3u8 索引文件:

m3u8 是一种纯文本文件(并不是一种视频格式),采用UTF-8编码,是一种Unicode版本的m3u文件。它存放了视频的基本信息分段视频的索引地址(将一个视频分成了时长不同的很多小段)。当播放 m3u8 视频时,就会按顺序下载播放索引列表的视频,从而完成一整段视频的播放。

// M3U8文件必须包含的标签,并且必须在文件的第一行
#EXTM3U
// M3U8文件的版本,常见的是3
#EXT-X-VERSION:3
// 第一个TS分片的序列号
#EXT-X-MEDIA-SEQUENCE:0
// 是否允许cache
#EXT-X-ALLOW-CACHE:YES
// 每个每个媒体段(ts)的最大的时长
#EXT-X-TARGETDURATION:39
// 每个媒体段(ts)的持续时间
#EXTINF:1.084422,
/videolib1/1903/15/9b4wxrd1g/SD/9b4wxrd1g-mobile-0.ts
// 每个媒体段(ts)的持续时间
#EXTINF:2.002000,
/videolib1/1903/15/9b4wxrd1g/SD/9b4wxrd1g-mobile-1.ts
// 每个媒体段(ts)的持续时间
#EXTINF:2.919578,
/videolib1/1903/15/9b4wxrd1g/SD/9b4wxrd1g-mobile-2.ts

// ... 中间部分省略

/videolib1/1903/15/9b4wxrd1g/SD/9b4wxrd1g-mobile-130.ts
// 每个媒体段(ts)的持续时间
#EXTINF:11.386378,
/videolib1/1903/15/9b4wxrd1g/SD/9b4wxrd1g-mobile-131.ts
// 表示PlayList的末尾了
#EXT-X-ENDLIST

上面的每个 ts 文件都对应一个视频片段。显然直接将其 feed 给< video/> 标签是无法播放的,需要我们进行一些转化 -> 可以手动把这些 ts 片段下载下来然后合并成一个大的 ts 文件,再转化为 mp4 文件,just like:

$ ffmpeg -f concat -safe 0 -i playlist.m3u8 -c copy output.ts
$ ffmpeg -i output.ts -acodec copy -vcodec copy output.mp4

或者更简单的

$ ffmpeg -i http://cdn.zlib.cn/m3u8/test.m3u8 -c copy output.mp4
m3u8 vs mp4
  • mp4 对 HTML5 的< video/>和flash播放器都挺友好的。但是文件资源太大,结构复杂。
  • m3u8 采用的是苹果的 HLS 协议,如上它的工作原理是将整个视频流分成一个个小的基于 http 的文件进行下载播放,因此支持直播

截屏2024-06-18 19.39.56.png