Merging MP3 Files with NAudio in C# and IronPython
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.
Comments
I install Python for .Net, put NAudio.dll to script directory, but when i run script - i have error:
KOS_MOSc:\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!
I'we installed Python for .Net, put NAudio.dll to script directory, but when i run script - i have error:
KOS_MOSc:\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!
I always run IronPython with ipy.exe. Not sure if that is your issue though.
Mark HI 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?
AnonymousUsing the above code I have merged around 80 files. I have also created an audio marker using following code.
AnonymousoStringBuilder.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?
Using the above code I have merged around 80 files. I have also created an audio marker using following code.
AnonymousoStringBuilder.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?
I have written following code using ur example
Ali Mohsinusing 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.
well you're saving it to a memory stream. You need to create a file stream with something like File.OpenWrite()
Mark HeathJust 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