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

3

我正在编写一个媒体演示程序,几乎完成了,但是我发现无法正确获取mp3文件的持续时间。我使用Microsoft.DirectX.AudioVideoPlayback.Audio类播放音频文件,对于wav文件效果很好。通过Google搜索,我发现当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;
是Microsoft.DirectX.AudioVideoPlayback.Audio的实例。 对于一首实际时长为5:49秒的歌曲,它报告的持续时间为39:13。这与Windows Explorer和VLC Player的长度相同。同时,已安装了K-Lite Mega Codec包,因此可能会产生干扰。我知道这个问题:如何在.NET中检索MP3的持续时间? 但是,目前在我的程序中,我没有时间切换到播放音频文件的新方法,那么我有没有其他选择使用仅DirectX来确定持续时间?或者我是否必须诉诸于BASS.NET或TagLib Sharp?(元数据是否包含VBR编码mp3的精确信息?)

还有一个:https://dev59.com/2UjSa4cB1Zd3GeqPHrEB - kol
这是一种重复的问题;我在这里尝试回答了:https://dev59.com/N0bRa4cB1Zd3GeqPww4u#13269914 - Daniel Mošmondor
2个回答

3

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

VBR文件的长度根本无法估计。它内部的每个mp3帧都可能具有不同的比特率,因此无法通过阅读文件的任何部分来确定文件的其他部分的数据密度。确定VBR mp3的确切长度的唯一方法是完全解码它,或者(如果您知道如何)逐个读取所有帧的头,并收集它们的解码持续时间。

只有在使用的CPU是需要保存的珍贵资源时,才会使用后一种方法。否则,请解码整个文件,您就可以得到持续时间。

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

更多信息:许多mp3文件添加了“杂项”,例如id3标签,如果您不查看整个文件,则可能会错误地在持续时间计算中使用该标签。


感谢Daniel和@anantholine。CPU很珍贵,因为用户可能会同时播放几个高清视频文件,而在加载此音频文件时,我将尝试使用您的mpg123项目,看看是否可以在我的环境中使其正常工作,感谢你们的帮助! - John Davis

1
据我所知,不可能在不运行整个文件的情况下确定可变比特率编码的MP3文件的正确长度(即使没有呈现,也必须进行某种解码/播放)。
您可以尝试读取ID3标签以获取长度(由最初编码曲目/解码曲目的应用程序写入)。但是,提供的MP3文件可能没有ID3标签,或者更糟糕的是,ID3标签中的值错误。

你的信息来源是什么?长度可以非常准确地估计。 - Alex Gordon
@Артём Царионов,不读/解码整个文件,你能做到吗?我想看一下文章或来源的链接,请。 - Ani
1
PHP5类(在PHP4中无法使用)用于检测常规MP3文件(非VBR文件)的比特率和持续时间。 - Daniel Mošmondor

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