Execute "ffmpeg" command in a loop
If you do need find
(for looking in subdirectories or performing more advanced filtering), try this:
find ./ -name "*.wav" -exec sh -c 'ffmpeg -i "$1" -ab 320k -ac 2 "$(basename "$1" wav).mp3"' _ {} \;
Piping the output of find
to the while
loop has two drawbacks:
- It fails in the (probably rare) situation where a matched filename contains a newline character.
ffmpeg
, for some reason unknown to me, will read from standard input, which interferes with theread
command. This is easy to fix, by simply redirecting standard input from/dev/null
, i.e.find ... | while read f; do ffmpeg ... < /dev/null; done
.
In any case, don't store commands in variable names and evaluate them using eval
. It's dangerous and a bad habit to get into. Use a shell function if you really need to factor out the actual command line.
Use the -nostdin
flag to disable interactive mode,
ffmpeg -nostdin -i "$f" -ab 320k -ac 2 "${f%.*}.mp3"
or have ffmpeg
read its input from the controlling terminal instead of stdin.
ffmpeg -i "$f" -ab 320k -ac 2 "${f%.*}.mp3" </dev/tty
See the -stdin
/-nostdin
flags in the ffmpeg documentation
No reason for find, just use bash wildcard globbing
#!/bin/bash
for name in *.wav; do
ffmpeg -i "$name" -ab 320k -ac 2 "${name%.*}.mp3"
done