2022-06-14 18:21:36 +00:00
|
|
|
using System;
|
|
|
|
using YoutubeExplode;
|
|
|
|
using YoutubeExplode.Videos;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using System.Net.Http;
|
|
|
|
using YoutubeExplode.Playlists;
|
|
|
|
using YoutubeExplode.Channels;
|
|
|
|
using System.IO;
|
|
|
|
using System.Globalization;
|
|
|
|
|
|
|
|
namespace Tesses.YouTubeDownloader
|
|
|
|
{
|
|
|
|
public class TYTDDownloaderStorageProxy : IStorage
|
|
|
|
{
|
|
|
|
public IDownloader Downloader {get;set;}
|
|
|
|
|
|
|
|
private ITYTDBase _base=null;
|
2022-06-24 23:02:51 +00:00
|
|
|
|
2022-06-14 18:21:36 +00:00
|
|
|
public ITYTDBase Storage {get {return _base;} set{_base=value;
|
|
|
|
var v = value as IStorage;
|
|
|
|
if(v != null)
|
|
|
|
SetStorage(v);}}
|
|
|
|
|
|
|
|
private void SetStorage(IStorage storage)
|
|
|
|
{
|
|
|
|
if(_storage !=null)
|
|
|
|
{
|
|
|
|
_storage.Bell -= _EVT_BELL;
|
|
|
|
_storage.BeforeSaveInfo -= _EVT_BSI;
|
|
|
|
_storage.VideoFinished -= _EVT_VFIN;
|
|
|
|
_storage.VideoProgress -= _EVT_VPROG;
|
|
|
|
_storage.VideoStarted -= _EVT_VSTAR;
|
2022-06-24 23:02:51 +00:00
|
|
|
_storage.Error -= _EVT_ERR;
|
2022-06-14 18:21:36 +00:00
|
|
|
}
|
|
|
|
_storage=storage;
|
|
|
|
if(storage != null)
|
|
|
|
{
|
|
|
|
_storage.Bell += _EVT_BELL;
|
|
|
|
_storage.BeforeSaveInfo += _EVT_BSI;
|
|
|
|
_storage.VideoFinished += _EVT_VFIN;
|
|
|
|
_storage.VideoProgress += _EVT_VPROG;
|
|
|
|
_storage.VideoStarted += _EVT_VSTAR;
|
2022-06-24 23:02:51 +00:00
|
|
|
_storage.Error += _EVT_ERR;
|
2022-06-14 18:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
private void _EVT_VSTAR(object sender,VideoStartedEventArgs evt)
|
|
|
|
{
|
|
|
|
VideoStarted?.Invoke(this,evt);
|
|
|
|
}
|
|
|
|
private void _EVT_VPROG(object sender,VideoProgressEventArgs evt)
|
|
|
|
{
|
|
|
|
VideoProgress?.Invoke(this,evt);
|
|
|
|
}
|
|
|
|
private void _EVT_VFIN(object sender,VideoFinishedEventArgs evt)
|
|
|
|
{
|
|
|
|
VideoFinished?.Invoke(this,evt);
|
|
|
|
}
|
|
|
|
private void _EVT_BSI(object sender,BeforeSaveInfoEventArgs evt)
|
|
|
|
{
|
|
|
|
BeforeSaveInfo?.Invoke(this,evt);
|
|
|
|
}
|
|
|
|
private void _EVT_BELL(object sender,BellEventArgs evt)
|
|
|
|
{
|
|
|
|
Bell?.Invoke(this,evt);
|
|
|
|
}
|
2022-06-24 23:02:51 +00:00
|
|
|
private void _EVT_ERR(object sender,TYTDErrorEventArgs evt)
|
|
|
|
{
|
|
|
|
Error?.Invoke(this,evt);
|
|
|
|
}
|
2022-06-14 18:21:36 +00:00
|
|
|
IStorage _storage=null;
|
|
|
|
|
|
|
|
public LegacyConverter Legacy {
|
|
|
|
get{
|
|
|
|
LegacyConverter conv=null;
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
conv=e.Legacy;
|
|
|
|
});
|
|
|
|
return conv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool CanDownload { get {
|
|
|
|
bool dl=false;
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
dl=e.CanDownload;
|
|
|
|
});
|
|
|
|
return dl;
|
|
|
|
} set {StorageAsStorage((e)=>{e.CanDownload=value;});} }
|
|
|
|
public IExtensionContext ExtensionContext { get {IExtensionContext ctx=null;StorageAsStorage((e)=>{ctx=e.ExtensionContext;});return ctx;} set {StorageAsStorage((e)=>{e.ExtensionContext=value;});} }
|
|
|
|
public HttpClient HttpClient
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
HttpClient clt=null;
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
clt=e.HttpClient;
|
|
|
|
});
|
|
|
|
return clt;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
e.HttpClient=value;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public YoutubeClient YoutubeClient
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
YoutubeClient clt=null;
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
clt=e.YoutubeClient;
|
|
|
|
});
|
|
|
|
return clt;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
e.YoutubeClient=value;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public event EventHandler<BellEventArgs> Bell;
|
|
|
|
public event EventHandler<VideoStartedEventArgs> VideoStarted;
|
|
|
|
public event EventHandler<BeforeSaveInfoEventArgs> BeforeSaveInfo;
|
|
|
|
public event EventHandler<VideoProgressEventArgs> VideoProgress;
|
|
|
|
public event EventHandler<VideoFinishedEventArgs> VideoFinished;
|
|
|
|
|
2022-06-24 23:02:51 +00:00
|
|
|
public event EventHandler<TYTDErrorEventArgs> Error;
|
2022-06-14 18:21:36 +00:00
|
|
|
|
|
|
|
public async Task StorageAsStorageAsync(Func<IStorage,Task> callback)
|
|
|
|
{
|
|
|
|
var store = Storage as IStorage;
|
|
|
|
if(store != null && callback != null) await callback(store);
|
|
|
|
}
|
|
|
|
public void StorageAsStorage(Action<IStorage> callback)
|
|
|
|
{
|
|
|
|
var store = Storage as IStorage;
|
|
|
|
if(store != null && callback != null) callback(store);
|
|
|
|
}
|
|
|
|
public async Task StorageAsWritableAsync(Func<IWritable,Task> callback)
|
|
|
|
{
|
|
|
|
var store = Storage as IWritable;
|
|
|
|
if(store != null && callback != null) await callback(store);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public DownloaderMigration Migration
|
|
|
|
{
|
|
|
|
get{
|
|
|
|
return new DownloaderMigration(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<Stream> OpenOrCreateAsync(string path)
|
|
|
|
{
|
|
|
|
Stream strm=Stream.Null;
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
strm=await e.OpenOrCreateAsync(path);
|
|
|
|
});
|
|
|
|
return strm;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void RenameFile(string src, string dest)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
e.RenameFile(src,dest);
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<Stream> CreateAsync(string path)
|
|
|
|
{
|
|
|
|
Stream strm=Stream.Null;
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
strm=await e.CreateAsync(path);
|
|
|
|
});
|
|
|
|
return strm;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void CreateDirectory(string path)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
e.CreateDirectory(path);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void MoveDirectory(string src, string dest)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{e.MoveDirectory(src,dest);});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void DeleteFile(string file)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{e.DeleteFile(file);});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void DeleteDirectory(string dir, bool recursive = false)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{e.DeleteDirectory(dir,recursive);});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<Stream> OpenReadAsync(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return Stream.Null;
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.OpenReadAsync(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<bool> FileExistsAsync(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return false;
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.FileExistsAsync(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<bool> DirectoryExistsAsync(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return false;
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.DirectoryExistsAsync(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<string> EnumerateFilesAsync(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage == null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var item in Storage.EnumerateFilesAsync(path))
|
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<string> EnumerateDirectoriesAsync(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage == null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var item in Storage.EnumerateDirectoriesAsync(path))
|
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task WriteAllTextAsync(string path, string data)
|
|
|
|
{
|
|
|
|
await StorageAsWritableAsync(async(e)=>{await e.WriteAllTextAsync(path,data);});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<bool> MuxVideosAsync(SavedVideo video, string videoSrc, string audioSrc, string videoDest, IProgress<double> progress = null, CancellationToken token = default)
|
|
|
|
{
|
|
|
|
bool res=false;
|
|
|
|
await StorageAsStorageAsync(async (e)=>{
|
|
|
|
res=await e.MuxVideosAsync(video,videoSrc,audioSrc,videoDest,progress,token);
|
|
|
|
});
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<bool> Continue(string path)
|
|
|
|
{
|
|
|
|
bool res=false;
|
|
|
|
await StorageAsStorageAsync(async (e)=>{
|
|
|
|
res=await e.Continue(path);
|
|
|
|
});
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task WriteVideoInfoAsync(SavedVideo channel)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async (e)=>{
|
|
|
|
await e.WriteVideoInfoAsync(channel);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task WritePlaylistInfoAsync(SavedPlaylist channel)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async (e)=>{
|
|
|
|
await e.WritePlaylistInfoAsync(channel);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task WriteChannelInfoAsync(SavedChannel channel)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async (e)=>{
|
|
|
|
await e.WriteChannelInfoAsync(channel);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void CreateDirectoryIfNotExist(string path)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
e.CreateDirectoryIfNotExist(path);
|
|
|
|
});
|
|
|
|
}
|
2022-07-13 13:59:23 +00:00
|
|
|
public void WaitTillMediaContentQueueEmpty()
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>e.WaitTillMediaContentQueueEmpty());
|
|
|
|
}
|
2022-06-14 18:21:36 +00:00
|
|
|
public Logger GetLogger()
|
|
|
|
{
|
|
|
|
Logger logger=null;
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
logger=e.GetLogger();
|
|
|
|
});
|
|
|
|
return logger;
|
|
|
|
}
|
|
|
|
|
|
|
|
public LoggerProperties GetLoggerProperties()
|
|
|
|
{
|
|
|
|
LoggerProperties properties=null;
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
properties=e.GetLoggerProperties();
|
|
|
|
});
|
|
|
|
return properties;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<bool> DownloadVideoOnlyAsync(SavedVideo video, CancellationToken token, IProgress<double> progress, bool report = true)
|
|
|
|
{
|
|
|
|
bool res=false;
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
res= await e.DownloadVideoOnlyAsync(video,token,progress,report);
|
|
|
|
});
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task MoveLegacyStreams(SavedVideo video, BestStreams streams)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.MoveLegacyStreams(video,streams);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-06-24 23:02:51 +00:00
|
|
|
public async IAsyncEnumerable<ListContentItem> GetPersonalPlaylistContentsAsync(string name)
|
2022-06-14 18:21:36 +00:00
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
IAsyncEnumerable<ListContentItem> items=null;
|
2022-06-14 18:21:36 +00:00
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
items=e.GetPersonalPlaylistContentsAsync(name);
|
|
|
|
|
|
|
|
});
|
|
|
|
if(items == null) yield break;
|
|
|
|
await foreach(var item in items)
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task AddVideoAsync(VideoId id, Resolution resolution = Resolution.PreMuxed)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Downloader != null)
|
2022-06-14 18:21:36 +00:00
|
|
|
await Downloader.AddVideoAsync(id,resolution);
|
|
|
|
}
|
2022-07-06 22:59:50 +00:00
|
|
|
public async Task AddFileAsync(string url,bool download=true)
|
|
|
|
{
|
|
|
|
if(Downloader != null)
|
|
|
|
await Downloader.AddFileAsync(url,download);
|
|
|
|
}
|
2022-06-14 18:21:36 +00:00
|
|
|
|
|
|
|
public async Task AddPlaylistAsync(PlaylistId id, Resolution resolution = Resolution.PreMuxed)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Downloader != null)
|
2022-06-14 18:21:36 +00:00
|
|
|
await Downloader.AddPlaylistAsync(id,resolution);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task AddChannelAsync(ChannelId id, Resolution resolution = Resolution.PreMuxed)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Downloader != null)
|
2022-06-14 18:21:36 +00:00
|
|
|
await Downloader.AddChannelAsync(id,resolution);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task AddUserAsync(UserName userName, Resolution resolution = Resolution.PreMuxed)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Downloader != null)
|
2022-06-14 18:21:36 +00:00
|
|
|
await Downloader.AddUserAsync(userName,resolution);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IReadOnlyList<(SavedVideo Video, Resolution Resolution)> GetQueueList()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Downloader == null) return new List<(SavedVideo Video,Resolution Resolution)>();
|
2022-06-14 18:21:36 +00:00
|
|
|
return Downloader.GetQueueList();
|
|
|
|
}
|
|
|
|
|
|
|
|
public SavedVideoProgress GetProgress()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Downloader == null)return new SavedVideoProgress();
|
2022-06-14 18:21:36 +00:00
|
|
|
return Downloader.GetProgress();
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<Subscription> GetSubscriptionsAsync()
|
|
|
|
{
|
|
|
|
IAsyncEnumerable<Subscription> subscriptions=null;
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
subscriptions= e.GetSubscriptionsAsync();
|
|
|
|
});
|
|
|
|
if(subscriptions == null) yield break;
|
|
|
|
await foreach(var item in subscriptions)
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task UnsubscribeAsync(ChannelId id)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.UnsubscribeAsync(id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task SubscribeAsync(ChannelId id, bool downloadChannelInfo = false, ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.SubscribeAsync(id,downloadChannelInfo,bellInfo);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task SubscribeAsync(UserName name, ChannelBellInfo info = ChannelBellInfo.NotifyAndDownload)
|
|
|
|
{
|
|
|
|
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.SubscribeAsync(name,info);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task ResubscribeAsync(ChannelId id, ChannelBellInfo info = ChannelBellInfo.NotifyAndDownload)
|
|
|
|
{
|
|
|
|
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.ResubscribeAsync(id,info);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<string> GetPersonalPlaylistsAsync()
|
|
|
|
{
|
|
|
|
await foreach(var item in Storage.GetPersonalPlaylistsAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<(string Path, bool Delete)> GetRealUrlOrPathAsync(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage == null) return ("",false);
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.GetRealUrlOrPathAsync(path);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-06-24 23:02:51 +00:00
|
|
|
|
2022-06-14 18:21:36 +00:00
|
|
|
|
|
|
|
public bool FileExists(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage == null) return false;
|
2022-06-14 18:21:36 +00:00
|
|
|
return Storage.FileExists(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<string> GetVideoIdsAsync()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage == null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var id in Storage.GetVideoIdsAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<SavedVideo> GetVideoInfoAsync(VideoId id)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage == null) return new SavedVideo();
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.GetVideoInfoAsync(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<SavedVideo> GetVideosAsync()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var vid in Storage.GetVideosAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(vid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<SavedVideoLegacy> GetLegacyVideosAsync()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var item in Storage.GetLegacyVideosAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<SavedVideoLegacy> GetLegacyVideoInfoAsync(VideoId id)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage == null) return new SavedVideoLegacy();
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.GetLegacyVideoInfoAsync(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<SavedPlaylist> GetPlaylistsAsync()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var item in Storage.GetPlaylistsAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<byte[]> ReadAllBytesAsync(string path, CancellationToken token = default)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return new byte[0];
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.ReadAllBytesAsync(path,token);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<string> GetPlaylistIdsAsync()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var item in Storage.GetPlaylistIdsAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<string> GetChannelIdsAsync()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var item in Storage.GetChannelIdsAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<VideoId> GetYouTubeExplodeVideoIdsAsync()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var item in Storage.GetYouTubeExplodeVideoIdsAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<SavedChannel> GetChannelInfoAsync(ChannelId id)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return new SavedChannel();
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.GetChannelInfoAsync(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<SavedChannel> GetChannelsAsync()
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
2022-06-14 18:21:36 +00:00
|
|
|
await foreach(var item in Storage.GetChannelsAsync())
|
|
|
|
{
|
|
|
|
yield return await Task.FromResult(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool PlaylistInfoExists(PlaylistId id)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return false;
|
2022-06-14 18:21:36 +00:00
|
|
|
return Storage.PlaylistInfoExists(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool VideoInfoExists(VideoId id)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return false;
|
2022-06-14 18:21:36 +00:00
|
|
|
return Storage.VideoInfoExists(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool ChannelInfoExists(ChannelId id)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return false;
|
2022-06-14 18:21:36 +00:00
|
|
|
return Storage.ChannelInfoExists(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<SavedPlaylist> GetPlaylistInfoAsync(PlaylistId id)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return new SavedPlaylist();
|
2022-06-14 18:21:36 +00:00
|
|
|
return await Storage.GetPlaylistInfoAsync(id);
|
|
|
|
}
|
|
|
|
|
2022-06-24 23:02:51 +00:00
|
|
|
public async Task<string> ReadAllTextAsync(string file)
|
2022-06-14 18:21:36 +00:00
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return "";
|
|
|
|
return await Storage.ReadAllTextAsync(file);
|
2022-06-14 18:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public bool DirectoryExists(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) return false;
|
2022-06-14 18:21:36 +00:00
|
|
|
return Storage.DirectoryExists(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IEnumerable<string> EnumerateFiles(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
|
|
|
foreach(var item in Storage.EnumerateFiles(path))
|
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
|
|
|
|
2022-06-14 18:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public IEnumerable<string> EnumerateDirectories(string path)
|
|
|
|
{
|
2022-06-24 23:02:51 +00:00
|
|
|
if(Storage ==null) yield break;
|
|
|
|
foreach(var item in Storage.EnumerateDirectories(path))
|
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
2022-06-14 18:21:36 +00:00
|
|
|
}
|
|
|
|
|
2022-06-24 23:02:51 +00:00
|
|
|
|
2022-06-14 18:21:36 +00:00
|
|
|
public IReadOnlyList<Subscription> GetLoadedSubscriptions()
|
|
|
|
{
|
|
|
|
IReadOnlyList<Subscription> subs=new List<Subscription>();
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
subs=e.GetLoadedSubscriptions();
|
|
|
|
});
|
|
|
|
return subs;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Unsubscribe(ChannelId id)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
e.Unsubscribe(id);
|
|
|
|
});
|
|
|
|
}
|
2022-06-15 08:04:26 +00:00
|
|
|
|
|
|
|
public void StartLoop(CancellationToken token = default)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
e.StartLoop(token);
|
|
|
|
});
|
|
|
|
}
|
2022-06-24 23:02:51 +00:00
|
|
|
|
|
|
|
public async Task AddToPersonalPlaylistAsync(string name, IEnumerable<ListContentItem> items)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.AddToPersonalPlaylistAsync(name,items);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task ReplacePersonalPlaylistAsync(string name, IEnumerable<ListContentItem> items)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.ReplacePersonalPlaylistAsync(name,items);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task RemoveItemFromPersonalPlaylistAsync(string name, VideoId id)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.RemoveItemFromPersonalPlaylistAsync(name,id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task SetResolutionForItemInPersonalPlaylistAsync(string name, VideoId id, Resolution resolution)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.SetResolutionForItemInPersonalPlaylistAsync(name,id,resolution);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool PersonalPlaylistExists(string name)
|
|
|
|
{
|
|
|
|
if(Storage ==null) return false;
|
|
|
|
return Storage.PersonalPlaylistExists(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void DeletePersonalPlaylist(string name)
|
|
|
|
{
|
|
|
|
StorageAsStorage((e)=>{
|
|
|
|
e.DeletePersonalPlaylist(name);
|
|
|
|
});
|
|
|
|
}
|
2022-07-06 22:59:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
public async Task WriteBestStreamInfoAsync(VideoId id, BestStreamInfo.BestStreamsSerialized serialized)
|
|
|
|
{
|
|
|
|
await StorageAsStorageAsync(async(e)=>{
|
|
|
|
await e.WriteBestStreamInfoAsync(id,serialized);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<BestStreamInfo.BestStreamsSerialized> GetBestStreamInfoAsync(VideoId id)
|
|
|
|
{
|
2022-07-13 13:59:23 +00:00
|
|
|
return await Storage.GetBestStreamInfoAsync(id);
|
2022-07-06 22:59:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public bool BestStreamInfoExists(VideoId id)
|
|
|
|
{
|
2022-07-13 13:59:23 +00:00
|
|
|
|
|
|
|
return Storage.BestStreamInfoExists(id);
|
|
|
|
}
|
|
|
|
public bool DownloadExists(string p)
|
|
|
|
{
|
|
|
|
|
|
|
|
return Storage.DownloadExists(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<string> GetDownloadUrlsAsync()
|
|
|
|
{
|
|
|
|
await foreach(var url in Storage.GetDownloadUrlsAsync())
|
|
|
|
{
|
|
|
|
yield return url;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public async IAsyncEnumerable<SavedVideo> GetDownloadsAsync()
|
|
|
|
{
|
|
|
|
await foreach(var item in Storage.GetDownloadsAsync())
|
|
|
|
{
|
|
|
|
yield return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<SavedVideo> GetDownloadInfoAsync(string url)
|
|
|
|
{
|
|
|
|
return await Storage.GetDownloadInfoAsync(url);
|
2022-07-06 22:59:50 +00:00
|
|
|
}
|
2022-06-14 18:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public class DownloaderMigration
|
|
|
|
{
|
|
|
|
private TYTDDownloaderStorageProxy proxy;
|
|
|
|
|
|
|
|
public DownloaderMigration(TYTDDownloaderStorageProxy proxy)
|
|
|
|
{
|
|
|
|
this.proxy = proxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task DownloaderAsBaseAsync(Func<ITYTDBase,Task> callback)
|
|
|
|
{
|
|
|
|
var dl = proxy.Downloader as ITYTDBase;
|
|
|
|
if(dl != null && callback !=null) await callback(dl);
|
|
|
|
}
|
|
|
|
public void DownloaderAsBase(Action<ITYTDBase> callback)
|
|
|
|
{
|
|
|
|
var dl = proxy.Downloader as ITYTDBase;
|
|
|
|
if(dl != null && callback !=null) callback(dl);
|
|
|
|
}
|
|
|
|
public async Task CopyVideoAsync(VideoId id,Resolution res=Resolution.PreMuxed,IProgress<double> progress=null,CancellationToken token=default(CancellationToken),bool copyThumbnails=true)
|
|
|
|
{
|
|
|
|
await DownloaderAsBaseAsync(async(e)=>{
|
|
|
|
await proxy.StorageAsStorageAsync(async(f)=>{
|
|
|
|
await TYTDManager.CopyVideoAsync(id,e,f,res,progress,token,copyThumbnails);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
public async Task CopyAllVideosAsync(Resolution res=Resolution.PreMuxed,IProgress<double> progress=null,CancellationToken token=default(CancellationToken),bool copyThumbnails=true)
|
|
|
|
{
|
|
|
|
await DownloaderAsBaseAsync(async(e)=>{
|
|
|
|
await proxy.StorageAsStorageAsync(async(f)=>{
|
|
|
|
await TYTDManager.CopyAllVideosAsync(e,f,res,progress,token,copyThumbnails);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
public async Task CopyPlaylistAsync(PlaylistId id,Resolution res=Resolution.PreMuxed,IProgress<double> progress=null,CancellationToken token=default(CancellationToken),bool copyThumbnails=true,bool copyContents=true)
|
|
|
|
{
|
|
|
|
await DownloaderAsBaseAsync(async(e)=>{
|
|
|
|
await proxy.StorageAsStorageAsync(async(f)=>{
|
|
|
|
await TYTDManager.CopyPlaylistAsync(id,e,f,res,progress,token,copyThumbnails,copyContents);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
public async Task CopyChannelAsync(ChannelId id,Resolution res=Resolution.PreMuxed,IProgress<double> progress=null,CancellationToken token=default(CancellationToken),bool copyThumbnails=true,bool copyContents=false)
|
|
|
|
{
|
|
|
|
await DownloaderAsBaseAsync(async(e)=>{
|
|
|
|
await proxy.StorageAsStorageAsync(async(f)=>{
|
|
|
|
await TYTDManager.CopyChannelAsync(id,e,f,res,progress,token,copyThumbnails,copyContents);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
public async Task CopyAllPlaylistsAsync(Resolution res=Resolution.PreMuxed,IProgress<double> progress=null,CancellationToken token=default(CancellationToken),bool copyThumbnails=true,bool copyContents=true)
|
|
|
|
{
|
|
|
|
await DownloaderAsBaseAsync(async(e)=>{
|
|
|
|
await proxy.StorageAsStorageAsync(async(f)=>{
|
|
|
|
await TYTDManager.CopyAllPlaylistsAsync(e,f,res,progress,token,copyThumbnails,copyContents);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
public async Task CopyAllChannelsAsync(Resolution res=Resolution.PreMuxed,IProgress<double> progress=null,CancellationToken token=default(CancellationToken),bool copyThumbnails=true,bool copyContents=false)
|
|
|
|
{
|
|
|
|
await DownloaderAsBaseAsync(async(e)=>{
|
|
|
|
await proxy.StorageAsStorageAsync(async(f)=>{
|
|
|
|
await TYTDManager.CopyAllChannelsAsync(e,f,res,progress,token,copyThumbnails,copyContents);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
public async Task CopyEverythingAsync(Resolution res,IProgress<double> progress=null,CancellationToken token=default(CancellationToken),bool copyThumbnails=true)
|
|
|
|
{
|
|
|
|
await DownloaderAsBaseAsync(async(e)=>{
|
|
|
|
await proxy.StorageAsStorageAsync(async(f)=>{
|
|
|
|
await TYTDManager.CopyEverythingAsync(e,f,res,progress,token,copyThumbnails);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
public async Task CopyEverythingAsync(IProgress<double> progress=null,CancellationToken token=default(CancellationToken),bool copyThumbnails=true)
|
|
|
|
{
|
|
|
|
await DownloaderAsBaseAsync(async(e)=>{
|
|
|
|
await proxy.StorageAsStorageAsync(async(f)=>{
|
|
|
|
await TYTDManager.CopyEverythingAsync(e,f,progress,token,copyThumbnails);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|