/// <summary> /// Reads Lyrics3 tag in Mp3 format /// </summary> public static void ReadLyrics3Tag() { try { //ExStart:ReadLayrics3TagInMp3 // initialize Mp3Format class using (Mp3Format mp3Format = new Mp3Format((Common.MapSourceFilePath(filePath)))) { // get Lyrics3 v2.00 tag Lyrics3Tag lyrics3Tag = mp3Format.Lyrics3v2; // check if Lyrics3 is presented. It could be absent. if (lyrics3Tag != null) { // Display defined tag values Console.WriteLine("Album: {0}", lyrics3Tag.Album); Console.WriteLine("Artist: {0}", lyrics3Tag.Artist); Console.WriteLine("Track: {0}", lyrics3Tag.Track); // get all fields presented in Lyrics3Tag Lyrics3Field[] allFields = lyrics3Tag.Fields; foreach (Lyrics3Field lyrics3Field in allFields) { Console.WriteLine("Name: {0}, value: {1}", lyrics3Field.Name, lyrics3Field.Value); } } } //ExEnd:ReadLayrics3TagInMp3 } catch (Exception ex) { Console.WriteLine(ex.Message); } }
/// <summary> /// Update Lyrics3 Tag by replacing whole tag /// This method is supportd by version 18.10 or greater. /// </summary> public static void UpdateLyrics3TagByReplacingWholeTag() { using (Mp3Format format = new Mp3Format(Common.MapSourceFilePath(filePath))) { Lyrics3Tag tag = new Lyrics3Tag(); tag.Fields = new Lyrics3Field[] { new Lyrics3Field("EAL", "test album"), new Lyrics3Field("EAR", "test artist"), new Lyrics3Field("INF", "test info"), new Lyrics3Field("LYR", "[00:01] test lyrics"), }; format.UpdateLyrics3v2(tag); format.Save(Common.MapDestinationFilePath(filePath)); } }
public APEv2Tag(FileStream fs, ID3v1Tag id3v1, Lyrics3Tag lyrics3, bool afterAudioData) { Appended = false; Exists = false; Valid = false; long lngOffset = 32; //Size of footer tag of APEv2 if (id3v1.Exists) { lngOffset += id3v1.TagSize; //128 Bytes for ID3v1 } if (lyrics3.Exists) { lngOffset += lyrics3.TagSize; } RawFooter = new byte[32]; fs.Position = fs.Length - lngOffset; fs.Read(RawFooter, 0, 32); if (Encoding.ASCII.GetString(RawFooter, 0, 8) == "APETAGEX") { Exists = true; Appended = true; //Version uint v = ID3Base.expand(RawFooter[11], RawFooter[10], RawFooter[9], RawFooter[8]); TagSize = ID3Base.expand(RawFooter[15], RawFooter[14], RawFooter[13], RawFooter[12]); uint numOfItems = ID3Base.expand(RawFooter[19], RawFooter[18], RawFooter[17], RawFooter[16]); //Detect Header fs.Position = fs.Length - (lngOffset + TagSize); RawHeader = new byte[32]; fs.Read(RawHeader, 0, 32); if (Encoding.ASCII.GetString(RawHeader, 0, 8) == "APETAGEX") { //WERE GOOD ProcessFlags(); } } }
public MP3(string FileName) { Console.WriteLine(FileName); FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read); Valid = false; // Set the filename not including the path information strFileName = @fs.Name; char[] chrSeparators = new char[] { '\\', '/' }; string[] strSeparator = strFileName.Split(chrSeparators); int intUpper = strSeparator.GetUpperBound(0); strFileName = strSeparator[intUpper]; // Replace ' with '' for the SQL INSERT statement strFileName = strFileName.Replace("'", "''"); // Set the file size lngFileSize = fs.Length; byte[] bytHeader = new byte[4]; byte[] bytVBitRate = new byte[12]; int intPos = 0; // Keep reading 4 bytes from the header until we know for sure that in // fact it's an MP3 int nextFrame = 0; //Jeff - Location in stream to next Frame (current position + framesize) //Read if id3v1 exists id3v1 = new ID3v1Tag(fs); //Read if id3v2 exists id3v2 = new ID3v2Tag(fs); //Read if lyrics3 exists lyrics3 = new Lyrics3Tag(fs, id3v1.Exists); //Read if APEv2 exists apev2 = new APEv2Tag(fs, id3v1, lyrics3, true); //Pass up the ID3v2 tag (if it exists) if (id3v2.Exists) { if (!id3v2.FooterExists) { intPos = (int)id3v2.TagSize + 10; //+10 for header } else { intPos = (int)id3v2.TagSize + 20; //+20 for header and footer } } fs.Position = intPos; fs.Read(bytHeader, 0, 4); MPEGAudioFrame temp = new MPEGAudioFrame(bytHeader, 0); if (temp.Valid == false) { if (Encoding.ASCII.GetString(bytHeader, 0, 3) == "ID3") { //Another ID3v2 Tag? Console.WriteLine("Another ID3v2 tag was found after the initial one"); Console.WriteLine(); } else if (Encoding.ASCII.GetString(bytHeader, 0, 3) == "APE") { //APETAGEX has appeared before audio data Console.WriteLine("APEv2 Tag Found after ID3v2 tag"); Console.WriteLine(); } else { //Unknown - Somthing is here that is not supposed to be Console.WriteLine("Garbage found after ID3v2 tag"); Console.WriteLine(); } } //ID3v2 Tag was not valid, so the reported size may not be the actual size. Search backwards to try and find the first mpeg audio frame. if (!id3v2.Valid) { //Search Backwards (Max Search 16384) int intPosPrev = intPos; int maxPos = intPos - 16384; if (maxPos < 0) { maxPos = 0; } do { fs.Position = intPos; fs.Read(bytHeader, 0, 4); firstFrame = new MPEGAudioFrame(bytHeader, intPos); if (firstFrame.Valid) { nextFrame = intPos + firstFrame.FrameSize; fs.Position = nextFrame; bytHeader = new byte[4]; //Reset bytHeader array fs.Read(bytHeader, 0, 4); MPEGAudioFrame SecondHeader = new MPEGAudioFrame(bytHeader, nextFrame); if (SecondHeader.Valid) { Valid = true; break; } else { //The next frame did not appear valid - reset stream position fs.Position = intPos; } } intPos--; } while (!Valid && (fs.Position >= maxPos) && intPos >= 0); if (!Valid) { intPos = intPosPrev; } } //Search Forwards do { fs.Position = intPos; fs.Read(bytHeader, 0, 4); firstFrame = new MPEGAudioFrame(bytHeader, intPos); if (firstFrame.Valid) { nextFrame = intPos + firstFrame.FrameSize; fs.Position = nextFrame; bytHeader = new byte[4]; //Reset bytHeader array fs.Read(bytHeader, 0, 4); MPEGAudioFrame SecondHeader = new MPEGAudioFrame(bytHeader, nextFrame); if (SecondHeader.Valid) { Valid = true; break; } else { //The next frame did not appear valid - reset stream position fs.Position = intPos; } } intPos++; }while (!Valid && (fs.Position != fs.Length)); // If the current file stream position is equal to the length, // that means that we've read the entire file and it's not a valid MP3 file if (Valid && (fs.Position != fs.Length)) { intPos += 4; //Bypass the 4 byte header //The following is retrieved from XING SDK //http://www.mp3-tech.org/programmer/decoding.html if (firstFrame.getVersion() == 1.0) //MPEG Version 1 { if (firstFrame.ChannelModeIndex == 3) //Single Channel (Mono) { intPos += 17; } else { intPos += 32; } } else //MPEG Version 2.0 or 2.5 { if (firstFrame.ChannelModeIndex == 3) //Single Channel (Mono) { intPos += 9; } else { intPos += 17; } } // Check to see if the MP3 has a variable bitrate fs.Position = intPos; //fs.Read(bytVBitRate,0,12); //bVBR = LoadVBRHeader(bytVBitRate); vbrFrameInfo = new VBRHeader(fs, (long)intPos); // Find the last Audio Frame of the MP3 findLastFrame(fs); // Once the file's read in, then assign the properties of the file to the public variables intBitRate = getBitrate(); intFrequency = firstFrame.getFrequency(); strMode = firstFrame.getChannelMode(); intLength = getLengthInSeconds(); strLengthFormatted = getFormattedLength(); fs.Close(); } }