Version 1.0.1

This commit is contained in:
Michael Nolan 2022-04-09 19:18:45 -05:00
parent 7dfa5bdf5d
commit dadd15f7bc
6 changed files with 307 additions and 37 deletions

View File

@ -8,6 +8,8 @@ using YoutubeExplode.Videos;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using System.Text; using System.Text;
using YoutubeExplode.Playlists;
using YoutubeExplode.Channels;
namespace Tesses.YouTubeDownloader.Server namespace Tesses.YouTubeDownloader.Server
{ {
@ -94,22 +96,149 @@ namespace Tesses.YouTubeDownloader.Server
); );
return asAscii; return asAscii;
} }
public override async Task GetAsync(ServerContext ctx) public override async Task GetAsync(ServerContext ctx)
{ {
string path=ctx.UrlAndQuery; string path=ctx.UrlAndQuery;
if(path.StartsWith("/File/")) /*if(path.StartsWith("/File/NotConverted/"))
{ {
using(var s = await baseCtl.OpenReadAsyncWithLength( WebUtility.UrlDecode(path.Substring(6)))) // redirect to new
// /File/NotConverted/xxxxxxxxxxx.mp4
string idmp4=WebUtility.UrlDecode(path.Substring(19));
if(idmp4.Length == 15)
{
string id=Path.GetFileNameWithoutExtension(idmp4);
string path2 = $"Info/{id}.json";
if(!await baseCtl.FileExistsAsync(path2))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
} var data= await baseCtl.ReadAllTextAsync(path2);
var data2=JsonConvert.DeserializeObject<SavedVideo>(data);
var loc= await BestStreams.GetPathResolution(baseCtl,data2,Resolution.PreMuxed);
if(!await baseCtl.FileExistsAsync(loc))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
}
using(var s = await baseCtl.OpenReadAsyncWithLength(loc))
{
await ctx.SendStreamAsync(s,HeyRed.Mime.MimeTypesMap.GetMimeType(loc));
}
}
}
else if(path.StartsWith("/File/Converted/"))
{
// redirect to new
// /File/NotConverted/xxxxxxxxxxx.mp4
string idmp4=WebUtility.UrlDecode(path.Substring(16));
if(idmp4.Length == 15)
{
string id=Path.GetFileNameWithoutExtension(idmp4);
string path2 = $"Info/{id}.json";
if(!await baseCtl.FileExistsAsync(path2))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
} var data= await baseCtl.ReadAllTextAsync(path2);
var data2=JsonConvert.DeserializeObject<SavedVideo>(data);
var loc= await BestStreams.GetPathResolution(baseCtl,data2,Resolution.Mux);
if(!await baseCtl.FileExistsAsync(loc))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
}
using(var s = await baseCtl.OpenReadAsyncWithLength(loc))
{
await ctx.SendStreamAsync(s,HeyRed.Mime.MimeTypesMap.GetMimeType(loc));
}
}
}
else if(path.StartsWith("/File/Audio/"))
{
// redirect to new
// /File/NotConverted/xxxxxxxxxxx.mp4
string idmp4=WebUtility.UrlDecode(path.Substring(12));
if(idmp4.Length == 15)
{
string id=Path.GetFileNameWithoutExtension(idmp4);
string path2 = $"Info/{id}.json";
if(!await baseCtl.FileExistsAsync(path2))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
} var data= await baseCtl.ReadAllTextAsync(path2);
var data2=JsonConvert.DeserializeObject<SavedVideo>(data);
var loc= await BestStreams.GetPathResolution(baseCtl,data2,Resolution.AudioOnly);
if(!await baseCtl.FileExistsAsync(loc))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
}
using(var s = await baseCtl.OpenReadAsyncWithLength(loc))
{
await ctx.SendStreamAsync(s,HeyRed.Mime.MimeTypesMap.GetMimeType(loc));
}
}
}
else if(path.StartsWith("/File/Info/"))
{
string idjson=WebUtility.UrlDecode(path.Substring(11));
string path2 = $"Info/{idjson}";
if(!await baseCtl.FileExistsAsync(path2))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
}
var data= await baseCtl.ReadAllTextAsync(path2);
var data2=JsonConvert.DeserializeObject<SavedVideo>(data);
await ctx.SendJsonAsync(data2.ToLegacy());
}
else*/ if(path.StartsWith("/File/"))
{
string file=WebUtility.UrlDecode(path.Substring(6));
if(!await baseCtl.FileExistsAsync(file))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
}
using(var s = await baseCtl.OpenReadAsyncWithLength(file))
{ {
await ctx.SendStreamAsync(s); await ctx.SendStreamAsync(s);
} }
}else if(path.StartsWith("/GetFiles/")) }/*else if(path.StartsWith("/File-v2/"))
{
string file=WebUtility.UrlDecode(path.Substring(9));
if(!await baseCtl.FileExistsAsync(file))
{
await NotFoundServer.ServerNull.GetAsync(ctx);
return;
}
using(var s = await baseCtl.OpenReadAsyncWithLength(file))
{
await ctx.SendStreamAsync(s);
}
}*/
else if(path.StartsWith("/GetFiles/"))
{ {
await ctx.SendJsonAsync(baseCtl.EnumerateFiles( WebUtility.UrlDecode(path.Substring(10))).ToList()); await ctx.SendJsonAsync(baseCtl.EnumerateFiles( WebUtility.UrlDecode(path.Substring(10))).ToList());
}else if(path.StartsWith("/GetDirectories/")) }else if(path.StartsWith("/GetDirectories/"))
{ {
await ctx.SendJsonAsync(baseCtl.EnumerateDirectories( WebUtility.UrlDecode(path.Substring(16))).ToList()); await ctx.SendJsonAsync(baseCtl.EnumerateDirectories( WebUtility.UrlDecode(path.Substring(16))).ToList());
}else if(path.StartsWith("/FileExists/")) }else if(path.StartsWith("/FileExists-v2/"))
{
await ctx.SendTextAsync(baseCtl.FileExists(WebUtility.UrlDecode(path.Substring(15))) ? "true" : "false","text/plain");
}
else if(path.StartsWith("/FileExists/"))
{ {
await ctx.SendTextAsync(baseCtl.FileExists(WebUtility.UrlDecode(path.Substring(12))) ? "true" : "false","text/plain"); await ctx.SendTextAsync(baseCtl.FileExists(WebUtility.UrlDecode(path.Substring(12))) ? "true" : "false","text/plain");
}else if(path.StartsWith("/DirectoryExists/")) }else if(path.StartsWith("/DirectoryExists/"))
@ -132,7 +261,7 @@ namespace Tesses.YouTubeDownloader.Server
{ {
//Console.WriteLine("F is not null"); //Console.WriteLine("F is not null");
string filename = Path.GetFileName(path0); string filename = $"{v.Title}-{Path.GetFileName(path0)}";
string header=GetVideoContentDisposition(filename).ToString(); string header=GetVideoContentDisposition(filename).ToString();
ctx.ResponseHeaders.Add("Content-Disposition",header); ctx.ResponseHeaders.Add("Content-Disposition",header);
using(var strm = await baseCtl.OpenReadAsync(path0)) using(var strm = await baseCtl.OpenReadAsync(path0))
@ -172,7 +301,7 @@ namespace Tesses.YouTubeDownloader.Server
{ {
//Console.WriteLine("F is not null"); //Console.WriteLine("F is not null");
string filename = Path.GetFileName(path0); string filename = $"{v.Title}-{Path.GetFileName(path0)}";
string header=GetVideoContentDisposition(filename).ToString(); string header=GetVideoContentDisposition(filename).ToString();
ctx.ResponseHeaders.Add("Content-Disposition",header); ctx.ResponseHeaders.Add("Content-Disposition",header);
using(var strm = await baseCtl.OpenReadAsync(path0)) using(var strm = await baseCtl.OpenReadAsync(path0))
@ -197,6 +326,10 @@ namespace Tesses.YouTubeDownloader.Server
{ {
this.Downloader=downloader; this.Downloader=downloader;
Add("/AddItem",AddItem); Add("/AddItem",AddItem);
Add("/AddChannel",AddChannel);
Add("/AddUser",AddUser);
Add("/AddPlaylist",AddPlaylist);
Add("/AddVideo",AddVideo);
Add("/Progress",ProgressFunc); Add("/Progress",ProgressFunc);
Add("/QueueList",QueueList); Add("/QueueList",QueueList);
} }
@ -208,7 +341,7 @@ namespace Tesses.YouTubeDownloader.Server
{ {
await ctx.SendJsonAsync(Downloader.GetProgress()); await ctx.SendJsonAsync(Downloader.GetProgress());
} }
public async Task AddItem(ServerContext ctx) public async Task AddVideo(ServerContext ctx)
{ {
string id; string id;
if(ctx.QueryParams.TryGetFirst("v",out id)) if(ctx.QueryParams.TryGetFirst("v",out id))
@ -225,14 +358,110 @@ namespace Tesses.YouTubeDownloader.Server
VideoId? id1=VideoId.TryParse(id); VideoId? id1=VideoId.TryParse(id);
if(id1.HasValue) if(id1.HasValue)
{ {
await Downloader.AddItemAsync(id1,resolution); await Downloader.AddVideoAsync(id1.Value,resolution);
} }
} }
await ctx.SendTextAsync( await ctx.SendTextAsync(
$"<html><head><titleYou Will Be Redirected in 5 Sec</title><meta http-equiv=\"Refresh\" content=\"5; url='../../'\" /></head><body><h1>You Will Be Redirected in 5 Sec</h1></body></html>\n" $"<html><head><titleYou Will Be Redirected in 5 Sec</title><meta http-equiv=\"Refresh\" content=\"5; url='../../'\" /></head><body><h1>You Will Be Redirected in 5 Sec</h1></body></html>\n"
); );
} }
public async Task AddItem(ServerContext ctx)
{
string id;
if(ctx.QueryParams.TryGetFirst("v",out id))
{
Resolution resolution=Resolution.PreMuxed;
string res;
if(ctx.QueryParams.TryGetFirst("res",out res))
{
if(!Enum.TryParse<Resolution>(res,out resolution))
{
resolution=Resolution.PreMuxed;
}
}
await Downloader.AddItemAsync(id,resolution);
}
await ctx.SendTextAsync(
$"<html><head><titleYou Will Be Redirected in 5 Sec</title><meta http-equiv=\"Refresh\" content=\"5; url='../../'\" /></head><body><h1>You Will Be Redirected in 5 Sec</h1></body></html>\n"
);
}
public async Task AddUser(ServerContext ctx)
{
string id;
if(ctx.QueryParams.TryGetFirst("v",out id))
{
Resolution resolution=Resolution.PreMuxed;
string res;
if(ctx.QueryParams.TryGetFirst("res",out res))
{
if(!Enum.TryParse<Resolution>(res,out resolution))
{
resolution=Resolution.PreMuxed;
}
}
UserName? id1=UserName.TryParse(id);
if(id1.HasValue)
{
await Downloader.AddUserAsync(id1.Value,resolution);
}
}
await ctx.SendTextAsync(
$"<html><head><titleYou Will Be Redirected in 5 Sec</title><meta http-equiv=\"Refresh\" content=\"5; url='../../'\" /></head><body><h1>You Will Be Redirected in 5 Sec</h1></body></html>\n"
);
}
public async Task AddChannel(ServerContext ctx)
{
string id;
if(ctx.QueryParams.TryGetFirst("v",out id))
{
Resolution resolution=Resolution.PreMuxed;
string res;
if(ctx.QueryParams.TryGetFirst("res",out res))
{
if(!Enum.TryParse<Resolution>(res,out resolution))
{
resolution=Resolution.PreMuxed;
}
}
ChannelId? id1=ChannelId.TryParse(id);
if(id1.HasValue)
{
await Downloader.AddChannelAsync(id1.Value,resolution);
}
}
await ctx.SendTextAsync(
$"<html><head><titleYou Will Be Redirected in 5 Sec</title><meta http-equiv=\"Refresh\" content=\"5; url='../../'\" /></head><body><h1>You Will Be Redirected in 5 Sec</h1></body></html>\n"
);
}
public async Task AddPlaylist(ServerContext ctx)
{
string id;
if(ctx.QueryParams.TryGetFirst("v",out id))
{
Resolution resolution=Resolution.PreMuxed;
string res;
if(ctx.QueryParams.TryGetFirst("res",out res))
{
if(!Enum.TryParse<Resolution>(res,out resolution))
{
resolution=Resolution.PreMuxed;
}
}
PlaylistId? id1=PlaylistId.TryParse(id);
if(id1.HasValue)
{
await Downloader.AddPlaylistAsync(id1.Value,resolution);
}
}
await ctx.SendTextAsync(
$"<html><head><titleYou Will Be Redirected in 5 Sec</title><meta http-equiv=\"Refresh\" content=\"5; url='../../'\" /></head><body><h1>You Will Be Redirected in 5 Sec</h1></body></html>\n"
);
}
} }
public class TYTDServer public class TYTDServer
{ {

View File

@ -15,9 +15,9 @@
<PackageId>Tesses.YouTubeDownloader.Server</PackageId> <PackageId>Tesses.YouTubeDownloader.Server</PackageId>
<Author>Mike Nolan</Author> <Author>Mike Nolan</Author>
<Company>Tesses</Company> <Company>Tesses</Company>
<Version>1.0.0.0</Version> <Version>1.0.1.0</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion> <AssemblyVersion>1.0.1.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion> <FileVersion>1.0.1.0</FileVersion>
<Description>Adds WebServer to TYTD</Description> <Description>Adds WebServer to TYTD</Description>
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression> <PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>

View File

@ -241,6 +241,7 @@ namespace Tesses.YouTubeDownloader
audioInfo.AudioCodec=asi.AudioCodec; audioInfo.AudioCodec=asi.AudioCodec;
AudioInfo = audioInfo; AudioInfo = audioInfo;
} }
_si=info;
//vsi.VideoCodec //vsi.VideoCodec
} }
} }

View File

@ -26,7 +26,7 @@ namespace Tesses.YouTubeDownloader
var (Video, Resolution) = Dequeue(out hasAny); var (Video, Resolution) = Dequeue(out hasAny);
if (hasAny) if (hasAny)
{ {
await DownloadVideoAsync(Video, Resolution, token); await DownloadVideoAsync(Video, Resolution, token,new Progress<double>(ReportProgress),true);
} }
} }
@ -75,21 +75,41 @@ namespace Tesses.YouTubeDownloader
} }
} }
} }
private async Task DownloadVideoAsync(SavedVideo video, Resolution resolution, CancellationToken token) public async Task DownloadNoQueue(SavedVideo info,Resolution resolution=Resolution.Mux,CancellationToken token=default(CancellationToken),IProgress<double> progress=null)
{
await DownloadVideoAsync(info,resolution,token,progress,false);
}
public async Task<SavedVideo> GetSavedVideoAsync(VideoId id)
{
VideoMediaContext context=new VideoMediaContext(id,Resolution.PreMuxed);
List<(SavedVideo Video,Resolution)> s=new List<(SavedVideo Video, Resolution)>();
await context.FillQueue(this,s);
if(s.Count> 0)
{
return s.First().Video;
}
return null;
}
private async Task DownloadVideoAsync(SavedVideo video, Resolution resolution, CancellationToken token=default(CancellationToken),IProgress<double> progress=null,bool report=true)
{ {
switch (resolution) switch (resolution)
{ {
case Resolution.Mux: case Resolution.Mux:
await DownloadVideoMuxedAsync(video,token); await DownloadVideoMuxedAsync(video,token,progress,report);
break; break;
case Resolution.PreMuxed: case Resolution.PreMuxed:
await DownloadPreMuxedVideoAsync(video, token); await DownloadPreMuxedVideoAsync(video, token,progress,report);
break; break;
case Resolution.AudioOnly: case Resolution.AudioOnly:
await DownloadAudioOnlyAsync(video,token); await DownloadAudioOnlyAsync(video,token,progress,report);
break; break;
case Resolution.VideoOnly: case Resolution.VideoOnly:
await DownloadVideoOnlyAsync(video,token); await DownloadVideoOnlyAsync(video,token,progress,report);
break; break;
} }
@ -349,15 +369,15 @@ namespace Tesses.YouTubeDownloader
Directory.Delete("TYTD_TEMP",true); Directory.Delete("TYTD_TEMP",true);
return ret; return ret;
} }
private async Task DownloadVideoMuxedAsync(SavedVideo video,CancellationToken token) private async Task DownloadVideoMuxedAsync(SavedVideo video,CancellationToken token,IProgress<double> progress,bool report=true)
{ {
bool isValid=true; bool isValid=true;
isValid=await DownloadVideoOnlyAsync(video,token); isValid=await DownloadVideoOnlyAsync(video,token,progress,report);
if(token.IsCancellationRequested || !isValid) if(token.IsCancellationRequested || !isValid)
{ {
return; return;
} }
isValid = await DownloadAudioOnlyAsync(video,token); isValid = await DownloadAudioOnlyAsync(video,token,progress,report);
if(token.IsCancellationRequested || !isValid) if(token.IsCancellationRequested || !isValid)
{ {
return; return;
@ -367,6 +387,7 @@ namespace Tesses.YouTubeDownloader
{ {
return; return;
} }
if(report)
ReportStartVideo(video,Resolution.Mux,0); ReportStartVideo(video,Resolution.Mux,0);
string complete = $"Muxed/{video.Id}.mkv"; string complete = $"Muxed/{video.Id}.mkv";
string incomplete = $"Muxed/{video.Id}incomplete.mkv"; string incomplete = $"Muxed/{video.Id}incomplete.mkv";
@ -376,12 +397,12 @@ namespace Tesses.YouTubeDownloader
if(await Continue(complete)) if(await Continue(complete))
{ {
if(await MuxVideosAsync(video,complete_vidonly,complete_audonly,incomplete,new Progress<double>(ReportProgress),token)) if(await MuxVideosAsync(video,complete_vidonly,complete_audonly,incomplete,progress,token))
{ {
RenameFile(incomplete,complete); RenameFile(incomplete,complete);
} }
} }
if(report)
ReportEndVideo(video,Resolution.Mux); ReportEndVideo(video,Resolution.Mux);
} }
private void DeleteIfExists(string path) private void DeleteIfExists(string path)
@ -391,10 +412,12 @@ namespace Tesses.YouTubeDownloader
File.Delete(path); File.Delete(path);
} }
} }
public async Task<bool> DownloadVideoOnlyAsync(SavedVideo video,CancellationToken token) public async Task<bool> DownloadVideoOnlyAsync(SavedVideo video,CancellationToken token,IProgress<double> progress,bool report=true)
{ {
bool ret=false; bool ret=false;
var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false); var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false);
if(!can_download) return false;
if(streams != null) if(streams != null)
{ {
await MoveLegacyStreams(video,streams); await MoveLegacyStreams(video,streams);
@ -412,16 +435,18 @@ namespace Tesses.YouTubeDownloader
{ {
return false; return false;
} }
if(report)
ReportStartVideo(video, Resolution.VideoOnly,streams.VideoOnlyStreamInfo.Size.Bytes); ReportStartVideo(video, Resolution.VideoOnly,streams.VideoOnlyStreamInfo.Size.Bytes);
long len=await GetLengthAsync(incomplete); long len=await GetLengthAsync(incomplete);
using(var dest = await OpenOrCreateAsync(incomplete)) using(var dest = await OpenOrCreateAsync(incomplete))
{ {
ret=await CopyStreamAsync(strm,dest,len,streams.VideoOnlyStreamInfo.Size.Bytes,4096,new Progress<double>(ReportProgress),token); ret=await CopyStreamAsync(strm,dest,len,streams.VideoOnlyStreamInfo.Size.Bytes,4096,progress,token);
} }
if(ret) if(ret)
{ {
RenameFile(incomplete,complete); RenameFile(incomplete,complete);
if(report)
ReportEndVideo(video, Resolution.VideoOnly); ReportEndVideo(video, Resolution.VideoOnly);
} }
} }
@ -482,10 +507,12 @@ namespace Tesses.YouTubeDownloader
} }
} }
public async Task<bool> DownloadAudioOnlyAsync(SavedVideo video,CancellationToken token) private async Task<bool> DownloadAudioOnlyAsync(SavedVideo video,CancellationToken token,IProgress<double> progress,bool report=true)
{ {
bool ret=false; bool ret=false;
var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false); var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false);
if(!can_download) return false;
if(streams != null) if(streams != null)
{ {
string complete = $"AudioOnly/{video.Id}.{streams.AudioOnlyStreamInfo.Container}"; string complete = $"AudioOnly/{video.Id}.{streams.AudioOnlyStreamInfo.Container}";
@ -493,7 +520,7 @@ namespace Tesses.YouTubeDownloader
await MoveLegacyStreams(video,streams); await MoveLegacyStreams(video,streams);
if(await Continue(complete)) if(await Continue(complete))
{ {
streams = await BestStreamInfo.GetBestStreams(this,video.Id,token); streams = await BestStreamInfo.GetBestStreams(this,video.Id,token);
if(streams != null) if(streams != null)
{ {
@ -504,16 +531,18 @@ namespace Tesses.YouTubeDownloader
{ {
return false; return false;
} }
if(report)
ReportStartVideo(video, Resolution.AudioOnly,streams.AudioOnlyStreamInfo.Size.Bytes); ReportStartVideo(video, Resolution.AudioOnly,streams.AudioOnlyStreamInfo.Size.Bytes);
long len=await GetLengthAsync(incomplete); long len=await GetLengthAsync(incomplete);
using(var dest = await OpenOrCreateAsync(incomplete)) using(var dest = await OpenOrCreateAsync(incomplete))
{ {
ret=await CopyStreamAsync(strm,dest,len,streams.AudioOnlyStreamInfo.Size.Bytes,4096,new Progress<double>(ReportProgress),token); ret=await CopyStreamAsync(strm,dest,len,streams.AudioOnlyStreamInfo.Size.Bytes,4096,progress,token);
} }
if(ret) if(ret)
{ {
RenameFile(incomplete,complete); RenameFile(incomplete,complete);
if(report)
ReportEndVideo(video, Resolution.AudioOnly); ReportEndVideo(video, Resolution.AudioOnly);
} }
} }
@ -527,9 +556,10 @@ namespace Tesses.YouTubeDownloader
//We know its resolution //We know its resolution
return ret; return ret;
} }
private async Task DownloadPreMuxedVideoAsync(SavedVideo video, CancellationToken token) private async Task DownloadPreMuxedVideoAsync(SavedVideo video, CancellationToken token,IProgress<double> progress,bool report=true)
{ {
var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false); var streams = await BestStreamInfo.GetBestStreams(this, video.Id, token, false);
if(!can_download) return;
if(streams != null) if(streams != null)
{ {
await MoveLegacyStreams(video,streams); await MoveLegacyStreams(video,streams);
@ -549,17 +579,19 @@ namespace Tesses.YouTubeDownloader
{ {
return; return;
} }
if(report)
ReportStartVideo(video,Resolution.PreMuxed,streams.MuxedStreamInfo.Size.Bytes); ReportStartVideo(video,Resolution.PreMuxed,streams.MuxedStreamInfo.Size.Bytes);
long len=await GetLengthAsync(incomplete); long len=await GetLengthAsync(incomplete);
bool ret; bool ret;
using(var dest = await OpenOrCreateAsync(incomplete)) using(var dest = await OpenOrCreateAsync(incomplete))
{ {
ret=await CopyStreamAsync(strm,dest,len,streams.MuxedStreamInfo.Size.Bytes,4096,new Progress<double>(ReportProgress),token); ret=await CopyStreamAsync(strm,dest,len,streams.MuxedStreamInfo.Size.Bytes,4096,progress,token);
} }
//We know its resolution //We know its resolution
if(ret) if(ret)
{ {
RenameFile(incomplete,complete); RenameFile(incomplete,complete);
if(report)
ReportEndVideo(video, Resolution.PreMuxed); ReportEndVideo(video, Resolution.PreMuxed);
} }
} }

View File

@ -14,6 +14,7 @@ namespace Tesses.YouTubeDownloader
{ {
public abstract partial class TYTDStorage : TYTDBase, IWritable, IDownloader public abstract partial class TYTDStorage : TYTDBase, IWritable, IDownloader
{ {
private static readonly HttpClient _default = new HttpClient();
public abstract Task<Stream> CreateAsync(string path); public abstract Task<Stream> CreateAsync(string path);
public abstract void CreateDirectory(string path); public abstract void CreateDirectory(string path);
@ -28,7 +29,7 @@ namespace Tesses.YouTubeDownloader
} }
public TYTDStorage() public TYTDStorage()
{ {
HttpClient=new HttpClient(); HttpClient=_default;
YoutubeClient=new YoutubeClient(HttpClient); YoutubeClient=new YoutubeClient(HttpClient);
ExtensionContext=null; ExtensionContext=null;
} }
@ -40,6 +41,8 @@ namespace Tesses.YouTubeDownloader
} }
} }
bool can_download=true;
public bool CanDownload {get {return can_download;} set {can_download=value;}}
public abstract void MoveDirectory(string src,string dest); public abstract void MoveDirectory(string src,string dest);
public abstract void DeleteFile(string file); public abstract void DeleteFile(string file);
@ -92,6 +95,7 @@ namespace Tesses.YouTubeDownloader
} }
public async Task DownloadThumbnails(VideoId id) public async Task DownloadThumbnails(VideoId id)
{ {
if(!can_download) return;
string Id=id.Value; string Id=id.Value;
string[] res=new string[] {"default.jpg","sddefault.jpg","mqdefault.jpg","hqdefault.jpg","maxresdefault.jpg"}; string[] res=new string[] {"default.jpg","sddefault.jpg","mqdefault.jpg","hqdefault.jpg","maxresdefault.jpg"};
CreateDirectoryIfNotExist($"Thumbnails/{Id}"); CreateDirectoryIfNotExist($"Thumbnails/{Id}");
@ -109,14 +113,18 @@ namespace Tesses.YouTubeDownloader
} }
} }
} }
public void StartLoop(CancellationToken token = default(CancellationToken)) public void CreateDirectories()
{ {
CreateDirectoryIfNotExist("VideoOnly"); CreateDirectoryIfNotExist("VideoOnly");
CreateDirectoryIfNotExist("AudioOnly"); CreateDirectoryIfNotExist("AudioOnly");
CreateDirectoryIfNotExist("Muxed"); CreateDirectoryIfNotExist("Muxed");
CreateDirectoryIfNotExist("PreMuxed"); CreateDirectoryIfNotExist("PreMuxed");
CreateDirectoryIfNotExist("Info"); CreateDirectoryIfNotExist("Info");
CreateDirectoryIfNotExist("Thumbnails"); CreateDirectoryIfNotExist("Thumbnails");
}
public void StartLoop(CancellationToken token = default(CancellationToken))
{
CreateDirectories();
Thread thread0=new Thread(()=>{ Thread thread0=new Thread(()=>{
DownloadLoop(token).Wait(); DownloadLoop(token).Wait();
}); });

View File

@ -7,9 +7,9 @@
<PackageId>Tesses.YouTubeDownloader</PackageId> <PackageId>Tesses.YouTubeDownloader</PackageId>
<Author>Mike Nolan</Author> <Author>Mike Nolan</Author>
<Company>Tesses</Company> <Company>Tesses</Company>
<Version>1.0.0.0</Version> <Version>1.0.1.0</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion> <AssemblyVersion>1.0.1.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion> <FileVersion>1.0.1.0</FileVersion>
<Description>A YouTube Downloader</Description> <Description>A YouTube Downloader</Description>
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression> <PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>