如何在C#/ .NET / DirectX中检索mp3音频文件的正确持续时间?

时间:2012-06-20 19:48:59

标签: c# .net directx mp3

我正在写一个媒体演示程序,我几乎完成了,但由于某种原因,我得到的mp3文件持续时间不正确。我使用Microsoft.DirectX.AudioVideoPlayback.Audio类来播放音频文件,它适用于wav文件。从谷歌搜索,我可以看出,当使用可变比特率编码mp3时似乎是一个问题,但是我需要我的程序准确报告,无论媒体的比特率设置如何。这是代码:

Media_Audio aud = (Media_Audio)item.MediaFile;
TimeSpan total = aud.EndTime - aud.StartTime;
if (aud.EndTime.TotalSeconds == 0)
{
    total = TimeSpan.FromSeconds(aud.Player.Duration)-aud.StartTime;
}
TimeSpan now = TimeSpan.FromSeconds(aud.Player.CurrentPosition) - aud.StartTime;
string nows = now.Hours.ToString() + ":" + now.Minutes.ToString() + ":" + now.Seconds.ToString();
string tots = total.Hours.ToString() + ":" + total.Minutes.ToString() + ":" + total.Seconds.ToString();
item.currentPosition.Text = nows + "/" + tots;

关键是:

total = TimeSpan.FromSeconds(aud.Player.Duration)-aud.StartTime;

aud.Player是Microsoft.DirectX.AudioVideoPlayback.Audio的一个实例。

对于一首实际上长5:49秒的歌曲,它会报告39:13作为持续时间。与Windows资源管理器和VLC播放器的长度相同。另外,安装了K-Lite Mega Codec包。所以它可能会干扰。我知道这个问题:How to retrieve duration of MP3 in .NET? 但是,在我的程序的这个阶段,我没有时间从我当前的播放音频文件的方法切换到新的方法,所以我还有其他选项来确定仅使用DirectX的持续时间吗?或者我是否必须求助于BASS.NET或TagLib Sharp? (元数据甚至包含VBR编码的mp3的准确信息吗?)

2 个答案:

答案 0 :(得分:3)

我想发布它作为对@anantoline的评论,但它太长了......他是对的!

VBR文件的长度CAN'可以估计。其中的每个mp3帧都可能具有不同的比特率,因此通过读取文件的任何部分,您无法知道文件的任何其他部分的数据密度。确定VBR mp3的EXACT长度的唯一方法是整体解码它,或者(如果你知道的话)逐个读取帧的所有标题,并收集它们的解码DURATION。

只有当您使用的CPU是您需要保存的宝贵资源时,才会使用以后的方法。否则,解码整个文件,你就有了持续时间。

您可以使用我的mpg123端口来完成这项工作:http://sourceforge.net/projects/mpg123net/

更多:很多mp3文件都有"东西"添加到它,作为id3标记,如果你没有浏览所有文件,你可能会错误地在持续时间计算中使用该标记。

答案 1 :(得分:1)

AFAIK无法在不运行整个文件的情况下确定VBR编码的MP3文件的正确长度(即使未呈现也会发生某种解码/播放)。

您可以尝试读取ID3标签以获取长度(由最初编码轨道的应用程序写入/解码轨道一次。但是,提供的MP3文件可能没有ID3标签或更糟糕 - ID3标签中的值不正确。