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.