From df8d97ebbbb7f3617ce4bc9850ec408449ead186 Mon Sep 17 00:00:00 2001 From: Kerry Cao Date: Wed, 6 Sep 2023 13:19:02 -0600 Subject: [PATCH] allow os and architecture overrider --- FFMpegCore/Helpers/FFMpegDownloader.cs | 102 +++++++++++++++++-------- 1 file changed, 69 insertions(+), 33 deletions(-) diff --git a/FFMpegCore/Helpers/FFMpegDownloader.cs b/FFMpegCore/Helpers/FFMpegDownloader.cs index c07a30e..f465f1b 100644 --- a/FFMpegCore/Helpers/FFMpegDownloader.cs +++ b/FFMpegCore/Helpers/FFMpegDownloader.cs @@ -14,19 +14,8 @@ public class FFMpegDownloader [Flags] public enum FFMpegBinaries : ushort { - /// - /// FFMpeg binary - /// FFMpeg, - - /// - /// FFProbe binary - /// FFProbe, - - /// - /// FFPlay binary - /// FFPlay } @@ -43,17 +32,32 @@ public enum FFMpegVersions : ushort V3_2 } + public enum PlatformOverride : short + { + Windows64, + Windows32, + Linux64, + Linux32, + LinuxArmhf, + LinuxArmel, + LinuxArm64, + Osx64 + } + /// /// Download the latest FFMpeg suite binaries for current platform /// /// used to explicitly state the version of binary you want to download - /// used to explicitly state the binary you want to download + /// used to explicitly state the binaries you want to download (ffmpeg, ffprobe, ffplay) + /// used to explicitly state the os and architecture you want to download /// a list of the binaries that have been successfully downloaded - public static async Task> DownloadFFMpegSuite(FFMpegVersions version = FFMpegVersions.Latest, - FFMpegBinaries binaries = FFMpegBinaries.FFMpeg | FFMpegBinaries.FFProbe) + public static async Task> DownloadFFMpegSuite( + FFMpegVersions version = FFMpegVersions.Latest, + FFMpegBinaries binaries = FFMpegBinaries.FFMpeg | FFMpegBinaries.FFProbe, + PlatformOverride? platformOverride = null) { var versionInfo = await GetVersionInfo(version); - var downloadInfo = versionInfo.BinaryInfo?.GetCompatibleDownloadInfo() ?? + var downloadInfo = versionInfo.BinaryInfo?.GetCompatibleDownloadInfo(platformOverride) ?? throw new FFMpegDownloaderException("Failed to get compatible download info"); var successList = new List(); @@ -81,7 +85,7 @@ public static async Task> DownloadFFMpegSuite(FFMpegVersions versio return successList; } - + /// /// Download file from uri /// @@ -101,7 +105,7 @@ private static MemoryStream DownloadFileAsSteam(Uri address) /// /// steam of the zip file /// - private static List ExtractZipAndSave(Stream zipStream) + private static IEnumerable ExtractZipAndSave(Stream zipStream) { using var archive = new ZipArchive(zipStream, ZipArchiveMode.Read); List files = new(); @@ -121,33 +125,64 @@ private static List ExtractZipAndSave(Stream zipStream) private class DownloadInfo { - [JsonPropertyName("ffmpeg")] public string? FFMpeg { get; } + [JsonPropertyName("ffmpeg")] public string? FFMpeg { get; set; } - [JsonPropertyName("ffprobe")] public string? FFProbe { get; } + [JsonPropertyName("ffprobe")] public string? FFProbe { get; set; } - [JsonPropertyName("ffplay")] public string? FFPlay { get; } + [JsonPropertyName("ffplay")] public string? FFPlay { get; set; } } private class BinaryInfo { - [JsonPropertyName("windows-64")] public DownloadInfo? Windows64 { get; } + [JsonPropertyName("windows-64")] + public DownloadInfo? Windows64 { get; set; } - [JsonPropertyName("windows-32")] public DownloadInfo? Windows32 { get; } + [JsonPropertyName("windows-32")] + public DownloadInfo? Windows32 { get; set; } - [JsonPropertyName("linux-32")] public DownloadInfo? Linux32 { get; set; } + [JsonPropertyName("linux-32")] + public DownloadInfo? Linux32 { get; set; } - [JsonPropertyName("linux-64")] public DownloadInfo? Linux64 { get; } + [JsonPropertyName("linux-64")] + public DownloadInfo? Linux64 { get; set; } - [JsonPropertyName("linux-armhf")] public DownloadInfo? LinuxArmhf { get; } + [JsonPropertyName("linux-armhf")] + public DownloadInfo? LinuxArmhf { get; set; } - [JsonPropertyName("linux-armel")] public DownloadInfo? LinuxArmel { get; set; } + [JsonPropertyName("linux-armel")] + public DownloadInfo? LinuxArmel { get; set; } - [JsonPropertyName("linux-arm64")] public DownloadInfo? LinuxArm64 { get; } + [JsonPropertyName("linux-arm64")] + public DownloadInfo? LinuxArm64 { get; set; } - [JsonPropertyName("osx-64")] public DownloadInfo? Osx64 { get; } + [JsonPropertyName("osx-64")] + public DownloadInfo? Osx64 { get; set; } - public DownloadInfo? GetCompatibleDownloadInfo() + /// + /// Automatically get the compatible download info for current os and architecture + /// + /// + /// + /// + /// + public DownloadInfo? GetCompatibleDownloadInfo(PlatformOverride? platformOverride = null) { + if (platformOverride is not null) + { + return platformOverride switch + { + PlatformOverride.Windows64 => Windows64, + PlatformOverride.Windows32 => Windows32, + PlatformOverride.Linux64 => Linux64, + PlatformOverride.Linux32 => Linux32, + PlatformOverride.LinuxArmhf => LinuxArmhf, + PlatformOverride.LinuxArmel => LinuxArmel, + PlatformOverride.LinuxArm64 => LinuxArm64, + PlatformOverride.Osx64 => Osx64, + _ => throw new ArgumentOutOfRangeException(nameof(platformOverride), platformOverride, null) + }; + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return RuntimeInformation.OSArchitecture == Architecture.X64 ? Windows64 : Windows32; @@ -157,10 +192,11 @@ private class BinaryInfo { return RuntimeInformation.OSArchitecture switch { + Architecture.X86 => Linux32, Architecture.X64 => Linux64, Architecture.Arm => LinuxArmhf, Architecture.Arm64 => LinuxArm64, - _ => throw new PlatformNotSupportedException("Unsupported Linux architecture") + _ => LinuxArmel }; } @@ -169,7 +205,7 @@ private class BinaryInfo return Osx64; } - throw new PlatformNotSupportedException("Unsupported OS"); + throw new PlatformNotSupportedException("Unsupported OS or Architecture"); } } @@ -182,7 +218,7 @@ private class VersionInfo [JsonPropertyName("bin")] public BinaryInfo? BinaryInfo { get; set; } } - private static readonly Dictionary FFBinariesAPIs = new() + private static readonly Dictionary _FFBinariesAPIs = new() { { FFMpegVersions.Latest, "https://ffbinaries.com/api/v1/version/latest" }, { FFMpegVersions.V4_4_1, "https://ffbinaries.com/api/v1/version/4.4.1" }, @@ -203,7 +239,7 @@ private class VersionInfo /// private static async Task GetVersionInfo(FFMpegVersions version) { - if (!FFBinariesAPIs.TryGetValue(version, out var versionUri)) + if (!_FFBinariesAPIs.TryGetValue(version, out var versionUri)) { throw new FFMpegDownloaderException($"Invalid version selected: {version}", "contact dev"); }