在Linux上使用.net 6在c#中读取音频文件持续时间



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


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开发SDK之后):

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

  • 为您的目标平台安装了最新的LibVLC。无法加载共享库'libX11'或其依赖项之一。为了帮助诊断加载问题,可以考虑设置LD_DEBUG环境变量:libbx11:不能打开共享对象文件:LibVLCSharp.Shared.Core.Native.XInitThreads()中没有这样的文件或目录在LibVLCSharp.Shared.Core。InitializeDesktop(字符串libvlcDirectoryPath)在LibVLCSharp.Shared.Helpers.MarshalUtils。CreateWithOptions(String[] options, Func ' 3 create)

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

我建议您看一下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);

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

sudo apt install ffmpeg

要在windows中安装它,您需要下载构建文件,提取它,并将其添加到PATH。

接下来,安装Xabe。

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

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);
}
}
}

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

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

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

最新更新