feat(ui): 영상·오디오 인코딩 옵션 패널 — 출력 형식별 동적 노출
OptionsViewModel + 옵션 패널에 영상/오디오 인코딩 옵션을 선언적 바인딩으로 노출. - OptionsViewModel: 영상/오디오 ObservableProperty(코덱·레이트컨트롤·CRF·비트레이트·프리셋·해상도·fps· 회전·디인터레이스·faststart·SpatialAq / 오디오 코덱·비트레이트·VBR·샘플레이트·채널·loudnorm) + BuildVideo()/BuildAudio()로 VideoEncodeOptions/AudioEncodeOptions 구성, ToConvertOptions에 연결. - MainWindow.xaml: MediaPanel(VideoSubPanel/AudioSubPanel) — 레이트컨트롤 모드에 따라 CRF 슬라이더 ↔ 비트레이트 입력 DataTrigger 전환, 고급(회전/디인터레이스/SpatialAq)은 Expander. 전부 선언적 TwoWay 바인딩. - 코드비하인드: UpdateMediaPanelForFormat — 출력이 영상이면 영상+오디오, 오디오면 오디오만 노출. - 검증: 빌드 0/0, 106 테스트 그린, publish 후 메인 창 크래시 없이 로드. 옵션 실동작은 GUI 스모크 권장.
This commit is contained in:
parent
214789b656
commit
c10da19bfd
3 changed files with 211 additions and 1 deletions
|
|
@ -25,7 +25,28 @@ public partial class OptionsViewModel : ObservableObject
|
||||||
|
|
||||||
[ObservableProperty] private bool _videoPreferGpu = true;
|
[ObservableProperty] private bool _videoPreferGpu = true;
|
||||||
|
|
||||||
/// <summary>현재 상태로 불변 ConvertOptions를 구성한다(기존 MainWindow.BuildOptions와 동일 동작).</summary>
|
// ── 영상 인코딩 (출력이 영상 컨테이너일 때) ──────────────────────────────────────────────
|
||||||
|
[ObservableProperty] private int _videoCodecIndex; // 0=Auto,1=H264,2=H265,3=VP9,4=AV1,5=Copy
|
||||||
|
[ObservableProperty] private int _rateControlIndex; // 0=CRF,1=ABR,2=ConstrainedCRF,3=CBR,4=2pass
|
||||||
|
[ObservableProperty] private int _crf = 23; // 0~51
|
||||||
|
[ObservableProperty] private int _videoBitrateKbps = 8000;
|
||||||
|
[ObservableProperty] private int _presetIndex = 5; // 0=UltraFast..8=VerySlow(기본 Medium)
|
||||||
|
[ObservableProperty] private int _resolutionIndex; // 0=원본,1=2160p,2=1440p,3=1080p,4=720p,5=480p
|
||||||
|
[ObservableProperty] private int _fpsIndex; // 0=원본,1=24,2=30,3=60
|
||||||
|
[ObservableProperty] private int _rotateIndex; // 0=None,1=Cw90,2=Ccw90,3=180,4=FlipH,5=FlipV
|
||||||
|
[ObservableProperty] private int _deinterlaceIndex; // 0=Off,1=Yadif,2=Bwdif
|
||||||
|
[ObservableProperty] private bool _fastStart = true;
|
||||||
|
[ObservableProperty] private bool _spatialAq = true;
|
||||||
|
|
||||||
|
// ── 오디오 인코딩 (영상의 오디오 트랙 + 오디오 전용 출력) ─────────────────────────────────
|
||||||
|
[ObservableProperty] private int _audioCodecIndex; // 0=Auto,1=AAC,2=MP3,3=Opus,4=Vorbis,5=FLAC,6=PCM,7=Copy
|
||||||
|
[ObservableProperty] private int _audioBitrateIndex = 2; // 0=96,1=128,2=192,3=256,4=320
|
||||||
|
[ObservableProperty] private bool _audioVbr;
|
||||||
|
[ObservableProperty] private int _sampleRateIndex; // 0=원본,1=44100,2=48000
|
||||||
|
[ObservableProperty] private int _channelsIndex; // 0=원본,1=모노,2=스테레오
|
||||||
|
[ObservableProperty] private bool _loudnorm;
|
||||||
|
|
||||||
|
/// <summary>현재 상태로 불변 ConvertOptions를 구성한다(기존 MainWindow.BuildOptions와 동일 동작 + 영상/오디오).</summary>
|
||||||
public ConvertOptions ToConvertOptions()
|
public ConvertOptions ToConvertOptions()
|
||||||
{
|
{
|
||||||
var hasCustom = !string.IsNullOrWhiteSpace(CustomOutputDirectory);
|
var hasCustom = !string.IsNullOrWhiteSpace(CustomOutputDirectory);
|
||||||
|
|
@ -50,6 +71,34 @@ public partial class OptionsViewModel : ObservableObject
|
||||||
TargetLanguage = string.IsNullOrWhiteSpace(TargetLanguage) ? null : TargetLanguage.Trim(),
|
TargetLanguage = string.IsNullOrWhiteSpace(TargetLanguage) ? null : TargetLanguage.Trim(),
|
||||||
},
|
},
|
||||||
VideoPreferGpu = VideoPreferGpu,
|
VideoPreferGpu = VideoPreferGpu,
|
||||||
|
Video = BuildVideo(),
|
||||||
|
Audio = BuildAudio(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private VideoEncodeOptions BuildVideo() => new()
|
||||||
|
{
|
||||||
|
Codec = VideoCodecIndex switch { 1 => VideoCodec.H264, 2 => VideoCodec.H265, 3 => VideoCodec.Vp9, 4 => VideoCodec.Av1, 5 => VideoCodec.Copy, _ => VideoCodec.Auto },
|
||||||
|
RateControl = RateControlIndex switch { 1 => RateControlMode.AverageBitrate, 2 => RateControlMode.ConstrainedCrf, 3 => RateControlMode.Cbr, 4 => RateControlMode.TwoPass, _ => RateControlMode.Crf },
|
||||||
|
Crf = Math.Clamp(Crf, 0, 63),
|
||||||
|
VideoBitrateKbps = VideoBitrateKbps,
|
||||||
|
VideoMaxrateKbps = RateControlIndex == 2 ? VideoBitrateKbps : null, // 제약CRF는 비트레이트 입력을 상한으로
|
||||||
|
Preset = (VideoSpeedPreset)Math.Clamp(PresetIndex, 0, 8),
|
||||||
|
ScaleWidth = ResolutionIndex switch { 1 => 3840, 2 => 2560, 3 => 1920, 4 => 1280, 5 => 854, _ => (int?)null },
|
||||||
|
Fps = FpsIndex switch { 1 => 24.0, 2 => 30.0, 3 => 60.0, _ => (double?)null },
|
||||||
|
Rotate = (RotateMode)Math.Clamp(RotateIndex, 0, 5),
|
||||||
|
Deinterlace = (DeinterlaceMode)Math.Clamp(DeinterlaceIndex, 0, 2),
|
||||||
|
FastStart = FastStart,
|
||||||
|
SpatialAq = SpatialAq,
|
||||||
|
};
|
||||||
|
|
||||||
|
private AudioEncodeOptions BuildAudio() => new()
|
||||||
|
{
|
||||||
|
Codec = AudioCodecIndex switch { 1 => AudioCodec.Aac, 2 => AudioCodec.Mp3, 3 => AudioCodec.Opus, 4 => AudioCodec.Vorbis, 5 => AudioCodec.Flac, 6 => AudioCodec.Pcm, 7 => AudioCodec.Copy, _ => AudioCodec.Auto },
|
||||||
|
RateMode = AudioVbr ? AudioRateMode.Vbr : AudioRateMode.Bitrate,
|
||||||
|
AudioBitrateKbps = AudioBitrateIndex switch { 0 => 96, 1 => 128, 3 => 256, 4 => 320, _ => 192 },
|
||||||
|
SampleRate = SampleRateIndex switch { 1 => 44100, 2 => 48000, _ => (int?)null },
|
||||||
|
Channels = ChannelsIndex switch { 1 => 1, 2 => 2, _ => (int?)null },
|
||||||
|
Loudnorm = Loudnorm,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,153 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- 영상·오디오 인코딩 (출력이 영상/오디오일 때 동적 노출) -->
|
||||||
|
<StackPanel x:Name="MediaPanel" Margin="0,0,0,32" Visibility="Collapsed">
|
||||||
|
<TextBlock Text="영상·오디오 인코딩" Style="{StaticResource FsLabelStyle}"/>
|
||||||
|
|
||||||
|
<!-- 영상 (영상 컨테이너 출력 시) -->
|
||||||
|
<StackPanel x:Name="VideoSubPanel" Margin="0,8,0,0">
|
||||||
|
<TextBlock Text="비디오 코덱" Style="{StaticResource FsCaptionStyle}" Margin="0,0,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.VideoCodecIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="자동 (H.264 / 고해상도 H.265)"/>
|
||||||
|
<ComboBoxItem Content="H.264 (최대 호환)"/>
|
||||||
|
<ComboBoxItem Content="H.265 / HEVC (고압축)"/>
|
||||||
|
<ComboBoxItem Content="VP9"/>
|
||||||
|
<ComboBoxItem Content="AV1 (최고 압축)"/>
|
||||||
|
<ComboBoxItem Content="원본 복사 (재인코딩 없음)"/>
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
|
<TextBlock Text="레이트 컨트롤" Style="{StaticResource FsCaptionStyle}" Margin="0,10,0,4"/>
|
||||||
|
<ComboBox x:Name="RateControlCombo" SelectedIndex="{Binding Options.RateControlIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="CRF (품질 기준 · 권장)"/>
|
||||||
|
<ComboBoxItem Content="평균 비트레이트 (ABR)"/>
|
||||||
|
<ComboBoxItem Content="제약 CRF (품질+상한)"/>
|
||||||
|
<ComboBoxItem Content="고정 비트레이트 (CBR)"/>
|
||||||
|
<ComboBoxItem Content="2패스 (최고 효율)"/>
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
|
<!-- CRF 슬라이더 (CRF / 제약CRF 모드) -->
|
||||||
|
<StackPanel Margin="0,10,0,0">
|
||||||
|
<StackPanel.Style>
|
||||||
|
<Style TargetType="StackPanel">
|
||||||
|
<Setter Property="Visibility" Value="Visible"/>
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding SelectedIndex, ElementName=RateControlCombo}" Value="1"><Setter Property="Visibility" Value="Collapsed"/></DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding SelectedIndex, ElementName=RateControlCombo}" Value="3"><Setter Property="Visibility" Value="Collapsed"/></DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding SelectedIndex, ElementName=RateControlCombo}" Value="4"><Setter Property="Visibility" Value="Collapsed"/></DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</StackPanel.Style>
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Text="품질 (CRF) — 낮을수록 고화질" Style="{StaticResource FsCaptionStyle}"/>
|
||||||
|
<TextBlock Grid.Column="1" FontFamily="{StaticResource FsFontMono}" FontSize="12" Foreground="{StaticResource FsAccentBlue}"
|
||||||
|
Text="{Binding Options.Crf, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
||||||
|
</Grid>
|
||||||
|
<Slider Minimum="0" Maximum="51" Margin="0,4,0,0"
|
||||||
|
Value="{Binding Options.Crf, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- 비트레이트 입력 (ABR/제약CRF/CBR/2패스 모드) -->
|
||||||
|
<StackPanel Margin="0,10,0,0">
|
||||||
|
<StackPanel.Style>
|
||||||
|
<Style TargetType="StackPanel">
|
||||||
|
<Setter Property="Visibility" Value="Collapsed"/>
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding SelectedIndex, ElementName=RateControlCombo}" Value="1"><Setter Property="Visibility" Value="Visible"/></DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding SelectedIndex, ElementName=RateControlCombo}" Value="2"><Setter Property="Visibility" Value="Visible"/></DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding SelectedIndex, ElementName=RateControlCombo}" Value="3"><Setter Property="Visibility" Value="Visible"/></DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding SelectedIndex, ElementName=RateControlCombo}" Value="4"><Setter Property="Visibility" Value="Visible"/></DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</StackPanel.Style>
|
||||||
|
<TextBlock Text="비디오 비트레이트 (kbps)" Style="{StaticResource FsCaptionStyle}" Margin="0,0,0,4"/>
|
||||||
|
<TextBox Style="{StaticResource FsPathInputStyle}"
|
||||||
|
Text="{Binding Options.VideoBitrateKbps, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<TextBlock Text="인코딩 프리셋 (느릴수록 고압축)" Style="{StaticResource FsCaptionStyle}" Margin="0,10,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.PresetIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="UltraFast"/><ComboBoxItem Content="SuperFast"/><ComboBoxItem Content="VeryFast"/>
|
||||||
|
<ComboBoxItem Content="Faster"/><ComboBoxItem Content="Fast"/><ComboBoxItem Content="Medium"/>
|
||||||
|
<ComboBoxItem Content="Slow"/><ComboBoxItem Content="Slower"/><ComboBoxItem Content="VerySlow"/>
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
|
<Grid Margin="0,10,0,0">
|
||||||
|
<Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="10"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Grid.Column="0">
|
||||||
|
<TextBlock Text="해상도" Style="{StaticResource FsCaptionStyle}" Margin="0,0,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.ResolutionIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="원본"/><ComboBoxItem Content="2160p (4K)"/><ComboBoxItem Content="1440p"/>
|
||||||
|
<ComboBoxItem Content="1080p"/><ComboBoxItem Content="720p"/><ComboBoxItem Content="480p"/>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Column="2">
|
||||||
|
<TextBlock Text="프레임레이트" Style="{StaticResource FsCaptionStyle}" Margin="0,0,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.FpsIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="원본"/><ComboBoxItem Content="24"/><ComboBoxItem Content="30"/><ComboBoxItem Content="60"/>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<CheckBox Margin="0,12,0,0" Content="웹 스트리밍 최적화 (Faststart)"
|
||||||
|
IsChecked="{Binding Options.FastStart, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}"/>
|
||||||
|
<CheckBox Margin="0,6,0,0" Content="GPU 하드웨어 가속 (NVENC 등)"
|
||||||
|
IsChecked="{Binding Options.VideoPreferGpu, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}"/>
|
||||||
|
|
||||||
|
<Expander Header="고급" Margin="0,10,0,0" Foreground="{StaticResource FsTextSecondary}">
|
||||||
|
<StackPanel Margin="0,8,0,0">
|
||||||
|
<TextBlock Text="회전 / 뒤집기" Style="{StaticResource FsCaptionStyle}" Margin="0,0,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.RotateIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="없음"/><ComboBoxItem Content="시계 90°"/><ComboBoxItem Content="반시계 90°"/>
|
||||||
|
<ComboBoxItem Content="180°"/><ComboBoxItem Content="좌우 반전"/><ComboBoxItem Content="상하 반전"/>
|
||||||
|
</ComboBox>
|
||||||
|
<TextBlock Text="디인터레이스" Style="{StaticResource FsCaptionStyle}" Margin="0,10,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.DeinterlaceIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="끔"/><ComboBoxItem Content="Yadif"/><ComboBoxItem Content="Bwdif (고품질)"/>
|
||||||
|
</ComboBox>
|
||||||
|
<CheckBox Margin="0,10,0,0" Content="적응형 양자화 (GPU 화질↑)"
|
||||||
|
IsChecked="{Binding Options.SpatialAq, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Expander>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- 오디오 (영상의 오디오 트랙 + 오디오 전용 출력) -->
|
||||||
|
<StackPanel x:Name="AudioSubPanel" Margin="0,14,0,0">
|
||||||
|
<TextBlock Text="오디오" Style="{StaticResource FsLabelStyle}"/>
|
||||||
|
<TextBlock Text="오디오 코덱" Style="{StaticResource FsCaptionStyle}" Margin="0,8,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.AudioCodecIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="자동"/><ComboBoxItem Content="AAC"/><ComboBoxItem Content="MP3"/>
|
||||||
|
<ComboBoxItem Content="Opus"/><ComboBoxItem Content="Vorbis"/><ComboBoxItem Content="FLAC (무손실)"/>
|
||||||
|
<ComboBoxItem Content="PCM (WAV)"/><ComboBoxItem Content="원본 복사"/>
|
||||||
|
</ComboBox>
|
||||||
|
<TextBlock Text="오디오 비트레이트" Style="{StaticResource FsCaptionStyle}" Margin="0,10,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.AudioBitrateIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="96 kbps"/><ComboBoxItem Content="128 kbps"/><ComboBoxItem Content="192 kbps"/>
|
||||||
|
<ComboBoxItem Content="256 kbps"/><ComboBoxItem Content="320 kbps"/>
|
||||||
|
</ComboBox>
|
||||||
|
<CheckBox Margin="0,8,0,0" Content="가변 비트레이트 (VBR)"
|
||||||
|
IsChecked="{Binding Options.AudioVbr, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}"/>
|
||||||
|
<Grid Margin="0,10,0,0">
|
||||||
|
<Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="10"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Grid.Column="0">
|
||||||
|
<TextBlock Text="샘플레이트" Style="{StaticResource FsCaptionStyle}" Margin="0,0,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.SampleRateIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="원본"/><ComboBoxItem Content="44.1 kHz"/><ComboBoxItem Content="48 kHz"/>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Column="2">
|
||||||
|
<TextBlock Text="채널" Style="{StaticResource FsCaptionStyle}" Margin="0,0,0,4"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Options.ChannelsIndex, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="원본"/><ComboBoxItem Content="모노"/><ComboBoxItem Content="스테레오"/>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<CheckBox Margin="0,10,0,0" Content="음량 정규화 (EBU R128)"
|
||||||
|
IsChecked="{Binding Options.Loudnorm, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Stats Box -->
|
<!-- Stats Box -->
|
||||||
<Border Background="{StaticResource FsBgInput}"
|
<Border Background="{StaticResource FsBgInput}"
|
||||||
BorderBrush="{StaticResource FsBorderSubtle}"
|
BorderBrush="{StaticResource FsBorderSubtle}"
|
||||||
|
|
|
||||||
|
|
@ -1084,6 +1084,20 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
|
||||||
".avif" => "AVIF QUALITY",
|
".avif" => "AVIF QUALITY",
|
||||||
_ => "ENCODING QUALITY",
|
_ => "ENCODING QUALITY",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UpdateMediaPanelForFormat(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>출력이 영상/오디오일 때만 영상·오디오 인코딩 패널을 노출(영상이면 영상+오디오, 오디오면 오디오만).</summary>
|
||||||
|
private void UpdateMediaPanelForFormat(string? extension)
|
||||||
|
{
|
||||||
|
if (MediaPanel is null) return;
|
||||||
|
var ext = (extension ?? string.Empty).ToLowerInvariant();
|
||||||
|
var isVideo = ext is ".mp4" or ".mkv" or ".webm" or ".mov" or ".avi";
|
||||||
|
var isAudio = ext is ".mp3" or ".aac" or ".m4a" or ".opus" or ".ogg" or ".flac" or ".wav";
|
||||||
|
MediaPanel.Visibility = (isVideo || isAudio) ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
VideoSubPanel.Visibility = isVideo ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
AudioSubPanel.Visibility = (isVideo || isAudio) ? Visibility.Visible : Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateOutputDestHint(string? extension)
|
private void UpdateOutputDestHint(string? extension)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue