This question already has an answer here:
In your code, when you open the FileMp3Reader, uses the word Action and then placed inside by using a Lambda expression, a method.
What does the keyword Action?
Inside the file.Create method what is being done?
var mp3Path = @"C:\Users\ronnie\Desktop\mp3\dotnetrocks_0717_alan_dahl_imagethink.mp3";
int splitLength = 120;
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)
        {   
            writer.Dispose();
            createWriter();
            secsOffset = (int)reader.CurrentTime.TotalSeconds;              
        }
        writer.Write(frame.RawData, 0, frame.RawData.Length);
    }
    if(writer != null) writer.Dispose();
}
As noted in the comments, Action here is a delegate type. Which, given it's placement in the variable declaration, probably could have been inferred by many readers from the context. :)
The code in the File.Create() method simply generates a new file name based on the splitI index.
Ironically, in this particular case, the use of Action is superfluous. The code really should not have been written this way, as the delegate just makes it harder to read. A better version looks like this:
using (var reader = new Mp3FileReader(mp3Path))
{
    FileStream writer = null;      
    try
    {
        Mp3Frame frame;
        while ((frame = reader.ReadNextFrame()) != null)
        {           
            if (writer != null &&
                (int)reader.CurrentTime.TotalSeconds - secsOffset >= splitLength)
            {   
                writer.Dispose();
                writer = null;
                secsOffset = (int)reader.CurrentTime.TotalSeconds;              
            }
            if (writer == null)
                writer = File.Create(Path.Combine(splitDir,
                    Path.ChangeExtension(mp3File,(++splitI).ToString("D4") + ".mp3")));
            writer.Write(frame.RawData, 0, frame.RawData.Length);
        }
    }
    finally
    {
        if(writer != null) writer.Dispose();
    }
}
That way, the work to create a new FileStream instance is only ever needed in one place.
Even if it were really required to call it from two different places, IMHO this particular scenario would call for named method instead. The code would have been more readable that way, than using the delegate instance.
Path.ChangeExtension(mp3File,(++splitI).ToString("D4") + ".mp3"))); - missennasplitI), which is used to create file names of the form <original name>XXXX.mp3 where <original name> is of course the name of the original file, XXXX is the four-digit, zero-padding index of the segment being written, and of course .mp3 is the extension. This allows the loop to write out the original single file, as partial segments, each an MP3 clip no longer than splitLength in seconds. If you need more than that, you should post another question asking for specifics - Peter Duniho