4

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?

jocull
  • 20,008
  • 22
  • 105
  • 149

3 Answers3

6

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

  • I tried out the patch, it did not solve my problem of zero seconds, and also it confused all of my WMA and MP4/M4A files, returning them as just seconds. Thanks anyways. Is there a good place I can browse patches or outstanding issues for TagLib? – jocull Dec 03 '10 at 02:06
  • I just did a ton of digging in the TagLib# source and noticed two differences (but can't fully decipher what they are doing). One, it seems to do something with "Fraunhofer VBRI" headers. Second, it seems to pull its duration values out of some kind of "codec" variable. I can tell that my primary offenders are ID3V2 (2.2 maybe?) MP3 files. Oddly enough, foobar2000 reports them as 192kbps CBR. What is missing here? – jocull Dec 03 '10 at 04:08
  • @jocull Checking both source codes I see that the TagLib# is parsing both VBR Headers (Xing and Fraunhofer VBRI) of the MP3 files, but TagLib is parsing only Xing header. In this article http://www.codeproject.com/KB/audio-video/mpegaudioinfo.aspx#MPEGAudioFrame you can find additional information about both Headers. I think that if the parsing of the VBRI hader the zero seconds problem for the MP3 file must be resolved. – Luis G. Costantini R. Dec 08 '10 at 15:47
  • I noticed that too, but I couldn't determine if it was actually being used. I'll see what I can do with that. Thank you for the link. – jocull Dec 08 '10 at 18:24
3

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.

Brian Nickel
  • 26,890
  • 5
  • 80
  • 110
1

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:

TagLib::FileRef f(path);
int lengthInMillis = f.audioProperties()->lengthInMilliseconds();
Andrew Orobator
  • 7,978
  • 3
  • 36
  • 36