这阵子在捣鼓一个将游戏视频打包成本地可播放文件的模块。开始使用avi作为容器,弄了半天无奈avi对aac的支持实在有限,在播放时音视频时无法完美同步。 关于这点avi文档中有提到: For AAC, one RAW AAC frame usually spans over 1024 samples. However, depending on 因此建议大家不要用avi打包aac,如果实在需要avi格式,可以换成mp3。
言归正传,下面重点说说mp4打包时遇到的几个问题,希望对后来开发这方面的朋友能有帮助,少走弯路。 首先需要下载编译开源的mp4v2库。这里一般没什么问题,值得一提的是,mp4v2静态库会导出函数符号。如果你想让程序瘦身,可以这么做在 windows的工程属性中去掉MP4V2_EXPORTS预定义,添加MP4V2_USE_STATIC_LIB,这样最终的程序可以小100多KB。 mp4v2在vc2008下编译release版会在link时出现link内部错误(我遇到了,不知道其他人是否也遇到),需要在工程中去掉link时优化,再编译即可。 使用mp4v2打包音视频的具体步骤网上已经有很多例子,不再此啰嗦了,就说说需要注意的几点吧。 1、音频aac不需要包含adts头,即在设置faac选项时: struConfig.outputFormat = 0; /* Bitstream output format (0 = Raw; 1 = ADTS) */ 如果你包含了这个头,我测试下来迅雷播放器可以支持,但是百度影音、暴风影音放出来没声音。(ps,我整个开发过程下来迅雷播放器支持度最好,百度和暴风影音在格式设置错误情况下会出现崩溃和无声音现象,绝非广告) 2、MP4AddAudioTrack时,注意第三个参数sampleDuration要设置正确。如果每次添加的音频数据样本数相同,可以在这里 先设置好。mp4v2建议把刻度设置为采样率,这样第三个参数就是每次送入数据块的样本数。这个数据可以在编码aac时得到,faacEncOpen返回 的input样本数如果是2048,那么双通道实际就是1024。 3、设置完这些参数后,本以为万事大吉,但是播放器放出来还是没有声音。那就需要用MP4SetTrackESConfiguration设置音频 解码信息。音频解码信息怎么来,可以从faac里faacEncGetDecoderSpecificInfo得到,下面是我的代码:
将返回的信息,再用MP4SetTrackESConfiguration设置到音频track里去就ok了。 这里有个问题还要注意下,解码信息这块内存,是faac用malloc方式分配出来的,所以你不要忘记free它,否则会造成内存泄露(虽然很小,才2字节)
好了,以上就是我的一些心得,希望对你有帮助。打字不容易,转载请注明出处:) 有问题可进 “c++音视频讨论群” 16685004 (mywfool) |