9

是的,这是这个问题的完全副本,但是作为答案给出并接受的链接对我不起作用。它返回不正确的值(2 分钟的 mp3 将被列为 1'30,3 分钟为 2'20),没有明显的模式。

所以又来了:如何使用 C# 获得 MP3 的长度?

或者

我对MP3Header 类做错了什么:

MP3Header mp3hdr = new MP3Header();
bool boolIsMP3 = mp3hdr.ReadMP3Information("1.mp3");
if(boolIsMP3)
  Response.Write(mp3hdr.intLength);
4

7 回答 7

12

显然,此类使用 fileSize / bitRate 计算持续时间。这仅适用于恒定比特率,我假设您的 MP3 具有可变比特率......

编辑:看看TagLib Sharp,它可以给你持续时间

于 2009-07-31T18:26:24.983 回答
4

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

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

于 2009-07-31T18:26:09.587 回答
3

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

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

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

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

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

于 2010-08-24T19:46:53.483 回答
0

线程中的第二个帖子可能会对您有所帮助:http ://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/c72033c2-c392-4e0e-9993-1f8991acb2fd

于 2009-07-31T18:30:29.280 回答
0

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

于 2009-07-31T18:42:33.953 回答
0

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

只有当您使用的 CPU 是您需要节省的宝贵资源时,您才会使用稍后的方法。否则,解码整个文件,您将获得持续时间。

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

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

于 2012-06-20T22:26:19.173 回答
0

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

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;
}
于 2013-03-09T19:41:24.017 回答