Feb 22, 2011
Batch Create Audio Clips with Fades
Drop the GUI and use FFmpeg and SoX
I needed to generate a bunch of audio clips. After seeing how tedious this would be with a GUI audio editor, I did some digging to find a faster solution that I could run as a batch from the command line. Turns out it was quite easy.
I first turned to the excellent FFmpeg library. I knew I would be able to read and convert between a wide variety of formats (from mp3 to aac and Apple Lossless) and specify start and stop points. I was surprised to learn that it lacked the functionality to add fades.
For the fading, I turned to SoX, which has the ability to add audio filters, but as far as I can tell can't read as many formats out of the box.
The only tricky bit to all of this is getting everything installed. FFmpeg needs to be compiled from source with support for the LAME mp3 library. There are many tutorials around the web. SoX can either be installed from source or with one of the binary distributions.
The commands
After everything is installed, the commands are straightforward.
$ ffmpeg -y -i orig.m4a -ss 0:02:30 one.aiff
This converts orig.m4a to the lossless one.aiff file. The -y option will automatically overwrite the output if it exists and the -ss option specifies the start time which (in this example) will trim the first two and a half minutes from orig.m4a.
$ sox one.aiff two.aiff fade 1 0:01:00 1
This trims the one.aiff down to 1 minute in length, adds a one second fade to the beginning and end, and saves the result as two.aiff.
$ ffmpeg -y -i two.aiff -ab 128k clip.mp3
Finally, we use ffmpeg agin to transcode two.aiff down to our final 128k mp3 clip. The -ab flag is used to set the audio bitrate.
This works fine and all, but a better solution is to pipe the results of one command to the next to avoid creating the intermediate files:
$ ffmpeg -i orig.mp3 -ss 0:02:30 -f aiff pipe: | \ sox -t aiff - -t aiff - fade 1 1:00 1 | \ ffmpeg -y -i pipe: -ab 128k clip.mp3
There are a few things to note.
- To pipe the output from the first
ffmpegcommand, we need to specify the output format with-f aiff. - We also need to specify the incoming and outgoing formats of the pipes in the
soxcommand with-t aiff -. - I initally used
.wavas the intermediate format, but this didn't work due to issues with the pipes and file headers. - The backslash characters are just to break up the command into shorter lines.