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

那年仲夏 提交于 2019-12-20 12:06:18

问题


I used to calculate the duration of MP3 files server-side using ffmpeg - which seemed to work fine. Today i discovered that some of the calculations were wrong. Somehow, for some reason, ffmpeg will miscalculate the duration and it seems to happen with variable bit rate mp3 files only.

When testing this locally, i noticed that ffmpeg printed two extra lines in green.

Command used:

ffmpeg -i song_9747c077aef8.mp3

ffmpeg says:

[mp3 @ 0x102052600] max_analyze_duration 5000000 reached at 5015510
[mp3 @ 0x102052600] Estimating duration from bitrate, this may be inaccurate

After a nice, warm google session, i discovered some posts on this, but no solution was found.

I then tried to increase the maximum duration:

ffmpeg -analyzeduration 999999999 -i song_9747c077aef8.mp3

After this, ffmpeg returned only the second line:

[mp3 @ 0x102052600] Estimating duration from bitrate, this may be inaccurate

But in either case, the calculated duration was just plain wrong. Comparing it to VLC i noticed that there the duration is correct.

After more research i stumbled over mp3info - which i installed and used.

mp3info -p "%S" song_9747c077aef8.mp3

mp3info then returned the CORRECT duration, but only as an integer, which i cannot use as i need a more accurate number here. The reason for this was explained in a comment below, by user blahdiblah - mp3info is simply pulling ID3 info from the file and not actually performing any calculations.

I also tried using mplayer to retrieve the duration, but just as ffmpeg, mplayer is returning the wrong value.


回答1:


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




回答2:


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.




回答3:


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

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



回答4:


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.




回答5:


AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i audio.mp3 -f null -vn -c:a copy - 2>&1 | tail -n 2
if [[ "$(AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2 | head -n 1)" =~ \ time=([0-9]+):([0-9]{2}):([0-9]{2})\.([0-9]+) ]]; then
  declare duration=0 us="${BASH_REMATCH[4]}" t
  for t in "${BASH_REMATCH[@]:1:3}"; do
    ((duration *= 60))
    ((duration += ${t#0} ))
  done
  while [ ${#us} -lt 6 ]; do us+=0; done
  ((us >= 500000)) && ((duration++))
  ((duration)) || ((duration++))
fi
echo -E Duration: "$duration"



回答6:


ffmpeg will print all file information if no other arguments are provided.

Use grep or awk to only return the "Duration":

ffmpeg -i file.mp3 2>&1 | grep Duration

ffmpeg -i file.mp3 2>&1 | awk '/Duration/ { print substr($2,0,length($2)-1) }'



来源:https://stackoverflow.com/questions/10437750/how-to-get-the-real-actual-duration-of-an-mp3-file-vbr-or-cbr-server-side

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!