而且没有简单的方法可以做到这一点。
您需要使用第三方库。而且,虽然有一些第三方库可以透明地处理读取各种不同格式的标签,但它们只能以这种方式处理“基本集”标签;对于其他任何事情,您必须真正了解这些格式。
例如,使用TagLib,要获取艺术家,您只需这样做:
TagLib::FileRef f1("myfile.mp3");
cout << f1.tag()->artist();
TagLib::FileRef f2("myotherfile.aac");
cout << f2.tag()->artist();
但对于歌词,它是这样的:
TagLib::MPEG::File f1("myfile.mp3");
TagLib::ID3v2::FrameList frames = f1.ID3v2Tag()->frameListMap()["USLT"];
if (!frames.isEmpty()) {
TagLib::ID3v2::UnsynchronizedLyricsFrame *frame =
dynamic_cast<TagLib::ID3v2::UnsynchronizedLyricsFrame *>(frames.front());
// There could be multiple frames here; you may want to look at language
// and/or description, instead of just picking the first.
if (frame) cout << frames->text;
}
TagLib::MP4::File f2("myotherfile.aac");
TagLib::MP4::Item item = f2.tag()->itemListMap()["\xa9lyr"];
TagLib::StringList strings = item.toStringList();
if (!strings.isEmpty()) {
// As above, there could be multiple strings.
cout << strings->front();
}
这不是我的想法,所以不要指望它会完全按原样工作。当然,几乎没有错误处理。但是缺少的重要一点是它没有告诉您如何确定您正在处理的文件类型,以及您将从中得到什么类型的标签。 (对于上面的两个示例,这很容易,但是名为“.flac”的文件可以是 OGG FLAC 或原始 FLAC,并且可以具有 VORBISCOMMENT、MetaFLAC、ID3 或 APE 标签。)TagLib 有一些帮助也是,但它仍然不是微不足道的。
幸运的是,如果您只关心获得与 iTunes 10.6.3 完全相同的歌词,那并不难;规则似乎是这样的:
- 如果扩展名是 MP2 或 MP3(不区分大小写),并且是带有 ID3v2.3 或 ID3v2.4 元数据的 MPEG 音频文件,则第一个 USLT 标签的内容(无论描述或语言)是歌词。
- 如果扩展名与 .m4?、.aac、.mp4 或其他一些文件匹配,并且它是一个 MPEG-4 文件,其音轨包含 IMTF 元数据,则第一个 ©lyr 块中的第一个字符串的内容是歌词。
- 在任何其他情况下,都没有歌词。
而且,由于您只处理 ID3v2 和 ITMF,因此为每个使用单独的库实际上可能更简单 - 例如,libmp4v2 处理 MPEG4 文件比 TagLib 更简单(因为它不处理任何东西 但是 MPEG4 文件),类似这样:
MP4FileHandle f = MP4Open("myotherfile.aac");
const MP4Tags *tags = MP4TagsAlloc();
MP4TagsFetch(tags, f);
cout << tags->lyrics;
MP4TagsFree(tags);
MP4Close(f);
此外,如果不必使用本机代码(Cocoa 或 Carbon),则可以使用其他语言的一些更简单的库。例如,在 Python 中,使用Mutagen,您可以这样做:
def printlyrics(path):
f = mutagen.File(path)
for key in f.keys():
if key.startswith('USLT') or key == u'\xa9lyr':
print f[key]
return
printlyrics("myfile.mp3")
printlyrics("myotherfile.aac")
当然,我仍然必须知道 ID3v2 将歌词称为“USLT:my desc:'eng'”,而 ITMF 将它们称为“©lyr”,但由于 Python 的动态特性,Mutagen 可以隐藏所有其他细节.