示例#1
0
        /// <summary>
        /// Construct from file info; parse ID3 tags from stream and calculate where the audio must be
        /// </summary>
        /// <param name="fileinfo"></param>
        public MP3FileData(FileInfo fileinfo)
        {
            _sourceFileInfo = fileinfo;

            // create an empty frame model, to use if we don't parse anything better
            TagModel tagModel = new TagModel();

            // don't know how big the audio is until we've parsed the tags
            UInt32 audioNumBytes;

            using( FileStream sourceStream = fileinfo.Open( FileMode.Open, FileAccess.Read, FileShare.Read ) )
            {
                // all the header calculations use UInt32; 
                // this guarantees all the file offsets we have to deal with fit in a UInt32
                if( sourceStream.Length > UInt32.MaxValue )
                    throw new InvalidAudioFrameException( "MP3 file can't be bigger than 4gb" );

                // in the absence of any recognised tags,
                // audio starts at the start
                _audioStart = 0;
                // audio is entire file length
                audioNumBytes = (UInt32)sourceStream.Length;

                // try to read an ID3v1 block.
                // If ID3v2 block exists, its values overwrite these
                // Otherwise, if ID3V1 block exists, its values are used
                // The audio is anything that's left after all the tags are excluded.
                try
                {
                    ID3v1 id3v1 = new ID3v1();
                    id3v1.Deserialize( sourceStream );

                    // fill in ID3v2 block from the ID3v1 data
                    tagModel = id3v1.FrameModel;

                    // audio is shorter by the length of the id3v1 tag
                    audioNumBytes -= ID3v1.TagLength;
                }
                catch( TagNotFoundException )
                {
                    // ignore "no ID3v1 block"
                    // everything else isn't caught here, and throws out to the caller
                }

                try
                {
                    sourceStream.Seek( 0, SeekOrigin.Begin );
                    tagModel = TagManager.Deserialize( sourceStream );

                    // audio starts after the tag
                    _audioStart = (uint)sourceStream.Position;
                    // audio is shorter by the length of the id3v2 tag
                    audioNumBytes -= _audioStart;
                }
                catch( TagNotFoundException )
                {
                    // ignore "no ID3v2 block"
                    // everything else isn't caught here, and throws out to the caller
                }

                // create a taghandler to hold the tagmodel we've parsed, if any
                _tagHandler = new TagHandler( tagModel );

            } // closes sourceStream

            // save the location of the audio in the original file
            // passing in audio size and id3 length tag (if any) to help with bitrate calculations
            _audio = new AudioFile( fileinfo, _audioStart, audioNumBytes, _tagHandler.Length );
            _audioReplaced = false;
        }