twitch vod downloading done

ffmpeg essentials

fix

Project reorganized

git lfs

ffmpeg removed

ffmpeg added
This commit is contained in:
2024-02-14 02:07:22 +01:00
Unverified
parent 91f9b645bd
commit e3ec5c3a48
264 changed files with 6239 additions and 4014 deletions

View File

@@ -0,0 +1,90 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VDownload.Core.Tasks;
namespace VDownload.Core.ViewModels.Home
{
public partial class HomeDownloadsViewModel : ObservableObject
{
#region SERVICES
protected readonly IDownloadTaskManager _tasksManager;
#endregion
#region PROPERTIES
public ReadOnlyObservableCollection<DownloadTask> Tasks => _tasksManager.Tasks;
[ObservableProperty]
private bool _taskListIsEmpty;
#endregion
#region CONSTRUCTORS
public HomeDownloadsViewModel(IDownloadTaskManager tasksManager)
{
_tasksManager = tasksManager;
_tasksManager.TaskCollectionChanged += Tasks_CollectionChanged;
_taskListIsEmpty = _tasksManager.Tasks.Count == 0;
}
#endregion
#region PUBLIC METHODS
[RelayCommand]
public async Task StartCancelTask(DownloadTask task)
{
DownloadTaskStatus[] idleStatuses =
[
DownloadTaskStatus.Idle,
DownloadTaskStatus.EndedUnsuccessfully,
DownloadTaskStatus.EndedSuccessfully,
DownloadTaskStatus.EndedCancelled
];
if (idleStatuses.Contains(task.Status))
{
task.Enqueue();
}
else
{
await task.Cancel();
}
}
[RelayCommand]
public async Task RemoveTask(DownloadTask task)
{
await task.Cancel();
_tasksManager.RemoveTask(task);
}
#endregion
#region PRIVATE METHODS
private void Tasks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
TaskListIsEmpty = Tasks.Count == 0;
}
#endregion
}
}

View File

@@ -0,0 +1,185 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VDownload.Core.Tasks;
using VDownload.Models;
using VDownload.Services.Data.Settings;
using VDownload.Services.UI.StoragePicker;
namespace VDownload.Core.ViewModels.Home
{
public partial class HomeVideoViewModel : ObservableObject
{
#region SERVICES
protected readonly IDownloadTaskManager _tasksManager;
protected readonly ISettingsService _settingsService;
protected readonly IStoragePickerService _storagePickerService;
#endregion
#region FIELDS
protected Video _video;
#endregion
#region PROPERTIES
[ObservableProperty]
protected Uri _thumbnailUrl;
[ObservableProperty]
protected string _title;
[ObservableProperty]
protected string _author;
[ObservableProperty]
protected DateTime _publishDate;
[ObservableProperty]
protected TimeSpan _duration;
[ObservableProperty]
protected long _views;
[ObservableProperty]
protected ObservableCollection<VideoStream> _streams;
[ObservableProperty]
protected VideoStream _selectedStream;
[ObservableProperty]
protected MediaType _mediaType;
[ObservableProperty]
protected TimeSpan _trimStart;
[ObservableProperty]
protected TimeSpan _trimEnd;
[ObservableProperty]
protected string _directoryPath;
[ObservableProperty]
protected string _filename;
[ObservableProperty]
protected VideoExtension _videoExtension;
[ObservableProperty]
protected AudioExtension _audioExtension;
#endregion
#region EVENTS
public event EventHandler TaskAdded;
#endregion
#region CONSTRUCTORS
public HomeVideoViewModel(IDownloadTaskManager tasksManager, ISettingsService settingsService, IStoragePickerService storagePickerService)
{
_tasksManager = tasksManager;
_settingsService = settingsService;
_storagePickerService = storagePickerService;
}
#endregion
#region PUBLIC METHODS
public async void LoadVideo(Video video)
{
await _settingsService.Load();
_video = video;
ThumbnailUrl = video.ThumbnailUrl;
Title = video.Title;
Author = video.Author;
PublishDate = video.PublishDate;
Duration = video.Duration;
Views = video.Views;
Streams = [.. video.Streams];
SelectedStream = Streams[0];
MediaType = _settingsService.Data.Common.DefaultTaskSettings.MediaType;
TrimStart = TimeSpan.Zero;
TrimEnd = Duration;
DirectoryPath = _settingsService.Data.Common.DefaultTaskSettings.OutputDirectory;
Filename = Title.Length > 50 ? Title.Substring(0, 50) : Title;
VideoExtension = _settingsService.Data.Common.DefaultTaskSettings.VideoExtension;
AudioExtension = _settingsService.Data.Common.DefaultTaskSettings.AudioExtension;
}
[RelayCommand]
public async Task Browse()
{
string? newDirectory = await _storagePickerService.OpenDirectory();
if (newDirectory is not null)
{
this.DirectoryPath = newDirectory;
}
}
[RelayCommand]
public void CreateTask()
{
_tasksManager.AddTask(_video, BuildDownloadOptions());
TaskAdded?.Invoke(this, EventArgs.Empty);
}
[RelayCommand]
public void CreateTaskAndDownload()
{
DownloadTask task = _tasksManager.AddTask(_video, BuildDownloadOptions());
TaskAdded?.Invoke(this, EventArgs.Empty);
task.Enqueue();
}
#endregion
#region PRIVATE METHODS
protected VideoDownloadOptions BuildDownloadOptions()
{
return new VideoDownloadOptions(Duration)
{
MediaType = this.MediaType,
SelectedStream = this.SelectedStream,
TrimStart = this.TrimStart,
TrimEnd = this.TrimEnd,
Directory = this.DirectoryPath,
Filename = string.Join("_", this.Filename.Split(Path.GetInvalidFileNameChars())),
Extension = (this.MediaType == MediaType.OnlyAudio ? this.AudioExtension.ToString() : this.VideoExtension.ToString()).ToLower(),
};
}
#endregion
}
}

View File

@@ -0,0 +1,248 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VDownload.Models;
using VDownload.Services.Data.Configuration;
using VDownload.Services.Data.Settings;
using VDownload.Services.UI.StringResources;
using VDownload.Sources;
using VDownload.Sources.Common;
namespace VDownload.Core.ViewModels.Home
{
public partial class HomeViewModel : ObservableObject
{
#region ENUMS
public enum OptionBarContentType
{
None,
VideoSearch,
PlaylistSearch
}
public enum MainContentType
{
Downloads,
Video
}
#endregion
#region SERVICES
protected readonly IConfigurationService _configurationService;
protected readonly ISettingsService _settingsService;
protected readonly IStringResourcesService _stringResourcesService;
protected readonly ISearchService _searchService;
protected readonly HomeVideoViewModel _videoViewModel;
#endregion
#region FIELDS
protected readonly Type _downloadsView = typeof(HomeDownloadsViewModel);
protected readonly Type _videoView = typeof(HomeVideoViewModel);
#endregion
#region PROPERTIES
[ObservableProperty]
private Type _mainContent;
[ObservableProperty]
private OptionBarContentType _optionBarContent;
[ObservableProperty]
private string _optionBarMessage;
[ObservableProperty]
private bool _optionBarLoading;
[ObservableProperty]
private bool _optionBarVideoSearchButtonChecked;
[ObservableProperty]
private bool _optionBarPlaylistSearchButtonChecked;
[ObservableProperty]
private bool _optionBarSearchNotPending;
[ObservableProperty]
private string _optionBarVideoSearchTBValue;
[ObservableProperty]
private string _optionBarPlaylistSearchTBValue;
[ObservableProperty]
private int _optionBarPlaylistSearchNBValue;
#endregion
#region CONSTRUCTORS
public HomeViewModel(IConfigurationService configurationService, ISettingsService settingsService, IStringResourcesService stringResourcesService, ISearchService searchService, HomeVideoViewModel videoViewModel)
{
_configurationService = configurationService;
_settingsService = settingsService;
_stringResourcesService = stringResourcesService;
_searchService = searchService;
_videoViewModel = videoViewModel;
_videoViewModel.TaskAdded += VideoViewModel_TaskAdded;
}
#endregion
#region COMMANDS
[RelayCommand]
public async Task Navigation()
{
await _settingsService.Load();
MainContent = _downloadsView;
OptionBarContent = OptionBarContentType.None;
OptionBarMessage = null;
OptionBarVideoSearchButtonChecked = false;
OptionBarPlaylistSearchButtonChecked = false;
OptionBarSearchNotPending = true;
OptionBarVideoSearchTBValue = string.Empty;
OptionBarPlaylistSearchNBValue = _settingsService.Data.Common.MaxNumberOfVideosToGetFromPlaylist;
OptionBarPlaylistSearchTBValue = string.Empty;
}
[RelayCommand]
public void LoadFromSubscription()
{
MainContent = _downloadsView;
OptionBarContent = OptionBarContentType.None;
OptionBarVideoSearchButtonChecked = false;
OptionBarPlaylistSearchButtonChecked = false;
OptionBarSearchNotPending = false;
//TODO: Load videos
}
[RelayCommand]
public void VideoSearchShow()
{
MainContent = _downloadsView;
if (OptionBarContent != OptionBarContentType.VideoSearch)
{
OptionBarContent = OptionBarContentType.VideoSearch;
OptionBarPlaylistSearchButtonChecked = false;
}
else
{
OptionBarContent = OptionBarContentType.None;
}
}
[RelayCommand]
public void PlaylistSearchShow()
{
MainContent = _downloadsView;
if (OptionBarContent != OptionBarContentType.PlaylistSearch)
{
OptionBarContent = OptionBarContentType.PlaylistSearch;
OptionBarVideoSearchButtonChecked = false;
}
else
{
OptionBarContent = OptionBarContentType.None;
}
}
[RelayCommand]
public async Task VideoSearchStart()
{
OptionBarSearchNotPending = false;
OptionBarLoading = true;
OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
Video video;
try
{
video = await _searchService.SearchVideo(OptionBarVideoSearchTBValue);
}
catch (MediaSearchException ex)
{
OptionBarLoading = false;
OptionBarMessage = ex.Message;
OptionBarSearchNotPending = true;
return;
}
_videoViewModel.LoadVideo(video);
MainContent = _videoView;
OptionBarSearchNotPending = true;
OptionBarLoading = false;
OptionBarMessage = null;
}
[RelayCommand]
public async Task PlaylistSearchStart()
{
OptionBarSearchNotPending = false;
OptionBarLoading = true;
OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
Playlist playlist;
try
{
playlist = await _searchService.SearchPlaylist(OptionBarPlaylistSearchTBValue, OptionBarPlaylistSearchNBValue);
}
catch (MediaSearchException ex)
{
OptionBarLoading = false;
OptionBarMessage = ex.Message;
OptionBarSearchNotPending = true;
return;
}
OptionBarSearchNotPending = true;
OptionBarLoading = false;
OptionBarMessage = null;
}
[RelayCommand]
public void Download()
{
}
#endregion
#region PRIVATE METHODS
private async void VideoViewModel_TaskAdded(object sender, EventArgs e) => await Navigation();
#endregion
}
}