How to Concatenate Audio Files in Python

Explore different methods to join two or more audio files using either MoviePy, wave and PyDub libraries in Python.
  · 6 min read · Updated may 2024 · Python for Multimedia

Step up your coding game with AI-powered Code Explainer. Get insights like never before!

If you want to combine two or more audio files into one with Python, then in this tutorial, you will learn 3 different methods to concatenate audio files in Python using either MoviePy, wave, or PyDub libraries, and you're free to use any one of them.

To get started, let's install the necessary libraries:

$ pip install moviepy pydub tqdm

Method 1: Using MoviePy

To start, we need to import MoviePy to construct our script:

from moviepy.editor import concatenate_audioclips, AudioFileClip

MoviePy is a pretty straightforward library, and not much code is involved, the following function joins a list of audio files into one with MoviePy library:

def concatenate_audio_moviepy(audio_clip_paths, output_path):
    """Concatenates several audio files into one audio file using MoviePy
    and save it to `output_path`. Note that extension (mp3, etc.) must be added to `output_path`"""
    clips = [AudioFileClip(c) for c in audio_clip_paths]
    final_clip = concatenate_audioclips(clips)
    final_clip.write_audiofile(output_path)

The audio_clip_paths is a list of paths to the audio files, we instantiate an AudioFileClip object for each audio clip, and then we use the concatenate_audioclips() function provided by MoviePy to combine the audio files. Finally, we write the final clip with the write_audiofile() method.

Below is the code for parsing command-line arguments:

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Simple Audio file combiner using MoviePy library in Python")
    parser.add_argument("-c", "--clips", nargs="+",
                        help="List of audio clip paths")
    parser.add_argument("-o", "--output", help="The output audio file, extension must be included (such as mp3, etc.)")
    args = parser.parse_args()
    concatenate_audio_moviepy(args.clips, args.output)

Below is how to use the script:

$ python concatenate_audio_moviepy.py -c zoo.mp3 directed-by-robert.mp3 -o output_moviepy.mp3
MoviePy - Writing audio in output_moviepy.mp3
MoviePy - Done.

Personally, I had some weird errors with MoviePy when reading some audio files. As a result, I strived to use other methods.

Method 2: Using Wave

One of the advantages of wave is that it's in the Python standard library, which means we don't have to install anything with pip. The following function combines two or more wav audio files into one:

import wave

def concatenate_audio_wave(audio_clip_paths, output_path):
    """Concatenates several audio files into one audio file using Python's built-in wav module
    and save it to `output_path`. Note that extension (wav) must be added to `output_path`"""
    data = []
    for clip in audio_clip_paths:
        w = wave.open(clip, "rb")
        data.append([w.getparams(), w.readframes(w.getnframes())])
        w.close()
    output = wave.open(output_path, "wb")
    output.setparams(data[0][0])
    for i in range(len(data)):
        output.writeframes(data[i][1])
    output.close()

This method is reliable and much faster. However, the downside of the wave library is that only the wav extension is supported, so skip to the 3rd method if your audio files are not in the wave format.

Below is the typical argparse boilerplate code for parsing command-line arguments with this script. If you want to learn more about argparse, check this tutorial:

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Simple Audio file combiner using wave module in Python")
    parser.add_argument("-c", "--clips", nargs="+",
                        help="List of audio clip paths")
    parser.add_argument("-o", "--output", help="The output audio file, extension (wav) must be included")
    args = parser.parse_args()
    concatenate_audio_wave(args.clips, args.output)

You can pretty much use the same format for executing the script as previously.

Method 3: Using PyDub

I personally use this method to combine several audio files into one, as it supports a lot of audio file extensions and does not produce any weird error when loading audio files:

from pydub import AudioSegment
from tqdm import tqdm
import os


def concatenate_audio_pydub(audio_clip_paths, output_path, verbose=1):
    """
    Concatenates two or more audio files into one audio file using PyDub library
    and save it to `output_path`. A lot of extensions are supported, more on PyDub's doc.
    """
    def get_file_extension(filename):
        """A helper function to get a file's extension"""
        return os.path.splitext(filename)[1].lstrip(".")

    clips = []
    # wrap the audio clip paths with tqdm if verbose
    audio_clip_paths = tqdm(audio_clip_paths, "Reading audio file") if verbose else audio_clip_paths
    for clip_path in audio_clip_paths:
        # get extension of the audio file
        extension = get_file_extension(clip_path)
        # load the audio clip and append it to our list
        clip = AudioSegment.from_file(clip_path, extension)
        clips.append(clip)

    final_clip = clips[0]
    range_loop = tqdm(list(range(1, len(clips))), "Concatenating audio") if verbose else range(1, len(clips))
    for i in range_loop:
        # looping on all audio files and concatenating them together
        # ofc order is important
        final_clip = final_clip + clips[i]
    # export the final clip
    final_clip_extension = get_file_extension(output_path)
    if verbose:
        print(f"Exporting resulting audio file to {output_path}")
    final_clip.export(output_path, format=final_clip_extension)

As you may notice, it's a bit longer:

  • First, we write a helper function to get an extension of any file with Python, we'll use this to get the extension of the audio file automatically so we can pass it to PyDub.
  • Second, we load the audio files using the AudioSegment.from_file() method which expects the audio path, and the extension. We also wrap the list of audio files with tqdm if we want to print fancy progress bars with tqdm.
  • Next, we concatenate those audio files we just loaded with the simple '+' operator.
  • Finally, we export the resulting audio file with the export() method and passing the extension to the format argument.

Let's parse the command-line arguments:

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Simple Audio file combiner using PyDub library in Python")
    parser.add_argument("-c", "--clips", nargs="+",
                        help="List of audio clip paths")
    parser.add_argument("-o", "--output", help="The output audio file, extension must be included (such as mp3, etc.)")
    args = parser.parse_args()
    concatenate_audio_pydub(args.clips, args.output)

Let's test it out:

usage: concatenate_audio_pydub.py [-h] [-c CLIPS [CLIPS ...]] [-o OUTPUT]

Simple Audio file combiner using PyDub library in Python

optional arguments:
  -h, --help            show this help message and exit
  -c CLIPS [CLIPS ...], --clips CLIPS [CLIPS ...]
                        List of audio clip paths
  -o OUTPUT, --output OUTPUT
                        The output audio file, the extension must be included (such as mp3, etc.)

Right, let's combine 2 audio files:

$ python concatenate_audio_pydub.py -c zoo.mp3 directed-by-robert.mp3 -o output_pydub.mp3
Reading audio file: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00,  8.40it/s]
Concatenating audio: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 18.81it/s]
Exporting resulting audio file to output_pydub.mp3

Conclusion

Awesome! That's it!

Be aware in the third method, when you combine a lot of audio files in one go, you may encounter some delay on export() method. That's normal, but if you want it to be quicker, make sure you don't join your audio files in a single run.

By the way, MoviePy was designed to handle videos and not audio, I advise you to use the 3rd method for concatenating audio, and MoviePy to concatenate video, check this tutorial for more information and for the code.

Get the full code of this tutorial here.

Learn also: How to Extract Audio from Video in Python

Happy coding ♥

Just finished the article? Why not take your Python skills a notch higher with our Python Code Assistant? Check it out!

View Full Code Fix My Code
Sharing is caring!



Read Also



Comment panel

    Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!