【问题标题】:How to get an accurate duration of any audio file quickly?如何快速获得任何音频文件的准确持续时间?
【发布时间】:2020-03-12 18:50:42
【问题描述】:

有很多用 VBR 编码的音频文件没有准确的持续时间标签,命令行 FFMpeg 会输出以下内容:

根据比特率估计持续时间,这可能不准确

(确实如此)

使用libav,我们可以看到这是使用libavformat/utils.c中的has_duration()函数测试的

我有一个音频播放器,需要使用 libav 获取准确的持续时间信息。我已经尝试完全解码文件并计算解码的样本总数,这是通常的建议(并且是准确的),但是对于 60 分钟的音频文件,这可能需要 10 多秒,这是不可接受的。

我注意到有一些闭源音频解码器和音乐播放应用程序可以立即获得这些文件的准确持续时间。必须有一些便宜的方法来确定准确的持续时间吗?也许一个 sn-p 或高级描述会帮助我。

【问题讨论】:

  • “我已经尝试完全解码文件...”你能否通过对前几秒的采样和推断而不是整个文件来获得足够准确的估计?
  • 对于可变比特率 MP3 文件,扫描整个文件是唯一的方法。不一定需要解压整个文件,但需要读取每个 MP3 块头,应该比较快。
  • 否则,所有恒定比特率音频文件的标题中都有您需要的一切。我认为 libavformat 会支持这一点。
  • 我认为您应该能够使用 libavformat 而不是解码来仅执行“demux”(实际上并没有任何复用,但它仍然从流中解析数据包),在这种情况下应该是近乎即时。但我想知道你是否做错了什么使解码如此缓慢。我记得几十年前 mp3 解码超过 500 倍实时,所以现在应该快得多......
  • @R..GitHubSTOPHELPINGICE ffmpeg -i *.mp3 -f null - 在我的最新型号桌面上使用预构建的 ffmpeg 是 1550 倍,对于 60 分钟以上的曲目来说仍然需要几秒钟。在Android(我的目标)上它要慢得多。感谢解复用技巧,也许这就是解决方案

标签: c ffmpeg decode duration libav


【解决方案1】:

可以非常快速地“解复用”轨道并检查每个数据包的持续时间以确定轨道的总持续时间,无需解码。

只需在循环中添加持续时间,直到达到 EOF:

int read = av_read_frame(pFormatCtx, packet);
durationSeconds = packet->duration * (double) timebase;

【讨论】:

    猜你喜欢
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    • 2012-02-16
    • 2013-03-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    相关资源
    最近更新 更多