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点播,还有一些其他的问题需要解决,我将在下一篇文章中介绍。

MP4文件格式的解析,以及MP4文件的分割算法相关推荐

  1. java 解析mp4_MP4文件格式的解析,以及MP4文件的分割算法

    MP4文件格式的解析,以及MP4文件的分割算法 mp4应该算是一种比较复杂的媒体格式了,起源于QuickTime.以前研究的时候就花了一番的功夫,尤其是如何把它完美的融入到视频点播应用中,更是费尽了心 ...

  2. MP4 | MP4文件格式的解析

    参考资料: 1.MP4文件格式的解析,以及MP4文件的切割算法 2.mp4文件解析(纯c解析代码) 3.MP4文件格式详解--元数据moov(一)mvhd box 4.音视频解封装:MP4核心Box详 ...

  3. [转]MP4文件格式的解析及分割算法

    目前MP4的概念被炒得很火,也很乱.最开始MP4指的是音频(MP3的升级版),即MPEG-2 AAC标准.随后MP4概念被转移到视频上,对应的是MPEG-4标准.而现在我们流行的叫法,多半是指能播放M ...

  4. MP4文件格式简要解析

    准备 安装mediaInfo.QTAtomViewer.exe.MP4info.exe等软件 视频一些参数 封装格式:我也不太清楚 编码格式:我也不太清楚 分辨率:图像的长和宽. 帧率:一秒播放的图片 ...

  5. MP4文件格式简要解析---代码解析

    准备 安装mediaInfo.QTAtomViewer.exe.MP4info.exe等软件 视频一些参数 封装格式:我也不太清楚 编码格式:我也不太清楚 分辨率:图像的长和宽. 帧率:一秒播放的图片 ...

  6. MP4文件格式简要解析——图文代码并茂

    http://blog.csdn.net/chenshengfa/article/details/50512616 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 准备 安装m ...

  7. 第七季1:MP4文件格式解析

    以下内容源于朱有鹏课程,如有侵权,请告知删除. 本季内容 (1)将编解码得到的视频打包成mp4格式并存储到TF卡 MP4的组织形式和box解析 移植和使用mp4v2开源库来打包MP4 进一步研究MP4 ...

  8. 关于MP4文件格式解析

    MP4 文件格式 综述 关键概念 MP4 文件格式中,所有的内容存在一个称为movie的容器中.一个movie 可以由多个tracks 组成.每个track就是一个随时间变化的媒体序列,例如,视频帧序 ...

  9. MP4文件格式分析及分割实现(附源码)

    MP4文件格式分析及分割实现(附源码) MP4文件格式分析                   MP4(MPEG-4 Part 14)是一种常见的多媒体容器格式,它是在"ISO/IEC 14 ...

最新文章

  1. 为ubuntu操作系统增加root用户
  2. idea将项目打成jar包
  3. Java黑皮书课后题第3章:*3.25(几何:交点)第一条直线上面的两个点是(x1,y1)(x2,y2),第二条(x3,y3)(x4,y4),通过Cramer规则求出线性方程组
  4. mysql慢查询日志轮转_MySQL slow log相关参数解释
  5. javafx应用启动自动执行函数_JavaFx:Application start方法中的异常
  6. 一起谈.NET技术,巨大转变!ASP.NET MVC2调用AJAX新特征
  7. [Mac]图像处理JPEG工具箱jpegtbx_1.4的MATLAB编译及使用
  8. android 控制手机音量大小,android 控制手机音量的大小 切换声音的模式
  9. 弘辽科技:淘宝开店类别怎么选择?淘宝开店如何选类目?
  10. 安装xdg-open
  11. 平板xmind怎么添加父主题_XMind8主题使用教程
  12. Linux7安装oracle11g报错 Error in invoking target ‘agent nmhs‘ of makefile “ins_emagent.mk”
  13. hexo+yilia修改代码块等样式
  14. 使用pgAdmin把Excel文件导入PostgreSql数据库
  15. systemd 知:介绍
  16. Python基础模块:图像处理模块@PIL(批量分类处理图片及添加水印)
  17. TX2安装opencv3.4.0
  18. 杂念参加完了广东互联网大会的一些感想
  19. Dell R720 安装 win2003 64位 的安装步骤以及注意事项
  20. C# 根据汉字获取首字母拼音或全拼

热门文章

  1. Android动态方式破解apk进阶篇(IDA调试so源码)
  2. C# WinForm 在窗口菜单上显示已打开窗体的标题及其窗体的排列
  3. laravel 验证器怎么验证json对象_Postman使用tv4进行JSON Schema结构验证和断言
  4. 零基础学python看什么书-转行零基础该如何学习python?很庆幸,三年前的我选对了...
  5. 零基础代码学python-零基础学python之构建web应用(入门级)
  6. python怎么输入代码-教你如何将自己的脚本代码放到服务器上运行
  7. python绘制灰度图片直方图-python数字图像处理(9):直方图与均衡化
  8. python编码读法-python读音
  9. python编写一个软件-使用python制作一个解压缩软件
  10. python学习框架图-从零搭建深度学习框架(二)用Python实现计算图和自动微分