首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用ID3v2从char*缓冲区解析TagLib

用ID3v2从char*缓冲区解析TagLib
EN

Stack Overflow用户
提问于 2020-11-27 09:09:33
回答 2查看 281关注 0票数 0

我有一组音频文件(DSDIFF,规格说明),有人在其中附加了一个ID3v2标记。这不符合文件的标准,因此标准的ID3v2解析器(如TagLib)不能识别音频文件并拒绝解析它。(为什么做这种不标准的事情似乎是个好主意,我无法理解。)

我可以手动解析文件并提取原始的ID3标记(作为char* + size);但是,我不知道如何从这里开始获取原始标记中各个帧的值。

我想使用TagLib来解析char*,但我以前从未使用过这个库。我也可以使用其他库。我不想从头开始编写我自己的解析器。

以下是我到目前为止尝试过的:

尝试1

代码语言:javascript
复制
auto file_name = std::filesystem::path("location/of/audio.dff");
auto file_stream = std::fstream(file_name);

// ... parsing the DSDIFF section of the file
// until I encounter the "ID3 " chunk.

auto id3_start = file_stream.tellg();
TagLib::FileRef taglib_file(file_name.string().cstr());

// when executing, taglib_file.isNull() evaluates to true
if (taglib_file.isNull()) 
    std::cerr << "TagLib can't read the file." << std::endl;

auto tag = TagLib::ID3v2::Tag(taglib_file.file(), id3_start);
// ... handle the tag

这种方法不起作用,因为TagLib不知道如何解析DSDIFF格式。因此,taglib_file是一个NULL指针,不读取标记。

尝试2

代码语言:javascript
复制
auto file_name = std::filesystem::path("location/of/audio.dff");
auto file_stream = std::fstream(file_name);

// ... parsing the DSDIFF section of the file
// until I encounter "ID3 ".
// read the size of the tag and store it in `size`

char* id3tag = new char[size];
file_stream.read(buff, size);

// How to parse the id3tag here?

帕迪建议使用

代码语言:javascript
复制
auto tag = TagLib::ID3v2::Tag().parse(TagLib::ByteVector(buff, size));

不幸的是,.parseTag的一个受保护的方法。我尝试继承并创建一个内部调用parse的瘦包装器parse,但这也不起作用。

建议受到高度赞赏:)

我知道如果一个类似的问题:Taglib从任意文件ID3v2读取c++标记

但是,答案是“只需为您的文件类型使用特定的解析器”。在我的例子中,这个解析器不存在,因为文件类型实际上不支持ID3标记;无论如何,有人只是附加了它们。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-13 09:22:02

AmigoJack让我走上了正确的轨道,找到了一个解决方案。虽然TagLib::File是一个抽象类,不能直接实例化,但可以使用现有的文件格式特定解析器之一。可以创建一个只包含ID3标记的文件,并使用MPEG解析器读取它。

下面是相关的代码片段:

代码语言:javascript
复制
// ... parse the DSDIFF file and convert the data into FLAC format
// until ID3 tag

const struct {
    int length; // number of bytes in ID3 tag
    char* data; // filled while parsing the DSDIFF file
} *id3_data;

const auto data = TagLib::ByteVector(id3_data->data, id3_data->length);
auto stream = TagLib::ByteVectorStream(data);
auto file = TagLib::MPEG::File(&stream, TagLib::ID3v2::FrameFactory::instance());

/* copy all supported tags to the FLAC file*/
flac_tags.tag()->setProperties(file.tag()->properties());
票数 0
EN

Stack Overflow用户

发布于 2020-12-12 00:50:01

如果您已经能够提取ID3数据,那么将其放入一个/使其成为一个IOStream,然后将其交给TagLib的File构造函数。或者将其存储在单独的(临时)文件中,以便TagLib能够访问它。我本人从未使用过它,但如果它需要MPEG数据来识别任何ID3标记(毕竟,这些标记始终处于文件的开头或结尾,而不需要解析任何音频数据),我会感到惊讶。

您想提供的示例文件应该很小--我们中没有人需要音频数据,只需要ID3数据(前后可能有50字节)。即使这样,ID3v2内容也是无关紧要的--它的前30个字节应该足够一个妖魔化了--而这些字节可以像下面这样容易地打印出来:\x49\x44\x33\x03.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65034630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档