MP3/wav 音频文件的持续时间

Posted

技术标签:

【中文标题】MP3/wav 音频文件的持续时间【英文标题】:Duration of an MP3/wav audio file 【发布时间】:2009-06-30 18:00:48 【问题描述】:

如何在 Delphi 中获取 (以分钟和秒为单位)?

【问题讨论】:

您使用什么 API 来播放 MP3 文件? TMediaPlayer? 不,我不是在播放文件,我只需要文件中的信息。 【参考方案1】:

您可以通过将文件大小除以比特率来计算持续时间。您可以从其中一个帧头中获取比特率。当然,这不适用于可变速率 MP3,因为您可以为每帧设置不同的速率。

使用Header Layout(只有四个字节):

    在流中打开 MP3

    通过读取找到第一个帧头的开头,直到您 找到同步头,它有 11 个连续的位设置为 1。这 以前是 12,但经过调整以支持 MPEG 版本 2.5。

    确定 MPEG 版本 ID。为了找到比特率,V2.5 与 V2 相同

    确定层描述

    读取比特率指数

    使用 MPEG 版本、层描述和比特率索引,从链接头参考中的比特率索引表中确定实际比特率

    以千比特为单位的文件大小((8 * 以字节为单位的大小)/1000)除以比特率得到持续时间(以秒为单位)

我找不到 Delphi 示例,但这里有一个 C# implementation 使用此技术作为参​​考。请参阅 getLengthInSeconds 方法。

【讨论】:

+1,计算长度(以秒为单位)的代码与我找到的相同。 Downvoted:仅链接的答案,其中链接的文章自撰写后就消失了。 @Jules:我很欣赏投反对票的理由,这是有效的。我修复了链接并添加了所需步骤的摘要以及指向标题参考的链接。【参考方案2】:

Mp3 are divided into frames like this

你需要计算帧数

【讨论】:

并不是说那么简单。 mp3文件在帧开始之前有很多信息...【参考方案3】:

我建议你使用 BASS

http://www.un4seen.com/bass.html

BASS 是一个音频库.. 为开发者提供强大的流(MP3..OGG..)功能。所有这些都在一个很小的 ​​DLL 中,大小不到 100KB。

非常好用

   uses BASS;

   var
      playingChannel: HSTREAM;
      playingLength: Double;
      mp3filename: String;

    begin
      BASS_Init(-1,44100,0,Application.Handle,nil);
      playingChannel:=BASS_StreamCreateFile(FALSE,pchar(mp3filename),0,0,0);
      playingLength:=BASS_ChannelBytes2Seconds(playingChannel,
        BASS_ChannelGetLength(playingChannel,BASS_POS_BYTE));
    end;

【讨论】:

虽然不是免费的,是吗? 它是,用于非商业用途。请参阅 www.un4seen.com 上的“许可”【参考方案4】:

不确定这是否可行,但我找到了forum post。我会将结果与 winamp 之类的东西进行比较,以确保它有效。

【讨论】:

CBR(恒定比特率)准确,VBR(可变比特率)可能不准确。如果只需要大概的时间,这是个好主意 虽然这个方法假设你知道比特率! @Charlie Salts - 你是对的,该公式在 VBR 情况下不起作用,并且论坛帖子没有说明如何确定比特率。 Bruce McGee 的答案更完整,我会推荐一个而不是我的。【参考方案5】:

在 windows 下有一种相当有效的方法来确定 MP3 文件的长度。

这是一个巨大的 hack,但它似乎有效。

瑞恩。

//add MPlayer to the uses clause;
//
//add the MP3PlayLength function to an existing form and 
//place a button on the form, linking the button click method to see how it works.

uses MPlayer;

function TForm1.MP3PlayLength(aMP3FileName:string):string;
var
  wMP : TMediaPlayer;
  wLen : Cardinal;
begin
  Try
     wMP := TMediaPlayer.Create(self);
     try
        wMP.Visible := false;
        wMP.parent := self;
        wMP.FileName := aMP3FileName;
        wMP.TimeFormat := tfMilliseconds;
        wMP.DeviceType := dtAutoSelect;
        wMP.Open;
        try
           wLen := trunc(wMP.Length / 1000);
           result := inttostr(wLen div 60)+':'+inttostr(wLen mod 60);
        finally
           wMP.Close;
        end;
     finally
        wMP.free;
     end;
  except
     result := '(err)';
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   if OpenDialog1.Execute then
      showmessage(MP3PlayLength(OpenDialog1.FileName));
end;

【讨论】:

【参考方案6】:

或者,试试 MediaInfo.dll link text。

它包含一个 Delphi 包装类。 例如:

MediaInfo_Get(Handle, Stream_General, 0, 'Duration', Info_Text, Info_Name)

其他解决方案 DSPack link text

size := FilterGraph.Duration;

【讨论】:

【参考方案7】:

访问 www.un4seen.com 并下载低音库,您将从论坛部分获得大量信息。 ;)

【讨论】:

【参考方案8】:

查看此博客,在 ruby​​ 项目中使用 ffmpeg 作为后台解决方法。

http://blog.ncodedev.com

【讨论】:

【参考方案9】:

我已经很久没有和 Dephi 一起玩了。

试试,

FileSize(var aFile)

【讨论】:

这将以字节为单位给出大小,而不是分钟和秒。 @Charlie Salts - 这是在 OP 解释他们想要分钟/秒之前发布的。我会让 Secko 休息一下。此外,FileSize() 可能会有所帮助,并在我和 Bruce 发布的公式中使用。 问题是“如何在 Delphi 中获取 MP3/wav 音频文件的长度?”。 我会假设海报意味着时间长度。如果他们要求 any 文件的长度,我会假设文件大小。获取任何文件的文件大小通常是微不足道的,有时获取 MP3 的长度并非易事,因此问题。 我同意,但我的大脑不知何故只是给我发了一张 FileSize 函数的图片。

以上是关于MP3/wav 音频文件的持续时间的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 python 脚本停止/关闭音频文件(mp3/.wav)

在 iOS 中,如何从数据中创建音频文件(.wav、.mp3)文件?

Python播放mp3/wav文件音频(Pygame混音器)

exp-linux用aplay直接播放音频文件(mp3,wav)

Unity运行时加载外部mp3/wav音频

FFMPEG 音频转换命令