为什么 FFmpeg 在 while 循环中需要 nostdin?

为什么 FFmpeg 在 while 循环中需要 nostdin?

如果我有:

for i in *.mov;
do
ffmpeg -y -i $i -c:v copy -c:a copy ${i%%.mov}.mp4
done

运行正常。但如果我运行:

find . -name "*.ts" -print0 | while read -d $'\0' file;
do
  ffmpeg -i "$file" -c copy -map 0 "${file%%.ts}_rec.mp4";
done

这失败了。我需要输入 -nostdin。

find . -name "*.ts" -print0 | while read -d $'\0' file;
do
  ffmpeg -nostdin -i "$file" -c copy -map 0 "${file%%.ts}_rec.mp4";
done

文档解释说,这会禁用标准输入上的交互,并且对后台进程有帮助。

为什么在第二种情况下 FFmpeg 是后台进程?还是有其他问题?

答案1

FFmpeg 在这里不是后台进程。它只是读取它的stdin。它可能不是,但它确实会读取。这会消耗本应写入 的字符read。实际上,您可能会遇到类似这样的问题:

'while read' 循环遍历文本文件中的行,在 Bash 脚本中丢失字符。是 FFmpeg 行造成的吗?


文档中提到了后台进程,因为通常你不希望尤其是他们读取stdin。就你的情况而言,你不希望前台 FFmpeg 读取它的stdin

答案2

工作循环和非工作循环之间的区别是 | 创建了一个子 shell。

如果我没记错的话,我只需使用就可以解决这个问题echo "" | ffmpeg ...

来自 ffmpeg man:-stdin 启用标准输入上的交互。除非使用标准输入作为输入,否则默认启用。要明确禁用交互,您需要指定“-nostdin”。

       Disabling interaction on standard input is useful, for example, if ffmpeg is in the background process
       group. Roughly the same result can be achieved with "ffmpeg ... < /dev/null" but it requires a shell.

echo "" | ffmpeg是相同的ffmpeg ... < /dev/null

相关内容