Catenating mp3 files correctly under Linux

I sometimes download lots of mp3 files from the web (bit-torrent or music) and need to catenate them. This is usually the case when there are just too many files lying around or when they are too short like 3-5 minutes long and I want them to be 30 minutes long or more. This is very useful for educational material. In this post I will review the different methods to achieve this and offer my own solution.

Solution 1: catenate the files simply. cat *.mp3 > out.mp3. There are a few problems with this approach. First, an mp3 file is a file with a header and just concatenating the files would leave multiple headers in the output file. The output file will therefor have the headers of the first file. Not nice. Second, the output file could only be played by certain mp3 players which are forgiving about the file format so it may play well on your Linux system (mp3 players are very forgiving there) but not on a mobile device. Third, the output file has bad length and you will have problems moving around in it using most players.

Solution 2: use mp3wrap. This utility is available in most Linux distributions repositories (in Ubuntu it’s named simply mp3wrap). It offers an easy command line and manual page but it does not create a single mp3 file but rather an mp3 file that later can be split to create the original mp3 files. This wrapped file can be played by various Linux players which are forgiving but has lots of the issues discussed in the first solution.

Solution 3: use ffmpeg. This is idea is based on the following post. The idea is to run: ffmpeg -i "concat:file1.mp3|file2.mp3" -acodec copy output.mp3. This is a much better solution as the resulting mp3 file is a single file with correct length and the tags of the first file concatenated.

Solution 4: use a script since the previous solution is hard to use for many files.

#!/usr/bin/python
 
"""
This script will catenate mp3 files correctly using ffmpeg.
see: http://superuser.com/questions/314239/how-to-join-merge-many-mp3-files
"""
 
import subprocess
import sys
 
if len(sys.argv)<3:
        raise ValueError('usage: outfile.mp3 [infile1.mp3] [infile2.mp3] ...')
 
args=['ffmpeg','-i','concat:'+'|'.join(sys.argv[2:]),'-acodec','copy',sys.argv[1]]
#print args
subprocess.check_call(args)

Leave a Reply

Your email address will not be published.