介绍:
除了音轨之外,数字音频文件还可以包含相关的文本和/或图形信息。您可能熟悉的信息包括歌曲名称,艺术家名称,专辑名称,年份和流派的形式。这是在计算机或便携式设备上播放数字音频文件时显示的信息。
将声音以外的信息包含到这些数字音频文件中的过程通常称为“标记”,其中您用描述音频文件的其他信息“标记”音频文件。标记数字文件的原始标准由埃里克·肯普(Eric Kemp)于1996年开发,他创造了ID3一词。那时,ID3仅表示“识别MP3”。
ID3的版本:
ID3,ID3v1和ID3v2主要有2个版本,如下所述:
1. ID3v1: MP3标准不包括用于存储文件元数据的方法。 1996年,埃里克·坎普(Eric Kemp)提出了将一小部分数据添加到音频文件的想法,从而解决了这一问题。现在被称为ID3v1的方法迅速成为在MP3中存储元数据的标准。
ID3v1标签占用128个字节,从文件末尾开始,字符串TAG 128个字节开始。标签被放置在文件的末尾,以保持与旧媒体播放器的兼容性。有些玩家在读取标签时会播放一阵静电,但大多数人却忽略了它,几乎所有现代玩家都会正确地跳过它。此标签允许标题,艺术家,专辑和“评论”分别使用30个字节,一年中的4个字节和一个字节,以从预定义的80个值列表中识别歌曲的类型(Winamp后来将该列表扩展为148个值)。
ID3v1的一项改进是Michael Mutschler在1997年进行的。由于注释字段太小,无法编写任何有用的东西,因此他决定将其缩小两个字节,并使用这两个字节来存储轨道号。此类标签称为ID3v1.1
2. ID3v2:在1998年,由多个贡献者创建了一个称为ID3v2的新规范。[13]尽管它的名称为ID3,但其结构与ID3v1有很大不同。
ID3v2标签的大小可变,通常出现在文件的开头,这有助于流媒体,因为只要文件开始流传输,元数据就基本上可用,而不是像ID3v1那样要求首先读取整个文件。 ID3v2标签由许多帧组成,每个帧包含一个元数据。例如,TIT2框架包含标题,而WOAR框架包含艺术家网站的URL。帧的最大长度为16MB,而标签的总大小限制为256MB。通过不仅在ISO-8859-1中而且在Unicode中都允许对字符串进行编码,解决了国际化问题。 ID3v2进一步细分为3个版本,分别为ID3v2.2,ID3v2.3和ID3v2.4,它们之间的帧略有变化。
ID3匕首:
ID3标签可以通过多种方式进行编辑。在某些平台上,可以通过在文件管理器中查看扩展信息来编辑文件的属性。此外,大多数音频播放器都允许编辑单个或成组的文件。编辑文件组通常称为“批处理标记”。还有一些专门的应用程序,称为标记程序,专门用于编辑标记和相关任务。某些功能(例如puddletag)提供了高级功能,例如高级批处理标记或基于正则表达式的编辑。
下面是实现自己的标记器的代码。
例子:
Input: Input MP3 file name which needs to tagged like input.mp3 and output MP3
file name which would be created as a tagged MP3 file like output.mp3.
Output: MP3 file with tagging information as entered by the user.
以下是用于实现自己的标记器的C代码:
// C program for ID3 tagging of music files
#include
#include
#include
struct tags // Structure to store tagging information.
{
char title[100], artist[100], album[100],
track_num[100], year[100], genre[100];
};
void merge_file(char* file1, char* file2, char* file3)
{
FILE *f1, *f2, *f3;
int ch;
f1 = fopen(file1, "rb"); // Opening in write mode.
f2 = fopen(file2, "rb");
f3 = fopen(file3, "wb");
if (f1 == NULL || f2 == NULL) {
exit(EXIT_FAILURE);
}
while ((ch = fgetc(f1)) != EOF) // Appending tagging info.
fputc(ch, f3);
while ((ch = fgetc(f2)) != EOF) // Appending media file info.
fputc(ch, f3);
// Closing the files.
fclose(f1);
fclose(f2);
fclose(f3);
}
void tagging(char* file1, char* file2, char* file3)
{
int size = 0;
char clean[100];
struct tags t;
unsigned char pad1[7] = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76 };
unsigned char pad2[3] = { 0x00, 0x00, 0x00 };
FILE* f1;
f1 = fopen(file1, "wb");
fprintf(f1, "ID3");
fwrite(pad1, sizeof(pad1), 1, f1); /*Essential tag to identify
as an ID3 tagged media file.*/
gets(clean); // Clearing the input stream.
// Taking input from user.
printf("\nEnter the title of the mp3:");
scanf("%[^\n]%*c", t.title);
printf("\nEnter the artist of the mp3:");
scanf("%[^\n]%*c", t.artist);
printf("\nEnter the album of the mp3.\n");
scanf("%[^\n]%*c", t.album);
printf("\nEnter the year of the mp3.\n");
scanf("%[^\n]%*c", t.year);
printf("\nEnter the track number of the mp3.\n");
scanf("%[^\n]%*c", t.track_num);
// Track Number
// Tag to identify track number.
fprintf(f1, "TRCK");
// Essential 3 NULL bits required for separation.
fwrite(pad2, sizeof(pad2), 1, f1);
size = strlen(t.track_num);
size++; // Calculating size.
// Appending the size of the track number to tag.
fprintf(f1, "%c", size);
// Essential 3 NULL bits required for separation.
fwrite(pad2, sizeof(pad2), 1, f1);
// Adding tag number entered by the user.
fprintf(f1, "%s", t.track_num);
// Print Year
fprintf(f1, "TYER");
fwrite(pad2, sizeof(pad2), 1, f1);
size = strlen(t.year);
size++; // Calculating size.
fprintf(f1, "%c", size);
fwrite(pad2, sizeof(pad2), 1, f1);
fprintf(f1, "%s", t.year);
// Print Title
fprintf(f1, "TIT2");
fwrite(pad2, sizeof(pad2), 1, f1);
size = strlen(t.title);
size++; // Calculating size.
fprintf(f1, "%c", size);
fwrite(pad2, sizeof(pad2), 1, f1);
fprintf(f1, "%s", t.title);
// Print Artist
fprintf(f1, "TPE1");
fwrite(pad2, sizeof(pad2), 1, f1);
size = strlen(t.artist);
size++; // Calculating size.
fprintf(f1, "%c", size);
fwrite(pad2, sizeof(pad2), 1, f1);
fprintf(f1, "%s", t.artist);
// Print Album
fprintf(f1, "TALB");
fwrite(pad2, sizeof(pad2), 1, f1);
size = strlen(t.album);
size++; // Calculating size.
fprintf(f1, "%c", size);
fwrite(pad2, sizeof(pad2), 1, f1);
fprintf(f1, "%s", t.album);
// Print Genre
fprintf(f1, "TCON"); // Tag to identify genre.
fwrite(pad2, sizeof(pad2), 1, f1);
size = strlen(t.genre);
size++; // Calculating size.
fprintf(f1, "%c", size);
fwrite(pad2, sizeof(pad2), 1, f1);
fprintf(f1, "%s", t.genre);
fclose(f1); // Closing the file.
}
int main()
{
char file1[100] = "media_info.txt", file2[100], file3[100];
printf("\nEnter the input mp3 file name\n");
scanf("%s", file2);
printf("\nEnter the output mp3 file name\n");
scanf("%s", file3);
// Function to append media info to input file.
tagging(file1, file2, file3);
// Function to merge media info and media
// input file.
merge_file(file1, file2, file3);
return 0;
}
注意:运行代码的文件夹应包含input.mp3文件。
参考:
http://id3.org/id3v2.3.0
https://zh.wikipedia.org/wiki/ID3#ID3v2