Пример #1
0
 public Mp3Reader(FileInfo file)
 {
     _file       = file;
     _fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 65536);
     // Analyze keyframes data
     AnalyzeKeyFrames();
     _firstFrame = true;
     // Process ID3v2 header if present
     ProcessID3v2Header();
     // Create file metadata object
     _fileMeta = CreateFileMeta();
     // MP3 header is length of 32 bits, that is, 4 bytes
     // Read further if there's still data
     if (_fileStream.Length - _fileStream.Position > 4)
     {
         // Look to next frame
         SearchNextFrame();
         // Save position
         long pos = _fileStream.Position;
         // Read header...
         // Data in MP3 file goes header-data-header-data...header-data
         Mp3Header header = ReadHeader();
         // Set position
         _fileStream.Position = pos;
         // Check header
         if (header != null)
         {
             CheckValidHeader(header);
         }
         else
         {
             throw new NotSupportedException("No initial header found.");
         }
     }
 }
Пример #2
0
        /// <summary>
        /// Check if the file can be played back with Flash. Supported sample rates are 44KHz, 22KHz, 11KHz and 5.5KHz
        /// </summary>
        /// <param name="header"></param>
        private void CheckValidHeader(Mp3Header header)
        {
            switch (header.SampleRate)
            {
            case 44100:
            case 22050:
            case 11025:
            case 5513:
                // Supported sample rate
                break;

            default:
                throw new NotSupportedException("Unsupported sample rate: " + header.SampleRate);
            }
        }
Пример #3
0
        public bool HasMoreTags()
        {
            Mp3Header header = null;

            while (header == null && (_fileStream.Length - _fileStream.Position) > 4)
            {
                try
                {
                    byte[] buffer = new byte[4];
                    _fileStream.Read(buffer, 0, 4);
                    header = new Mp3Header(buffer);
                }
                catch (IOException ex)
                {
                    log.Error("MP3Reader HasMoreTags", ex);
                    break;
                }
                catch (Exception)
                {
                    SearchNextFrame();
                }
            }

            if (header == null)
            {
                return(false);
            }

            if (header.FrameSize == 0)
            {
                // TODO find better solution how to deal with broken files...
                // See APPSERVER-62 for details
                return(false);
            }

            if (_fileStream.Position + header.FrameSize - 4 > _fileStream.Length)
            {
                // Last frame is incomplete
                _fileStream.Position = _fileStream.Length;
                return(false);
            }

            _fileStream.Position = _fileStream.Position - 4;
            return(true);
        }
Пример #4
0
        private Mp3Header ReadHeader()
        {
            Mp3Header header = null;

            while (header == null && (_fileStream.Length - _fileStream.Position) > 4)
            {
                try
                {
                    byte[] buffer = new byte[4];
                    _fileStream.Read(buffer, 0, 4);
                    header = new Mp3Header(buffer);
                }
                catch (IOException ex)
                {
                    log.Error("MP3Reader ReadTag", ex);
                    break;
                }
                catch (Exception)
                {
                    SearchNextFrame();
                }
            }
            return(header);
        }
Пример #5
0
        public KeyFrameMeta AnalyzeKeyFrames()
        {
            lock (_syncLock)
            {
                if (_frameMeta != null)
                {
                    return(_frameMeta);
                }

#if !NET_1_1
                List <long>   positionList  = new List <long>();
                List <double> timestampList = new List <double>();
#else
                ArrayList positionList  = new ArrayList();
                ArrayList timestampList = new ArrayList();
#endif
                _dataRate = 0;
                long   rate    = 0;
                int    count   = 0;
                long   origPos = _fileStream.Position;
                double time    = 0;
                _fileStream.Position = 0;
                ProcessID3v2Header();
                SearchNextFrame();
                while (this.HasMoreTags())
                {
                    Mp3Header header = ReadHeader();
                    if (header == null)
                    {
                        // No more tags
                        break;
                    }

                    if (header.FrameSize == 0)
                    {
                        // TODO find better solution how to deal with broken files...
                        // See APPSERVER-62 for details
                        break;
                    }

                    long pos = _fileStream.Position - 4;
                    if (pos + header.FrameSize > _fileStream.Length)
                    {
                        // Last frame is incomplete
                        break;
                    }

                    positionList.Add(pos);
                    timestampList.Add(time);
                    rate += header.BitRate / 1000;
                    time += header.FrameDuration;
                    _fileStream.Position = pos + header.FrameSize;
                    count++;
                }
                // restore the pos
                _fileStream.Position = origPos;

                _duration = (long)time;
                _dataRate = (int)(rate / count);
#if !NET_1_1
                _posTimeMap = new Dictionary <long, double>();
#else
                _posTimeMap = new Hashtable();
#endif
                _frameMeta            = new KeyFrameMeta();
                _frameMeta.Duration   = _duration;
                _frameMeta.Positions  = new long[positionList.Count];
                _frameMeta.Timestamps = new int[timestampList.Count];
                _frameMeta.AudioOnly  = true;
                for (int i = 0; i < _frameMeta.Positions.Length; i++)
                {
                    _frameMeta.Positions[i]  = (int)positionList[i];
                    _frameMeta.Timestamps[i] = (int)timestampList[i];
                    _posTimeMap.Add(positionList[i], timestampList[i]);
                }
                return(_frameMeta);
            }
        }
Пример #6
0
        public ITag ReadTag()
        {
            lock (_syncLock)
            {
                if (_firstFrame)
                {
                    // Return file metadata as first tag.
                    _firstFrame = false;
                    return(_fileMeta);
                }

                Mp3Header header = ReadHeader();
                if (header == null)
                {
                    return(null);
                }

                int frameSize = header.FrameSize;
                if (frameSize == 0)
                {
                    // TODO find better solution how to deal with broken files...
                    // See APPSERVER-62 for details
                    return(null);
                }

                if (_fileStream.Position + frameSize - 4 > _fileStream.Length)
                {
                    // Last frame is incomplete
                    _fileStream.Position = _fileStream.Length;
                    return(null);
                }

                _tag          = new Tag(IOConstants.TYPE_AUDIO, (int)_currentTime, frameSize + 1, null, _prevSize);
                _prevSize     = frameSize + 1;
                _currentTime += header.FrameDuration;
                byte[] buffer = new byte[_tag.BodySize];
                //ByteBuffer body = ByteBuffer.Allocate(_tag.BodySize);
                byte tagType = (byte)((IOConstants.FLAG_FORMAT_MP3 << 4) | (IOConstants.FLAG_SIZE_16_BIT << 1));
                switch (header.SampleRate)
                {
                case 44100:
                    tagType |= (byte)(IOConstants.FLAG_RATE_44_KHZ << 2);
                    break;

                case 22050:
                    tagType |= (byte)(IOConstants.FLAG_RATE_22_KHZ << 2);
                    break;

                case 11025:
                    tagType |= (byte)(IOConstants.FLAG_RATE_11_KHZ << 2);
                    break;

                default:
                    tagType |= (byte)(IOConstants.FLAG_RATE_5_5_KHZ << 2);
                    break;
                }
                tagType |= (header.IsStereo ? IOConstants.FLAG_TYPE_STEREO : IOConstants.FLAG_TYPE_MONO);

                /*
                 * body.Put(tagType);
                 * body.PutInt(header.Data);
                 * byte[] buffer = new byte[frameSize - 4];
                 * _fileStream.Read(buffer, 0, buffer.Length);
                 * body.Put(buffer);
                 * body.Flip();
                 * _tag.Body = body.ToArray();
                 */
                buffer[0] = tagType;
                Array.Copy(header.Data, 0, buffer, 1, 4);
                _fileStream.Read(buffer, 5, frameSize - 4);
                _tag.Body = buffer;
                return(_tag);
            }
        }