Add Shorts look preview and visual crop editor
Show opening/closing 9:16 stills from the same filtergraph, and let users drag a keep-region on a source frame to fill the crop insets.
This commit is contained in:
@@ -389,4 +389,128 @@ public class ShortsPipelineTests
|
||||
// Assert
|
||||
Assert.AreEqual(1000, width);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ValidatePreview_WithMissingTitleAndOutput_DoesNotThrow()
|
||||
{
|
||||
// Arrange
|
||||
string directory = CreateTempDirectory();
|
||||
string input = Path.Combine(directory, "clip.mp4");
|
||||
File.WriteAllText(input, "data");
|
||||
ShortSettings settings = ValidSettings(input, Path.Combine(directory, "missing-font.ttf")) with
|
||||
{
|
||||
Title = "",
|
||||
OutputPath = "",
|
||||
};
|
||||
|
||||
// Act & Assert (no exception)
|
||||
ShortsPipeline.ValidatePreview(settings);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ValidatePreview_WithMissingInput_ThrowsFileNotFoundException()
|
||||
{
|
||||
// Arrange
|
||||
string directory = CreateTempDirectory();
|
||||
ShortSettings settings = ValidSettings(Path.Combine(directory, "missing.mp4"), "font.ttf");
|
||||
|
||||
// Act & Assert
|
||||
Assert.ThrowsExactly<FileNotFoundException>(() => ShortsPipeline.ValidatePreview(settings));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PreviewOverlayWindows_Opening_HidesTitleCard()
|
||||
{
|
||||
// Act
|
||||
(double hookEnd, double infoStart, double ctaStart) = ShortsPipeline.PreviewOverlayWindows(ShortPreviewShot.Opening, 30);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(30, hookEnd);
|
||||
Assert.AreEqual(31, infoStart);
|
||||
Assert.AreEqual(31, ctaStart);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PreviewOverlayWindows_Closing_ShowsTitlesImmediately()
|
||||
{
|
||||
// Act
|
||||
(double hookEnd, double infoStart, double ctaStart) = ShortsPipeline.PreviewOverlayWindows(ShortPreviewShot.Closing, 30);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(-1, hookEnd);
|
||||
Assert.AreEqual(0, infoStart);
|
||||
Assert.AreEqual(0, ctaStart);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PreviewSeekSeconds_OpeningAndClosing_StayInsideDuration()
|
||||
{
|
||||
// Act
|
||||
double opening = ShortsPipeline.PreviewSeekSeconds(ShortPreviewShot.Opening, 30);
|
||||
double closing = ShortsPipeline.PreviewSeekSeconds(ShortPreviewShot.Closing, 30);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1.2, opening);
|
||||
Assert.AreEqual(29.6, closing);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AddTimestampOffset_AddsFractionalSeconds()
|
||||
{
|
||||
// Act
|
||||
string result = ShortsPipeline.AddTimestampOffset("00:01:10", 1.2);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual("00:01:11.200", result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BuildInputArguments_VideoStyle_IncludesLoopedBackgroundVideo()
|
||||
{
|
||||
// Arrange
|
||||
ShortSettings settings = ValidSettings("in.mp4", "font.ttf", ShortStyle.Video) with
|
||||
{
|
||||
BackgroundVideo = @"D:\bg.mp4",
|
||||
};
|
||||
|
||||
// Act
|
||||
List<string> args = ShortsPipeline.BuildInputArguments(settings, 0.12, "00:00:01.200");
|
||||
|
||||
// Assert
|
||||
CollectionAssert.Contains(args, "00:00:01.200");
|
||||
CollectionAssert.Contains(args, "-stream_loop");
|
||||
CollectionAssert.Contains(args, @"D:\bg.mp4");
|
||||
CollectionAssert.Contains(args, "in.mp4");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BuildExtractFrameArguments_SeeksToStartAndWritesOnePng()
|
||||
{
|
||||
// Act
|
||||
List<string> args = ShortsPipeline.BuildExtractFrameArguments(@"D:\clip.mp4", "00:00:05", @"C:\tmp\frame.png");
|
||||
|
||||
// Assert
|
||||
CollectionAssert.Contains(args, "00:00:05");
|
||||
CollectionAssert.Contains(args, @"D:\clip.mp4");
|
||||
CollectionAssert.Contains(args, "-frames:v");
|
||||
CollectionAssert.Contains(args, "1");
|
||||
CollectionAssert.Contains(args, @"C:\tmp\frame.png");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BuildFilterComplex_WithoutTextOverlays_SkipsDrawtext()
|
||||
{
|
||||
// Act
|
||||
string result = ShortsPipeline.BuildFilterComplex(
|
||||
"[0:v]copy[base]",
|
||||
fontEsc: "", hookEsc: "", titleEsc: "", metaEsc: "", websiteEsc: "",
|
||||
hookEnd: 2.7, infoStart: 23, ctaStart: 26.5,
|
||||
includeTextOverlays: false);
|
||||
|
||||
// Assert
|
||||
StringAssert.Contains(result, "[0:v]copy[base]");
|
||||
StringAssert.Contains(result, "[vout]");
|
||||
Assert.IsFalse(result.Contains("drawtext", StringComparison.Ordinal));
|
||||
Assert.IsFalse(result.Contains("drawbox", StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user