the tag is used to describe the mpeg audio file. it contains information about artist, title, album, publishing year and genre. there is some extra space for comments. it is exactly 128 bytes long and is located at very end of the audio data. you can get it by reading the last 128 bytes of the mpeg audio file.
aaabbbbb bbbbbbbb bbbbbbbb bbbbbbbb
bccccccc cccccccc cccccccc cccccccd
dddddddd dddddddd dddddddd dddddeee
efffffff ffffffff ffffffff fffffffg
sign | length (bytes) | position (bytes) | description |
a | 3 | (0-2) | tag identification. must contain 'tag' if tag exists and is correct. |
b | 30 | (3-32) | title |
c | 30 | (33-62) | artist |
d | 30 | (63-92) | album |
e | 4 | (93-96) | year |
f | 30 | (97-126) | comment |
g | 1 | (127) | genre |
the specification asks for all fields to be padded with null character (ascii 0). however, not all applications respect this (an example is winamp which pads fields with <space>, ascii 32).
there is a small change proposed in mp3v1.1 structure. the last byte of the comment field may be used to specify the track number of a song in an album. it should contain a null character (ascii 0) if the information is unknown.
genre is a numeric field which may have one of the following values:
0 | 'blues' | 20 | 'alternative' | 40 | 'alternrock' | 60 | 'top 40' |
1 | 'classic rock' | 21 | 'ska' | 41 | 'bass' | 61 | 'christian rap' |
2 | 'country' | 22 | 'death metal' | 42 | 'soul' | 62 | 'pop/funk' |
3 | 'dance' | 23 | 'pranks' | 43 | 'punk' | 63 | 'jungle' |
4 | 'disco' | 24 | 'soundtrack' | 44 | 'space' | 64 | 'native american' |
5 | 'funk' | 25 | 'euro-techno' | 45 | 'meditative' | 65 | 'cabaret' |
6 | 'grunge' | 26 | 'ambient' | 46 | 'instrumental pop' | 66 | 'new wave' |
7 | 'hip-hop' | 27 | 'trip-hop' | 47 | 'instrumental rock' | 67 | 'psychadelic' |
8 | 'jazz' | 28 | 'vocal' | 48 | 'ethnic' | 68 | 'rave' |
9 | 'metal' | 29 | 'jazz+funk' | 49 | 'gothic' | 69 | 'showtunes' |
10 | 'new age' | 30 | 'fusion' | 50 | 'darkwave' | 70 | 'trailer' |
11 | 'oldies' | 31 | 'trance' | 51 | 'techno-industrial' | 71 | 'lo-fi' |
12 | 'other' | 32 | 'classical' | 52 | 'electronic' | 72 | 'tribal' |
13 | 'pop' | 33 | 'instrumental' | 53 | 'pop-folk' | 73 | 'acid punk' |
14 | 'r&b' | 34 | 'acid' | 54 | 'eurodance' | 74 | 'acid jazz' |
15 | 'rap' | 35 | 'house' | 55 | 'dream' | 75 | 'polka' |
16 | 'reggae' | 36 | 'game' | 56 | 'southern rock' | 76 | 'retro' |
17 | 'rock' | 37 | 'sound clip' | 57 | 'comedy' | 77 | 'musical' |
18 | 'techno' | 38 | 'gospel' | 58 | 'cult' | 78 | 'rock & roll' |
19 | 'industrial' | 39 | 'noise' | 59 | 'gangsta' | 79 | 'hard rock' |
any other value should be considered as 'unknown' |
以上是mp3文件tag区的文档格式:
下面针对上面的说明,来订制一个读取tag信息的类:
using system;
using system.text;
namespace mp3coder
{
/**//// <summary>
/// clsmp3tag 的摘要说明。
/// 利用c#来解读mp3文件的tag区信息。
/// </summary>
/// 作者:任兀
/// nick name:dsclub(兀儿 - 干部)
/// qq:9967030
/// e-mail:dsclub at 126.com
/// msn:dsclub at hotmail.com
/// 版权声明:本代码只用于c#的学习交流。
/// 如果您想转载或将代码应用于您的作品中,请保留此信息。
public class clsmp3tag
{
private byte[] tagbody = new byte[128];
private byte[] stag = new byte[3];
private byte[] stitle = new byte[30];
private byte[] sartist = new byte[30];
private byte[] salbum = new byte[30];
private byte[] syear = new byte[4];
private byte[] scomment = new byte[30];
private byte[] sgenre = new byte[1];
system.exception myexception;
public clsmp3tag(byte[] tag)
{
if( tag.length != 128 )
{
myexception = new exception("不是标准的 mpeg-mp3 tag 格式。/ntag长度应该是 128 byte。");
throw(myexception);
}
else
{
array.copy(tag, 0, stag, 0, 3);
if( !encoding.default.getstring(stag).equals("tag") )
{
myexception = new exception("不是标准的 mpeg-mp3 tag 格式。/ntag位校验出错。");
throw(myexception);
}
array.copy(tag, 3, stitle, 0, 30);
array.copy(tag, 33, sartist, 0, 30);
array.copy(tag, 63, salbum, 0, 30);
array.copy(tag, 93, syear, 0, 4);
array.copy(tag, 97, scomment, 0, 30);
array.copy(tag, 127, sgenre, 0, 1);
}
}
/**///////////////////////////////////////////////////////
/// 以下是属性,只读
//////////////////////////////////////////////////////
public string title
{
get
{
return encoding.default.getstring(stitle);
}
}
public string artist
{
get
{
return encoding.default.getstring(sartist);
}
}
public string album
{
get
{
return encoding.default.getstring(salbum);
}
}
public string year
{
get
{
return encoding.default.getstring(syear);
}
}
public string comment
{
get
{
return encoding.default.getstring(scomment);
}
}
public , string genre
{
get
{
switch(convert.toint16(sgenre[0]))
{
case 0: return "blues"; case 20: return "alternative"; case 40: return "alternrock"; case 60: return "top 40";
case 1: return "classic rock"; case 21: return "ska"; case 41: return "bass"; case 61: return "christian rap";
case 2: return "country"; case 22: return "death metal"; case 42: return "soul"; case 62: return "pop/funk";
case 3: return "dance"; case 23: return "pranks"; case 43: return "punk"; case 63: return "jungle";
case 4: return "disco"; case 24: return "soundtrack"; case 44: return "space"; case 64: return "native american";
case 5: return "funk"; case 25: return "euro-techno"; case 45: return "meditative"; case 65: return "cabaret";
case 6: return "grunge"; case 26: return "ambient"; case 46: return "instrumental pop"; case 66: return "new wave";
case 7: return "hip-hop"; case 27: return "trip-hop"; case 47: return "instrumental rock"; case 67: return "psychadelic";
case 8: return "jazz"; case 28: return "vocal"; case 48: return "ethnic"; case 68: return "rave";
case 9: return "metal"; case 29: return "jazz+funk"; case 49: return "gothic"; case 69: return "showtunes";
case 10: return "new age"; case 30: return "fusion"; case 50: return "darkwave"; case 70: return "trailer";
case 11: return "oldies"; case 31: return "trance"; case 51: return "techno-industrial"; case 71: return "lo-fi";
case 12: return "other"; case 32: return "classical"; case 52: return "electronic"; case 72: return "tribal";
case 13: return "pop"; case 33: return "instrumental"; case 53: return "pop-folk"; case 73: return "acid punk";
case 14: return "r&b"; case 34: return "acid"; case 54: return "eurodance"; case 74: return "acid jazz";
case 15: return "rap"; case 35: return "house"; case 55: return "dream"; case 75: return "polka";
case 16: return "reggae"; case 36: return "game"; case 56: return "southern rock"; case 76: return "retro";
case 17: return "rock"; case 37: return "sound clip"; case 57: return "comedy"; case 77: return "musical";
case 18: return "techno"; case 38: return "gospel"; case 58: return "cult"; case 78: return "rock & roll";
case 19: return "industrial"; case 39: return "noise"; case 59: return "gangsta"; case 79: return "hard rock";
default:
return "未知类型";
}
}
}
}
}