From c3de49fff5a7025bb6496afb532002aaf4540f6e5b8e1fc04d074bb716e1eea0 Mon Sep 17 00:00:00 2001 From: copecone Date: Tue, 18 Aug 2026 11:02:08 +0900 Subject: [PATCH] Add Custom Extension in Advanced Config --- Core/RenderManager.cs | 27 +++++++++------------------ Data/RenderConfig.cs | 6 +++++- UI/RenderConfigUIManager.cs | 26 +++++++++++++++++++++----- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/Core/RenderManager.cs b/Core/RenderManager.cs index bc8dc67..4c6c031 100644 --- a/Core/RenderManager.cs +++ b/Core/RenderManager.cs @@ -500,12 +500,9 @@ namespace ADOFAIRenderer.Core var renderFPS = Configuration.RenderFPS; var videoFPS = Configuration.VideoFPS; - - var selectedCodec = Configuration.VideoConfig.Codec; - var ext = GetOutputExtension(selectedCodec); var startTime = DateTime.Now; - var fileName = startTime.ToString("yyyy-MM-dd HH-mm-ss") + ext; + var fileName = startTime.ToString("yyyy-MM-dd HH-mm-ss") + $".{Configuration.AdvancedConfig.Extension}"; _currentOutPath = Path.Combine(MelonEnvironment.GameRootDirectory, "Render", fileName); if (RenderContext.OutputPath != null) _currentOutPath = RenderContext.OutputPath; @@ -520,7 +517,7 @@ namespace ADOFAIRenderer.Core Width = Configuration.RenderWidth, Height = Configuration.RenderHeight, FPS = effectiveVideoFps, - Codec = selectedCodec, + Codec = Configuration.VideoConfig.Codec, Mode = Configuration.VideoConfig.RateControlMode, QualityValue = Configuration.VideoConfig.QP, TargetBitrate = Configuration.VideoConfig.Bitrate, @@ -832,19 +829,13 @@ namespace ADOFAIRenderer.Core Cursor.visible = true; } - private string GetOutputExtension(Codec codec) + private static readonly Dictionary AudioCodecMatch = new() { - return codec switch - { - Codec.AV1 or Codec.VP9 => ".webm", - Codec.VVC => ".mkv", - _ => ".mp4" - }; - } - - private AVCodecID GetAudioCodecId(string ext) - { - return ext == ".mp4" ? AVCodecID.AV_CODEC_ID_AAC : AVCodecID.AV_CODEC_ID_OPUS; - } + [Codec.H264] = AVCodecID.AV_CODEC_ID_AAC, + [Codec.H265] = AVCodecID.AV_CODEC_ID_AAC, + [Codec.VP9] = AVCodecID.AV_CODEC_ID_OPUS, + [Codec.AV1] = AVCodecID.AV_CODEC_ID_OPUS, + [Codec.VVC] = AVCodecID.AV_CODEC_ID_OPUS + }; } } \ No newline at end of file diff --git a/Data/RenderConfig.cs b/Data/RenderConfig.cs index 7181ac8..bae11c9 100644 --- a/Data/RenderConfig.cs +++ b/Data/RenderConfig.cs @@ -1,7 +1,9 @@ +using System.Diagnostics.CodeAnalysis; using ADOFAIRenderer.Util.FFmpeg; namespace ADOFAIRenderer.Data { + [SuppressMessage("ReSharper", "RedundantDefaultMemberInitializer")] public class RenderConfig { public double RenderFPS { get; set; } @@ -15,14 +17,16 @@ namespace ADOFAIRenderer.Data public AdvancedConfig AdvancedConfig { get; set; } = new(); public double DelayAfterEnd { get; set; } - public bool ShowJudgementText { get; set; } + public bool ShowJudgementText { get; set; } = false; } + [SuppressMessage("ReSharper", "RedundantDefaultMemberInitializer")] public class AdvancedConfig { public int? RandomSeed { get; set; } = null; public bool ProcessAudio { get; set; } = true; public bool NonTile { get; set; } = false; + public string Extension { get; set; } = "mkv"; } public class VideoEncodingConfig diff --git a/UI/RenderConfigUIManager.cs b/UI/RenderConfigUIManager.cs index ee44a03..bd66328 100644 --- a/UI/RenderConfigUIManager.cs +++ b/UI/RenderConfigUIManager.cs @@ -123,7 +123,8 @@ namespace ADOFAIRenderer.UI { ProcessAudio = config.AdvancedConfig.ProcessAudio, RandomSeed = config.AdvancedConfig.RandomSeed, - NonTile = config.AdvancedConfig.NonTile + NonTile = config.AdvancedConfig.NonTile, + Extension = config.AdvancedConfig.Extension }; if (_advancedConfigContainer != null && _root.Contains(_advancedConfigContainer)) @@ -160,7 +161,21 @@ namespace ADOFAIRenderer.UI titleRow.Add(titleLabel); _advancedConfigContainer.Add(titleRow); - // 2. 오디오 처리 로우 + // 2. 확장자 로우 + var extensionRow = CreateRow(); + var extensionLabel = CreateFormLabel("확장자"); + var extensionChoices = new List { "mkv", "mp4", "mov", "webm", "avi" }; + var currentExt = string.IsNullOrWhiteSpace(tempConfig.Extension) ? "mkv" : tempConfig.Extension.TrimStart('.').ToLower(); + if (!extensionChoices.Contains(currentExt)) + { + extensionChoices.Add(currentExt); + } + var extensionDropdown = new DropdownField(extensionChoices, currentExt) { name = "AdvancedExtension" }; + extensionRow.Add(extensionLabel); + extensionRow.Add(extensionDropdown); + _advancedConfigContainer.Add(extensionRow); + + // 3. 오디오 처리 로우 var processAudioRow = CreateRow(); var processAudioLabel = CreateFormLabel("오디오 처리"); var processAudioToggle = new Toggle { name = "AdvancedProcessAudioToggle", label = "", value = tempConfig.ProcessAudio }; @@ -168,7 +183,7 @@ namespace ADOFAIRenderer.UI processAudioRow.Add(processAudioToggle); _advancedConfigContainer.Add(processAudioRow); - // 3. 논타일 모드 로우 + // 4. 논타일 모드 로우 var nonTileRow = CreateRow(); var nonTileLabel = CreateFormLabel("논타일 모드"); var nonTileToggle = new Toggle { name = "AdvancedNonTileToggle", label = "", value = tempConfig.NonTile }; @@ -176,7 +191,7 @@ namespace ADOFAIRenderer.UI nonTileRow.Add(nonTileToggle); _advancedConfigContainer.Add(nonTileRow); - // 4. 랜덤 시드 로우 + // 5. 랜덤 시드 로우 var randomSeedRow = CreateRow(); var randomSeedLabel = CreateFormLabel("랜덤 시드 (입력 선택)"); var randomSeedField = new TextField { name = "AdvancedRandomSeed", label = "", value = tempConfig.RandomSeed?.ToString() ?? string.Empty }; @@ -194,7 +209,7 @@ namespace ADOFAIRenderer.UI randomSeedRow.Add(randomSeedField); _advancedConfigContainer.Add(randomSeedRow); - // 5. 제어 버튼 로우 (취소 / 저장) + // 6. 제어 버튼 로우 (취소 / 저장) var buttonRow = CreateRow(); var cancelBtn = new Button { text = "취소" }; var saveBtn = new Button { text = "저장" }; @@ -212,6 +227,7 @@ namespace ADOFAIRenderer.UI saveBtn.RegisterCallback(_ => { + tempConfig.Extension = extensionDropdown.value; tempConfig.ProcessAudio = processAudioToggle.value; tempConfig.NonTile = nonTileToggle.value; if (int.TryParse(randomSeedField.value?.Trim(), out var seed))