「while read」循環遍歷文字檔案中的行,遺失 Bash 腳本中的字元。是FFmpeg線路的錯嗎?

「while read」循環遍歷文字檔案中的行,遺失 Bash 腳本中的字元。是FFmpeg線路的錯嗎?

我正在使用“讀取時”循環遍歷文字檔案。我從每一行讀取三個變數 - 兩個檔案名稱和一個十進制數。我知道這適用於普通設定(循環、讀取行、回顯行、提取變量,僅此而已),因為我已經在輸入文件上測試了它。

不過,一旦我添加了我的例程的主要部分,即調用 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但它需要一個外殼。

答案2

您可能是對的,ffmpeg 可能正在從您的輸入中讀取,誰知道為什麼,所以只需將該命令重定向到 read from /dev/null,即添加到 ffmpeg line </dev/null

相關內容