Add Shorts wizard and v4 video-style pipeline
Turn the Shorts tab into a step-by-step wizard and port amigadb-short-fx-v4.sh: Video background style, auto/manual crop, source fade-in, and blur/opacity/margin settings.
This commit is contained in:
@@ -28,6 +28,16 @@ public sealed record AppSettings
|
||||
public string ShortsWebsite { get; init; } = "AMIGADB.NET";
|
||||
public string ShortsFontFile { get; init; } = "";
|
||||
public string ShortsBackgroundImage { get; init; } = "";
|
||||
public string ShortsBackgroundVideo { get; init; } = "";
|
||||
public string ShortsVideoBlur { get; init; } = "0";
|
||||
public string ShortsVideoOpacity { get; init; } = "1.0";
|
||||
public string ShortsSourceCropMode { get; init; } = "Auto";
|
||||
public string ShortsCropLeft { get; init; } = "0";
|
||||
public string ShortsCropRight { get; init; } = "0";
|
||||
public string ShortsCropTop { get; init; } = "0";
|
||||
public string ShortsCropBottom { get; init; } = "0";
|
||||
public string ShortsSourceMarginX { get; init; } = "40";
|
||||
public string ShortsSourceFadeIn { get; init; } = "1.5";
|
||||
public string ShortsCrf { get; init; } = "16";
|
||||
public string ShortsPreset { get; init; } = "slow";
|
||||
|
||||
@@ -68,6 +78,16 @@ public sealed record AppSettings
|
||||
ShortsWebsite = ShortsWebsite ?? "AMIGADB.NET",
|
||||
ShortsFontFile = ShortsFontFile ?? "",
|
||||
ShortsBackgroundImage = ShortsBackgroundImage ?? "",
|
||||
ShortsBackgroundVideo = ShortsBackgroundVideo ?? "",
|
||||
ShortsVideoBlur = string.IsNullOrWhiteSpace(ShortsVideoBlur) ? "0" : ShortsVideoBlur,
|
||||
ShortsVideoOpacity = string.IsNullOrWhiteSpace(ShortsVideoOpacity) ? "1.0" : ShortsVideoOpacity,
|
||||
ShortsSourceCropMode = string.IsNullOrWhiteSpace(ShortsSourceCropMode) ? "Auto" : ShortsSourceCropMode,
|
||||
ShortsCropLeft = string.IsNullOrWhiteSpace(ShortsCropLeft) ? "0" : ShortsCropLeft,
|
||||
ShortsCropRight = string.IsNullOrWhiteSpace(ShortsCropRight) ? "0" : ShortsCropRight,
|
||||
ShortsCropTop = string.IsNullOrWhiteSpace(ShortsCropTop) ? "0" : ShortsCropTop,
|
||||
ShortsCropBottom = string.IsNullOrWhiteSpace(ShortsCropBottom) ? "0" : ShortsCropBottom,
|
||||
ShortsSourceMarginX = string.IsNullOrWhiteSpace(ShortsSourceMarginX) ? "40" : ShortsSourceMarginX,
|
||||
ShortsSourceFadeIn = string.IsNullOrWhiteSpace(ShortsSourceFadeIn) ? "1.5" : ShortsSourceFadeIn,
|
||||
ShortsCrf = string.IsNullOrWhiteSpace(ShortsCrf) ? "16" : ShortsCrf,
|
||||
ShortsPreset = string.IsNullOrWhiteSpace(ShortsPreset) ? "slow" : ShortsPreset,
|
||||
};
|
||||
|
||||
+20
-2
@@ -1,6 +1,6 @@
|
||||
namespace AmiReel.Models;
|
||||
|
||||
/// <summary>Visual style applied to a YouTube Short. Mirrors the --style values of amigadb-short.sh.</summary>
|
||||
/// <summary>Visual style applied to a YouTube Short. Mirrors the --style values of amigadb-short-fx-v4.sh.</summary>
|
||||
public enum ShortStyle
|
||||
{
|
||||
Brand,
|
||||
@@ -22,9 +22,17 @@ public enum ShortStyle
|
||||
Monitor,
|
||||
Split,
|
||||
Spectrum,
|
||||
Video,
|
||||
}
|
||||
|
||||
/// <summary>One YouTube Shorts render job's parameters (port of amigadb-short.sh's arguments).</summary>
|
||||
/// <summary>How the video style crops the Amiga source before overlaying it.</summary>
|
||||
public enum ShortSourceCropMode
|
||||
{
|
||||
Auto,
|
||||
Center,
|
||||
}
|
||||
|
||||
/// <summary>One YouTube Shorts render job's parameters (port of amigadb-short-fx-v4.sh).</summary>
|
||||
public sealed record ShortSettings
|
||||
{
|
||||
public required string InputFile { get; init; }
|
||||
@@ -39,6 +47,16 @@ public sealed record ShortSettings
|
||||
public required double DurationSeconds { get; init; }
|
||||
public required ShortStyle Style { get; init; }
|
||||
public string BackgroundImage { get; init; } = "";
|
||||
public string BackgroundVideo { get; init; } = "";
|
||||
public double VideoBlur { get; init; }
|
||||
public double VideoOpacity { get; init; } = 1.0;
|
||||
public ShortSourceCropMode SourceCropMode { get; init; } = ShortSourceCropMode.Auto;
|
||||
public int CropLeft { get; init; }
|
||||
public int CropRight { get; init; }
|
||||
public int CropTop { get; init; }
|
||||
public int CropBottom { get; init; }
|
||||
public int SourceMarginX { get; init; } = 40;
|
||||
public double SourceFadeInSeconds { get; init; } = 1.5;
|
||||
public required string FontFile { get; init; }
|
||||
public required string FfmpegPath { get; init; }
|
||||
public required string FfprobePath { get; init; }
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
namespace AmiReel.Models;
|
||||
|
||||
/// <summary>One page of the Shorts create-wizard. Extra effect pages are inserted only when the style needs them.</summary>
|
||||
public enum ShortWizardStep
|
||||
{
|
||||
Clip,
|
||||
Effect,
|
||||
StyleOptions,
|
||||
Titles,
|
||||
Encode,
|
||||
}
|
||||
|
||||
/// <summary>Builds the Shorts wizard page list for a chosen visual style.</summary>
|
||||
public static class ShortWizard
|
||||
{
|
||||
public static IReadOnlyList<ShortWizardStep> StepsFor(ShortStyle style)
|
||||
{
|
||||
List<ShortWizardStep> steps = [ShortWizardStep.Clip, ShortWizardStep.Effect];
|
||||
if (NeedsStyleOptions(style))
|
||||
steps.Add(ShortWizardStep.StyleOptions);
|
||||
steps.Add(ShortWizardStep.Titles);
|
||||
steps.Add(ShortWizardStep.Encode);
|
||||
return steps;
|
||||
}
|
||||
|
||||
public static bool NeedsStyleOptions(ShortStyle style) =>
|
||||
style is ShortStyle.Brand or ShortStyle.Video;
|
||||
|
||||
public static string Title(ShortWizardStep step) => step switch
|
||||
{
|
||||
ShortWizardStep.Clip => "Source clip",
|
||||
ShortWizardStep.Effect => "Visual effect",
|
||||
ShortWizardStep.StyleOptions => "Effect settings",
|
||||
ShortWizardStep.Titles => "Title card",
|
||||
ShortWizardStep.Encode => "Encoding",
|
||||
_ => "Short",
|
||||
};
|
||||
|
||||
public static string Description(ShortStyle style) => style switch
|
||||
{
|
||||
ShortStyle.Brand => "Title-card background image with a framed source clip.",
|
||||
ShortStyle.Pixel => "Pixelated backdrop with neon scan bars.",
|
||||
ShortStyle.Mirror => "Reflected source strips above and below the clip.",
|
||||
ShortStyle.Crop => "Full-frame vertical crop of the source.",
|
||||
ShortStyle.Workbench => "Workbench-style window around the source.",
|
||||
ShortStyle.Blur => "Blurred backdrop with a centered source.",
|
||||
ShortStyle.Crt => "CRT curvature, scanlines, and a rolling highlight.",
|
||||
ShortStyle.Copper => "Amiga copper bars behind the source.",
|
||||
ShortStyle.Stars => "Twinkling star field behind a framed clip.",
|
||||
ShortStyle.Grid => "Neon grid horizon behind the source.",
|
||||
ShortStyle.Tiles => "Four-tile mirrored backdrop.",
|
||||
ShortStyle.Scan => "Chunky scanlines and moving bars.",
|
||||
ShortStyle.Starfield => "Fast-moving star streaks.",
|
||||
ShortStyle.Plasma => "Demoscene plasma backdrop.",
|
||||
ShortStyle.Rasterbars => "Classic raster bars above and below the clip.",
|
||||
ShortStyle.Vhs => "Tape noise, chroma shift, and scanlines.",
|
||||
ShortStyle.Monitor => "CRT monitor bezel around the source.",
|
||||
ShortStyle.Split => "Split-band source strips around the main clip.",
|
||||
ShortStyle.Spectrum => "Scrolling audio spectrum. The source video must have audio.",
|
||||
ShortStyle.Video => "Looping background video with the Amiga clip overlaid.",
|
||||
_ => "",
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user