FFMPEG C++无法设置AAC_LC编码,音频兼容性问题求助
录屏工具MP4音频兼容性问题解决
问题背景
用C++结合FFmpeg开发带麦克风录制的录屏工具,遇到以下问题:
- 输出的MP4文件仅能在VLC播放器正常播放音视频
- Windows媒体播放器、其他桌面播放器及移动端播放时,只有视频没有音频
- 用FFmpeg命令行
ffmpeg -i myfile.mp4 output.mp4重新编码后,output.mp4可在所有播放器正常播放
通过ffprobe对比原文件和重编码文件的音频流:
ffprobe -show_streams -select_streams a -i myfile.mp4 ffprobe -show_streams -select_streams a -i output.mp4
发现核心差异:原文件音频流的profile=-1,重编码后的文件音频profile=LC。尝试在代码多处设置AAC_LC编码,但始终无效。
当前代码的问题
原代码中参数设置顺序和传递逻辑有误:
- 先设置
AVCodecParameters再同步到AVCodecContext,可能导致profile被覆盖 - 打开编码器时未传入包含
profile的参数字典,编码器可能未正确识别设置
原代码片段:
// 省略部分变量定义 av_codec_par_out->profile = FF_PROFILE_AAC_LOW; av_dict_set(&options, "profile", "aac_low", 0); avformat_open_input(&ifmt_ctx, "my audio device name", ifmt, &options); av_codec_out = avcodec_find_encoder(av_codec_par_out->codec_id); av_cntx_out = avcodec_alloc_context3(av_codec_out); avcodec_parameters_to_context(av_cntx_out, av_codec_par_out); av_cntx_out->profile = FF_PROFILE_AAC_LOW; avcodec_parameters_copy(av_stream->codecpar, av_codec_par_out); avcodec_open2(av_cntx_out, av_codec_out, NULL);
修正方案
调整参数设置逻辑,确保编码器上下文正确接收并应用AAC_LC profile:
修正后的音频编码器设置代码
const AVCodec* av_codec_out; AVCodecContext* av_cntx_out; AVStream* av_stream; // 1. 查找AAC编码器 av_codec_out = avcodec_find_encoder(AV_CODEC_ID_AAC); if (!av_codec_out) { // 处理编码器查找失败逻辑 return -1; } // 2. 分配编码器上下文 av_cntx_out = avcodec_alloc_context3(av_codec_out); if (!av_cntx_out) { // 处理上下文分配失败逻辑 return -1; } // 3. 直接在编码器上下文设置关键参数 av_cntx_out->codec_id = AV_CODEC_ID_AAC; av_cntx_out->codec_type = AVMEDIA_TYPE_AUDIO; av_cntx_out->bit_rate = 128000; av_cntx_out->sample_fmt = AV_SAMPLE_FMT_FLTP; av_cntx_out->sample_rate = 44100; av_cntx_out->channels = 2; av_cntx_out->channel_layout = AV_CH_LAYOUT_STEREO; // 明确设置声道布局 av_cntx_out->time_base = {1, 44100}; av_cntx_out->profile = FF_PROFILE_AAC_LOW; // 核心:直接设置profile av_cntx_out->strict_std_compliance = FF_COMPLIANCE_NORMAL; // 4. 创建输出流 av_stream = avformat_new_stream(ofmt_ctx, av_codec_out); if (!av_stream) { // 处理流创建失败逻辑 return -1; } // 5. 将编码器上下文参数同步到流的codecpar if (avcodec_parameters_from_context(av_stream->codecpar, av_cntx_out) < 0) { // 处理参数同步失败逻辑 return -1; } // 6. 打开编码器,传入参数字典确保profile生效 AVDictionary* options = NULL; av_dict_set(&options, "profile", "aac_low", 0); int ret = avcodec_open2(av_cntx_out, av_codec_out, &options); av_dict_free(&options); // 释放字典资源 if (ret < 0) { // 处理编码器打开失败逻辑 return -1; }
关键修正点
- 直接在
AVCodecContext上设置profile,避免参数被后续同步操作覆盖 - 使用
avcodec_parameters_from_context将编码器上下文参数同步到流的codecpar,确保流的参数和编码器一致 - 打开编码器时传入包含
profile的参数字典,双重保证编码器使用AAC_LC编码 - 明确设置
channel_layout,避免播放器解析音频通道时出现异常
内容的提问来源于stack exchange,提问作者Arun K
相关产品推荐
相关产品推荐

