1.了解mp4结构
Mp4文件解析如下:
http://blog.sina.com.cn/s/blog_48f93b530100jz4b.html
其中比较重要的是moov结构里的mvhd。
Movie Box(moov)
Movie Header Box(mvhd)
字段 | 字节数 | 意义 |
box size | 4 | box大小 |
box type | 4 | box类型 |
version | 1 | box版本,0或1,一般为0。(以下字节数均按version=0) |
flags | 3 | |
creation time | 4 | 创建时间(相对于UTC时间1904-01-01零点的秒数) |
modification time | 4 | 修改时间 |
time scale | 4 | 文件媒体在1秒时间内的刻度值,可以理解为1秒长度的时间单元数 |
duration | 4 | 该track的时间长度,用duration和time scale值可以计算track时长,比如audio track的time scale = 8000, duration = 560128,时长为70.016,video track的time scale = 600, duration = 42000,时长为70 |
rate | 4 | 推荐播放速率,高16位和低16位分别为小数点整数部分和小数部分,即[16.16] 格式,该值为1.0(0x00010000)表示正常前向播放 |
volume | 2 | 与rate类似,[8.8] 格式,1.0(0x0100)表示最大音量 |
reserved | 10 | 保留位 |
matrix | 36 | 视频变换矩阵 |
pre-defined | 24 | |
next track id | 4 | 下一个track使用的id号 |
2.定位不能边缓冲边播放的原因
mp4是很多box的嵌套,最上层box包括ftyp,free,moov,mdat等等,其中moov存放着视频详细描述,算是索引,
而mdat存放着视频的具体信息。那么需要播放的时候,先必须拿到moov,在实际的mp4打包中,moov可能被放到了mdat后面,
导致了文件不被下载完的时候无法获取moov,而无法边缓存边播放。
3.实现边缓冲边播放
使用FFmpeg编码时,确实是没有特殊处理,如果想要将moov放到文件头,指令的方式是 加上 -movflags faststart。代码的方式是:
AVDictionary* pOpts = NULL;
if (m_pVideoState->pFormatCtxEnc->oformat->video_codec == AV_CODEC_ID_H264)
{
av_dict_set(&pOpts, "movflags", "faststart", 0);
}
if ((nRet = avformat_write_header(m_pVideoState->pFormatCtxEnc, &pOpts)) == 0)
4.参考网址:
mp4文件格式解析:http://blog.sina.com.cn/s/blog_48f93b530100jz4b.html
ffmpeg对H264 faststart方式说明:
http://www.ffmpeg.org/ffmpeg-formats.html