Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: 新增音视频批量更改下载质量操作 #167

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions DownKyi/ViewModels/PageViewModels/VideoQuality.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using ImTools;
using Prism.Mvvm;

namespace DownKyi.ViewModels.PageViewModels;

public class VideoQuality : BindableBase
public class VideoQuality : BindableBase, IEquatable<VideoQuality>
{
private int quality;

Expand Down Expand Up @@ -42,4 +45,14 @@ public string SelectedVideoCodec
}
}
}

public bool Equals(VideoQuality? other)
{
if (other is null) return false;
return this.Quality == other.Quality;
}

public override bool Equals(object? obj) => Equals(obj as VideoQuality);

public override int GetHashCode() => quality.GetHashCode();
}
149 changes: 145 additions & 4 deletions DownKyi/ViewModels/ViewVideoDetailViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Reflection.Metadata;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.BiliApi.VideoStream;
using DownKyi.Core.Logging;
Expand All @@ -17,6 +21,7 @@
using DownKyi.Utils;
using DownKyi.ViewModels.Dialogs;
using DownKyi.ViewModels.PageViewModels;
using DownKyi.Views;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
Expand Down Expand Up @@ -121,14 +126,78 @@ public bool NoDataVisibility
set => SetProperty(ref _noDataVisibility, value);
}

public ObservableCollection<string> AvailableAudioQualities { get; set; } = new();
public ObservableCollection<VideoQuality> AvailableVideoQualities { get; set; } = new();

private bool _audioQualityPopupIsOpen;

private bool _videoQualityPopupIsOpen;

public bool VideoQualityPopupIsOpen
{
get => _videoQualityPopupIsOpen;
set => SetProperty(ref _videoQualityPopupIsOpen, value);
}

public bool AudioQualityPopupIsOpen
{
get => _audioQualityPopupIsOpen;
set => SetProperty(ref _audioQualityPopupIsOpen, value);
}

private bool _batchUpdateButtonIsVisible = false;

public bool BatchUpdateButtonIsVisible
{
get => _batchUpdateButtonIsVisible;
set => SetProperty(ref _batchUpdateButtonIsVisible, value);
}

private int _availableAudioIndex;

private int _availableVideoIndex;


public int AvailableVideoIndex
{
get { return _availableVideoIndex; }
set
{
if (_availableVideoIndex != value)
{
OnAvailableVideoIndexChanged(_availableVideoIndex, value);
SetProperty(ref _availableVideoIndex, value);
}
}

}

public int AvailableAudioIndex
{
get => _availableAudioIndex;
set
{
if(_availableAudioIndex != value)
{
OnAvailableAudioIndexChanged(_availableAudioIndex,value);
SetProperty(ref _availableAudioIndex, value);
}
}
}
#endregion

public ViewVideoDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator, dialogService)
{
// 初始化loading
Loading = true;
LoadingVisibility = false;

var mainWindow = Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime;
var window = mainWindow.MainWindow;
window.Deactivated += (s, e) =>
{
AudioQualityPopupIsOpen = false;
VideoQualityPopupIsOpen = false;
};
// 下载管理按钮
DownloadManage = ButtonIcon.Instance().DownloadManage;
DownloadManage.Height = 24;
Expand All @@ -146,6 +215,73 @@ public ViewVideoDetailViewModel(IEventAggregator eventAggregator, IDialogService

public DelegateCommand BackSpaceCommand => _backSpaceCommand ??= new DelegateCommand(ExecuteBackSpace);

public DelegateCommand BatchUpdateSelectedAudioQualityCommand => new DelegateCommand(BatchUpdateSelectedAudioQuality);

public DelegateCommand BatchUpdateSelectedVideoQualityCommand => new DelegateCommand(BatchUpdateSelectedVideoQuality);
private void BatchUpdateSelectedAudioQuality()
{
if (!BatchUpdateButtonIsVisible) return;
AudioQualityPopupIsOpen = !AudioQualityPopupIsOpen;
var section = VideoSections.FirstOrDefault(item => item.IsSelected);
var s = section?.VideoPages.Where(x => x.AudioQualityFormatList is not null && x.AudioQualityFormatList.Count > 0)
.Select(x => x.AudioQualityFormatList).FirstOrDefault();
if (s is null) return;
var difference = s.Except(AvailableAudioQualities);
AvailableAudioQualities.AddRange(difference.ToList());
}

private void BatchUpdateSelectedVideoQuality()
{
if (!BatchUpdateButtonIsVisible) return;
VideoQualityPopupIsOpen = !VideoQualityPopupIsOpen;
var section = VideoSections.FirstOrDefault(item => item.IsSelected);
var s = section?.VideoPages.Where(x => x.VideoQualityList is not null && x.VideoQualityList.Count > 0)
.Select(x => x.VideoQualityList).FirstOrDefault();
if (s is null) return;
var difference = s.Except(AvailableVideoQualities);
AvailableVideoQualities.AddRange(difference.ToList());
}
private void OnAvailableAudioIndexChanged(int oldVal,int newVal)
{
AudioQualityPopupIsOpen = false;
var section = VideoSections.FirstOrDefault(item => item.IsSelected);
if (section == null) return;

var isSelectAnyItem = section.VideoPages.Any(x => x.IsSelected);
var selectedQuality = AvailableAudioQualities[newVal];
var videoPages = section.VideoPages
.Where(x => isSelectAnyItem ? x.IsSelected : true)
.Where(x => x.AudioQualityFormatList?.Count > 0);
foreach (var sec in videoPages)
{
if (sec.AudioQualityFormatList.Contains(selectedQuality))
{
sec.AudioQualityFormat = selectedQuality;
}
}
}

private void OnAvailableVideoIndexChanged(int oldVal, int newVal)
{
VideoQualityPopupIsOpen = false;
var section = VideoSections.FirstOrDefault(item => item.IsSelected);
if (section == null) return;
var curr = AvailableVideoQualities[newVal];
var isSelectAnyItem = section.VideoPages.Any(x => x.IsSelected);
var videoPages = section.VideoPages
.Where(x => isSelectAnyItem ? x.IsSelected : true)
.Where(x => x.VideoQualityList?.Count > 0);
foreach (var sec in videoPages)
{
int index = sec.VideoQualityList.FindIndex(x => x.Quality == curr.Quality);
if(index != -1)
{
sec.VideoQuality = sec.VideoQualityList[index];
}
}
}


/// <summary>
/// 返回
/// </summary>
Expand Down Expand Up @@ -359,7 +495,10 @@ private void ExecuteVideoPagesCommand(IList parameter)
var avids = new HashSet<long>(parameter.Cast<VideoPage>().Select(x => x.Avid));
section.VideoPages.ToList().ForEach(videoPage =>
videoPage.IsSelected = avids.Contains(videoPage.Avid)
);
);
BatchUpdateButtonIsVisible = section.VideoPages.Count > 0
&& section.VideoPages.Any(x => x.VideoQualityList?.Count > 0
&& x.VideoQualityList?.Count > 0);
IsSelectAll = section.VideoPages.Count == videoPages.Count && section.VideoPages.Count != 0;
}

Expand Down Expand Up @@ -551,7 +690,7 @@ await Task.Run(() =>
{
AddToDownload(true);
}

BatchUpdateButtonIsVisible = true;
LogManager.Debug(Tag, $"ParseScope: {parseScope:G}");
}

Expand Down Expand Up @@ -587,7 +726,9 @@ private void InitView()
LoadingVisibility = true;
ContentVisibility = false;
NoDataVisibility = false;

VideoQualityPopupIsOpen = false;
AudioQualityPopupIsOpen = false;
BatchUpdateButtonIsVisible = false;
VideoSections.Clear();
CaCheVideoSections.Clear();
}
Expand Down
68 changes: 64 additions & 4 deletions DownKyi/Views/ViewVideoDetail.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,38 @@
Binding="{ReflectionBinding Duration}"
Header="{DynamicResource Duration}" />
<DataGridTemplateColumn
Width="120"
Header="{DynamicResource AudioQuality}">
Width="120">
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{DynamicResource AudioQuality}" />
<Button Width="15" Height="15"
IsVisible="{Binding BatchUpdateButtonIsVisible}"
Command="{Binding BatchUpdateSelectedAudioQualityCommand}"
Background="Transparent"
BorderThickness="0">
<Path Data="M 0,0 L 10,0 L 5,5 Z" Fill="{DynamicResource ColorTextDark}" />
</Button>
<Popup
IsOpen="{Binding AudioQualityPopupIsOpen}">
<Border Background="Transparent" BorderBrush="Black"
BorderThickness="1">
<StackPanel>
<ComboBox
Foreground="{DynamicResource BrushTextDark}"
Background="{DynamicResource BrushPrimary}"
ItemsSource="{Binding AvailableAudioQualities}"
SelectedIndex="{Binding AvailableAudioIndex,Mode=TwoWay}"
Width="120">

</ComboBox>
</StackPanel>
</Border>
</Popup>

</StackPanel>

</DataGridTemplateColumn.Header>

<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vmp:VideoPage">
<Grid>
Expand All @@ -388,8 +418,36 @@
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn
Width="120"
Header="{DynamicResource VideoQuality}">
Width="120" >
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{DynamicResource VideoQuality}" />
<Button Width="15" Height="15"
IsVisible="{Binding BatchUpdateButtonIsVisible}"
Command="{Binding BatchUpdateSelectedVideoQualityCommand}"
Background="Transparent"
BorderThickness="0">
<Path Data="M 0,0 L 10,0 L 5,5 Z" Fill="{DynamicResource ColorTextDark}" />
</Button>
<Popup
IsOpen="{Binding VideoQualityPopupIsOpen}">
<Border Background="Transparent" BorderBrush="Black"
BorderThickness="1">
<StackPanel>
<ComboBox
Foreground="{DynamicResource BrushTextDark}"
Background="{DynamicResource BrushPrimary}"
ItemsSource="{Binding AvailableVideoQualities}"
DisplayMemberBinding="{Binding QualityFormat}"
SelectedIndex="{Binding AvailableVideoIndex,Mode=TwoWay}"
Width="120">

</ComboBox>
</StackPanel>
</Border>
</Popup>
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vmp:VideoPage">
<Grid>
Expand Down Expand Up @@ -490,4 +548,6 @@
IsVisible="{Binding NoDataVisibility}" />

</Grid>


</UserControl>