-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFFmpeg.cs
147 lines (133 loc) · 5.31 KB
/
FFmpeg.cs
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
using engenious.Helper;
namespace engenious.Pipeline
{
/// <summary>
/// Wrapper class for the ffmpeg command line utility.
/// </summary>
public class FFmpeg
{
private string _ffmpegExe;
private readonly SynchronizationContext _syncContext;
/// <summary>
/// Initializes a new instance of the <see cref="FFmpeg"/> class.
/// </summary>
/// <param name="syncContext">
/// The synchronization context used for UI. To be able to select ffmpeg executable with an open file dialog.
/// </param>
/// <param name="exePath">The path to the ffmpeg executable.</param>
public FFmpeg(SynchronizationContext syncContext,string exePath)
{
_syncContext = syncContext;
_ffmpegExe = exePath;
}
/// <summary>
/// Initializes a new instance of the <see cref="FFmpeg"/> class.
/// </summary>
/// <param name="syncContext">
/// The synchronization context used for UI. To be able to select ffmpeg executable with an open file dialog.
/// </param>
public FFmpeg(SynchronizationContext syncContext)
: this(syncContext,LocateFFmpegExe())
{
}
private static string LocateFFmpegExe()
{
string completePath;
try
{
completePath = File.ReadAllText(".ffmpeg");
if (File.Exists(completePath))
return completePath;
}
catch
{
// ignored
}
string? path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string ext =string.Empty;
var platform = PlatformHelper.RunningPlatform();
switch (platform)
{
case Platform.Windows:
ext = ".exe";
break;
}
// ReSharper disable once AssignNullToNotNullAttribute
completePath = path == null ? "ffmpeg" + ext : Path.Combine(path, "ffmpeg" + ext);
if (File.Exists(completePath))
return completePath;
switch (platform)
{
case Platform.Linux:
completePath = Path.Combine("/usr/bin", "ffmpeg" + ext);
if (File.Exists(completePath))
return completePath;
break;
case Platform.Mac:
completePath = Path.Combine("/Applications", "ffmpeg" + ext);
if (File.Exists(completePath))
return completePath;
break;
case Platform.Windows:
var envPath = Environment.GetEnvironmentVariable("FFMPEG");
if (envPath != null && File.Exists(envPath))
return envPath;
break;
}
return "ffmpeg" + ext;
}
/// <summary>
/// Run the ffmpeg command with arguments.
/// </summary>
/// <param name="arguments">The arguments to pass to the ffmpeg command.</param>
/// <param name="throwAll">Whether to throw all exceptions or not.</param>
/// <returns>The started ffmpeg process.</returns>
/// <exception cref="FileNotFoundException">Thrown when ffmpeg was not found.</exception>
public Process RunCommand(string arguments, bool throwAll = false)
{
Process p = new();
p.StartInfo = new ProcessStartInfo(_ffmpegExe, arguments);
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
try
{
if (p.Start())
{
return p;
}
}
catch (Win32Exception ex)
{
if (throwAll || ex.NativeErrorCode != 2) //File not found
throw new FileNotFoundException($"Could not find ffmpeg at location: '{_ffmpegExe}'.");
_syncContext?.Send(o =>
{
// TODO: implement new file dialog
/*using (var ofd = new OpenFileDialog())
{
ofd.Title = "FFmpeg";
ofd.FileName = _ffmpegExe;
ofd.Filter = "Executable files|" + (PlatformHelper.RunningPlatform() == Platform.Windows ? "*.exe" : "*.*");
if (ofd.ShowDialog() == DialogResult.OK)
{
_ffmpegExe = ofd.FileName;
File.WriteAllText(".ffmpeg", _ffmpegExe);
}
}*/
},null);
if (File.Exists(_ffmpegExe))
return RunCommand(arguments, true);
throw new FileNotFoundException($"Could not find ffmpeg at location: '{_ffmpegExe}'.");
}
return p;
}
}
}