diff --git a/.vs/youtube-downloader/xs/UserPrefs.xml b/.vs/youtube-downloader/xs/UserPrefs.xml index 71545d3..4330388 100644 --- a/.vs/youtube-downloader/xs/UserPrefs.xml +++ b/.vs/youtube-downloader/xs/UserPrefs.xml @@ -1,28 +1,27 @@  - + - - + + - + + + + - - - - - - + + @@ -33,9 +32,7 @@ - - - + \ No newline at end of file diff --git a/Program.cs b/Program.cs index a11742d..1a60151 100644 --- a/Program.cs +++ b/Program.cs @@ -20,7 +20,7 @@ namespace youtube_downloader class Program { - + static string webSitePath; static void Main(string[] arg) { @@ -36,205 +36,59 @@ namespace youtube_downloader // we need to get our app name so that // we can create unique names for our mutex and our pipe - string webSitePath = Server.Functions.Downloader.DL.GetPath(true, "WebSite"); + webSitePath = Server.Functions.Downloader.DL.GetPath(true, "WebSite"); - /*Route.Add("/api/endpoint/", (rq, rp, args) => - { - rp.AsText(HandleRequest(rq.InputStream,rq.CurrentEncoding), "application/json"); - }, - "POST");*/ + + + /* Generic */ + Route.Add("/api/AddItems", (HttpAction)AddItems, "POST"); + Route.Add("/api/AddFile/{Url}", (HttpAction)AddFile); + Route.Add("/api/AddCaptions/{Id}", (HttpAction)AddCaptions); + + /* Videos */ + Route.Add("/api/AddVideoInfo/{Id}", (HttpAction)AddVideoInfo); + Route.Add("/api/AddVideo/{Id}", (HttpAction)AddVideo); + Route.Add("/api/AddVideoRes/{R}/{Id}", (HttpAction)AddVideoRes); + Route.Add("/api/Redownload", (HttpAction)Redownload); + Route.Add("/api/Redownload/{R}", (HttpAction)RedownloadRes); + Route.Add("/api/Watch/{VideoId}", (HttpAction)Watch); + + /* Playlist */ + Route.Add("/api/AddPlaylistOnly/{Id}", (HttpAction)AddPlaylistOnly); + Route.Add("/api/AddPlaylist/{Id}", (HttpAction)AddPlaylist); + Route.Add("/api/AddPlaylistRes/{R}/{Id}", (HttpAction)AddPlaylistRes); + + /* Search */ + Route.Add("/api/SearchOnly/{text}", (HttpAction)SearchOnly); + Route.Add("/api/Search/{text}", (HttpAction)Search); - Route.Add("/api/upload/", (rq,rp,args) => { - var files = rq.ParseBody(args); - foreach (var f in files.Values) - f.Save(Path.Combine(webSitePath,f.FileName)); - rp.AsText("uploaded", "text/plain"); - },"POST"); - Route.Add("/api/AddItems", (HttpAction)AddItems,"POST"); - Route.Add("/", (rq, rp, args) => - { - rp.AsFile(rq, Path.Combine(webSitePath, "index.html")); - }); - Route.Add("/api/Search/{text}", (rq, rp, args) => - { - string search = System.Web.HttpUtility.UrlDecode(args["text"]); - string json = JsonConvert.SerializeObject(Server.Functions.Downloader.Search(search)); - rp.AsText(json, "application/json"); + /* Channel */ + Route.Add("/api/AddChannelOnly/{Id}", (HttpAction)AddChannelOnly); + Route.Add("/api/AddChannel/{Id}", (HttpAction)AddChannel); + Route.Add("/api/AddChannelRes/{R}/{Id}", (HttpAction)AddChannelRes); - }); - Route.Add("/api/SearchOnly/{text}", (rq, rp, args) => - { - string search = System.Web.HttpUtility.UrlDecode(args["text"]); - string json = JsonConvert.SerializeObject(Server.Functions.Downloader.Search(search,false)); - rp.AsText(json, "application/json"); + /* User */ + Route.Add("/api/AddUserOnly/{Id}", (HttpAction)AddUserOnly); + Route.Add("/api/AddUser/{Id}", (HttpAction)AddUser); + Route.Add("/api/AddUserRes/{R}/{Id}", (HttpAction)AddUserRes); - }); - Route.Add("/api/Storage/GetDirectories/{Path}", (rq, rp, args) => - { - string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); + /* Queue and Progress */ + Route.Add("/api/QueueList", (HttpAction)QueueList); + Route.Add("/api/QueueMove/{From}/{To}", (HttpAction)QueueMove); + Route.Add("/api/QueueMove2/{To}/{Id}", (HttpAction)QueueMove2); + Route.Add("/api/Progress", (HttpAction)VideoProgress); + + /* Storage */ + Route.Add("/api/Storage/GetDirectories/{Path}", (HttpAction)StorageGetDirectories); + Route.Add("/api/Storage/GetFiles/{Path}", (HttpAction)StorageGetFiles); + Route.Add("/api/Storage/DirectoryExists/{Path}", (HttpAction)StorageDirectoryExists); + Route.Add("/api/Storage/FileExists/{Path}", (HttpAction)StorageFileExists); + Route.Add("/api/Storage/File/{Path}", (HttpAction)StorageFile); + Route.Add("/api/upload/", (HttpAction)UploadFiles, "POST"); - if (Directory.Exists(path)) - { - string json = Newtonsoft.Json.JsonConvert.SerializeObject(Directory.EnumerateDirectories(path).Select((o) => { return Path.GetFileName(o); })); - rp.AsText(json, "application/json"); - } - else - { - rp.AsText("[]", "application/json"); - } - }); - Route.Add("/api/Storage/GetFiles/{Path}", (rq, rp, args) => - { - string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); - - if (Directory.Exists(path)) - { - string json = Newtonsoft.Json.JsonConvert.SerializeObject(Directory.EnumerateFiles(path).Select((o) => { return Path.GetFileName(o); })); - rp.AsText(json, "application/json"); - } - else - { - rp.AsText("[]", "application/json"); - } - }); - - Route.Add("/api/Storage/FileExists/{Path}", (rq, rp, args) => - { - string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); - string json = File.Exists(path) ? "true" : "false"; - rp.AsText(json, "text/plain"); - - }); - Route.Add("/api/Storage/DirectoryExists/{Path}", (rq, rp, args) => - { - string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); - string json = Directory.Exists(path) ? "true" : "false"; - rp.AsText(json, "text/plain"); - - }); - Route.Add("/api/Storage/File/{Path}", (rq, rp, args) => - { - if (args["path"].StartsWith("config/")) - { - rp.AsText("Access denied"); - } - else - { - string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); - - rp.AsFile(rq, path); - } - }); - Route.Add("/api/AddVideo/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"])); - - rp.AsRedirect("/"); - }); - Route.Add("/api/AddVideoRes/{R}/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); - rp.AsRedirect("/"); - }); - Route.Add("/api/AddPlaylist/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"])); - - rp.AsRedirect("/"); - }); - Route.Add("/api/AddPlaylistRes/{R}/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); - rp.AsRedirect("/"); - }); - Route.Add("/api/AddChannel/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"])); - - rp.AsRedirect("/"); - }); - Route.Add("/api/AddChannelRes/{R}/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); - rp.AsRedirect("/"); - }); - Route.Add("/api/AddUser/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"])); - - rp.AsRedirect("/"); - }); - Route.Add("/api/AddChannelOnly/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadChannelOnly(System.Web.HttpUtility.UrlDecode(args["Id"])); - - rp.AsRedirect("/"); - }); - Route.Add("/api/AddUserOnly/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadUserOnly(System.Web.HttpUtility.UrlDecode(args["Id"])); - rp.AsRedirect("/"); - }); - Route.Add("/api/AddPlaylistOnly/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadPlaylistOnly(System.Web.HttpUtility.UrlDecode(args["Id"]),Resolution.NoConvert); - rp.AsRedirect("/"); - }); - Route.Add("/api/AddVideoInfo/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadVideoInfo(System.Web.HttpUtility.UrlDecode(args["Id"]),Resolution.NoConvert); - rp.AsRedirect("/"); - }); - Route.Add("/api/AddUserRes/{R}/{Id}", (rq, rp, args) => - { - Server.Functions.Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); - rp.AsRedirect("/"); - }); - Route.Add("/api/QueueMove/{From}/{To}", (rq, rp, args) => - { - Server.Functions.Downloader.ModQueue(args["To"], args["From"]); - rp.AsRedirect("/"); - }); - Route.Add("/api/QueueList", (rq, rp, args) => - { - string json = Server.Functions.Downloader.GetQueue(); - rp.AsText(json, "application/json"); - }); - Route.Add("/api/Progress", (rq, rp, args) => - { - string json = JsonConvert.SerializeObject(Server.Functions.Downloader.GetProgress()); - rp.AsText(json, "application/json"); - }); - Route.Add("/api/Watch/{VideoId}", (rq, rp, args) => - { - var txt = Templating.RenderFile(Path.Combine(webSitePath, "watch_page.thtml"), args); //populate template - rp.AsText(txt); - }); - - Route.Add("/api/Redownload", (rq, rp, args) => - { - foreach (var item in Directory.GetFiles(Server.Functions.Downloader.DL.GetPath(true, "Info"), "*.json")) - { - string id = System.IO.Path.GetFileNameWithoutExtension(item); - Server.Functions.Downloader.DownloadVideo(id, Resolution.NoConvert); - } - rp.AsRedirect("/"); - }); - Route.Add("/api/Redownload/{R}", (rq, rp, args) => - { - foreach (var item in Directory.GetFiles(Server.Functions.Downloader.DL.GetPath(true, "Info"), "*.json")) - { - string id = System.IO.Path.GetFileNameWithoutExtension(item); - Server.Functions.Downloader.DownloadVideo(id, (Resolution)int.Parse(args["R"])); - } - rp.AsRedirect("/"); - }); - Route.Add("/{Path}", (rq, rp, args) => - { - string path = Path.Combine(webSitePath, args["Path"].Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0]); - - rp.AsFile(rq, path); - }); + /* Other */ + Route.Add("/", (HttpAction)Index); + Route.Add("/{Path}", (HttpAction)RootPath); Console.WriteLine("Almost Ready To Listen"); if (arg.Length > 0) @@ -249,33 +103,243 @@ namespace youtube_downloader } } + #region Generic private static void AddItems(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) { var f = request.ParseBody(arguments); - foreach(var file in f.Values) + foreach (var file in f.Values) { using (var req = new StreamReader(file.Value)) { - List tripletlst = JsonConvert.DeserializeObject>( req.ReadToEnd()); + List tripletlst = JsonConvert.DeserializeObject>(req.ReadToEnd()); Server.Functions.Downloader.DownloadItems(tripletlst); response.Redirect("/"); } } - + } - /* -private static string HandleRequest(Stream inputStream, Encoding currentEncoding) -{ - using (var streamReader = new StreamReader(inputStream, currentEncoding)) - { - return Newtonsoft.Json.JsonConvert.SerializeObject(HandleRequest(Newtonsoft.Json.JsonConvert.DeserializeObject(streamReader.ReadToEnd())); - } -} -private static YoutubeDownloaderResponse HandleRequest(YoutubeDownloaderRequest data) -{ + public static void AddFile(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) + { + Server.Functions.Downloader.DownloadFile(arguments["Url"]); + } + public static void AddCaptions(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) + { + Server.Functions.Downloader.DownloadCaptions(arguments["Id"]); + } + #endregion + #region Video + public static void AddVideoInfo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadVideoInfo(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert); + rp.AsRedirect("/"); + } + public static void AddVideo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"])); + + rp.AsRedirect("/"); + } + public static void AddVideoRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); + rp.AsRedirect("/"); + } + public static void Redownload(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + foreach (var item in Directory.GetFiles(Server.Functions.Downloader.DL.GetPath(true, "Info"), "*.json")) + { + string id = System.IO.Path.GetFileNameWithoutExtension(item); + Server.Functions.Downloader.DownloadVideo(id, Resolution.NoConvert); + } + rp.AsRedirect("/"); + } + + public static void RedownloadRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + foreach (var item in Directory.GetFiles(Server.Functions.Downloader.DL.GetPath(true, "Info"), "*.json")) + { + string id = System.IO.Path.GetFileNameWithoutExtension(item); + Server.Functions.Downloader.DownloadVideo(id, (Resolution)int.Parse(args["R"])); + } + rp.AsRedirect("/"); + } + public static void Watch(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + var txt = Templating.RenderFile(Path.Combine(webSitePath, "watch_page.thtml"), args); //populate template + rp.AsText(txt); + } + #endregion + #region Playlist + public static void AddPlaylistOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadPlaylistOnly(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert); + rp.AsRedirect("/"); + } + public static void AddPlaylist(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"])); + + rp.AsRedirect("/"); + } + public static void AddPlaylistRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); + rp.AsRedirect("/"); + } + #endregion + #region Search + public static void SearchOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string search = System.Web.HttpUtility.UrlDecode(args["text"]); + string json = JsonConvert.SerializeObject(Server.Functions.Downloader.Search(search, false)); + rp.AsText(json, "application/json"); + + } + public static void Search(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string search = System.Web.HttpUtility.UrlDecode(args["text"]); + string json = JsonConvert.SerializeObject(Server.Functions.Downloader.Search(search)); + rp.AsText(json, "application/json"); + + } + #endregion + #region Channel + public static void AddChannelOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadChannelOnly(System.Web.HttpUtility.UrlDecode(args["Id"])); + + rp.AsRedirect("/"); + } + public static void AddChannel(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"])); + + rp.AsRedirect("/"); + } + public static void AddChannelRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); + rp.AsRedirect("/"); + } + #endregion + #region User + public static void AddUserOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadUserOnly(System.Web.HttpUtility.UrlDecode(args["Id"])); + rp.AsRedirect("/"); + } + public static void AddUser(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"])); + + rp.AsRedirect("/"); + } + public static void AddUserRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); + rp.AsRedirect("/"); + } + #endregion + #region Queue And Progress + public static void QueueList(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string json = Server.Functions.Downloader.GetQueue(); + rp.AsText(json, "application/json"); + } + public static void QueueMove(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + Server.Functions.Downloader.ModQueue(args["To"], args["From"]); + rp.AsRedirect("/"); + } + public static void QueueMove2(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) + { + Server.Functions.Downloader.ModQueue2(arguments["To"], arguments["Id"]); + response.AsRedirect("/"); + } + public static void VideoProgress(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string json = JsonConvert.SerializeObject(Server.Functions.Downloader.GetProgress()); + rp.AsText(json, "application/json"); + } + #endregion + #region Storage + public static void StorageGetDirectories(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); + + if (Directory.Exists(path)) + { + string json = Newtonsoft.Json.JsonConvert.SerializeObject(Directory.EnumerateDirectories(path).Select((o) => { return Path.GetFileName(o); })); + rp.AsText(json, "application/json"); + } + else + { + rp.AsText("[]", "application/json"); + } + } + public static void StorageGetFiles(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); + + if (Directory.Exists(path)) + { + string json = Newtonsoft.Json.JsonConvert.SerializeObject(Directory.EnumerateFiles(path).Select((o) => { return Path.GetFileName(o); })); + rp.AsText(json, "application/json"); + } + else + { + rp.AsText("[]", "application/json"); + } + } + public static void StorageDirectoryExists(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); + string json = Directory.Exists(path) ? "true" : "false"; + rp.AsText(json, "text/plain"); + + } + public static void StorageFileExists(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); + string json = File.Exists(path) ? "true" : "false"; + rp.AsText(json, "text/plain"); + + } + public static void StorageFile(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + if (args["path"].StartsWith("config/")) + { + rp.AsText("Access denied"); + } + else + { + string path = Server.Functions.Downloader.DL.GetPath(true, args["Path"]); + + rp.AsFile(rq, path); + } + } + public static void UploadFiles(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + var files = rq.ParseBody(args); + foreach (var f in files.Values) + f.Save(Path.Combine(webSitePath, f.FileName)); + rp.AsText("uploaded", "text/plain"); + } + #endregion + #region Other + public static void Index(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + rp.AsFile(rq, Path.Combine(webSitePath, "index.html")); + } + public static void RootPath(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) + { + string path = Path.Combine(webSitePath, args["Path"].Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0]); + + rp.AsFile(rq, path); + } + #endregion -}*/ } } diff --git a/Server/Functions/Downloader.cs b/Server/Functions/Downloader.cs index 7eb918a..c34c07a 100644 --- a/Server/Functions/Downloader.cs +++ b/Server/Functions/Downloader.cs @@ -23,24 +23,24 @@ namespace youtube_downloader.Server.Functions { public Downloader() { - // TessesYoutubeDownloader.Server.Functions.Downloader.DL.DownloadThread().GetAwaiter().GetResult(); + // TessesYoutubeDownloader.Server.Functions.Downloader.DL.DownloadThread().GetAwaiter().GetResult(); } - public List infoQueue = new List(); + public List infoQueue = new List(); public static YoutubeClient CreateYoutubeClient() { - + ServicePointManager .ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; HttpClientHandler handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; - + Directory.CreateDirectory("config"); - string cookiesFile=Path.Combine("config", "cookies.txt"); + string cookiesFile = Path.Combine("config", "cookies.txt"); if (File.Exists(cookiesFile)) { - var cookies=CookiesTxt.Parser.ParseFileAsCookieCollection(cookiesFile); + var cookies = CookiesTxt.Parser.ParseFileAsCookieCollection(cookiesFile); handler.CookieContainer.Add(cookies); } Http = new HttpClient(handler); @@ -54,18 +54,18 @@ namespace youtube_downloader.Server.Functions static HttpClient Http; - internal YoutubeClient ytc = CreateYoutubeClient(); - static VideoDownloadProgress P=new VideoDownloadProgress(); - Progress DownloadP =new Progress( (e)=> { P.Progress = (int)(e * 100.0); }); - - public List Queue = new List(); + internal YoutubeClient ytc = CreateYoutubeClient(); + static VideoDownloadProgress P = new VideoDownloadProgress(); + Progress DownloadP = new Progress((e) => { P.Progress = (int)(e * 100.0); P.ProgressRaw = e; }); + + public List Queue = new List(); internal static string GetQueue() { string q; lock (DL.Queue) { - q = JsonConvert.SerializeObject(DL.Queue.Select(o => o.Video)) ; + q = JsonConvert.SerializeObject(DL.Queue.Select(o => o.Video)); } return q; } @@ -97,7 +97,7 @@ namespace youtube_downloader.Server.Functions { _DownloadVideos(items); } - }catch(Exception ex) + } catch (Exception ex) { Console.WriteLine(ex.Message); @@ -106,34 +106,32 @@ namespace youtube_downloader.Server.Functions } } while (true); } - internal static void ModQueue(string mvto, string index) + internal static void ModQueue2(string mvto, string index) { try { - //?mv=up|down|top|bottom|remove,int&i=0,last + //?mv=up|down|top|bottom|remove,int&i=videoId;URL lock (DL.Queue) { - int index2 = 0; - if (index == "last") + int index2 = -1; + for(int i=0;i= DL.Queue.Count) + if(index2 < 0) { - index2 = DL.Queue.Count - 1; + return; } if (mvto == "top") { var v = DL.Queue[index2]; DL.Queue.Remove(v); - DL.Queue.Insert(0,v); + DL.Queue.Insert(0, v); } else if (mvto == "bottom") { @@ -188,7 +186,98 @@ namespace youtube_downloader.Server.Functions } } - }catch(Exception ex) + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + + _ = ex; + } + } + + internal static void ModQueue(string mvto, string index) + { + try + { + //?mv=up|down|top|bottom|remove,int&i=0,last + lock (DL.Queue) + { + int index2 = 0; + if (index == "last") + { + index2 = DL.Queue.Count - 1; + } + else + { + if (!int.TryParse(index, out index2)) + { + index2 = 0; + } + } + if (index2 >= DL.Queue.Count) + { + index2 = DL.Queue.Count - 1; + } + if (mvto == "top") + { + var v = DL.Queue[index2]; + DL.Queue.Remove(v); + DL.Queue.Insert(0, v); + } + else if (mvto == "bottom") + { + var v = DL.Queue[index2]; + DL.Queue.Remove(v); + DL.Queue.Add(v); + } + else if (mvto == "remove") + { + var v = DL.Queue[index2]; + DL.Queue.Remove(v); + + } + else if (mvto == "up") + { + if (index2 > 0) + { + var v = DL.Queue[index2]; + DL.Queue.Remove(v); + + DL.Queue.Insert(index2 - 1, v); + } + + } + else if (mvto == "down") + { + if (index2 < DL.Queue.Count - 1) + { + var v = DL.Queue[index2]; + DL.Queue.Remove(v); + + DL.Queue.Insert(index2 + 1, v); + } + } + else + { + int n1; + + if (int.TryParse(mvto, out n1)) + { + var v = DL.Queue[index2]; + DL.Queue.Remove(v); + if (n1 > index2) + { + DL.Queue.Insert(n1 - 1, v); + } + else + { + DL.Queue.Insert(n1, v); + } + } + } + + } + } catch (Exception ex) { Console.WriteLine(ex.Message); @@ -201,7 +290,7 @@ namespace youtube_downloader.Server.Functions ChannelId? v = ChannelId.TryParse(id); if (v.HasValue) { - InfomationQueueItem item = new InfomationQueueItem(v.Value,Resolution.NoConvert,false); + InfomationQueueItem item = new InfomationQueueItem(v.Value, Resolution.NoConvert, false); lock (DL.infoQueue) { DL.infoQueue.Insert(0, item); @@ -211,10 +300,10 @@ namespace youtube_downloader.Server.Functions public static void DownloadItems(List id) { List items = new List(); - foreach(var item in id) + foreach (var item in id) { var iqi = item.ToInfomationQueueItem(); - if(iqi != null) + if (iqi != null) { items.Add(iqi); } @@ -224,7 +313,7 @@ namespace youtube_downloader.Server.Functions lock (DL.infoQueue) { - DL.infoQueue.InsertRange(0,items); + DL.infoQueue.InsertRange(0, items); } } } @@ -245,7 +334,7 @@ namespace youtube_downloader.Server.Functions { if (File.Exists(v)) { - using(var f = File.OpenRead(v)) + using (var f = File.OpenRead(v)) { return f.Length == 0; } @@ -256,7 +345,7 @@ namespace youtube_downloader.Server.Functions { if (File.Exists("loc.txt")) { - string loc=File.ReadAllText("loc.txt"); + string loc = File.ReadAllText("loc.txt"); try { Directory.CreateDirectory(loc); @@ -264,7 +353,7 @@ namespace youtube_downloader.Server.Functions { return loc; } - }catch(Exception ex) + } catch (Exception ex) { Console.WriteLine(ex.Message); @@ -275,8 +364,8 @@ namespace youtube_downloader.Server.Functions } public string StorageLocation { get { return gStorageLocation(); } } private void _DownloadVideos(SavedVideoObject[] items) - { - + { + lock (Queue) { foreach (var item in items) @@ -286,6 +375,17 @@ namespace youtube_downloader.Server.Functions } } } + public bool FileExists(string nameSrc,ref string nameDest,ref int i) + { + if(i == 1) + { + i++; + return File.Exists(nameSrc); + } + i++; + nameDest= Path.Combine(Path.GetDirectoryName(nameSrc), $"{Path.GetFileNameWithoutExtension(nameSrc)} ({i}){Path.GetExtension(nameSrc)}"); + return File.Exists(nameDest); + } public async Task DownloadThread() { do @@ -294,13 +394,21 @@ namespace youtube_downloader.Server.Functions SavedVideoObject v; lock (Queue) { - canDownload= Queue.Count > 0; + canDownload = Queue.Count > 0; if (canDownload) { v = Queue[0]; Queue.RemoveAt(0); P.Saved = v.Video; - Console.WriteLine($"Download: {v.Video.Title}"); + if (v.RegularFile) + { + Console.WriteLine($"Download: {v.Video.Id}"); + } + else + { + Console.WriteLine($"Download: {v.Video.Title}"); + } + } else { @@ -312,84 +420,103 @@ namespace youtube_downloader.Server.Functions { try { - switch (v.Resolution) - { - case Resolution.Convert: + if (v.RegularFile) { - string mypath = GetPath(true, "Converted", v.Video.Id + "-vidonly.bkp"); - string mypathaudio = GetPath(true, "Audio", v.Video.Id + "incomplete.mp4"); - string mypathCompleteAudio = GetPath(true, "Audio", v.Video.Id + ".mp4"); - string mypathComplete = GetPath(true, "Converted", v.Video.Id + ".mp4"); - string mypathIncompleteConverting = GetPath(true, "Converted", "conv.mkv"); - - if (Continue(mypathComplete)) + var req=await Http.GetAsync(v.Video.Id); + long? Len=req.Content.Headers.ContentLength; + Uri u = new Uri(v.Video.Id); + string abs = u.AbsolutePath; + string name = "file.bin"; + if(abs.Contains("/")) + { + name=abs.Substring(abs.LastIndexOf('/') + 1); + } + if (req.Content.Headers.Contains("Content-Disposition")) + { + name=req.Content.Headers.ContentDisposition.FileName; + } + int fileI=1; + P.Saved.Title = name; + name=GetPath(true, "Download", name); + string filename=name; + while (FileExists(name, ref filename, ref fileI)) ; + long Len2 = long.MaxValue; + if(Len.HasValue) + { + if(Len.Value > 0) { - var s3 = await ytc.Videos.Streams.GetManifestAsync(v.Video.Id); - var best2 = s3.GetAudioOnlyStreams().GetWithHighestBitrate(); + Len2 = Len.Value; + } + } - - - var best = s3.GetVideoOnlyStreams().GetWithHighestVideoQuality(); - P.Length = best.Size.Bytes + best2.Size.Bytes; - ProgressTwo p = new ProgressTwo(best.Size.Bytes, best2.Size.Bytes, DownloadP); - - using (var destStrm = System.IO.File.Open(mypath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) + P.Length = Len2; + long Pos = 0; + byte[] buffer = new byte[4096]; + int Cycles = 0; + IProgress p = DownloadP; + int CYCLES_BETWEEN_REPORT = 5; + using (var srcFile = await req.Content.ReadAsStreamAsync()) + { + using (var destFile = File.Create(filename)) + { + int read; + do { - long pos = 0; - long len = 0; - using (var srcStrm = await ytc.Videos.Streams.GetAsync(best)) + read = await srcFile.ReadAsync(buffer, 0, buffer.Length); + await destFile.WriteAsync(buffer, 0, read); + Pos += read; + Cycles++; + if (Cycles > CYCLES_BETWEEN_REPORT) { - len = srcStrm.Length; - pos = destStrm.Length; - IProgress myProgress = p.Video; - if (pos >= len) - { - - myProgress.Report(1); - - } - /* This is why videos get corrupted */ - srcStrm.Seek(destStrm.Length, SeekOrigin.Begin); - destStrm.Seek(destStrm.Length,SeekOrigin.Begin); - byte[] buffer = new byte[4096]; - int read = 0; - do - { - read = srcStrm.Read(buffer, 0, buffer.Length); - destStrm.Write(buffer, 0, read); - - pos += read; - double myP = (double)pos / (double)len; - myProgress.Report(myP); - } - while (read > 0); + Cycles = 0; + p.Report(Pos / Len2); } + } while (read > 0); + } + } + // DownloadP. + } + else + { + switch (v.Resolution) + { + case Resolution.Convert: - } + string mypath = GetPath(true, "Converted", v.Video.Id + "-vidonly.bkp"); + string mypathaudio = GetPath(true, "Audio", v.Video.Id + "incomplete.mp4"); + string mypathCompleteAudio = GetPath(true, "Audio", v.Video.Id + ".mp4"); + string mypathComplete = GetPath(true, "Converted", v.Video.Id + ".mp4"); + string mypathIncompleteConverting = GetPath(true, "Converted", "conv.mkv"); - IProgress pv = p.Video; - pv.Report(1); - if (Continue(mypathCompleteAudio)) + if (Continue(mypathComplete)) { - long pos = 0; - long len = 0; - using (var destStrm = System.IO.File.Open(mypathaudio, FileMode.OpenOrCreate, FileAccess.ReadWrite)) + var s3 = await ytc.Videos.Streams.GetManifestAsync(v.Video.Id); + var best2 = s3.GetAudioOnlyStreams().GetWithHighestBitrate(); + + + + var best = s3.GetVideoOnlyStreams().GetWithHighestVideoQuality(); + P.Length = best.Size.Bytes + best2.Size.Bytes; + ProgressTwo p = new ProgressTwo(best.Size.Bytes, best2.Size.Bytes, DownloadP); + + using (var destStrm = System.IO.File.Open(mypath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { - using (var srcStrm = await ytc.Videos.Streams.GetAsync(best2)) + long pos = 0; + long len = 0; + using (var srcStrm = await ytc.Videos.Streams.GetAsync(best)) { len = srcStrm.Length; pos = destStrm.Length; - IProgress myProgress = p.Audio; + IProgress myProgress = p.Video; if (pos >= len) { myProgress.Report(1); } - /* This is why videos get corrupted */ + /* This is why videos get corrupted */ srcStrm.Seek(destStrm.Length, SeekOrigin.Begin); - destStrm.Seek(destStrm.Length,SeekOrigin.Begin); - + destStrm.Seek(destStrm.Length, SeekOrigin.Begin); byte[] buffer = new byte[4096]; int read = 0; do @@ -405,128 +532,168 @@ namespace youtube_downloader.Server.Functions } } - File.Move(mypathaudio, mypathCompleteAudio); - } - IProgress pa = p.Video; - pa.Report(1); - ffmpeg.mux(mypath, mypathCompleteAudio, mypathIncompleteConverting); - - File.Move(mypathIncompleteConverting, mypathComplete); - } - break; - case Resolution.NoConvert: - string mypath2 = GetPath(true, "NotConverted", v.Video.Id + "incomplete.mp4"); - string mypath2Complete = GetPath(true, "NotConverted", v.Video.Id + ".mp4"); - - if (Continue(mypath2Complete)) - { - var s = await ytc.Videos.Streams.GetManifestAsync(v.Video.Id); - var best = s.GetMuxedStreams().GetWithHighestVideoQuality(); - P.Length = best.Size.Bytes; - long pos = 0; - long len = 0; - using (var destStrm = System.IO.File.Open(mypath2, FileMode.OpenOrCreate, FileAccess.ReadWrite)) - { - using (var srcStrm = await ytc.Videos.Streams.GetAsync(best)) + IProgress pv = p.Video; + pv.Report(1); + if (Continue(mypathCompleteAudio)) { - len = srcStrm.Length; - pos = destStrm.Length; - IProgress myProgress = DownloadP; - if (pos >= len) + long pos = 0; + long len = 0; + using (var destStrm = System.IO.File.Open(mypathaudio, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { + using (var srcStrm = await ytc.Videos.Streams.GetAsync(best2)) + { + len = srcStrm.Length; + pos = destStrm.Length; + IProgress myProgress = p.Audio; + if (pos >= len) + { - myProgress.Report(1); + myProgress.Report(1); + + } + /* This is why videos get corrupted */ + srcStrm.Seek(destStrm.Length, SeekOrigin.Begin); + destStrm.Seek(destStrm.Length, SeekOrigin.Begin); + + byte[] buffer = new byte[4096]; + int read = 0; + do + { + read = srcStrm.Read(buffer, 0, buffer.Length); + destStrm.Write(buffer, 0, read); + + pos += read; + double myP = (double)pos / (double)len; + myProgress.Report(myP); + } + while (read > 0); + } } - /* This is why videos get corrupted */ - srcStrm.Seek(destStrm.Length, SeekOrigin.Begin); - destStrm.Seek(destStrm.Length,SeekOrigin.Begin); - byte[] buffer = new byte[4096]; - int read = 0; - do - { - read = srcStrm.Read(buffer, 0, buffer.Length); - destStrm.Write(buffer, 0, read); - - pos += read; - double myP = (double)pos / (double)len; - myProgress.Report(myP); - } - while (read > 0); + File.Move(mypathaudio, mypathCompleteAudio); } + IProgress pa = p.Video; + pa.Report(1); + ffmpeg.mux(mypath, mypathCompleteAudio, mypathIncompleteConverting); + + File.Move(mypathIncompleteConverting, mypathComplete); } - File.Move(mypath2, mypath2Complete); - } + break; + case Resolution.NoConvert: + string mypath2 = GetPath(true, "NotConverted", v.Video.Id + "incomplete.mp4"); + string mypath2Complete = GetPath(true, "NotConverted", v.Video.Id + ".mp4"); - - break; - case Resolution.Audio: - string mypath3 = GetPath(true, "Audio", v.Video.Id + "incomplete.mp4"); - string mypath3Complete = GetPath(true, "Audio", v.Video.Id + ".mp4"); - if (Continue(mypath3Complete)) - { - var s2 = await ytc.Videos.Streams.GetManifestAsync(v.Video.Id); - var best2 = s2.GetAudioOnlyStreams().GetWithHighestBitrate(); - P.Length = best2.Size.Bytes; - long pos = 0; - long len = 0; - using (var destStrm = System.IO.File.Open(mypath3, FileMode.OpenOrCreate, FileAccess.ReadWrite)) + if (Continue(mypath2Complete)) { - using (var srcStrm = await ytc.Videos.Streams.GetAsync(best2)) + var s = await ytc.Videos.Streams.GetManifestAsync(v.Video.Id); + var best = s.GetMuxedStreams().GetWithHighestVideoQuality(); + P.Length = best.Size.Bytes; + long pos = 0; + long len = 0; + using (var destStrm = System.IO.File.Open(mypath2, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { - len = srcStrm.Length; - pos = destStrm.Length; - IProgress myProgress = DownloadP; - if (pos >= len) + using (var srcStrm = await ytc.Videos.Streams.GetAsync(best)) { + len = srcStrm.Length; + pos = destStrm.Length; + IProgress myProgress = DownloadP; + if (pos >= len) + { - myProgress.Report(1); + myProgress.Report(1); + } + /* This is why videos get corrupted */ + srcStrm.Seek(destStrm.Length, SeekOrigin.Begin); + destStrm.Seek(destStrm.Length, SeekOrigin.Begin); + byte[] buffer = new byte[4096]; + int read = 0; + do + { + read = srcStrm.Read(buffer, 0, buffer.Length); + destStrm.Write(buffer, 0, read); + + pos += read; + double myP = (double)pos / (double)len; + myProgress.Report(myP); + } + while (read > 0); } - /* This is why videos get corrupted */ - srcStrm.Seek(destStrm.Length, SeekOrigin.Begin); - destStrm.Seek(destStrm.Length,SeekOrigin.Begin); - byte[] buffer = new byte[4096]; - int read = 0; - do - { - read = srcStrm.Read(buffer, 0, buffer.Length); - destStrm.Write(buffer, 0, read); - pos += read; - double myP = (double)pos / (double)len; - myProgress.Report(myP); - } - while (read > 0); } - + File.Move(mypath2, mypath2Complete); } - File.Move(mypath3, mypath3Complete); - } - break; + + + break; + case Resolution.Audio: + string mypath3 = GetPath(true, "Audio", v.Video.Id + "incomplete.mp4"); + string mypath3Complete = GetPath(true, "Audio", v.Video.Id + ".mp4"); + if (Continue(mypath3Complete)) + { + var s2 = await ytc.Videos.Streams.GetManifestAsync(v.Video.Id); + var best2 = s2.GetAudioOnlyStreams().GetWithHighestBitrate(); + P.Length = best2.Size.Bytes; + long pos = 0; + long len = 0; + using (var destStrm = System.IO.File.Open(mypath3, FileMode.OpenOrCreate, FileAccess.ReadWrite)) + { + using (var srcStrm = await ytc.Videos.Streams.GetAsync(best2)) + { + len = srcStrm.Length; + pos = destStrm.Length; + IProgress myProgress = DownloadP; + if (pos >= len) + { + + myProgress.Report(1); + + } + /* This is why videos get corrupted */ + srcStrm.Seek(destStrm.Length, SeekOrigin.Begin); + destStrm.Seek(destStrm.Length, SeekOrigin.Begin); + byte[] buffer = new byte[4096]; + int read = 0; + do + { + read = srcStrm.Read(buffer, 0, buffer.Length); + destStrm.Write(buffer, 0, read); + + pos += read; + double myP = (double)pos / (double)len; + myProgress.Report(myP); + } + while (read > 0); + } + + } + File.Move(mypath3, mypath3Complete); + } + break; + } } - }catch(Exception ex) + } catch (Exception ex) { Console.WriteLine(ex.Message); } } System.Threading.Thread.Sleep(4000); - } + } while (true); } - internal void _DownloadThumbnail(int w,int h,string id,string tnail) + internal void _DownloadThumbnail(int w, int h, string id, string tnail) { try { - string p = GetPath(true,"Thumbnails", w.ToString() + 'x' + h.ToString(), id + ".jpg"); + string p = GetPath(true, "Thumbnails", w.ToString() + 'x' + h.ToString(), id + ".jpg"); if (!File.Exists(p)) { ffmpeg.download_thumbnail(tnail, p); - } + } } - catch(Exception ex) + catch (Exception ex) { Console.WriteLine(ex.Message); @@ -553,12 +720,12 @@ namespace youtube_downloader.Server.Functions _ = ex; } } - public static async Task> Search(string text,bool downloadThumbs=true) + public static async Task> Search(string text, bool downloadThumbs = true) { List media = new List(); try { - + await DL.ytc.Search.GetVideosAsync(text).ForEachAsync((e) => { if (downloadThumbs) @@ -569,7 +736,7 @@ namespace youtube_downloader.Server.Functions } } media.Add(new SavedMedia() { Title = e.Title, Id = e.Id, Kind = InfoType.Video }); - + }); await DL.ytc.Search.GetPlaylistsAsync(text).ForEachAsync((e) => { if (downloadThumbs) @@ -579,8 +746,8 @@ namespace youtube_downloader.Server.Functions DL._DownloadThumbnail2(t.Resolution.Width, t.Resolution.Height, e.Id, t.Url); } } - media.Add(new SavedMedia() { Title = e.Title, Id = e.Id, Kind = InfoType.Playlist }); - + media.Add(new SavedMedia() { Title = e.Title, Id = e.Id, Kind = InfoType.Playlist }); + }); await DL.ytc.Search.GetChannelsAsync(text).ForEachAsync((e) => { if (downloadThumbs) @@ -590,10 +757,10 @@ namespace youtube_downloader.Server.Functions DL._DownloadThumbnail2(t.Resolution.Width, t.Resolution.Height, e.Id, t.Url); } } - media.Add(new SavedMedia() { Title = e.Title, Id = e.Id, Kind = InfoType.Channel }); - + media.Add(new SavedMedia() { Title = e.Title, Id = e.Id, Kind = InfoType.Channel }); + }); - }catch (Exception ex) + } catch (Exception ex) { _ = ex; } @@ -603,9 +770,19 @@ namespace youtube_downloader.Server.Functions { return DL.Queue; } + public static void DownloadFile(string id) + { - - public static void DownloadVideo(string id,Resolution res) + + InfomationQueueItem item = new InfomationQueueItem(new Uri(id)); + lock (DL.infoQueue) + { + DL.infoQueue.Insert(0, item); + } + + } + + public static void DownloadVideo(string id, Resolution res) { VideoId? v = VideoId.TryParse(id); if (v.HasValue) @@ -634,6 +811,18 @@ namespace youtube_downloader.Server.Functions { DownloadVideo(v, Resolution.NoConvert); } + public static void DownloadCaptions(string id) + { + VideoId? v = VideoId.TryParse(id); + if(v.HasValue) + { + InfomationQueueItem item = new InfomationQueueItem(v.Value); + lock (DL.infoQueue) + { + DL.infoQueue.Insert(0, item); + } + } + } public static void DownloadPlaylist(string id,Resolution res) { PlaylistId? v = PlaylistId.TryParse(id); diff --git a/Server/Models/InfoType.cs b/Server/Models/InfoType.cs index fcfe540..fe03aec 100644 --- a/Server/Models/InfoType.cs +++ b/Server/Models/InfoType.cs @@ -10,7 +10,8 @@ namespace youtube_downloader.Server.Models Playlist=1, Channel=2, User=3, - ClosedCaptions=4 + ClosedCaptions=4, + FileDownload=5 } public class IDResolutionTypeTriplet { @@ -40,6 +41,9 @@ namespace youtube_downloader.Server.Models UserName user = Id; return new InfomationQueueItem(user, Resolution, download); + case InfoType.ClosedCaptions: + VideoId vid2 = Id; + return new InfomationQueueItem(vid2); } return null; diff --git a/Server/Models/InfomationQueueItem.cs b/Server/Models/InfomationQueueItem.cs index 167413d..f358d08 100644 --- a/Server/Models/InfomationQueueItem.cs +++ b/Server/Models/InfomationQueueItem.cs @@ -22,6 +22,20 @@ namespace youtube_downloader.Server.Models Type = InfoType.Video; this.res = res; } + public InfomationQueueItem(VideoId id) + { + Data = id.Value; + DownloadActualDataAfterwards = false; + Type = InfoType.ClosedCaptions; + this.res = 0; + } + public InfomationQueueItem(IDResolutionTypeTriplet triplet) + { + Data = triplet.Id; + DownloadActualDataAfterwards = true; + Type = triplet.Type; + this.res = triplet.Resolution; + } public InfomationQueueItem(PlaylistId id,Resolution res,bool download = true) { Data = id.Value; @@ -29,6 +43,13 @@ namespace youtube_downloader.Server.Models Type = InfoType.Playlist; this.res = res; } + public InfomationQueueItem(Uri url) + { + Data = url.ToString(); + DownloadActualDataAfterwards = true; + Type = InfoType.FileDownload; + this.res = 0; + } public InfomationQueueItem(ChannelId id, Resolution res, bool download = true) { Data = id.Value; @@ -61,6 +82,25 @@ namespace youtube_downloader.Server.Models { switch (Type) { + case InfoType.FileDownload: + return new SavedVideoObject[] { new SavedVideoObject(Data) }; + case InfoType.ClosedCaptions: + string path = Functions.Downloader.DL.GetPath(true, "ClosedCaptions", Data); + if (!Directory.Exists(path)) + { + + var cc0 = await Functions.Downloader.DL.ytc.Videos.ClosedCaptions.GetManifestAsync(Data); + string trackInfo = Functions.Downloader.DL.GetPath(true, "ClosedCaptions", Data,"track_info.json"); + File.WriteAllText(trackInfo, JsonConvert.SerializeObject(cc0.Tracks)); + foreach (var track in cc0.Tracks) + { + string trackType = track.IsAutoGenerated ? "auto" : "manu"; + string langFileName = $"{trackType}_{track.Language.Code}.srt"; + string track2 = Functions.Downloader.DL.GetPath(true, "ClosedCaptions", Data,langFileName); + await Functions.Downloader.DL.ytc.Videos.ClosedCaptions.DownloadAsync(track, track2); + } + } + break; case InfoType.Video: { string infPath = Functions.Downloader.DL.GetPath(true, "Info", Data + ".json"); diff --git a/Server/Models/SavedVideo.cs b/Server/Models/SavedVideo.cs index 5a8bcfe..61754e8 100644 --- a/Server/Models/SavedVideo.cs +++ b/Server/Models/SavedVideo.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using youtube_downloader.Server.Functions; - +using YoutubeExplode.Videos; namespace TessesYoutubeDownloader.Server.Models { @@ -14,8 +14,28 @@ namespace TessesYoutubeDownloader.Server.Models NoConvert=1, Audio=2 } + public struct ClosedCaptions + { + public ClosedCaptions(VideoId id) + { + VideoId = id; + } + public VideoId VideoId; + } public class SavedVideoObject { + public SavedVideoObject() + { + RegularFile = false; + } + public SavedVideoObject(string url) + { + RegularFile = true; + Video = new SavedVideo() { Id = url }; + } + public bool RegularFile { get; set; } + + public SavedVideo Video { get; set; } public Resolution Resolution { get; set; } } diff --git a/bin/Release/youtube-downloader.exe b/bin/Release/youtube-downloader.exe index 214a490..1e98e63 100644 Binary files a/bin/Release/youtube-downloader.exe and b/bin/Release/youtube-downloader.exe differ diff --git a/obj/x86/Release/youtube-downloader.csprojAssemblyReference.cache b/obj/x86/Release/youtube-downloader.csprojAssemblyReference.cache index c81f003..a54278b 100644 Binary files a/obj/x86/Release/youtube-downloader.csprojAssemblyReference.cache and b/obj/x86/Release/youtube-downloader.csprojAssemblyReference.cache differ diff --git a/obj/x86/Release/youtube-downloader.exe b/obj/x86/Release/youtube-downloader.exe index 214a490..1e98e63 100644 Binary files a/obj/x86/Release/youtube-downloader.exe and b/obj/x86/Release/youtube-downloader.exe differ