27

我曾经使用 ffmpeg 在服务器端计算 MP3 文件的持续时间 - 这似乎工作正常。今天我发现有些计算是错误的。不知何故,由于某种原因,ffmpeg 会错误计算持续时间,而且它似乎只发生在可变比特率 mp3 文件中。

在本地测试时,我注意到 ffmpeg 以绿色打印了两行额外的行。

使用的命令:

ffmpeg -i song_9747c077aef8.mp3

ffmpeg 说:

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

在一个不错的、温暖的谷歌会话之后,我发现了一些关于此的帖子,但没有找到解决方案。

然后我尝试增加最大持续时间:

ffmpeg -analyzeduration 999999999 -i song_9747c077aef8.mp3

在此之后,ffmpeg 只返回了第二行:

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

但无论哪种情况,计算出的持续时间都是完全错误的。将其与 VLC 进行比较,我注意到持续时间是正确的。

经过更多研究后,我偶然发现了 mp3info - 我安装并使用了它。

mp3info -p "%S" song_9747c077aef8.mp3

mp3info 然后返回了正确的持续时间,但只是作为一个整数,我不能使用它,因为我需要一个更准确的数字。用户blahdiblah在下面的评论中解释了其原因- mp3info 只是从文件中提取 ID3 信息而不实际执行任何计算。

我也尝试使用 mplayer 来检索持续时间,但就像 ffmpeg 一样,mplayer 返回错误的值。

4

7 回答 7

24

我终于找到了使用 sox 解决这个问题的正确方法——它返回了正确的信息。

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

长度(秒):219.062857

于 2012-05-13T12:20:44.123 回答
17

您可以完全解码文件以获得实际持续时间:

ffmpeg -i input.mp3 -f null -

控制台输出的倒数第二行将显示如下内容:

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

time实际持续时间在哪里。在这个例子中,整个过程大约需要 0.5 秒。

于 2015-10-14T01:50:12.213 回答
8

更简单的方法是使用 ffmpeg 从 ID3 标签中持续时间错误的文件中复制文件。这会导致它写入正确的信息。

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

因为它使用复制,所以它只需要原始编码时间的一小部分。这对于一首歌来说几乎是不明显的,但你真的很欣赏这本 7 小时的有声读物。重新编码后,ID3“持续时间”标签现在具有正确的信息。

于 2019-03-10T04:18:55.243 回答
5

来自 llogan (LordNeckbeard) 的扩展解决方案。要仅获取统计信息,您可以添加标志 -v quiet -stats

ffmpeg -v quiet -stats -i input.mp3 -f null - 
于 2018-12-06T09:30:31.280 回答
4

如果没有提供其他参数, ffmpeg将打印所有文件信息。

使用grepawk仅返回“持续时间”:

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

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

于 2019-12-09T22:52:05.397 回答
1
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
declare out="$(AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -vn -c:a copy - 2>&1 | tail -n 2 | head -n 1)"
if [[ "$out" =~ \ 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"
于 2019-08-30T19:42:00.653 回答
0
sudo apt install sox 
sudo apt-get install libsox-fmt-mp3

进而:

sox yourfile.mp3 -n stat
于 2020-03-24T09:07:02.130 回答