推荐一款全平台广告聚合SDK【ADEasy】:https://blog.csdn.net/u013640004/article/details/105416193

对于这套方法我已经封装成库,可以直接下载使用。
MP4Info1.0.2.jar下载
配套的视频播放器终于出来了,可自定义性很大。
MP4Player1.0.1.jarDemo下载
另外写了一个查看MP4结构的软件,安卓版的
(下载安卓版MP4Info查看MP4结构)
码云项目
MP4Info-码云开源

QQ群交流:425219113(计算机语言交流)


边下边播方法初试

**刚开始实现这个的时候,我第一下想到的是:**先将MP4文件单纯的从字节的层次分为若干个文件,然后播放的时候,不断从服务器一边下载,一边追加到一个源文件里面,最后直接播放这个源文件就可以了。如图:

这个方法到底可不可行呢?能否播放?如果遇到播放快于下载的情况,会不会出错呢?
这个方法在一定的情况下是可行的,如果遇到播放错误,也只需要给VideoView设置错误监听器setOnErrorListener()就行。如果监听到错误,就显示加载框,然后继续下载,下载完了再尝试播放。
但后来我发现,并不是所有的MP4都支持这种做法,有的MP4这样做依然是要等到全部下载完了才能播放的。


MP4结构分析 -怎么才能边下边播##

先了解一下MP4的基本结构。(可以用百度手机助手下载MP4Info查看MP4结构)

简要地说,MP4文件主要由ftyp,mdat,moov这三部分组成。

  • ftyp 记录了mp4格式,编码格式之类的一些基本信息
  • mdat记录了视频媒体信息(mdat的体积往往非常的大,几乎等于MP4总大小)
  • moov是如同检索表一样的存在,里面记录了每一帧对应的数据在哪里等等

MP4播放流程大概是

  1. 读取ftype部分决定解码方式。
  2. 寻找并读取moov部分,获取视频总时长等信息。
  3. 根据moov的检索信息到mdat里面读取相应的媒体信息,进而播放。

所以,想要播放MP4,一定要让播放器先读取到ftyp与moov才行的。但根据我最开始的做法,如果MP4的moov在mdat的前面的话,正常分割,追加,自然可以做到边下边播。但是,如果moov在mdat后面的话,就需要等下载完ftyp-mdat-moov(等于下载整个MP4)才能正常播放了。

重要的是,有的甚至是大部分MP4是如上图的结构的,moov在mdat的后面。


边下边播方法再试

那面对moov在mdat后面的MP4,我们应该如何处理呢?怎么才能让播放器先读取到ftyp与moov呢

然后,我想着单纯在字节层次,将moov整个搬到mdat的前面,ftyp的后面。但失败了,大概是因为moov里面已经写死了对应mdat的地址检索表,所以我们这样移动定然改变了mdat的原本位置,而导致无法检索数据。如下图:

这里注意,播放器播放视频的时候,大概是不在乎mdat的数据是否正确的,而是哪里正确则播放到哪里,直到错误报错。


边下边播方法成功

所以我后来受到网上的启示。先不管mdat这一部分,只下载ftyp与moov部分,并按照其原本的位置放置,而将mdat这一部分架空。最后和方法一同样,不断下载mdat的分段文件并追加到指定位置。(注意,可能有这三者以外的其他数据,所以我将视频重新分为三部分:head,mDat,foot,head是mDat的前面部分,foot是mDat的后面部分)


边下边播方法改良

上面已经是很久之前的做法了,从数据结构上来说,分的并不是很合理。现在我改变了一下这里的逻辑:将head、foot、自定义数据、mDat大小这些信息在切割的时候就包含子自定义文件tjbb里面,然后在下载回来的时候,先下载tjbb文件就可以了解析所有必要信息了


到了这里,就能实现边下载边播放了。但要怎么样才能知道ftyp,mdat,moov的位置呢。
这里就要再了解一下mp4结构了。

MP4由多个Box组成,Box可以理解为一种结构规范,另外Box可以层层嵌套,如Moov里面又有很多个Box。

下面所讨论的Box都具备以下特性:以8个字节开头,接着就是Box的数据。该8个字节,前四个字节包含了整一个Box的大小信息,后四个字节包含了该Box的类型(也可以说是名字)。有一种叫footBox不太一样。

我们可以通过将字节转化为字符串的形式,获取mdat字符的位置,然后减去4个字节(存储大小信息的部分),就能得到mdat这个box的起始位置了,然后再读取其大小信息,获取mdat的总大小,就能获取到mdat的结束位置。

特别注意,这里我们不是讲mp4分为type,mdat与moov了,而是分为head,mdat,foot,因为其中间可能还有一些别的Box,而这种分法,还有可能moov在mdat前面的,而导致没有foot,这也是需要注意的。

另外,查找mdat位置的时候,不要一次性将mp4读取到手机内存啊,会崩溃的,需要用到缓冲池,我倒是写了不少算法,不过也不是很齐全,日后再发了。

到此,这就是我实现mp4边下边播的方法了,挺有意思的不是。如果有问题可以评论留言。

Android实现MP4边下边播(边缓存边播放、在线播放)原理与代码相关推荐

  1. (转载)封装bilibili播放器,自定义边下边播和缓存功能

    感谢并转载自:https://www.jianshu.com/p/264324559c07 源码下载,欢迎star 演示Demo下载 image 本项目使用播放器是ijkplay, 并且进行封装和修改 ...

  2. php音视频边下边播,封装bilibili播放器,自定义边下边播和缓存功能

    image 本项目使用播放器是ijkplay, 并且进行封装和修改主要功能: 1.重新编辑ijkplay的so库, 使其更精简和支持https协议 2.自定义MediaDataSource, 使用ok ...

  3. iOS开发 - 使用IJKPlayer时,关于需求要边下边播的缓存功能,退回来后播放缓存不再耗流量

    博主以前做的项目,使用的流播放,rtmp,基于bilibili的ijkplayer,想必大家都有用过或者听过,是一个很不错的开源的直播,播放流视频的播放器,后面又有了一批需求,客户要求我们做一个缓存功 ...

  4. php中fopen打开mp4边下边播,解决mp4流媒体转换不能边下边播

    近期项目需要,把N个MP4文件压缩处理为流媒体格式,并放至服务器,使用CDN加速供WEB播放器点播.出现几个问题,作下记录. 问题:MP4格式非流媒体,即不能边下载边播放,用户体验非常差. 原因: 由 ...

  5. [iOS]仿微博视频边下边播之滑动 TableView 自动播放

    注意:框架已经迭代到2.0版本,我重新架构了整个框架,API 也得到了更好的设计,我为 2.0 版本的实现写了一篇文章 [iOS]如何重新架构 JPVideoPlayer ?.此文中的实现思路仍然是一 ...

  6. [iOS]仿微博视频边下边播之滑动TableView自动播放

    Tips:这次的内容分为两篇文章讲述 01.[iOS]仿微博视频边下边播之封装播放器 讲述如何封装一个实现了边下边播并且缓存的视频播放器. 02.[iOS]仿微博视频边下边播之滑动TableView自 ...

  7. 仿微博视频边下边播之封装播放器

    来源:NewPan(@盼盼_HKbuy) 链接:http://www.jianshu.com/p/0d4588a7540f Tips:这次的内容分为两篇文章讲述 01.[iOS]仿微博视频边下边播之封 ...

  8. iOS开发之仿微博视频边下边播之自定义AVPlayer播放器, 边下边播解剖。视频处理流程,建立连接-请求数据-统筹数据-解码数据-视频呈现

    Tips:这次的内容分为两篇文章讲述 01.[iOS]仿微博视频边下边播之封装播放器 讲述如何封装一个实现了边下边播并且缓存的视频播放器. 02.[iOS]仿微博视频边下边播之滑动TableView自 ...

  9. Android 视频边下边播,MP4头信息在后调整头信息

    mp4视频有两种格式,一种视频头信息在前,这种直接可以先缓存头信息,然后直接边下边播,还有一种是头信息在最后,这种情况下则需要处理mp4的头信息,并调整mp4的格式. mp4文件的格式如下图 图1 从 ...

  10. Android 实现视屏播放器、边播边缓存功能,附源码

    热文导读 | 点击标题阅读 [墙裂推荐]AndroidVideoCache:实现视屏播放边下边播 吊炸天!74款APP完整源码! 一份年薪30万的Android面试宝典,附答案 来源:http://w ...

最新文章

  1. JVM的YGC,这次被它搞惨了!
  2. mysql 获取当月每一天_mysql获取从某个时间到今天的每一天的日期,以及笛卡尔积...
  3. Android http通信案例
  4. BIO,NIO,AIO
  5. Java多线程学习八:线程池常用的阻塞队列
  6. c 取数组 最大值 算法_拜托,面试别再问我最大值最小值了!!!
  7. ASP.NET MVC初体验
  8. 不容错过!Greenplum的又一本好书
  9. JMeter使用教程-压测
  10. 虚拟服务器设置自动关机,ESXi单个主机定时开关机的设置
  11. 物理机能够ping通虚拟机,但是虚拟机无法ping通物理机
  12. 汉字转拼音多音字java_汉字转拼音多音字解决方案 搜索引擎分词细胞词库更新 搜狗词库提取TXT PHP高性能输出UNICODE正则汉字列表...
  13. TcaplusDB君 | 行业新闻汇编(7月1日)
  14. jsp页面打开为空白页
  15. lunix内核—死锁的四个必要条件和解决办法
  16. 泪目了!原河南常务副省长的艰辛求学路竟然这么感人
  17. Android Things:外设I/O接口-UART
  18. 机器学习实例--预测美国人口收入状况
  19. transforms.ToTensor()与transforms.Normalize()函数解析
  20. 混合颜色带的应用(一)

热门文章

  1. 【基础学习】操作系统学习笔记 - 内存管理:内存使用与分段、内存分区与分页、多级页表、快表、段页式内存管理的实现、内存的换入换出
  2. Depends工具(检查exe文件依赖的好朋友)
  3. libtorrent源码分析(二)VS上libtorrent编译总结
  4. Insyde uefi 隐藏设置_Android/iOS QQ 8.1.5测试版同时发布:私密会话可以隐藏
  5. K-Means K均值算法python实现 (包括绘图)
  6. MATLAB数据类型结构
  7. matlab数据类型的转换方法
  8. 华为交换机命令基础入门学习,菜鸟也能看得懂!
  9. Linux服务器(CentOS7)基础信息设置之满足等保三级测评要求
  10. cm11 android l,【鹰眼出品】安卓4.4.4 CM11已刷,流畅度爆表!《转》