咸鱼

咸鱼是以盐腌渍后,晒干的鱼

0%

HTTP边下边播MP4文件

通过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就会报错。
这就是为什么两个文件都可以本地播放,而网络播放有一个不可以播放。

解决网络播放问题

  1. 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...
  2. Web服务器支持断点下载
    断点下载,即请求时携带HeaderRANGE: bytes=- ,这不仅需要服务器支持断点,播放器也要支持,播放器首先请求moov信息,再请求mdata,这也是一种方法,但比较麻烦,出图也慢。