Files
AmiReel/Models/AppSettings.cs
T
klevze a590904e89 Add video preview, source crop, find-videos, and render toasts
Bring the Video tab closer to Shorts with 4K preview stills and crop
modes (none, auto, center, plus the visual editor). Settings store a
default source folder so Find videos can collect output.avi sequences.
Cap the FFmpeg log with auto-scroll, hide repeat spam, and show a
Windows notification when a video or short finishes or fails.
2026-08-16 09:20:56 +02:00

113 lines
6.0 KiB
C#

namespace AmiReel.Models;
/// <summary>
/// Persisted user settings (%LOCALAPPDATA%\AmiReel\settings.json). Uses named init
/// properties rather than a positional constructor: several members share the same
/// <see langword="string"/> type (e.g. TrimStart/FadeSeconds/EndCardHoldSeconds), so a
/// positional record would let two arguments be silently transposed at a call site
/// without the compiler catching it.
/// </summary>
public sealed record AppSettings
{
public required string OutputFolder { get; init; }
public required string EndCardPath { get; init; }
public required string FfmpegPath { get; init; }
public required string FfprobePath { get; init; }
public required string PreviewPlayerPath { get; init; }
public required string Theme { get; init; }
public required string Encoder { get; init; }
public required string TrimStart { get; init; }
public required string FadeSeconds { get; init; }
public required string EndCardHoldSeconds { get; init; }
public required string ThumbnailInterval { get; init; }
public bool? MoveSourcesToOriginals { get; init; }
public string SourceSearchFolder { get; init; } = "";
public string VideoSourceCropMode { get; init; } = "Auto";
public string VideoCropLeft { get; init; } = "0";
public string VideoCropRight { get; init; } = "0";
public string VideoCropTop { get; init; } = "0";
public string VideoCropBottom { get; init; } = "0";
// Shorts tab defaults (sticky across launches, same as the fields above).
public string ShortsStyle { get; init; } = "Brand";
public string ShortsHook { get; init; } = "THIS RAN ON AN AMIGA";
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";
public bool ShouldMoveSourcesToOriginals => MoveSourcesToOriginals != false;
public static AppSettings Default(string outputFolder) => new()
{
OutputFolder = outputFolder,
EndCardPath = "",
FfmpegPath = "",
FfprobePath = "",
PreviewPlayerPath = "",
Theme = "Dark",
Encoder = "Auto",
TrimStart = "4.414",
FadeSeconds = "3",
EndCardHoldSeconds = "4",
ThumbnailInterval = "10",
MoveSourcesToOriginals = true,
SourceSearchFolder = "",
VideoSourceCropMode = "Auto",
VideoCropLeft = "0",
VideoCropRight = "0",
VideoCropTop = "0",
VideoCropBottom = "0",
};
public AppSettings Normalize(string fallbackOutputFolder) => this with
{
OutputFolder = string.IsNullOrWhiteSpace(OutputFolder) ? fallbackOutputFolder : OutputFolder,
EndCardPath = EndCardPath ?? "",
FfmpegPath = FfmpegPath ?? "",
FfprobePath = FfprobePath ?? "",
PreviewPlayerPath = PreviewPlayerPath ?? "",
Theme = string.IsNullOrWhiteSpace(Theme) ? "Dark" : Theme,
Encoder = string.IsNullOrWhiteSpace(Encoder) ? "Auto" : Encoder,
TrimStart = string.IsNullOrWhiteSpace(TrimStart) ? "4.414" : TrimStart,
FadeSeconds = string.IsNullOrWhiteSpace(FadeSeconds) ? "3" : FadeSeconds,
EndCardHoldSeconds = string.IsNullOrWhiteSpace(EndCardHoldSeconds) ? "4" : EndCardHoldSeconds,
ThumbnailInterval = string.IsNullOrWhiteSpace(ThumbnailInterval) ? "10" : ThumbnailInterval,
MoveSourcesToOriginals = MoveSourcesToOriginals ?? true,
SourceSearchFolder = SourceSearchFolder ?? "",
VideoSourceCropMode = string.IsNullOrWhiteSpace(VideoSourceCropMode) ? "Auto" : VideoSourceCropMode,
VideoCropLeft = string.IsNullOrWhiteSpace(VideoCropLeft) ? "0" : VideoCropLeft,
VideoCropRight = string.IsNullOrWhiteSpace(VideoCropRight) ? "0" : VideoCropRight,
VideoCropTop = string.IsNullOrWhiteSpace(VideoCropTop) ? "0" : VideoCropTop,
VideoCropBottom = string.IsNullOrWhiteSpace(VideoCropBottom) ? "0" : VideoCropBottom,
ShortsStyle = string.IsNullOrWhiteSpace(ShortsStyle) ? "Brand" : ShortsStyle,
ShortsHook = ShortsHook ?? "THIS RAN ON AN AMIGA",
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,
};
}