我的semestral项目将于本周四到期,我在阅读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标签的文件以及带有它们的一些文件,它可以正常工作,但是对于其他一些文件,ffmpeg(我用于解码)返回“无标题”错误,这意味着它没有正确捕获MP3标题。我知道,因为如果我从.mp3文件中移除ID3(例如Winamp),则不会发生错误。结论是大小计数算法并不总是有效。
所以问题是:我如何才能知道.mp3文件的整个ID3部分究竟有多大(所有可能的标签,专辑图片等等)?我到处寻找它,但我一直在寻找上面发布的这个算法。有时我还需要考虑一些大约10个字节的页脚,但它似乎经常会超过10个字节,以便最终捕获正确的MP3帧。
答案 0 :(得分:2)
ID3v1标签的大小始终固定为128字节。
我会找到以下说明
如果您对所有这些字段的大小求和,我们会看到30 + 30 + 30 + 4 + 30 + 1等于125字节而不是128字节。丢失的三个字节可以在歌曲标题之前的标签的最开头找到。这三个字节始终为“TAG”,并且标识这确实是ID3标记。查找ID3v1 / 1.1标记的最简单方法是从文件末尾查找128字节的单词“TAG”。
还有另一个名为ID3v2的版本:
其中一个设计目标是ID3v2应该非常灵活和可扩展...... 由于每个帧可以是16MB并且整个标记可以是256MB,因此您可能永远不会再次遇到与您尝试在旧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字节长的标记表示为$ 00 00 02 01.
答案 1 :(得分:2)
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;
}