使用ffmpeg拼接无音频MP4文件失败,生成0字节文件无法正常打开
问题根因&修复方案
1. Java调用外部进程缓冲区阻塞
当前executeCMD方法只启动进程并等待结束,未消费进程的标准输出/错误输出,当ffmpeg输出的日志占满系统缓冲区后,进程会被直接挂起停止运行,最终生成0字节文件。
修正后的executeCMD方法:
private boolean executeCMD(ProcessBuilder pb) { pb.redirectErrorStream(true); Process p = null; BufferedReader reader = null; try { p = pb.start(); // 消费进程输出日志,避免缓冲区阻塞 reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; // 可打印日志定位ffmpeg执行报错原因 while ((line = reader.readLine()) != null) { System.out.println("ffmpeg log: " + line); } int exitCode = p.waitFor(); // ffmpeg正常执行完成的退出码为0,非0代表执行出错 return exitCode == 0; } catch (Exception ex) { ex.printStackTrace(); return false; } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (p != null) { p.destroy(); } } }
2. concat demuxer参数顺序错误
你当前写的demuxer参数顺序有误,-safe 0是concat demuxer的专属参数,需要放在-i参数之前,正确的cmd1数组应为:
String[] cmd1 = {ffmpegPath, "-f", "concat", "-safe", "0", "-i", "/Users/JL/Documents/workspace/VidTest/src/concat.txt", "-c:v", "copy", tempVidPath};
3. ffmpeg路径校验
Mac环境下通过Homebrew安装的ffmpeg默认路径为/usr/local/bin/ffmpeg,你填写的/usr/bin/local/ffmpeg大概率存在路径错误,可先打开终端执行which ffmpeg获取真实路径后替换即可。
4. concat滤镜方案参数优化
如果使用concat滤镜方案,可补充编码器参数避免默认编码器兼容问题:
String[] cmd1 = {ffmpegPath, "-i", tempA, "-i", tempB, "-filter_complex", "[0:v][1:v]concat=n=2:v=1:a=0[out]", "-map", "[out]", "-c:v", "libx264", "-pix_fmt", "yuv420p", tempVidPath};
额外排查点
使用concat demuxer的copy模式时,需要保证两个输入视频的编码格式、分辨率、帧率完全一致,否则会执行失败,若两个视频参数不一致直接用滤镜方案重新编码即可。
内容的提问来源于stack exchange,提问作者jjli19
相关产品推荐
相关产品推荐

