完善下载服务中,20211221暂存

croire 3 years ago
parent 966b707165
commit 7c43873e87

@ -18,5 +18,19 @@ namespace DownKyi.Core.BiliApi.Bangumi
{ 10, "Unknown" }
};
public static Dictionary<int, int> TypeId = new Dictionary<int, int>()
{
{ 1, 13 },
{ 2, 23 },
{ 3, 177 },
{ 4, 167 },
{ 5, 11 },
{ 6, -1 },
{ 7, -1 },
{ 8, -1 },
{ 9, -1 },
{ 10, -1 }
};
}
}

@ -14,5 +14,15 @@ namespace DownKyi.Core.BiliApi.BiliUtils
{ 30280, "192K" }
};
/// <summary>
/// 音质id及含义
/// </summary>
public static Dictionary<string, int> AudioQualityId { get; } = new Dictionary<string, int>()
{
{ "64K", 30216 },
{ "132K", 30232 },
{ "192K", 30280 }
};
}
}

@ -21,5 +21,7 @@ namespace DownKyi.Core.BiliApi.Video.Models
public string Weblink { get; set; }
[JsonProperty("dimension")]
public Dimension Dimension { get; set; }
[JsonProperty("first_frame")]
public string FirstFrame { get; set; }
}
}

@ -37,7 +37,8 @@ namespace DownKyi.Core.BiliApi.VideoStream
}
/// <summary>
/// 获取所有字幕
/// 获取所有字幕<br/>
/// 若视频没有字幕返回null
/// </summary>
/// <param name="avid"></param>
/// <param name="bvid"></param>
@ -48,8 +49,12 @@ namespace DownKyi.Core.BiliApi.VideoStream
List<SubRipText> subRipTexts = new List<SubRipText>();
// 获取播放器信息
var player = PlayerV2(avid, bvid, cid);
PlayerV2 player = PlayerV2(avid, bvid, cid);
if (player == null) { return subRipTexts; }
if (player.Subtitle != null && player.Subtitle.Subtitles != null && player.Subtitle.Subtitles.Count == 0)
{
return null;
}
foreach (var subtitle in player.Subtitle.Subtitles)
{

@ -34,6 +34,9 @@
{
switch (tid)
{
// 课堂
case -10:
return "Zone.cheeseDrawingImage";
case 1:
return "Zone.dougaDrawingImage";
case 13:

@ -46,6 +46,21 @@
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="Zone.cheeseDrawingImage">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V128 H128 V0 H0 Z">
<GeometryDrawing Brush="#FFFBC92A" Geometry="F1 M128,128z M0,0z M105.8,0C109.2,0 112.3,0.9 115.2,2.6 118.1,4.3 120.3,6.6 122,9.5 123.7,12.4 124.5,15.5 124.5,19L124.5,108.9C124.5,112.4 123.7,115.6 122,118.4 120.3,121.3 118,123.6 115.2,125.3 112.4,127 109.2,127.9 105.8,127.9L61.6,127.9C61.6,126.6 60.6,125.4 58.7,124.4 56.8,123.4 54.5,122.9 51.9,122.9 49.3,122.9 47,123.4 45.1,124.4 43.2,125.4 42.2,126.6 42.2,127.9L22.2,127.9C18.8,127.9 15.7,127 12.8,125.3 9.9,123.6 7.7,121.3 6,118.4 4.3,115.5 3.5,112.4 3.5,108.9L3.5,19.1C3.6,15.6 4.5,12.4 6.1,9.6 7.7,6.8 10,4.4 12.8,2.7 15.7,1 18.8,0.100000000000001 22.2,0.100000000000001L105.8,0.100000000000001 105.8,0z" />
<GeometryDrawing Brush="#FFFFEA85" Geometry="F1 M128,128z M0,0z M105.8,0C109.2,0 112.3,0.9 115.2,2.6 118.1,4.3 120.3,6.6 122,9.5 123.7,12.4 124.5,15.5 124.5,19L124.5,54.2C120.2,54.7 116.7,55.5 114,56.9 111.3,58.3 110,59.8 110,61.5 110,63.2 111.3,64.7 114,66.1 116.7,67.4 120.2,68.3 124.5,68.6L124.5,74.5C124.5,78 123.7,81.2 122,84 120.3,86.9 118,89.1 115.2,90.8 112.4,92.5 109.2,93.3 105.8,93.3L22.2,93.3C18.8,93.3 15.7,92.5 12.8,90.8 9.9,89.1 7.7,86.8 6,84 4.3,81.1 3.5,78 3.5,74.5L3.5,19.1C3.6,15.6 4.5,12.4 6.1,9.6 7.7,6.8 10,4.4 12.8,2.7 15.7,1 18.8,0.100000000000001 22.2,0.100000000000001L105.8,0 105.8,0z" />
<GeometryDrawing Brush="#FFFBC92A" Geometry="F1 M128,128z M0,0z M32.6,93.4C32.6,95.2 33.4,96.9 35.1,98.4 36.8,99.9 39.1,101.1 42.1,102 45.1,102.9 48.3,103.3 51.9,103.3 55.4,103.3 58.7,102.9 61.6,102 64.5,101.1 66.9,99.9 68.6,98.4 70.3,96.9 71.2,95.3 71.2,93.5 71.2,91.8 70.3,90.1 68.6,88.6 66.9,87.1 64.5,85.9 61.6,85 58.7,84.1 55.4,83.7 51.9,83.7 48.4,83.7 45.1,84.1 42.1,85 39.1,85.9 36.8,87.1 35.1,88.6 33.5,90.1 32.6,91.7 32.6,93.4L32.6,93.4z" />
<GeometryDrawing Brush="#FFF4B828" Geometry="F1 M128,128z M0,0z M18.1,113.2C18.1,115.2 18.8,116.9 20.2,118.3 21.6,119.6 23.3,120.3 25.3,120.3 27.3,120.3 29,119.6 30.4,118.3 31.9,117 32.6,115.3 32.6,113.3 32.6,111.3 31.9,109.6 30.4,108.2 28.9,106.8 27.2,106.1 25.3,106.1 23.4,106.1 21.6,106.8 20.2,108.2 18.8,109.6 18.1,111.2 18.1,113.2L18.1,113.2z" />
<GeometryDrawing Brush="#FFF4B828" Geometry="F1 M128,128z M0,0z M56.7,113.2C56.7,115.2 57.9,116.9 60.2,118.3 62.5,119.7 65.4,120.3 68.7,120.3 72,120.3 74.9,119.6 77.3,118.3 79.7,117 80.9,115.3 80.9,113.3 80.9,111.3 79.7,109.6 77.3,108.2 74.9,106.8 72,106.1 68.7,106.1 65.4,106.1 62.5,106.8 60.2,108.2 57.9,109.6 56.7,111.2 56.7,113.2L56.7,113.2z" />
<GeometryDrawing Brush="#FFF0BF4C" Geometry="F1 M128,128z M0,0z M87.9,58.2C88.8,57.3 89.9,56.9 91.2,56.9 92.5,57 93.6,57.5 94.4,58.4 95.2,59.3 95.7,60.5 95.7,61.8 95.7,63.1 95.2,64.2 94.2,65.1 89.1,70 83.2,73.4 76.5,75.1 69.8,76.8 63,76.8 56.3,75.1 49.6,73.4 43.6,70 38.4,65.1 37.5,64.2 37,63.1 37,61.8 36.9,60.5 37.4,59.4 38.3,58.4 39.2,57.4 40.3,56.9 41.6,56.9 42.9,56.8 44,57.3 44.9,58.2 48.8,62 53.4,64.6 58.6,66 63.8,67.3 69,67.3 74.2,66 79.4,64.7 83.9,62 87.9,58.2L87.9,58.2z" />
<GeometryDrawing Brush="#FFF0BF4C" Geometry="F1 M128,128z M0,0z M98.1,23.8L98.9,23.8C100.8,23.8 102.5,24.5 103.9,25.9 105.3,27.3 106,29 105.8,30.9L105.8,40.3C105.8,42.3 105.1,44 103.8,45.4 102.5,46.8 100.8,47.5 98.9,47.5L98.1,47.5C96.1,47.4 94.4,46.7 93,45.3 91.6,43.9 91,42.3 91,40.2L91,30.8C91,28.9 91.7,27.2 93.1,25.8 94.5,24.5 96.2,23.8 98.1,23.8z" />
<GeometryDrawing Brush="#FFF0BF4C" Geometry="F1 M128,128z M0,0z M33.8,23.8L34.6,23.8C36.5,23.8 38.2,24.5 39.6,25.9 41,27.3 41.7,29 41.5,30.9L41.5,40.3C41.5,42.3 40.8,44 39.5,45.4 38.2,46.8 36.5,47.5 34.6,47.5L33.8,47.5C31.8,47.4 30.1,46.7 28.7,45.3 27.4,44 26.7,42.3 26.7,40.2L26.7,30.8C26.7,28.9 27.4,27.2 28.8,25.8 30.2,24.5 31.9,23.8 33.8,23.8z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="Zone.cinephileDrawingImage">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V1024 H1024 V0 H0 Z">

@ -1,4 +1,6 @@
namespace DownKyi.Core.Utils
using System.Text.RegularExpressions;
namespace DownKyi.Core.Utils
{
public static class Format
{
@ -164,5 +166,39 @@
return formatFileSize;
}
/// <summary>
/// 去除非法字符
/// </summary>
/// <param name="originName"></param>
/// <returns></returns>
public static string FormatFileName(string originName)
{
string destName = originName;
// Windows中不能作为文件名的字符
destName = destName.Replace("\\", " ");
destName = destName.Replace("/", " ");
destName = destName.Replace(":", " ");
destName = destName.Replace("*", " ");
destName = destName.Replace("?", " ");
destName = destName.Replace("\"", " ");
destName = destName.Replace("<", " ");
destName = destName.Replace(">", " ");
destName = destName.Replace("|", " ");
// 转义字符
destName = destName.Replace("\a", "");
destName = destName.Replace("\b", "");
destName = destName.Replace("\f", "");
destName = destName.Replace("\n", "");
destName = destName.Replace("\r", "");
destName = destName.Replace("\t", "");
destName = destName.Replace("\v", "");
// 控制字符
destName = Regex.Replace(destName, @"\p{C}+", string.Empty);
return destName.Trim();
}
}
}

@ -43,76 +43,6 @@ namespace DownKyi
DownloadingList = new ObservableCollection<DownloadingItem>();
DownloadedList = new ObservableCollection<DownloadedItem>();
// test DownloadingList data
DownloadingList.Add(new DownloadingItem
{
MainTitle = "Test1",
Name = "name1=name1=name1=name1=name1=name1=name1=name1=name1=name1=name1",
ZoneImage = (System.Windows.Media.DrawingImage)Current.Resources[Core.BiliApi.Zone.VideoZoneIcon.Instance().GetZoneImageKey(4)],
Resolution = new Resolution
{
Name = "1080P",
Id = 64
},
AudioCodecName = "194K",
});
DownloadingList.Add(new DownloadingItem
{
MainTitle = "Test2",
Name = "name2",
ZoneImage = (System.Windows.Media.DrawingImage)Current.Resources[Core.BiliApi.Zone.VideoZoneIcon.Instance().GetZoneImageKey(3)],
Resolution = new Resolution
{
Name = "1080P",
Id = 64
},
Duration = "1h23m50s",
VideoCodecName = "HEVC",
AudioCodecName = "194K",
});
DownloadingList.Add(new DownloadingItem
{
MainTitle = "Test3",
Name = "name3",
ZoneImage = (System.Windows.Media.DrawingImage)Current.Resources[Core.BiliApi.Zone.VideoZoneIcon.Instance().GetZoneImageKey(3)],
Resolution = new Resolution
{
Name = "720P",
Id = 64
},
Duration = "23m50s",
VideoCodecName = "AVC",
AudioCodecName = "194K",
});
DownloadingList.Add(new DownloadingItem
{
MainTitle = "Test4",
Name = "name4",
ZoneImage = (System.Windows.Media.DrawingImage)Current.Resources[Core.BiliApi.Zone.VideoZoneIcon.Instance().GetZoneImageKey(3)],
Resolution = new Resolution
{
Name = "720P",
Id = 64
},
Duration = "23m50s",
VideoCodecName = "AVC",
AudioCodecName = "194K",
});
DownloadingList.Add(new DownloadingItem
{
MainTitle = "Test5",
Name = "name5",
ZoneImage = (System.Windows.Media.DrawingImage)Current.Resources[Core.BiliApi.Zone.VideoZoneIcon.Instance().GetZoneImageKey(5)],
Resolution = new Resolution
{
Name = "720P",
Id = 64
},
Duration = "23m50s",
VideoCodecName = "AVC",
AudioCodecName = "194K",
});
// TODO 从数据库读取
// 启动下载服务

@ -87,6 +87,7 @@
<Compile Include="Images\LogoIcon.cs" />
<Compile Include="Images\NavigationIcon.cs" />
<Compile Include="Images\NormalIcon.cs" />
<Compile Include="Models\DownloadBaseItem.cs" />
<Compile Include="Models\DownloadedItem.cs" />
<Compile Include="Models\DownloadingItem.cs" />
<Compile Include="Models\DownloadStatus.cs" />

@ -64,6 +64,12 @@
<system:String x:Key="DownloadSelected">下载选中项</system:String>
<system:String x:Key="AddAllToDownload">下载全部</system:String>
<system:String x:Key="TipAlreadyToAddDownloading">已经添加到下载列表~</system:String>
<system:String x:Key="TipAlreadyToAddDownloaded">已经下载完成~</system:String>
<system:String x:Key="TipAddDownloadingZero">没有选中项符合下载要求!</system:String>
<system:String x:Key="TipAddDownloadingFinished1">成功添加了</system:String>
<system:String x:Key="TipAddDownloadingFinished2">项~</system:String>
<!-- DownloadManager -->
<system:String x:Key="Downloading">正在下载</system:String>
<system:String x:Key="DownloadFinished">已下载</system:String>

@ -0,0 +1,122 @@
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Windows.Media;
namespace DownKyi.Models
{
public class DownloadBaseItem : BindableBase
{
public DownloadBaseItem()
{
// 唯一id
Uuid = Guid.NewGuid().ToString("N");
// 初始化需要下载的内容
NeedDownloadContent = new Dictionary<string, bool>
{
{ "downloadAudio", true },
{ "downloadVideo", true },
{ "downloadDanmaku", true },
{ "downloadSubtitle", true },
{ "downloadCover", true }
};
}
// 此条下载项的id
public string Uuid { get; }
// 需要下载的内容
public Dictionary<string, bool> NeedDownloadContent { get; private set; }
// 视频的id
public string Bvid { get; set; }
public long Avid { get; set; }
public long Cid { get; set; }
public long EpisodeId { get; set; }
// 视频封面的url
public string CoverUrl { get; set; }
private DrawingImage zoneImage;
public DrawingImage ZoneImage
{
get => zoneImage;
set => SetProperty(ref zoneImage, value);
}
// 视频序号
private int order;
public int Order
{
get => order;
set => SetProperty(ref order, value);
}
// 视频主标题
private string mainTitle;
public string MainTitle
{
get => mainTitle;
set => SetProperty(ref mainTitle, value);
}
// 视频标题
private string name;
public string Name
{
get => name;
set => SetProperty(ref name, value);
}
// 时长
private string duration;
public string Duration
{
get => duration;
set => SetProperty(ref duration, value);
}
// 音频编码
public int AudioCodecId { get; set; }
private string audioCodecName;
public string AudioCodecName
{
get => audioCodecName;
set => SetProperty(ref audioCodecName, value);
}
// 视频编码
// "hev1.2.4.L156.90"
// "avc1.640034"
//public string VideoCodecId { get; set; }
// 视频编码名称AVC、HEVC
private string videoCodecName;
public string VideoCodecName
{
get => videoCodecName;
set => SetProperty(ref videoCodecName, value);
}
// 视频画质
private Resolution resolution;
public Resolution Resolution
{
get => resolution;
set => SetProperty(ref resolution, value);
}
// 文件路径,不包含扩展名,所有内容均以此路径下载
public string FilePath { get; set; }
// 文件大小
private string fileSize;
public string FileSize
{
get => fileSize;
set => SetProperty(ref fileSize, value);
}
}
}

@ -1,13 +1,9 @@
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DownKyi.Models
namespace DownKyi.Models
{
public class DownloadedItem : BindableBase
public class DownloadedItem : DownloadBaseItem
{
public DownloadedItem() : base()
{
}
}
}

@ -1,34 +1,19 @@
using DownKyi.Core.BiliApi.VideoStream.Models;
using DownKyi.Core.Aria2cNet.Client;
using DownKyi.Core.BiliApi.VideoStream.Models;
using DownKyi.Images;
using DownKyi.Utils;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Windows.Media;
namespace DownKyi.Models
{
public class DownloadingItem : BindableBase
public class DownloadingItem : DownloadBaseItem
{
public DownloadingItem()
public DownloadingItem() : base()
{
// 唯一id
Uuid = Guid.NewGuid().ToString("N");
// 初始化下载的文件列表
DownloadFiles = new List<string>();
// 初始化需要下载的内容
NeedDownloadContent = new Dictionary<string, bool>
{
{ "downloadAudio", true },
{ "downloadVideo", true },
{ "downloadDanmaku", true },
{ "downloadSubtitle", true },
{ "downloadCover", true }
};
// 暂停继续按钮
StartOrPause = ButtonIcon.Instance().Pause;
StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
@ -40,109 +25,15 @@ namespace DownKyi.Models
public PlayUrl PlayUrl { get; set; }
// 此条下载项的id
public string Uuid { get; }
// Aria相关
public string Gid { get; set; }
// 文件路径,不包含扩展名,所有内容均以此路径下载
public string FilePath { get; set; }
// 下载的文件
public List<string> DownloadFiles { get; private set; }
// 文件大小
private string fileSize;
public string FileSize
{
get => fileSize;
set => SetProperty(ref fileSize, value);
}
// 视频类别
public PlayStreamType PlayStreamType { get; set; }
// 视频的id
public string Bvid { get; set; }
public long Avid { get; set; }
public long Cid { get; set; }
public long EpisodeId { get; set; }
// 视频封面的url
public string CoverUrl { get; set; }
private DrawingImage zoneImage;
public DrawingImage ZoneImage
{
get => zoneImage;
set => SetProperty(ref zoneImage, value);
}
// 视频序号
private int order;
public int Order
{
get => order;
set => SetProperty(ref order, value);
}
// 视频主标题
private string mainTitle;
public string MainTitle
{
get => mainTitle;
set => SetProperty(ref mainTitle, value);
}
// 视频标题
private string name;
public string Name
{
get => name;
set => SetProperty(ref name, value);
}
// 时长
private string duration;
public string Duration
{
get => duration;
set => SetProperty(ref duration, value);
}
// 音频编码
public int AudioCodecId { get; set; }
private string audioCodecName;
public string AudioCodecName
{
get => audioCodecName;
set => SetProperty(ref audioCodecName, value);
}
// 视频编码
// "hev1.2.4.L156.90"
// "avc1.640034"
public string VideoCodecId { get; set; }
// 视频编码名称AVC、HEVC
private string videoCodecName;
public string VideoCodecName
{
get => videoCodecName;
set => SetProperty(ref videoCodecName, value);
}
// 视频画质
private Resolution resolution;
public Resolution Resolution
{
get => resolution;
set => SetProperty(ref resolution, value);
}
// 需要下载的内容
public Dictionary<string, bool> NeedDownloadContent { get; private set; }
// 正在下载内容(音频、视频、弹幕、字幕、封面)
private string downloadContent;

@ -9,103 +9,104 @@ namespace DownKyi.Models
{
public string CoverUrl { get; set; }
public long UpperMid { get; set; }
public int TypeId { get; set; }
private BitmapImage cover;
public BitmapImage Cover
{
get { return cover; }
set { SetProperty(ref cover, value); }
get => cover;
set => SetProperty(ref cover, value);
}
private string title;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
get => title;
set => SetProperty(ref title, value);
}
private string videoZone;
public string VideoZone
{
get { return videoZone; }
set { SetProperty(ref videoZone, value); }
get => videoZone;
set => SetProperty(ref videoZone, value);
}
private string createTime;
public string CreateTime
{
get { return createTime; }
set { SetProperty(ref createTime, value); }
get => createTime;
set => SetProperty(ref createTime, value);
}
private string playNumber;
public string PlayNumber
{
get { return playNumber; }
set { SetProperty(ref playNumber, value); }
get => playNumber;
set => SetProperty(ref playNumber, value);
}
private string danmakuNumber;
public string DanmakuNumber
{
get { return danmakuNumber; }
set { SetProperty(ref danmakuNumber, value); }
get => danmakuNumber;
set => SetProperty(ref danmakuNumber, value);
}
private string likeNumber;
public string LikeNumber
{
get { return likeNumber; }
set { SetProperty(ref likeNumber, value); }
get => likeNumber;
set => SetProperty(ref likeNumber, value);
}
private string coinNumber;
public string CoinNumber
{
get { return coinNumber; }
set { SetProperty(ref coinNumber, value); }
get => coinNumber;
set => SetProperty(ref coinNumber, value);
}
private string favoriteNumber;
public string FavoriteNumber
{
get { return favoriteNumber; }
set { SetProperty(ref favoriteNumber, value); }
get => favoriteNumber;
set => SetProperty(ref favoriteNumber, value);
}
private string shareNumber;
public string ShareNumber
{
get { return shareNumber; }
set { SetProperty(ref shareNumber, value); }
get => shareNumber;
set => SetProperty(ref shareNumber, value);
}
private string replyNumber;
public string ReplyNumber
{
get { return replyNumber; }
set { SetProperty(ref replyNumber, value); }
get => replyNumber;
set => SetProperty(ref replyNumber, value);
}
private string description;
public string Description
{
get { return description; }
set { SetProperty(ref description, value); }
get => description;
set => SetProperty(ref description, value);
}
private string upName;
public string UpName
{
get { return upName; }
set { SetProperty(ref upName, value); }
get => upName;
set => SetProperty(ref upName, value);
}
private BitmapImage upHeader;
public BitmapImage UpHeader
{
get { return upHeader; }
set { SetProperty(ref upHeader, value); }
get => upHeader;
set => SetProperty(ref upHeader, value);
}
}

@ -13,60 +13,62 @@ namespace DownKyi.Models
public long Cid { get; set; }
public long EpisodeId { get; set; }
public string FirstFrame { get; set; }
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set { SetProperty(ref isSelected, value); }
get => isSelected;
set => SetProperty(ref isSelected, value);
}
private int order;
public int Order
{
get { return order; }
set { SetProperty(ref order, value); }
get => order;
set => SetProperty(ref order, value);
}
private string name;
public string Name
{
get { return name; }
set { SetProperty(ref name, value); }
get => name;
set => SetProperty(ref name, value);
}
private string duration;
public string Duration
{
get { return duration; }
set { SetProperty(ref duration, value); }
get => duration;
set => SetProperty(ref duration, value);
}
private List<string> audioQualityFormatList;
public List<string> AudioQualityFormatList
{
get { return audioQualityFormatList; }
set { SetProperty(ref audioQualityFormatList, value); }
get => audioQualityFormatList;
set => SetProperty(ref audioQualityFormatList, value);
}
private string audioQualityFormat;
public string AudioQualityFormat
{
get { return audioQualityFormat; }
set { SetProperty(ref audioQualityFormat, value); }
get => audioQualityFormat;
set => SetProperty(ref audioQualityFormat, value);
}
private List<VideoQuality> videoQualityList;
public List<VideoQuality> VideoQualityList
{
get { return videoQualityList; }
set { SetProperty(ref videoQualityList, value); }
get => videoQualityList;
set => SetProperty(ref videoQualityList, value);
}
private VideoQuality videoQuality;
public VideoQuality VideoQuality
{
get { return videoQuality; }
set { SetProperty(ref videoQuality, value); }
get => videoQuality;
set => SetProperty(ref videoQuality, value);
}
}

@ -8,30 +8,29 @@ namespace DownKyi.Models
private int quality;
public int Quality
{
get { return quality; }
set { SetProperty(ref quality, value); }
get => quality;
set => SetProperty(ref quality, value);
}
private string qualityFormat;
public string QualityFormat
{
get { return qualityFormat; }
set { SetProperty(ref qualityFormat, value); }
get => qualityFormat;
set => SetProperty(ref qualityFormat, value);
}
private List<string> videoCodecList;
public List<string> VideoCodecList
{
get { return videoCodecList; }
set { SetProperty(ref videoCodecList, value); }
get => videoCodecList;
set => SetProperty(ref videoCodecList, value);
}
private string selectedVideoCodec;
public string SelectedVideoCodec
{
get { return selectedVideoCodec; }
set { SetProperty(ref selectedVideoCodec, value); }
get => selectedVideoCodec;
set => SetProperty(ref selectedVideoCodec, value);
}
}
}

@ -93,6 +93,7 @@ namespace DownKyi.Services
Bvid = episode.Bvid,
Cid = episode.Cid,
EpisodeId = -1,
FirstFrame = episode.Cover,
Order = order,
Name = name,
Duration = "N/A"
@ -149,6 +150,7 @@ namespace DownKyi.Services
Bvid = episode.Bvid,
Cid = episode.Cid,
EpisodeId = -1,
FirstFrame = episode.Cover,
Order = order,
Name = name,
Duration = "N/A"
@ -218,6 +220,9 @@ namespace DownKyi.Services
videoInfoView.Cover = cover == null ? null : new BitmapImage(new Uri(cover));
videoInfoView.Title = bangumiSeason.Title;
// 分区id
videoInfoView.TypeId = BangumiType.TypeId[bangumiSeason.Type];
videoInfoView.VideoZone = DictionaryResource.GetString(BangumiType.Type[bangumiSeason.Type]);
videoInfoView.PlayNumber = Format.FormatNumber(bangumiSeason.Stat.Views);

@ -61,6 +61,7 @@ namespace DownKyi.Services
Bvid = null,
Cid = episode.Cid,
EpisodeId = episode.Id,
FirstFrame = episode.Cover,
Order = order,
Name = name,
Duration = "N/A"
@ -129,6 +130,10 @@ namespace DownKyi.Services
videoInfoView.Cover = cover == null ? null : new BitmapImage(new Uri(cover));
videoInfoView.Title = cheeseView.Title;
// 分区id
// 课堂的type id B站没有定义这里自定义为-10
videoInfoView.TypeId = -10;
videoInfoView.VideoZone = DictionaryResource.GetString("Cheese");
videoInfoView.CreateTime = "";

@ -67,38 +67,6 @@ namespace DownKyi.Services.Download
}
return DownloadVideo(downloading, downloadAudio);
//// 如果音频为空,说明没有匹配到可下载的音频
//if (downloadAudio == null) { return null; }
//// 下载链接
//List<string> audioUrls = new List<string>();
//if (downloadAudio.BaseUrl != null) { audioUrls.Add(downloadAudio.BaseUrl); }
//if (downloadAudio.BackupUrl != null) { audioUrls.AddRange(downloadAudio.BackupUrl); }
//// 路径
//string[] temp = downloading.FilePath.Split('/');
//string path = downloading.FilePath.Replace(temp[temp.Length - 1], "");
//// 下载文件名
//string fileName = Guid.NewGuid().ToString("N");
//fileName = Path.Combine(path, fileName);
//// 记录本次下载的文件
//downloading.DownloadFiles.Add(fileName);
//// 开始下载
//DownloadResult downloadStatus = DownloadByAria(downloading, audioUrls, path, fileName);
//switch (downloadStatus)
//{
// case DownloadResult.SUCCESS:
// return fileName;
// case DownloadResult.FAILED:
// return null;
// case DownloadResult.ABORT:
// return null;
// default:
// return null;
//}
}
/// <summary>
@ -123,7 +91,7 @@ namespace DownKyi.Services.Download
PlayUrlDashVideo downloadVideo = null;
foreach (PlayUrlDashVideo video in downloading.PlayUrl.Dash.Video)
{
if (video.Id == downloading.Resolution.Id && video.Codecs == downloading.VideoCodecId)
if (video.Id == downloading.Resolution.Id && Utils.GetVideoCodecName(video.Codecs) == downloading.VideoCodecName)
{
downloadVideo = video;
break;
@ -155,7 +123,6 @@ namespace DownKyi.Services.Download
// 下载文件名
string fileName = Guid.NewGuid().ToString("N");
fileName = Path.Combine(path, fileName);
// 记录本次下载的文件
downloading.DownloadFiles.Add(fileName);
@ -165,7 +132,7 @@ namespace DownKyi.Services.Download
switch (downloadStatus)
{
case DownloadResult.SUCCESS:
return fileName;
return Path.Combine(path, fileName);
case DownloadResult.FAILED:
return null;
case DownloadResult.ABORT:
@ -287,6 +254,11 @@ namespace DownKyi.Services.Download
List<string> srtFiles = new List<string>();
var subRipTexts = VideoStream.GetSubtitle(downloading.Avid, downloading.Bvid, downloading.Cid);
if (subRipTexts == null)
{
return null;
}
foreach (var subRip in subRipTexts)
{
string srtFile = $"{downloading.FilePath}_{subRip.LanDoc}.srt";
@ -547,11 +519,18 @@ namespace DownKyi.Services.Download
// 检测字幕是否下载成功
if (downloading.NeedDownloadContent["downloadSubtitle"])
{
foreach (string subtitle in outputSubtitles)
if (outputSubtitles == null)
{
// 为null时表示不存在字幕
}
else
{
if (File.Exists(subtitle))
foreach (string subtitle in outputSubtitles)
{
// 成功
if (File.Exists(subtitle))
{
// 成功
}
}
}
}
@ -692,7 +671,7 @@ namespace DownKyi.Services.Download
}
// 添加一个下载
var ariaAddUri = AriaClient.AddUriAsync(urls, option);
Task<AriaAddUri> ariaAddUri = AriaClient.AddUriAsync(urls, option);
if (ariaAddUri == null || ariaAddUri.Result == null || ariaAddUri.Result.Result == null)
{
return DownloadResult.FAILED;
@ -711,12 +690,10 @@ namespace DownKyi.Services.Download
switch (downloading.DownloadStatus)
{
case DownloadStatus.PAUSE:
var ariaPause = AriaClient.PauseAsync(downloading.Gid);
// TODO
Task<AriaPause> ariaPause = AriaClient.PauseAsync(downloading.Gid);
break;
case DownloadStatus.DOWNLOADING:
var ariaUnpause = AriaClient.UnpauseAsync(downloading.Gid);
// TODO
Task<AriaPause> ariaUnpause = AriaClient.UnpauseAsync(downloading.Gid);
break;
}
}));
@ -726,6 +703,7 @@ namespace DownKyi.Services.Download
{
// 当前的下载视频
DownloadingItem video = downloadingList.FirstOrDefault(it => it.Gid == gid);
if (video == null) { return; }
float percent = 0;
if (totalLength != 0)

@ -26,9 +26,9 @@ namespace DownKyi.Services
page.PlayUrl = playUrl;
// 获取设置
var userInfo = SettingsManager.GetInstance().GetUserInfo();
UserInfoSettings userInfo = SettingsManager.GetInstance().GetUserInfo();
int defaultQuality = SettingsManager.GetInstance().GetQuality();
var videoCodecs = SettingsManager.GetInstance().GetVideoCodecs();
VideoCodecs videoCodecs = SettingsManager.GetInstance().GetVideoCodecs();
int defaultAudioQuality = SettingsManager.GetInstance().GetAudioQuality();
// 未登录时最高仅720P
@ -201,7 +201,7 @@ namespace DownKyi.Services
/// </summary>
/// <param name="origin"></param>
/// <returns></returns>
private static string GetVideoCodecName(string origin)
internal static string GetVideoCodecName(string origin)
{
return origin.Contains("avc") ? "H.264/AVC" : origin.Contains("hev") ? "H.265/HEVC" : "";
}

@ -78,6 +78,7 @@ namespace DownKyi.Services
Bvid = videoView.Bvid,
Cid = page.Cid,
EpisodeId = -1,
FirstFrame = page.FirstFrame,
Order = order,
Name = name,
Duration = "N/A"
@ -114,6 +115,7 @@ namespace DownKyi.Services
Bvid = episode.Bvid,
Cid = episode.Cid,
EpisodeId = -1,
FirstFrame = episode.Page.FirstFrame,
Order = order,
Name = episode.Title,
Duration = "N/A"
@ -203,6 +205,9 @@ namespace DownKyi.Services
videoInfoView.Cover = cover == null ? null : new BitmapImage(new Uri(cover));
videoInfoView.Title = videoView.Title;
// 分区id
videoInfoView.TypeId = videoView.Tid;
videoInfoView.VideoZone = videoZone;
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区

@ -1,12 +1,9 @@
using DownKyi.Models;
using DownKyi.Images;
using DownKyi.Models;
using DownKyi.Utils;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
namespace DownKyi.ViewModels.DownloadManager
{
@ -29,15 +26,6 @@ namespace DownKyi.ViewModels.DownloadManager
{
// 初始化DownloadingList
DownloadingList = App.DownloadingList;
//// 下载列表发生变化时执行的任务
//DownloadingList.CollectionChanged += new NotifyCollectionChangedEventHandler((object sender, NotifyCollectionChangedEventArgs e) =>
//{
// // save the downloading list and finished list.
// //SaveHistory();
//});
}
#region 命令申明
@ -51,6 +39,34 @@ namespace DownKyi.ViewModels.DownloadManager
/// </summary>
private void ExecutePauseAllDownloadingCommand()
{
foreach (DownloadingItem downloading in downloadingList)
{
switch (downloading.DownloadStatus)
{
case DownloadStatus.NOT_STARTED:
case DownloadStatus.WAIT_FOR_DOWNLOAD:
downloading.DownloadStatus = DownloadStatus.PAUSE_STARTED;
break;
case DownloadStatus.PAUSE_STARTED:
break;
case DownloadStatus.PAUSE:
break;
case DownloadStatus.DOWNLOADING:
downloading.DownloadStatus = DownloadStatus.PAUSE;
break;
case DownloadStatus.DOWNLOAD_SUCCEED:
// 下载成功后会从下载列表中删除
// 不会出现此分支
break;
case DownloadStatus.DOWNLOAD_FAILED:
break;
default:
break;
}
downloading.StartOrPause = ButtonIcon.Instance().Start;
downloading.StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
}
}
// 继续所有下载事件
@ -62,6 +78,35 @@ namespace DownKyi.ViewModels.DownloadManager
/// </summary>
private void ExecuteContinueAllDownloadingCommand()
{
foreach (DownloadingItem downloading in downloadingList)
{
switch (downloading.DownloadStatus)
{
case DownloadStatus.NOT_STARTED:
case DownloadStatus.WAIT_FOR_DOWNLOAD:
break;
case DownloadStatus.PAUSE_STARTED:
downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD;
break;
case DownloadStatus.PAUSE:
downloading.DownloadStatus = DownloadStatus.DOWNLOADING;
break;
case DownloadStatus.DOWNLOADING:
break;
case DownloadStatus.DOWNLOAD_SUCCEED:
// 下载成功后会从下载列表中删除
// 不会出现此分支
break;
case DownloadStatus.DOWNLOAD_FAILED:
downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD;
break;
default:
break;
}
downloading.StartOrPause = ButtonIcon.Instance().Pause;
downloading.StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
}
}
// 删除所有下载事件
@ -73,6 +118,7 @@ namespace DownKyi.ViewModels.DownloadManager
/// </summary>
private void ExecuteDeleteAllDownloadingCommand()
{
DownloadingList.Clear();
}
#endregion

@ -1,6 +1,9 @@
using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.BiliApi.Zone;
using DownKyi.Core.FileName;
using DownKyi.Core.Logging;
using DownKyi.Core.Settings;
using DownKyi.Core.Utils;
using DownKyi.CustomControl;
using DownKyi.Events;
using DownKyi.Images;
@ -13,11 +16,13 @@ using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
namespace DownKyi.ViewModels
{
@ -32,76 +37,75 @@ namespace DownKyi.ViewModels
private VectorImage arrowBack;
public VectorImage ArrowBack
{
get { return arrowBack; }
set { SetProperty(ref arrowBack, value); }
get => arrowBack;
set => SetProperty(ref arrowBack, value);
}
private string inputText;
public string InputText
{
get { return inputText; }
set { SetProperty(ref inputText, value); }
get => inputText;
set => SetProperty(ref inputText, value);
}
private GifImage loading;
public GifImage Loading
{
get { return loading; }
set { SetProperty(ref loading, value); }
get => loading;
set => SetProperty(ref loading, value);
}
private Visibility loadingVisibility;
public Visibility LoadingVisibility
{
get { return loadingVisibility; }
set { SetProperty(ref loadingVisibility, value); }
get => loadingVisibility;
set => SetProperty(ref loadingVisibility, value);
}
private VectorImage downloadManage;
public VectorImage DownloadManage
{
get { return downloadManage; }
set { SetProperty(ref downloadManage, value); }
get => downloadManage;
set => SetProperty(ref downloadManage, value);
}
private VideoInfoView videoInfoView;
public VideoInfoView VideoInfoView
{
get { return videoInfoView; }
set { SetProperty(ref videoInfoView, value); }
get => videoInfoView;
set => SetProperty(ref videoInfoView, value);
}
private ObservableCollection<VideoSection> videoSections;
public ObservableCollection<VideoSection> VideoSections
{
get { return videoSections; }
set { SetProperty(ref videoSections, value); }
get => videoSections;
set => SetProperty(ref videoSections, value);
}
private bool isSelectAll;
public bool IsSelectAll
{
get { return isSelectAll; }
set { SetProperty(ref isSelectAll, value); }
get => isSelectAll;
set => SetProperty(ref isSelectAll, value);
}
private Visibility contentVisibility;
public Visibility ContentVisibility
{
get { return contentVisibility; }
set { SetProperty(ref contentVisibility, value); }
get => contentVisibility;
set => SetProperty(ref contentVisibility, value);
}
private Visibility noDataVisibility;
public Visibility NoDataVisibility
{
get { return noDataVisibility; }
set { SetProperty(ref noDataVisibility, value); }
get => noDataVisibility;
set => SetProperty(ref noDataVisibility, value);
}
#endregion
public ViewVideoDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator)
{
this.dialogService = dialogService;
@ -265,7 +269,7 @@ namespace DownKyi.ViewModels
if (!(parameter is VideoSection section)) { return; }
bool isSelectAll = true;
foreach (var page in section.VideoPages)
foreach (VideoPage page in section.VideoPages)
{
if (!page.IsSelected)
{
@ -304,7 +308,7 @@ namespace DownKyi.ViewModels
private void ExecuteKeySelectAllCommand(object parameter)
{
if (!(parameter is VideoSection section)) { return; }
foreach (var page in section.VideoPages)
foreach (VideoPage page in section.VideoPages)
{
page.IsSelected = true;
}
@ -323,14 +327,14 @@ namespace DownKyi.ViewModels
if (!(parameter is VideoSection section)) { return; }
if (IsSelectAll)
{
foreach (var page in section.VideoPages)
foreach (VideoPage page in section.VideoPages)
{
page.IsSelected = true;
}
}
else
{
foreach (var page in section.VideoPages)
foreach (VideoPage page in section.VideoPages)
{
page.IsSelected = false;
}
@ -424,11 +428,11 @@ namespace DownKyi.ViewModels
case ParseScope.NONE:
break;
case ParseScope.SELECTED_ITEM:
foreach (var section in VideoSections)
foreach (VideoSection section in VideoSections)
{
foreach (var page in section.VideoPages)
foreach (VideoPage page in section.VideoPages)
{
var videoPage = section.VideoPages.FirstOrDefault(t => t == page);
VideoPage videoPage = section.VideoPages.FirstOrDefault(t => t == page);
if (videoPage.IsSelected)
{
@ -439,13 +443,13 @@ namespace DownKyi.ViewModels
}
break;
case ParseScope.CURRENT_SECTION:
foreach (var section in VideoSections)
foreach (VideoSection section in VideoSections)
{
if (section.IsSelected)
{
foreach (var page in section.VideoPages)
foreach (VideoPage page in section.VideoPages)
{
var videoPage = section.VideoPages.FirstOrDefault(t => t == page);
VideoPage videoPage = section.VideoPages.FirstOrDefault(t => t == page);
// 执行解析任务
UnityUpdateView(ParseVideo, null, videoPage);
@ -454,11 +458,11 @@ namespace DownKyi.ViewModels
}
break;
case ParseScope.ALL:
foreach (var section in VideoSections)
foreach (VideoSection section in VideoSections)
{
foreach (var page in section.VideoPages)
foreach (VideoPage page in section.VideoPages)
{
var videoPage = section.VideoPages.FirstOrDefault(t => t == page);
VideoPage videoPage = section.VideoPages.FirstOrDefault(t => t == page);
// 执行解析任务
UnityUpdateView(ParseVideo, null, videoPage);
@ -530,12 +534,6 @@ namespace DownKyi.ViewModels
downloadDanmaku = result.Parameters.GetValue<bool>("downloadDanmaku");
downloadSubtitle = result.Parameters.GetValue<bool>("downloadSubtitle");
downloadCover = result.Parameters.GetValue<bool>("downloadCover");
// 文件夹不存在则创建
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
}
});
}
@ -545,8 +543,144 @@ namespace DownKyi.ViewModels
// 这时直接退出
if (directory == string.Empty) { return; }
// 文件夹不存在则创建
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// 添加视频计数
int i = 0;
// 添加到下载
eventAggregator.GetEvent<MessageEvent>().Publish(directory);
foreach (VideoSection section in VideoSections)
{
foreach (VideoPage page in section.VideoPages)
{
// 只下载选中项,跳过未选中项
if (!page.IsSelected) { continue; }
// 没有解析的也跳过
if (page.PlayUrl == null) { continue; }
// 判断是否同一个视频需要cid、画质、音质、视频编码都相同
// 如果存在正在下载列表,则跳过,并提示
foreach (DownloadingItem item in App.DownloadingList)
{
if (item.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodecName == page.AudioQualityFormat && item.VideoCodecName == page.VideoQuality.SelectedVideoCodec)
{
eventAggregator.GetEvent<MessageEvent>().Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloading")}");
continue;
}
}
// 如果存在下载完成列表,弹出选择框是否再次下载
foreach (DownloadedItem item in App.DownloadedList)
{
if (item.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodecName == page.AudioQualityFormat && item.VideoCodecName == page.VideoQuality.SelectedVideoCodec)
{
eventAggregator.GetEvent<MessageEvent>().Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloaded")}");
continue;
}
}
// 文件路径
List<FileNamePart> fileNameParts = SettingsManager.GetInstance().GetFileNameParts();
FileName fileName = FileName.Builder(fileNameParts)
.SetOrder(page.Order)
.SetSection(Format.FormatFileName(section.Title))
.SetMainTitle(Format.FormatFileName(VideoInfoView.Title))
.SetPageTitle(Format.FormatFileName(page.Name))
.SetVideoZone(VideoInfoView.VideoZone.Split('>')[0])
.SetAudioQuality(page.AudioQualityFormat)
.SetVideoQuality(page.VideoQuality.QualityFormat)
.SetVideoCodec(page.VideoQuality.SelectedVideoCodec.Contains("AVC") ? "AVC" : page.VideoQuality.SelectedVideoCodec.Contains("HEVC") ? "HEVC" : "");
string filePath = Path.Combine(directory, fileName.RelativePath());
// 视频类别
PlayStreamType playStreamType;
switch (VideoInfoView.TypeId)
{
case -10:
playStreamType = PlayStreamType.CHEESE;
break;
case 13:
case 23:
case 177:
case 167:
case 11:
playStreamType = PlayStreamType.BANGUMI;
break;
case 1:
case 3:
case 129:
case 4:
case 36:
case 188:
case 234:
case 223:
case 160:
case 211:
case 217:
case 119:
case 155:
case 202:
case 5:
case 181:
default:
playStreamType = PlayStreamType.VIDEO;
break;
}
// 如果不存在,直接添加到下载列表
DownloadingItem downloading = new DownloadingItem
{
PlayUrl = page.PlayUrl,
Bvid = page.Bvid,
Avid = page.Avid,
Cid = page.Cid,
EpisodeId = page.EpisodeId,
CoverUrl = page.FirstFrame,
ZoneImage = (DrawingImage)Application.Current.Resources[VideoZoneIcon.Instance().GetZoneImageKey(VideoInfoView.TypeId)],
Order = page.Order,
MainTitle = VideoInfoView.Title,
Name = page.Name,
Duration = page.Duration,
AudioCodecId = Constant.AudioQualityId[page.AudioQualityFormat],
AudioCodecName = page.AudioQualityFormat,
VideoCodecName = page.VideoQuality.SelectedVideoCodec,
Resolution = new Resolution { Name = page.VideoQuality.QualityFormat, Id = page.VideoQuality.Quality },
FilePath = filePath,
PlayStreamType = playStreamType,
DownloadStatus = DownloadStatus.NOT_STARTED,
};
// 需要下载的内容
downloading.NeedDownloadContent["downloadAudio"] = downloadAudio;
downloading.NeedDownloadContent["downloadVideo"] = downloadVideo;
downloading.NeedDownloadContent["downloadDanmaku"] = downloadDanmaku;
downloading.NeedDownloadContent["downloadSubtitle"] = downloadSubtitle;
downloading.NeedDownloadContent["downloadCover"] = downloadCover;
// 添加到下载列表
App.DownloadingList.Add(downloading);
i++;
}
}
// 通知用户添加到下载列表的结果
if (i == 0)
{
eventAggregator.GetEvent<MessageEvent>().Publish(DictionaryResource.GetString("TipAddDownloadingZero"));
}
else
{
eventAggregator.GetEvent<MessageEvent>().Publish($"{DictionaryResource.GetString("TipAddDownloadingFinished1")}{i}{DictionaryResource.GetString("TipAddDownloadingFinished2")}");
}
}
/// <summary>
@ -627,12 +761,12 @@ namespace DownKyi.ViewModels
NoDataVisibility = Visibility.Collapsed;
}
var videoSections = videoInfoService.GetVideoSections();
List<VideoSection> videoSections = videoInfoService.GetVideoSections();
if (videoSections == null)
{
LogManager.Debug(Tag, "videoSections is not exist.");
var pages = videoInfoService.GetVideoPages();
List<VideoPage> pages = videoInfoService.GetVideoPages();
PropertyChangeAsync(new Action(() =>
{

@ -88,7 +88,7 @@
<Grid Grid.Row="0" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="100" />
<ColumnDefinition />
</Grid.ColumnDefinitions>

@ -558,6 +558,7 @@
<ListBox
x:Name="nameVideoSections"
Grid.Row="0"
ItemContainerStyle="{StaticResource TagItemStyle}"
ItemsSource="{Binding VideoSections, Mode=TwoWay}"
SelectionMode="Single">
<i:Interaction.Triggers>
@ -566,7 +567,7 @@
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Style BasedOn="{StaticResource TagStyle}" TargetType="{x:Type ListBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding VideoSections.Count}" Value="0">
<Setter Property="Height" Value="0" />
@ -577,56 +578,6 @@
</Style.Triggers>
</Style>
</ListBox.Style>
<ListBox.Template>
<ControlTemplate TargetType="{x:Type ListBox}">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled">
<WrapPanel
IsItemsHost="True"
Orientation="Horizontal"
ScrollViewer.CanContentScroll="True" />
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
Name="Border"
Margin="5,3"
Padding="8,2"
Background="{DynamicResource BrushPrimary}"
CornerRadius="10"
Cursor="Hand">
<ContentPresenter
Name="content"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{Binding Title}" />
</Border>
<ControlTemplate.Triggers>
<!-- 顺序很重要,不能修改 -->
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="{DynamicResource BrushBackgroundGrey}" />
<Setter Property="Foreground" Value="{DynamicResource BrushText}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="{DynamicResource BrushPrimaryTranslucent}" />
<Setter Property="Foreground" Value="{DynamicResource BrushText}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="{DynamicResource BrushPrimary}" />
<Setter Property="Foreground" Value="{DynamicResource BrushText}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<!-- 视频分P -->

Loading…
Cancel
Save