通过HTTP无法播放MP4视频?
有一个摄像机录制的视频文件record.mp4 ,放在web服务器上边下边播(http://mydomain.com/record.mp4
),发现无法播放,下载到本地可以播放。
但是从抖音下载的视频douyin.mp4文件,同样放在web服务器上,可以边下边播(http://mydomain.com/douyin.mp4
)能正常播放。
都是MP4封装格式 ,这两个文件有什么不同呢?
通过 Mp4Explorer
这个软件,可以查看MP4的详细信息。
moov 是box参数列表,可以粗暴理解为 配置信息
mdata 是音视频数据
1. record.mp4
2. douyin.mp4
通过上图可知道:
record.mp4 的数据顺序是 mdata + moov
douyin.mp4 的数据顺序是 moov + mdata
大多数录制的MP4工具,都会将moov放在文件尾部,播放器播放MP4视频要首先解析moov中的box参数进行初始化,然后才能对mdata里面的音视频数据进行音视频同步播放。
在本地播放,播放器会去文件尾部读取moov,不会影响播放,但是通过网络(HTTP)播放就会有问题,播放器读取不到moov就会报错。
这就是为什么两个文件都可以本地播放,而网络播放有一个不可以播放。
解决网络播放问题
moov提前(推荐)
将moov信息提取到文件头部,播放器可以首先读取到moov数据,出图快,一劳永逸。
那如何提前?
①. ffmpeg -i record.mp4 -c copy -f mp4 -movflags faststart output.mp4 (ffmpeg 大小20 ~ 30M)
②.(推荐)单独编译 ffmpeg 项目中 faststart.c 文件 (大概20KB),【faststart.c源码】1
2
3
4
5
6
7
8
9
10
11
12# 示例:Ubuntu下gcc编译 qt-faststart.c
$ vim qt-faststart.c #拷贝源码
$ gcc qt-faststart.c -o qt-faststart
$ qt-faststart input.mp4 output.mp4
ftyp 0 28
mdat 28 771862
moov 771890 2050
patching stco atom...
patching stco atom...
writing ftyp atom...
writing moov atom...
copying rest of file...Web服务器支持断点下载
断点下载,即请求时携带HeaderRANGE: bytes=-
,这不仅需要服务器支持断点,播放器也要支持,播放器首先请求moov信息,再请求mdata,这也是一种方法,但比较麻烦,出图也慢。