3

I'm writing a quick script to go through huge amounts of music to convert all the m4as to mp3s. Most of them are already mp3s, but I'd like all of them to be mp3s. Here's what I have so far:

for f in *.m4a; do ffmpeg -i "$f" -acodec libmp3lame -ab 320 "${f%.m4a}.mp3"; done

Does it on one level, how do I integrate this ffmpeg into a find command to do it recursively?

Thanks for the help!

4

1 回答 1

7

If you want to also loop in subfolders, you can use the globstar shell optional behavior, see the Pattern Matching section of the reference manual and the Shopt Builtin section of the reference manual as so:

shopt -s globstar
for f in **/*.m4a; do ffmpeg -i "$f" -acodec libmp3lame -ab 320 "${f%.m4a}.mp3"; done

Using find it's a bit trickier since you're using a Shell Parameter Expansion. Here's a possibility that will be 100% safe regarding files with spaces or other funny symbols in their name:

find . -name '*.m4a' -type f -exec bash -c 'ffmpeg -i "$0" -acodec libmp3lame -ab 320 "${0%.m4a}.mp3"' {} \;

This second possibility might be faster if you have a huge number of files, since globbing is known to be quite slow for huge number of files.


In the -exec statement of find, I'm using bash -c '...'. In this case, every parameter given after the string to be executed will be set as the positional parameters, indexed from 0, hence the $0 that appears in the code

ffmpeg -i "$0" -acodec libmp3lame -ab 320 "${0%.m4a}.mp3"

Hope this helps!

于 2013-07-01T16:32:47.373 回答