发布v1.5.0-alpha2

pull/252/head v1.5.0-alpha2
leiurayer 3 years ago
parent 9b320cf3cf
commit cf41095725

@ -1,5 +1,12 @@
# 更新日志
* `2022/03/07` v1.5.0-alpha2
1. [优化] 重构程序架构,解决一些已知问题。
2. [优化] 界面UI的显示与操作。
3. [新增] 文件命名格式avid、bvid、cid、UP主信息、视频发布时间。
4. [修复] 视频音质列表导致的闪退问题。
5. [修复] 图片下载导致的闪退问题。
* `2022/03/05` v1.5.0-alpha1
1. [优化] 重构程序架构,解决一些已知问题。
2. [新增] 最高支持8K视频。

@ -9,22 +9,19 @@
[全部更新日志](CHANGELOG.md)
* `2022/03/05` v1.5.0-alpha1
* `2022/03/07` v1.5.0-alpha2
1. [优化] 重构程序架构,解决一些已知问题。
2. [新增] 最高支持8K视频。
3. [新增] 支持杜比全景声和杜比视界。
4. [新增] 支持字幕下载。
5. [新增] 支持部分短链接(如 https://b23.tv/BV17x411w7KC )。
6. [新增] 下载内容可选,可根据需要选择下载视频、音频、弹幕、字幕、封面。
7. [新增] 下载文件命名模块,可自主设置文件名。
2. [优化] 界面UI的显示与操作。
3. [新增] 文件命名格式avid、bvid、cid、UP主信息、视频发布时间。
4. [修复] 视频音质列表导致的闪退问题。
5. [修复] 图片下载导致的闪退问题。
## 下载
- [哔哩下载姬最新版](https://github.com/FlySelfLog/downkyi/releases/download/v1.5.0-alpha1/DownKyi-1.5.0-alpha1.zip)
- [哔哩下载姬最新版](https://github.com/FlySelfLog/downkyi/releases/download/v1.5.0-alpha2/DownKyi-1.5.0-alpha2.zip)
- [下载页面](https://github.com/FlySelfLog/downkyi/releases)
## 赞助
如果这个项目对您有很大帮助,并且您希望支持该项目的开发和维护,请随时扫描一下二维码进行捐赠。非常感谢您的捐款,谢谢!

@ -33,7 +33,10 @@ namespace DownKyi.Core.BiliApi.BiliUtils
/// <returns></returns>
public static List<Quality> GetResolutions()
{
return resolutions;
// 使用深复制,
// 保证外部修改list后
// 不会影响其他调用处
return new List<Quality>(resolutions);
}
/// <summary>
@ -42,7 +45,10 @@ namespace DownKyi.Core.BiliApi.BiliUtils
/// <returns></returns>
public static List<Quality> GetAudioQualities()
{
return qualities;
// 使用深复制,
// 保证外部修改list后
// 不会影响其他调用处
return new List<Quality>(qualities);
}
}

@ -7,13 +7,13 @@ namespace DownKyi.Core.BiliApi.BiliUtils
/// 解析输入的字符串<para/>
/// 支持的格式有:<para/>
/// av号av170001, AV170001, https://www.bilibili.com/video/av170001 <para/>
/// BV号BV17x411w7KC, https://www.bilibili.com/video/BV17x411w7KC <para/>
/// BV号BV17x411w7KC, https://www.bilibili.com/video/BV17x411w7KC, https://b23.tv/BV17x411w7KC <para/>
/// 番剧电影、电视剧ss号ss32982, SS32982, https://www.bilibili.com/bangumi/play/ss32982 <para/>
/// 番剧电影、电视剧ep号ep317925, EP317925, https://www.bilibili.com/bangumi/play/ep317925 <para/>
/// 番剧电影、电视剧md号md28228367, MD28228367, https://www.bilibili.com/bangumi/media/md28228367 <para/>
/// 课程ss号https://www.bilibili.com/cheese/play/ss205 <para/>
/// 课程ep号https://www.bilibili.com/cheese/play/ep3489 <para/>
/// 收藏夹ml1329019876, ML1329019876, https://www.bilibili.com/medialist/detail/ml1329019876 <para/>
/// 收藏夹ml1329019876, ML1329019876, https://www.bilibili.com/medialist/detail/ml1329019876, https://www.bilibili.com/medialist/play/ml1329019876/ <para/>
/// 用户空间uid928123, UID928123, uid:928123, UID:928123, https://space.bilibili.com/928123
/// </summary>
public static class ParseEntrance

@ -15,6 +15,15 @@ namespace DownKyi.Core.FileName
private string videoQuality = "VIDEO_QUALITY";
private string videoCodec = "VIDEO_CODEC";
private string videoPublishTime = "VIDEO_PUBLISH_TIME";
private long avid = -1;
private string bvid = "BVID";
private long cid = -1;
private long upMid = -1;
private string upName = "UP_NAME";
private FileName(List<FileNamePart> nameParts)
{
this.nameParts = nameParts;
@ -73,6 +82,42 @@ namespace DownKyi.Core.FileName
return this;
}
public FileName SetVideoPublishTime(string videoPublishTime)
{
this.videoPublishTime = videoPublishTime;
return this;
}
public FileName SetAvid(long avid)
{
this.avid = avid;
return this;
}
public FileName SetBvid(string bvid)
{
this.bvid = bvid;
return this;
}
public FileName SetCid(long cid)
{
this.cid = cid;
return this;
}
public FileName SetUpMid(long upMid)
{
this.upMid = upMid;
return this;
}
public FileName SetUpName(string upName)
{
this.upName = upName;
return this;
}
public string RelativePath()
{
string path = string.Empty;
@ -112,6 +157,24 @@ namespace DownKyi.Core.FileName
case FileNamePart.VIDEO_CODEC:
path += videoCodec;
break;
case FileNamePart.VIDEO_PUBLISH_TIME:
path += videoPublishTime;
break;
case FileNamePart.AVID:
path += avid;
break;
case FileNamePart.BVID:
path += bvid;
break;
case FileNamePart.CID:
path += cid;
break;
case FileNamePart.UP_MID:
path += upMid;
break;
case FileNamePart.UP_NAME:
path += upName;
break;
}
if (((int)part) >= 100)

@ -12,6 +12,15 @@
VIDEO_QUALITY,
VIDEO_CODEC,
VIDEO_PUBLISH_TIME,
AVID,
BVID,
CID,
UP_MID,
UP_NAME,
// 斜杠
SLASH = 100,

@ -165,12 +165,14 @@ namespace DownKyi.Core.Storage
{
string destFile = $"{StorageManager.GetCover()}/{md5}";
// 如果不存在
if (!File.Exists(destFile))
try
{
// 移动到指定位置
File.Move(localFile, destFile);
File.Delete(destFile);
}
catch { }
// 移动到指定位置
File.Move(localFile, destFile);
return md5;
}

@ -28,7 +28,7 @@ namespace DownKyi.Core.Storage
public BitmapImage GetHeaderThumbnail(long mid, string name, string url, int width, int height)
{
string header = GetHeader(mid, name, url);
if(header == null) { return null; }
if (header == null) { return null; }
return GetHeaderThumbnail(header, width, height);
}
@ -42,6 +42,8 @@ namespace DownKyi.Core.Storage
/// <returns></returns>
public BitmapImage GetHeaderThumbnail(string header, int width, int height)
{
if (header == null) { return null; }
var bitmap = new Bitmap(header);
var thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero);
@ -141,7 +143,16 @@ namespace DownKyi.Core.Storage
if (File.Exists(localFile))
{
File.Move(localFile, $"{StorageManager.GetHeader()}/{md5}");
string destFile = $"{StorageManager.GetHeader()}/{md5}";
try
{
File.Delete(destFile);
}
catch { }
// 移动到指定位置
File.Move(localFile, destFile);
return md5;
}

@ -214,7 +214,10 @@
<system:String x:Key="DisplayAudioQuality">音质</system:String>
<system:String x:Key="DisplayVideoQuality">画质</system:String>
<system:String x:Key="DisplayVideoCodec">视频编码</system:String>
<system:String x:Key="DisplayVideoPublishTime">视频发布时间</system:String>
<system:String x:Key="DisplaySpace">空格</system:String>
<system:String x:Key="DisplayUpMid">UP主ID</system:String>
<system:String x:Key="DisplayUpName">UP主昵称</system:String>
<system:String x:Key="Reset">恢复默认</system:String>
<system:String x:Key="SettingDanmaku">弹幕</system:String>

@ -3,12 +3,12 @@
public class AppInfo
{
public string Name { get; } = "哔哩下载姬";
public int VersionCode { get; } = 500;
public int VersionCode { get; } = 501;
#if DEBUG
public string VersionName { get; } = "1.5.0-alpha1 Debug";
public string VersionName { get; } = "1.5.0-alpha2 Debug";
#else
public string VersionName { get; } = "1.5.0-alpha1";
public string VersionName { get; } = "1.5.0-alpha2";
#endif
}

@ -99,6 +99,32 @@ namespace DownKyi.Services
Name = name,
Duration = "N/A"
};
// UP主信息
if (bangumiSeason.UpInfo != null)
{
page.Owner = new Core.BiliApi.Models.VideoOwner
{
Name = bangumiSeason.UpInfo.Name,
Face = bangumiSeason.UpInfo.Avatar,
Mid = bangumiSeason.UpInfo.Mid,
};
}
else
{
page.Owner = new Core.BiliApi.Models.VideoOwner
{
Name = "",
Face = "",
Mid = -1,
};
}
// 视频发布时间
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
DateTime dateTime = startTime.AddSeconds(episode.PubTime);
page.PublishTime = dateTime.ToString("yyyy-MM-dd");
pages.Add(page);
}

@ -67,6 +67,32 @@ namespace DownKyi.Services
Name = name,
Duration = "N/A"
};
// UP主信息
if (cheeseView.UpInfo != null)
{
page.Owner = new Core.BiliApi.Models.VideoOwner
{
Name = cheeseView.UpInfo.Name,
Face = cheeseView.UpInfo.Avatar,
Mid = cheeseView.UpInfo.Mid,
};
}
else
{
page.Owner = new Core.BiliApi.Models.VideoOwner
{
Name = "",
Face = "",
Mid = -1,
};
}
// 视频发布时间
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
DateTime dateTime = startTime.AddSeconds(episode.ReleaseDate);
page.PublishTime = dateTime.ToString("yyyy-MM-dd");
pages.Add(page);
}

@ -294,7 +294,13 @@ namespace DownKyi.Services.Download
.SetVideoZone(videoInfoView.VideoZone.Split('>')[0])
.SetAudioQuality(page.AudioQualityFormat)
.SetVideoQuality(page.VideoQuality == null ? "" : page.VideoQuality.QualityFormat)
.SetVideoCodec(page.VideoQuality == null ? "" : page.VideoQuality.SelectedVideoCodec.Contains("AVC") ? "AVC" : page.VideoQuality.SelectedVideoCodec.Contains("HEVC") ? "HEVC" : page.VideoQuality.SelectedVideoCodec.Contains("Dolby") ? "Dolby Vision" : "");
.SetVideoCodec(page.VideoQuality == null ? "" : page.VideoQuality.SelectedVideoCodec.Contains("AVC") ? "AVC" : page.VideoQuality.SelectedVideoCodec.Contains("HEVC") ? "HEVC" : page.VideoQuality.SelectedVideoCodec.Contains("Dolby") ? "Dolby Vision" : "")
.SetVideoPublishTime(page.PublishTime)
.SetAvid(page.Avid)
.SetBvid(page.Bvid)
.SetCid(page.Cid)
.SetUpMid(page.Owner.Mid)
.SetUpName(page.Owner.Name);
string filePath = Path.Combine(directory, fileName.RelativePath());
// 视频类别

@ -11,7 +11,7 @@ namespace DownKyi.Services
/// 解析支持的输入,
/// 支持的格式有:<para/>
/// av号av170001, AV170001, https://www.bilibili.com/video/av170001 <para/>
/// BV号BV17x411w7KC, https://www.bilibili.com/video/BV17x411w7KC <para/>
/// BV号BV17x411w7KC, https://www.bilibili.com/video/BV17x411w7KC, https://b23.tv/BV17x411w7KC <para/>
/// 番剧电影、电视剧ss号ss32982, SS32982, https://www.bilibili.com/bangumi/play/ss32982 <para/>
/// 番剧电影、电视剧ep号ep317925, EP317925, https://www.bilibili.com/bangumi/play/ep317925 <para/>
/// 番剧电影、电视剧md号md28228367, MD28228367, https://www.bilibili.com/bangumi/media/md28228367 <para/>

@ -165,7 +165,10 @@ namespace DownKyi.Services
if (videoQualityExist == null)
{
List<string> videoCodecList = new List<string>();
ListHelper.AddUnique(videoCodecList, codecName);
if (codecName != string.Empty)
{
ListHelper.AddUnique(videoCodecList, codecName);
}
VideoQuality videoQuality = new VideoQuality()
{
@ -179,12 +182,24 @@ namespace DownKyi.Services
{
if (!videoQualityList[videoQualityList.IndexOf(videoQualityExist)].VideoCodecList.Exists(t => t.Equals(codecName)))
{
videoQualityList[videoQualityList.IndexOf(videoQualityExist)].VideoCodecList.Add(codecName);
if (codecName != string.Empty)
{
videoQualityList[videoQualityList.IndexOf(videoQualityExist)].VideoCodecList.Add(codecName);
}
}
}
// 设置选中的视频编码
VideoQuality selectedVideoQuality = videoQualityList.FirstOrDefault(t => t.Quality == video.Id);
if(selectedVideoQuality == null) { continue; }
if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Count == 1)
{
// 当获取的视频没有设置的视频编码时,执行
videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList[0];
}
// 设置选中的视频编码
switch (videoCodecs)
{
case VideoCodecs.AVC:
@ -205,11 +220,6 @@ namespace DownKyi.Services
break;
}
if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Count == 1)
{
// 当获取的视频没有设置的视频编码时,执行
videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList[0];
}
}
return videoQualityList;

@ -83,6 +83,24 @@ namespace DownKyi.Services
Name = name,
Duration = "N/A"
};
// UP主信息
videoPage.Owner = videoView.Owner;
if (videoPage.Owner == null)
{
videoPage.Owner = new Core.BiliApi.Models.VideoOwner
{
Name = "",
Face = "",
Mid = -1,
};
}
// 视频发布时间
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
DateTime dateTime = startTime.AddSeconds(videoView.Pubdate);
videoPage.PublishTime = dateTime.ToString("yyyy-MM-dd");
videoPages.Add(videoPage);
}

@ -1,8 +1,11 @@
using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.BiliApi.Models;
using DownKyi.Core.BiliApi.VideoStream.Models;
using DownKyi.Core.Logging;
using DownKyi.Core.Utils;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@ -16,6 +19,8 @@ namespace DownKyi.ViewModels.PageViewModels
public string Bvid { get; set; }
public long Cid { get; set; }
public long EpisodeId { get; set; }
public VideoOwner Owner { get; set; }
public string PublishTime { get; set; }
public string FirstFrame { get; set; }
@ -87,7 +92,18 @@ namespace DownKyi.ViewModels.PageViewModels
private void ExecuteVideoQualitySelectedCommand()
{
// 杜比视界
string dolby = Constant.GetAudioQualities()[3].Name;
string dolby = string.Empty;
try
{
var qualities = Constant.GetAudioQualities();
dolby = qualities[3].Name;
}
catch (Exception e)
{
Core.Utils.Debugging.Console.PrintLine("ExecuteVideoQualitySelectedCommand()发生异常: {0}", e);
LogManager.Error("ExecuteVideoQualitySelectedCommand", e);
}
if (VideoQuality != null && VideoQuality.Quality == 126)
{
ListHelper.AddUnique(AudioQualityFormatList, dolby);
@ -101,7 +117,6 @@ namespace DownKyi.ViewModels.PageViewModels
AudioQualityFormat = AudioQualityFormatList[0];
}
}
}
#endregion

@ -469,6 +469,24 @@ namespace DownKyi.ViewModels.Settings
case FileNamePart.VIDEO_CODEC:
display = DictionaryResource.GetString("DisplayVideoCodec");
break;
case FileNamePart.VIDEO_PUBLISH_TIME:
display = DictionaryResource.GetString("DisplayVideoPublishTime");
break;
case FileNamePart.AVID:
display = "avid";
break;
case FileNamePart.BVID:
display = "bvid";
break;
case FileNamePart.CID:
display = "cid";
break;
case FileNamePart.UP_MID:
display = DictionaryResource.GetString("DisplayUpMid");
break;
case FileNamePart.UP_NAME:
display = DictionaryResource.GetString("DisplayUpName");
break;
}
if (((int)item) >= 100)

@ -297,6 +297,7 @@ namespace DownKyi.ViewModels
}
Medias.Clear();
IsSelectAll = false;
LoadingVisibility = Visibility.Visible;
NoDataVisibility = Visibility.Collapsed;

@ -190,6 +190,9 @@ namespace DownKyi.ViewModels
{
if (!(parameter is TabHeader tabHeader)) { return; }
// 顶部tab点击后隐藏Content
ContentVisibility = Visibility.Collapsed;
// 页面选择
Pager = new CustomPagerViewModel(1, 1);
Pager.CurrentChanged += OnCurrentChanged_Pager;
@ -354,6 +357,8 @@ namespace DownKyi.ViewModels
private async void UpdateBangumiMediaList(int current)
{
Medias.Clear();
IsSelectAll = false;
LoadingVisibility = Visibility.Visible;
NoDataVisibility = Visibility.Collapsed;

@ -80,6 +80,14 @@ namespace DownKyi.ViewModels
set => SetProperty(ref mediaLoading, value);
}
private Visibility mediaContentVisibility;
public Visibility MediaContentVisibility
{
get => mediaContentVisibility;
set => SetProperty(ref mediaContentVisibility, value);
}
private Visibility mediaLoadingVisibility;
public Visibility MediaLoadingVisibility
{
@ -211,6 +219,9 @@ namespace DownKyi.ViewModels
{
if (!(parameter is TabHeader tabHeader)) { return; }
// tab点击后隐藏MediaContent
MediaContentVisibility = Visibility.Collapsed;
// 页面选择
Pager = new CustomPagerViewModel(1, (int)Math.Ceiling(double.Parse(tabHeader.SubTitle) / VideoNumberInPage));
Pager.CurrentChanged += OnCurrentChanged_Pager;
@ -375,6 +386,8 @@ namespace DownKyi.ViewModels
private async void UpdateFavoritesMediaList(int current)
{
Medias.Clear();
IsSelectAll = false;
MediaLoadingVisibility = Visibility.Visible;
MediaNoDataVisibility = Visibility.Collapsed;
@ -391,11 +404,13 @@ namespace DownKyi.ViewModels
List<Core.BiliApi.Favorites.Models.FavoritesMedia> medias = FavoritesResource.GetFavoritesMedia(tab.Id, current, VideoNumberInPage);
if (medias == null || medias.Count == 0)
{
MediaContentVisibility = Visibility.Visible;
MediaLoadingVisibility = Visibility.Collapsed;
MediaNoDataVisibility = Visibility.Visible;
return;
}
MediaContentVisibility = Visibility.Visible;
MediaLoadingVisibility = Visibility.Collapsed;
MediaNoDataVisibility = Visibility.Collapsed;

@ -334,6 +334,7 @@ namespace DownKyi.ViewModels
}
Medias.Clear();
IsSelectAll = false;
LoadingVisibility = Visibility.Visible;
NoDataVisibility = Visibility.Collapsed;

@ -221,7 +221,10 @@
</i:Interaction.Triggers>
</ListBox>
<Grid Name="nameMediaPanel" Grid.Column="1">
<Grid
Name="nameMediaPanel"
Grid.Column="1"
Visibility="{Binding MediaContentVisibility}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="1" />
@ -268,27 +271,6 @@
</ListBox.Style>
</ListBox>
<!-- 加载gif -->
<StackPanel
Grid.Row="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical"
Visibility="{Binding MediaLoadingVisibility}">
<ContentControl
Width="40"
Height="40"
Content="{Binding MediaLoading}" />
</StackPanel>
<!-- 没有数据提示 -->
<Image
Grid.Row="0"
Width="256"
Height="256"
Source="/DownKyi;component/Resources/no-data.png"
Visibility="{Binding MediaNoDataVisibility}" />
<TextBlock Grid.Row="1" Background="{DynamicResource BrushBorder}" />
<Grid Grid.Row="2">
@ -340,6 +322,28 @@
Style="{StaticResource BtnStyle}" />
</Grid>
</Grid>
<!-- 加载gif -->
<StackPanel
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical"
Visibility="{Binding MediaLoadingVisibility}">
<ContentControl
Width="40"
Height="40"
Content="{Binding MediaLoading}" />
</StackPanel>
<!-- 没有数据提示 -->
<Image
Grid.Column="1"
Width="256"
Height="256"
Source="/DownKyi;component/Resources/no-data.png"
Visibility="{Binding MediaNoDataVisibility}" />
</Grid>
<!-- 加载gif -->

@ -16,6 +16,8 @@
- [x] 支持封面下载
- [x] 支持自定义文件命名
- [x] 支持断点续传
- [x] 支持Aria2c
@ -60,7 +62,7 @@
目前已支持的有:
- [x] av号av170001https://www.bilibili.com/video/av170001
- [x] BV号BV17x411w7KChttps://www.bilibili.com/video/BV17x411w7KC
- [x] BV号BV17x411w7KChttps://www.bilibili.com/video/BV17x411w7KC, https://b23.tv/BV17x411w7KC
- [x] 番剧电影、电视剧ss号https://www.bilibili.com/bangumi/play/ss32982
- [x] 番剧电影、电视剧ep号https://www.bilibili.com/bangumi/play/ep317925
- [x] 番剧电影、电视剧md号https://www.bilibili.com/bangumi/media/md28228367

Loading…
Cancel
Save