一种方法是在服务器端做调整,即将带有编码信息的头放在开始,另外一种就是先下载这个编码头。

mp4文档比较复杂,我用简单的方式描述一下,mp4是很多box的嵌套,最上层box包括ftyp,free,moov,mdat等等,其中moov存放着视频详细描述,算是索引,而mdat存放着视频的具体信息。那么需要播放的时候,先必须拿到moov,在实际的mp4打包中,moov可能被放到了mdat后面,导致了文件不被下载完的时候无法获取moov,而无法边缓存边播放。

问题分析出来了,一种简单的方式就是在服务端重新打包,使用mp4box把moov放到mdat前面。还一种方式就是在客户端进行重新调整下载顺序。

我这里稍微介绍一下在客户端进行重新调整下载顺序的解决思路,我们顺序的读取inputstream,当遇到mdat box时,获取mdat整个包长度,并不下载,直接填入空字节。根据长度跳跃到下一个box,直至遇到 moov。完成了moov后,回头再填写mdat,这时已经可以下载一部分播放一部分了。

转自:http://blog.csdn.net/c_crazyren/article/details/7184948

现在将参考文章摘自如下:http://www.cnblogs.com/haibindev/archive/2011/10/17/2214518.html

MP4文件格式的解析,以及MP4文件的分割算法

  mp4应该算是一种比较复杂的媒体格式了,起源于QuickTime。以前研究的时候就花了一番的功夫,尤其是如何把它完美的融入到视频点播应用中,更是费尽了心思,主要问题是处理mp4文件庞大的“媒体头”。当然,流媒体点播也可以采用flv格式来做,flv也可以封装H.264视频数据的,不过Adobe却不推荐这么做,人家说毕竟mp4才是H.264最佳的存储格式嘛。

  这几天整理并重构了一下mp4文件的解析程序,融合了分解与合并的程序,以前是c语言写的,应用在linux上运行的服务器程序上,现在改成c++,方便我在其他项目中使用它,至于用不用移植一份c#的,暂时用不到,等有必要了再说吧。这篇文章先简单介绍一下mp4文件的大体结构,以及它的分割算法,之后再写文章介绍如何把mp4完美应用在点播项目中。

一、MP4格式分析                  

  MP4(MPEG-4 Part 14)是一种常见的多媒体容器格式,它是在“ISO/IEC 14496-14”标准文件中定义的,属于MPEG-4的一部分,是“ISO/IEC 14496-12(MPEG-4 Part 12 ISO base media file format)”标准中所定义的媒体格式的一种实现,后者定义了一种通用的媒体文件结构标准。MP4是一种描述较为全面的容器格式,被认为可以在其中嵌入任何形式的数据,各种编码的视频、音频等都不在话下,不过我们常见的大部分的MP4文件存放的AVC(H.264)MPEG-4(Part 2)编码的视频和AAC编码的音频。MP4格式的官方文件后缀名是“.mp4”,还有其他的以mp4为基础进行的扩展或者是缩水版本的格式,包括:M4V,  3GPF4V等。

  mp4是由一个个“box”组成的,大box中存放小box,一级嵌套一级来存放媒体信息。box的基本结构是:

  其中,size指明了整个box所占用的大小,包括header部分。如果box很大(例如存放具体视频数据的mdat box),超过了uint32的最大数值,size就被设置为1,并用接下来的8位uint64来存放大小。

  一个mp4文件有可能包含非常多的box,在很大程度上增加了解析的复杂性,这个网页上http://mp4ra.org/atoms.html记录了一些当前注册过的box类型。看到这么多box,如果要全部支持,一个个解析,怕是头都要爆了。还好,大部分mp4文件没有那么多的box类型,下图就是一个简化了的,常见的mp4文件结构:

  一般来说,解析媒体文件,最关心的部分是视频文件的宽高、时长、码率、编码格式、帧列表、关键帧列表,以及所对应的时戳和在文件中的位置,这些信息,在mp4中,是以特定的算法分开存放在stbl box下属的几个box中的,需要解析stbl下面所有的box,来还原媒体信息。下表是对于以上几个重要的box存放信息的说明:

  看吧,要获取到mp4文件的帧列表,还挺不容易的,需要一层层解析,然后综合stts stsc stsz stss stco等这几个box的信息,才能还原出帧列表,每一帧的时戳和偏移量。而且,你要照顾可能出现或者可能不出现的那些box。。。可以看的出来,mp4把帧sample进行了分组,也就是chunk,需要间接的通过chunk来描述帧,这样做的理由是可以压缩存储空间,缩小媒体信息所占用的文件大小。这里面,stsc box的解析相对来说比较复杂,它用了一种巧妙的方式来说明sample和chunk的映射关系,特别介绍一下。

  这是stsc box的结构,前几项的意义就不解释了,可以看到stsc box里每个entry结构体都存有三项数据,它们的意思是:“从first_chunk这个chunk序号开始,每个chunk都有samples_per_chunk个数的sample,而且每个sample都可以通过sample_description_index这个索引,在stsd box中找到描述信息”。也就是说,每个entry结构体描述的是一组chunk,它们有相同的特点,那就是每个chunk包含samples_per_chunk个sample,好,那你要问,这组相同特点的chunk有多少个?请通过下一个entry结构体来推算,用下一个entry的first_chunk减去本次的first_chunk,就得到了这组chunk的个数。最后一个entry结构体则表明从该first_chunk到最后一个chunk,每个chunk都有sampls_per_chunk个sample。很拗口吧,不过,就是这个意思:)。由于这种算法无法得知文件所有chunk的个数,所以你必须借助于stco或co64。直接上代码可能会清楚些:

  1. 首先直接分析entry

  2. 然后,通过stco或co64获知chunk总个数之后,开始还原映射表

  读出stsc之后,就可以综合stbl下的所有box,推算出视频和音频帧列表,时戳和偏移量等数据。下面截图展示获取到的关键帧列表:

  有了关键帧列表之后,就可以继续我们一下个题目,就是mp4文件的分割。实现mp4的分割,是把mp4应用到点播系统中最关键的技术环节,做不到这个,就无法实现点播播放mp4影片的“拖动”。

二、MP4文件的分割算法

  所谓“分割”,就是把大文件切成小文件,要实现mp4的分割,

  •   首先,需要获取到关键帧列表
  •   然后,选择要分割的时间段(比如从关键帧开始)
  •   接着,重新生成moov box(注意所有相关的box 以及 box size都需要改变)
  •   最后,拷贝对应的数据,生成新文件

  第一点,上面已经介绍了,第二点,只需要遍历关键帧列表,就能找到离你想要分割的时间段最接近的关键帧,第四点就是“copy-paste”的工作,关键在于第三点。因为这一步涉及到stbl下的所有box,必须重新生成entrys,同样的,其他的box都还好,只需要保留关键帧所对应的sample和chunk,其余的删掉即可,只是stsc box的比较麻烦,说起来比较啰嗦,还是直接看代码吧:

  修改完box之后,需要重新生成moov box,由于moov box的大小以及时长等信息都发生了改变,所以需要box的大小做相应的修改,这点千万不能忘记,否则播放器会解析错误。重新生成box之后,还要计算一下分割后的数据的长度,由于数据长度也发生了改变,所以修改mdat box的大小的同时,要同时修改stbl下所有box的chunk offset,切记!

  以下是整个的逻辑过程:

  好了,所有这些都实现之后,就具备了做mp4点播系统的条件了。不过,要做mp4点播,还有一些其他的问题需要解决,我将在下一篇文章中介绍。

怎么实现边下载边播放相关推荐

  1. iOS视频边下载边播放

    随着视频行业的发展,很多用户对于观看体验也有了更高的要求,以前的习惯是下载好了在观看,而现在是希望1分钟都不要等,ZUI好一边看着一边下载,等把这个视频看完也下载完了,也就是我们常说的"视频 ...

  2. 成功解决android 网络视频边下载变播放。

    关于android网络视频在线播放也困扰着很多新手们,在网络上找了很久都没有找到合适解决方案. 在网上找到了边下载边播放功能,根本不成功,要么是有bug,要么是无法播放,有些是下载完了才可以播放.达不 ...

  3. 微信语音(录音,上传,下载,播放,停止)

    1.api:微信:JSSDK    https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 (1)初始化微信:一般在 ...

  4. iOS音视频实现边下载边播放

    iOS音视频实现边下载边播放 近段时间制作视频播放社区的功能,期间查找了不少资料,做过很多尝试,现在来整理一下其中遇到的一些坑.由于考虑到AVPlayer对视频有更高自由度的控制,而且能够使用它自定义 ...

  5. Downcast for Mac 2.11.1下载、播放和同步您的播客。

    Downcast for Mac - 麦金塔 macnp.com Downcast让您可以通过专为播客构建的直观界面下载.播放和同步**您喜爱的播客. 订阅功能 搜索.订阅和下载音频和视频播客 通过 ...

  6. 边下载边播放的播放器Android边下边播

    看到很多朋友有提问到Android边下载边播放的播放器,小编在这里给大家做个关于这方面的分享. 首先作为一款播放器,支持转码或者支持各种视频格式是必须的,比如常见的视频格式:MP4/FLV/M3U8/ ...

  7. 实现MP4文件边下载边播放

    最近遇到的需求,在老系统中有部分MP4视频在播放时需要完全加载完才能播放,使得用户体验很差(现在都是边下载边播放模式),造成这种情况的原因是用来描述MP4文件的moov atom元数据被放在MP4文件 ...

  8. woo语言实现 m3u8流媒体视频文件 下载并播放

    woo 代码如下: 已经在gitee开源:https://gitee.com/oshine/woo_spider PS:运行前注意,一般爬虫网站会要求有refer,请把对应的refer填写到下方代码中 ...

  9. 安卓实现M3U8文件的下载和播放

    现如今网络上的视频大多数都是m3u8格式的,使用m3u8格式有以下好处 1. 方便切换码率,例如从高清转到蓝光 2. 节约流量,m3u8实际切割成一段段的TS后缀视频,传统请求是把整个文件流返回去,网 ...

最新文章

  1. C++中的参数传递方式:传值、传地址、传引用总结
  2. CentOS 7 安装jdk
  3. 使用Python和OpenCV检测图像中的物体并将物体裁剪下来
  4. 【java】实现一个简单的正则:判断一个字符串是否全由数字组成
  5. jvm_虚拟机参数讲解(一)
  6. Codeforces Round #658 (Div. 2)
  7. Tomcat 的 Server 文件配置详解
  8. x86汇编语言——处理器架构
  9. python解析xml生成代码_python解析xml模块封装代码
  10. memcached全面剖析–2. 理解memcached的内存存储
  11. 计算机清理的作用,电脑也有自带的垃圾清理功能,甚至比众多清理软件更好用!...
  12. html5音乐播放器在线生成,一款极简的HTML5音乐播放器-skPlayer
  13. 省市定位(省市区三级联动插件Distpicker)
  14. SQL Server 无法启动WMI服务
  15. java gwt开发_java – 如何启动GWT超级开发模式
  16. linux中括号的用法,全面梳理linux下shell中各种括号的作用和用法
  17. 梆梆加固函数抽取执行流程
  18. 哈工大计算机系名单,哈工大计算机学部公布拟录取名单,计算机科学与技术仅录29人!...
  19. node.js 安装,详细步骤教程
  20. 保险知识(一):五大险种入门

热门文章

  1. 请求的资源不可用html,Eclipse请求的资源不可用。
  2. SAP官网学习教程(1)申请个人学习环境
  3. 简易新闻系统,功能包含用户登录、新闻发布删除、评论管理等
  4. Matlab:写入到 Diary 文件
  5. 基于spaCy的领域命名实体识别
  6. 软件开发工程师转正申请书
  7. 微信web开发工具如何使用_优秀的设计师和开发人员使用出色的Web开发工具
  8. springboot+thymeleaf实例
  9. 调用Nero SDK 刻录光盘(含代码)
  10. 港科夜闻|香港科大新任校长叶玉如教授回应施政报告