【问题标题】:mp3 file length isn't shown correctmp3 文件长度显示不正确
【发布时间】:2013-03-29 12:02:53
【问题描述】:

我正在尝试使用 LAME (win7,vs2010,c++) 将 WAV 文件转换为 MP3 文件。

我找到了这段代码:

convert wav to mp3 using lame

转换工作正常,但是当我尝试使用 windows 媒体播放器打开文件时,文件的长度是错误的。

有什么方法可以使用 lame lib 来解决这个问题吗?(不能使用其他程序或其他 lib 或命令行,只能使用 c++ 代码...)

已编辑:在阅读了一些内容后,我尝试按照 sellibitze 的建议使用 lame_get_lametag_frame 函数。 这是我的代码:

#include <stdio.h>
#include <lame/lame.h>

int main(void)
{
  int read, write;

  FILE *pcm = fopen("in.pcm", "rb");
  FILE *mp3 = fopen("out.mp3", "wb");

  const int PCM_SIZE = 8192;
  const int MP3_SIZE = 8192;

  short int pcm_buffer[PCM_SIZE*2];
  unsigned char mp3_buffer[MP3_SIZE];

  lame_t lame = lame_init();
  lame_set_in_samplerate(lame, 44100);
  lame_set_VBR(lame, vbr_default);
  lame_set_write_id3tag_automatic(lame, 0);
  lame_init_params(lame);

  char buffer[256];
  int imp3=lame_get_id3v2_tag(gfp, buffer, sizeof(buffer));
  fwrite(buffer, 1, imp3, outf);
  long audio_pos=ftell(outf); // store beginning of audio data

  do {
    read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
    if (read == 0)
        write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
    else
        write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
    fwrite(mp3_buffer, write, 1, mp3);
  } while (read != 0);

  imp3=lame_get_id3v1_tag(gfp, buffer, sizeof(buffer));
  fwrite(buffer, 1, imp3, outf);

  imp3=lame_get_lametag_frame(gfp, buffer, sizeof(buffer));
  fseek(outf,audio_pos,SEEK_SET); // remember beginning of audio data
  fwrite(buffer, 1, imp3, outf);

  lame_close(lame);
  fclose(mp3);
  fclose(pcm);

  return 0;
}

已修复

我设法解决了这个问题,但我真的不明白它是如何解决的。 我将 mp3 文件的名称从“out.mp3”更改为任何其他名称,并且 wmp 显示正确的长度。我还尝试将已经创建的文件的名称从 out 更改为其他名称,并且它起作用了。任何人都可以向我解释它的发生方式吗?名称 out.mp3 保存了吗?

【问题讨论】:

    标签: c++ audio mp3 wav lame


    【解决方案1】:

    您喜欢使用 VBR 模式的示例代码。这种情况下的长度信息通常作为元数据放入第一帧。这称为 Xing/VBR 标头。它还包括一个低精度搜索表。但是这个信息显然只有在你将所有的音频数据传递给 LAME 之后才可用。我建议您在 LAME API 中寻找一个能够更新 Xing/VBR 标头以反映正确长度和查找表的函数,并在关闭文件之前调用它。

    lame_encode_flush 不会占用您的 FILE* 东西,因此它无法返回文件的开头并使用 Xing/VBR 标头更新第一个 mp3 帧。

    【讨论】:

    • 函数lame_encode_flush()不是写了id3标签和正确的长度吗?我总是得到相同的长度 1:24 分钟。但是当我在 win 7 explorer 中查看时,它显示了正确的长度。有什么方法可以从 Windows 中获取价值? Xing/VBR 标头中的这个值是如何保存的?(以哪种格式,多少字节等...)
    • @user2171244:看我的修改
    • 是否有任何功能可以做到这一点?(在蹩脚的 API 中)或者唯一的方法是更新 id3v2?如果我将其更改为使用 CBR,它会修复它吗?
    • @user2171244:请阅读头文件中关于lame_get_lametag_frame的文档
    • 对代码的新更改我确实更改了 wmp 中的时间栏,但它仍然不是正确的长度。我做错了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 2011-08-27
    • 2010-09-12
    • 1970-01-01
    • 2021-12-03
    相关资源
    最近更新 更多