2

I am looping through a text file, using 'while read'. I read three variables from each line - two filenames and a decimal number. I know that this works in a vanilla setup (loop, read line, echo line, extract variables, nothing else), because I have tested it on my input file.

I am getting an odd result, though, once I add in the meat of my routine - which is a call to ffmpeg to merge the audio and video streams represented by the filenames. Successive 'read' operations omit leading characters from the line. I read here that calls for 'read' input within a 'while read' loop can cause problems, and wonder if the ffmpeg call is doing something that confuses bash, but this seems unlikely and bizarre! NB: I don't really understand the ffmpeg call - I got it from an answer to another question.

Any help would be appreciated!

The first 'read' works as expected (and the ffmpeg command completes):

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

The second 'read' loses 36 characters from the beginning of the line (and the ffmpeg command fails because the file represented by the variable V which takes the first item of the line doesn't point at a file):

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...

The third 'read' works as expected (and the ffmpeg command completes):

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...

The fourth 'read' loses 37 character (one more than the last fail) from the beginning of the line (and the ffmpeg command fails):

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....

That's the pattern. When not preceded by a successful call to ffmpeg, the 'read' works as expected. After each successive successful ffmpeg call, characters are omitted from the beginning of the line: 36 characters to begin with, then 37, 38, 39...

The clincher is that when ffmpeg fails after a 'successful' read (due to another problem), the following 'read' works as expected.

CONCLUSION: a successful ffmpeg call results in a read fail on the next iteration through the loop.

Why does this happen, and how can I stop it?

Here's my code: ...

# 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  

Thanks for looking!

  • Both suggestions work. Thanks so much. I identified the option that is ffmpeg 'native' as the answer because of that aspect. – Dilgreen Jun 12 '16 at 16:25
5

Use -nostdin option in ffmpeg. From FFmpeg documentation:

Enable interaction on standard input. On by default unless standard input is used as an input. To explicitly disable interaction you need to specify -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.

0

You are probably right that ffmpeg is probably reading from your input, who knows why, so simply redirect that command to read from /dev/null, ie add to the ffmpeg line </dev/null.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.