public ID3v2(string path) { this.path = path; this.frames = new ArrayList(); this.frames.Add("TPE1"); this.frames.Add("TALB"); this.frames.Add("TIT2"); this.frameIDs = new Hashtable(); this.frameIDs.Add("TP1", "TPE1"); this.frameIDs.Add("TAL", "TALB"); this.frameIDs.Add("TT2", "TIT2"); using (ID3TagFileStream fs = new ID3TagFileStream(path, FileMode.Open)) { if (!fs.HaveID3v2()) { fs.Close(); isComplete = false; return; } version = fs.ReadVersion(); // Read ID3v2 version fs.ReadByte(); // Throw away flags byte // Read frames ReadFrames(fs, fs.ReadSize()); fs.Close(); string tempPath = System.IO.Path.GetFileNameWithoutExtension(path); if (title == "" || title == null) { title = tempPath; } if (artist == "" || artist == null) { artist = "Unknown"; } if (album == "" || album == null) { album = "Unknown"; } } }
/// <summary> /// Read all frames from specific FileStream /// </summary> /// <param name="Data">FileStream to read data from</param> /// <param name="length">Length of data to read from FileStream</param> private void ReadFrames(ID3TagFileStream dataStream, int length) { string frameID; int frameLength; byte buffer; // Check version for frameID length int frameIDLength = version.Minor == 2 ? 3 : 4; // Minimum frame size is 10 because frame header is 10 byte while (length > 10 && !isComplete) { // Remove padding buffer = dataStream.ReadByte(); if (buffer == 0) { length--; continue; } // If byte is nor zero, read frameID dataStream.Seek(-1, SeekOrigin.Current); // Read frame header frameID = dataStream.ReadText(frameIDLength); if (frameIDLength == 3 && frameIDs.Contains(frameID)) { frameID = (string)frameIDs[frameID]; } byte[] b = new byte[frameIDLength]; dataStream.Read(b, 0, b.Length); frameLength = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; // Throw away 2 flag bytes for (int i = 0; i < 2; i++) { dataStream.ReadByte(); } long pos = dataStream.Position; if (length > 0x10000000) { throw (new Exception("This file contain frame that have more than 256MB data")); } if (frames.Contains(frameID)) { // Throw away encoding byte dataStream.ReadByte(); frameLength--; string read = dataStream.ReadText(frameLength); switch (frameID) { case "TPE1": artist = read; break; case "TALB": album = read; break; case "TIT2": title = read; break; default: break; } if (artist != null && album != null && title != null) { isComplete = true; } } else { dataStream.Position = pos + frameLength; } length -= frameLength + 10; } }