|
1 |
| -using System.Diagnostics; |
2 | 1 | using System.IO;
|
3 |
| -using System.Linq; |
4 |
| -using System.Net; |
5 |
| -using System.Threading; |
6 |
| -using System.Windows.Forms; |
7 | 2 |
|
8 | 3 | using BizHawk.Common;
|
9 | 4 |
|
10 | 5 | namespace BizHawk.Client.EmuHawk
|
11 | 6 | {
|
12 |
| - /// <summary> |
13 |
| - /// Downloads FFmpeg |
14 |
| - /// </summary> |
15 |
| - public partial class FFmpegDownloaderForm : Form |
| 7 | + public sealed class FFmpegDownloaderForm : DownloaderForm |
16 | 8 | {
|
17 |
| - public FFmpegDownloaderForm() |
18 |
| - { |
19 |
| - _path = FFmpegService.FFmpegPath; |
20 |
| - _url = FFmpegService.Url; |
21 |
| - |
22 |
| - InitializeComponent(); |
23 |
| - |
24 |
| - txtLocation.Text = _path; |
25 |
| - txtUrl.Text = _url; |
26 |
| - |
27 |
| - if (OSTailoredCode.IsUnixHost) textBox1.Text = string.Join("\n", textBox1.Text.Split('\n').Take(3)) + "\n\n(Linux user: If installing manually, you can use a symlink.)"; |
28 |
| - } |
29 |
| - |
30 |
| - private readonly string _path; |
31 |
| - private readonly string _url; |
32 |
| - |
33 |
| - private int _pct = 0; |
34 |
| - private bool _exiting = false; |
35 |
| - private bool _succeeded = false; |
36 |
| - private bool _failed = false; |
37 |
| - |
38 |
| - private void ThreadProc() |
39 |
| - { |
40 |
| - Download(); |
41 |
| - } |
42 |
| - |
43 |
| - private void Download() |
44 |
| - { |
45 |
| - //the temp file is owned by this thread |
46 |
| - var fn = TempFileManager.GetTempFilename("ffmpeg_download", ".7z", false); |
47 |
| - |
48 |
| - try |
49 |
| - { |
50 |
| - DirectoryInfo parentDir = new(Path.GetDirectoryName(_path)!); |
51 |
| - if (!parentDir.Exists) parentDir.Create(); |
52 |
| - // check writable before bothering with the download |
53 |
| - if (File.Exists(_path)) File.Delete(_path); |
54 |
| - using var fs = File.Create(_path); |
55 |
| - using (var evt = new ManualResetEvent(false)) |
56 |
| - { |
57 |
| - using var client = new WebClient(); |
58 |
| - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; |
59 |
| - client.DownloadFileAsync(new Uri(_url), fn); |
60 |
| - client.DownloadProgressChanged += (_, progressArgs) => _pct = progressArgs.ProgressPercentage; |
61 |
| - client.DownloadFileCompleted += (_, _) => evt.Set(); // we don't really need a status, we'll just try to unzip it when it's done |
62 |
| - |
63 |
| - while (true) |
64 |
| - { |
65 |
| - if (evt.WaitOne(10)) break; |
66 |
| - |
67 |
| - //if the gui thread ordered an exit, cancel the download and wait for it to acknowledge |
68 |
| - if (_exiting) |
69 |
| - { |
70 |
| - client.CancelAsync(); |
71 |
| - evt.WaitOne(); |
72 |
| - break; |
73 |
| - } |
74 |
| - } |
75 |
| - } |
| 9 | + protected override string ComponentName |
| 10 | + => "FFmpeg"; |
76 | 11 |
|
77 |
| -// throw new Exception("test of download failure"); |
| 12 | + protected override string DownloadTemp { get; } |
| 13 | + = TempFileManager.GetTempFilename("ffmpeg_download", ".7z", delete: false); |
78 | 14 |
|
79 |
| - //if we were ordered to exit, bail without wasting any more time |
80 |
| - if (_exiting) return; |
81 |
| - |
82 |
| - //try acquiring file |
83 |
| - using (var hf = new HawkFile(fn)) |
84 |
| - { |
85 |
| - using (var exe = OSTailoredCode.IsUnixHost ? hf.BindArchiveMember("ffmpeg") : hf.BindFirstOf(".exe")) |
86 |
| - { |
87 |
| - //last chance. exiting, don't dump the new ffmpeg file |
88 |
| - if (_exiting) return; |
89 |
| - exe!.GetStream().CopyTo(fs); |
90 |
| - fs.Dispose(); |
91 |
| - if (OSTailoredCode.IsUnixHost) |
92 |
| - { |
93 |
| - OSTailoredCode.ConstructSubshell("chmod", $"+x {_path}", checkStdout: false).Start(); |
94 |
| - Thread.Sleep(50); // Linux I/O flush idk |
95 |
| - } |
96 |
| - } |
97 |
| - } |
98 |
| - |
99 |
| - //make sure it worked |
100 |
| - if (!FFmpegService.QueryServiceAvailable()) throw new Exception("download failed"); |
101 |
| - |
102 |
| - _succeeded = true; |
103 |
| - } |
104 |
| - catch (Exception e) |
105 |
| - { |
106 |
| - _failed = true; |
107 |
| - Util.DebugWriteLine($"FFmpeg download failed with:\n{e}"); |
108 |
| - } |
109 |
| - finally |
110 |
| - { |
111 |
| - try |
112 |
| - { |
113 |
| - File.Delete(fn); |
114 |
| - } |
115 |
| - catch |
116 |
| - { |
117 |
| - // ignore |
118 |
| - } |
119 |
| - } |
120 |
| - } |
121 |
| - |
122 |
| - private void btnDownload_Click(object sender, EventArgs e) |
123 |
| - { |
124 |
| - btnDownload.Text = "Downloading..."; |
125 |
| - btnDownload.Enabled = false; |
126 |
| - _failed = false; |
127 |
| - _succeeded = false; |
128 |
| - _pct = 0; |
129 |
| - var t = new Thread(ThreadProc); |
130 |
| - t.Start(); |
131 |
| - } |
132 |
| - |
133 |
| - private void btnCancel_Click(object sender, EventArgs e) |
134 |
| - { |
135 |
| - Close(); |
136 |
| - } |
137 |
| - |
138 |
| - protected override void OnClosed(EventArgs e) |
| 15 | + public FFmpegDownloaderForm() |
139 | 16 | {
|
140 |
| - //inform the worker thread that it needs to try terminating without doing anything else |
141 |
| - //(it will linger on in background for a bit til it can service this) |
142 |
| - _exiting = true; |
| 17 | + Description = "BizHawk relies on a specific version of FFmpeg. No other version will do. The wrong version will be ignored. There is no way to override this behavior." |
| 18 | + + "\n\nThe required version could not be found." |
| 19 | + + (OSTailoredCode.IsUnixHost |
| 20 | + ? "\n\n(Linux user: If installing manually, you can use a symlink.)" |
| 21 | + : "\n\nUse this dialog to download it automatically, or download it yourself from the URL below and place it in the specified location."); |
| 22 | + DownloadFrom = FFmpegService.Url; |
| 23 | + DownloadTo = FFmpegService.FFmpegPath; |
143 | 24 | }
|
144 | 25 |
|
145 |
| - private void timer1_Tick(object sender, EventArgs e) |
146 |
| - { |
147 |
| - //if it's done, close the window. the user will be smart enough to reopen it |
148 |
| - if (_succeeded) Close(); |
149 |
| - if (_failed) |
150 |
| - { |
151 |
| - _failed = false; |
152 |
| - _pct = 0; |
153 |
| - btnDownload.Text = "FAILED - Download Again"; |
154 |
| - btnDownload.Enabled = true; |
155 |
| - } |
156 |
| - progressBar1.Value = _pct; |
157 |
| - } |
| 26 | + protected override Stream GetExtractionStream(HawkFile downloaded) |
| 27 | + => (OSTailoredCode.IsUnixHost |
| 28 | + ? downloaded.BindArchiveMember("ffmpeg")! |
| 29 | + : downloaded.BindFirstOf(".exe")).GetStream(); |
158 | 30 |
|
159 |
| - private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) |
160 |
| - { |
161 |
| - Process.Start(_url); |
162 |
| - } |
| 31 | + protected override bool PostChmodCheck() |
| 32 | + => FFmpegService.QueryServiceAvailable(); |
163 | 33 | }
|
164 | 34 | }
|
0 commit comments