java 获取id3v1信息_ID3v1信息结构(MP3文件)的读取、修改(C#)

本文介绍了如何使用Java读取和修改MP3文件的ID3v1元数据,包括歌曲名、艺术家、专辑、发行年、备注、曲目编号和流派等信息。详细讲解了ID3v1.0和1.1版本的区别,并提供了相关的编码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

前几天了解到MP3文件的ID3v1信息和ID3v2信息结构,其中ID3v1信息存储的内容比较简单,有歌曲名、艺术家、专辑、发行年、备注、曲目编号、流派。其版本有1.0和1.1,其中1.0没有曲目编号。

正文

ID3v1信息存储在MP3文件的尾部,一共128字节,可有可无。以下是其信息排列:

ID3v1.1(1.0中无曲目编号,所以其备注包括Null character和Track,共30字节)

Tag Field

Data(character)

Offset(from end of mp3)

TAG

3

-128 to -126

Song title(歌曲名)

30

-125 to -96

Artist(艺术家)

30

-95 to -66

Album(专辑)

30

-65 to -36

Year(发行年)

4

-35 to -32

Comment(备注)

28

-31 to -4

Null character

1

-3

Track(曲目编号)

1

-2

Genre(流派)

1

-1

说明

Year:以字符串形式存在,获取时无需将其从byte[4]转换成int。

Null character:此为保留位,1.1中始终为(byte)0,所以通过其判断Comment的大小和ID3v1的版本。

Track:int类型,其值为 0 - 255,毕竟1byte只能存这么多。

Genre: int类型,其对应类型详见附录。

知道了以上信息就可以开始编码了。

publicenumID3v1TagVersion

{

ID3v10,

ID3v11

}

ID3v1

707d287cf53a4aa60c0a5baadd3eef3e.png

privateID3v1(){ }publicID3v1(stringpath)

{

MP3Path=path;

ReadPath(MP3Path);

}

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png私有字段和共属性

#regionPrivate FieldsprivateID3v1TagVersion _tagVersion;privatestring_title;//30 charactersprivatestring_artist;//30 charactersprivatestring_album;//30 charactersprivatestring_year;//4 charactersprivatestring_comment;//28 characters, sometimes it's 30 characters when the next byte is not be 0 and this tag has not track information.privatestring_reserved;//1 byte, if it's 0 that means the next byte should contain which track on the CD this music comes from.privateint_track;//1 byte, sometimes not exist if the reserved byte is not 0.privateint_genre=12;//1 byteprivatestringMP3Path;//mp3 file path#endregion#regionPropertypublicID3v1TagVersion TagVersion

{get{return_tagVersion; }set{ _tagVersion=value;if(value==ID3v1TagVersion.ID3v11) {this.Comment=this._comment; } }

}publicstringTitle

{get{return_title; }set{ _title=GetString(value,30); }

}publicstringArtist

{get{return_artist; }set{ _artist=GetString(value,30); }

}publicstringAlbum

{get{return_album; }set{ _album=GetString(value,30); }

}publicstringYear

{get{return_year; }set{ _year=GetString(value,4); }

}publicstringComment

{get{return_comment; }set{ _comment=GetString(value,this._tagVersion==ID3v1TagVersion.ID3v10?30:28); }

}privatestringReserved

{get{return_reserved; }set{ _reserved=value; }

}publicintTrack

{get{return_track; }set{if(value>=0&&value<=0xff)

{

_track=value;if(this._tagVersion==ID3v1TagVersion.ID3v10)

{this.TagVersion=ID3v1TagVersion.ID3v11;

}

}

}

}publicintGenre

{get{return_genre; }set{ _genre=value; }

}#endregion

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png读取ID3v1信息

privatevoidReadPath(stringpath)

{using(FileStream stream=File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))

{this.ReadStream(stream);

}

}privatevoidReadStream(Stream stream)

{if(stream.Length>=128)

{

Encoding encode=Encoding.Default;byte[] tag=newbyte[128];

stream.Seek(-128L, SeekOrigin.End);

stream.Read(tag,0,128);if("TAG"==encode.GetString(tag,0,3))

{this._title=encode.GetString(tag,3,30);this._artist=encode.GetString(tag,33,30);this._album=encode.GetString(tag,63,30);this._year=encode.GetString(tag,93,4);if(tag[125]==0)

{this._tagVersion=ID3v1TagVersion.ID3v11;this._comment=encode.GetString(tag,97,28);this._track=tag[126];

}else{this._tagVersion=ID3v1TagVersion.ID3v10;this._comment=encode.GetString(tag,97,30);this._track=0;

}this._genre=(int)tag[127];

}

}

}

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png保存ID3v1信息

privatevoidSave(stringpath)

{using(FileStream stream=File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None))

{

Save(stream);

}

}privatevoidSave(Stream stream)

{byte[] header=SafeGetBytes("TAG");byte[] title=SafeGetBytes(this._title);byte[] artist=SafeGetBytes(this._artist);byte[] album=SafeGetBytes(this._album);byte[] year=SafeGetBytes(this._year);byte[] comment=SafeGetBytes(this._comment);

stream.Seek((long)-GetTagSize(stream), SeekOrigin.End);

stream.Write(header,0,3);

WriteBytesPadded(stream, title,30);

WriteBytesPadded(stream, artist,30);

WriteBytesPadded(stream, album,30);

WriteBytesPadded(stream, year,4);if(this._tagVersion==ID3v1TagVersion.ID3v11)

{

WriteBytesPadded(stream, comment,28);

stream.WriteByte(0);

stream.WriteByte((byte)this._track);

}else{

WriteBytesPadded(stream, comment,30);

}

stream.WriteByte((byte)this._genre);

}

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png私有函数

privatestaticstringGetString(stringvalue,intmaxLength)

{if(value==null)

{returnnull;

}

value=value.Trim();returnvalue.Length>maxLength?value.Substring(0, maxLength) : value;

}privatestaticintGetTagSize(stringpath)

{using(FileStream stream=File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))

{returnGetTagSize(stream);

}return0;

}privatestaticintGetTagSize(Stream stream)

{if(stream.Length>=128L)

{byte[] header=newbyte[3];

stream.Seek(-128L, SeekOrigin.End);

stream.Read(header,0,3);if(Encoding.Default.GetString(header)=="TAG")

{return128;

}

}return0;

}privatestaticbyte[] SafeGetBytes(stringvalue)

{if(value==null)

{returnnewbyte[0];

}returnEncoding.Default.GetBytes(value);

}privatestaticvoidWriteBytesPadded(Stream stream,byte[] buffer,intlength)

{intindex=0;while((index

{

stream.WriteByte(buffer[index]);

index++;

}while(index

{

stream.WriteByte(0);

index++;

}

}

结语

有了这些就可以实现MP3的ID3v1信息的读取和修改了。

附录

流派信息有两部分,摘自ID3.ORG。若想知道其他流派信息,请自行搜索。

1. ID3v1定义的(流派前的数字是编号)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngID3v1定义

0. Blues1. Classic Rock2. Country3. Dance4. Disco5. Funk6. Grunge7. Hip-Hop8. Jazz9. Metal10. New Age11. Oldies12. Other13. Pop14. R&B15. Rap16. Reggae17. Rock18. Techno19. Industrial20. Alternative21. Ska22. Death Metal23. Pranks24. Soundtrack25. Euro-Techno26. Ambient27. Trip-Hop28. Vocal29. Jazz+Funk30. Fusion31. Trance32. Classical33. Instrumental34. Acid35. House36. Game37. Sound Clip38. Gospel39. Noise40. AlternRock41. Bass42. Soul43. Punk44. Space45. Meditative46. Instrumental Pop47. Instrumental Rock48. Ethnic49. Gothic50. Darkwave51. Techno-Industrial52. Electronic53. Pop-Folk54. Eurodance55. Dream56. Southern Rock57. Comedy58. Cult59. Gangsta60. Top4061. Christian Rap62. Pop/Funk63. Jungle64. Native American65. Cabaret66. New Wave67. Psychadelic68. Rave69. Showtunes70. Trailer71. Lo-Fi72. Tribal73. Acid Punk74. Acid Jazz75. Polka76. Retro77. Musical78. Rock&Roll79. Hard Rock

2. Winamp扩展的

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngWinamp扩展

80. Folk81. Folk-Rock82. National Folk83. Swing84. Fast Fusion85. Bebob86. Latin87. Revival88. Celtic89. Bluegrass90. Avantgarde91. Gothic Rock92. Progressive Rock93. Psychedelic Rock94. Symphonic Rock95. Slow Rock96. Big Band97. Chorus98. Easy Listening99. Acoustic100. Humour101. Speech102. Chanson103. Opera104. Chamber Music105. Sonata106. Symphony107. Booty Bass108. Primus109. Porn Groove110. Satire111. Slow Jam112. Club113. Tango114. Samba115. Folklore116. Ballad117. Power Ballad118. Rhythmic Soul119. Freestyle120. Duet121. Punk Rock122. Drum Solo123. A capella124. Euro-House125. Dance Hall

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值