美文网首页Android开发
又有坑是吧——MediaPlayer加载视频为什么这么慢

又有坑是吧——MediaPlayer加载视频为什么这么慢

作者: Android柯南 | 来源:发表于2021-01-15 20:36 被阅读0次

    "今天又是充满希望的一天"

    背景

    最近在做一个视频播放的需求,因为比较简单,只需要实现基本的loading,播放,暂停等功能,所以就用Android系统的播放器MediaPlayer。本来开开心心打完了工,正偷偷给妹妹发微信,测试大姐拿着手机过来就噼里啪啦一顿输出

    “啊,你们的视频加载怎么这么慢?!”

    “你看看人家iOS就不这样,这样能上线吗?!”

    我X,我测的时候明明好好的啊,怎么现在加载个视频就要30多秒。看着不断转圈圈的loading图,我心里大骂

    “又tm有坑是吧”

    为了不耽误各位男哥哥女哥哥的时间,直接上结论:视频元数据位置不对

    ???什么是视频元数据?哪里位置不对?你特么写技术文还要别人百度是吧?

    别别别,听我解释

    关键的一句话

    实际项目中用到的视频格式大多是MP4,MP4格式的视频是由一个个Box组成的。这个Box可以理解为数据块。Box里面可以嵌套Box:

    (如果哥哥们想自己体验一把, mac可以用MediaParaser, window用Mp4Info)

    ftyp,moov,mdat就是Box的名字。这里需要重点关注的是moov和mdat两个Box。

    moov就是视频的元数据,存放着视频的总体信息,时长啦,码率啦,宽高等等

    mdat是具体的媒体数据,也就是我们播放的内容

    下面这句话很关键

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

    这句话是这篇文章的核心。其他可以不管,这个起码要记住

    所以关于播放器加载视频慢的原因,聪明的哥哥一定早就有答案了,继续看无非就是验证一下啦

    原因

    上面那张图是理想状态下视频box的位置。

    但一些视频在压制的时候,会把moov box放在视频尾部,也就是mdat之后。这就造成播放器必须把整个视频下载完才能获取到moov box,然后才能播放。

    相当于你和妹子去约会,刚见面老板说线上有问题让你解决,你哼哧哼哧解决完继续约会你看妹妹会不会当场跟你分手

    方案一

    直接原因是找到了。聪明的哥哥一定会提出另一个问题

    既然moov box这么关键,为什么有的视频会把它放在最后呢?

    这个我做了一下实验,发现ffmpeg在转换视频格式的时候,会默认把moov box放在视频尾部。我猜是ffmpeg转化完整个视频之后才能确切知道新视频的时长,码率等信息,所以顺手就把它放到新视频的末尾了。

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

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

    这不就是解决方案之一吗?

    用新的视频一试,加载时间果然变成2~3秒了

    真相大白!!!

    方案二

    正当我神清气爽准备再找妹妹交流感情之时,产品阿姨告诉我,我们视频有几万个,项目马上要上线了,谁给你时间一个个转换,你说啊,你说啊!!!

    我就是个打工的.. 别骂我嘛..

    实际开发中会有各种情况无法对视频源做修改,这时候我们只能自己想办法。

    视频播放的前提是要获取到moov box,而视频源moov box在尾部,那么我们能不能

    先请求视频的尾部获取到moov box,然后再从头请求视频呢?

    当然可以。流媒体的请求并不是一次请求完成的,而是分片请求。 先发起一个http请求,读取响应body的开头,如果发现moov在开头就继续往下读mdat。如果没有发现,第二个请求直接读取文件末尾的数据,这样用两个请求也能获取到moov。这个方案要求服务端能支持Request-Range请求,也就是能通过Range直接读取文件尾部,不过一般的oss服务都支持。

    image

    这个方案可以耶!可是难道要我重写一遍MediaPlayer的请求??那我的妹妹怎么办?!

    转念一想,这个问题应该很普遍,聪明的哥哥们一定已经填过坑了。于是我用ijkPlayer和exoPlayer分别测了一下,果然这两个播放器都已经对这种情况做了处理,直接替换就好。ijkPlayer的官方so库不支持https请求,于是最终采用了exoPlayer

    耶!终于结束了!虽然妹妹早就不耐烦地不回我消息了,但我相信只要坚持对她好她一定会感动的。下个坑,我一定不会再让妹妹久等了

    相关文章

      网友评论

        本文标题:又有坑是吧——MediaPlayer加载视频为什么这么慢

        本文链接:https://www.haomeiwen.com/subject/xnawaktx.html