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

5
在Delphi中如何获取MP3/wav音频文件的持续时间(以分钟和秒为单位)?

你使用什么API来播放MP3文件?TMediaPlayer吗? - J. Polfer
不,我不是在播放文件,我只需要从文件中获取信息。 - Attilah
9个回答

7
您可以通过将文件大小除以比特率来计算持续时间。您可以从一个帧头中获取比特率。当然,对于可变速率的MP3文件,每个帧可以有不同的速率,因此这种方法无法使用。
使用Header Layout(仅为四个字节):
  1. 在流中打开MP3文件

  2. 读取直到找到同步头为止,同步头有11位连续的1。 这曾经是12位,但它已被调整以支持MPEG版本2.5。

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

  4. 确定层描述

  5. 读取比特率索引

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

  7. 将文件大小(以字节为单位)转换成千位((8 * size in bytes)/ 1000),再除以比特率,以秒为单位得到持续时间

我找不到Delphi示例,但是这里有一个C#实现,供参考。请查看getLengthInSeconds方法。

+1,计算秒数长度的代码与我找到的完全相同。 - J. Polfer
被踩:仅包含链接的回答,链接指向的文章已经消失。 - Jules
@Jules:感谢您提供了一个有效的负评理由。我已经修复了链接,并添加了所需步骤的摘要以及标题参考的链接。 - Bruce McGee

4

我建议你使用BASS

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

BASS是一个音频库,旨在为开发者提供强大的流媒体(MP3、OGG等)功能。它只有不到100KB大小的微小DLL,非常容易使用。
   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;

虽然不是免费的,对吧? - Vassilis
1
它是供非商业使用的。请查看www.un4seen.com上的“许可证”。 - PA.

3

并不是简单地说。在帧开始之前,mp3文件有很多信息... - The Student

2
在Windows下,有一种相对有效的方式来确定MP3文件的长度。
这是一个巨大的黑客技术,但它似乎是有效的。
Ryan。
//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;

2

或者,尝试使用MediaInfo.dll 链接文本

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

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

其他解决方案 DSPack 链接文本

size := FilterGraph.Duration;

2

我不确定这会起作用,但我找到了这个论坛帖子。为确保其可行性,建议与类似winamp的软件进行比较。


1
对于CBR(恒定比特率)准确,对于VBR(可变比特率)可能不准确。在只需要大致时间的情况下,这是一个好主意。 - Charlie Salts
1
虽然这种方法假定您知道比特率! - Charlie Salts
@Charlie Salts - 你说得对,这个公式在VBR情况下不适用,并且论坛帖子没有说明如何确定比特率。Bruce McGee的回答更完整,我建议选择他的回答而不是我的。 - J. Polfer

1

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


0

-1

我已经很久没有玩Delphi了。

试试看,

FileSize(var aFile)

这将给出以字节为单位的大小,而不是分钟和秒。 - Charlie Salts
1
@Charlie Salts - 在 OP 解释他们想要分钟/秒之前发布了这篇文章。我会给 Secko 一个休息。另外,FileSize() 可能会有帮助,并且可以在 Bruce 和我发布的公式中使用。 - J. Polfer
问题是:“如何在Delphi中获取MP3 / wav音频文件的长度?” - Secko
我本以为发帖者指的是时间长度。如果他们要求任何文件的长度,我会认为是文件大小。获取任何文件的大小通常很简单,但有时候获取MP3的长度并不容易,所以才会有这个问题。 - Charlie Salts
2
我同意,但我的大脑不知怎么就给我发了一个FileSize函数的图片。 - Secko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接