代码之家  ›  专栏  ›  技术社区  ›  jocull

TaLib(C)和TagLib(C+)长度的差异

  •  3
  • jocull  · 技术社区  · 15 年前

    我目前正在把我的C应用程序移动到Qt/C++。TagLib的长度有问题。我觉得奇怪的是,TagLib以毫秒为单位返回音频持续时间,而TagLib以秒为单位返回其(不正确的)持续时间。TagLib刚刚返回 对于长度值,而TagLib#保持正确。

    这是我在C#/TagLib#。。。

    TagLib.File tagfile = TagLib.File.Create(path);
    uint milliseconds = (uint)tagfile.Properties.Duration.TotalMilliseconds;
    

    这里是在C++/TAGLIB中几乎等价的东西。我甚至强迫它准确阅读。没有成功。

    TagLib::FileName fn(path);
    TagLib::FileRef fr(fn, true, TagLib::AudioProperties::Accurate);
    uint length = fr.audioProperties()->length();
    

    我的大部分媒体文件都能正常工作。但是,一些选定的音频文件无法返回任何音频属性(其余的标记信息可以读取!)。返回的音频属性完全相同,但TagLib没有问题。

    任何想法都值得赞赏。谢谢。

    赏金结束前还有人有什么想法吗?

    3 回复  |  直到 15 年前
        1
  •  5
  •   Luis G. Costantini R.    15 年前

    嗨,taglib有一个补丁可以计算毫秒长度,这个家伙添加了一个方法(length milliseconds())可以返回毫秒长度,也许这对你有用: http://web.archiveorange.com/archive/v/sF3Pjr01lSQjsqjrAC7L

        2
  •  3
  •   Brian Nickel    15 年前

    TagLib对音频文件的解析自最初移植以来发生了很大的变化,所以很难说这种差异到底会发生在哪里。您可以检查C++程序的调试消息。

    我的猜测是,这两个库对无效头的反应不同。如果找到的第一个帧头无效,TagLib将不会计算任何音频属性值。另一方面,TagLib查找文件音频部分的前16KiB中的第一个有效头。如果遇到的第一个报头损坏,它将扫描下一个报头。如果我没记错的话,错误保存的ID3v2标记可能会导致0xFF FF FF出现在文件音频部分的开头。这将触发上述类型的故障。

    问题出在taglib/mpeg/mpegproperties.cpp的第166行。这可以使用与第171行到第191行相同的方法来解决,但是您需要更新代码,以便在一个点之后放弃,以防它真的不是MP3文件。

        3
  •  1
  •   Andrew Orobator    9 年前

    在撰写本文时,TagLib 1.11beta 2本机支持以毫秒为单位获取音频长度。您可以使用以下代码执行此操作:

    TagLib::FileRef f(path);
    int lengthInMillis = f.audioProperties()->lengthInMilliseconds();