diff --git a/src/LibVLCSharp/Shared/Core/Constants.cs b/src/LibVLCSharp/Shared/Core/Constants.cs index e36b8e45..a80cb875 100644 --- a/src/LibVLCSharp/Shared/Core/Constants.cs +++ b/src/LibVLCSharp/Shared/Core/Constants.cs @@ -35,6 +35,7 @@ internal static class ArchitectureNames internal const string Win64 = "win-x64"; internal const string Win86 = "win-x86"; internal const string MacOS64 = "osx-x64"; + internal const string MacOSArm64 = "osx-arm64"; } [Flags] diff --git a/src/LibVLCSharp/Shared/Core/Core.cs b/src/LibVLCSharp/Shared/Core/Core.cs index 2afe6598..bb5fbeb7 100644 --- a/src/LibVLCSharp/Shared/Core/Core.cs +++ b/src/LibVLCSharp/Shared/Core/Core.cs @@ -73,12 +73,15 @@ static internal bool LibVLCLoaded var paths = new List<(string, string)>(); string arch; +#if !NET40 && !NETSTANDARD1_1 if (PlatformHelper.IsMac) { - arch = Path.Combine(ArchitectureNames.MacOS64, Constants.Lib); + arch = RuntimeInformation.ProcessArchitecture switch + { + Architecture.Arm64 => ArchitectureNames.MacOSArm64, + _ => ArchitectureNames.MacOS64, + }; } - -#if !NET40 && !NETSTANDARD1_1 else if (PlatformHelper.IsWindows) { arch = RuntimeInformation.ProcessArchitecture switch @@ -89,9 +92,8 @@ static internal bool LibVLCLoaded _ => PlatformHelper.IsX64BitProcess ? ArchitectureNames.Win64 : ArchitectureNames.Win86 }; } -#endif - else +#endif { arch = PlatformHelper.IsX64BitProcess ? ArchitectureNames.Win64 : ArchitectureNames.Win86; } @@ -138,11 +140,14 @@ static internal bool LibVLCLoaded paths.Add((string.Empty, libvlcPath3)); - // Add Win64 folders as fallback for WinArm64 to keep compatibility - if (arch == ArchitectureNames.WinArm64) + // Add x64 folders as fallback for ARM64 to keep compatibility + if (arch == ArchitectureNames.WinArm64 || arch == ArchitectureNames.MacOSArm64) { + var fallbackArchitecture = arch == ArchitectureNames.WinArm64 + ? ArchitectureNames.Win64 : ArchitectureNames.MacOS64; + var fallbackLibvlcDirPath1 = Path.Combine(Path.GetDirectoryName(libvlcAssemblyLocation)!, - Constants.LibrariesRepositoryFolderName, ArchitectureNames.Win64); + Constants.LibrariesRepositoryFolderName, fallbackArchitecture); var fallbackLibvlccorePath1 = LibVLCCorePath(fallbackLibvlcDirPath1); var fallbackLibvlcPath1 = LibVLCPath(fallbackLibvlcDirPath1); @@ -151,7 +156,7 @@ static internal bool LibVLCLoaded if (!string.IsNullOrEmpty(assemblyLocation)) { var fallbackLibvlcDirPath2 = Path.Combine(Path.GetDirectoryName(assemblyLocation)!, - Constants.LibrariesRepositoryFolderName, ArchitectureNames.Win64); + Constants.LibrariesRepositoryFolderName, fallbackArchitecture); var fallbackLibvlccorePath2 = LibVLCCorePath(fallbackLibvlcDirPath2); var fallbackLibvlcPath2 = LibVLCPath(fallbackLibvlcDirPath2); @@ -161,9 +166,8 @@ static internal bool LibVLCLoaded if (PlatformHelper.IsMac) { - var libvlcPath4 = Path.Combine(Path.Combine(Path.GetDirectoryName(libvlcAssemblyLocation)!, - Constants.Lib), $"{Constants.LibVLC}{LibraryExtension}"); - var libvlccorePath4 = LibVLCCorePath(Path.Combine(Path.GetDirectoryName(libvlcAssemblyLocation)!, Constants.Lib)); + var libvlcPath4 = Path.Combine(Path.GetDirectoryName(libvlcAssemblyLocation)!, $"{Constants.LibVLC}{LibraryExtension}"); + var libvlccorePath4 = LibVLCCorePath(Path.GetDirectoryName(libvlcAssemblyLocation)!); paths.Add((libvlccorePath4, libvlcPath4)); } @@ -188,6 +192,19 @@ static void LoadLibVLC(string? libvlcDirectoryPath = null) loadResult = LoadNativeLibrary(libvlcPath, out LibvlcHandle); if (!loadResult) Log($"Failed to load required native libraries at {libvlcPath}"); + +#if NET5_0_OR_GREATER + // register custom resolver to load library from provided path + NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), (dll, _, _) => + { + return dll switch + { + Constants.LibraryName => NativeLibrary.Load(libvlcPath), + Constants.CoreLibraryName => NativeLibrary.Load(libvlccorePath), + _ => IntPtr.Zero + }; + }); +#endif return; } @@ -197,8 +214,21 @@ static void LoadLibVLC(string? libvlcDirectoryPath = null) { LoadNativeLibrary(libvlccore, out LibvlccoreHandle); var loadResult = LoadNativeLibrary(libvlc, out LibvlcHandle); - if (loadResult) - break; + if (!loadResult) continue; + +#if NET5_0_OR_GREATER + // register custom resolver to load library from discovered path + NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), (dll, _, _) => + { + return dll switch + { + Constants.LibraryName => NativeLibrary.Load(libvlc), + Constants.CoreLibraryName => NativeLibrary.Load(libvlccore), + _ => IntPtr.Zero + }; + }); +#endif + break; } if (!LibVLCLoaded)