我有一组音频文件(DSDIFF,规格说明),有人在其中附加了一个ID3v2标记。这不符合文件的标准,因此标准的ID3v2解析器(如TagLib)不能识别音频文件并拒绝解析它。(为什么做这种不标准的事情似乎是个好主意,我无法理解。)
我可以手动解析文件并提取原始的ID3标记(作为char* + size);但是,我不知道如何从这里开始获取原始标记中各个帧的值。
我想使用TagLib来解析char*,但我以前从未使用过这个库。我也可以使用其他库。我不想从头开始编写我自己的解析器。
以下是我到目前为止尝试过的:
尝试1
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
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?帕迪建议使用
auto tag = TagLib::ID3v2::Tag().parse(TagLib::ByteVector(buff, size));不幸的是,.parse是Tag的一个受保护的方法。我尝试继承并创建一个内部调用parse的瘦包装器parse,但这也不起作用。
建议受到高度赞赏:)
我知道如果一个类似的问题:Taglib从任意文件ID3v2读取c++标记
但是,答案是“只需为您的文件类型使用特定的解析器”。在我的例子中,这个解析器不存在,因为文件类型实际上不支持ID3标记;无论如何,有人只是附加了它们。
发布于 2021-01-13 09:22:02
AmigoJack让我走上了正确的轨道,找到了一个解决方案。虽然TagLib::File是一个抽象类,不能直接实例化,但可以使用现有的文件格式特定解析器之一。可以创建一个只包含ID3标记的文件,并使用MPEG解析器读取它。
下面是相关的代码片段:
// ... 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());发布于 2020-12-12 00:50:01
如果您已经能够提取ID3数据,那么将其放入一个/使其成为一个IOStream,然后将其交给TagLib的File构造函数。或者将其存储在单独的(临时)文件中,以便TagLib能够访问它。我本人从未使用过它,但如果它需要MPEG数据来识别任何ID3标记(毕竟,这些标记始终处于文件的开头或结尾,而不需要解析任何音频数据),我会感到惊讶。
您想提供的示例文件应该很小--我们中没有人需要音频数据,只需要ID3数据(前后可能有50字节)。即使这样,ID3v2内容也是无关紧要的--它的前30个字节应该足够一个妖魔化了--而这些字节可以像下面这样容易地打印出来:\x49\x44\x33\x03.
https://stackoverflow.com/questions/65034630
复制相似问题