diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw
index f6b9601..07e88ad 100644
--- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw
+++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw
@@ -117,6 +117,21 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ No internet connection. Try again later.
+
+
+ Error
+
+
+ Downloading timeout. Check your internet connection and try again later.
+
+
+ FFmpeg exited with error.
+
+
+ No FFmpeg executables found. Check path in settings and try again.
+
Cancelled
diff --git a/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs b/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
index 05fa933..f19fd9b 100644
--- a/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
+++ b/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
@@ -13,6 +13,9 @@ using System.IO;
using VDownload.Services.UI.Notifications;
using VDownload.Services.UI.StringResources;
using System.Collections.Generic;
+using System.Net.Http;
+using Instances.Exceptions;
+using FFMpegCore.Exceptions;
namespace VDownload.Core.Tasks
{
@@ -140,7 +143,11 @@ namespace VDownload.Core.Tasks
await _settingsService.Load();
- string tempDirectory = $"{_settingsService.Data.Common.Temp.Directory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{Id}";
+ string tempDirectory = $"{_settingsService.Data.Common.Temp.Directory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{Guid.NewGuid()}";
+ if (Directory.Exists(tempDirectory))
+ {
+ Directory.Delete(tempDirectory, true);
+ }
Directory.CreateDirectory(tempDirectory);
List content = new List()
@@ -180,10 +187,11 @@ namespace VDownload.Core.Tasks
.JoinProgressReporter(onProgressProcessing, downloadResult.NewDuration);
await ffmpegBuilder.RunAsync(downloadResult.File, outputPath);
+ StorageFile outputFile = await StorageFile.GetFileFromPathAsync(outputPath);
+
UpdateStatusWithDispatcher(DownloadTaskStatus.Finalizing);
- string destination = $"{DownloadOptions.Directory}\\{DownloadOptions.Filename}.{DownloadOptions.Extension}";
- File.Copy(outputPath, destination, true);
+ await Finalizing(outputFile);
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedSuccessfully);
@@ -199,7 +207,26 @@ namespace VDownload.Core.Tasks
}
catch (Exception ex)
{
- UpdateErrorWithDispatcher(ex.Message);
+ string message;
+
+ if (ex is TaskCanceledException || ex is HttpRequestException)
+ {
+ message = _stringResourcesService.HomeDownloadsViewResources.Get("ErrorDownloadingTimeout");
+ }
+ else if (ex is InstanceFileNotFoundException)
+ {
+ message = _stringResourcesService.HomeDownloadsViewResources.Get("ErrorFFmpegPath");
+ }
+ else if (ex is FFMpegException)
+ {
+ message = _stringResourcesService.HomeDownloadsViewResources.Get("ErrorFFmpeg");
+ }
+ else
+ {
+ message = ex.Message;
+ }
+
+ UpdateErrorWithDispatcher(message);
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedUnsuccessfully);
if (_settingsService.Data.Common.Notifications.OnUnsuccessful)
@@ -218,11 +245,19 @@ namespace VDownload.Core.Tasks
}
}
- private void UpdateStatusWithDispatcher(DownloadTaskStatus status) => _dispatcherQueue.TryEnqueue(() => Status = status);
+ protected async Task Finalizing(StorageFile outputFile)
+ {
+ StorageFolder destination = await StorageFolder.GetFolderFromPathAsync(DownloadOptions.Directory);
- private void UpdateProgressWithDispatcher(double progress) => _dispatcherQueue.TryEnqueue(() => Progress = progress);
+ string filename = $"{DownloadOptions.Filename}.{DownloadOptions.Extension}";
+ await outputFile.CopyAsync(destination, filename, NameCollisionOption.ReplaceExisting);
+ }
- private void UpdateErrorWithDispatcher(string message) => _dispatcherQueue.TryEnqueue(() => Error = message);
+ protected void UpdateStatusWithDispatcher(DownloadTaskStatus status) => _dispatcherQueue.TryEnqueue(() => Status = status);
+
+ protected void UpdateProgressWithDispatcher(double progress) => _dispatcherQueue.TryEnqueue(() => Progress = progress);
+
+ protected void UpdateErrorWithDispatcher(string message) => _dispatcherQueue.TryEnqueue(() => Error = message);
#endregion
}
diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs
index cf82579..7d03e7f 100644
--- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs
+++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs
@@ -68,6 +68,14 @@ namespace VDownload.Core.ViewModels.Home
];
if (idleStatuses.Contains(task.Status))
{
+ if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
+ {
+ string title = _stringResourcesService.HomeDownloadsViewResources.Get("DialogErrorTitle");
+ string message = _stringResourcesService.HomeDownloadsViewResources.Get("DialogErrorMessageNoInternetConnection");
+ await _dialogsService.ShowOk(title, message);
+ return;
+ }
+
bool continueEnqueue = true;
if (NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection)
{
diff --git a/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.FFmpeg/FFmpegBuilder.cs b/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.FFmpeg/FFmpegBuilder.cs
index fc635da..33ea457 100644
--- a/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.FFmpeg/FFmpegBuilder.cs
+++ b/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.FFmpeg/FFmpegBuilder.cs
@@ -40,6 +40,9 @@ namespace VDownload.Services.Utility.FFmpeg
protected string _inputFile;
protected string _outputFile;
+ protected string _audioCodec;
+ protected string _videoCodec;
+
protected FFOptions _options;
#endregion
@@ -103,6 +106,10 @@ namespace VDownload.Services.Utility.FFmpeg
_inputFile = inputFile;
_outputFile = outputFile;
+ IMediaAnalysis analysis = await FFProbe.AnalyseAsync(_inputFile, _options);
+ _audioCodec = analysis.AudioStreams.First().CodecName;
+ _videoCodec = analysis.VideoStreams.First().CodecName;
+
FFMpegArgumentProcessor ffmpegArguments = FFMpegArguments.FromFileInput(inputFile, true, async (options) => await BuildInputArgumentOptions(options))
.OutputToFile(outputFile, true, async (options) => await BuildOutputArgumentOptions(options));
@@ -154,17 +161,13 @@ namespace VDownload.Services.Utility.FFmpeg
private async Task BuildOutputArgumentOptions(FFMpegArgumentOptions options)
{
- IMediaAnalysis analysis = await FFProbe.AnalyseAsync(_inputFile, _options);
- string audioCodec = analysis.AudioStreams.First().CodecName;
- string videoCodec = analysis.VideoStreams.First().CodecName;
-
string extension = Path.GetExtension(_outputFile).Replace(".", string.Empty);
Data.Configuration.Models.Muxer muxer = _configurationService.Common.Processing.Muxers.First(x => x.Extension == extension);
if (_mediaType != MediaType.OnlyAudio)
{
IEnumerable availableCodecs = muxer.VideoCodecs;
- string selectedCodec = availableCodecs.Contains(videoCodec) ? "copy" : availableCodecs.First();
+ string selectedCodec = availableCodecs.Contains(_videoCodec) ? "copy" : availableCodecs.First();
options.WithCustomArgument($"-vcodec {selectedCodec}");
}
else
@@ -175,7 +178,7 @@ namespace VDownload.Services.Utility.FFmpeg
if (_mediaType != MediaType.OnlyVideo)
{
IEnumerable availableCodecs = muxer.AudioCodecs;
- string selectedCodec = availableCodecs.Contains(audioCodec) ? "copy" : availableCodecs.First();
+ string selectedCodec = availableCodecs.Contains(_audioCodec) ? "copy" : availableCodecs.First();
options.WithCustomArgument($"-acodec {selectedCodec}");
}
else
diff --git a/VDownload.Sources/VDownload.Sources.Twitch/VDownload.Sources.Twitch.Models/TwitchVodStream.cs b/VDownload.Sources/VDownload.Sources.Twitch/VDownload.Sources.Twitch.Models/TwitchVodStream.cs
index 5c00f2f..2e052c2 100644
--- a/VDownload.Sources/VDownload.Sources.Twitch/VDownload.Sources.Twitch.Models/TwitchVodStream.cs
+++ b/VDownload.Sources/VDownload.Sources.Twitch/VDownload.Sources.Twitch.Models/TwitchVodStream.cs
@@ -145,15 +145,17 @@ namespace VDownload.Sources.Twitch.Models
{
token.ThrowIfCancellationRequested();
- using (FileStream inputStream = File.OpenRead(path))
+ using (FileStream inputStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
inputStream.CopyTo(outputStream);
}
-
- if (deleteSource)
- {
- File.Delete(path);
- }
+ }
+ }
+ foreach (string item in sourceFiles)
+ {
+ if (deleteSource)
+ {
+ File.Delete(item);
}
}
}
@@ -184,10 +186,7 @@ namespace VDownload.Sources.Twitch.Models
int retriesCount = 0;
while (true)
{
- if (token.IsCancellationRequested)
- {
- return;
- }
+ token.ThrowIfCancellationRequested();
try
{
byte[] data = await _httpClient.GetByteArrayAsync(chunk.Url, token);
@@ -195,10 +194,6 @@ namespace VDownload.Sources.Twitch.Models
onTaskEndSuccessfully.Invoke();
return;
}
- catch (OperationCanceledException)
- {
- return;
- }
catch (Exception ex) when (ex is HttpRequestException || ex is TaskCanceledException)
{
if (_settingsService.Data.Twitch.Vod.ChunkDownloadingError.Retry && retriesCount < _settingsService.Data.Twitch.Vod.ChunkDownloadingError.RetriesCount)