How to get the real, actual duration of an MP3 file (VBR or CBR) server-side

I finally found a proper solution to this problem using sox - which returns the correct information.

sox file.mp3 -n stat
Samples read:          19321344
Length (seconds):    219.062857
Scaled by:         2147483647.0
Maximum amplitude:     1.000000
Minimum amplitude:    -1.000000
Midline amplitude:    -0.000000
Mean    norm:          0.141787
Mean    amplitude:     0.000060
RMS     amplitude:     0.191376
Maximum delta:         0.947598
Minimum delta:         0.000000
Mean    delta:         0.086211
RMS     delta:         0.115971
Rough   frequency:         4253
Volume adjustment:        1.000

Length (seconds): 219.062857


You can decode the file completely to get the actual duration:

ffmpeg -i input.mp3 -f null -

The second to the last line of the console output will show something like:

size=N/A time=00:03:49.12 bitrate=N/A

Where time is the actual duration. In this example the whole process took about 0.5 seconds.


Extending solution from llogan (LordNeckbeard). To get only stats you can add flags -v quiet -stats

ffmpeg -v quiet -stats -i input.mp3 -f null - 

Simpler is to use ffmpeg to copy the file from the one with the faulty duration in its ID3 tag. This causes it to write the correct information.

ffmpeg -i "audio.mp3" -acodec copy "audio_fixed.mp3"

Because it uses copy it takes a fraction of the time the original encoding takes. This is hardly noticeable with a song, but you really appreciate it with a 7 hour audiobook. After re-encoding, the ID3 "Duration" tag now has the correct information.