Linux command to concatenate audio files and output them to ogg

SoX can handle a large number of audio formats, depending on what libraries it's compiled against, and can concatenate files with a simple command line

sox file1.wav file2.mp3 file3.flac outfile.ogg

I believe this only works if the source audio files all have the same number of channels, but I've not tested this.

As far as I know, SoX has zero support for .wma files, so converting at least those files with something like ffmpeg first is probably unavoidable.

ffmpeg -i infile.wma outfile.wav

Here's my suggestion: Use mplayer and oggenc connected with a named pipe.

  • Use mplayer to decode the audio. It can play back a wide variety of audio (and video) formats, and it also can play multiple files.

  • Use oggencto encode the audio to Ogg Vorbis.

  • To eliminate the need for a temporary file, use a named pipe to transfer the data between encoder and decoder.

Putting that into a script:

#!/bin/sh
# Usage: ./combine2ogg destination.ogg source1.wma source2.wma ...
# Requires: mplayer, oggenc
destination="$1"
shift
readpipe="$destination.tmpr"
writepipe="$destination.tmpw"
mkfifo "$readpipe"
mkfifo "$writepipe"
cat "$writepipe" > "$readpipe" &
mplayer -really-quiet -slave -nolirc -vc null -vo null -ao "pcm:fast:file=$writepipe" "$@" &
oggenc --quiet -o "$destination" "$readpipe"
rm -f "$readpipe"
rm -f "$writepipe"

Explained:

  1. Take the destination file name from the first command line parameter.
  2. Remove the first command line parameter, leaving only the source file names.
  3. Create a name for a pipe for oggenc to read from.
  4. Create a name for a pipe for mplayer to write to
  5. Create the pipes.
  6. Use cat to continuously dump the writepipe to the readpipe (this helps avoid issues where mplayer may terminate, but prevents oggenc from thinking it's done when this happens)
  7. Decode the audio from the source files using mplayer. Options -really-quiet -slave -nolirc are there to disable messages and to make it not read the keyboard or the remote. Options -vc null -vo null are there to disable video encoding and output. The -ao option directs it to output the audio in WAV format to the named write pipe.
  8. While the previous command is running, simultaneously encode from the named read pipe into Ogg using oggenc.
  9. Remove the named pipes.

Stuff to left to improve: Terminating the script early if one of the commands fails (use set -e), but still properly cleaning up the fifo (trap the necessary signals).


I would use ffmpeg. To convert wma to ogg vorbis try:

ffmpeg -i sample.wma -acodec vorbis -aq 100 sample.ogg

or mp3:

ffmpeg -i input.wma -acodec libmp3lame output.mp3

you'll need lame installed for the mp3 convert. sudo apt-get install lame libmp3lame0

Cat, then convert doen't seem to work well, although you can find lots of references on the web saying you can do something like cat *.wma | ffmpeg -i - -acodec ... - this doesn't work on my machine - only the first file gets processed. There is a 'copy' codec for ffmpeg, but doesn't make much difference.

Doing the convert with ffmpeg first, then cat *.ogg > output.ogg worked for me.