合并253 pull request

croire 3 years ago
parent 60880abb8b
commit 3a918a6e5c

@ -137,6 +137,18 @@ namespace DownKyi.Core.Aria2cNet.Server
public static async Task<bool> CloseServerAsync() public static async Task<bool> CloseServerAsync()
{ {
await AriaClient.ShutdownAsync(); await AriaClient.ShutdownAsync();
// 等待进程结束
await Task.Run(() =>
{
Server.WaitForExit(30000);
try
{
Server.Kill();
}
catch (Exception)
{
}
});
return true; return true;
} }
@ -166,7 +178,18 @@ namespace DownKyi.Core.Aria2cNet.Server
{ {
var task = AriaClient.ShutdownAsync(); var task = AriaClient.ShutdownAsync();
if (task.Result != null && task.Result.Result != null && task.Result.Result == "OK") if (task.Result != null && task.Result.Result != null && task.Result.Result == "OK")
{ return true; } {
// 等待进程结束
Server.WaitForExit(30000);
try
{
Server.Kill();
}
catch (Exception)
{
}
return true;
}
return false; return false;
} }
@ -208,39 +231,35 @@ namespace DownKyi.Core.Aria2cNet.Server
private static void ExcuteProcess(string exe, string arg, string workingDirectory, DataReceivedEventHandler output) private static void ExcuteProcess(string exe, string arg, string workingDirectory, DataReceivedEventHandler output)
{ {
using (var p = new Process()) var p = new Process();
{ Server = p;
Server = p;
p.StartInfo.FileName = exe; p.StartInfo.FileName = exe;
p.StartInfo.Arguments = arg; p.StartInfo.Arguments = arg;
// 工作目录 // 工作目录
if (workingDirectory != null) if (workingDirectory != null)
{ {
p.StartInfo.WorkingDirectory = workingDirectory; p.StartInfo.WorkingDirectory = workingDirectory;
} }
// 输出信息重定向 // 输出信息重定向
p.StartInfo.UseShellExecute = false; p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true; p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true; p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardOutput = true;
// 将 StandardErrorEncoding 改为 UTF-8 才不会出现中文乱码 // 将 StandardErrorEncoding 改为 UTF-8 才不会出现中文乱码
p.StartInfo.StandardOutputEncoding = Encoding.UTF8; p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
p.StartInfo.StandardErrorEncoding = Encoding.UTF8; p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
p.OutputDataReceived += output; p.OutputDataReceived += output;
p.ErrorDataReceived += output; p.ErrorDataReceived += output;
// 启动线程 // 启动线程
p.Start(); p.Start();
p.BeginOutputReadLine(); p.BeginOutputReadLine();
p.BeginErrorReadLine(); p.BeginErrorReadLine();
// 等待进程结束
p.WaitForExit();
}
} }
} }

@ -17,14 +17,14 @@ namespace DownKyi.Core.FFmpeg
/// <param name="destVideo"></param> /// <param name="destVideo"></param>
public static bool MergeVideo(string video1, string video2, string destVideo) public static bool MergeVideo(string video1, string video2, string destVideo)
{ {
string param = $"-i \"{video1}\" -i \"{video2}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\""; string param = $"-y -i \"{video1}\" -i \"{video2}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\"";
if (video1 == null || !File.Exists(video1)) if (video1 == null || !File.Exists(video1))
{ {
param = $"-i \"{video2}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\""; param = $"-y -i \"{video2}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\"";
} }
if (video2 == null || !File.Exists(video2)) if (video2 == null || !File.Exists(video2))
{ {
param = $"-i \"{video1}\" -acodec copy -f aac \"{destVideo}\""; param = $"-y -i \"{video1}\" -acodec copy -f aac \"{destVideo}\"";
} }
if (!File.Exists(video1) && !File.Exists(video2)) { return false; } if (!File.Exists(video1) && !File.Exists(video2)) { return false; }
@ -89,9 +89,9 @@ namespace DownKyi.Core.FFmpeg
return false; return false;
} }
// ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mkv // ffmpeg -y -f concat -safe 0 -i filelist.txt -c copy output.mkv
// 加上-y表示如果有同名文件则默认覆盖 // 加上-y表示如果有同名文件则默认覆盖
string param = $"-f concat -safe 0 -i {concatFileName} -c copy \"{destVideo}\" -y"; string param = $"-y -f concat -safe 0 -i {concatFileName} -c copy \"{destVideo}\" -y";
ExcuteProcess("ffmpeg.exe", param, workingDirectory, (s, e) => Console.WriteLine(e.Data)); ExcuteProcess("ffmpeg.exe", param, workingDirectory, (s, e) => Console.WriteLine(e.Data));
// 删除临时文件 // 删除临时文件
@ -126,8 +126,8 @@ namespace DownKyi.Core.FFmpeg
/// <param name="action"></param> /// <param name="action"></param>
public static void Delogo(string video, string destVideo, int x, int y, int width, int height, Action<string> action) public static void Delogo(string video, string destVideo, int x, int y, int width, int height, Action<string> action)
{ {
// ffmpeg -i "video.mp4" -vf delogo=x=1670:y=50:w=180:h=70:show=1 "delogo.mp4" // ffmpeg -y -i "video.mp4" -vf delogo=x=1670:y=50:w=180:h=70:show=1 "delogo.mp4"
string param = $"-i \"{video}\" -vf delogo=x={x}:y={y}:w={width}:h={height}:show=0 \"{destVideo}\" -hide_banner -y"; string param = $"-y -i \"{video}\" -vf delogo=x={x}:y={y}:w={width}:h={height}:show=0 \"{destVideo}\" -hide_banner -y";
ExcuteProcess("ffmpeg.exe", param, null, (s, e) => ExcuteProcess("ffmpeg.exe", param, null, (s, e) =>
{ {
Console.WriteLine(e.Data); Console.WriteLine(e.Data);

@ -30,7 +30,10 @@ namespace DownKyi.Services.Download
/// </summary> /// </summary>
public class AriaDownloadService : DownloadService, IDownloadService public class AriaDownloadService : DownloadService, IDownloadService
{ {
private Task workTask;
private CancellationTokenSource tokenSource; private CancellationTokenSource tokenSource;
private CancellationToken cancellationToken;
private List<Task> downloadingTasks = new List<Task>();
private readonly int retry = 5; private readonly int retry = 5;
private readonly string nullMark = "<null>"; private readonly string nullMark = "<null>";
@ -144,7 +147,9 @@ namespace DownKyi.Services.Download
// 老版本数据库没有这一项会变成null // 老版本数据库没有这一项会变成null
if (downloading.Downloading.DownloadedFiles == null) if (downloading.Downloading.DownloadedFiles == null)
downloading.Downloading.DownloadedFiles = new List<string>(); downloading.Downloading.DownloadedFiles = new List<string>();
if (downloading.Downloading.DownloadedFiles.Contains(key)) // 还要检查一下文件有没有被人删掉,删掉的话重新下载
// 如果下载视频之后音频文件被人删了。此时gid还是视频的会下错文件
if (downloading.Downloading.DownloadedFiles.Contains(key) && File.Exists(Path.Combine(path, fileName)))
return Path.Combine(path, fileName); return Path.Combine(path, fileName);
if (downloading.Downloading.DownloadFiles.ContainsKey(key)) if (downloading.Downloading.DownloadFiles.ContainsKey(key))
{ {
@ -171,6 +176,7 @@ namespace DownKyi.Services.Download
{ {
case DownloadResult.SUCCESS: case DownloadResult.SUCCESS:
downloading.Downloading.DownloadedFiles.Add(key); downloading.Downloading.DownloadedFiles.Add(key);
downloading.Downloading.Gid = null;
return Path.Combine(path, fileName); return Path.Combine(path, fileName);
case DownloadResult.FAILED: case DownloadResult.FAILED:
case DownloadResult.ABORT: case DownloadResult.ABORT:
@ -419,10 +425,17 @@ namespace DownKyi.Services.Download
} }
/// <summary> /// <summary>
/// 停止下载服务 /// 停止下载服务(转换await和Task.Wait两种调用形式)
/// </summary> /// </summary>
public void End() private async Task EndTask()
{ {
// 结束任务
tokenSource.Cancel();
await workTask;
//先简单等待一下
// 下载数据存储服务 // 下载数据存储服务
DownloadStorageService downloadStorageService = new DownloadStorageService(); DownloadStorageService downloadStorageService = new DownloadStorageService();
// 保存数据 // 保存数据
@ -441,7 +454,7 @@ namespace DownKyi.Services.Download
case DownloadStatus.DOWNLOADING: case DownloadStatus.DOWNLOADING:
// TODO 添加设置让用户选择重启后是否自动开始下载 // TODO 添加设置让用户选择重启后是否自动开始下载
item.Downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; item.Downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD;
item.Downloading.DownloadStatus = DownloadStatus.PAUSE; //item.Downloading.DownloadStatus = DownloadStatus.PAUSE;
break; break;
case DownloadStatus.DOWNLOAD_SUCCEED: case DownloadStatus.DOWNLOAD_SUCCEED:
case DownloadStatus.DOWNLOAD_FAILED: case DownloadStatus.DOWNLOAD_FAILED:
@ -460,29 +473,35 @@ namespace DownKyi.Services.Download
} }
// 关闭Aria服务器 // 关闭Aria服务器
CloseAriaServer(); await CloseAriaServer();
}
// 结束任务 /// <summary>
tokenSource.Cancel(); /// 停止下载服务
/// </summary>
public void End()
{
Task.Run(EndTask).Wait();
} }
/// <summary> /// <summary>
/// 启动下载服务 /// 启动下载服务
/// </summary> /// </summary>
public async void Start() public void Start()
{ {
// 启动Aria服务器 // 启动Aria服务器
StartAriaServer(); StartAriaServer();
await Task.Run(DoWork, (tokenSource = new CancellationTokenSource()).Token); tokenSource = new CancellationTokenSource();
cancellationToken = tokenSource.Token;
workTask = Task.Run(DoWork);
} }
/// <summary> /// <summary>
/// 执行任务 /// 执行任务
/// </summary> /// </summary>
private void DoWork() private async Task DoWork()
{ {
CancellationToken cancellationToken = tokenSource.Token;
while (true) while (true)
{ {
int maxDownloading = SettingsManager.GetInstance().GetAriaMaxConcurrentDownloads(); int maxDownloading = SettingsManager.GetInstance().GetAriaMaxConcurrentDownloads();
@ -490,6 +509,7 @@ namespace DownKyi.Services.Download
try try
{ {
downloadingTasks.RemoveAll((m) => m.IsCompleted);
foreach (DownloadingItem downloading in downloadingList) foreach (DownloadingItem downloading in downloadingList)
{ {
if (downloading.Downloading.DownloadStatus == DownloadStatus.DOWNLOADING) if (downloading.Downloading.DownloadStatus == DownloadStatus.DOWNLOADING)
@ -508,7 +528,9 @@ namespace DownKyi.Services.Download
// 开始下载 // 开始下载
if (downloading.Downloading.DownloadStatus == DownloadStatus.NOT_STARTED || downloading.Downloading.DownloadStatus == DownloadStatus.WAIT_FOR_DOWNLOAD) if (downloading.Downloading.DownloadStatus == DownloadStatus.NOT_STARTED || downloading.Downloading.DownloadStatus == DownloadStatus.WAIT_FOR_DOWNLOAD)
{ {
SingleDownload(downloading); //这里需要立刻设置状态否则如果SingleDownload没有及时执行会重复创建任务
downloading.Downloading.DownloadStatus = DownloadStatus.DOWNLOADING;
downloadingTasks.Add(SingleDownload(downloading));
downloadingCount++; downloadingCount++;
} }
} }
@ -533,7 +555,14 @@ namespace DownKyi.Services.Download
} }
// 降低CPU占用 // 降低CPU占用
Thread.Sleep(500); await Task.Delay(500);
}
await Task.WhenAny(Task.WhenAll(downloadingTasks), Task.Delay(30000));
foreach (Task tsk in downloadingTasks.FindAll((m) => !m.IsCompleted))
{
Core.Utils.Debugging.Console.PrintLine("AriaDownloadService: 任务结束超时");
LogManager.Debug(Tag, "任务结束超时");
} }
} }
@ -542,7 +571,7 @@ namespace DownKyi.Services.Download
/// </summary> /// </summary>
/// <param name="downloading"></param> /// <param name="downloading"></param>
/// <returns></returns> /// <returns></returns>
private async void SingleDownload(DownloadingItem downloading) private async Task SingleDownload(DownloadingItem downloading)
{ {
// 路径 // 路径
string[] temp = downloading.DownloadBase.FilePath.Split('/'); string[] temp = downloading.DownloadBase.FilePath.Split('/');
@ -567,12 +596,6 @@ namespace DownKyi.Services.Download
// 暂停 // 暂停
Pause(downloading); Pause(downloading);
// 是否存在
var isExist = IsExist(downloading);
if (!isExist.Result)
{
return;
}
string audioUid = null; string audioUid = null;
// 如果需要下载音频 // 如果需要下载音频
@ -596,12 +619,6 @@ namespace DownKyi.Services.Download
// 暂停 // 暂停
Pause(downloading); Pause(downloading);
// 是否存在
isExist = IsExist(downloading);
if (!isExist.Result)
{
return;
}
string videoUid = null; string videoUid = null;
// 如果需要下载视频 // 如果需要下载视频
@ -625,12 +642,6 @@ namespace DownKyi.Services.Download
// 暂停 // 暂停
Pause(downloading); Pause(downloading);
// 是否存在
isExist = IsExist(downloading);
if (!isExist.Result)
{
return;
}
string outputDanmaku = null; string outputDanmaku = null;
// 如果需要下载弹幕 // 如果需要下载弹幕
@ -641,12 +652,6 @@ namespace DownKyi.Services.Download
// 暂停 // 暂停
Pause(downloading); Pause(downloading);
// 是否存在
isExist = IsExist(downloading);
if (!isExist.Result)
{
return;
}
List<string> outputSubtitles = null; List<string> outputSubtitles = null;
// 如果需要下载字幕 // 如果需要下载字幕
@ -657,12 +662,6 @@ namespace DownKyi.Services.Download
// 暂停 // 暂停
Pause(downloading); Pause(downloading);
// 是否存在
isExist = IsExist(downloading);
if (!isExist.Result)
{
return;
}
string outputCover = null; string outputCover = null;
string outputPageCover = null; string outputPageCover = null;
@ -679,12 +678,6 @@ namespace DownKyi.Services.Download
// 暂停 // 暂停
Pause(downloading); Pause(downloading);
// 是否存在
isExist = IsExist(downloading);
if (!isExist.Result)
{
return;
}
// 混流 // 混流
string outputMedia = string.Empty; string outputMedia = string.Empty;
@ -693,14 +686,13 @@ namespace DownKyi.Services.Download
outputMedia = MixedFlow(downloading, audioUid, videoUid); outputMedia = MixedFlow(downloading, audioUid, videoUid);
} }
// 暂停 // 这里本来只有IsExist没有pause不知道怎么处理
//Pause(downloading);
// 是否存在 // 是否存在
isExist = IsExist(downloading); //isExist = IsExist(downloading);
if (!isExist.Result) //if (!isExist.Result)
{ //{
return; // return;
} //}
// 检测音频、视频是否下载成功 // 检测音频、视频是否下载成功
bool isMediaSuccess = true; bool isMediaSuccess = true;
@ -847,11 +839,19 @@ namespace DownKyi.Services.Download
/// <param name="downloading"></param> /// <param name="downloading"></param>
private void Pause(DownloadingItem downloading) private void Pause(DownloadingItem downloading)
{ {
cancellationToken.ThrowIfCancellationRequested();
downloading.DownloadStatusTitle = DictionaryResource.GetString("Pausing"); downloading.DownloadStatusTitle = DictionaryResource.GetString("Pausing");
if (downloading.Downloading.DownloadStatus == DownloadStatus.PAUSE) if (downloading.Downloading.DownloadStatus == DownloadStatus.PAUSE)
{ {
throw new OperationCanceledException("Stop thread by pause"); throw new OperationCanceledException("Stop thread by pause");
} }
// 是否存在
var isExist = IsExist(downloading);
if (!isExist.Result)
{
throw new OperationCanceledException("Task is deleted");
}
} }
/// <summary> /// <summary>
@ -915,26 +915,28 @@ namespace DownKyi.Services.Download
}; };
var task = await AriaServer.StartServerAsync(config); var task = await AriaServer.StartServerAsync(config);
if (task) { Console.WriteLine("Start ServerAsync Completed"); } if (task) { Console.WriteLine("Start ServerAsync Completed"); }
for (int i = 0; i < 10; i++)
{
var globOpt = await AriaClient.GetGlobalOptionAsync();
if (globOpt != null)
break;
await Task.Delay(1000);
}
Console.WriteLine("Start ServerAsync end"); Console.WriteLine("Start ServerAsync end");
} }
/// <summary> /// <summary>
/// 关闭Aria服务器 /// 关闭Aria服务器
/// </summary> /// </summary>
private void CloseAriaServer() private async Task CloseAriaServer()
{ {
new Thread(() => // 暂停所有下载
{ var ariaPause = await AriaClient.PauseAllAsync();
// 暂停所有下载 Core.Utils.Debugging.Console.PrintLine(ariaPause.ToString());
var ariaPause = AriaClient.PauseAllAsync();
Core.Utils.Debugging.Console.PrintLine(ariaPause.ToString()); // 关闭服务器
bool close = AriaServer.CloseServer();
// 关闭服务器 Core.Utils.Debugging.Console.PrintLine(close);
bool close = AriaServer.CloseServer();
Core.Utils.Debugging.Console.PrintLine(close);
})
{ IsBackground = false }
.Start();
} }
/// <summary> /// <summary>
@ -955,6 +957,14 @@ namespace DownKyi.Services.Download
Task<AriaTellStatus> status = AriaClient.TellStatus(downloading.Downloading.Gid); Task<AriaTellStatus> status = AriaClient.TellStatus(downloading.Downloading.Gid);
if (status == null || status.Result == null) if (status == null || status.Result == null)
downloading.Downloading.Gid = null; downloading.Downloading.Gid = null;
else if (status.Result.Result == null && status.Result.Error != null)
{
if (status.Result.Error.Message.Contains("is not found"))
{
downloading.Downloading.Gid = null;
}
}
} }
if (downloading.Downloading.Gid == null) if (downloading.Downloading.Gid == null)
@ -997,6 +1007,7 @@ namespace DownKyi.Services.Download
ariaManager.DownloadFinish += AriaDownloadFinish; ariaManager.DownloadFinish += AriaDownloadFinish;
return ariaManager.GetDownloadStatus(downloading.Downloading.Gid, new Action(() => return ariaManager.GetDownloadStatus(downloading.Downloading.Gid, new Action(() =>
{ {
cancellationToken.ThrowIfCancellationRequested();
switch (downloading.Downloading.DownloadStatus) switch (downloading.Downloading.DownloadStatus)
{ {
case DownloadStatus.PAUSE: case DownloadStatus.PAUSE:

Loading…
Cancel
Save