【问题标题】:Differences in length in TagLib# (C#) and TagLib (C++)TagLib# (C#) 和 TagLib (C++) 中的长度差异
【发布时间】:2010-11-29 06:10:26
【问题描述】:

我目前正在将我的 C# 应用程序迁移到 Qt / C++。我遇到了来自 TagLib 的长度问题。我觉得奇怪的是 TagLib# 以毫秒为单位返回音频持续时间,而 TagLib 以秒为单位返回其(不正确的)持续时间。 TagLib 只为长度值返回 zero,而 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# 上返回完全相同的音频属性,没有问题。

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

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

【问题讨论】:

    标签: c# c++ taglib taglib-sharp


    【解决方案1】:

    嗨,taglib 有一个以毫秒为单位计算长度的补丁,这个人添加了一个以毫秒为单位返回长度的方法 (lengthMilliseconds()),也许这对你有用: http://web.archiveorange.com/archive/v/sF3Pjr01lSQjsqjrAC7L

    【讨论】:

    • 谢谢,我去看看。
    • 我试用了这个补丁,它并没有解决我的零秒问题,而且它混淆了我所有的 WMA 和 MP4/M4A 文件,只返回几秒钟。无论如何谢谢。有什么好地方可以让我浏览 TagLib 的补丁或未解决的问题?
    • 我刚刚在 TagLib# 源代码中进行了大量挖掘,发现了两个不同之处(但无法完全理解它们在做什么)。一,它似乎对“Fraunhofer VBRI”标题做了一些事情。其次,它似乎将其持续时间值从某种“编解码器”变量中提取出来。我可以说我的主要罪犯是 ID3V2(可能是 2.2?)MP3 文件。奇怪的是,foobar2000 将它们报告为 192kbps CBR。这里缺少什么?
    • @jocull 检查两个源代码我看到 TagLib# 正在解析 MP3 文件的两个 VBR 标头(Xing 和 Fraunhofer VBRI),但 TagLib 仅解析 Xing 标头。在这篇文章codeproject.com/KB/audio-video/… 中,您可以找到有关这两个标头的更多信息。我认为如果VBRI hader的解析必须解决MP3文件的零秒问题。
    • 我也注意到了这一点,但我无法确定它是否真的被使用了。我会看看我能用它做什么。谢谢你的链接。
    【解决方案2】:

    自最初移植以来,TagLib# 对音频文件的解析发生了很大变化,因此很难说具体会发生在哪里。您可以检查您的 C++ 程序是否有调试消息。

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 2014-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多