new_version_init
This commit is contained in:
201
VDownload.Tasks/DownloadTask.cs
Normal file
201
VDownload.Tasks/DownloadTask.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Common;
|
||||
using VDownload.Common.Models;
|
||||
|
||||
namespace VDownload.Tasks
|
||||
{
|
||||
public partial class DownloadTask : ObservableObject
|
||||
{
|
||||
#region FIELDS
|
||||
|
||||
private CancellationTokenSource? _cancellationTokenSource;
|
||||
|
||||
private Task _downloadTask;
|
||||
|
||||
private DispatcherQueue _dispatcherQueue;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PROPERTIES
|
||||
|
||||
[ObservableProperty]
|
||||
private Video _video;
|
||||
|
||||
[ObservableProperty]
|
||||
private VideoStream _videoStream;
|
||||
|
||||
[ObservableProperty]
|
||||
private MediaType _mediaType;
|
||||
|
||||
[ObservableProperty]
|
||||
private TimeSpan _trimStart;
|
||||
|
||||
[ObservableProperty]
|
||||
private TimeSpan _trimEnd;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _directoryPath;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _filename;
|
||||
|
||||
[ObservableProperty]
|
||||
private VideoExtension _videoExtension;
|
||||
|
||||
[ObservableProperty]
|
||||
private AudioExtension _audioExtension;
|
||||
|
||||
[ObservableProperty]
|
||||
private DownloadTaskStatus _status;
|
||||
|
||||
[ObservableProperty]
|
||||
private DateTime _createDate;
|
||||
|
||||
[ObservableProperty]
|
||||
private double _progress;
|
||||
|
||||
public TimeSpan DurationAfterTrim
|
||||
{
|
||||
get => _durationAfterTrim;
|
||||
protected set => SetProperty(ref _durationAfterTrim, value);
|
||||
}
|
||||
protected TimeSpan _durationAfterTrim;
|
||||
|
||||
public bool IsTrimmed
|
||||
{
|
||||
get => _isTrimmed;
|
||||
protected set => SetProperty(ref _isTrimmed, value);
|
||||
}
|
||||
protected bool _isTrimmed;
|
||||
|
||||
public string FilePath
|
||||
{
|
||||
get => _filePath;
|
||||
protected set => SetProperty(ref _filePath, value);
|
||||
}
|
||||
protected string _filePath;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public DownloadTask(Video video)
|
||||
{
|
||||
base.PropertyChanged += PropertyChanged;
|
||||
|
||||
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
_video = video;
|
||||
_videoStream = _video.Streams[0];
|
||||
_mediaType = MediaType.Original; // TODO: get from settings
|
||||
_trimStart = TimeSpan.Zero;
|
||||
_trimEnd = _video.Duration;
|
||||
_directoryPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); // TODO: get from settings
|
||||
_filename = _video.Title.Length > 50 ? _video.Title.Substring(0, 50) : _video.Title;
|
||||
_videoExtension = VideoExtension.MP4; // TODO: get from settings
|
||||
_audioExtension = AudioExtension.MP3; // TODO: get from settings
|
||||
_status = DownloadTaskStatus.Idle;
|
||||
_createDate = DateTime.Now;
|
||||
_progress = 0;
|
||||
_durationAfterTrim = _video.Duration;
|
||||
_isTrimmed = false;
|
||||
_filePath = $"{DirectoryPath}/{Filename}.{((object)(MediaType == MediaType.OnlyAudio ? AudioExtension : VideoExtension)).ToString().ToLower()}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PUBLIC METHODS
|
||||
|
||||
public void Enqueue()
|
||||
{
|
||||
DownloadTaskStatus[] statuses =
|
||||
[
|
||||
DownloadTaskStatus.Idle,
|
||||
DownloadTaskStatus.EndedUnsuccessfully,
|
||||
DownloadTaskStatus.EndedSuccessfully,
|
||||
DownloadTaskStatus.EndedCancelled,
|
||||
];
|
||||
if (statuses.Contains(Status))
|
||||
{
|
||||
Status = DownloadTaskStatus.Queued;
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
UpdateStatusWithDispatcher(DownloadTaskStatus.Initializing);
|
||||
|
||||
_downloadTask = Task.Run(Download);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
if (_cancellationTokenSource is not null)
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
_cancellationTokenSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PRIVATE METHODS
|
||||
|
||||
private void Download()
|
||||
{
|
||||
CancellationToken token = _cancellationTokenSource.Token;
|
||||
}
|
||||
|
||||
private void UpdateStatusWithDispatcher(DownloadTaskStatus status)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(() => Status = status);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region EVENT HANDLERS
|
||||
|
||||
private void PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(Filename):
|
||||
case nameof(DirectoryPath):
|
||||
case nameof(VideoExtension):
|
||||
case nameof(AudioExtension):
|
||||
FilePath = $"{DirectoryPath}/{Filename}.{((object)(MediaType == MediaType.OnlyAudio ? AudioExtension : VideoExtension)).ToString().ToLower()}";
|
||||
break;
|
||||
case nameof(TrimStart):
|
||||
case nameof(TrimEnd):
|
||||
DurationAfterTrim = TrimEnd.Subtract(TrimStart);
|
||||
break;
|
||||
case nameof(DurationAfterTrim):
|
||||
IsTrimmed = DurationAfterTrim != Video.Duration;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
21
VDownload.Tasks/DownloadTaskStatus.cs
Normal file
21
VDownload.Tasks/DownloadTaskStatus.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Common
|
||||
{
|
||||
public enum DownloadTaskStatus
|
||||
{
|
||||
Idle,
|
||||
EndedSuccessfully,
|
||||
EndedUnsuccessfully,
|
||||
EndedCancelled,
|
||||
Queued,
|
||||
Initializing,
|
||||
Processing,
|
||||
Downloading,
|
||||
Finalizing,
|
||||
}
|
||||
}
|
||||
101
VDownload.Tasks/DownloadTasksManager.cs
Normal file
101
VDownload.Tasks/DownloadTasksManager.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Common;
|
||||
|
||||
namespace VDownload.Tasks
|
||||
{
|
||||
public interface IDownloadTasksManager
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
ObservableCollection<DownloadTask> Tasks { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region METHODS
|
||||
|
||||
void AddTask(DownloadTask task);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class DownloadTasksManager : IDownloadTasksManager
|
||||
{
|
||||
#region FIELDS
|
||||
|
||||
private readonly Task _taskMonitor;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PROPERTIES
|
||||
|
||||
public ObservableCollection<DownloadTask> Tasks { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public DownloadTasksManager()
|
||||
{
|
||||
Tasks = new ObservableCollection<DownloadTask>();
|
||||
|
||||
_taskMonitor = Task.Run(TaskMonitor);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PUBLIC METHODS
|
||||
|
||||
public void AddTask(DownloadTask task)
|
||||
{
|
||||
Tasks.Add(task);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PRIVATE METHODS
|
||||
|
||||
private void TaskMonitor()
|
||||
{
|
||||
int maxTaskNumber = 5; //TODO: from settings
|
||||
DownloadTaskStatus[] pendingStatuses =
|
||||
[
|
||||
DownloadTaskStatus.Initializing,
|
||||
DownloadTaskStatus.Downloading,
|
||||
DownloadTaskStatus.Processing,
|
||||
DownloadTaskStatus.Finalizing
|
||||
];
|
||||
while (true)
|
||||
{
|
||||
IEnumerable<DownloadTask> pendingTasks = Tasks.Where(x => pendingStatuses.Contains(x.Status));
|
||||
int freeSlots = maxTaskNumber - pendingTasks.Count();
|
||||
if (freeSlots > 0)
|
||||
{
|
||||
IEnumerable<DownloadTask> queuedTasks = Tasks.Where(x => x.Status == DownloadTaskStatus.Queued).OrderBy(x => x.CreateDate).Take(freeSlots);
|
||||
foreach (DownloadTask queuedTask in queuedTasks)
|
||||
{
|
||||
queuedTask.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
19
VDownload.Tasks/VDownload.Tasks.csproj
Normal file
19
VDownload.Tasks/VDownload.Tasks.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<RootNamespace>VDownload.Tasks</RootNamespace>
|
||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<UseRidGraph>true</UseRidGraph>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.230913002" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.755" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VDownload.Common\VDownload.Common.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user