diff --git a/Tesses.YouTubeDownloader/ExtraData.cs b/Tesses.YouTubeDownloader/ExtraData.cs new file mode 100644 index 0000000..c2d7c2a --- /dev/null +++ b/Tesses.YouTubeDownloader/ExtraData.cs @@ -0,0 +1,26 @@ +namespace Tesses.YouTubeDownloader +{ + public class ExtraData + { + public string TYTDTag {get;set;} + public string TYTDDownloaderVersion {get;set;} + public string TYTDServerVersion {get;set;} + + public string TessesWebServerVersion {get;set;} + + public long ItemsInQueue {get;set;} + + public long ItemsInInfoQueue {get;set;} + + public ExtraData() + { + ItemsInInfoQueue=0; + ItemsInQueue=0; + TessesWebServerVersion="0.0.0.0"; + TYTDServerVersion="0.0.0.0"; + TYTDTag=TYTDStorage.TYTDTag; + TYTDDownloaderVersion = this.GetType().Assembly.GetName().Version.ToString(); + + } + } +} \ No newline at end of file diff --git a/Tesses.YouTubeDownloader/IDownloader.cs b/Tesses.YouTubeDownloader/IDownloader.cs index 06554ef..cb5798d 100644 --- a/Tesses.YouTubeDownloader/IDownloader.cs +++ b/Tesses.YouTubeDownloader/IDownloader.cs @@ -12,6 +12,16 @@ namespace Tesses.YouTubeDownloader { public interface IDownloader : IPersonalPlaylistSet { + event EventHandler VideoStarted; + + + + event EventHandler VideoProgress; + + event EventHandler VideoFinished; + event EventHandler Error; + event EventHandler Bell; + void CancelDownload(bool restart=false); Task AddVideoAsync(VideoId id,Resolution resolution=Resolution.PreMuxed); Task AddPlaylistAsync(PlaylistId id,Resolution resolution=Resolution.PreMuxed); @@ -23,7 +33,7 @@ namespace Tesses.YouTubeDownloader SavedVideoProgress GetProgress(); IAsyncEnumerable GetSubscriptionsAsync(); Task UnsubscribeAsync(ChannelId id); - Task SubscribeAsync(ChannelId id,bool downloadChannelInfo=false,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload); + Task SubscribeAsync(ChannelId id,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload); Task SubscribeAsync(UserName name,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload); Task ResubscribeAsync(ChannelId id,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload); void DeletePersonalPlaylist(string name); diff --git a/Tesses.YouTubeDownloader/IStorage.cs b/Tesses.YouTubeDownloader/IStorage.cs index 93ec7eb..800e8df 100644 --- a/Tesses.YouTubeDownloader/IStorage.cs +++ b/Tesses.YouTubeDownloader/IStorage.cs @@ -29,14 +29,8 @@ namespace Tesses.YouTubeDownloader Logger GetLogger(); LoggerProperties GetLoggerProperties(); IReadOnlyList GetLoadedSubscriptions(); - event EventHandler Bell; - event EventHandler VideoStarted; - - event EventHandler BeforeSaveInfo; - - event EventHandler VideoProgress; - - public event EventHandler VideoFinished; + + bool CanDownload {get;set;} IExtensionContext ExtensionContext {get;set;} HttpClient HttpClient {get;set;} @@ -58,6 +52,6 @@ namespace Tesses.YouTubeDownloader Task MoveLegacyStreams(SavedVideo video,BestStreams streams); void StartLoop(CancellationToken token=default(CancellationToken)); - event EventHandler Error; + } } \ No newline at end of file diff --git a/Tesses.YouTubeDownloader/SSEClient.cs b/Tesses.YouTubeDownloader/SSEClient.cs new file mode 100644 index 0000000..d2fc5f2 --- /dev/null +++ b/Tesses.YouTubeDownloader/SSEClient.cs @@ -0,0 +1,81 @@ +using System; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +namespace Tesses.YouTubeDownloader +{ +public static class SSEExtensions +{ + public static async Task GetSSEClientAsync(this HttpClient clt,string url) + { + var strm=await clt.GetStreamAsync(url); + return new SSEClient(strm); + } +} + +public class SSEEvent : EventArgs +{ + public SSEEvent(string data) + { + Data=data; + } + public string Data {get;set;} + public T ParseJson() + { + return JsonConvert.DeserializeObject(Data); + } +} +public class SSEClient +{ + Stream strm; + + public SSEClient(Stream strm) + { + this.strm=strm; + } + public EventHandler Event; + + public async Task ReadEventsAsync(CancellationToken token=default(CancellationToken)) + { + try{ + using(var sr = new StreamReader(strm)){ + token.Register(()=>{ + sr.Dispose(); + }); + + while(!token.IsCancellationRequested) + { + + string text=await sr.ReadLineAsync(); + if(!string.IsNullOrWhiteSpace(text)) + Event?.Invoke(this,new SSEEvent(text.Substring(6))); + } + } + }catch(Exception ex) + { + _=ex; + } + } + +} +public class ProgressItem +{ + public long Length {get;set;} + public double Percent {get;set;} + + public SavedVideo Video {get;set;} + + public bool StartEvent {get;set;} + public bool StopEvent {get;set;} + public bool BellEvent {get;set;} + + public bool ErrorEvent {get;set;} + public string Error {get;set;} + public string Id {get;set;} + public string Message {get;set;} + public string ExceptionName {get;set;} +} +} \ No newline at end of file diff --git a/Tesses.YouTubeDownloader/SubscribedTo.cs b/Tesses.YouTubeDownloader/SubscribedTo.cs index 88ffd37..d12fa31 100644 --- a/Tesses.YouTubeDownloader/SubscribedTo.cs +++ b/Tesses.YouTubeDownloader/SubscribedTo.cs @@ -114,9 +114,9 @@ namespace Tesses.YouTubeDownloader /// /// Subscribe to creator /// - public async Task SubscribeAsync(ChannelId id, bool downloadChannelInfo=false,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload) + public async Task SubscribeAsync(ChannelId id,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload) { - if(downloadChannelInfo) + if(bellInfo.HasFlag(ChannelBellInfo.GetInfo)) { ChannelMediaContext context=new ChannelMediaContext(id,Resolution.NoDownload); var c=await context.GetChannel(this); @@ -136,7 +136,7 @@ namespace Tesses.YouTubeDownloader { ChannelMediaContext context=new ChannelMediaContext(name,Resolution.NoDownload); var c=await context.GetChannel(this); - await SubscribeAsync(ChannelId.Parse(c.Id),false,bellInfo); + await SubscribeAsync(ChannelId.Parse(c.Id),bellInfo); } public IReadOnlyList GetLoadedSubscriptions() { diff --git a/Tesses.YouTubeDownloader/TYTD.cs b/Tesses.YouTubeDownloader/TYTD.cs index d8b5fbe..8572ece 100644 --- a/Tesses.YouTubeDownloader/TYTD.cs +++ b/Tesses.YouTubeDownloader/TYTD.cs @@ -17,6 +17,19 @@ namespace Tesses.YouTubeDownloader public abstract partial class TYTDStorage : TYTDBase, IStorage { + public override ExtraData GetExtraData() + { + ExtraData data=new ExtraData(); + lock(Temporary){ + data.ItemsInInfoQueue=Temporary.Count; + } + lock(QueueList) + { + data.ItemsInQueue=QueueList.Count; + } + + return data; + } internal class ConsoleWriterCLS : TextWriter { Action cls; @@ -288,5 +301,20 @@ namespace Tesses.YouTubeDownloader await WriteAllTextAsync($"PersonalPlaylist/{name}.json",JsonConvert.SerializeObject(items0)); } + + public void RegisterVideoStarted(EventHandler vs) + { + VideoStarted+=vs; + } + + public void RegisterVideoFinished(EventHandler vf) + { + VideoFinished+=vf; + } + + public void RegisterVideoProgress(EventHandler vp) + { + VideoProgress+=vp; + } } } diff --git a/Tesses.YouTubeDownloader/TYTDBase.cs b/Tesses.YouTubeDownloader/TYTDBase.cs index f52a7c5..7d37245 100644 --- a/Tesses.YouTubeDownloader/TYTDBase.cs +++ b/Tesses.YouTubeDownloader/TYTDBase.cs @@ -276,6 +276,12 @@ namespace Tesses.YouTubeDownloader public abstract IAsyncEnumerable EnumerateDirectoriesAsync(string path); + public virtual ExtraData GetExtraData() + { + ExtraData data=new ExtraData(); + return data; + + } } public class ListContentItem @@ -857,6 +863,7 @@ namespace Tesses.YouTubeDownloader } public interface IPersonalPlaylistGet { + ExtraData GetExtraData(); IAsyncEnumerable GetPersonalPlaylistContentsAsync(string name); bool PersonalPlaylistExists(string name); } diff --git a/Tesses.YouTubeDownloader/TYTDClient.cs b/Tesses.YouTubeDownloader/TYTDClient.cs index 7484ba3..c98f0ac 100644 --- a/Tesses.YouTubeDownloader/TYTDClient.cs +++ b/Tesses.YouTubeDownloader/TYTDClient.cs @@ -223,7 +223,7 @@ internal class SegmentedHttpStream : Stream await client.GetStringAsync($"{url}api/v2/AddChannel?v={id.Value}&res={resolution.ToString()}"); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } @@ -233,7 +233,7 @@ internal class SegmentedHttpStream : Stream await client.GetStringAsync($"{url}api/v2/AddPlaylist?v={id.Value}&res={resolution.ToString()}"); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } @@ -243,7 +243,7 @@ internal class SegmentedHttpStream : Stream await client.GetStringAsync($"{url}api/v2/AddUser?v={userName.Value}&res={resolution.ToString()}"); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } @@ -253,7 +253,7 @@ internal class SegmentedHttpStream : Stream await client.GetStringAsync($"{url}api/v2/AddVideo?v={id.Value}&res={resolution.ToString()}"); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } public async Task AddFileAsync(string url,bool download=true) @@ -262,7 +262,7 @@ internal class SegmentedHttpStream : Stream await client.GetStringAsync($"{url}api/v2/AddFile?url={WebUtility.UrlEncode(url)}&download={download}"); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } public override async Task DirectoryExistsAsync(string path) @@ -272,7 +272,7 @@ internal class SegmentedHttpStream : Stream return v=="true"; }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } return false; } @@ -285,7 +285,7 @@ internal class SegmentedHttpStream : Stream items=JsonConvert.DeserializeObject>(v); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } if(items==null) @@ -305,7 +305,7 @@ internal class SegmentedHttpStream : Stream v=await client.GetStringAsync("{url}api/v2/subscriptions"); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } foreach(var item in JsonConvert.DeserializeObject>(v)) { @@ -321,18 +321,18 @@ internal class SegmentedHttpStream : Stream }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } - public async Task SubscribeAsync(ChannelId id,bool downloadChannelInfo=false,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload) + public async Task SubscribeAsync(ChannelId id,ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload) { try{ - string dlcid=downloadChannelInfo ? "true" : "false"; - string v=await client.GetStringAsync($"{url}api/v2/subscribe?id={id.Value}&conf={bellInfo.ToString()}&getinfo={dlcid}"); + + string v=await client.GetStringAsync($"{url}api/v2/subscribe?id={id.Value}&conf={bellInfo.ToString()}"); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } public async Task SubscribeAsync(UserName name,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload) @@ -344,7 +344,7 @@ internal class SegmentedHttpStream : Stream }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } public async Task ResubscribeAsync(ChannelId id,ChannelBellInfo info=ChannelBellInfo.NotifyAndDownload) @@ -356,7 +356,7 @@ internal class SegmentedHttpStream : Stream }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } public async override IAsyncEnumerable EnumerateFilesAsync(string path) @@ -367,7 +367,7 @@ internal class SegmentedHttpStream : Stream items=JsonConvert.DeserializeObject>(v); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } if(items==null) @@ -388,7 +388,7 @@ internal class SegmentedHttpStream : Stream return v=="true"; }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } return false; } @@ -400,7 +400,7 @@ internal class SegmentedHttpStream : Stream return JsonConvert.DeserializeObject>(v); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } return new List<(SavedVideo video,Resolution resolution)>(); @@ -413,19 +413,24 @@ internal class SegmentedHttpStream : Stream return JsonConvert.DeserializeObject(v); }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } return null; } public SavedVideoProgress GetProgress() { - return GetProgressAsync().GetAwaiter().GetResult(); + if(hadBeenListeningToEvents) + { + return progress; + }else{ + return Task.Run(GetProgressAsync).GetAwaiter().GetResult(); + } } public IReadOnlyList<(SavedVideo Video, Resolution Resolution)> GetQueueList() { - return GetQueueListAsync().GetAwaiter().GetResult(); + return Task.Run(GetQueueListAsync).GetAwaiter().GetResult(); } @@ -439,7 +444,7 @@ internal class SegmentedHttpStream : Stream return v; }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } return Stream.Null; @@ -479,7 +484,7 @@ internal class SegmentedHttpStream : Stream }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } @@ -492,7 +497,7 @@ internal class SegmentedHttpStream : Stream }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } public void DeletePersonalPlaylist(string name) @@ -504,7 +509,7 @@ internal class SegmentedHttpStream : Stream }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } @@ -517,8 +522,196 @@ internal class SegmentedHttpStream : Stream }catch(Exception ex) { - _=ex; + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); } } + + SavedVideoProgress progress=new SavedVideoProgress(); + CancellationTokenSource src=new CancellationTokenSource(); + bool hadBeenListeningToEvents=false; + private async Task _startEventStreamAsync() + { + try{ + src=new CancellationTokenSource(); + hadBeenListeningToEvents=true; + var sse=await client.GetSSEClientAsync($"{url}api/v2/event"); + sse.Event += sse_Event; + await sse.ReadEventsAsync(src.Token); + + }catch(Exception ex){ + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); + } + } + public void ResetEvents() + { + if(src != null) { + src.Cancel(); + src.Dispose(); + } + + if(hadBeenListeningToEvents) + { + hadBeenListeningToEvents=false; + _startEventStream(); + } + + + } + public void CancelEvents() + { + if(src!= null){ + src.Cancel(); + src.Dispose(); + } + src=null; + hadBeenListeningToEvents=false; + } + private event EventHandler _started_video; + private event EventHandler _ended_video; + private event EventHandler _progress_video; + private event EventHandler _error; + private event EventHandler _bell; + public event EventHandler VideoStarted + { + add{ + _started_video += value; + _startEventStream(); + + + } + remove + { + _started_video-=value; + } + } + + public event EventHandler VideoProgress + { + add{ + _progress_video += value; + _startEventStream(); + + } + remove + { + _progress_video -=value; + } + } + public event EventHandler VideoFinished + { + add + { + _ended_video+=value; + _startEventStream(); + + } + remove + { + _ended_video -= value; + } + } + public event EventHandler Error + { + add + { + _error += value; + _startEventStream(); + } + remove + { + _error-=value; + } + } + public event EventHandler Bell + { + add + { + _bell+=value; + _startEventStream(); + } + remove + { + _bell-=value; + } + } + + private void sse_Event(object sender,SSEEvent evt) + { + bool started=false;bool ended=false;bool error=false;bool bell=false; + try{ + ProgressItem item = evt.ParseJson(); + if(item != null) + { + if(item.Video != null) + { + progress.Video = item.Video; + } + if(item.StartEvent) + { + started = true; + } + if(item.StopEvent) + { + ended =true; + } + if(item.BellEvent) + { + + } + progress.Length = item.Length; + progress.ProgressRaw=item.Percent; + progress.Progress = ((int)(item.Percent * 100) % 101); + if(started) + { + VideoStartedEventArgs evt0=new VideoStartedEventArgs(); + evt0.EstimatedLength=item.Length; + evt0.Resolution=Resolution.PreMuxed; + evt0.VideoInfo=progress.Video; + + _started_video?.Invoke(this,evt0); + + }else if(ended) + { + VideoFinishedEventArgs evt0=new VideoFinishedEventArgs(); + evt0.Resolution=Resolution.PreMuxed; + evt0.VideoInfo=progress.Video; + _ended_video?.Invoke(this,evt0); + }else if(error) + { + TYTDErrorEventArgs evt0=new TYTDErrorEventArgs(item.Id,new TYTDException(item.Message,item.Error,item.ExceptionName)); + _error?.Invoke(this,evt0); + }else if(bell) + { + BellEventArgs evt0=new BellEventArgs(); + evt0.Id = item.Id; + _bell?.Invoke(this,evt0); + } + else{ + VideoProgressEventArgs evt0=new VideoProgressEventArgs(); + evt0.Progress = item.Percent; + evt0.VideoInfo = progress.Video; + _progress_video?.Invoke(this,evt0); + } + } + } + catch(Exception ex) + { + _error.Invoke(this,new TYTDErrorEventArgs("jNQXAC9IVRw",ex)); + } + } + private void _startEventStream() + { + + Task.Run(_startEventStreamAsync).Wait(0); + } + + public override ExtraData GetExtraData() + { + return Task.Run(async()=>{ + string text= await client.GetStringAsync($"{url}api/v2/extra_data.json"); + return JsonConvert.DeserializeObject(text); + }).GetAwaiter().GetResult(); + } + } } \ No newline at end of file diff --git a/Tesses.YouTubeDownloader/TYTDException.cs b/Tesses.YouTubeDownloader/TYTDException.cs new file mode 100644 index 0000000..750191b --- /dev/null +++ b/Tesses.YouTubeDownloader/TYTDException.cs @@ -0,0 +1,44 @@ +using System; +using System.Runtime.Serialization; + +namespace Tesses.YouTubeDownloader +{ + [Serializable] + internal class TYTDException : Exception + { + public TYTDException() + { + this.full=""; + Type=""; + } + + public TYTDException(string message) : base(message) + { + this.full=""; + Type=""; + } + + public TYTDException(string message, Exception innerException) : base(message, innerException) + { + this.full=""; + Type=""; + } + public TYTDException(string message,string full,string type) : base(message) + { + this.full=full; + Type=type; + } + + protected TYTDException(SerializationInfo info, StreamingContext context) : base(info, context) + { + this.full=""; + Type=""; + } + string full; + public string Type {get;private set;} + public override string ToString() + { + return full; + } + } +} \ No newline at end of file diff --git a/Tesses.YouTubeDownloader/TYTDIDownloaderStorageProxy.cs b/Tesses.YouTubeDownloader/TYTDIDownloaderStorageProxy.cs index 97a384f..4485152 100644 --- a/Tesses.YouTubeDownloader/TYTDIDownloaderStorageProxy.cs +++ b/Tesses.YouTubeDownloader/TYTDIDownloaderStorageProxy.cs @@ -15,64 +15,73 @@ namespace Tesses.YouTubeDownloader { public class TYTDDownloaderStorageProxy : IStorage { - public IDownloader Downloader {get;set;} - - private ITYTDBase _base=null; - - public ITYTDBase Storage {get {return _base;} set{_base=value; - var v = value as IStorage; - if(v != null) - SetStorage(v);}} - - private void SetStorage(IStorage storage) + public IDownloader Downloader {get{return _downloader;} set { - if(_storage !=null) + SetDownloader(_downloader); + } + + } + + private IDownloader _downloader=null; + + public ITYTDBase Storage {get;set;} + private int SetEVT_ERR=0; + private int SetEVT_VFIN=0; + private int SetEVT_VSTAR=0; + + private int SetEVT_VPROG=0; + private int SetEVT_BELL=0; + + private void SetDownloader(IDownloader downloader) + { + if(_downloader !=null) { - _storage.Bell -= _EVT_BELL; - _storage.BeforeSaveInfo -= _EVT_BSI; - _storage.VideoFinished -= _EVT_VFIN; - _storage.VideoProgress -= _EVT_VPROG; - _storage.VideoStarted -= _EVT_VSTAR; - _storage.Error -= _EVT_ERR; + if(SetEVT_BELL > 0)_downloader.Bell -= _EVT_BELL; + + if(SetEVT_VFIN > 0)_downloader.VideoFinished -= _EVT_VFIN; + if(SetEVT_VPROG > 0)_downloader.VideoProgress -= _EVT_VPROG; + if(SetEVT_VSTAR > 0)_downloader.VideoStarted -= _EVT_VSTAR; + if(SetEVT_ERR > 0)_downloader.Error -= _EVT_ERR; } - _storage=storage; - if(storage != null) + _downloader=downloader; + if(downloader != null) { - _storage.Bell += _EVT_BELL; - _storage.BeforeSaveInfo += _EVT_BSI; - _storage.VideoFinished += _EVT_VFIN; - _storage.VideoProgress += _EVT_VPROG; - _storage.VideoStarted += _EVT_VSTAR; - _storage.Error += _EVT_ERR; + if(SetEVT_BELL > 0)_downloader.Bell += _EVT_BELL; + + if(SetEVT_VFIN > 0)_downloader.VideoFinished += _EVT_VFIN; + if(SetEVT_VPROG > 0)_downloader.VideoProgress += _EVT_VPROG; + if(SetEVT_VSTAR > 0)_downloader.VideoStarted += _EVT_VSTAR; + if(SetEVT_ERR > 0)_downloader.Error += _EVT_ERR; } } private void _EVT_VSTAR(object sender,VideoStartedEventArgs evt) { - VideoStarted?.Invoke(this,evt); + _vstar?.Invoke(this,evt); } private void _EVT_VPROG(object sender,VideoProgressEventArgs evt) { - VideoProgress?.Invoke(this,evt); + _vprog?.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); + _vfin?.Invoke(this,evt); } + private event EventHandler _bell; + private event EventHandler _vstar; + private event EventHandler _vprog; + private event EventHandler _vfin; + private event EventHandler _error; + private void _EVT_BELL(object sender,BellEventArgs evt) { - Bell?.Invoke(this,evt); + _bell?.Invoke(this,evt); } private void _EVT_ERR(object sender,TYTDErrorEventArgs evt) { - Error?.Invoke(this,evt); + _error?.Invoke(this,evt); } - IStorage _storage=null; - + public LegacyConverter Legacy { get{ LegacyConverter conv=null; @@ -126,13 +135,137 @@ namespace Tesses.YouTubeDownloader } } - public event EventHandler Bell; - public event EventHandler VideoStarted; - public event EventHandler BeforeSaveInfo; - public event EventHandler VideoProgress; - public event EventHandler VideoFinished; + public event EventHandler Bell + { + add + { + if(SetEVT_BELL == 0) + { + Downloader.Bell += _EVT_BELL; + + } + _bell += value; + SetEVT_BELL++; - public event EventHandler Error; + } + remove + { + SetEVT_BELL--; + if(SetEVT_BELL <= 0) + { + SetEVT_BELL=0; + Downloader.Bell -= _EVT_BELL; + + } + _bell -= value; + + } + } + public event EventHandler VideoStarted + { + add + { + if(SetEVT_VSTAR == 0) + { + Downloader.VideoStarted += _EVT_VSTAR; + + } + _vstar += value; + SetEVT_VSTAR++; + + } + remove + { + SetEVT_VSTAR--; + if(SetEVT_VSTAR <= 0) + { + SetEVT_VSTAR=0; + Downloader.VideoStarted -= _EVT_VSTAR; + + } + _vstar -= value; + + } + } + public event EventHandler VideoProgress + { + add + { + if(SetEVT_VPROG == 0) + { + Downloader.VideoProgress += _EVT_VPROG; + + } + _vprog += value; + SetEVT_VPROG++; + + } + remove + { + SetEVT_VPROG--; + if(SetEVT_VPROG <= 0) + { + SetEVT_VPROG=0; + Downloader.VideoProgress -= _EVT_VPROG; + + } + _vprog -= value; + + } + } + public event EventHandler VideoFinished + { + add + { + if(SetEVT_VFIN == 0) + { + Downloader.VideoFinished += _EVT_VFIN; + + } + _vfin += value; + SetEVT_VFIN++; + + } + remove + { + SetEVT_VFIN--; + if(SetEVT_VFIN <= 0) + { + SetEVT_VFIN=0; + Downloader.VideoFinished -= _EVT_VFIN; + + } + _vfin -= value; + + } + } + + public event EventHandler Error + { + add + { + if(SetEVT_ERR == 0) + { + Downloader.Error += _EVT_ERR; + + } + _error += value; + SetEVT_ERR++; + + } + remove + { + SetEVT_ERR--; + if(SetEVT_ERR <= 0) + { + SetEVT_ERR=0; + Downloader.Error -= _EVT_ERR; + + } + _error -= value; + + } + } public async Task StorageAsStorageAsync(Func callback) { @@ -412,10 +545,10 @@ namespace Tesses.YouTubeDownloader }); } - public async Task SubscribeAsync(ChannelId id, bool downloadChannelInfo = false, ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload) + public async Task SubscribeAsync(ChannelId id, ChannelBellInfo bellInfo = ChannelBellInfo.NotifyAndDownload) { await StorageAsStorageAsync(async(e)=>{ - await e.SubscribeAsync(id,downloadChannelInfo,bellInfo); + await e.SubscribeAsync(id,bellInfo); }); } @@ -732,6 +865,11 @@ namespace Tesses.YouTubeDownloader { Downloader.CancelDownload(restart); } + + public ExtraData GetExtraData() + { + throw new NotImplementedException(); + } } public class DownloaderMigration diff --git a/Tesses.YouTubeDownloader/Tesses.YouTubeDownloader.csproj b/Tesses.YouTubeDownloader/Tesses.YouTubeDownloader.csproj index 18b4851..ed3f69e 100644 --- a/Tesses.YouTubeDownloader/Tesses.YouTubeDownloader.csproj +++ b/Tesses.YouTubeDownloader/Tesses.YouTubeDownloader.csproj @@ -7,9 +7,9 @@ Tesses.YouTubeDownloader Mike Nolan Tesses - 1.2.3 - 1.2.3 - 1.2.3 + 1.2.4 + 1.2.4 + 1.2.4 A YouTube Downloader LGPL-3.0-only true