Shell Script and FFMpeg

Greetings,
I'm working on a script that will perform a transcode using FFMpeg, and I'm encountering some strange behavior.

Location

$ pwd


Code:
/tmp/test

The script.sh

$ cat script.sh


Code:
#!/bin/sh

WORKDIR='/tmp/test'

cd "${WORKDIR}" || exit 1

# Bucle
while read -r FILENAME; do

  if [ -e ./"${FILENAME}" ]; then

    echo "Transcoding ${FILENAME}. . ."
    ffmpeg -y -hide_banner -i "${FILENAME}" -c:a libvorbis -ar 44100 "${FILENAME}".ogg

  else

    echo "File ${FILENAME} not found"

  fi

done < ./list.txt
exit 0

The list.txt content

$ cat list.txt


Code:
file1.wav
file2.wav
file3.wav

Run the script

$ ./script.sh


The output
Code:
Transcoding file1.wav. . .
[aist#0:0/pcm_s16le @ 0x2ad11385a300] Guessed Channel Layout: mono
Input #0, wav, from 'file1.wav':
  Duration: 00:00:12.53, bitrate: 768 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 1 channels, s16, 768 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> vorbis (libvorbis))
Press [q] to stop, [?] for help
Output #0, ogg, to 'file1.wav.ogg':
  Metadata:
    encoder         : Lavf60.16.100
  Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp
    Metadata:
      encoder         : Lavc60.31.102 libvorbis
[out#0/ogg @ 0x2ad113858340] video:0kB audio:103kB subtitle:0kB other streams:0kB global headers:3kB muxing overhead: 4.170636%
size=     107kB time=00:00:12.50 bitrate=  69.9kbits/s speed= 166x   
File ile2.wav not found
Transcoding file3.wav. . .
[aist#0:0/pcm_s16le @ 0x2f629be5a300] Guessed Channel Layout: mono
Input #0, wav, from 'file3.wav':
  Duration: 00:00:12.53, bitrate: 768 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 1 channels, s16, 768 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> vorbis (libvorbis))
Press [q] to stop, [?] for help
Output #0, ogg, to 'file3.wav.ogg':
  Metadata:
    encoder         : Lavf60.16.100
  Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp
    Metadata:
      encoder         : Lavc60.31.102 libvorbis
[out#0/ogg @ 0x2f629be58340] video:0kB audio:103kB subtitle:0kB other streams:0kB global headers:3kB muxing overhead: 4.170636%
size=     107kB time=00:00:12.50 bitrate=  69.9kbits/s speed= 166x

The result of run the script

$ ls *.ogg


Code:
file1.wav.ogg    file3.wav.ogg

The error is in the file called 'file2.wav'
Code:
File ile2.wav not found

I don't understand why FFMpeg in the second file cuts off the initial 'f' from the name...

The list.txt file has no strange characters, I have checked it several times and even created it from the 'vi' editor.

I'm using the default shell


$ echo $SHELL


Code:
/bin/sh

Thanks for your advice in advance.
 
New information:

If I put a line between the names on the list, it works...


$ cat list.txt


Code:
file1.wav

file2.wav

file3.wav

The result

$ ls *.ogg


Code:
file1.wav.ogg    file2.wav.ogg    file3.wav.ogg
 
Try running it as `sh -x script.sh` to see more of what's going on.

$ cat list.txt


Code:
file1.wav
file2.wav
file3.wav


$ sh -x ./script.sh


Code:
+ WORKDIR=/tmp/test
+ cd /tmp/test
+ read -r FILENAME
+ [ -e ./file1.wav ]
+ echo 'Transcoding file1.wav. . .'
Transcoding file1.wav. . .
+ ffmpeg -y -hide_banner -i file1.wav -c:a libvorbis -ar 44100 file1.wav.ogg
[aist#0:0/pcm_s16le @ 0x3b02685a300] Guessed Channel Layout: mono
Input #0, wav, from 'file1.wav':
  Duration: 00:00:12.53, bitrate: 768 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 1 channels, s16, 768 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> vorbis (libvorbis))
Press [q] to stop, [?] for help
Output #0, ogg, to 'file1.wav.ogg':
  Metadata:
    encoder         : Lavf60.16.100
  Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp
    Metadata:
      encoder         : Lavc60.31.102 libvorbis
[out#0/ogg @ 0x3b026858340] video:0kB audio:103kB subtitle:0kB other streams:0kB global headers:3kB muxing overhead: 4.170636%
size=     107kB time=00:00:12.50 bitrate=  69.9kbits/s speed= 166x   
+ read -r FILENAME
+ [ -e ./ile2.wav ]
+ echo 'File ile2.wav not found'
File ile2.wav not found
+ read -r FILENAME
+ [ -e ./file3.wav ]
+ echo 'Transcoding file3.wav. . .'
Transcoding file3.wav. . .
+ ffmpeg -y -hide_banner -i file3.wav -c:a libvorbis -ar 44100 file3.wav.ogg
[aist#0:0/pcm_s16le @ 0x22a31085a300] Guessed Channel Layout: mono
Input #0, wav, from 'file3.wav':
  Duration: 00:00:12.53, bitrate: 768 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 1 channels, s16, 768 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> vorbis (libvorbis))
Press [q] to stop, [?] for help
Output #0, ogg, to 'file3.wav.ogg':
  Metadata:
    encoder         : Lavf60.16.100
  Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp
    Metadata:
      encoder         : Lavc60.31.102 libvorbis
[out#0/ogg @ 0x22a310858340] video:0kB audio:103kB subtitle:0kB other streams:0kB global headers:3kB muxing overhead: 4.170636%
size=     107kB time=00:00:12.50 bitrate=  69.9kbits/s speed= 167x   
+ read -r FILENAME
+ exit 0


$ ls *.ogg


Code:
file1.wav.ogg    file3.wav.ogg
 
I'm thinking the problem is with FFMpeg, since if I modify the script to perform a touch, it does so without errors...

The script (only touch)

Code:
#!/bin/sh

WORKDIR='/tmp/test'

cd "${WORKDIR}" || exit 1

# Bucle
while read -r FILENAME; do

  if [ -e ./"${FILENAME}" ]; then

    touch ./"${FILENAME}".txt

  else

    echo "File ${FILENAME} not found"

  fi

done < ./list.txt
exit 0

The result

$ ls *.wav.txt


Code:
file1.wav.txt    file2.wav.txt    file3.wav.txt
 
Maybe there has some empty space, etc. in file2.wav file?
Can you please test it yourself? I've already tried it on two different versions of FreeBSD with the different result...

14.0-RELEASE-p9

File e2.wav not found

14.2-RELEASE-p4

File ile2.wav not found

Different e2.wav vs ile2.wav
 
put that at the top of the script

The new code
Code:
#!/bin/sh

unset IFS

WORKDIR='/tmp/test'

cd "${WORKDIR}" || exit 1

# Bucle
while read -r FILENAME; do
...

When running

Code:
Transcoding file1.wav. . .
...
File ile2.wav not found
Transcoding file3.wav. . .

The result
Code:
file1.wav.ogg    file3.wav.ogg
 
seems like ffmpeg will read something from stdin if it cans and will fsck things up (the next shell read)
maybe someone can search the docs for why it does it....
 
seems like ffmpeg will read something from stdin if it cans and will fsck things up (the next shell read)
maybe someone can search the docs for why it does it....
not surprised, but thanks for the additional input. ffmpeg can be quite infuriating. I use it for a lot of batch mode transcoding which is why my "higher than normal" interest.
 
Back
Top