13

I am very new to audio or mp3 stuff, was looking for a way to have a feature to split an mp3 file in C#, asp.net. After googling for a good 3-day without much of a great help, I am hoping that somebody here can point me to a right direction.

Can I use NAudio to accomplish this? Is there any sample code for that? Thanks in advance.

Robin Rodricks
  • 110,798
  • 141
  • 398
  • 607
joe kirk
  • 700
  • 2
  • 10
  • 25
  • possible duplicate of [Trim an MP3 Programatically](http://stackoverflow.com/questions/551074/trim-an-mp3-programatically) – ErikE Jan 05 '13 at 08:09

5 Answers5

13

My final solution to split mp3 file in c# is to use NAudio. Here is a sample script for that, hope it helps someone in the community:

string strMP3Folder = "<YOUR FOLDER PATH>";
string strMP3SourceFilename = "<YOUR SOURCE MP3 FILENAMe>";
string strMP3OutputFilename = "<YOUR OUTPUT MP3 FILENAME>";

using (Mp3FileReader reader = new Mp3FileReader(strMP3Folder + strMP3SourceFilename))
{
    int count = 1;
    Mp3Frame mp3Frame = reader.ReadNextFrame();
    System.IO.FileStream _fs = new System.IO.FileStream(strMP3Folder + strMP3OutputFilename, System.IO.FileMode.Create, System.IO.FileAccess.Write);

    while (mp3Frame != null)
    {
        if (count > 500) //retrieve a sample of 500 frames
            return;

        _fs.Write(mp3Frame.RawData, 0, mp3Frame.RawData.Length);
        count = count + 1;
        mp3Frame = reader.ReadNextFrame();
     }

     _fs.Close();
}

Thanks to Mark Heath's suggestion for this.

The namespace required is NAudio.Wave.

joe kirk
  • 700
  • 2
  • 10
  • 25
12

An MP3 File is made up of a sequence of MP3 frames (plus often ID3 tags on the beginning and end). The cleanest way to split an MP3 file then is to copy a certain number of frames into a new file (and optionally bring the ID3 tags along too if that is important).

NAudio's MP3FileReader class features a ReadNextFrame method. This returns an MP3Frame class, which contains the raw data as a byte array in the RawData property. It also includes a SampleCount property which you can use to accurately measure the duration of each MP3 Frame.

Mark Heath
  • 48,273
  • 29
  • 137
  • 194
  • Thanks for the comment, I will try out on this.. I will come back to update my findings later. Thanks! – joe kirk May 24 '11 at 01:15
  • how many milliseconds does every mp3Frame has?? is there any formula or something I can use to get the length of every mp3frame in milliseconds? – Desolator Jun 02 '11 at 21:03
  • 1
    @ermac2014 use the sample rate. If you know samples per second and you know number of samples, then divide number of samples by sample rate to get duration. – Mark Heath Jun 06 '11 at 08:46
6

The previous answers helped me get started. NAudio is the way to go.

For my PodcastTool I needed to to split podcasts at 2 minute intervals to make seeking to a specific place faster.

Here's the code to split an mp3 every N seconds:

    var mp3Path = @"C:\Users\ronnie\Desktop\mp3\dotnetrocks_0717_alan_dahl_imagethink.mp3";
    int splitLength = 120; // seconds

    var mp3Dir = Path.GetDirectoryName(mp3Path);
    var mp3File = Path.GetFileName(mp3Path);
    var splitDir = Path.Combine(mp3Dir,Path.GetFileNameWithoutExtension(mp3Path));
    Directory.CreateDirectory(splitDir);

    int splitI = 0;
    int secsOffset = 0;

    using (var reader = new Mp3FileReader(mp3Path))
    {   
        FileStream writer = null;       
        Action createWriter = new Action(() => {
            writer = File.Create(Path.Combine(splitDir,Path.ChangeExtension(mp3File,(++splitI).ToString("D4") + ".mp3")));
        });

        Mp3Frame frame;
        while ((frame = reader.ReadNextFrame()) != null)
        {           
            if (writer == null) createWriter();

            if ((int)reader.CurrentTime.TotalSeconds - secsOffset >= splitLength)
            {   
                // time for a new file
                writer.Dispose();
                createWriter();
                secsOffset = (int)reader.CurrentTime.TotalSeconds;              
            }

            writer.Write(frame.RawData, 0, frame.RawData.Length);
        }

        if(writer != null) writer.Dispose();
    }
Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346
  • 1
    It shouldn't be very difficult to modify my sample to achieve that. Have you tried it? I could take a crack at it sometime, just not this moment. What is the unit of measurement for start and stop trim points? – Ronnie Overby Jan 03 '13 at 21:39
  • I've been trying still haven't got it yet. My first time with NAudio. The measurements would be a timespan. Start and stop. so basically a trim start and trim end. – Andre DeMattia Jan 04 '13 at 23:32
  • I tried it but CurrentTime is always zero, does anybody know why? – Paolo Costa Mar 03 '17 at 18:51
2

these would be helpful Alvas Audio (commercial) and ffmpeg

Govind Malviya
  • 13,627
  • 17
  • 68
  • 94
0

If you want to split podcasts, copy the tracks to an audio device (swimming headers in my case) and include a little audio header made from the Text To Speech service from Google to identify the tracks. (e.g. "History of the world in a hundred objects. Episode 15. Track 1 of 4") you could check a little bash script https://github.com/pulijon/cpodcast/blob/main/cutpodcast.bash

It is prepared to add the audio header in Spanish. For other languages you should change the option -l and the string of header

gtts-cli "Corte $((10#$ntrack)) de $((10#$numtracks)). $5 " -l es --output pre_$track
J.M. Robles
  • 614
  • 5
  • 9