mirror of
https://github.com/unclshura/splitter.git
synced 2026-08-06 03:33:39 +00:00
104 lines
3.0 KiB
C#
104 lines
3.0 KiB
C#
using System.Diagnostics;
|
|
using System.Globalization;
|
|
|
|
namespace splitter;
|
|
|
|
public sealed class PassthroughSplitter : LoggingBase, ISegmentProcessor
|
|
{
|
|
private sealed class State : IFrameProcessingState
|
|
{
|
|
public Process? EncodeProcess { get; set; }
|
|
|
|
public string InputFile { get; }
|
|
public string OutputFile { get; }
|
|
public double Start { get; }
|
|
public double Length { get; }
|
|
public string[] Passthrough { get; }
|
|
|
|
public State(SingleTask job)
|
|
{
|
|
InputFile = job.Job.InputFile;
|
|
OutputFile = job.OutputFileName;
|
|
Start = job.SegmentStart;
|
|
Length = job.SegmentLength;
|
|
Passthrough = job.Job.Passthrough;
|
|
}
|
|
}
|
|
|
|
public PassthroughSplitter(int segmentNo, ILogger logger)
|
|
: base(logger, segmentNo)
|
|
{
|
|
}
|
|
|
|
public IFrameProcessingState InitSegment(SingleTask job, CancellationToken token)
|
|
{
|
|
var state = new State(job);
|
|
state.EncodeProcess = StartEncode(job);
|
|
return state;
|
|
}
|
|
|
|
public FrameProcessingResult GetNextProcessedFrame(IFrameProcessingState processorState, CancellationToken token)
|
|
{
|
|
return new FrameProcessingResult(null, [], null);
|
|
}
|
|
|
|
public void FinishSegment(IFrameProcessingState processorState)
|
|
{
|
|
var state = (State)processorState;
|
|
|
|
try
|
|
{
|
|
if (state.EncodeProcess != null && !state.EncodeProcess.HasExited)
|
|
state.EncodeProcess.WaitForExit();
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
public async Task ProcessSegment(
|
|
SingleTask job,
|
|
Action<FrameProcessingResult>? onFrameProcessed,
|
|
CancellationToken token)
|
|
{
|
|
var state = (State)InitSegment(job, token);
|
|
|
|
var p = state.EncodeProcess;
|
|
if (p != null)
|
|
await p.WaitForExitAsync(token);
|
|
|
|
FinishSegment(state);
|
|
|
|
ClearProgress(job.OutputFileName);
|
|
|
|
if (p != null && p.ExitCode != 0)
|
|
LogError($"Segment {job.OutputFileName} FFmpeg passthrough failed");
|
|
else
|
|
LogInfo($"Segment {job.OutputFileName} passthrough completed");
|
|
}
|
|
|
|
private Process StartEncode(SingleTask job)
|
|
{
|
|
var inputFile = job.Job.InputFile;
|
|
var outputFile = job.OutputFileName;
|
|
var start = job.SegmentStart;
|
|
var length = job.SegmentLength;
|
|
|
|
var args =
|
|
$"-ss {start.ToString(CultureInfo.InvariantCulture)} " +
|
|
$"-i \"{inputFile}\" " +
|
|
$"-t {length.ToString(CultureInfo.InvariantCulture)} " +
|
|
$"-c copy {string.Join(" ", job.Job.Passthrough)} " +
|
|
$"\"{outputFile}\" -y";
|
|
|
|
var psi = new ProcessStartInfo
|
|
{
|
|
FileName = "ffmpeg",
|
|
Arguments = args,
|
|
RedirectStandardError = true,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true
|
|
};
|
|
|
|
return Process.Start(psi) ?? throw new Exception("Failed to start ffmpeg passthrough.");
|
|
}
|
|
}
|