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

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

我正在使用“while read”循环遍历一个文本文件。我从每一行读取三个变量 - 两个文件名和一个十进制数。我知道这在 vanilla 设置(循环、读取行、回显行、提取变量,没有其他内容)中有效,因为我已经在输入文件上对其进行了测试。

不过,当我添加例程的核心部分时,我得到了一个奇怪的结果 - 即调用 ffmpeg 来合并文件名所代表的音频和视频流。连续的“读取”操作会省略行中的前导字符。我读到这里在“while read”循环中调用“read”输入可能会导致问题,并且想知道 ffmpeg 调用是否正在做一些让 bash 感到困惑的事情,但这似乎不太可能而且很奇怪!注意:我不太了解 ffmpeg 调用——我是从另一个问题的答案中得到它的。

任何帮助,将不胜感激!

第一个“读取”按预期工作(并且 ffmpeg 命令完成):

LINE  1
vidsNeedingSound/448£generic@06_10_16-09_30_47.mp4 soundToAdd/448£generic@06_10_16-12_11_54.wav 6.988354
V: vidsNeedingSound/448£generic@06_10_16-09_30_47.mp4   A: soundToAdd/448£generic@06_10_16-12_11_54.wav   D: 6.988354

第二次“读取”丢失了行首的 36 个字符(并且 ffmpeg 命令失败,因为取该行第一项的变量 V 所表示的文件没有指向文件):

LINE  2
6-09_30_47.mp4 soundToAdd/452£generic@06_10_16-12_11_54.wav 9.64663
V: 6-09_30_47.mp4   A: soundToAdd/452...

第三次“读取”按预期工作(并且 ffmpeg 命令完成):

LINE  3
vidsNeedingSound/452£left@06_10_16-09_30_47.mp4 soundToAdd/452£left@06_10_16-12_11_54.wav 9.862118
V: vidsNeedingSound/452£left@06_10_16-09_30_47.mp4   A: soundToAdd/452...

第四次“读取”从行首丢失 37 个字符(比上一次失败多一个)(并且 ffmpeg 命令失败):

LINE  4
09_30_47.mp4 soundToAdd/452£right@06_10_16-12_11_54.wav 9.431392
V: 09_30_47.mp4   A: soundToAdd/452....

这就是模式。如果没有成功调用 ffmpeg,则“读取”将按预期工作。每次成功调用 ffmpeg 后,行首的字符都会被省略:首先是 36 个字符,然后是 37、38、39...

关键在于,当 ffmpeg 在“成功”读取后失败(由于另一个问题)时,接下来的“读取”仍按预期工作。

结论:成功调用 ffmpeg 会导致循环下一次迭代时读取失败。

为什么会发生这种情况?我该如何阻止它?

这是我的代码:...

# Loop through lines in the merge file
IT_COUNT=1
while read MERGE_LINE           
    do         
    echo "LINE " $IT_COUNT
    ((IT_COUNT+=1))
    echo $MERGE_LINE   # testing use
    read VID_FILE AUD_FILE DURATION <<< "$MERGE_LINE" # Get the data from each line
    echo "V: $VID_FILE   A: $AUD_FILE   D: $DURATION"         # testing use
....
    # add audio to video
    ffmpeg -i $VID_FILE -i $AUD_FILE -filter_complex "aevalsrc=0:d=$AUD_SHIFT[s1];[s1][1:a]concat=n=2:v=0:a=1[aout]" -c:v copy -map 0:v -map [aout] $FILE_OUT -hide_banner

done <$MERGE_FILE  

谢谢你的观看!

答案1

使用-nostdin中的选项ffmpeg。从FFmpeg 文档

启用标准输入上的交互。除非使用标准输入作为输入,否则默认启用。要明确禁用交互,您需要指定-nostdin

禁用标准输入上的交互很有用,例如,如果 ffmpeg 位于后台进程组中。使用 可以实现大致相同的结果,ffmpeg ... < /dev/null但它需要一个 shell。

答案2

您可能是对的,ffmpeg 可能正在读取您的输入,谁知道为什么,所以只需将该命令重定向到读取/dev/null,即添加到 ffmpeg 行</dev/null

相关内容