Posted in:

If you would like to concatenate MP3 files using NAudio, it is quite simple to do. I recommend getting the very latest source code and building your own copy of NAudio, as this will work best with some of the changes that are in preparation for NAudio 1.4.

Here’s the C# code for a function that takes MP3 filenames, and writes a combined MP3 to the output stream:

public static void Combine(string[] inputFiles, Stream output)
{
    foreach (string file in inputFiles)
    {
        Mp3FileReader reader = new Mp3FileReader(file);
        if ((output.Position == 0) && (reader.Id3v2Tag != null))
        {
            output.Write(reader.Id3v2Tag.RawData, 0, reader.Id3v2Tag.RawData.Length);
        }
        Mp3Frame frame;
        while ((frame = reader.ReadNextFrame()) != null)
        {
            output.Write(frame.RawData, 0, frame.RawData.Length);
        }
    }
}

And here’s an IronPython script (just put NAudio.dll in the same folder as the mp3merge.py script):

import clr
clr.AddReference('NAudio.dll')

import sys
from NAudio.Wave import Mp3FileReader
from System.IO import File

def GetAllFrames(reader):
    while True:
        frame = reader.ReadNextFrame()
        if frame:
            yield frame
        else:
            return

def Merge(files, outputStream):
    for file in files:
        with Mp3FileReader(file) as reader:
            if reader.XingHeader:
                print 'discarding a Xing header'
            if not outputStream.Position and reader.Id3v2Tag:
                outputStream.Write(reader.Id3v2Tag.RawData, 0, reader.Id3v2Tag.RawData.Length)                
            for frame in GetAllFrames(reader):
                outputStream.Write(frame.RawData, 0, frame.RawData.Length);
            
if __name__ == '__main__':
    if len(sys.argv) < 3:
        print "Usage: ipy mp3merge.py output.mp3 File1.mp3 File2.mp3"
    else:
        with File.OpenWrite(sys.argv[1]) as outStream:
            Merge(sys.argv[2:],outStream)

Notes:

I simply copy across the ID3v2 tag from the first MP3 file if present. All other ID3v2 tags are discarded (as are ID3v1 tags). Also, I discard the Xing frame from VBR files. It could easily be re-included if desired, although it’s information will not necessarily be valid about the combined MP3 file. One final thing, I wouldn’t recommend merging MP3 files of different sample rates, or mixing mono with stereo, as it could cause various players issues.

Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.

Comments

Comment by KOS_MOS

I install Python for .Net, put NAudio.dll to script directory, but when i run script - i have error:

c:\Temp\pmerge>C:\Python.Net\python.exe mp3merge.py
Traceback (most recent call last):
File "mp3merge.py", line 2, in
clr.AddReference('NAudio.dll')
System.IO.FileNotFoundException

Please help!

Comment by KOS_MOS

I'we installed Python for .Net, put NAudio.dll to script directory, but when i run script - i have error:

c:\Temp\pmerge>C:\Python.Net\python.exe mp3merge.py
Traceback (most recent call last):
File "mp3merge.py", line 2, in
clr.AddReference('NAudio.dll')
System.IO.FileNotFoundException

Please help me!

Comment by Mark H

I always run IronPython with ipy.exe. Not sure if that is your issue though.

Comment by Anonymous

I want to merger multiple mp3 files- say 3 files. So i've array of 3 mp3 files path. Secong one of these files is Blank file of 20 sec. when i merge these blank file doesnt merge. Any suggestion?

Anonymous
Comment by Anonymous

Using the above code I have merged around 80 files. I have also created an audio marker using following code.

oStringBuilder.AppendFormat("",
Path.GetFileNameWithoutExtension(file), Math.Round(oCurrentTime,3), Math.Round(oCurrentTime + reader.TotalTime.TotalSeconds,3));

And then I use these markers to play specific section of the merged MP3 in various browsers.

The audio markers work alright in chrome but in Safari and IE the markers are inaccurate, any idea?

Anonymous
Comment by Anonymous

Using the above code I have merged around 80 files. I have also created an audio marker using following code.

oStringBuilder.AppendFormat("",
Path.GetFileNameWithoutExtension(file), Math.Round(oCurrentTime,3), Math.Round(oCurrentTime + reader.TotalTime.TotalSeconds,3));

And then I use these markers to play specific section of the merged MP3 in various browsers.

The audio markers work alright in chrome but in Safari and IE the markers are inaccurate, any idea?

Anonymous
Comment by Ali Mohsin

I have written following code using ur example
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NAudio.Wave;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
string[] s = { "C:\\Users\\ali.mohsin\\Downloads\\Music\\GF BF 2016 Full Video Song 1080p HD mp4_(new).mp3", "C:\\Users\\ali.mohsin\\Downloads\\Music\\Sunny Leone_ ISHQ DA SUTTA Video Song _ ONE NIGHT STAND _ Meet Bros, Jasmine Sandlas _ T-Series_(new).mp3" };
System.IO.Stream stream = new System.IO.MemoryStream();
Combine(s, stream);
}
public static void Combine(string[] inputFiles, Stream output)
{
foreach (string file in inputFiles)
{
Mp3FileReader reader = new Mp3FileReader(file);
if ((output.Position == 0) && (reader.Id3v2Tag != null))
{
output.Write(reader.Id3v2Tag.RawData, 0, reader.Id3v2Tag.RawData.Length);
}
Mp3Frame frame;
while ((frame = reader.ReadNextFrame()) != null)
{
output.Write(frame.RawData, 0, frame.RawData.Length);
}
}
}
}
}
BUT WHERE is my output file hoe can i play it.

Ali Mohsin
Comment by Mark Heath

well you're saving it to a memory stream. You need to create a file stream with something like File.OpenWrite()

Mark Heath
Comment by Gideon Scheepers

Just reading the code, my understanding is that by "merge mp3 files" you mean concatenating them, not layering them on top of each other right?

Gideon Scheepers