如何解决如何使用 LAME 编码器库从 PCM (WAV) 文件中检索 ID3 标签信息?
我在从测试 WAV 文件中检索标签信息时遇到问题(没有声音,只有空的 WAV 文件)。
这是我初始化 LAME 的方法:
lame_global_flags* lame = NULL;
lame = lame_init();
lame_set_in_samplerate(lame,44100);
lame_set_VBR(lame,vbr_default);
id3tag_init(lame);
id3tag_add_v2(lame);
id3tag_v2_only(lame);
lame_set_write_id3tag_automatic(lame,1);
// id3tag_set_artist(lame,"Test artist");
// id3tag_set_album(lame,"Test ablum");
lame_init_params(lame);
unsigned char buffer[256];
size_t id3tagSize = lame_get_id3v2_tag(lame,buffer,sizeof(buffer));
老实说,这并没有真正帮助解决问题,因为它不涉及已读取的文件(请参阅下面的代码)。
这是我的输入 PCM 文件的十六进制视图(只是 ID3 标签信息数据块):
您可以看到包含TIT2(标题)、TALB(专辑)、TPUB(出版商)等的信息块(见列表所有 ID3 标签名称为 here),这意味着信息在那里,但 LAME 编码器似乎忽略了它。
如果标签名称不为空,则根据我的观察,它后跟特定数量的字节。例如TIT2后接0x00 0x00 0x00 0x08
,转换为十进制表示标题的length+1
,即"Message"
加上0x00
的填充。
但是,如果我输入轨道总数 TRACKTOTAL
,我会得到 1 0x00
字节(可能是填充)加上任意数量的字节,每个字节都包含数字的十六进制代码表示。例如,如果我将 300
作为总曲目数,我将得到 54 52 41 43 4b 54 4f 54 41 4c 00 33 30 30
,就可以将其转换为字符串 TRACKTOTAL 300
。
我可以尝试手动解析此信息,但我宁愿花时间处理代码的另一部分。有非标准的标签名称,标签信息通常放在文件的开头或结尾(基于 RIFF WAVE 文件的规范)等。不想编写自己的 ID3 标签解析器。 -_-
起初我没有尝试配置任何与标记相关的内容。根据 lame.h
,LAME 的默认行为(除非禁用标记)是启用 lame_set_write_id3tag_automatic(lame_global_flags * gfp,int)
(int
参数)。我的初始代码是:
#include <stdio.h>
#include <lame.h>
int main(int argc,char* argv[])
{
int read = 0;
int write = 0;
char* path = argv[1];
printf("WAV input: %s\n",path);
FILE *pcm = fopen(path,"rb");
FILE *mp3 = fopen("output.mp3","wb");
fseek(pcm,SEEK_END);
const int PCM_SIZE = ftell(pcm);
fseek(pcm,SEEK_SET);
const int MP3_SIZE = PCM_SIZE;
short int pcm_buffer[PCM_SIZE * 2];
unsigned char mp3_buffer[MP3_SIZE];
lame_global_flags* lame = NULL;
lame = lame_init();
lame_set_in_samplerate(lame,44100);
lame_set_VBR(lame,vbr_default);
lame_init_params(lame);
do
{
read = fread(pcm_buffer,2 * sizeof(short int),PCM_SIZE,pcm);
if (read == 0)
{
// Todo Retrieve ID3 tag here? copy?
write = lame_encode_flush(lame,mp3_buffer,MP3_SIZE);
}
else
{
write = lame_encode_buffer_interleaved(lame,pcm_buffer,read,MP3_SIZE);
}
fwrite(mp3_buffer,write,1,mp3);
}
while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
然而,即使制作了 MP3 文件并且所有音频数据都在其中(当然我也尝试过其他 WAV 文件),但 ID3 标签信息却不见了。
使用 id3tag_set_artist(...)
、id3tag_set_album(...)
等手动设置 ID3 标签有效。但是,我正在寻找一种将 ID3 标签从源 (PCM) 复制到目标 (MP3) 的方法。 LAME 的文档基本上是它的标题,这并不是那么好。除了 lame_set_write_id3tag_automatic(...)
之外,我找不到与复制标签相关的任何内容。
我尝试了 ID3v1 和 ID3v2,因为只有当其中一个文本字段不适合 ID3v1 时才会生成 ID3v2,但另一方面强制 ID3v2 应该覆盖此设置。
此外,lame_encode_flush(...)
应该写入任何 ID3v1 标签。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。