Search code examples
cffmpegdecodedurationlibav

How to get an accurate duration of any audio file quickly?


There are many audio files in the wild encoded with VBR which don't have an accurate duration tag, and command line FFMpeg would output the following:

Estimating duration from bitrate, this may be inaccurate

(and indeed, it is)

Using libav, we can see that this is tested with the has_duration() function from libavformat/utils.c

I have an audio player that needs to get an accurate duration information using libav. I've tried completely decoding the file and counting the total number of samples decoded which is the usual recommendation (and is accurate), but this can take 10+ seconds on a 60 minute audio file, which is not acceptable.

I notice that there are some closed source audio decoders and music playing apps which can get an accurate duration for these files immediately. There must be some cheap way of determining the accurate duration? Perhaps a snippet or high-level description would help me out.


Solution

  • It is possible to "demux" the track very quickly and examine the duration of each packet to determine the total duration of the track, decoding is not necessary.

    Simply adding durations in a loop until EOF is reached:

    int read = av_read_frame(pFormatCtx, packet);
    durationSeconds += packet->duration * (double) timebase;