批量执行FFmpeg切割命令时半数文件被跳过的原因排查
批量执行FFmpeg切割命令时半数文件被跳过的原因排查
兄弟,我一眼就看出问题出在哪了——根本不是时间重叠的锅,是FFmpeg和你的while read循环抢标准输入(stdin)导致的!
问题根源
当你用这条命令循环执行脚本时:
while read -r line; do eval "$line"; done < commands.txt
整个循环的标准输入(stdin)被绑定到了commands.txt文件。而FFmpeg默认会读取stdin来接收用户交互指令(比如中途按q停止转码),所以第一个FFmpeg命令运行时,会把commands.txt里剩下的所有行都当作自己的输入给“吞掉”了!
这就导致read命令只能拿到第1、3、5...这些奇数行的命令,自然只生成了对应的文件——哪怕你修改了时间区间,只要这个stdin冲突的问题没解决,就还是会跳过半数文件。
解决办法
这里给你几个简单的修复方案,任选其一就行:
方案1:给FFmpeg加-nostdin参数
直接在每个FFmpeg命令里加上-nostdin,让它不要读取stdin:
ffmpeg -nostdin -ss 00:00 -i TGP.mp4 -ss 00:00:00 -to 00:44:01 -c copy '01_Myles_Burnyeat_on_Plato.mp4'
把commands.txt里的所有命令都加上这个参数,再重新运行循环就没问题了。
方案2:循环里把FFmpeg的stdin重定向到/dev/null
不用修改原命令,直接在循环里把FFmpeg的输入指向空设备:
while read -r line; do eval "$line" < /dev/null; done < commands.txt
这样FFmpeg就不会去读commands.txt的内容了。
方案3:用独立文件描述符读取命令文件
换一种方式读取commands.txt,用文件描述符3来读取,避免和FFmpeg的stdin冲突:
while read -r line <&3; do eval "$line"; done 3< commands.txt
这种方式也能彻底避免stdin争抢的问题。
验证一下
你可以先手动执行一条偶数行的命令,比如第二条:
ffmpeg -ss 00:00 -i TGP.mp4 -ss 00:43:57 -to 01:27:26 -c copy '02_Martha_Nussbaum_on_Aristotle.mp4'
肯定能正常生成文件,这就说明命令本身没问题,就是循环时的stdin冲突导致的。
备注:内容来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

