using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.BiliApi.VideoStream;
using DownKyi.Core.BiliApi.Zone;
using DownKyi.Core.FileName;
using DownKyi.Core.Logging;
using DownKyi.Core.Settings;
using DownKyi.Core.Utils;
using DownKyi.Events;
using DownKyi.Models;
using DownKyi.Utils;
using DownKyi.ViewModels.Dialogs;
using DownKyi.ViewModels.DownloadManager;
using DownKyi.ViewModels.PageViewModels;
using Prism.Events;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
namespace DownKyi.Services.Download
{
///
/// 添加到下载列表服务
///
public class AddToDownloadService
{
private readonly string Tag = "AddToDownloadService";
private IInfoService videoInfoService;
private VideoInfoView videoInfoView;
private List videoSections;
// 下载内容
private bool downloadAudio = true;
private bool downloadVideo = true;
private bool downloadDanmaku = true;
private bool downloadSubtitle = true;
private bool downloadCover = true;
///
/// 添加下载
///
///
public AddToDownloadService(PlayStreamType streamType)
{
switch (streamType)
{
case PlayStreamType.VIDEO:
videoInfoService = new VideoInfoService(null);
break;
case PlayStreamType.BANGUMI:
videoInfoService = new BangumiInfoService(null);
break;
case PlayStreamType.CHEESE:
videoInfoService = new CheeseInfoService(null);
break;
default:
break;
}
}
///
/// 添加下载
///
///
///
public AddToDownloadService(string id, PlayStreamType streamType)
{
switch (streamType)
{
case PlayStreamType.VIDEO:
videoInfoService = new VideoInfoService(id);
break;
case PlayStreamType.BANGUMI:
videoInfoService = new BangumiInfoService(id);
break;
case PlayStreamType.CHEESE:
videoInfoService = new CheeseInfoService(id);
break;
default:
break;
}
}
public void SetVideoInfoService(IInfoService videoInfoService)
{
this.videoInfoService = videoInfoService;
}
public void GetVideo(VideoInfoView videoInfoView, List videoSections)
{
this.videoInfoView = videoInfoView;
this.videoSections = videoSections;
}
public void GetVideo()
{
videoInfoView = videoInfoService.GetVideoView();
if (videoInfoView == null)
{
LogManager.Debug(Tag, "VideoInfoView is null.");
return;
}
videoSections = videoInfoService.GetVideoSections();
if (videoSections == null)
{
LogManager.Debug(Tag, "videoSections is not exist.");
videoSections = new List
{
new VideoSection
{
Id = 0,
Title = "default",
IsSelected = true,
VideoPages = videoInfoService.GetVideoPages()
}
};
}
// 将所有视频设置为选中
foreach (VideoSection section in videoSections)
{
foreach (var item in section.VideoPages)
{
item.IsSelected = true;
}
}
}
///
/// 解析视频流
///
///
public void ParseVideo(IInfoService videoInfoService)
{
if (videoSections == null) { return; }
foreach (VideoSection section in videoSections)
{
foreach (VideoPage page in section.VideoPages)
{
// 执行解析任务
videoInfoService.GetVideoStream(page);
}
}
}
///
/// 选择文件夹和下载项
///
///
public string SetDirectory(IDialogService dialogService)
{
// 选择的下载文件夹
string directory = string.Empty;
// 是否使用默认下载目录
if (SettingsManager.GetInstance().IsUseSaveVideoRootPath() == AllowStatus.YES)
{
directory = SettingsManager.GetInstance().GetSaveVideoRootPath();
}
else
{
// 打开文件夹选择器
dialogService.ShowDialog(ViewDownloadSetterViewModel.Tag, null, result =>
{
if (result.Result == ButtonResult.OK)
{
// 选择的下载文件夹
directory = result.Parameters.GetValue("directory");
// 下载内容
downloadAudio = result.Parameters.GetValue("downloadAudio");
downloadVideo = result.Parameters.GetValue("downloadVideo");
downloadDanmaku = result.Parameters.GetValue("downloadDanmaku");
downloadSubtitle = result.Parameters.GetValue("downloadSubtitle");
downloadCover = result.Parameters.GetValue("downloadCover");
}
});
}
// 下载设置dialog中如果点击取消或者关闭窗口,
// 会返回空字符串,
// 这时直接退出
if (directory == null || directory == string.Empty) { return null; }
// 文件夹不存在则创建
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
return directory;
}
public int AddToDownload(IEventAggregator eventAggregator, string directory)
{
if (directory == null || directory == string.Empty) { return -1; }
if (videoSections == null) { return -1; }
// 视频计数
int i = 0;
// 添加到下载
foreach (VideoSection section in videoSections)
{
if (section.VideoPages == null) { continue; }
foreach (VideoPage page in section.VideoPages)
{
// 只下载选中项,跳过未选中项
if (!page.IsSelected) { continue; }
// 没有解析的也跳过
if (page.PlayUrl == null) { continue; }
// 判断VideoQuality
int retry = 0;
while (page.VideoQuality == null && retry < 5)
{
// 执行解析任务
videoInfoService.GetVideoStream(page);
retry++;
}
if (page.VideoQuality == null) { continue; }
// 判断是否同一个视频,需要cid、画质、音质、视频编码都相同
// 如果存在正在下载列表,则跳过,并提示
bool isDownloading = false;
foreach (DownloadingItem item in App.DownloadingList)
{
if (item.DownloadBase == null) { continue; }
if (item.DownloadBase.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodec.Name == page.AudioQualityFormat && item.VideoCodecName == page.VideoQuality.SelectedVideoCodec)
{
eventAggregator.GetEvent().Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloading")}");
isDownloading = true;
break;
}
}
if (isDownloading) { continue; }
// 如果存在下载完成列表,弹出选择框是否再次下载
bool isDownloaded = false;
foreach (DownloadedItem item in App.DownloadedList)
{
if (item.DownloadBase == null) { continue; }
if (item.DownloadBase.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodec.Name == page.AudioQualityFormat && item.VideoCodecName == page.VideoQuality.SelectedVideoCodec)
{
eventAggregator.GetEvent().Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloaded")}");
isDownloaded = true;
break;
}
}
if (isDownloaded) { continue; }
// 视频分区
int zoneId = -1;
List zoneList = VideoZone.Instance().GetZones();
ZoneAttr zone = zoneList.Find(it => it.Id == videoInfoView.TypeId);
if (zone != null)
{
if (zone.ParentId == 0)
{
zoneId = zone.Id;
}
else
{
ZoneAttr zoneParent = zoneList.Find(it => it.Id == zone.ParentId);
if (zoneParent != null)
{
zoneId = zoneParent.Id;
}
}
}
// 如果只有一个视频章节,则不在命名中出现
string sectionName = string.Empty;
if (videoSections.Count > 1)
{
sectionName = section.Title;
}
// 文件路径
List fileNameParts = SettingsManager.GetInstance().GetFileNameParts();
FileName fileName = FileName.Builder(fileNameParts)
.SetOrder(page.Order)
.SetSection(Format.FormatFileName(sectionName))
.SetMainTitle(Format.FormatFileName(videoInfoView.Title))
.SetPageTitle(Format.FormatFileName(page.Name))
.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" : "")
.SetVideoPublishTime(page.PublishTime)
.SetAvid(page.Avid)
.SetBvid(page.Bvid)
.SetCid(page.Cid)
.SetUpMid(page.Owner.Mid)
.SetUpName(Format.FormatFileName(page.Owner.Name));
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;
}
// 添加到下载列表
App.PropertyChangeAsync(new Action(() =>
{
// 如果不存在,直接添加到下载列表
DownloadBase downloadBase = new DownloadBase
{
Bvid = page.Bvid,
Avid = page.Avid,
Cid = page.Cid,
EpisodeId = page.EpisodeId,
CoverUrl = videoInfoView.CoverUrl,
PageCoverUrl = page.FirstFrame,
ZoneId = zoneId,
FilePath = filePath,
Order = page.Order,
MainTitle = videoInfoView.Title,
Name = page.Name,
Duration = page.Duration,
VideoCodecName = page.VideoQuality.SelectedVideoCodec,
Resolution = new Quality { Name = page.VideoQuality.QualityFormat, Id = page.VideoQuality.Quality },
AudioCodec = Constant.GetAudioQualities().FirstOrDefault(t => { return t.Name == page.AudioQualityFormat; }),
};
Downloading downloading = new Downloading
{
PlayStreamType = playStreamType,
DownloadStatus = DownloadStatus.NOT_STARTED,
};
// 需要下载的内容
downloadBase.NeedDownloadContent["downloadAudio"] = downloadAudio;
downloadBase.NeedDownloadContent["downloadVideo"] = downloadVideo;
downloadBase.NeedDownloadContent["downloadDanmaku"] = downloadDanmaku;
downloadBase.NeedDownloadContent["downloadSubtitle"] = downloadSubtitle;
downloadBase.NeedDownloadContent["downloadCover"] = downloadCover;
DownloadingItem downloadingItem = new DownloadingItem
{
DownloadBase = downloadBase,
Downloading = downloading,
PlayUrl = page.PlayUrl,
};
App.DownloadingList.Add(downloadingItem);
Thread.Sleep(10);
}));
i++;
}
}
return i;
}
}
}