如何在C#中获取MP3的长度

时间:2009-07-31 18:13:48

标签: c# .net mp3

是的,这与this question完全相同,但给出并接受的链接对我来说不起作用。它返回的值不正确(2分钟mp3将被列为1'30,3分钟为2'20),没有明显的模式。

所以这又是:我如何使用C#获取MP3的长度?

我对MP3Header class

做错了什么
MP3Header mp3hdr = new MP3Header();
bool boolIsMP3 = mp3hdr.ReadMP3Information("1.mp3");
if(boolIsMP3)
  Response.Write(mp3hdr.intLength);

7 个答案:

答案 0 :(得分:10)

显然这个类使用fileSize / bitRate计算持续时间。这只能用于恒定的比特率,我认为你的MP3有可变的bitRate ...

编辑:查看TagLib Sharp,它可以为您提供持续时间

答案 1 :(得分:4)

你如何确定“错误”的MP3的长度?我经常发现标题信息可能是错误的:例如,有一个特定版本的LAME存在这个问题。

如果您在Windows资源管理器中显示文件的属性,那会显示什么?

答案 2 :(得分:3)

我包装了mp3解码器库并使其可供.net开发人员使用。你可以在这里找到它:

http://sourceforge.net/projects/mpg123net/

包括将mp3文件转换为PCM并读取ID3标签的示例。

我猜你可以用它来读取mp3文件的持续时间。最糟糕的情况是你读取所有帧并计算持续时间--VBR文件。

要准确确定mp3持续时间,您必须读取所有帧并从其总计持续时间计算持续时间。有很多情况下人们将各种“元数据”放在mp3文件中,所以如果你根据比特率和文件大小估算,你会猜错了。

答案 3 :(得分:0)

答案 4 :(得分:0)

我会考虑使用外部应用程序来执行此操作。考虑尝试Sox并运行使用soxi(无exe)执行的程序版本并尝试解析该输出。考虑到你的选择,我认为你最好只相信那些花时间解决mp3文件中所有奇怪问题的人,除非这个功能是你正在做的事情的核心。祝你好运!

答案 5 :(得分:0)

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

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

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

更多:许多mp3文件添加了“stuff”,作为id3标签,如果你没有浏览所有文件,你可能会错误地在持续时间计算中使用该标签。

答案 6 :(得分:0)

我的C#解决方案带有sox声音处理库。

public static double GetAudioDuration(string soxPath, string audioPath)
{
    double duration = 0;
    var startInfo = new ProcessStartInfo(soxPath,
        string.Format("\"{0}\" -n stat", audioPath));
    startInfo.UseShellExecute = false;
    startInfo.CreateNoWindow = true;
    startInfo.RedirectStandardError = true;
    startInfo.RedirectStandardOutput = true;
    var process = Process.Start(startInfo);
    process.WaitForExit();

    string str;
    using (var outputThread = process.StandardError)
        str = outputThread.ReadToEnd();

    if (string.IsNullOrEmpty(str))
        using (var outputThread = process.StandardOutput)
            str = outputThread.ReadToEnd();

    try
    {
        string[] lines = str.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
        string lengthLine = lines.First(line => line.Contains("Length (seconds)"));
        duration = double.Parse(lengthLine.Split(':')[1]);
    }
    catch (Exception ex)
    {
    }

    return duration;
}