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

发布于 2024-07-29 05:32:49 字数 545 浏览 3 评论 0原文

是的,这是这个问题的精确重复,但给出的链接并被接受为答案不适合我。 它返回不正确的值(2 分钟的 mp3 将被列为 1'30,3 分钟为 2'20),没有明显的模式。

那么问题又来了:如何使用 C# 获取 MP3 的长度?

我对MP3Header类<做错了什么/a>:

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

Yes this is an exact duplicate of this question, but the link given and accepted as answer is not working for me. It is returning incorrect values (a 2 minutes mp3 will be listed as 1'30, 3 minutes as 2'20) with no obvious pattern.

So here it is again: how can I get the length of a MP3 using C# ?

or

What am I doing wrong with the MP3Header class:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

木格 2024-08-05 05:32:49

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

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

Apparently this class computes the duration using fileSize / bitRate. This can only work for constant bitrate, and I assume your MP3 has variable bitRate...

EDIT : have a look at TagLib Sharp, it can give you the duration

若能看破又如何 2024-08-05 05:32:49

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

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

How have you ascertained the lengths of the MP3s which are "wrong"? I've often found that the header information can be wrong: there was a particular version of LAME which had this problem, for example.

If you bring the file's properties up in Windows Explorer, what does that show?

瞳孔里扚悲伤 2024-08-05 05:32:49

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

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

您可以 将 mp3 文件转换为 PCM 并读取 ID3 标签的示例。

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

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

I wrapped mp3 decoder library and made it available for .net developers. You can find it here:

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

Included are the samples to convert mp3 file to PCM, and read ID3 tags.

I guess that you can use it to read mp3 file duration. Worst case will be that you read all the frames and compute the duration - VBR file.

To accurately determine mp3 duration, you HAVE TO read all the frames and calculate duration from their summed duration. There are lots of cases when people put various 'metadata' inside mp3 files, so if you estimate from bitrate and file size, you'll guess wrong.

长发绾君心 2024-08-05 05:32:49

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

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

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

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

Length of the VBR file CAN'T be estimated at all. Every mp3 frame inside of it could have different bitrate, so from reading any part of the file you can't know what density of the data is at any other part of the file. Only way of determining EXACT length of VBR mp3 is to DECODE it in whole, OR (if you know how) read all the headers of the frames one by one, and collect their decoded DURATION.

You will use later method only if the CPU that you use is a precious resource that you need to save. Otherwise, decode the whole file and you'll have the duration.

You can use my port of mpg123 to do the job: http://sourceforge.net/projects/mpg123net/

More: many mp3 files have "stuff" added to it, as a id3 tags, and if you don't go through all the file you could mistakenly use that tag in duration calculation.

难如初 2024-08-05 05:32:49

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

I would consider using an external application to do this. Consider trying Sox and just run the version of the program that's executed by using soxi (no exe) and try parsing that output. Given your options I think you're better off just trusting someone else who has spent the time to work out all the weirdness in mp3 files unless this functionality is core to what you're doing. Good luck!

孤云独去闲 2024-08-05 05:32:49

我有一个带有 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;
}

There is my solution for C# with sox sound processing library.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文