diff --git a/FFMpegCore.Extensions.Downloader/FFMpegDownloader.cs b/FFMpegCore.Extensions.Downloader/FFMpegDownloader.cs
index 9cad618..a05f9c6 100644
--- a/FFMpegCore.Extensions.Downloader/FFMpegDownloader.cs
+++ b/FFMpegCore.Extensions.Downloader/FFMpegDownloader.cs
@@ -1,53 +1,86 @@
-using FFMpegCore.Extensions.Downloader.Enums;
+using System.IO.Compression;
+using System.Text.Json;
+using FFMpegCore.Extensions.Downloader.Enums;
using FFMpegCore.Extensions.Downloader.Exceptions;
-using FFMpegCore.Extensions.Downloader.Services;
+using FFMpegCore.Extensions.Downloader.Extensions;
+using FFMpegCore.Extensions.Downloader.Models;
namespace FFMpegCore.Extensions.Downloader;
-public class FFMpegDownloader
+public static class FFMpegDownloader
{
///
/// 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 binaries you want to download (ffmpeg, ffprobe, ffplay)
+ /// used for specifying binary folder to download binaries into. If not provided, GlobalFFOptions are used
/// 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,
+ FFOptions? options = null,
SupportedPlatforms? platformOverride = null)
{
- // get all available versions
- var versionInfo = await FFbinariesService.GetVersionInfo(version);
+ using var httpClient = new HttpClient();
- // get the download info for the current platform
- var downloadInfo = versionInfo.BinaryInfo?.GetCompatibleDownloadInfo(platformOverride) ??
- throw new FFMpegDownloaderException("Failed to get compatible download info");
+ var versionInfo = await httpClient.GetVersionInfo(version);
+ var binariesDictionary = versionInfo.BinaryInfo?.GetCompatibleDownloadInfo(platformOverride) ??
+ throw new FFMpegDownloaderException("Failed to get compatible download info");
var successList = new List();
-
- // download ffmpeg if selected
- if (binaries.HasFlag(FFMpegBinaries.FFMpeg) && downloadInfo.FFMpeg is not null)
+ var relevantOptions = options ?? GlobalFFOptions.Current;
+ if (string.IsNullOrEmpty(relevantOptions.BinaryFolder))
{
- await using var zipStream = await FFbinariesService.DownloadFileAsStream(new Uri(downloadInfo.FFMpeg));
- successList.AddRange(FFbinariesService.ExtractZipAndSave(zipStream));
+ throw new FFMpegDownloaderException("Binary folder not specified");
}
- // download ffprobe if selected
- if (binaries.HasFlag(FFMpegBinaries.FFProbe) && downloadInfo.FFProbe is not null)
+ var binaryFlags = binaries.GetFlags();
+ foreach (var binaryFlag in binaryFlags)
{
- await using var zipStream = await FFbinariesService.DownloadFileAsStream(new Uri(downloadInfo.FFProbe));
- successList.AddRange(FFbinariesService.ExtractZipAndSave(zipStream));
- }
-
- // download ffplay if selected
- if (binaries.HasFlag(FFMpegBinaries.FFPlay) && downloadInfo.FFPlay is not null)
- {
- await using var zipStream = await FFbinariesService.DownloadFileAsStream(new Uri(downloadInfo.FFPlay));
- successList.AddRange(FFbinariesService.ExtractZipAndSave(zipStream));
+ if (binariesDictionary.TryGetValue(binaryFlag.ToString().ToLowerInvariant(), out var binaryUrl))
+ {
+ await using var zipStream = await httpClient.GetStreamAsync(new Uri(binaryUrl));
+ var extracted = ExtractZipAndSave(zipStream, relevantOptions.BinaryFolder);
+ successList.AddRange(extracted);
+ }
}
return successList;
}
+
+ private static async Task GetVersionInfo(this HttpClient client, FFMpegVersions version)
+ {
+ var versionUri = version.GetDescription();
+
+ var response = await client.GetAsync(versionUri);
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new FFMpegDownloaderException($"Failed to get version info from {versionUri}", "network error");
+ }
+
+ var jsonString = await response.Content.ReadAsStringAsync();
+ var versionInfo = JsonSerializer.Deserialize(jsonString);
+
+ return versionInfo ??
+ throw new FFMpegDownloaderException($"Failed to deserialize version info from {versionUri}", jsonString);
+ }
+
+ private static IEnumerable ExtractZipAndSave(Stream zipStream, string binaryFolder)
+ {
+ using var archive = new ZipArchive(zipStream, ZipArchiveMode.Read);
+ List files = new();
+ foreach (var entry in archive.Entries)
+ {
+ if (entry.Name is "ffmpeg" or "ffmpeg.exe" or "ffprobe.exe" or "ffprobe" or "ffplay.exe" or "ffplay")
+ {
+ var filePath = Path.Combine(binaryFolder, entry.Name);
+ entry.ExtractToFile(filePath, true);
+ files.Add(filePath);
+ }
+ }
+
+ return files;
+ }
}
diff --git a/FFMpegCore.Extensions.Downloader/Models/BinaryInfo.cs b/FFMpegCore.Extensions.Downloader/Models/BinaryInfo.cs
index e91fcee..d02cb14 100644
--- a/FFMpegCore.Extensions.Downloader/Models/BinaryInfo.cs
+++ b/FFMpegCore.Extensions.Downloader/Models/BinaryInfo.cs
@@ -4,23 +4,23 @@ using FFMpegCore.Extensions.Downloader.Enums;
namespace FFMpegCore.Extensions.Downloader.Models;
-internal record BinaryInfo
+internal class BinaryInfo
{
- [JsonPropertyName("windows-64")] public DownloadInfo? Windows64 { get; set; }
+ [JsonPropertyName("windows-64")] public Dictionary? Windows64 { get; set; }
- [JsonPropertyName("windows-32")] public DownloadInfo? Windows32 { get; set; }
+ [JsonPropertyName("windows-32")] public Dictionary? Windows32 { get; set; }
- [JsonPropertyName("linux-32")] public DownloadInfo? Linux32 { get; set; }
+ [JsonPropertyName("linux-32")] public Dictionary? Linux32 { get; set; }
- [JsonPropertyName("linux-64")] public DownloadInfo? Linux64 { get; set; }
+ [JsonPropertyName("linux-64")] public Dictionary? Linux64 { get; set; }
- [JsonPropertyName("linux-armhf")] public DownloadInfo? LinuxArmhf { get; set; }
+ [JsonPropertyName("linux-armhf")] public Dictionary? LinuxArmhf { get; set; }
- [JsonPropertyName("linux-armel")] public DownloadInfo? LinuxArmel { get; set; }
+ [JsonPropertyName("linux-armel")] public Dictionary? LinuxArmel { get; set; }
- [JsonPropertyName("linux-arm64")] public DownloadInfo? LinuxArm64 { get; set; }
+ [JsonPropertyName("linux-arm64")] public Dictionary? LinuxArm64 { get; set; }
- [JsonPropertyName("osx-64")] public DownloadInfo? Osx64 { get; set; }
+ [JsonPropertyName("osx-64")] public Dictionary? Osx64 { get; set; }
///
/// Automatically get the compatible download info for current os and architecture
@@ -29,7 +29,7 @@ internal record BinaryInfo
///
///
///
- public DownloadInfo? GetCompatibleDownloadInfo(SupportedPlatforms? platformOverride = null)
+ public Dictionary? GetCompatibleDownloadInfo(SupportedPlatforms? platformOverride = null)
{
if (platformOverride is not null)
{
@@ -64,7 +64,7 @@ internal record BinaryInfo
};
}
- if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && RuntimeInformation.OSArchitecture == Architecture.X64)
{
return Osx64;
}
diff --git a/FFMpegCore.Extensions.Downloader/Models/DownloadInfo.cs b/FFMpegCore.Extensions.Downloader/Models/DownloadInfo.cs
deleted file mode 100644
index 5b7c0fd..0000000
--- a/FFMpegCore.Extensions.Downloader/Models/DownloadInfo.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace FFMpegCore.Extensions.Downloader.Models;
-
-internal record DownloadInfo
-{
- [JsonPropertyName("ffmpeg")] public string? FFMpeg { get; set; }
-
- [JsonPropertyName("ffprobe")] public string? FFProbe { get; set; }
-
- [JsonPropertyName("ffplay")] public string? FFPlay { get; set; }
-}
diff --git a/FFMpegCore.Extensions.Downloader/Services/FFbinariesService.cs b/FFMpegCore.Extensions.Downloader/Services/FFbinariesService.cs
deleted file mode 100644
index 9e46db3..0000000
--- a/FFMpegCore.Extensions.Downloader/Services/FFbinariesService.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using System.IO.Compression;
-using System.Text.Json;
-using FFMpegCore.Extensions.Downloader.Enums;
-using FFMpegCore.Extensions.Downloader.Exceptions;
-using FFMpegCore.Extensions.Downloader.Extensions;
-using FFMpegCore.Extensions.Downloader.Models;
-
-namespace FFMpegCore.Extensions.Downloader.Services;
-
-///
-/// Service to interact with ffbinaries.com API
-///
-internal class FFbinariesService
-{
- ///
- /// Get version info from ffbinaries.com
- ///
- /// use to explicitly state the version of ffmpeg you want
- ///
- ///
- internal static async Task GetVersionInfo(FFMpegVersions version)
- {
- var versionUri = version.GetDescription();
-
- HttpClient client = new();
- var response = await client.GetAsync(versionUri);
-
- if (!response.IsSuccessStatusCode)
- {
- throw new FFMpegDownloaderException($"Failed to get version info from {versionUri}", "network error");
- }
-
- var jsonString = await response.Content.ReadAsStringAsync();
- var versionInfo = JsonSerializer.Deserialize(jsonString);
-
- return versionInfo ??
- throw new FFMpegDownloaderException($"Failed to deserialize version info from {versionUri}", jsonString);
- }
-
- ///
- /// Download file from uri
- ///
- /// uri of the file
- ///
- internal static async Task DownloadFileAsStream(Uri address)
- {
- var client = new HttpClient();
- return await client.GetStreamAsync(address);
- }
-
- ///
- /// Extracts the binaries from the zip stream and saves them to the current binary folder
- ///
- /// steam of the zip file
- ///
- internal static IEnumerable ExtractZipAndSave(Stream zipStream)
- {
- if (string.IsNullOrEmpty(GlobalFFOptions.Current.BinaryFolder))
- {
- throw new FFMpegDownloaderException("Binary folder not specified");
- }
-
- using var archive = new ZipArchive(zipStream, ZipArchiveMode.Read);
- List files = new();
- foreach (var entry in archive.Entries)
- {
- if (entry.Name is "ffmpeg" or "ffmpeg.exe" or "ffprobe.exe" or "ffprobe" or "ffplay.exe" or "ffplay")
- {
- entry.ExtractToFile(Path.Combine(GlobalFFOptions.Current.BinaryFolder, entry.Name), true);
- files.Add(Path.Combine(GlobalFFOptions.Current.BinaryFolder, entry.Name));
- }
- }
-
- return files;
- }
-}