public void ReverseVideo(string outputPath, string videoPath) { if (string.IsNullOrEmpty(outputPath)) { throw new ArgumentNullException(nameof(outputPath)); } if (string.IsNullOrEmpty(videoPath)) { throw new ArgumentNullException(nameof(videoPath)); } if (System.IO.File.Exists(outputPath)) { System.IO.File.Delete(outputPath); } string audioArg = string.Empty; if (MediaFileInfo.FileHasAudio(videoPath)) { audioArg = "-af areverse "; } FFmpegProcessRunner fpr = new FFmpegProcessRunner(); fpr.OnDurationMessage += DurationMessageReceived; fpr.OnTimeMessage += TimeMessageReceived; totalSteps = 1; currentStep = 1; fpr.Run($"-i \"{videoPath}\" -vf reverse {audioArg}\"{outputPath}\""); fpr.OnDurationMessage -= DurationMessageReceived; fpr.OnTimeMessage -= TimeMessageReceived; }
public void CombineVideos(string outputPath, string videoPath1, string videoPath2, bool combineHorizontally) { if (string.IsNullOrEmpty(outputPath)) { throw new ArgumentNullException(nameof(outputPath)); } if (string.IsNullOrEmpty(videoPath1)) { throw new ArgumentNullException(nameof(videoPath1)); } if (string.IsNullOrEmpty(videoPath2)) { throw new ArgumentNullException(nameof(videoPath2)); } if (System.IO.File.Exists(outputPath)) { System.IO.File.Delete(outputPath); } string stackArg = null; if (combineHorizontally) { stackArg = "hstack"; } else { stackArg = "vstack"; } bool video1HasAudio = MediaFileInfo.FileHasAudio(videoPath1); bool video2HasAudio = MediaFileInfo.FileHasAudio(videoPath2); string args = null; if (video1HasAudio && video2HasAudio) { args = $"-i \"{videoPath1}\" -i \"{videoPath2}\" -filter_complex \"[0:v][1:v]{stackArg}=inputs=2[v];[0:a][1:a]amerge[a]\" -map \"[v]\" -map \"[a]\" -ac 2 \"{outputPath}\""; } else if (!video1HasAudio && !video2HasAudio) { args = $"-i \"{videoPath1}\" -i \"{videoPath2}\" -filter_complex \"[0:v][1:v]{stackArg}=inputs=2[v]\" -map \"[v]\" \"{outputPath}\""; } else { throw new NotImplementedException(); } FFmpegProcessRunner fpr = new FFmpegProcessRunner(); fpr.OnDurationMessage += DurationMessageReceived; fpr.OnTimeMessage += TimeMessageReceived; totalSteps = 1; currentStep = 1; fpr.Run(args); fpr.OnDurationMessage -= DurationMessageReceived; fpr.OnTimeMessage -= TimeMessageReceived; }
public void GetScreenshotAtEnd(string outputPath, string videoPath) { if (string.IsNullOrEmpty(outputPath)) { throw new ArgumentNullException(nameof(outputPath)); } if (string.IsNullOrEmpty(videoPath)) { throw new ArgumentNullException(nameof(videoPath)); } if (System.IO.File.Exists(outputPath)) { System.IO.File.Delete(outputPath); } MediaFileInfo mediaFileInfo = new MediaFileInfo(videoPath); FFmpegProcessRunner fpr = new FFmpegProcessRunner(); fpr.Run($"-i \"{videoPath}\" -vf \"select='eq(n,{mediaFileInfo.FrameCount - 1})'\" -vframes 1 -q:v 2 \"{outputPath}\""); }
public void AdjustVideoSpeed(string outputPath, string videoFilepath, float newPlaybackRate, float newFramerate = 0, bool alsoChangeAudio = false) { if (string.IsNullOrEmpty(outputPath)) { throw new ArgumentNullException(nameof(outputPath)); } if (string.IsNullOrEmpty(videoFilepath)) { throw new ArgumentNullException(nameof(videoFilepath)); } if (alsoChangeAudio && !MediaFileInfo.FileHasAudio(videoFilepath)) { alsoChangeAudio = false; } if (alsoChangeAudio) { if (newPlaybackRate <= 0) { throw new ArgumentOutOfRangeException(nameof(newPlaybackRate)); } if (newPlaybackRate < 0.5f && !(new List <float> { 0.25f, 0.125f, 0.0625f, 0.03125f, 0.015625f, 0.0078125f, 0.00390625f }).Contains(newPlaybackRate)) { throw new ArgumentException("Playback rates lower than 0.5 must be: 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, or 0.00390625."); } if (newPlaybackRate > 2 && !(new List <float> { 4, 8, 16, 32, 64, 128, 256 }).Contains(newPlaybackRate)) { throw new ArgumentException("Playback rates higher than 2 must be: 4, 8, 16, 32, 64, 128, or 256."); } } if (System.IO.File.Exists(outputPath)) { System.IO.File.Delete(outputPath); } float setptsVal = 1 / newPlaybackRate; string frameRateArg = string.Empty; if (newFramerate > 0) { frameRateArg = $"-r {newFramerate} "; } string args; if (alsoChangeAudio) { string audioArg; if (newPlaybackRate < 0.5f) { audioArg = "atempo=0.5"; float temp = newPlaybackRate; while (temp < 0.5f) { temp /= 0.5f; audioArg += ",atempo=0.5"; } } else if (newPlaybackRate > 2) { audioArg = "atempo=2.0"; float temp = newPlaybackRate; while (temp > 2) { temp /= 2; audioArg += ",atempo=2.0"; } } else { audioArg = $"atempo={newPlaybackRate}"; } args = $"-i \"{videoFilepath}\" {frameRateArg}-filter_complex \"[0:v]setpts={setptsVal}*PTS[v];[0:a]{audioArg}[a]\" -map \"[v]\" -map \"[a]\" \"{outputPath}\""; } else { args = $"-i \"{videoFilepath}\" {frameRateArg}-filter:v \"setpts={setptsVal}*PTS\" -an \"{outputPath}\""; } FFmpegProcessRunner fpr = new FFmpegProcessRunner(); fpr.OnDurationMessage += DurationMessageReceived; fpr.OnTimeMessage += TimeMessageReceived; totalSteps = 1; currentStep = 1; fpr.Run(args); fpr.OnDurationMessage -= DurationMessageReceived; fpr.OnTimeMessage -= TimeMessageReceived; }
public static bool FileHasVideo(MediaFileInfo mfi) { IReadOnlyList <VideoStreamInfo> videoStreams = mfi.VideoStreams; return(videoStreams != null && videoStreams.Count > 0); }
public static bool FileHasAudio(MediaFileInfo mfi) { IReadOnlyList <AudioStreamInfo> audioStreams = mfi.AudioStreams; return(audioStreams != null && audioStreams.Count > 0); }