微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 LAME 编码器库从 PCM (WAV) 文件中检索 ID3 标签信息?

如何解决如何使用 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 标签信息数据块):

enter image description here

您可以看到包含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 举报,一经查实,本站将立刻删除。