This project has moved. For the latest updates, please go here.

Mp3FileReader not returning CurrentTime and Position

Nov 26, 2016 at 12:57 AM
I was using the following routine to trim (grab pieces of) MP3 files. Not sure when it stopped working, but now I find that no matter how many ReadNextFrames I issue the reader.CurrentTime and reader.Position remain 0. I'm running on Windows 10 Prof, and using Visual Studio 2013. I've tried the code with Naudio 1.7, 1.7.2, and 1.7.3 - same result. Any ideas as to where I'm going wrong would be appreciated. Here's the code ...
 public static void TrimMp3File(string inputPath, string outputPath, TimeSpan? begin, TimeSpan? end)
        {
            //  This routine trims an MP3 file
            //     Ref: http://stackoverflow.com/questions/7932951/trimming-mp3-files-using-naudio
            //             original code from Mark Heath (Naudio creator)

            // ********************** DEBUG: Start ************************* 
            TimeSpan Zero = new TimeSpan(0,0,0);  
            TimeSpan CurrentTime;
            TimeSpan CalculatedCurrentTime, CalculatedCurrentTimeBasedOnBytesRead;
            bool ProbePoint; 
            long BytesRead = 0;
            // **********************  DEBUG: End  *************************                                             

            if (begin.HasValue && end.HasValue && begin > end)
                throw new ArgumentOutOfRangeException("end", "end should be greater than begin");

            using (var reader = new Mp3FileReader(inputPath))
            {
                using (var writer = File.Create(outputPath))
                {
                    Mp3Frame frame;
                    while ((frame = reader.ReadNextFrame()) != null)
                    {
                        // ********************** DEBUG: Start **************************
                        //  BUG: reader.Position and reader.CurrentTime are never updated
                        // ************************************************************** 
                        CurrentTime = reader.CurrentTime;  
                        CalculatedCurrentTime = TimeSpan.FromSeconds((double)reader.Position / reader.WaveFormat.AverageBytesPerSecond); 
                        BytesRead += frame.RawData.Length;
                        CalculatedCurrentTimeBasedOnBytesRead = TimeSpan.FromSeconds((double)BytesRead / reader.WaveFormat.AverageBytesPerSecond); ;
                        if (CurrentTime != Zero) 
                        {
                           ProbePoint = true ;
                        }  
                        // **********************  DEBUG: End  *************************

                        if (reader.CurrentTime >= begin || !begin.HasValue)
                        {
                            if (reader.CurrentTime <= end || !end.HasValue)
                                writer.Write(frame.RawData, 0, frame.RawData.Length);
                            else break;
                        }

                    }

                }
            }
            
        }
Nov 26, 2016 at 9:45 PM
As a work around, I altered the program to calculate it's own CurrentTime rather than relying on reader.CurrentTime as follows.
I'm back in business ...

public static void TrimMp3File(string inputPath, string outputPath, TimeSpan? begin, TimeSpan? end)
        {
            //  This routine trims an MP3 file
            //     Ref: http://stackoverflow.com/questions/7932951/trimming-mp3-files-using-naudio
            //            * original code from Mark Heath (Naudio creator)
            //          http://stackoverflow.com/questions/6220660/calculating-the-length-of-mp3-frames-in-milliseconds
            //            * frame length in ms formula: lucianolev

            double currentSecond = 0.0D; //                                         2016-11-26: Start - fix: replaced reliance on reader.CurrentTime (which is not being updated)
            double beginSecond = 0.0D;   //                                                                  with the calculated currentSecond.
            double endSecond = 9999.0D;                                                             
            TimeSpan totalDuration = new TimeSpan(0, 0, 0); //                      2016-11-26: End
           
            if (begin.HasValue && end.HasValue && begin > end)
                throw new ArgumentOutOfRangeException("end", "end should be greater than begin");

            using (var reader = new Mp3FileReader(inputPath)) {
                totalDuration = reader.TotalTime; //                                2016-11-26: Start
                if (begin.HasValue) beginSecond = ((TimeSpan)begin).TotalSeconds;
                if (end.HasValue) endSecond = ((TimeSpan)end).TotalSeconds;
                else endSecond = totalDuration.TotalSeconds; //                     2016-11-26: End
                
                using (var writer = File.Create(outputPath)) {
                    Mp3Frame frame;
                    while ((frame = reader.ReadNextFrame()) != null) {
                         currentSecond += ((double)frame.SampleCount / (double)frame.SampleRate); //    2016-11-26
                         if (currentSecond >= beginSecond) { //                                         2016-11-26                                                    
                            if (currentSecond <= endSecond)  //                                         2016-11-26
                                writer.Write(frame.RawData, 0, frame.RawData.Length);
                            else break;
                        }
                    }
                }
            }
        }