-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProcessHandler.cs
95 lines (75 loc) · 3.25 KB
/
ProcessHandler.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
using dis.Features.Common;
using Serilog;
using Xabe.FFmpeg;
namespace dis.Features.Conversion;
public sealed class ProcessHandler(ILogger logger, CodecParser codecParser, StreamConfigurator configurator)
{
private const string NoStreamError = "There is no video or audio stream in the file";
private const string FastStartParam = "-movflags +faststart";
public static void SetTimeStamps(string path, DateTime date)
{
File.SetCreationTime(path, date);
File.SetLastWriteTime(path, date);
File.SetLastAccessTime(path, date);
}
public IConversion? ConfigureConversion(Settings o, IList<IStream> streams, string outP, TrimSettings? trimSettings = null)
{
var videoStream = streams.OfType<IVideoStream>().FirstOrDefault();
var audioStream = streams.OfType<IAudioStream>().FirstOrDefault();
if (videoStream is null && audioStream is null)
{
logger.Error(NoStreamError);
return default;
}
var parameters = new List<string> { $"-crf {o.Crf}" };
// Add trim parameters first if provided
if (trimSettings is not null)
parameters.Insert(0, trimSettings.GetFFmpegArgs());
// Add faststart for web playback formats
var isWebPlayBackFormat = o.VideoCodec is "libx264" or "h264" ||
outP.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) ||
outP.EndsWith(".mov", StringComparison.OrdinalIgnoreCase);
if (isWebPlayBackFormat)
{
parameters.Add(FastStartParam);
}
var conversion = FFmpeg.Conversions.New()
.AddParameter(string.Join(" ", parameters))
.SetPixelFormat(PixelFormat.yuv420p)
.SetPreset(ConversionPreset.VerySlow);
ConfigureVideoStream(conversion, videoStream, o);
ConfigureAudioStream(conversion, audioStream, o);
conversion.SetOutput(outP);
return conversion;
}
private void ConfigureVideoStream(IConversion conversion, IVideoStream? videoStream, Settings o)
{
if (videoStream is null) return;
var videoCodec = codecParser.GetCodec(o.VideoCodec);
conversion.AddStream(videoStream);
switch (videoCodec)
{
case VideoCodec.vp9:
configurator.SetVp9Args(conversion);
break;
case VideoCodec.av1:
configurator.SetCpuForAv1(conversion, videoStream.Framerate);
conversion.SetPixelFormat(PixelFormat.yuv420p10le);
break;
default:
conversion.UseMultiThread(o.MultiThread);
break;
}
if (!string.IsNullOrEmpty(o.Resolution))
configurator.SetResolution(videoStream, o.Resolution);
}
private static void ConfigureAudioStream(IConversion conversion, IAudioStream? audioStream, Settings o)
{
if (audioStream is null) return;
if (o.AudioBitrate.HasValue)
conversion.SetAudioBitrate((long)(o.AudioBitrate * 1000));
var audioCodec = o.VideoCodec is "vp8" or "vp9" or "av1" ? AudioCodec.libopus : AudioCodec.aac;
audioStream.SetCodec(audioCodec);
conversion.AddStream(audioStream);
}
}