如果我有:
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