我已经构建了一个 WPF 应用程序,用户可以在其中将 MP3 文件拖放到列表框上。我需要一种方法来计算播放列表的总持续时间。
我应该使用任何库吗?或者是否可以仅使用 .NET 框架?
经过大量的理论研究,我找到了一种正确且无可争议地计算 mp3 文件持续时间的方法。
让我首先重申一下为什么上面的标准方法不起作用:
ID3 方法:并非所有文件都有 id3 标签,如果有,则可能没有在其中设置持续时间字段。
通过读取一帧 * 文件大小进行估计:不适用于 VBR 文件。
Xing 标头:并非所有文件都有它。
通过 PCM 大小解码和确定它:我有 3+ GB 的文件,我不会等到它解码。
我到处阅读,所有事情都导致了 NAudio。马克,感谢您的努力和干净的来源!然而,NAudio 最常用的一种方法是使用 Mp3FileReader 读取文件并获取所有帧。问题:Mp3FileReader 在开始时创建一个 TOC,这需要很长时间,即使对于只有一天的小文件也是如此 :)
Mark 建议我删除 TOC 创建,因为源可用,并且在执行此操作时,我发现了更简单的方法。这里是; 不言自明:
double GetMediaDuration(string MediaFilename)
{
double duration = 0.0;
using (FileStream fs = File.OpenRead(MediaFilename))
{
Mp3Frame frame = Mp3Frame.LoadFromStream(fs);
if (frame != null)
{
_sampleFrequency = (uint)frame.SampleRate;
}
while (frame != null)
{
if (frame.ChannelMode == ChannelMode.Mono)
{
duration += (double)frame.SampleCount * 2.0 / (double)frame.SampleRate;
}
else
{
duration += (double)frame.SampleCount * 4.0 / (double)frame.SampleRate;
}
frame = Mp3Frame.LoadFromStream(fs);
}
}
return duration;
}
我包装了 mp3 解码器库,并将其提供给 .net 开发人员。你可以在这里找到它:
http://sourceforge.net/projects/mpg123net/
包括将 mp3 文件转换为 PCM 和读取 ID3 标签的示例。
我猜它可以用来正确计算 mp3 文件的持续时间。
几年前,我最终为此编写了自己的文章。您可以使用闪存编写一个有效的客户端。我记得的关键点是:
编辑:我意识到你想用 .Net 来做这件事,但在你将文件上传到服务器之前了解客户端实际上可能更有用,就像你想对文件长度施加限制一样,你可以更早地做到这一点进行中。
[我自己的解决方案]
我添加了第二个 mediaelement 控件,用于打开列表框中的每个 mp3 文件并获取它的 NaturalDuration。打开和关闭列表中的每个文件并对所有值求和。
正如其他人所说,mp3 标题不准确。mediaelement 提供正确的持续时间。
这可能不是最快的方法,但在我的情况下是最简单的(它不依赖于其他库)。