TagLib# (C#) 和 TagLib (C++) 中长度的差异
我目前正在将我的 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# 上没有任何问题。
任何想法表示赞赏。谢谢。
在赏金结束之前,有人还有更多想法吗?
I am currently in the process of moving my C# application over to Qt / C++. I'm running into problems with lengths from TagLib. I find it odd that TagLib# returns audio durations in milliseconds, while TagLib returns its (incorrect) durations in seconds. TagLib just returns zero for the length values, while TagLib# remains correct.
Here is my source in C# / TagLib#...
TagLib.File tagfile = TagLib.File.Create(path);
uint milliseconds = (uint)tagfile.Properties.Duration.TotalMilliseconds;
And here is what should be nearly equivalent in C++ / TagLib. I've even forced it to read accurately. No success.
TagLib::FileName fn(path);
TagLib::FileRef fr(fn, true, TagLib::AudioProperties::Accurate);
uint length = fr.audioProperties()->length();
It works as expected for a good majority of my media files. However, a select few audio files fail to return any audio properties (the rest of the tag information reads fine!). The exact same audio properties are returned with no issues on TagLib#.
Any ideas are appreciated. Thanks.
Does anyone have any more ideas before the bounty ends?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您好,taglib 有一个补丁可以计算以毫秒为单位的长度,这个人添加了一个方法(lengthMilliseconds()),它返回以毫秒为单位的长度,也许这对您有用:
http://web.archiveorange.com/archive/v/sF3Pjr01lSQjsqjrAC7L
Hi there is a patch to taglib that calculate the length in milliseconds, this guy added a method (lengthMilliseconds()) that return the length in milliseconds, maybe that could be useful for you:
http://web.archiveorange.com/archive/v/sF3Pjr01lSQjsqjrAC7L
自最初移植以来,TagLib# 的音频文件解析发生了很多变化,因此很难说具体的差异会发生在哪里。您可以检查 C++ 程序的调试消息。
我的猜测是,差异在于两个库对无效标头的反应方式。看来,如果它找到的第一个帧头无效,TagLib 将不会计算任何音频属性值。另一方面,TagLib# 在文件音频部分的前 16KiB 中查找第一个有效标头。如果它遇到的第一个标头已损坏,它将扫描下一个标头。如果我没记错的话,错误保存的 ID3v2 标签可能会导致 0xFF FF FF FF 出现在文件音频部分的开头。这将触发上述类型的故障。
问题出在 taglib/mpeg/mpegproperties.cpp 的第 166 行。这可以使用与第 171 行到 191 行相同的方法来解决,但您可能希望更新代码以在某个点后放弃,以防它确实不是 MP3 文件。
A lot has changed in TagLib#'s parsing of audio files since it was originally ported, so its hard to say where exactly the difference would occur. You may check your C++ program for debug messages.
My guess is that the difference is in how the two libraries react to invalid headers. It appears that if the first frame header it finds is invalid, TagLib won't calculate any audio property values. TagLib#, on the other hand, looks for the first valid header in the first 16KiB of the audio part of the file. If the first header it encounters is corrupt, it will scan for the next one. If I remember correctly, an incorrectly saved ID3v2 tag could result in 0xFF FF FF FF appearing in the beginning of the audio section of the file. This would trigger the type of failure described above.
The problem is at line 166 of taglib/mpeg/mpegproperties.cpp. This could be solved using the same approach as lines 171 to 191, but you would want to update the code to give up after a point in case it really isn't an MP3 file.
截至撰写本文时,TagLib 1.11 BETA 2 本身支持获取以毫秒为单位的音频长度。您可以使用以下代码来执行此操作:
As of this writing, TagLib 1.11 BETA 2 natively supports getting the length of audio in milliseconds. You can do so with the following code: