Android播放mp4首次加载慢

mp4第一帧加载较慢的原因?

开发过程中遇到同样一个视频URL地址,Android要比Ios首帧加载耗时大两到三倍。

mp4

check视频moov区域

image.png

moov区域前置

image.png

重新测试播放时间

原因

mp4是由很多box组成的,其中MOOV box里存放的是音视频编码之类的对播放很重要的信息,先要拿到这些信息才能播放。所以MOOV box放在文件的前面通过一次http请求就可以直接读取到,解析,继续读取音视频数据播放。MOOV box放在文件的后边,但是播放器不知道它放在后面,需要先发起一次http请求读开头部分数据,发现没有MOOV box,它会seek到文件后边位置,读取MOOV box,读完之后再seek到文件前边位置,从开始位置读取音视频帧数据播放,每发生一次seek就重新发起一次http connetion请求。所以MOOV box放在后边比放在前边多了2次http connection,用时是放在前边方案的3倍。下边是两个短视频一个moov box放在了前边,一个放在了后边,放在了后边的通过NmdPlayer的log可以都看到会发生re-connection,请求文件最后一段数据来获取moov box。

普通MP4文件播放时,ftyp与moov box需同时加载完成后,并下载部分mdat box的帧数据后,才能开始播放。
那对于一些长视频,确实存在文件头过大,从而影响第一帧的加载速度问题。另外,对于不是很规范的文件,moov box基本在文件最后位置,还有可能存在视频文件基本下载完成后才能播放的问题。

播放器

播放器获取到moov box才能开始播放视频!!!

moov区域前置

ffmpeg其实也提供了移动moov box到视频头部的命令

ffmpeg -i input.mp4 -c copy -f mp4 -movflags faststart output.mp4

流媒体请求

image.png

结论&解决方案

  • mp4的结构特性是导致长视频首帧显示过慢的主要原因。
    播放mp4音视频数据前需要先加载moov数据,moov的大小和视频长度成正比(如问题视频为长度为46分01秒,moov数据约2.2M)。在网络较差的情况下,加载moov数据会耗费较长时间。
  • 预加载,在适当时机提前加载视频头部数据,写入本地文件,播放器从本地读取数据,快速构建索引表,进入首帧解码。
  • moov在视频文件尾部,多了一次seek请求操作。相对于第一点,影响较小。解决方案:服务器端将moov从文件尾部移到ftyp后面。

工具

mac MediaParser

参考

https://www.jianshu.com/p/865c566c0a06?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=weixin

你可能感兴趣的:(Android播放mp4首次加载慢)