1. Open the audio file for reading in binary mode.
2. Check if the last 128 bytes contain the "TAG" header that identifies the ID3 tag.
3. Extract the following fields from the ID3 tag:
- Title: 30 characters
- Artist: 30 characters
- Album: 30 characters
- Year: 4 characters
- Comment: 30 characters
- Genre: 1 byte (integer representing a predefined genre)
4. Display the extracted data in a human-readable format, converting the genre number into its corresponding music genre.
5. Handle cases where the file does not contain an ID3 tag.
ID3 specifications apply to any file or audiovisual container, but they are primarily used with audio containers. There are three compatible versions of the specification. For example, a file may contain both version 1.1 and version 2.0 tags simultaneously, and in this case, the media player must determine which tags are relevant.
ID3 version 1 is a very simple specification. It involves appending a fixed block size of 128 bytes to the end of the file in question. This block contains the following tags:
A header that identifies the presence of the ID3 block and its version. Specifically, this header comprises the characters "TAG".
- Title: 30 characters.
- Artist: 30 characters.
- Album: 30 characters.
- Year: 4 characters.
- Comment: 30 characters.
- Genre (music): 1 character.
All tags use ASCII characters, except for genre, which is an integer stored within a single byte. The musical genre associated with each byte is predefined in the standard definitions and includes 80 genres numbered from 0 to 79. Some tagging programs have expanded the predefined genres beyond 79.
using System;
using System.IO;
using System.Text;
class ID3Reader
{
static void Main(string[] args)
{
Console.WriteLine("Please enter the path of the audio file:");
string filePath = Console.ReadLine();
if (!File.Exists(filePath))
{
Console.WriteLine("File does not exist.");
return;
}
try
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
fs.Seek(-128, SeekOrigin.End);
byte[] id3Tag = new byte[128];
fs.Read(id3Tag, 0, 128);
if (Encoding.ASCII.GetString(id3Tag, 0, 3) == "TAG")
{
string title = Encoding.ASCII.GetString(id3Tag, 3, 30).Trim();
string artist = Encoding.ASCII.GetString(id3Tag, 33, 30).Trim();
string album = Encoding.ASCII.GetString(id3Tag, 63, 30).Trim();
string year = Encoding.ASCII.GetString(id3Tag, 93, 4).Trim();
string comment = Encoding.ASCII.GetString(id3Tag, 97, 30).Trim();
byte genreByte = id3Tag[127];
string[] genres = new string[]
{
"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop",
"Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae",
"Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
"Soundtrack", "Euro-Techno", "Pop/Funk", "Jungle", "Native American", "Cabaret",
"New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Trance",
"Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel",
"Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental"
};
Console.WriteLine("Title: " + title);
Console.WriteLine("Artist: " + artist);
Console.WriteLine("Album: " + album);
Console.WriteLine("Year: " + year);
Console.WriteLine("Comment: " + comment);
Console.WriteLine("Genre: " + (genreByte >= 0 && genreByte < genres.Length ? genres[genreByte] : "Unknown"));
}
else
{
Console.WriteLine("No ID3v1 tag found in the file.");
}
}
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
}
}
Output
//Given the audio file contains an ID3 tag, the program will display:
Please enter the path of the audio file:
C:\path\to\audio.mp3
Title: My Song
Artist: Some Artist
Album: My Album
Year: 2021
Comment: Great song!
Genre: Rock
//If no ID3 tag is found, the program will output:
Please enter the path of the audio file:
C:\path\to\audio.mp3
No ID3v1 tag found in the file.