allow os and architecture overrider

This commit is contained in:
Kerry Cao 2023-09-06 13:19:02 -06:00
parent ae92e9370c
commit df8d97ebbb

View file

@ -14,19 +14,8 @@ public class FFMpegDownloader
[Flags] [Flags]
public enum FFMpegBinaries : ushort public enum FFMpegBinaries : ushort
{ {
/// <summary>
/// FFMpeg binary
/// </summary>
FFMpeg, FFMpeg,
/// <summary>
/// FFProbe binary
/// </summary>
FFProbe, FFProbe,
/// <summary>
/// FFPlay binary
/// </summary>
FFPlay FFPlay
} }
@ -43,17 +32,32 @@ public enum FFMpegVersions : ushort
V3_2 V3_2
} }
public enum PlatformOverride : short
{
Windows64,
Windows32,
Linux64,
Linux32,
LinuxArmhf,
LinuxArmel,
LinuxArm64,
Osx64
}
/// <summary> /// <summary>
/// Download the latest FFMpeg suite binaries for current platform /// Download the latest FFMpeg suite binaries for current platform
/// </summary> /// </summary>
/// <param name="version">used to explicitly state the version of binary you want to download</param> /// <param name="version">used to explicitly state the version of binary you want to download</param>
/// <param name="binaries">used to explicitly state the binary you want to download</param> /// <param name="binaries">used to explicitly state the binaries you want to download (ffmpeg, ffprobe, ffplay)</param>
/// <param name="platformOverride">used to explicitly state the os and architecture you want to download</param>
/// <returns>a list of the binaries that have been successfully downloaded</returns> /// <returns>a list of the binaries that have been successfully downloaded</returns>
public static async Task<List<string>> DownloadFFMpegSuite(FFMpegVersions version = FFMpegVersions.Latest, public static async Task<List<string>> DownloadFFMpegSuite(
FFMpegBinaries binaries = FFMpegBinaries.FFMpeg | FFMpegBinaries.FFProbe) FFMpegVersions version = FFMpegVersions.Latest,
FFMpegBinaries binaries = FFMpegBinaries.FFMpeg | FFMpegBinaries.FFProbe,
PlatformOverride? platformOverride = null)
{ {
var versionInfo = await GetVersionInfo(version); 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"); throw new FFMpegDownloaderException("Failed to get compatible download info");
var successList = new List<string>(); var successList = new List<string>();
@ -81,7 +85,7 @@ public static async Task<List<string>> DownloadFFMpegSuite(FFMpegVersions versio
return successList; return successList;
} }
/// <summary> /// <summary>
/// Download file from uri /// Download file from uri
/// </summary> /// </summary>
@ -101,7 +105,7 @@ private static MemoryStream DownloadFileAsSteam(Uri address)
/// </summary> /// </summary>
/// <param name="zipStream">steam of the zip file</param> /// <param name="zipStream">steam of the zip file</param>
/// <returns></returns> /// <returns></returns>
private static List<string> ExtractZipAndSave(Stream zipStream) private static IEnumerable<string> ExtractZipAndSave(Stream zipStream)
{ {
using var archive = new ZipArchive(zipStream, ZipArchiveMode.Read); using var archive = new ZipArchive(zipStream, ZipArchiveMode.Read);
List<string> files = new(); List<string> files = new();
@ -121,33 +125,64 @@ private static List<string> ExtractZipAndSave(Stream zipStream)
private class DownloadInfo 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 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() /// <summary>
/// Automatically get the compatible download info for current os and architecture
/// </summary>
/// <param name="platformOverride"></param>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="PlatformNotSupportedException"></exception>
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)) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{ {
return RuntimeInformation.OSArchitecture == Architecture.X64 ? Windows64 : Windows32; return RuntimeInformation.OSArchitecture == Architecture.X64 ? Windows64 : Windows32;
@ -157,10 +192,11 @@ private class BinaryInfo
{ {
return RuntimeInformation.OSArchitecture switch return RuntimeInformation.OSArchitecture switch
{ {
Architecture.X86 => Linux32,
Architecture.X64 => Linux64, Architecture.X64 => Linux64,
Architecture.Arm => LinuxArmhf, Architecture.Arm => LinuxArmhf,
Architecture.Arm64 => LinuxArm64, Architecture.Arm64 => LinuxArm64,
_ => throw new PlatformNotSupportedException("Unsupported Linux architecture") _ => LinuxArmel
}; };
} }
@ -169,7 +205,7 @@ private class BinaryInfo
return Osx64; 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; } [JsonPropertyName("bin")] public BinaryInfo? BinaryInfo { get; set; }
} }
private static readonly Dictionary<FFMpegVersions, string> FFBinariesAPIs = new() private static readonly Dictionary<FFMpegVersions, string> _FFBinariesAPIs = new()
{ {
{ FFMpegVersions.Latest, "https://ffbinaries.com/api/v1/version/latest" }, { FFMpegVersions.Latest, "https://ffbinaries.com/api/v1/version/latest" },
{ FFMpegVersions.V4_4_1, "https://ffbinaries.com/api/v1/version/4.4.1" }, { FFMpegVersions.V4_4_1, "https://ffbinaries.com/api/v1/version/4.4.1" },
@ -203,7 +239,7 @@ private class VersionInfo
/// <exception cref="FFMpegDownloaderException"></exception> /// <exception cref="FFMpegDownloaderException"></exception>
private static async Task<VersionInfo> GetVersionInfo(FFMpegVersions version) private static async Task<VersionInfo> 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"); throw new FFMpegDownloaderException($"Invalid version selected: {version}", "contact dev");
} }