diff --git a/FFMpegCore.Test/ArgumentBuilderTest.cs b/FFMpegCore.Test/ArgumentBuilderTest.cs index b0c5140..68df940 100644 --- a/FFMpegCore.Test/ArgumentBuilderTest.cs +++ b/FFMpegCore.Test/ArgumentBuilderTest.cs @@ -214,5 +214,12 @@ public void Builder_BuildString_Codec_Override() Assert.AreEqual(str, "-i \"input.mp4\" -codec:v libx264 -pix_fmt yuv420p -y \"output.mp4\""); } + + [TestMethod] + public void Builder_BuildString_Duration() { + var str = GetArgumentsString(new DurationArgument(TimeSpan.FromSeconds(20))); + + Assert.AreEqual(str, "-i \"input.mp4\" -t 00:00:20 \"output.mp4\""); + } } } diff --git a/FFMpegCore.Test/VideoTest.cs b/FFMpegCore.Test/VideoTest.cs index bb5e109..88510e6 100644 --- a/FFMpegCore.Test/VideoTest.cs +++ b/FFMpegCore.Test/VideoTest.cs @@ -3,6 +3,7 @@ using FFMpegCore.FFMPEG.Enums; using FFMpegCore.Test.Resources; using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; using System.Collections.Generic; using System.Drawing.Imaging; using System.IO; @@ -318,5 +319,27 @@ public void Video_With_Only_Audio_Should_Extract_Metadata() Assert.AreEqual(video.Duration.TotalSeconds, 79); Assert.AreEqual(video.Size, 1.25); } + + [TestMethod] + public void Video_Duration() { + var video = VideoInfo.FromFileInfo(VideoLibrary.LocalVideo); + var output = Input.OutputLocation(VideoType.Mp4); + + var arguments = new ArgumentContainer(); + arguments.Add(new InputArgument(VideoLibrary.LocalVideo)); + arguments.Add(new DurationArgument(TimeSpan.FromSeconds(video.Duration.TotalSeconds - 5))); + arguments.Add(new OutputArgument(output)); + + try { + Encoder.Convert(arguments); + + Assert.IsTrue(File.Exists(output.FullName)); + var outputVideo = new VideoInfo(output.FullName); + Assert.AreEqual(video.Duration.TotalSeconds - 5, outputVideo.Duration.TotalSeconds); + } finally { + if (File.Exists(output.FullName)) + output.Delete(); + } + } } } diff --git a/FFMpegCore/FFMPEG/Argument/ArgumentStringifier.cs b/FFMpegCore/FFMPEG/Argument/ArgumentStringifier.cs index b8057df..30d2001 100644 --- a/FFMpegCore/FFMPEG/Argument/ArgumentStringifier.cs +++ b/FFMpegCore/FFMPEG/Argument/ArgumentStringifier.cs @@ -201,5 +201,10 @@ internal static string StartNumber(int v) { return $"-start_number {v} "; } + + internal static string Duration(TimeSpan? duration) + { + return !duration.HasValue ? string.Empty : $"-t {duration} "; + } } } \ No newline at end of file diff --git a/FFMpegCore/FFMPEG/Argument/Atoms/DurationArgument.cs b/FFMpegCore/FFMPEG/Argument/Atoms/DurationArgument.cs new file mode 100644 index 0000000..0e764db --- /dev/null +++ b/FFMpegCore/FFMPEG/Argument/Atoms/DurationArgument.cs @@ -0,0 +1,27 @@ +using System; + +namespace FFMpegCore.FFMPEG.Argument +{ + /// + /// Represents duration parameter + /// + public class DurationArgument : Argument + { + public DurationArgument() + { + } + + public DurationArgument(TimeSpan? value) : base(value) + { + } + + /// + /// String representation of the argument + /// + /// String representation of the argument + public override string GetStringValue() + { + return ArgumentStringifier.Duration(Value); + } + } +}