diff --git a/Tesses.YouTubeDownloader/BestStreams.cs b/Tesses.YouTubeDownloader/BestStreams.cs index 622ebd8..bdb67f2 100644 --- a/Tesses.YouTubeDownloader/BestStreams.cs +++ b/Tesses.YouTubeDownloader/BestStreams.cs @@ -11,6 +11,7 @@ namespace Tesses.YouTubeDownloader { public class BestStreams { + public TimeSpan TillExpire {get;set;} public bool VideoFrozen {get;set;} public BestStreamInfo MuxedStreamInfo {get;set;} @@ -88,6 +89,7 @@ namespace Tesses.YouTubeDownloader if(DateTime.Now < serialization.Expires || !expire_check) { BestStreams streams=new BestStreams(); + streams.TillExpire = serialization.Expires - DateTime.Now; streams.VideoOnlyStreamInfo = new BestStreamInfo(serialization.VideoOnly); streams.AudioOnlyStreamInfo = new BestStreamInfo(serialization.Audio); streams.MuxedStreamInfo =new BestStreamInfo(serialization.Muxed); @@ -103,7 +105,7 @@ namespace Tesses.YouTubeDownloader if(video.VideoFrozen) { - return new BestStreams() {VideoFrozen=true,MuxedStreamInfo=null,VideoOnlyStreamInfo=null,AudioOnlyStreamInfo=null}; + return new BestStreams() {VideoFrozen=true,MuxedStreamInfo=null,VideoOnlyStreamInfo=null,AudioOnlyStreamInfo=null,TillExpire=new TimeSpan(0,0,0)}; } } var res=await storage.YoutubeClient.Videos.Streams.GetManifestAsync(id,token); @@ -114,6 +116,7 @@ namespace Tesses.YouTubeDownloader BestStreamsSerialized serialized=new BestStreamsSerialized(); serialized.Expires=expires; BestStreams streams1 = new BestStreams(); + streams1.TillExpire = new TimeSpan(6,0,0); streams1.VideoOnlyStreamInfo=new BestStreamInfo(); streams1.VideoOnlyStreamInfo.SetInfo(videoOnly); serialized.VideoOnly=streams1.VideoOnlyStreamInfo.Serialization; diff --git a/Tesses.YouTubeDownloader/DownloadLoop.cs b/Tesses.YouTubeDownloader/DownloadLoop.cs index fbbeda2..715899b 100644 --- a/Tesses.YouTubeDownloader/DownloadLoop.cs +++ b/Tesses.YouTubeDownloader/DownloadLoop.cs @@ -40,7 +40,7 @@ namespace Tesses.YouTubeDownloader } } } - + private CancellationTokenSource currentVideoCancelSource=null; public readonly SavedVideoProgress Progress = new SavedVideoProgress(); private async Task ReportProgress(double progress) { @@ -107,7 +107,7 @@ namespace Tesses.YouTubeDownloader public async Task DownloadNoQueue(SavedVideo info,Resolution resolution=Resolution.Mux,CancellationToken token=default(CancellationToken),IProgress progress=null) { - + await DownloadVideoAsync(info,resolution,token,progress,false); } @@ -169,7 +169,7 @@ namespace Tesses.YouTubeDownloader { restartDownload=false; goto begin_download; - + } } public bool cancelDownload=false; @@ -179,6 +179,7 @@ namespace Tesses.YouTubeDownloader { cancelDownload=true; restartDownload=restart; + if(currentVideoCancelSource != null) currentVideoCancelSource.Cancel(); } private async Task DownloadFileAsync(SavedVideo video, CancellationToken token, IProgress progress, bool report) @@ -521,6 +522,7 @@ namespace Tesses.YouTubeDownloader } private async Task DownloadVideoMuxedAsync(SavedVideo video,CancellationToken token,IProgress progress,bool report=true) { + bool isValid=true; isValid=await DownloadVideoOnlyAsync(video,token,progress,report); if(token.IsCancellationRequested || !isValid || cancelDownload || restartDownload) @@ -564,9 +566,15 @@ namespace Tesses.YouTubeDownloader } public async Task DownloadVideoOnlyAsync(SavedVideo video,CancellationToken token,IProgress progress,bool report=true) { - + currentVideoCancelSource = new CancellationTokenSource(); + token.Register(()=>{ + currentVideoCancelSource.Cancel(); + }); + + bool ret=false; - var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false); + var streams = await BestStreamInfo.GetBestStreams(this, video.Id, currentVideoCancelSource.Token, false); + if(streams != null) { @@ -581,10 +589,12 @@ namespace Tesses.YouTubeDownloader if(await Continue(complete)) { if(!can_download) return false; - streams = await BestStreamInfo.GetBestStreams(this,video.Id,token); + streams = await BestStreamInfo.GetBestStreams(this,video.Id,currentVideoCancelSource.Token); if(streams != null) { - using(var strm = await YoutubeClient.Videos.Streams.GetAsync(streams.VideoOnlyStreamInfo,token)) + currentVideoCancelSource.CancelAfter(streams.TillExpire - new TimeSpan(0,5,0)); + + using(var strm = await YoutubeClient.Videos.Streams.GetAsync(streams.VideoOnlyStreamInfo,currentVideoCancelSource.Token)) { if(token.IsCancellationRequested || cancelDownload || restartDownload) { @@ -596,7 +606,9 @@ namespace Tesses.YouTubeDownloader using(var dest = await OpenOrCreateAsync(incomplete)) { - ret=await CopyStreamAsync(strm,dest,dest.Length,streams.VideoOnlyStreamInfo.Size.Bytes,4096,progress,token); + ret=await CopyStreamAsync(strm,dest,dest.Length,streams.VideoOnlyStreamInfo.Size.Bytes,4096,progress,currentVideoCancelSource.Token); + currentVideoCancelSource.Dispose(); + currentVideoCancelSource=null; } if(ret) { @@ -665,10 +677,15 @@ namespace Tesses.YouTubeDownloader } private async Task DownloadAudioOnlyAsync(SavedVideo video,CancellationToken token,IProgress progress,bool report=true) { + currentVideoCancelSource = new CancellationTokenSource(); + token.Register(()=>{ + currentVideoCancelSource.Cancel(); + }); bool ret=false; var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false); + if(streams != null) { if(streams.VideoFrozen) @@ -682,11 +699,13 @@ namespace Tesses.YouTubeDownloader if(await Continue(complete)) { if(!can_download) return false; - streams = await BestStreamInfo.GetBestStreams(this,video.Id,token); + streams = await BestStreamInfo.GetBestStreams(this,video.Id,currentVideoCancelSource.Token); + if(streams != null) { - - using(var strm = await YoutubeClient.Videos.Streams.GetAsync(streams.AudioOnlyStreamInfo,token)) + currentVideoCancelSource.CancelAfter(streams.TillExpire - new TimeSpan(0,5,0)); + + using(var strm = await YoutubeClient.Videos.Streams.GetAsync(streams.AudioOnlyStreamInfo,currentVideoCancelSource.Token)) { if(token.IsCancellationRequested || cancelDownload || restartDownload) { @@ -698,7 +717,9 @@ namespace Tesses.YouTubeDownloader using(var dest = await OpenOrCreateAsync(incomplete)) { - ret=await CopyStreamAsync(strm,dest,dest.Length,streams.AudioOnlyStreamInfo.Size.Bytes,4096,progress,token); + ret=await CopyStreamAsync(strm,dest,dest.Length,streams.AudioOnlyStreamInfo.Size.Bytes,4096,progress,currentVideoCancelSource.Token); + currentVideoCancelSource.Dispose(); + currentVideoCancelSource=null; } if(ret) { @@ -719,7 +740,14 @@ namespace Tesses.YouTubeDownloader } private async Task DownloadPreMuxedVideoAsync(SavedVideo video, CancellationToken token,IProgress progress,bool report=true) { - var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false); + currentVideoCancelSource = new CancellationTokenSource(); + token.Register(()=>{ + currentVideoCancelSource.Cancel(); + }); + + + var streams = await BestStreamInfo.GetBestStreams(this, video.Id, currentVideoCancelSource.Token, false); + if(!can_download) return; if(streams != null) { @@ -734,11 +762,13 @@ namespace Tesses.YouTubeDownloader if(await Continue(complete)) { - streams = await BestStreamInfo.GetBestStreams(this,video.Id,token); + streams = await BestStreamInfo.GetBestStreams(this,video.Id,currentVideoCancelSource.Token); + if(streams != null) { - - using(var strm = await YoutubeClient.Videos.Streams.GetAsync(streams.MuxedStreamInfo,token)) + currentVideoCancelSource.CancelAfter(streams.TillExpire - new TimeSpan(0,5,0)); + + using(var strm = await YoutubeClient.Videos.Streams.GetAsync(streams.MuxedStreamInfo,currentVideoCancelSource.Token)) { if(token.IsCancellationRequested || cancelDownload || restartDownload) { @@ -750,7 +780,9 @@ namespace Tesses.YouTubeDownloader bool ret; using(var dest = await OpenOrCreateAsync(incomplete)) { - ret=await CopyStreamAsync(strm,dest,dest.Length,streams.MuxedStreamInfo.Size.Bytes,4096,progress,token); + ret=await CopyStreamAsync(strm,dest,dest.Length,streams.MuxedStreamInfo.Size.Bytes,4096,progress,currentVideoCancelSource.Token); + currentVideoCancelSource.Dispose(); + currentVideoCancelSource=null; } //We know its resolution if(ret) diff --git a/Tesses.YouTubeDownloader/Tesses.YouTubeDownloader.csproj b/Tesses.YouTubeDownloader/Tesses.YouTubeDownloader.csproj index 08415b7..46c987d 100644 --- a/Tesses.YouTubeDownloader/Tesses.YouTubeDownloader.csproj +++ b/Tesses.YouTubeDownloader/Tesses.YouTubeDownloader.csproj @@ -7,9 +7,9 @@ Tesses.YouTubeDownloader Mike Nolan Tesses - 1.2.0 - 1.2.0 - 1.2.0 + 1.2.1 + 1.2.1 + 1.2.1 A YouTube Downloader LGPL-3.0-only true