如何获取MP3文件(VBR或CBR)服务器端的实际持续时间

Squ*_*Cat 22 mp3 duration ffmpeg

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

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

使用的命令:

ffmpeg -i song_9747c077aef8.mp3
Run Code Online (Sandbox Code Playgroud)

ffmpeg说:

[mp3 @ 0x102052600] max_analyze_duration 5000000 reached at 5015510
[mp3 @ 0x102052600] Estimating duration from bitrate, this may be inaccurate
Run Code Online (Sandbox Code Playgroud)

在一个不错的,温暖的谷歌会议之后,我发现了一些帖子,但没有找到解决方案.

然后我试着增加最长持续时间:

ffmpeg -analyzeduration 999999999 -i song_9747c077aef8.mp3
Run Code Online (Sandbox Code Playgroud)

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

[mp3 @ 0x102052600] Estimating duration from bitrate, this may be inaccurate
Run Code Online (Sandbox Code Playgroud)

但在任何一种情况下,计算的持续时间都是完全错误的.将其与VLC进行比较我注意到持续时间是正确的.

经过更多的研究,我偶然发现了mp3info - 我安装和使用了它.

mp3info -p "%S" song_9747c077aef8.mp3
Run Code Online (Sandbox Code Playgroud)

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

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

Squ*_*Cat 21

我终于使用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
Run Code Online (Sandbox Code Playgroud)

长度(秒):219.062857

  • 它默认输出`sox FAIL 格式:没有文件扩展名 mp3 的处理程序`。我应该如何安装它? (5认同)
  • @shukshin.ivan:如果您还需要支持其他格式,则需要安装“libsox-fmt-mp3”或“libsox-fmt-all”。 (2认同)

llo*_*gan 10

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

ffmpeg -i input.mp3 -f null -
Run Code Online (Sandbox Code Playgroud)

控制台输出的第二行到最后一行将显示如下内容:

size=N/A time=00:03:49.12 bitrate=N/A
Run Code Online (Sandbox Code Playgroud)

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


mir*_*iam 6

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

ffmpeg -i "audio.mp3" -acodec copy "audio_fixed.mp3"
Run Code Online (Sandbox Code Playgroud)

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


JSO*_*C11 6

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

使用grep或awk仅返回“持续时间”:

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

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

  • ffmpeg 输出不适合机器解析。[使用 ffprobe 代替](/sf/answers/1557068411/)。一个例外是,如果您想[使用 ffmpeg 完全解码文件以获取持续时间](/sf/answers/2318072151/),但您的示例没有这样做。 (2认同)

Mit*_*boc 5

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

ffmpeg -v quiet -stats -i input.mp3 -f null - 
Run Code Online (Sandbox Code Playgroud)