static string BuildCommandLine(VideoSegment segment) { var sb = new StringBuilder(); sb.Append(" -hide_banner"); sb.Append($" -ss {segment.CutFrom}"); sb.Append($" -i \"{segment.SourceFile}\""); sb.Append($" -t {segment.CutDuration}"); sb.Append(" -avoid_negative_ts make_zero"); if (Settings.Instance.RemoveAudio) { sb.Append($" -an {segment.CutFrom}"); } else { sb.Append(" -acodec copy"); } sb.Append(" -vcodec copy"); sb.Append(" -scodec copy"); if (!Settings.Instance.IncludeAllStreams) { sb.Append(" -map 0"); } sb.Append(" -map_metadata 0"); sb.Append(" -ignore_unknown"); sb.Append($" -y \"{segment.OutputFile}\""); return(sb.ToString()); }
public async Task Cut(VideoSegment segment) { var commandLine = BuildCommandLine(segment); using var ffmpegProcess = new Process { StartInfo = new ProcessStartInfo { Arguments = commandLine, FileName = FfmpegStatics.FfmpegPath, CreateNoWindow = true, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden } }; ffmpegProcess.ErrorDataReceived += (sender, e) => { if (e.Data == null) { return; } var c = FfmpegStatics.ProgressRegex.Matches(e.Data); if (c.Count == 0 || c[0].Groups.Count < 2) { return; } if (!TimeSpan.TryParse(c[0].Groups[1].Value, out TimeSpan progress)) { return; } Progress?.Invoke(new ProgressEventArgs(progress / segment.CutDuration)); }; await ffmpegProcess.WaitForExitAsync(null); if (ffmpegProcess.ExitCode != 0) { throw new Exception("Failed to cut. Uncheck 'Include all streams' and try again. Otherwise run ffmpeg yourself and see what reports to you"); } }