MP4前置知识
MP4文件格式
MP4 文件由 box 组成,每个 box 分为 Header 和 Data。其中 Header 部分包含了 box 的类型和大小,Data 包含了子 box 或者数据,box 可以嵌套子 box。


参考文章:https://zhuanlan.zhihu.com/p/520256902
解决方式
方式一:基于Range 的分段按需加载
由MP4视频格式可以看出,MP4文件的时长,标题等信息是单独放在moov中的mvhd中的,则当首次加载时可先返回这些基本信息,展示出来
但由于很多视频文件的 moov 元数据在尾部,这会导致浏览器需要整个下载完后才能播放,使用 FFmpeg 就可以把 moov 元数据提前。拿到 moov box 的数据就能初始化解码器并开始播放。
其次浏览器原生的 <video> 标签支持 HTTP Range 请求,可以通过支持 Range 请求的服务器按需返回视频的某一部分,当初次加载的时候,则加载前段视频资源,当用户拖动进度条,浏览器会发起新的 Range 请求加载相应片段的数据,而不需要等全部视频下载后才能播放。
那么直接返回MP4.moov.mvhd.message,然后结合Http请求头Range 它为并行下载以及断点续传提供了技术支持。 一个HTTP请求头示例:
Accept-Encoding: identity;q=1, *;q=0
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Host: localhost:8080
Range: bytes=0-1024
Range请求头的意思是告诉服务端,这次请求客户端只需要资源的第0-1024个字节的区间数据,服务端只需要响应这部分数据就可以了。
使用<video>标签的src属性指向服务器链接,当服务器响应的HTTP状态码为206时,浏览器会自动开启分段式播放,在每次的HTTP请求头中自动加入Range请求头,服务端只需要根据前端传过来的Range信息截取视频的指定区间来响应即可。
参考文章:
方式二:基于HLS协议分片技术
对于流媒体点播来说,最大的缺点就是它的媒体信息和关键帧索引都集中存放在moov box中,而导致越大的文件,moov box越大,对播放器来说,获取不到moov box,根本无从解码,所以就导致MP4文件点播,需要缓冲很久,加载头部数据
基于HLS协议分片技术就是,将视频分成多种分辨率的视频,根据用户网络加载不同分辨率的视频,比如480P,1080P,再把视频切片成几秒一个的 .ts 或 .mp4 小块,每个文件有个.m3u8 索引文件内容,用于需要播放哪个 .ts 视频段的位置、顺序、时长、码率,
ffmpeg 是一个非常有名的高性能音视频处理工具,它可以轻松实现视频转码、分割、码率调整、分辨率调整、元数据解析、帧包解析等等
优点:可配合 CDN 缓存每个分段,降低服务器压力
参考文章
https://zhuanlan.zhihu.com/p/546033759
暂时没有回复