Mass file conversion using find and exec

Table of Contents

convert mp3 to opus

The short solution

find ./ -type f -name '*.mp3' -exec sh -c 'ffmpeg -i "{}" -f wav - | opusenc --music - "{}.opus"' \;

The full journey to the solution

The first trick was just to use ffmpeg to convert to .wav, and then to take that .wav output and feed it to opusenc1 ffmpeg -i input.mp3 -f wav - | opusenc –bitrate 256 - output.opus

find ./ -name ‘*.wma’ -type f | sed ‘s,\.wma$,.mp3,’

Works for finding and listing all:

find ./ -type f -name '*.mp3' -exec echo {} +

ffmpeg Worked for one

In two steps I was able to convert one target to an opus file.

ffmpeg -i "11 John Harrison with the Wichita State University Chamber Players - Winter Mvt 2 Largo.mp3" -f wav "11 Winter Mvt 2 Largo.wav"

and then

opusenc --music "11 Winter Mvt 2 Largo.wav" "11 Winter Mvt 2 Largo.opus"

at once:

ffmpeg -i "12 John Harrison with the Wichita State University Chamber Players - Winter Mvt 3 Allegro.mp3" -f wav - | opusenc --music - "12 John Harrison with the Wichita State University Chamber Players - Winter Mvt 3 Allegro.opus"

What I didn’t realize is that piping is something the shell is doing, which would come to give me troubles in wrapping this in to find -exec.

Try for multiple

find ./ -type f -name '*.mp3' -exec ffmpeg -i "\{\}" -f wav "\{\}.wav" +
# find: missing argument to `-exec'

Problem: can’t get the syntax right for `find exec` (multiple files, .mp3 to .opus)

I have mp3 files that I want to convert to opus, all at once. The right tool for the job should be find, but I can’t get the syntax to work. What is working for just one:

ffmpeg -i "12 John Harrison with the Wichita State University Chamber Players - Winter Mvt 3 Allegro.mp3" -f wav - | opusenc --music - "12 John Harrison with the Wichita State University Chamber Players - Winter Mvt 3 Allegro.opus"

Obviously the filenames are a mouthful so I would like find to take care of that for me2. But here is my attempt, and the failure I can’t seem to get past:

find ./ -type f -name '*.mp3' -exec 'ffmpeg -i "\{\}" -f wav - | opusenc --music - "\{\}.opus"' +
# find: missing argument to `-exec'

Works without error but prints output to stdout. Notice the use of sh in the -exec block3:

find ./ -type f -name '*.mp3' -exec sh -c 'ffmpeg -i "{}" -f wav -' \;

Success!

trying to put the output right, and it all worked! It was suprisingly fast, taking only some seconds on my machine (again, only a dozen files were here).

find ./ -type f -name '*.mp3' -exec sh -c 'ffmpeg -i "{}" -f wav - | opusenc --music - "{}.opus"' \;

Bonus: renaming with emacs dired edit

As you could guess from the code, my process produced the directory of .mp3.opus filenames, which is a bit unseemly. I open the directory in dired and fire up dired-toggle-read-only (which I have bound to C-c C-r in dired buffers) and do a quick replace of “.mp3.opus” to “.opus” and save the changes. dired-toggle-read-only is a very handy command that I use frequently.

Bonus 2: Filesize

Converting to from .mp3 to .opus was not motivated purely by filesize; there was mostly the compelling reason that opus is a better (and free²) format4 . Nonetheless it was gratifying to find that for just 12 files my opus conversion took 51M of .mp3 to just 33M of .opus; that conversion size savings rate of 33% (only 2/3rds the filesize of .opus) I would expect the progress to be much more significant for more than a trivial dozen mp3 files.

Footnotes

1 The process for a single-file is recommended here: https://askubuntu.com/questions/211054/how-to-convert-a-sound-file-to-opus

2 The linux command find is good at inserting the found name into a command: https://unix.stackexchange.com/questions/60404/manipulate-file-name-piped-from-find-command

3 When piping is going to be done with find exec, you need to account for the fact that piping is a method provided by the shell, not by find; hence the need to include a shell -c command. https://stackoverflow.com/questions/307015/how-do-i-include-a-pipe-in-my-linux-find-exec-command

4 Opus format is described at https://en.m.wikipedia.org/wiki/Opus_(audio_format) or, with more partiality, at https://opus-codec.org/ .

Tory Anderson avatar
Tory Anderson
Full-time Web App Engineer, Digital Humanist, Researcher, Computer Psychologist