使用mp4v2将aac音频h264视频数据封装成mp4开发心得

这阵子在捣鼓一个将游戏视频打包成本地可播放文件的模块。开始使用avi作为容器,弄了半天无奈avi对aac的支持实在有限,在播放时音视频时无法完美同步。

关于这点avi文档中有提到:

For AAC, one RAW AAC frame usually spans over 1024 samples. However, depending on
the source container (e.g. ADTS), it is theoretically possible that you are not able to extract
packets of equal duration from your source le. In this case, it is highly recommended not
to mux the AAC stream into AVI, but report a fatal error instead.

因此建议大家不要用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得到,下面是我的代码:

unsigned int CAACCodec::GetDecoderSpecificInfo(unsigned char * & apInfo)
{
    if ( m_hCodec == NULL )
    {
        return 0;
    }

    unsigned long uLen = 0;
    faacEncGetDecoderSpecificInfo(m_hCodec, &apInfo, &uLen);
    return uLen;
}

将返回的信息,再用MP4SetTrackESConfiguration设置到音频track里去就ok了。

这里有个问题还要注意下,解码信息这块内存,是faac用malloc方式分配出来的,所以你不要忘记free它,否则会造成内存泄露(虽然很小,才2字节)


好了,以上就是我的一些心得,希望对你有帮助。打字不容易,转载请注明出处:)


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用 MP4v2 AAC 编码音频写 M4A 文件可以通过以下步骤完: 首先,需要准备好要写入的音频数据,并使用 AAC 编码格式进行编码AAC 是一种广泛使用音频编码格式,可以提供高质量的音频压缩。可以使用 MP4v2 库中的编码器功能将音频数据转换为 AAC 格式。 接下来,在使用 MP4v2 库之前,需要确保已经正确安装和配置了该库。根据操作系统的不同,可以在官方网站上找到相关的安装和配置指南。 一旦确认库的安装和配置完毕,就可以开始编写代码了。首先,需要导入 MP4v2 库,并创建一个 MP4 文件对象。然后,通过调用 MP4SetAudioProfileLevel 函数设置音频编码参数,例如比特率、声道数等。 接下来,需要将编码后的 AAC 音频数据写入 M4A 文件。可以使用 MP4WriteSample 函数来实现这一步骤。需要注意的是,写入音频数据时需要指定音频帧的时间戳,以确保音频数据的顺序正确。 最后,需要调用 MP4Close 函数来关闭文件,保存并释放资源。 使用 MP4v2 AAC 编码音频写 M4A 文件的示例代码如下: ```cpp #include <mp4v2/mp4v2.h> void writeM4AFile(const char* audioFileName, const char* outputFile) { MP4FileHandle fileHandle = MP4Create(outputFile); // 设置音频编码参数 MP4SetAudioProfileLevel(fileHandle, 0x2); // AAC-LC MP4SetAudioChannels(fileHandle, 2); // 声道数 MP4SetAudioDuration(fileHandle, 0); // 设置音频时长(可选) MP4SetAudioProfileLevel(fileHandle, 0x15); // 采样率 // 打开音频文件 FILE* audioFile = fopen(audioFileName, "rb"); if (audioFile != NULL) { // 读取音频数据并写入 M4A 文件 while (!feof(audioFile)) { unsigned char buffer[1024]; size_t bytesRead = fread(buffer, 1, sizeof(buffer), audioFile); MP4WriteSample(fileHandle, 1, buffer, bytesRead, MP4_INVALID_DURATION, 0, 1); } fclose(audioFile); } // 关闭文件,保存并释放资源 MP4Close(fileHandle, MP4_CLOSE_DO_NOT_COMPUTE); } int main() { const char* audioFileName = "audio.pcm"; const char* outputFile = "output.m4a"; writeM4AFile(audioFileName, outputFile); return 0; } ``` 上述代码是一个简单的示例,需要根据具体的需求进行适当的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值