Randy Karels

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.

Installation

Installation is simple with homebrew:

$ brew install ffmpeg  
$ brew install sox

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 2 0:01:00 5

This trims the one.aiff down to 1 minute in length, adds a two second fade to the beginning, adds a five second fade to the 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 2 1:00 5 | \
  ffmpeg -y -i pipe: -ab 128k clip.mp3

There are a few things to note.

  • To pipe the output from the first ffmpeg command, 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 sox command with -t aiff -.
  • I initially used .wav as 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.