From fe5c1f5b58d4089d87036783dd302ca319256563 Mon Sep 17 00:00:00 2001 From: Kevin Heritage Date: Mon, 23 May 2022 07:32:32 +0200 Subject: [PATCH 1/5] Create end seek argument --- FFMpegCore.Test/ArgumentBuilderTest.cs | 7 ++++ .../FFMpeg/Arguments/EndSeekArgument.cs | 35 +++++++++++++++++++ FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs | 1 + 3 files changed, 43 insertions(+) create mode 100644 FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs diff --git a/FFMpegCore.Test/ArgumentBuilderTest.cs b/FFMpegCore.Test/ArgumentBuilderTest.cs index f676a44..2c550c9 100644 --- a/FFMpegCore.Test/ArgumentBuilderTest.cs +++ b/FFMpegCore.Test/ArgumentBuilderTest.cs @@ -258,6 +258,13 @@ public void Builder_BuildString_Seek() Assert.AreEqual("-ss 00:00:10.000 -i \"input.mp4\" -ss 00:00:10.000 \"output.mp4\"", str); } + [TestMethod] + public void Builder_BuildString_EndSeek() + { + var str = FFMpegArguments.FromFileInput("input.mp4", false, opt => opt.EndSeek(TimeSpan.FromSeconds(10))).OutputToFile("output.mp4", false, opt => opt.EndSeek(TimeSpan.FromSeconds(10))).Arguments; + Assert.AreEqual("-to 00:00:10.000 -i \"input.mp4\" -to 00:00:10.000 \"output.mp4\"", str); + } + [TestMethod] public void Builder_BuildString_Shortest() { diff --git a/FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs b/FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs new file mode 100644 index 0000000..5ced1c4 --- /dev/null +++ b/FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs @@ -0,0 +1,35 @@ +using System; + +namespace FFMpegCore.Arguments +{ + /// + /// Represents seek parameter + /// + public class EndSeekArgument : IArgument + { + public readonly TimeSpan? SeekTo; + + public EndSeekArgument(TimeSpan? seekTo) + { + SeekTo = seekTo; + } + + public string Text { + get { + if(SeekTo.HasValue) + { + int hours = SeekTo.Value.Hours; + if(SeekTo.Value.Days > 0) + { + hours += SeekTo.Value.Days * 24; + } + return $"-to {hours.ToString("00")}:{SeekTo.Value.Minutes.ToString("00")}:{SeekTo.Value.Seconds.ToString("00")}.{SeekTo.Value.Milliseconds.ToString("000")}"; + } + else + { + return string.Empty; + } + } + } + } +} diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs index 0f54b8c..cc49c5f 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs @@ -54,6 +54,7 @@ public FFMpegArgumentOptions WithAudioFilters(Action audioFi public FFMpegArgumentOptions WithCustomArgument(string argument) => WithArgument(new CustomArgument(argument)); public FFMpegArgumentOptions Seek(TimeSpan? seekTo) => WithArgument(new SeekArgument(seekTo)); + public FFMpegArgumentOptions EndSeek(TimeSpan? seekTo) => WithArgument(new EndSeekArgument(seekTo)); public FFMpegArgumentOptions Loop(int times) => WithArgument(new LoopArgument(times)); public FFMpegArgumentOptions OverwriteExisting() => WithArgument(new OverwriteArgument()); public FFMpegArgumentOptions SelectStream(int streamIndex, int inputFileIndex = 0, From c7c591b451b76ce0162b7d6d53cbd529ea267570 Mon Sep 17 00:00:00 2001 From: Kevin Heritage Date: Mon, 23 May 2022 09:53:29 +0200 Subject: [PATCH 2/5] Create cut video function From a2c899d02e4384da7076a3a9b9d125755b79a672 Mon Sep 17 00:00:00 2001 From: Kevin Heritage Date: Fri, 17 Feb 2023 19:17:31 +0100 Subject: [PATCH 3/5] feat: create sub video function --- FFMpegCore/FFMpeg/FFMpeg.cs | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs index 58526b8..3939502 100644 --- a/FFMpegCore/FFMpeg/FFMpeg.cs +++ b/FFMpegCore/FFMpeg/FFMpeg.cs @@ -239,6 +239,46 @@ public static bool Join(string output, params string[] videos) } } + private static FFMpegArgumentProcessor BaseSubVideo(string input, string output, TimeSpan startTime, TimeSpan endTime) + { + if (Path.GetExtension(input) != Path.GetExtension(output)) + { + output = Path.Combine(Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), Path.GetExtension(input)); + } + + return FFMpegArguments + .FromFileInput(input, true, options => options.Seek(startTime).EndSeek(endTime)) + .OutputToFile(output, true, options => options.CopyChannel()); + } + + /// + /// Creates a new video starting and ending at the specified times + /// + /// Input video file. + /// Output video file. + /// The start time of when the sub video needs to start + /// The end time of where the sub video needs to end + /// Output video information. + public static bool SubVideo(string input, string output, TimeSpan startTime, TimeSpan endTime) + { + return BaseSubVideo(input, output, startTime, endTime) + .ProcessSynchronously(); + } + + /// + /// Creates a new video starting and ending at the specified times + /// + /// Input video file. + /// Output video file. + /// The start time of when the sub video needs to start + /// The end time of where the sub video needs to end + /// Output video information. + public static async Task SubVideoAsync(string input, string output, TimeSpan startTime, TimeSpan endTime) + { + return await BaseSubVideo(input, output, startTime, endTime) + .ProcessAsynchronously(); + } + /// /// Records M3U8 streams to the specified output. /// From a31f3886fd5a21d657b7bf62f944c69a45e18d8f Mon Sep 17 00:00:00 2001 From: Kevin Heritage Date: Fri, 17 Feb 2023 19:17:44 +0100 Subject: [PATCH 4/5] docs: update documentation to include sub video function --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 990361e..d2a9633 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,15 @@ FFMpeg.Join(@"..\joined_video.mp4", ); ``` +### Create a sub video +``` csharp +FFMpeg.SubVideo(inputPath, + outputPath, + TimeSpan.FromSeconds(0) + TimeSpan.FromSeconds(30) +); +``` + ### Join images into a video: ```csharp FFMpeg.JoinImageSequence(@"..\joined_video.mp4", frameRate: 1, From 59d43bb1c36ccae186c31c2529dce9e73a8be2c6 Mon Sep 17 00:00:00 2001 From: Kevin Heritage Date: Fri, 17 Feb 2023 19:27:30 +0100 Subject: [PATCH 5/5] chore: apply changes to format end seek --- FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs b/FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs index 5ced1c4..ea57339 100644 --- a/FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/EndSeekArgument.cs @@ -1,6 +1,4 @@ -using System; - -namespace FFMpegCore.Arguments +namespace FFMpegCore.Arguments { /// /// Represents seek parameter @@ -14,15 +12,18 @@ public EndSeekArgument(TimeSpan? seekTo) SeekTo = seekTo; } - public string Text { - get { - if(SeekTo.HasValue) + public string Text + { + get + { + if (SeekTo.HasValue) { - int hours = SeekTo.Value.Hours; - if(SeekTo.Value.Days > 0) + var hours = SeekTo.Value.Hours; + if (SeekTo.Value.Days > 0) { hours += SeekTo.Value.Days * 24; } + return $"-to {hours.ToString("00")}:{SeekTo.Value.Minutes.ToString("00")}:{SeekTo.Value.Seconds.ToString("00")}.{SeekTo.Value.Milliseconds.ToString("000")}"; } else