forked from Killers0992/AudioPlayerApi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFfmpeg.cs
More file actions
124 lines (104 loc) · 4.51 KB
/
Ffmpeg.cs
File metadata and controls
124 lines (104 loc) · 4.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using SharpCompress.Archives;
using SharpCompress.Archives.Tar;
using SharpCompress.Common;
using SharpCompress.Compressors.Xz;
using SharpCompress.Readers;
using SharpCompress.Readers.Tar;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
public class Ffmpeg
{
private static readonly string FfmpegDir = Path.Combine(AppContext.BaseDirectory, "ffmpeg");
private static readonly string WindowsUrl = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip";
private static readonly string LinuxUrl = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz";
public static string FfmpegPath =>
RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Path.Combine(FfmpegDir, "ffmpeg.exe")
: Path.Combine(FfmpegDir, "ffmpeg-master-latest-linux64-gpl", "bin", "ffmpeg");
/// <summary>
/// Ensures that FFmpeg is downloaded and ready to use.
/// </summary>
public static async Task InitializeFfmpegAsync()
{
Directory.CreateDirectory(FfmpegDir);
if (File.Exists(FfmpegPath))
return;
string url = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? WindowsUrl : LinuxUrl;
string archivePath = Path.Combine(FfmpegDir, Path.GetFileName(url));
ServerConsole.AddLog($"[AudioPlayer] [FFmpeg] Downloading from {url} to {archivePath}");
using (HttpClient client = new HttpClient())
using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
long? contentLength = response.Content.Headers.ContentLength;
using (var stream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(archivePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
var buffer = new byte[8192];
long totalRead = 0;
int lastLogged = -1;
while (true)
{
int read = await stream.ReadAsync(buffer, 0, buffer.Length);
if (read == 0)
break;
await fileStream.WriteAsync(buffer, 0, read);
totalRead += read;
if (contentLength.HasValue)
{
int percent = (int)((totalRead * 100L) / contentLength.Value);
if (percent != lastLogged)
{
ServerConsole.AddLog($"[AudioPlayer] [FFmpeg] Download progress: {percent}%");
lastLogged = percent;
}
}
else
{
if (totalRead % (5 * 1024 * 1024) < buffer.Length)
ServerConsole.AddLog($"[AudioPlayer] [FFmpeg] Downloaded {totalRead / (1024 * 1024)} MB...");
}
}
}
}
ServerConsole.AddLog($"[AudioPlayer] [FFmpeg] Extracting to {FfmpegDir}");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
System.IO.Compression.ZipFile.ExtractToDirectory(archivePath, FfmpegDir);
var exe = Directory.GetFiles(FfmpegDir, "ffmpeg.exe", SearchOption.AllDirectories).FirstOrDefault();
if (exe != null)
File.Copy(exe, FfmpegPath, true);
File.Delete(archivePath);
File.Delete(FfmpegDir);
}
else
{
try
{
ExtractTarXz(archivePath, FfmpegDir);
}
catch (Exception ex)
{
ServerConsole.AddLog($"[AudioPlayer] [FFmpeg] Error extracting tar.xz: {ex}");
return;
}
File.Delete(archivePath);
}
ServerConsole.AddLog("[AudioPlayer] [FFmpeg] Extraction complete.");
}
public static void ExtractTarXz(string archivePath, string destination)
{
using (Stream xzStream = File.OpenRead(archivePath))
using (var decompressedStream = new XZStream(xzStream))
using (var reader = TarReader.Open(decompressedStream))
{
reader.WriteAllToDirectory(destination, new ExtractionOptions
{
ExtractFullPath = true,
Overwrite = true,
PreserveFileTime = true
});
}
}
}