/// <summary> /// Parse ID3 tags from stream and calculate where the audio must be /// </summary> /// <remarks> /// if this throws an exception, the File is not usable. /// </remarks> private void Initialise() { // create an empty framemodel, to use if we don't parse anything better FrameModel tagModel = new FrameModel(); // clear out any previous taghandler _tagHandler = null; // don't know how big the audio is until we've parsed the tags _audio = null; UInt32 audioNumBytes; using (FileStream sourceStream = _sourceFileInfo.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 = FrameManager.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(_sourceFileInfo, _audioStart, audioNumBytes, _tagHandler.Length); _audioReplaced = false; }