正确读取被ID3标签干扰的MP3文件

Proper reading of MP3 file disrupted by ID3 tags

本文关键字:干扰 MP3 文件 标签 ID3 读取      更新时间:2023-10-16

我的学期项目将于本周四到期,我在阅读MP3文件时遇到了重大问题(该项目是关于声音分析的,不要问我到底是关于什么以及为什么这么晚才做)。

首先,我读取前10个字节来检查ID3标签。如果他们在场,我会跳到第一个MP3标题——或者至少这是个大主意。以下是我如何计算ID3标签大小:

if (inbuf[0] == 'I' && inbuf[1] == 'D' && inbuf[2] == '3') //inbuf contains first 10 bytes from file
{
int size = inbuf[3] * 2097152 + inbuf[4] * 16384 + inbuf[5] * 128 + inbuf[6]; //Will change to binary shifts later
//Do something else with it - skip rest of ID3 tags etc
}

它适用于没有ID3标记的文件和一些带有ID3标签的文件,但对于其他一些文件,ffmpeg(我用于解码)返回"无标题"错误,这意味着它没有正确捕获MP3标题。我知道,因为如果我从.mp3文件中删除ID3(例如使用Winamp),就不会出现错误。结论是大小计数算法并不总是有效的。

所以问题是:我如何才能知道.mp3文件的整个ID3部分到底有多大(所有可能的标签、相册图片等等)?我到处都在找,但我一直在找我上面发布的这个算法。有时我也需要考虑一些10字节的页脚,但似乎它经常会超过10字节,以便最终捕捉到合适的MP3帧。

ID3v1标记的大小始终固定为128字节。

我会找到以下描述

如果将所有这些字段的大小相加,我们会看到30+30+30+4+30+1等于125字节,而不是128字节。缺失的三个字节可以在标签的开头,歌曲标题之前找到。这三个字节总是"TAG",并且是这确实是ID3标签的标识。查找ID3v1/1.1标记的最简单方法是从文件末尾查找128字节的单词"tag"。

来源:http://id3.org/ID3v1

还有另一个版本,称为ID3v2:

设计目标之一是ID3v2应该非常灵活和可扩展。。。由于每个帧可以是16MB,整个标签可以是256MB,因此您可能再也不会处于与您试图在旧ID3中写一个有用的注释时相同的情况,因为旧ID3限制为30个字符。

此ID3v2始终从音频文件的开头开始,您可以在此处阅读:http://id3.org/ID3v2Easy

ID3v2/file identifier   "ID3"
ID3v2 version           $03 00
ID3v2 flags             %abc00000
ID3v2 size              4 * %0xxxxxxx

ID3v2标签大小用四个字节编码,其中每个字节中的最高有效位(位7)设置为零,总共28位。零位被忽略,因此257字节长的标签表示为$000 02 01。

bool LameDecoder::skipDataIfRequired()
{
auto data = m_file.read(3);
Q_ASSERT(data.size() == 3);
if (data.size() != 3)
return false;
if (memcmp(data.constData(), "ID3", 3))
{
m_file.seek(0);
return true;
}
// ID3v2 tag is detected; skip it
m_file.seek(3+2+1);
data = m_file.read(4);
if (data.size() != 4)
return false;
qint32 size = (data[0] << (7*3)) | (data[1] << (7*2)) |
(data[2] << 7) | data[3];
m_file.seek(3+2+1+4+size);
return true;
}