video视频播放

22 阅读2分钟

背景

视频播放的时候对于视频比较大的情况下,直接用video标签引用进行播放,但是视频播放加载速度比较慢,需要等好几秒才会开始播放。

image.png

image.png

看网络请求了好几个请求。

这是第一个请求,看起来也都是对的,先请求了22kb的视频,但是视频还是不播放。经过调研,原来mp4视频有一个元信息的片段,叫moov,他是视频的目录和索引,播放器要先读到他才知道怎么播放,一个mp4视频分为3个片段,第一个是文件类型ftyp,第二个是moov,也即是播放索引,第3个是mdat,也就是真正的视频音频数据。

moov装的是什么

moov就是movie box,moov相当于视频的目录,里面包含视频总时长,帧率,分辨率,音视频轨道信息,每一帧在文件里面的位置,关键帧位置(I)

没有moov,播放器根本不知道,第1s的视频在哪里播,从哪里开始解码,怎么seek也就是拖进度条。

所以视频加载了一部分但是播放不了,很有可能是moov在文件末尾,这个是最常见的坑。视频可能是这种借口[ftyp][mdat][moov]

这样就是浏览器必须先下载完整体的mdat视频数据,才能读到moov,才知道怎么播放。

所以我们可以把视频改成[ftyp][moov][mdat]这种格式,这样浏览器一开始就能拿到索引,边下边播,秒开播放。

这叫做Fast Start(快速启动)。

所以我们第一个解决办法就是可以把这个moov放到视频数据的前面,这样浏览器拿到索引就可以边下边播了。

还有一个就是关键帧,关键帧是一张可以单独看懂的完整画面。没有关键帧,视频是解不开的。

视频不是一帧一帧的,为了省体积,视频用的是压缩编码,只存完整少量画面,其余画面只存变化。

这个关键帧就是视频播放的起点,可以独立解码,不依赖其他帧,是一张完整的图片。

如果视频每10s才有一个关键帧,如果你从第5s开始加载,必须要等第10s才能等到那个关键帧才能开始播放。

但是帧也不是越小越好,越小的话视频体积会越大。

一般web常用24fps,2秒 = 48帧,或者30fps,2秒 = 60帧

ffmpeg -i input.mp4 \
-c:v libx264 -profile:v main -level 4.0 \
-g 48 -keyint_min 48 -sc_threshold 0 \
-movflags +faststart \
-c:a aac \
output.mp4

然后还要检查服务端必须支持http range请求才行。