You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++通过Boost调用FFmpeg失败,终端执行正常问题排查

Boost启动FFmpeg进程时滤镜链解析失败的问题

错误信息

[AVFilterGraph @ 0x3cfadc0] Error parsing filterchain "[0:v]split=3[v1][v2][v3];[v1]copy[v1out];[v2]scale=w=1280:h=720[v2out];[v3]scale=w=640:h=360[v3out]"
    
[AVFilterGraph @ 0x2f9fb00] Error parsing filterchain 
    
[AVFilterGraph @ 0x3cfadc0] Trailing garbage after a filter: split=3[v1][v2][v3];[v1]copy[v1out];[v2]scale=w=1280:h=720[v2out];[v3]scale=w=640:h=360[v3out]

代码实现

std::vector<std::string> args;
args.push_back("-i"); args.push_back("input.mp4");
args.push_back("-filter_complex");
args.push_back("\"[0:v]split=3[v1][v2][v3];[v1]copy[v1out];[v2]scale=w=1280:h=720[v2out];[v3]scale=w=640:h=360[v3out]\"");

args.push_back("-map");  args.push_back("[v1out]");
args.push_back("-c:v:0");  args.push_back("libx264");
args.push_back("-x264-params");  args.push_back("\"nal-hrd=cbr:force-cfr=1\"");
args.push_back("-b:v:0");  args.push_back("1M");
args.push_back("-maxrate:v:0");  args.push_back("2M");
args.push_back("-minrate:v:0");  args.push_back("2M");
args.push_back("-bufsize:v:0");  args.push_back("2M");
args.push_back("-preset");  args.push_back("fast");
args.push_back("-g");  args.push_back("48");
args.push_back("-sc_threshold");  args.push_back("0");
args.push_back("-keyint_min");  args.push_back("48");

args.push_back("-map");  args.push_back("[v2out]");
args.push_back("-c:v:1");  args.push_back("libx264");
args.push_back("-x264-params");  args.push_back("\"nal-hrd=cbr:force-cfr=1\"");
args.push_back("-b:v:1");  args.push_back("1M");
args.push_back("-maxrate:v:1");  args.push_back("1M");
args.push_back("-minrate:v:1");  args.push_back("1M");
args.push_back("-bufsize:v:1");  args.push_back("1M");
args.push_back("-preset");  args.push_back("fast");
args.push_back("-g");  args.push_back("48");
args.push_back("-sc_threshold");  args.push_back("0");
args.push_back("-keyint_min");  args.push_back("48");

args.push_back("-map");  args.push_back("[v3out]");
args.push_back("-c:v:2");  args.push_back("libx264");
args.push_back("-x264-params");  args.push_back("\"nal-hrd=cbr:force-cfr=1\"");
args.push_back("-b:v:2");  args.push_back("500K");
args.push_back("-maxrate:v:2");  args.push_back("500K");
args.push_back("-minrate:v:2");  args.push_back("500K");
args.push_back("-bufsize:v:2");  args.push_back("500K");
args.push_back("-preset");  args.push_back("fast");
args.push_back("-g");  args.push_back("48");
args.push_back("-sc_threshold");  args.push_back("0");
args.push_back("-keyint_min");  args.push_back("48");

args.push_back("-map");  args.push_back("a:0");
args.push_back("-c:a:0");  args.push_back("aac");
args.push_back("-b:a:0");  args.push_back("96k");
args.push_back("-ac");  args.push_back("2");
args.push_back("-map");  args.push_back("a:0");
args.push_back("-c:a:1");  args.push_back("aac");
args.push_back("-b:a:1");  args.push_back("96k");
args.push_back("-ac");  args.push_back("2");
args.push_back("-map");  args.push_back("a:0");
args.push_back("-c:a:2");  args.push_back("aac");
args.push_back("-b:a:2");  args.push_back("48k");
args.push_back("-ac");  args.push_back("2");

args.push_back("-avoid_negative_ts");  args.push_back("1");
args.push_back("-f");  args.push_back("hls");
args.push_back("-hls_time");  args.push_back("6");
args.push_back("-hls_list_size");  args.push_back("15");
args.push_back("-hls_flags");  args.push_back("independent_segments");
args.push_back("-hls_segment_type");  args.push_back("mpegts");
args.push_back("-hls_segment_filename");  args.push_back("/output/stream_%v_data%02d.ts");
args.push_back("-master_pl_name");  args.push_back("index.m3u8");
args.push_back("-var_stream_map");  args.push_back("\"v:0,a:0 v:1,a:1 v:2,a:2\"");
args.push_back("/output/stream_%v.m3u8");


m_childProcess = std::make_unique<bp::child>(
            bp::exe = ffmpegPath,
            bp::args = args);

代码生成的命令(格式化后)

ffmpeg -i input.mp4 -c copy -filter_complex "[0:v]split=3[v1][v2][v3];[v1]copy[v1out];[v2]scale=w=1280:h=720[v2out];[v3]scale=w=640:h=360[v3out]" 
-map [v1out] -c:v:0 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:0 1M -maxrate:v:0 2M -minrate:v:0 2M -bufsize:v:0 2M -preset fast -g 48 -sc_threshold 0 -keyint_min 48 
-map [v2out] -c:v:1 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:1 1M -maxrate:v:1 1M -minrate:v:1 1M -bufsize:v:1 1M -preset fast -g 48 -sc_threshold 0 -keyint_min 48  
-map [v3out] -c:v:2 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:2 500K -maxrate:v:2 500K -minrate:v:2 500K -bufsize:v:2 500K -preset fast -g 48 -sc_threshold 0 -keyint_min 48 -map a:0 -c:a:0 aac -b:a:0 96k -ac 2 
-map a:0 -c:a:1 aac -b:a:1 96k -ac 2 -map a:0 -c:a:2 aac -b:a:2 48k -ac 2 
-avoid_negative_ts 1 -f hls -hls_time 6 -hls_list_size 15 -hls_flags independent_segments -hls_segment_type mpegts -hls_segment_filename /output/stream_%v_data%02d.ts -master_pl_name index.m3u8 -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" /output/stream_%v.m3u8

问题原因及解决办法

问题出在参数中多余的双引号:

  • 终端里用双引号是为了让Shell把包含分号、空格等特殊字符的内容识别为单个参数,但Boost的bp::args是直接将每个元素作为独立参数传递给FFmpeg,不需要额外加引号。
  • 你代码中给-filter_complex、-x264-params、-var_stream_map的参数加了\",这些引号会被FFmpeg当作参数内容的一部分解析,导致滤镜链内容包含多余的首尾引号,触发"Trailing garbage"解析错误。

修改方法:去掉所有参数前后的双引号,示例如下:

// 原错误写法
// args.push_back("\"[0:v]split=3[v1][v2][v3];[v1]copy[v1out];[v2]scale=w=1280:h=720[v2out];[v3]scale=w=640:h=360[v3out]\"");
// 修改后
args.push_back("[0:v]split=3[v1][v2][v3];[v1]copy[v1out];[v2]scale=w=1280:h=720[v2out];[v3]scale=w=640:h=360[v3out]");

// 原错误写法
// args.push_back("\"nal-hrd=cbr:force-cfr=1\"");
// 修改后
args.push_back("nal-hrd=cbr:force-cfr=1");

// 原错误写法
// args.push_back("\"v:0,a:0 v:1,a:1 v:2,a:2\"");
// 修改后
args.push_back("v:0,a:0 v:1,a:1 v:2,a:2");

内容的提问来源于stack exchange,提问作者Pit Digger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 03:17:24