【问题标题】:Read audio file duration in C# on Linux with .net 6使用 .net 6 在 Linux 上的 C# 中读取音频文件持续时间
【发布时间】:2023-01-30 10:40:07
【问题描述】:

我有一个最近从 .net5 更新到 .net6 的 asp.net 核心 API。 有一段代码应该读取音频文件的持续时间。似乎适用于以前版本的代码是这样的:


try
{
    //
    // NAudio -- Windows only
    //
    using var fileReader = new AudioFileReader(filePath);
    return Convert.ToInt32(Math.Ceiling(fileReader.TotalTime.TotalSeconds));
}
catch (DllNotFoundException)
{
    try
    {
        //
        // LibVLCSharp is crossplatform
        //
        using var libVLC = new LibVLC();
        using var media = new Media(libVLC, filePath, FromType.FromPath);
        MediaParsedStatus parsed = Task.Run(async () => await media.Parse(MediaParseOptions.ParseNetwork, timeout: 2000).ConfigureAwait(false)).Result;
        if (parsed != MediaParsedStatus.Done) throw new ArgumentException("Could not read audio file");
        if (!media.Tracks.Any(t => t.TrackType == TrackType.Audio) || (media.Duration <= 100)) throw new ArgumentException("Could not read audio from file");
        return Convert.ToInt32(Math.Ceiling(TimeSpan.FromMilliseconds(media.Duration).TotalSeconds));
    }
    catch (Exception ex) when (ex is DllNotFoundException || ex is LibVLCSharp.Shared.VLCException)
    {
        try
        {
            using var fileReader = new Mp3FileReader(filePath);
            return Convert.ToInt32(Math.Ceiling(fileReader.TotalTime.TotalSeconds));
        }
        catch (InvalidOperationException)
        {
            throw new ArgumentException("Could not read audio file");
        }
    }
}

该应用程序部署在 Linux 上,我不知道代码的哪一部分进行了准确的计算(我假设是 VLC 部分),但是自从更新到 .NET6 后,所有这些都失败了,并且自从上次回退是NAudio,我们得到以下异常:

无法加载共享库“Msacm32.dll”或其依赖项之一。

我正在使用 Windows,但我尝试使用 WSL 运行该应用程序,但我也无法运行 VLC 部分 - 它总是抛出以下异常(即使在安装 vlc 和 vlc dev SDK 之后):

无法创建 LibVLC。确保您已完成以下操作:

  • 为您的目标平台安装了来自 nuget 的最新 LibVLC。 无法加载共享库“libX11”或其依赖项之一。为了帮助诊断加载问题,请考虑设置 LD_DEBUG 环境变量:liblibX11: cannot open shared object file: No such file or directory at LibVLCSharp.Shared.Core.Native.XInitThreads() 在 LibVLCSharp.Shared.Core.InitializeDesktop(字符串 libvlcDirectoryPath) 在 LibVLCSharp.Shared.Helpers.MarshalUtils.CreateWithOptions(字符串 [] 选项,Func`3 创建)

有什么干净的方法可以在所有平台上读取音频文件的持续时间吗? 不用说,NAudio 在 Windows 上的工作就像一个魅力,VLC 也是如此(使用适当的 nuget 包)。

【问题讨论】:

    标签: c# windows-subsystem-for-linux naudio libvlcsharp


    【解决方案1】:

    如果你安装ffmpeg,你可以很容易地做到这一点。 ffmpeg 默认安装在大多数 Linux 发行版中,但如果没有,您可以使用您喜欢的包管理器安装它。

    sudo apt 安装 ffmpeg

    要在 Windows 中安装它,您需要 download the build files,将其解压缩并将其添加到 PATH。

    接下来,在您的项目中安装Xabe.FFMpeg包。

    最后,您可以调用静态方法Xabe.FFMpeg.FFMpeg.GetMediaInfo() 来获取有关您的音频文件的所有信息。这是我在我的 linux 机器上测试的示例 sn-p。

    using System;
    using System.IO;
    using Xabe.FFmpeg;
    namespace Program;
    public static class Program
    {
        public static void Main(string[] args)
        {
            string filename;
            if (args.Length == 0)
            {
                Console.WriteLine("No arguments found! Provide the audio file path as argument!");
                return;
            }
            else if (File.Exists(filename = args[0]) == false)
            {
                Console.WriteLine("Given file does not exist!");
                return;
            }
            try
            {
                var info = FFmpeg.GetMediaInfo(filename).Result;
                TimeSpan duration = info.Duration;
                Console.WriteLine($"Audio file duration is {duration}");
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您看到的错误是因为我们假设您将使用 X11 在 Linux 上显示视频,所以我们总是初始化 X11。见here。

      我们不应该为您的用例这样做(因为您可能没有可用的 GUI)。请在这里报告问题:https://code.videolan.org/videolan/LibVLCSharp/-/issues 或者更好的是,在 github 或 gitlab 上提交拉取请求。

      至于你的问题,为什么它在 .net 5 上工作,而不是在 .net 5 上工作,我不确定我们是否有足够的信息来说明原因,因为你没有从那台机器向我们发送错误消息。

      【讨论】:

      • 有道理,我会报告这个问题,谢谢。更新到 .net6 后,我从该机器收到的错误消息是:无法加载共享库“Msacm32.dll”或其依赖项之一。
      • 这发生在最后一个回退中,来自 NAudio。我的假设是 VLC 从未在 Linux 上运行,最后一个回退可能已经运行,因为在旧版本中它不需要 Msacm32.dll,但我仍然需要验证这一点
      【解决方案3】:

      我鼓励你看看atldotnet。它是一个小型、维护良好的完全托管代码/跨平台库,没有任何外部依赖性,并且在我的所有测试用例中都能准确检测音频文件持续时间(比ffmpeg 更准确)。支持最常见的音频格式。

          var t = new Track(audioFilePath);    
          // Works the same way on any supported format (MP3, FLAC, WMA, SPC...)
          System.Console.WriteLine("Duration (ms) : " + t.DurationMs);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-13
        • 2013-03-01
        • 2016-04-23
        • 1970-01-01
        • 2021-07-18
        • 2014-02-08
        • 2010-11-17
        • 2020-06-02
        相关资源
        最近更新 更多