From b42bf51e2f5c9c61eeb39d0081e1fad13e55eeab Mon Sep 17 00:00:00 2001 From: Kannagi Date: Tue, 29 Nov 2022 10:38:29 +0800 Subject: [PATCH] [Feature] Proxy, Chapters, DynamicRange Tag, About --- languages/en-US/yt-dlp-gui.lang | 16 +++- languages/zh-TW/yt-dlp-gui.lang | 16 +++- yt-dlp-gui/App.xaml.cs | 2 +- yt-dlp-gui/Controls/Duration.cs | 27 ++++--- yt-dlp-gui/Controls/TextView.xaml.cs | 14 +++- yt-dlp-gui/Models/Chapters.cs | 15 ++++ yt-dlp-gui/Models/Lang.cs | 14 +++- yt-dlp-gui/Models/Video.cs | 1 + yt-dlp-gui/Themes/CustomUI.xaml | 110 +++++++++++++++++++++++++-- yt-dlp-gui/ViewModels/Main.cs | 21 +++++ yt-dlp-gui/Views/About.xaml | 24 +++++- yt-dlp-gui/Views/About.xaml.cs | 32 +++++++- yt-dlp-gui/Views/Main.xaml | 106 +++++++++++++++++++++----- yt-dlp-gui/Views/Main.xaml.cs | 62 ++++++++++++--- yt-dlp-gui/Wrappers/DLP.cs | 4 + yt-dlp-gui/Wrappers/FFMPEG.cs | 15 ++++ yt-dlp-gui/yt-dlp-gui.csproj | 6 +- 17 files changed, 426 insertions(+), 59 deletions(-) create mode 100644 yt-dlp-gui/Models/Chapters.cs diff --git a/languages/en-US/yt-dlp-gui.lang b/languages/en-US/yt-dlp-gui.lang index 14bd4f8..013198b 100644 --- a/languages/en-US/yt-dlp-gui.lang +++ b/languages/en-US/yt-dlp-gui.lang @@ -9,10 +9,17 @@ Main: About: About... # Tab Formats Formats: Formats + Chapters: Chapters + ChaptersNone: "[None]" + ChaptersAll: "[All]" + ChaptersSplite: "[Split by Chapters]" Video: Video Audio: Audio Subtitle: Subtitle + SubtitleIgnore: "[Ignore]" + SubtitleNone: "[None]" VideoRes: Resolution + VideoDynamicRange: DR VideoFPS: FPS VideoExt: Ext. VideoCodec: Codec @@ -21,7 +28,7 @@ Main: AudioExt: Ext. AudioCodec: Codec AudioSize: FileSize - # Tab Formats + # Tab Advance Advance: Advance EmbedSubs: Embed Subtitles EmbedSubsEnabled: Enabled @@ -37,6 +44,9 @@ Main: RememberWindowState: Remember Window State RememberWindowPosition: Position RememberWindowSize: Size + Proxy: Proxy + ProxyEnabled: Enabled + ProxyHelper: "socks5://user:pass@127.0.0.1:1080/" Cookie: Cookie CookieWhenNeeded: When Needed CookieNever: Never @@ -61,6 +71,10 @@ About: About: About Website: Website Authors: Authors + # Extended information can be modified arbitrarily + Extends: + Localization Author: カンナギ Kannagi + Localization Website: https://github.com/Kannagi0303/yt-dlp-gui Releases: Releases: Releases Loading: Loading... diff --git a/languages/zh-TW/yt-dlp-gui.lang b/languages/zh-TW/yt-dlp-gui.lang index 30be3da..f2217f5 100644 --- a/languages/zh-TW/yt-dlp-gui.lang +++ b/languages/zh-TW/yt-dlp-gui.lang @@ -9,10 +9,17 @@ Main: About: 關於... # Tab Formats Formats: 格式 + Chapters: 章節 + ChaptersNone: "[無]" + ChaptersAll: "[所有]" + ChaptersSplite: "[按照章節分割]" Video: 視頻 Audio: 音頻 Subtitle: 字幕 + SubtitleIgnore: "[不使用]" + SubtitleNone: "[無]" VideoRes: 解析度 + VideoDynamicRange: 色彩 VideoFPS: 幀率 VideoExt: 格式 VideoCodec: 編碼 @@ -21,7 +28,7 @@ Main: AudioExt: 格式 AudioCodec: 編碼 AudioSize: 容量 - # Tab Formats + # Tab Advance Advance: 進階 EmbedSubs: 內嵌字幕 EmbedSubsEnabled: 啟用 @@ -37,6 +44,9 @@ Main: RememberWindowState: 記憶視窗 RememberWindowPosition: 位置 RememberWindowSize: 尺寸 + Proxy: 代理 + ProxyEnabled: 啟用 + ProxyHelper: "socks5://user:pass@127.0.0.1:1080/" Cookie: Cookie CookieWhenNeeded: 當需要時 CookieNever: 不使用 @@ -61,6 +71,10 @@ About: About: 關於 Website: 網站 Authors: 作者 + # Extended information can be modified arbitrarily + Extends: + 繁中作者: カンナギ Kannagi + 繁中網址: https://github.com/Kannagi0303/yt-dlp-gui Releases: Releases: 發行版本 Loading: 讀取中... diff --git a/yt-dlp-gui/App.xaml.cs b/yt-dlp-gui/App.xaml.cs index 7175e6f..3427c0e 100644 --- a/yt-dlp-gui/App.xaml.cs +++ b/yt-dlp-gui/App.xaml.cs @@ -8,7 +8,7 @@ namespace yt_dlp_gui { /// Interaction logic for App.xaml /// public partial class App : Application { - public static string CurrentVersion = "2022.11.14"; + public static string CurrentVersion = "2022.11.29"; public static Lang Lang { get; set; } = new(); private void Application_Startup(object sender, StartupEventArgs e) { var args = e.Args.ToList(); diff --git a/yt-dlp-gui/Controls/Duration.cs b/yt-dlp-gui/Controls/Duration.cs index eee6ba5..d3fd538 100644 --- a/yt-dlp-gui/Controls/Duration.cs +++ b/yt-dlp-gui/Controls/Duration.cs @@ -6,22 +6,27 @@ namespace yt_dlp_gui.Controls { public abstract class Duration { // Visible -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ public static readonly DependencyProperty SecsProperty - = DependencyProperty.RegisterAttached("Secs", typeof(double), typeof(Duration), - new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, SecsChanged)); + = DependencyProperty.RegisterAttached("Secs", typeof(double?), typeof(Duration), + new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, SecsChanged)); private static void SecsChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs e) { var (d, v) = (dpo as TextBlock, GetSecs(dpo)); - TimeSpan ts = TimeSpan.FromSeconds(v); - if (ts.Days > 0) { - d.Text = ts.ToString("d'.'hh':'mm':'ss"); - } else if (ts.Hours > 0) { - d.Text = ts.ToString("h':'mm':'ss"); + if (v.HasValue) { + TimeSpan ts = TimeSpan.FromSeconds(v.Value); + if (ts.Days > 0) { + d.Text = ts.ToString("d'.'hh':'mm':'ss"); + } else if (ts.Hours > 0) { + d.Text = ts.ToString("h':'mm':'ss"); + } else { + d.Text = ts.ToString("mm':'ss"); + } } else { - d.Text = ts.ToString("mm':'ss"); + d.Text = ""; } } - public static void SetSecs(DependencyObject dpo, double value) + public static void SetSecs(DependencyObject dpo, double? value) => dpo.SetValue(SecsProperty, value); - public static double GetSecs(DependencyObject dpo) - => (double)dpo.GetValue(SecsProperty); + public static double? GetSecs(DependencyObject dpo) + => (double?)dpo.GetValue(SecsProperty); + } } diff --git a/yt-dlp-gui/Controls/TextView.xaml.cs b/yt-dlp-gui/Controls/TextView.xaml.cs index f57b1a2..6336375 100644 --- a/yt-dlp-gui/Controls/TextView.xaml.cs +++ b/yt-dlp-gui/Controls/TextView.xaml.cs @@ -26,6 +26,9 @@ public partial class TextView : UserControl, ITextView { public static readonly DependencyProperty SyntaxProperty = DependencyProperty.RegisterAttached( "Syntax", typeof(string), typeof(TextView), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, onSyntaxChanged)); + public static readonly DependencyProperty EnableHyperlinksProperty = DependencyProperty.RegisterAttached( + "EnableHyperlinks", typeof(bool), typeof(TextView), + new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, onLinkChanged)); private static void onTextChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs e) { var d = (dpo as TextView); if (d != null) { @@ -40,6 +43,11 @@ public partial class TextView : UserControl, ITextView { var n = e.NewValue?.ToString() ?? ""; //d?.LoadDefinition(n); } + private static void onLinkChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs e) { + var d = (dpo as TextView); + d.textView.Options.EnableHyperlinks = d.EnableHyperlinks; + d.textView.Options.RequireControlModifierForHyperlinkClick = !d.EnableHyperlinks; + } public string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); @@ -52,6 +60,10 @@ public partial class TextView : UserControl, ITextView { get => (bool)GetValue(MultilineProperty); set => SetValue(MultilineProperty, value); } + public bool EnableHyperlinks { + get => (bool)GetValue(EnableHyperlinksProperty); + set => SetValue(EnableHyperlinksProperty, value); + } public IHighlightingDefinition SyntaxDefinition { set { textView.LineTransformers.Clear(); @@ -61,7 +73,7 @@ public partial class TextView : UserControl, ITextView { public TextView() { InitializeComponent(); textView.Document = new TextDocument(); - textView.Options.EnableHyperlinks = false; + textView.Options.EnableHyperlinks = EnableHyperlinks; } } public interface ITextView { diff --git a/yt-dlp-gui/Models/Chapters.cs b/yt-dlp-gui/Models/Chapters.cs new file mode 100644 index 0000000..c93bc5f --- /dev/null +++ b/yt-dlp-gui/Models/Chapters.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.ComponentModel; + +namespace yt_dlp_gui.Models { + public enum ChaptersType { + None, Split, Segment + } + public class Chapters : INotifyPropertyChanged { + public event PropertyChangedEventHandler? PropertyChanged; + public decimal start_time { get; set; } = 0; + public string title { get; set; } = string.Empty; + public decimal end_time { get; set; } = 0; + public ChaptersType type { get; set; } = ChaptersType.Segment; + } +} diff --git a/yt-dlp-gui/Models/Lang.cs b/yt-dlp-gui/Models/Lang.cs index 2309e08..865552a 100644 --- a/yt-dlp-gui/Models/Lang.cs +++ b/yt-dlp-gui/Models/Lang.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; namespace yt_dlp_gui.Models { public class Lang :INotifyPropertyChanged { @@ -20,10 +21,17 @@ public class LangMain :INotifyPropertyChanged { public string About { get; set; } = "About..."; //Tab Format public string Formats { get; set; } = "Formats"; + public string Chapters { get; set; } = "Chapters"; + public string ChaptersNone { get; set; } = "[None]"; + public string ChaptersAll { get; set; } = "[All]"; + public string ChaptersSplite { get; set; } = "[Split by Chapters]"; public string Video { get; set; } = "Video"; public string Audio { get; set; } = "Audio"; public string Subtitle { get; set; } = "Subtitle"; + public string SubtitleIgnore { get; set; } = "[Ignore]"; + public string SubtitleNone { get; set; } = "[None]"; public string VideoRes { get; set; } = "Resolution"; + public string VideoDynamicRange { get; set; } = "DR"; public string VideoFPS { get; set; } = "FPS"; public string VideoExt { get; set; } = "Ext."; public string VideoCodec { get; set; } = "Codec"; @@ -48,6 +56,9 @@ public class LangMain :INotifyPropertyChanged { public string RememberWindowState { get; set; } = "Remember Window State"; public string RememberWindowPosition { get; set; } = "Position"; public string RememberWindowSize { get; set; } = "Size"; + public string Proxy { get; set; } = "Proxy"; + public string ProxyEnabled { get; set; } = "Enabled"; + public string ProxyHelper { get; set; } = "socks5://user:pass@127.0.0.1:1080/"; public string Cookie { get; set; } = "Cookie"; public string CookieWhenNeeded { get; set; } = "When Needed"; public string CookieNever { get; set; } = "Never"; @@ -76,6 +87,7 @@ public class LangAbout :INotifyPropertyChanged { public string About { get; set; } = "About"; public string Website { get; set; } = "Website"; public string Authors { get; set; } = "Authors"; + public Dictionary Extends { get; set; } = new(); } public class LangReleases :INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; diff --git a/yt-dlp-gui/Models/Video.cs b/yt-dlp-gui/Models/Video.cs index 6da003b..2cdba9e 100644 --- a/yt-dlp-gui/Models/Video.cs +++ b/yt-dlp-gui/Models/Video.cs @@ -16,5 +16,6 @@ public class Video : INotifyPropertyChanged { public List requested_formats { get; set; } = new(); public string _filename { get; set; } = string.Empty; public bool is_live { get; set; } = false; + public List? chapters { get; set; } = null; } } diff --git a/yt-dlp-gui/Themes/CustomUI.xaml b/yt-dlp-gui/Themes/CustomUI.xaml index f6b324c..eabb4fd 100644 --- a/yt-dlp-gui/Themes/CustomUI.xaml +++ b/yt-dlp-gui/Themes/CustomUI.xaml @@ -57,6 +57,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -89,12 +182,14 @@ + - - - - + + + + + @@ -181,11 +276,12 @@ + - - - + + + diff --git a/yt-dlp-gui/ViewModels/Main.cs b/yt-dlp-gui/ViewModels/Main.cs index fd8ffec..1f6bf15 100644 --- a/yt-dlp-gui/ViewModels/Main.cs +++ b/yt-dlp-gui/ViewModels/Main.cs @@ -17,6 +17,13 @@ public partial class Main :Window { public class ViewData :INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; public ViewData() { + Chapters.PropertyChanged += (s, e) => { + switch (e.PropertyName) { + case nameof(ConcurrentObservableCollection.CollectionView): + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ChaptersView))); + break; + } + }; Formats.PropertyChanged += (s, e) => { switch (e.PropertyName) { case nameof(ConcurrentObservableCollection.CollectionView): @@ -109,6 +116,7 @@ public class ViewData :INotifyPropertyChanged { if (AutoSaveConfig) Util.PropertyCopy(this, GUIConfig); } public void SelectFormatBest() { + selectedChapter = Chapters.FirstOrDefault(); if (UseFormat) { selectedVideo = FormatsVideo.FirstOrDefault(); selectedAudio = FormatsAudio.FirstOrDefault(); @@ -140,6 +148,8 @@ public class ViewData :INotifyPropertyChanged { public Config selectedConfig { get; set; } = new(); public bool UseFormat { get; set; } = true; public bool UseOutput { get; set; } = true; + public ConcurrentObservableCollection Chapters { get; set; } = new(); + public IEnumerable ChaptersView => Chapters.CollectionView; public ConcurrentObservableCollection Formats { get; set; } = new(); public IEnumerable FormatsView => Formats.CollectionView.OrderBy(x => x.width * x.height); public IEnumerable FormatsVideo => Formats.CollectionView.Where(x => x.type == FormatType.package || x.type == FormatType.video).OrderBy(x => x, ComparerVideo.Comparer); @@ -149,6 +159,7 @@ public class ViewData :INotifyPropertyChanged { public IEnumerable ThumbnailsView => Thumbnails.CollectionView; public ConcurrentObservableCollection Subtitles { get; set; } = new(); public IEnumerable SubtitlesView => Subtitles.CollectionView; + public Chapters? selectedChapter { get; set; } = null; public Format selectedVideo { get; set; } = new(); public Format selectedAudio { get; set; } = new(); public Subs selectedSub { get; set; } = new(); @@ -163,6 +174,8 @@ public class ViewData :INotifyPropertyChanged { public double Left { get; set; } = 0; public double Width { get; set; } = 600; public double Height { get; set; } = 380; + public bool ProxyEnabled { get; set; } = false; + public string ProxyUrl { get; set; } = string.Empty; public bool CanCancel { get; set; } = false; public string Url { get; set; } = string.Empty; public string CommandLine { get; set; } = string.Empty; @@ -208,6 +221,7 @@ public class ViewData :INotifyPropertyChanged { private void CheckEnable() { Enable.Url = true; Enable.Analyze = true; + Enable.SelectChapters= true; Enable.FormatVideo = true; Enable.FormatAudio = true; Enable.Download = true; @@ -226,6 +240,7 @@ public class ViewData :INotifyPropertyChanged { if (IsAnalyze) { Enable.Url = false; Enable.Analyze = false; + Enable.SelectChapters= false; Enable.FormatVideo = false; Enable.FormatAudio = false; Enable.Download = false; @@ -241,6 +256,7 @@ public class ViewData :INotifyPropertyChanged { if (IsDownload) { Enable.Url = false; Enable.Analyze = false; + Enable.SelectChapters = false; Enable.FormatVideo = false; Enable.FormatAudio = false; Enable.Browser = false; @@ -254,6 +270,7 @@ public class ViewData :INotifyPropertyChanged { Enable.UseNotifications = false; Enable.UseAria2 = false; } + if (Video.chapters == null) Enable.SelectChapters = false; if (!FormatsVideo.Any()) { Enable.FormatVideo = false; Enable.SaveVideo = false; @@ -298,6 +315,7 @@ public class Enable :INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; public bool Url { get; set; } = true; public bool Analyze { get; set; } = true; + public bool SelectChapters { get; set; } = true; public bool FormatVideo { get; set; } = true; public bool FormatAudio { get; set; } = true; public bool Download { get; set; } = true; @@ -330,6 +348,9 @@ public class GUIConfig :IYamlConfig, INotifyPropertyChanged { public double Left { get; set; } = 0; public double Width { get; set; } = 600; public double Height { get; set; } = 380; + [Description("Proxy")] + public bool ProxyEnabled { get; set; } = false; + public string ProxyUrl { get; set; } = string.Empty; [Description("Use Cookie From Browser")] public UseCookie UseCookie { get; set; } = UseCookie.WhenNeeded; public CookieType CookieType { get; set; } = CookieType.Chrome; [Description("With Thumbnail When Downlaod")] public bool SaveThumbnail { get; set; } = true; diff --git a/yt-dlp-gui/Views/About.xaml b/yt-dlp-gui/Views/About.xaml index 4b3f5b5..5dec0c6 100644 --- a/yt-dlp-gui/Views/About.xaml +++ b/yt-dlp-gui/Views/About.xaml @@ -8,7 +8,8 @@ mc:Ignorable="d" Style="{DynamicResource DialogStyle}" WindowStartupLocation="CenterOwner" ShowInTaskbar="False" - Title="{Binding Source={x:Static app:App.Lang}, Path=About.About}" Height="150" Width="420"> + SizeToContent="Height" + Title="{Binding Source={x:Static app:App.Lang}, Path=About.About}" Width="420"> @@ -35,7 +36,7 @@ --> - + @@ -45,6 +46,24 @@ + + + + + + + + + + + + + + + + + + - + @@ -340,6 +399,7 @@ ItemsSource="{Binding FormatsAudio}">