diff --git a/.vs/youtube-downloader/xs/UserPrefs.xml b/.vs/youtube-downloader/xs/UserPrefs.xml index 36fbc28..11cc4ca 100644 --- a/.vs/youtube-downloader/xs/UserPrefs.xml +++ b/.vs/youtube-downloader/xs/UserPrefs.xml @@ -7,7 +7,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/Program.cs b/Program.cs index b938d8d..5096bce 100644 --- a/Program.cs +++ b/Program.cs @@ -24,6 +24,7 @@ using PlaylistsNET.Utils; using YoutubeExplode.Playlists; using Dasync.Collections; using YoutubeExplode.Search; +using Hyperlinq; namespace TYTD { @@ -41,6 +42,7 @@ namespace TYTD static string webSitePath; static void Main(string[] arg) { + Directory.CreateDirectory(Path.Combine("config", "apidll")); Downloader.GetManifest = GetManifest; Thread t = new Thread(new ThreadStart(() => { Downloader.DL.DownloadThread().GetAwaiter().GetResult(); @@ -59,81 +61,107 @@ namespace TYTD webSitePath = Downloader.DL.GetPath(true, "WebSite"); Route.Before += Route_Before; - - - /* Generic */ - Route.Add("/api/AddItems", (HttpAction)AddItems, "POST"); - Route.Add("/api/AddItem/{Id}", (HttpAction)AddItem); - Route.Add("/api/AddItemRes/{R}/{Id}", (HttpAction)AddItemRes); - Route.Add("/api/AddFile/{Url}", (HttpAction)AddFile); - Route.Add("/api/AddCaptions/{Id}", (HttpAction)AddCaptions); - - /* Videos */ - Route.Add("/api/AddVideoInfo/{Id}", 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); - Route.Add("/api/VideoInfo/{Id}",(HttpAction)VideoInfo); - /* Playlist */ - Route.Add("/api/AddPlaylistOnly/{Id}", AddPlaylistOnly); - Route.Add("/api/AddPlaylist/{Id}", (HttpAction)AddPlaylist); - Route.Add("/api/AddPlaylistRes/{R}/{Id}", (HttpAction)AddPlaylistRes); - Route.Add("/api/PersonalPlaylist/{PlaylistName}",(HttpAction)PersonalPlaylist); - Route.Add("/api/CreatePlaylist/{Ids}/playlist.{extension}", (HttpAction)CreatePlaylist); - Route.Add("/api/CreatePlaylistRes/{Ids}/playlist.{extension}", (HttpAction)CreatePlaylistRes); - Route.Add("/api/PlaylistInfo/{Id}", (HttpAction)PlaylistInfo); - Route.Add("/api/ListPlaylists/", (HttpAction)ListPlaylists); - /* Search */ - Route.Add("/api/SearchOnly/{text}", (HttpAction)SearchOnly); - Route.Add("/api/Search/{text}", (HttpAction)Search); - Route.Add("/api/SearchPage/", SearchPage); - Route.Add("/api/SearchPage/{query}",SearchPage); - Route.Add("/api/SearchPage/",SearchPage,"POST"); - Route.Add("/api/SearchVideos/", (HttpAction)SearchVideos,"POST"); - Route.Add("/api/SearchVideos/{query}", (HttpAction)SearchVideos, "GET"); - Route.Add("/api/SearchVideos/", (HttpAction)SearchVideos, "GET"); - - /* Channel */ - Route.Add("/api/AddChannelOnly/{Id}", AddChannelOnly); - Route.Add("/api/AddChannel/{Id}", (HttpAction)AddChannel); - Route.Add("/api/AddChannelRes/{R}/{Id}", (HttpAction)AddChannelRes); - - /* User */ - Route.Add("/api/AddUserOnly/{Id}", AddUserOnly); - Route.Add("/api/AddUser/{Id}", (HttpAction)AddUser); - Route.Add("/api/AddUserRes/{R}/{Id}", (HttpAction)AddUserRes); - - /* Queue and Progress */ - Route.Add("/api/QueueList", (HttpAction)QueueList); - Route.Add("/api/QueueListPage/", (HttpAction)QueueListHtml); - Route.Add("/api/QueueMove/{From}/{To}", (HttpAction)QueueMove); - Route.Add("/api/QueueMove2/{To}/{Id}", (HttpAction)QueueMove2); - Route.Add("/api/Progress", (HttpAction)VideoProgress); - Route.Add("/api/Progress.html", (HttpAction)VideoProgressHtml); - Route.Add("/api/Redo", (HttpAction)Redo); - Route.Add("/api/Cancel", (HttpAction)Cancel); - /* 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/Storage/Video/{Id}",(HttpAction)Video); - Route.Add("/api/Storage/VideoRes/{Res}/{Id}",(HttpAction)VideoRes); - Route.Add("/api/upload/", (HttpAction)UploadFiles, "POST"); - Route.Add("/api/endpoint", (HttpAction)Endpoint,"POST"); + /* Generic */ + Downloader.RouteAdd("/api/AddItems","Generic","Post JSON file with\n" + WebUtility.HtmlEncode("") + "\nJson structure is like: this", (HttpAction)AddItems, "POST"); + Downloader.RouteAdd("/api/AddItem/{Id}", "Generic", "Add Item to downloader\nDownloader will auto detect media type\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Id or URL for the media",(HttpAction)AddItem); + Downloader.RouteAdd("/api/AddItemRes/{R}/{Id}","Generic", "Add Item to downloader\nDownloader will auto detect media type\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or URL for the media", (HttpAction)AddItemRes); + Downloader.RouteAdd("/api/AddFile/{Url}", "Generic", "Add Normal HTTP(S) download\nParams:\n{Url}: url to file for download", (HttpAction)AddFile); + Downloader.RouteAdd("/api/AddCaptions/{Id}", "Generic", "Download all subtitles for video\nParams:\n{Id}: video id to get subtitles from", (HttpAction)AddCaptions); + + + /* Videos */ + Downloader.RouteAdd("/api/AddVideoInfo/{Id}", "Videos", "Get Video Info only (Don't Download the video)\nParams:\n{Id}: Video Id to download Info and Thumbnails for",AddVideoInfo); + Downloader.RouteAdd("/api/AddVideo/{Id}","Videos", "Add Video to downloader\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Id or URL for the video", (HttpAction)AddVideo); + Downloader.RouteAdd("/api/AddVideoRes/{R}/{Id}","Videos", "Add Video to downloader\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or URL for the video", (HttpAction)AddVideoRes); + Downloader.RouteAdd("/api/Redownload","Videos","Resume all videos downloading (Ignores Complete) (SD, Premuxed Video)", (HttpAction)Redownload); + Downloader.RouteAdd("/api/RedownloadRes/{R}","Videos", "Resume all videos downloading (Ignores Complete)\nParams:\n{R}: 0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only", (HttpAction)RedownloadRes); + Downloader.RouteAdd("/api/Watch/{VideoId}","Videos", "Brings Up Watch Page, loads watch_page.thtml\nParams:\n{VideoId}: the video id, replaces value in thtml file", (HttpAction)Watch); + Downloader.RouteAdd("/api/VideoInfo/{Id}","Videos","Brings up html Video Info\nParams:\n{Id}: Video Id or Url to get info from",(HttpAction)VideoInfo); + /* Playlist */ + Downloader.RouteAdd("/api/AddPlaylistOnly/{Id}","Playlist","Add playlist, dont download videos\nParams:\n{Id}: Playlist Id or Url to download", AddPlaylistOnly); + Downloader.RouteAdd("/api/RedownloadPlaylist/{Id}", "Playlist", "Redownload Playlist Entries (Wont Update Playlist, use /api/AddPlaylist/ for that)\nThis will download playlist if not already done, or if playlist is empty\n(SD, Premuxed Video)\nParams:\n{Id}: Existing Playlist Id",(HttpAction)RedownloadPlaylist); + Downloader.RouteAdd("/api/RedownloadPlaylistRes/{R}/{Id}", "Playlist", "Redownload Playlist Entries (Wont Update Playlist, use /api/AddPlaylist/ for that)\nThis will download playlist if not already done, or if playlist is empty\nParams:\n{Id}: Existing Playlist Id\n{R}: 0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only", (HttpAction)RedownloadPlaylistRes); + Downloader.RouteAdd("/api/AddPlaylist/{Id}","Playlist", "Add Playlist to downloader\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Id or URL for the Playlist", (HttpAction)AddPlaylist); + Downloader.RouteAdd("/api/AddPlaylistRes/{R}/{Id}","Playlist", "Add Playlist to downloader\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or URL for the playlist", (HttpAction)AddPlaylistRes); + Downloader.RouteAdd("/api/PersonalPlaylist/{PlaylistName}","PersonalPlaylist","Create personal playlist with name",(HttpAction)PersonalPlaylist); + Downloader.RouteAdd("/api/CreatePlaylist/{Ids}/playlist.{extension}","PersonalPlaylist","Create Playlist with Ids\nParams:\n{Ids}: Comma seperated VideoIds\n{extension}: m3u, m3u8, pls, wpl, zpl", (HttpAction)CreatePlaylist); + Downloader.RouteAdd("/api/CreatePlaylistRes/{Ids}/playlist.{extension}","PersonalPlaylist","Create Playlist with Ids, Res\nParams:\n {Ids}: Comma seperated VideoIds,Res,VideoId,Res where Res is 0=HD, 1=SD, 2=Audio only\n{extension}: m3u, m3u8, pls, wpl, zpl", (HttpAction)CreatePlaylistRes); + Downloader.RouteAdd("/api/PlaylistInfo/{Id}","Playlist", "Brings up html Playlist Info\nParams:\n{Id}: Playlist Id or Url to get info from", (HttpAction)PlaylistInfo); + Downloader.RouteAdd("/api/ListPlaylists/","Playlist","List all playlists", (HttpAction)ListPlaylists); + /* Search */ + Downloader.RouteAdd("/api/SearchOnly/{text}","Search","Search youtube without downloading thumbnails, VideoInfos", (HttpAction)SearchOnly); + Downloader.RouteAdd("/api/Search/{text}","Search","Search youtube", (HttpAction)Search); + Downloader.RouteAdd("/api/SearchPage/","Search","Search youtube html", SearchPage); + Downloader.RouteAdd("/api/SearchPage/{query}","Search","Search youtube html",SearchPage); + Downloader.RouteAdd("/api/SearchPage/","Search","Search youtube html",SearchPage,"POST"); + Downloader.RouteAdd("/api/SearchVideos/","Video", "Search existing videos", (HttpAction)SearchVideos,"POST"); + Downloader.RouteAdd("/api/SearchVideos/{query}","Videos", "Search existing videos", (HttpAction)SearchVideos, "GET"); + Downloader.RouteAdd("/api/SearchVideos/", "Videos", "Search existing videos", (HttpAction)SearchVideos, "GET"); + + /* Channel */ + Downloader.RouteAdd("/api/AddChannelOnly/{Id}","Channel", "Add Channel, dont download videos\nParams:\n{Id}: Channel Id or Url to download", AddChannelOnly); + Downloader.RouteAdd("/api/AddChannel/{Id}","Channel", "Add Channel to downloader\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Id or URL for the Channel", (HttpAction)AddChannel); + Downloader.RouteAdd("/api/AddChannelRes/{R}/{Id}","Channel", "Add Channel to downloader\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or URL for the Channel", (HttpAction)AddChannelRes); + + /* User */ + Downloader.RouteAdd("/api/AddUserOnly/{Id}","User", "Add Channel By Username, dont download videos\nParams:\n{Id}: Username or UserUrl to download", AddUserOnly); + Downloader.RouteAdd("/api/AddUser/{Id}","User", "Add Channel By Username to downloader\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Name or UserURL for the Channel", (HttpAction)AddUser); + Downloader.RouteAdd("/api/AddUserRes/{R}/{Id}","User", "Add Channel By Username to downloader\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or UserURL for the Channel", (HttpAction)AddUserRes); + + /* Queue and Progress */ + Downloader.RouteAdd("/api/QueueList","Queue","QueueList as json", (HttpAction)QueueList); + Downloader.RouteAdd("/api/QueueListPage/","Queue","QueueList as html", (HttpAction)QueueListHtml); + Downloader.RouteAdd("/api/QueueMove/{From}/{To}","Queue","Move item in queue\nParams:\n{From}: where to move item from (Either number or \"last\")\n{To}: where to move item to (Either number, \"up\", \"down\", \"top\", \"bottom\" or \"remove\"", (HttpAction)QueueMove); + Downloader.RouteAdd("/api/QueueMoveId/{To}/{Id}","Queue", "Move item in queue (Id is from)\nParams:\n{Id}: Video Id (some queue position)\n{To}: where to move item to (Either number, \"up\", \"down\", \"top\", \"bottom\" or \"remove\"", (HttpAction)QueueMove2); + Downloader.RouteAdd("/api/Progress","Current","Get progress as json", (HttpAction)VideoProgress); + Downloader.RouteAdd("/api/Progress.html","Current","Get progress as html", (HttpAction)VideoProgressHtml); + Downloader.RouteAdd("/api/Redo","Current","Cancel current video, redo video (however It may act like /api/Cancel, that is a bug)", (HttpAction)Redo); + + Downloader.RouteAdd("/api/Cancel","Current","Cancel current video, go to next", (HttpAction)Cancel); + + + /* Storage */ + Downloader.RouteAdd("/api/Storage/GetDirectories/{Path}", "Storage","Get list of directories in Path\nAlready used Path.GetFileName(), its json array", (HttpAction)StorageGetDirectories); + Downloader.RouteAdd("/api/Storage/GetFiles/{Path}","Storage","Get list of files in Path\nAlready used Path.GetFileName(), its json array", (HttpAction)StorageGetFiles); + Downloader.RouteAdd("/api/Storage/DirectoryExists/{Path}", "Storage", "returns \"true\" if directory exists or \"false\" if not",(HttpAction)StorageDirectoryExists); + Downloader.RouteAdd("/api/Storage/FileExists/{Path}","Storage","returns \"true\" if file exists or \"false\" if not", (HttpAction)StorageFileExists); + Downloader.RouteAdd("/api/Storage/File/{Path}","Storage","Get file based on working directory", (HttpAction)StorageFile); + Downloader.RouteAdd("/api/Storage/Video/{Id}","Storage","",(HttpAction)Video); + Downloader.RouteAdd("/api/Storage/VideoRes/{Res}/{Id}","Storage","Download Video to Computer from Downloader\nParams:\n{Res}: 0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: Video Id to Download",(HttpAction)VideoRes); + Downloader.RouteAdd("/api/upload/","Storage","Upload file via POST", (HttpAction)UploadFiles, "POST"); + + Downloader.RouteAdd("/api/endpoint","Generic","POST endpoint for many functions\nDocumentation", (HttpAction)Endpoint,"POST"); + Downloader.RouteAdd("/api/endpoints.html","Other","This Page", (HttpAction)Endpoints); + Route.Add("/api/example_tripple_structure.json", (req, resp, args) => + { + List v = new List(); + v.Add(new IDResolutionTypeTriplet() { Id = "xxxxxxxxxxx", Resolution = Resolution.NoConvert, Type = InfoType.Video }); + v.Add(new IDResolutionTypeTriplet() { Id = "PLxxxxxxxxxxxxxxxxx", Resolution = Resolution.NoConvert, Type = InfoType.Playlist }); + v.Add(new IDResolutionTypeTriplet() { Id = "UCxxxxxxxxxxxxxxxxxxxxxx", Resolution = Resolution.NoConvert, Type = InfoType.Channel }); + v.Add(new IDResolutionTypeTriplet() { Id = "SomeUserName", Resolution = Resolution.NoConvert, Type = InfoType.User }); + v.Add(new IDResolutionTypeTriplet() { Id = "xxxxxxxxxxx", Resolution = Resolution.NoConvert, Type = InfoType.ClosedCaptions }); + v.Add(new IDResolutionTypeTriplet() { Id = "https://example.com/path/to/file.txt", Resolution = Resolution.NoConvert, Type = InfoType.FileDownload }); + + resp.AsJson(v); + }); ApiLoader.Init(); + Downloader.RouteAdd("/api{p}","Other","Just a redirect to /api/endpoints.html", (request, response, action) => + { + request.RedirectIt(response, "/api/endpoints.html"); + }); + + + + /* Other */ - Route.Add("/", (HttpAction)Index); - Route.Add("/extensions.html", (HttpAction)Extensions); - Route.Add("/{Path}", (HttpAction)RootPath); - Route.Add("/{Path}",(HttpAction)UploadFilePut,"PUT"); + Downloader.RouteAdd("/","Other","Home page", (HttpAction)Index); + Downloader.RouteAdd("/extensions.html","Other","Extensions URL", (HttpAction)Extensions); + Downloader.RouteAdd("/{Path}","Other","Website Files", (HttpAction)RootPath); + Downloader.RouteAdd("/{Path}","Other","Upload file over put",(HttpAction)UploadFilePut,"PUT"); Console.CancelKeyPress += (sender, e) => { ApiLoader.Dispose();var date = DateTime.Now.ToString("yyyyMMdd_HHmmss");Directory.CreateDirectory(Path.Combine("config","queues-close")); File.WriteAllText(Path.Combine("config", "queues-close", $"{date}.json"), Downloader.GetQueue()); Console.WriteLine("TYTD has Closed"); Environment.Exit(0); }; @@ -301,6 +329,60 @@ namespace TYTD } #endregion #region Playlist + public static void RedownloadPlaylistRes(HttpListenerRequest req,HttpListenerResponse resp,Dictionary args) + { + Resolution res=(Resolution)int.Parse(args["R"]); + var id = args["Id"]; + string jsonFile = Path.Combine("Playlist", $"{id}.json"); + + if (File.Exists(jsonFile)) + { + SavedPlaylist playlist = JsonConvert.DeserializeObject(File.ReadAllText(jsonFile)); + if (playlist.Videos != null && playlist.Videos.Count > 0) + { + foreach (var v in playlist.Videos) + { + Downloader.DownloadVideo(v,res); + } + req.RedirectIt(resp); + } + else + { + AddPlaylistRes(req, resp, args); + } + + } + else + { + AddPlaylistRes(req, resp, args); + } + } + public static void RedownloadPlaylist(HttpListenerRequest req,HttpListenerResponse resp,Dictionary args) + { + var id=args["Id"]; + string jsonFile = Path.Combine("Playlist", $"{id}.json"); + if(File.Exists(jsonFile)) + { + SavedPlaylist playlist = JsonConvert.DeserializeObject(File.ReadAllText(jsonFile)); + if(playlist.Videos != null && playlist.Videos.Count > 0) + { + foreach(var v in playlist.Videos) + { + Downloader.DownloadVideo(v); + } + req.RedirectIt(resp); + } + else + { + AddPlaylist(req, resp, args); + } + + } + else + { + AddPlaylist(req, resp, args); + } + } public static async Task AddPlaylistOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { await Downloader.DownloadPlaylistOnly(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert); @@ -1043,6 +1125,41 @@ namespace TYTD response.WithCode(HttpStatusCode.Created); } } + private static void Endpoints(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) + { + Func get_color = (meth) => + { + switch(meth) + { + case "GET": + return "red"; + case "POST": + return "green"; + case "PUT": + return "blue"; + case "PATCH": + return "purple"; + } + return "orange"; + }; + StringBuilder builder = new StringBuilder(); + builder.Append("TYTD Endpoint Documentation

TYTD Endpoint Documentation

"); + foreach(var g in Downloader.Endpoints) + { + builder.Append($"

{g.Key}


"); + foreach(var j in g.Value) + { + builder.Append($"

{j.Method} {j.Path}"); + builder.Append($"

{j.Description}


"); + } + builder.Append("
"); + + } + builder.Append(""); + + response.AsText(builder.ToString()); + } + private static void Endpoint(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) { @@ -1364,17 +1481,18 @@ namespace TYTD response.WithCORS(); return false; } - public static void RedirectIt(this HttpListenerRequest req,HttpListenerResponse resp) + public static void RedirectIt(this HttpListenerRequest req,HttpListenerResponse resp,string path="/") { if (req.Headers.AllKeys.Contains("ServerRoot")) { - resp.AsRedirect(req.Headers["ServerRoot"]); + resp.AsRedirect(req.Headers["ServerRoot"].TrimEnd('/') + path); } else { - resp.AsRedirect("/"); + resp.AsRedirect(path); } } + public static string GetServerRoot(HttpListenerRequest req) { if(req.Headers.AllKeys.Contains("ServerRoot")) diff --git a/TYTD.Api/Log.cs b/TYTD.Api/Log.cs new file mode 100644 index 0000000..c70e5af --- /dev/null +++ b/TYTD.Api/Log.cs @@ -0,0 +1,10 @@ +using System; +namespace TYTD.Api +{ + public class Log + { + public Log() + { + } + } +} diff --git a/TYTD.Api/Server/Functions/Downloader.cs b/TYTD.Api/Server/Functions/Downloader.cs index 64e9b7b..78e7002 100644 --- a/TYTD.Api/Server/Functions/Downloader.cs +++ b/TYTD.Api/Server/Functions/Downloader.cs @@ -16,11 +16,52 @@ using YoutubeExplode.Playlists; using Dasync.Collections; using System.Threading; +using SimpleHttp; +using System.Text; namespace TYTD.Server.Functions { public class Downloader { + private static string HandleDescription(string desc) + { + StringBuilder builder = new StringBuilder(); + foreach(var ln in desc.Split('\n')) + { + + builder.Append($"    {ln}
"); + } + return builder.ToString(); + } + public static Dictionary> Endpoints = new Dictionary>(); + /// + /// Adds route while adding it to list for documentation + /// + /// Path. + /// Group. + /// Description. (you have to use WebUtility.HtmlEncode()) + /// action to call + /// HTTP Method + public static void RouteAdd(string path, string group, string description, HttpActionAsync act, string method = "GET") + { + + Endpoints.AddToList(group, (WebUtility.HtmlEncode(path), HandleDescription(description), method)); + //_endpoint.((WebUtility.HtmlEncode(path),description)); + Route.Add(path, act, method); + } + /// + /// Adds route while adding it to list for documentation + /// + /// Path. + /// Group. + /// Description. (you have to use WebUtility.HtmlEncode()) + /// action to call + /// HTTP Method + public static void RouteAdd(string path, string group, string description, HttpAction act, string method = "GET") + { + Endpoints.AddToList(group, (WebUtility.HtmlEncode(path), HandleDescription(description), method)); + Route.Add(path, act, method); + } public static List SearchFor(string str) { diff --git a/TYTD.Api/SimpleHttpExtensions.cs b/TYTD.Api/SimpleHttpExtensions.cs new file mode 100644 index 0000000..442f2b8 --- /dev/null +++ b/TYTD.Api/SimpleHttpExtensions.cs @@ -0,0 +1,431 @@ +using System; +using System.Net; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using Hyperlinq; +//Uses nuget packages HyperLinq, SimpleHttp +namespace SimpleHttp +{ + + public delegate void HttpActionQuery(HttpListenerRequest req, HttpListenerResponse resp, Dictionary> args); + public delegate Task HttpActionQueryAsync(HttpListenerRequest req, HttpListenerResponse resp, Dictionary> args); + + public static class RequestExtensionsQuery + { + + public static void AsJson(this HttpListenerResponse resp, object respValue, string mime = "application/json") + { + resp.AsText(JsonConvert.SerializeObject(respValue), mime); + } + public static T ParseRawBodyJson(this HttpListenerRequest req) + { + return JsonConvert.DeserializeObject(req.BodyAsString()); + } + public static object ParseRawBodyJson(this HttpListenerRequest req) + { + return JsonConvert.DeserializeObject(req.BodyAsString()); + } + public static void AddToList(this Dictionary> dict, T key, T2 value) + { + if (dict.ContainsKey(key)) + { + dict[key].Add(value); + } + else + { + List items = new List(); + items.Add(value); + dict.Add(key, items); + } + } + public static Dictionary> GetQueryParams(this string parm) + { + Dictionary> ls = new Dictionary>(); + + string[] args = parm.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var arg in args) + { + //name=value + string[] nvp = arg.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries); + + if (nvp.Length == 2) + { + ls.AddToList(nvp[0], nvp[1]); + } + else if (nvp.Length == 1) + { + ls.AddToList(nvp[0], ""); + } + + } + return ls; + } + + /// + /// Parses body of the request including form and multi-part form data. + /// + /// HTTP request. + /// Key-value pairs populated by the form data by this function. + /// Name-file pair collection. + public static Dictionary ParseBody(this HttpListenerRequest request, Dictionary> args) + { + return request.ParseBody(args, (n, fn, ct) => new MemoryStream()); + } + + /// + /// Parses body of the request including form and multi-part form data. + /// + /// HTTP request. + /// Key-value pairs populated by the form data by this function. + /// + /// Function called if a file is about to be parsed. The stream is attached to a corresponding . + /// By default, is used, but for large files, it is recommended to open directly. + /// + /// Name-file pair collection. + public static Dictionary ParseBody(this HttpListenerRequest request, Dictionary> args, OnFile onFile) + { + if (request == null) + throw new ArgumentNullException(nameof(request)); + + if (args == null) + throw new ArgumentNullException(nameof(args)); + + if (onFile == null) + throw new ArgumentNullException(nameof(onFile)); + + + var files = new Dictionary(); + + if (request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.Ordinal)) + { + ParseForm(request, args); + } + else if (request.ContentType.StartsWith("multipart/form-data", StringComparison.Ordinal)) + { + files = ParseMultipartForm(request, args, onFile); + } + else + throw new NotSupportedException("The body content-type is not supported."); + + return files; + } + static bool ParseForm(HttpListenerRequest request, Dictionary> args) + { + if (request.ContentType != "application/x-www-form-urlencoded") + return false; + + var str = request.BodyAsString(); + if (str == null) + return false; + + foreach (var pair in str.Split('&')) + { + var nameValue = pair.Split('='); + if (nameValue.Length != (1 + 1)) + continue; + + args.AddToList(nameValue[0], WebUtility.UrlDecode(nameValue[1])); + } + + return true; + } + + static string BodyAsString(this HttpListenerRequest request) + { + if (!request.HasEntityBody) + return null; + + string str = null; + using (var reader = new StreamReader(request.InputStream, request.ContentEncoding)) + { + str = reader.ReadToEnd(); + } + + return str; + } + static Dictionary ParseMultipartForm(HttpListenerRequest request, Dictionary> args, OnFile onFile) + { + if (request.ContentType.StartsWith("multipart/form-data") == false) + throw new InvalidDataException("Not 'multipart/form-data'."); + + var boundary = Regex.Match(request.ContentType, "boundary=(.+)").Groups[1].Value; + boundary = "--" + boundary; + + + var files = new Dictionary(); + var inputStream = new BufferedStream(request.InputStream); + + parseUntillBoundaryEnd(inputStream, new MemoryStream(), boundary); + while (true) + { + var (n, v, fn, ct) = parseSection(inputStream, "\r\n" + boundary, onFile); + if (String.IsNullOrEmpty(n)) break; + + v.Position = 0; + if (!String.IsNullOrEmpty(fn)) + files.Add(n, new HttpFileQuery(fn, v, ct)); + else + args.AddToList(n, readAsString(v)); + } + + return files; + } + + private static (string Name, Stream Value, string FileName, string ContentType) parseSection(Stream source, string boundary, OnFile onFile) + { + var (n, fn, ct) = readContentDisposition(source); + source.ReadByte(); source.ReadByte(); //\r\n (empty row) + + var dst = String.IsNullOrEmpty(fn) ? new MemoryStream() : onFile(n, fn, ct); + if (dst == null) + throw new ArgumentException(nameof(onFile), "The on-file callback must return a stream."); + + parseUntillBoundaryEnd(source, dst, boundary); + + return (n, dst, fn, ct); + } + + private static (string Name, string FileName, string ContentType) readContentDisposition(Stream stream) + { + const string UTF_FNAME = "utf-8''"; + + var l = readLine(stream); + if (String.IsNullOrEmpty(l)) + return (null, null, null); + + //(regex matches are taken from NancyFX) and modified + var n = Regex.Match(l, @"name=""?(?[^\""]*)").Groups["n"].Value; + var f = Regex.Match(l, @"filename\*?=""?(?[^\"";]*)").Groups["f"]?.Value; + + string cType = null; + if (!String.IsNullOrEmpty(f)) + { + if (f.StartsWith(UTF_FNAME)) + f = Uri.UnescapeDataString(f.Substring(UTF_FNAME.Length)); + + l = readLine(stream); + cType = Regex.Match(l, "Content-Type: (?.+)").Groups["cType"].Value; + } + + return (n, f, cType); + } + + private static void parseUntillBoundaryEnd(Stream source, Stream destination, string boundary) + { + var checkBuffer = new byte[boundary.Length]; //for boundary checking + + int b, i = 0; + while ((b = source.ReadByte()) != -1) + { + if (i == boundary.Length) //boundary found -> go to the end of line + { + if (b == '\n') break; + continue; + } + + if (b == boundary[i]) //start filling the check buffer + { + checkBuffer[i] = (byte)b; + i++; + } + else + { + var idx = 0; + while (idx < i) //write the buffer data to stream + { + destination.WriteByte(checkBuffer[idx]); + idx++; + } + + i = 0; + destination.WriteByte((byte)b); //write the current byte + } + } + } + + private static string readLine(Stream stream) + { + var sb = new StringBuilder(); + + int b; + while ((b = stream.ReadByte()) != -1 && b != '\n') + sb.Append((char)b); + + if (sb.Length > 0 && sb[sb.Length - 1] == '\r') + sb.Remove(sb.Length - 1, 1); + + return sb.ToString(); + } + + private static string readAsString(Stream stream) + { + var sb = new StringBuilder(); + + int b; + while ((b = stream.ReadByte()) != -1) + sb.Append((char)b); + + return sb.ToString(); + } + } + + /// + /// HTTP file data container. + /// + public class HttpFileQuery : IDisposable + { + /// + /// Creates new HTTP file data container. + /// + /// File name. + /// Data. + /// Content type. + internal HttpFileQuery(string fileName, Stream value, string contentType) + { + Value = value; + FileName = fileName; + ContentType = contentType; + } + + /// + /// Gets the name of the file. + /// + public string FileName { get; private set; } + + /// + /// Gets the data. + /// If a stream is created it will be closed when this HttpFile object is disposed. + /// + public Stream Value { get; private set; } + + /// + /// Content type. + /// + public string ContentType { get; private set; } + + /// + /// Saves the data into a file. + /// Directory path will be auto created if does not exists. + /// + /// File path with name. + /// True to overwrite the existing file, false otherwise. + /// True if the file is saved/overwritten, false otherwise. + public bool Save(string fileName, bool overwrite = false) + { + if (File.Exists(Path.GetFullPath(fileName))) + return false; + + var dir = Path.GetDirectoryName(Path.GetFullPath(fileName)); + Directory.CreateDirectory(dir); + + Value.Position = 0; + using (var outStream = File.OpenWrite(fileName)) + Value.CopyTo(outStream); + + return true; + } + + /// + /// Disposes the current instance. + /// + public void Dispose() + { + if (Value != null) + { + Value?.Dispose(); + Value = null; + } + } + + /// + /// Disposes the current instance. + /// + ~HttpFileQuery() + { + Dispose(); + } + } + public static class RouteQuery + { + + public static void AsHtml(this HttpListenerResponse resp, HElement element) + { + resp.AsText(element.ToString()); + } + + public static void AddQuery(string url, HttpActionQueryAsync httpActionQueryAsync, string method = "GET", string queryText = "query_parms") + { + Route.Add($"{url}{{{queryText}}}", async (req, resp, args) => { + string queryparms = args[queryText]; + + Dictionary> str = new Dictionary>(); + foreach (var arg in args) + { + if (arg.Key != queryText) + { + str.AddToList(arg.Key, arg.Value); + } + } + foreach (var queryParm in queryparms.GetQueryParams()) + { + foreach (var value in queryParm.Value) + { + str.AddToList(queryParm.Key, value); + } + } + await httpActionQueryAsync(req, resp, str); + }); + } + public static void AddQuery(string url, HttpActionQuery httpActionQuery, string method = "GET", string queryText = "query_parms") + { + Route.Add($"{url}{{{queryText}}}", (req, resp, args) => { + string queryparms = args[queryText]; + Dictionary> str = new Dictionary>(); + foreach (var arg in args) + { + if (arg.Key != queryText) + { + str.AddToList(arg.Key, arg.Value); + } + } + foreach (var queryParm in queryparms.GetQueryParams()) + { + foreach (var value in queryParm.Value) + { + str.AddToList(queryParm.Key, value); + } + } + httpActionQuery(req, resp, str); + }); + } + public static void AddQuery(string url, HttpActionAsync httpActionAsync, string method = "GET", string queryText = "query_parms") + { + Route.Add($"{url}{{{queryText}}}", async (req, resp, args) => { + string queryparms = args[queryText]; + foreach (var queryParm in queryparms.GetQueryParams()) + { + args.Add(queryParm.Key, queryParm.Value[0]); + } + await httpActionAsync(req, resp, args); + }); + } + public static void AddQuery(string url, HttpAction action, string method = "GET", string queryText = "query_parms") + { + Route.Add($"{url}{{{queryText}}}", (req, resp, args) => + { + string queryparms = args[queryText]; + foreach (var queryParm in queryparms.GetQueryParams()) + { + args.Add(queryParm.Key, queryParm.Value[0]); + } + action(req, resp, args); + }, method); + Route.Add(url, action, method); + } + } + +} diff --git a/TYTD.Api/TYTD.Api.csproj b/TYTD.Api/TYTD.Api.csproj index ee5b96b..ea31976 100644 --- a/TYTD.Api/TYTD.Api.csproj +++ b/TYTD.Api/TYTD.Api.csproj @@ -105,6 +105,9 @@ ..\packages\Simple-HTTP.1.0.6\lib\net47\SimpleHTTP.dll + + ..\packages\Hyperlinq.1.0.7\lib\net40-client\Hyperlinq.dll + @@ -118,6 +121,7 @@ + diff --git a/TYTD.Api/bin/Release/Hyperlinq.dll b/TYTD.Api/bin/Release/Hyperlinq.dll new file mode 100644 index 0000000..d7f0352 Binary files /dev/null and b/TYTD.Api/bin/Release/Hyperlinq.dll differ diff --git a/TYTD.Api/bin/Release/TYTD.Api.dll b/TYTD.Api/bin/Release/TYTD.Api.dll index c42bd75..a3c5995 100644 Binary files a/TYTD.Api/bin/Release/TYTD.Api.dll and b/TYTD.Api/bin/Release/TYTD.Api.dll differ diff --git a/TYTD.Api/obj/Release/TYTD.Api.csproj.CoreCompileInputs.cache b/TYTD.Api/obj/Release/TYTD.Api.csproj.CoreCompileInputs.cache index b20e070..21d1060 100644 --- a/TYTD.Api/obj/Release/TYTD.Api.csproj.CoreCompileInputs.cache +++ b/TYTD.Api/obj/Release/TYTD.Api.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -6a4cb1f3341b0b875221333595f3f3db569f2e65 +4109925d72e51f8e54758eee44e6f087ed4fc279 diff --git a/TYTD.Api/obj/Release/TYTD.Api.csproj.FileListAbsolute.txt b/TYTD.Api/obj/Release/TYTD.Api.csproj.FileListAbsolute.txt index a5764da..3e6b41f 100644 --- a/TYTD.Api/obj/Release/TYTD.Api.csproj.FileListAbsolute.txt +++ b/TYTD.Api/obj/Release/TYTD.Api.csproj.FileListAbsolute.txt @@ -391,3 +391,4 @@ /home/mike/tytd-server/TYTD.Api/obj/Release/TYTD.Api.csproj.CoreCompileInputs.cache /home/mike/tytd-server/TYTD.Api/obj/Release/TYTD.Api.csproj.CopyComplete /home/mike/tytd-server/TYTD.Api/obj/Release/TYTD.Api.dll +/home/mike/tytd-server/TYTD.Api/bin/Release/Hyperlinq.dll diff --git a/TYTD.Api/obj/Release/TYTD.Api.csprojAssemblyReference.cache b/TYTD.Api/obj/Release/TYTD.Api.csprojAssemblyReference.cache index 63ac678..22fae63 100644 Binary files a/TYTD.Api/obj/Release/TYTD.Api.csprojAssemblyReference.cache and b/TYTD.Api/obj/Release/TYTD.Api.csprojAssemblyReference.cache differ diff --git a/TYTD.Api/obj/Release/TYTD.Api.dll b/TYTD.Api/obj/Release/TYTD.Api.dll index c42bd75..a3c5995 100644 Binary files a/TYTD.Api/obj/Release/TYTD.Api.dll and b/TYTD.Api/obj/Release/TYTD.Api.dll differ diff --git a/TYTD.Api/packages.config b/TYTD.Api/packages.config index efc812f..2e6ac4a 100644 --- a/TYTD.Api/packages.config +++ b/TYTD.Api/packages.config @@ -3,6 +3,7 @@ + diff --git a/bin/Release/Hyperlinq.dll b/bin/Release/Hyperlinq.dll new file mode 100644 index 0000000..d7f0352 Binary files /dev/null and b/bin/Release/Hyperlinq.dll differ diff --git a/bin/Release/TYTD.Api.dll b/bin/Release/TYTD.Api.dll index c42bd75..a3c5995 100644 Binary files a/bin/Release/TYTD.Api.dll and b/bin/Release/TYTD.Api.dll differ diff --git a/bin/Release/config/queues-close/20220228_170605.json b/bin/Release/config/queues-close/20220228_170605.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/bin/Release/config/queues-close/20220228_170605.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/bin/Release/config/queues-close/20220228_170829.json b/bin/Release/config/queues-close/20220228_170829.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/bin/Release/config/queues-close/20220228_170829.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/bin/Release/youtube-downloader.exe b/bin/Release/youtube-downloader.exe index c2eb7fe..05d1b34 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.csproj.CoreCompileInputs.cache b/obj/x86/Release/youtube-downloader.csproj.CoreCompileInputs.cache index a674724..a9c2f37 100644 --- a/obj/x86/Release/youtube-downloader.csproj.CoreCompileInputs.cache +++ b/obj/x86/Release/youtube-downloader.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -3a0ad01444a7c622c3bd15b537d0dc7e888f6685 +8f38b4bfd3e4101cea207f521c4ab951a53995e7 diff --git a/obj/x86/Release/youtube-downloader.csproj.FileListAbsolute.txt b/obj/x86/Release/youtube-downloader.csproj.FileListAbsolute.txt index f13c524..f7a096e 100644 --- a/obj/x86/Release/youtube-downloader.csproj.FileListAbsolute.txt +++ b/obj/x86/Release/youtube-downloader.csproj.FileListAbsolute.txt @@ -706,3 +706,4 @@ /home/mike/tytd-server/obj/x86/Release/youtube-downloader.exe /home/mike/tytd-server/bin/Release/System.Text.Encoding.CodePages.xml /home/mike/tytd-server/bin/Release/PlaylistsNET.dll +/home/mike/tytd-server/bin/Release/Hyperlinq.dll diff --git a/obj/x86/Release/youtube-downloader.csprojAssemblyReference.cache b/obj/x86/Release/youtube-downloader.csprojAssemblyReference.cache index a96666b..0188d6d 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 c2eb7fe..05d1b34 100644 Binary files a/obj/x86/Release/youtube-downloader.exe and b/obj/x86/Release/youtube-downloader.exe differ diff --git a/packages.config b/packages.config index 3cdeb66..fca9106 100644 --- a/packages.config +++ b/packages.config @@ -3,6 +3,7 @@ + diff --git a/packages/YoutubeExplode.6.1.0/.nupkg.metadata b/packages/YoutubeExplode.6.1.0/.nupkg.metadata new file mode 100644 index 0000000..bc60d6e --- /dev/null +++ b/packages/YoutubeExplode.6.1.0/.nupkg.metadata @@ -0,0 +1,5 @@ +{ + "version": 2, + "contentHash": "ZirloBlRv604Cg4ObTRR5mdPnYThe6E1rlkEGUX9O1e4QvoNr8MFhYO/QyCjetByZPICCTT+U/XBJ2Um39CrRQ==", + "source": "https://api.nuget.org/v3/index.json" +} \ No newline at end of file diff --git a/packages/YoutubeExplode.6.1.0/.signature.p7s b/packages/YoutubeExplode.6.1.0/.signature.p7s new file mode 100755 index 0000000..2e7621a Binary files /dev/null and b/packages/YoutubeExplode.6.1.0/.signature.p7s differ diff --git a/packages/YoutubeExplode.6.1.0/ReadMe.md b/packages/YoutubeExplode.6.1.0/ReadMe.md new file mode 100755 index 0000000..060ad30 --- /dev/null +++ b/packages/YoutubeExplode.6.1.0/ReadMe.md @@ -0,0 +1,405 @@ +# YoutubeExplode + +[![Build](https://github.com/Tyrrrz/YoutubeExplode/workflows/main/badge.svg?branch=master)](https://github.com/Tyrrrz/YoutubeExplode/actions) +[![Coverage](https://codecov.io/gh/Tyrrrz/YoutubeExplode/branch/master/graph/badge.svg)](https://codecov.io/gh/Tyrrrz/YoutubeExplode) +[![Version](https://img.shields.io/nuget/v/YoutubeExplode.svg)](https://nuget.org/packages/YoutubeExplode) +[![Downloads](https://img.shields.io/nuget/dt/YoutubeExplode.svg)](https://nuget.org/packages/YoutubeExplode) +[![Discord](https://img.shields.io/discord/869237470565392384?label=discord)](https://discord.gg/2SUWKFnHSm) +[![Donate](https://img.shields.io/badge/donate-$$$-purple.svg)](https://tyrrrz.me/donate) + +⚠️ **Project status: maintenance mode**. [What does it mean?](https://github.com/Tyrrrz/.github/blob/master/docs/project-status.md) + +**YoutubeExplode** is a library that provides an interface to query metadata of YouTube videos, playlists and channels, as well as to resolve and download video streams and closed caption tracks. +Behind a layer of abstraction, the library parses raw page content and uses reverse-engineered requests to retrieve information. +As it doesn't rely on the official API, there's also no need for an API key and there are no usage quotas. + +✨ This library is used in [**YoutubeDownloader**](https://github.com/Tyrrrz/YoutubeDownloader) -- a desktop application for downloading YouTube videos. + +💬 **If you want to chat, join my [Discord server](https://discord.gg/2SUWKFnHSm)**. + +## Download + +- 📦 [NuGet](https://nuget.org/packages/YoutubeExplode): `dotnet add package YoutubeExplode` (**main package**) +- 📦 [NuGet](https://nuget.org/packages/YoutubeExplode.Converter): `dotnet add package YoutubeExplode.Converter` (**FFmpeg integration**) + +## Screenshots + +![demo](.screenshots/demo.png) + +## Usage + +**YoutubeExplode** exposes its functionality through a single entry point -- the `YoutubeClient` class. +Create an instance of this class and use the provided operations on `Videos`, `Playlists`, `Channels`, and `Search` properties to send requests. + +### Videos + +#### Retrieving video metadata + +To retrieve metadata associated with a YouTube video, call `Videos.GetAsync(...)`: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +// You can specify both video ID or URL +var video = await youtube.Videos.GetAsync("https://youtube.com/watch?v=u_yIGGhubZs"); + +var title = video.Title; // "Collections - Blender 2.80 Fundamentals" +var author = video.Author.Title; // "Blender" +var duration = video.Duration; // 00:07:20 +``` + +#### Downloading video streams + +Every YouTube video has a number of streams available, differing in containers, video quality, bitrate, framerate, and other properties. +Additionally, depending on the content of the stream, the streams are further divided into 3 categories: + +- Muxed streams -- contain both video and audio +- Audio-only streams -- contain only audio +- Video-only streams -- contain only video + +You can request the manifest that lists all available streams for a particular video by calling `Videos.Streams.GetManifestAsync(...)`: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +var streamManifest = await youtube.Videos.Streams.GetManifestAsync("u_yIGGhubZs"); +``` + +Once you get the manifest, you can filter through the streams and select the ones you're interested in: + +```csharp +using YoutubeExplode; +using YoutubeExplode.Videos.Streams; + +// ... + +// Get highest quality muxed stream +var streamInfo = streamManifest.GetMuxedStreams().GetWithHighestVideoQuality(); + +// ...or highest bitrate audio-only stream +var streamInfo = streamManifest.GetAudioOnlyStreams().GetWithHighestBitrate(); + +// ...or highest quality MP4 video-only stream +var streamInfo = streamManifest + .GetVideoOnlyStreams() + .Where(s => s.Container == Container.Mp4) + .GetWithHighestVideoQuality() +``` + +Finally, you can resolve the actual stream represented by the specified metadata using `Videos.Streams.GetAsync(...)` or download it directly to a file with `Videos.Streams.DownloadAsync(...)`: + +```csharp +// ... + +// Get the actual stream +var stream = await youtube.Videos.Streams.GetAsync(streamInfo); + +// Download the stream to a file +await youtube.Videos.Streams.DownloadAsync(streamInfo, $"video.{streamInfo.Container}"); +``` + +> ⚠ Muxed streams contain both audio and video, but these streams are very limited in quality (up to 720p30). +To download video in the highest available quality, you need to resolve the best audio-only and video-only streams separately and then mux them together. +This can be accomplished by using the **YoutubeExplode.Converter** package (see below). + +#### Downloading video with muxing or conversion + +> ⚠ Downloading with muxing or conversion requires [YoutubeExplode.Converter](https://nuget.org/packages/YoutubeExplode.Converter). + +> ⚠ This package also relies on [FFmpeg](https://ffmpeg.org) CLI, which can be downloaded [here](https://ffbinaries.com/downloads). +Ensure that the FFmpeg binary is located in your application's probe directory or on the system's `PATH`, or use one of the overloads to provide a custom location directly. + +You can download a video with muxing or conversion through one of the extension methods provided on `VideoClient`. +For example, to download a video in the specified format using highest quality streams, simply call `DownloadAsync(...)` with the video ID and the destination file path: + +```csharp +using YoutubeExplode; +using YoutubeExplode.Converter; + +var youtube = new YoutubeClient(); +await youtube.Videos.DownloadAsync("https://youtube.com/watch?v=u_yIGGhubZs", "video.mp4"); +``` + +Under the hood, this resolves the video's media streams and selects the best candidates based on format, bitrate, quality, and framerate. +If the specified output format is a known audio-only container (e.g. `mp3` or `ogg`) then only the audio stream is downloaded. + +> ⚠ Stream muxing is a CPU-heavy process. +> You can reduce resource usage and execution time by using streams that don't require transcoding to the output format (e.g. `mp4` audio/video streams for `mp4` output format). +> Currently, YouTube only provides adaptive streams in `mp4` or `webm` containers, with highest quality video streams (e.g. 4K) only available in `webm`. + +To configure various aspects related to the conversion process, use one of the overloads of `DownloadAsync(...)`: + +```csharp +using YoutubeExplode; +using YoutubeExplode.Converter; + +var youtube = new YoutubeClient(); + +await youtube.Videos.DownloadAsync("https://youtube.com/watch?v=u_yIGGhubZs", "video.mp4", o => o + .SetFormat("webm") // override format + .SetPreset(ConversionPreset.UltraFast) // change preset + .SetFFmpegPath("path/to/ffmpeg") // custom FFmpeg location +); +``` + +If you need precise control over which streams are used for muxing, you can also provide them yourself: + +```csharp +using YoutubeExplode; +using YoutubeExplode.Videos.Streams; +using YoutubeExplode.Converter; + +var youtube = new YoutubeClient(); + +// Get stream manifest +var streamManifest = await youtube.Videos.Streams.GetManifestAsync("u_yIGGhubZs"); + +// Select streams (1080p60 / highest bitrate audio) +var audioStreamInfo = streamManifest.GetAudioStreams().GetWithHighestBitrate(); +var videoStreamInfo = streamManifest.GetVideoStreams().First(s => s.VideoQuality.Label == "1080p60"); +var streamInfos = new IStreamInfo[] { audioStreamInfo, videoStreamInfo }; + +// Download and process them into one file +await youtube.Videos.DownloadAsync(streamInfos, new ConversionRequestBuilder("video.mp4").Build()); +``` + +#### Downloading closed captions + +Closed captions can be downloaded in a similar way to media streams. +To get the list of available closed caption tracks, call `Videos.ClosedCaptions.GetManifestAsync(...)`: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +var trackManifest = await youtube.Videos.ClosedCaptions.GetManifestAsync("u_yIGGhubZs"); +``` + +Then retrieve metadata for a particular track: + +```csharp +// ... + +// Find closed caption track in English +var trackInfo = trackManifest.GetByLanguage("en"); +``` + +Finally, use `Videos.ClosedCaptions.GetAsync(...)` to get the actual content of the track: + +```csharp +// ... + +var track = await youtube.Videos.ClosedCaptions.GetAsync(trackInfo); + +// Get the caption displayed at 0:35 +var caption = track.GetByTime(TimeSpan.FromSeconds(35)); +var text = caption.Text; // "collection acts as the parent collection" +``` + +You can also download the closed caption track in SRT file format with `Videos.ClosedCaptions.DownloadAsync(...)`: + +```csharp +// ... + +await youtube.Videos.ClosedCaptions.DownloadAsync(trackInfo, "cc_track.srt"); +``` + +### Playlists + +#### Retrieving playlist metadata + +You can get metadata associated with a YouTube playlist by calling `Playlists.GetAsync(...)` method: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +var playlist = await youtube.Playlists.GetAsync("PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6"); + +var title = playlist.Title; // "First Steps - Blender 2.80 Fundamentals" +var author = playlist.Author.Title; // "Blender" +``` + +#### Getting videos included in a playlist + +To get the videos included in a playlist, call `Playlists.GetVideosAsync(...)`: + +```csharp +using YoutubeExplode; +using YoutubeExplode.Common; + +var youtube = new YoutubeClient(); + +// Get all playlist videos +var videos = await youtube.Playlists.GetVideosAsync("PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6"); + +// Get only the first 20 playlist videos +var videosSubset = await youtube.Playlists + .GetVideosAsync(playlist.Id) + .CollectAsync(20); +``` + +You can also enumerate videos lazily without waiting for the whole list to load: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +await foreach (var video in youtube.Playlists.GetVideosAsync("PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6")) +{ + var title = video.Title; + var author = video.Author; +} +``` + +If you need precise control over how many requests you send to YouTube, use `Playlists.GetVideoBatchesAsync(...)` which returns videos wrapped in batches: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +// Each batch corresponds to one request +await foreach (var batch in youtube.Playlists.GetVideoBatchesAsync("PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6")) +{ + foreach (var video in batch.Items) + { + var title = video.Title; + var author = video.Author; + } +} +``` + +### Channels + +#### Retrieving channel metadata + +You can get metadata associated with a YouTube channel by calling `Channels.GetAsync(...)` method: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +var channel = await youtube.Channels.GetAsync("UCSMOQeBJ2RAnuFungnQOxLg"); + +var title = channel.Title; // "Blender" +``` + +You can also get channel metadata by username with `Channels.GetByUserAsync(...)`: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +var channel = await youtube.Channels.GetByUserAsync("Blender"); + +var id = channel.Id; // "UCSMOQeBJ2RAnuFungnQOxLg" +``` + +#### Getting channel uploads + +To get a list of videos uploaded by a channel, call `Channels.GetUploadsAsync(...)`: + +```csharp +using YoutubeExplode; +using YoutubeExplode.Common; + +var youtube = new YoutubeClient(); + +var videos = await youtube.Channels.GetUploadsAsync("UCSMOQeBJ2RAnuFungnQOxLg"); +``` + +### Searching + +You can execute a search query and get its results by calling `Search.GetResultsAsync(...)`. +Each result may represent either a video, a playlist, or a channel, so you need to apply pattern matching to handle the corresponding cases: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +await foreach (var result in youtube.Search.GetResultsAsync("blender tutorials")) +{ + // Use pattern matching to handle different results (videos, playlists, channels) + switch (result) + { + case VideoSearchResult video: + { + var id = video.Id; + var title = video.Title; + var duration = video.Duration; + break; + } + case PlaylistSearchResult playlist: + { + var id = playlist.Id; + var title = playlist.Title; + break; + } + case ChannelSearchResult channel: + { + var id = channel.Id; + var title = channel.Title; + break; + } + } +} +``` + +To limit results to a specific type, use `Search.GetVideosAsync(...)`, `Search.GetPlaylistsAsync(...)`, or `Search.GetChannelsAsync(...)`: + +```csharp +using YoutubeExplode; +using YoutubeExplode.Common; + +var youtube = new YoutubeClient(); + +var videos = await youtube.Search.GetVideosAsync("blender tutorials"); +var playlists = await youtube.Search.GetPlaylistsAsync("blender tutorials"); +var channels = await youtube.Search.GetChannelsAsync("blender tutorials"); +``` + +Similarly to playlists, you can also enumerate results in batches by calling `Search.GetResultBatchesAsync(...)`: + +```csharp +using YoutubeExplode; + +var youtube = new YoutubeClient(); + +// Each batch corresponds to one request +await foreach (var batch in youtube.Search.GetResultBatchesAsync("blender tutorials")) +{ + foreach (var result in batch.Items) + { + switch (result) + { + case VideoSearchResult videoResult: + { + // ... + } + case PlaylistSearchResult playlistResult: + { + // ... + } + case ChannelSearchResult channelResult: + { + // ... + } + } + } +} +``` + +## Etymology + +The "Explode" in **YoutubeExplode** comes from the name of a PHP function that splits up strings, [`explode()`](https://www.php.net/manual/en/function.explode.php). When I was just starting development on this library, most of the reference source code I read was written in PHP, hence the inspiration for the name. diff --git a/packages/YoutubeExplode.6.1.0/YoutubeExplode.6.1.0.nupkg b/packages/YoutubeExplode.6.1.0/YoutubeExplode.6.1.0.nupkg new file mode 100755 index 0000000..664434a Binary files /dev/null and b/packages/YoutubeExplode.6.1.0/YoutubeExplode.6.1.0.nupkg differ diff --git a/packages/YoutubeExplode.6.1.0/favicon.png b/packages/YoutubeExplode.6.1.0/favicon.png new file mode 100755 index 0000000..6804b68 Binary files /dev/null and b/packages/YoutubeExplode.6.1.0/favicon.png differ diff --git a/packages/YoutubeExplode.6.1.0/lib/net461/YoutubeExplode.dll b/packages/YoutubeExplode.6.1.0/lib/net461/YoutubeExplode.dll new file mode 100755 index 0000000..7524d03 Binary files /dev/null and b/packages/YoutubeExplode.6.1.0/lib/net461/YoutubeExplode.dll differ diff --git a/packages/YoutubeExplode.6.1.0/lib/net461/YoutubeExplode.xml b/packages/YoutubeExplode.6.1.0/lib/net461/YoutubeExplode.xml new file mode 100755 index 0000000..b8e4c3b --- /dev/null +++ b/packages/YoutubeExplode.6.1.0/lib/net461/YoutubeExplode.xml @@ -0,0 +1,1762 @@ + + + + YoutubeExplode + + + + + Metadata associated with a YouTube channel. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube channels. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified channel. + + + + + Gets the metadata associated with the channel of the specified user. + + + + + Enumerates videos uploaded by the specified channel. + + + + + Represents a syntactically valid YouTube channel ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube channel ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube channel ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Properties shared by channel metadata resolved from different sources. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Channel thumbnails. + + + + + Represents a syntactically valid YouTube user name. + + + + + Raw user name value. + + + + + + + + Attempts to parse the specified string as a YouTube user name or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube user name. + + + + + Converts string to user name. + + + + + Converts user name to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Reference to a channel that owns a specific YouTube video or playlist. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Initializes an instance of . + + + + + + + + Generic collection of items returned by a single request. + + + + + Items included in the batch. + + + + + Initializes an instance of . + + + + + Represents an item that can be included in . + This interface is used as a marker to enable extension methods. + + + + + Extensions for . + + + + + Enumerates all items in the sequence and buffers them in memory. + + + + + Enumerates a subset of items in the sequence and buffers them in memory. + + + + + + + + Resolution of an image or a video. + + + + + Canvas width (in pixels). + + + + + Canvas height (in pixels). + + + + + Canvas area (width multiplied by height). + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Thumbnail image. + + + + + Thumbnail URL. + + + + + Thumbnail resolution. + + + + + Initializes an instance of . + + + + + + + + Extensions for . + + + + + Gets the thumbnail with the highest resolution (by area). + Returns null if the sequence is empty. + + + + + Gets the thumbnail with the highest resolution (by area). + + + + + Exception thrown when the requested playlist is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when YouTube denies a request because the client has exceeded rate limit. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video requires purchase. + + + + + ID of a free preview video which is used as promotion for the original video. + + + + + Initializes an instance of + + + + + Exception thrown when the requested video is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video is unplayable. + + + + + Initializes an instance of . + + + + + Exception thrown within . + + + + + Initializes an instance of . + + + + + + Properties shared by playlist metadata resolved from different sources. + + + + + Playlist ID. + + + + + Playlist URL. + + + + + Playlist title. + + + + + Playlist author. + + + May be null in case of auto-generated playlists (e.g. mixes, topics, etc). + + + + + Playlist thumbnails. + + + + + Metadata associated with a YouTube playlist. + + + + + + + + + + + + + + + + + Playlist description. + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube playlists. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified playlist. + + + + + Enumerates batches of videos included in the specified playlist. + + + + + Enumerates videos included in the specified playlist. + + + + + Represents a syntactically valid YouTube playlist ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube playlist ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube playlist ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Metadata associated with a YouTube video included in a playlist. + + + + + ID of the playlist that contains this video. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + Metadata associated with a YouTube channel returned by a search query. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + +

+ Abstract result returned by a search query. + Use pattern matching to handle specific instances of this type. +

+

+ Can be either one of the following: + + + + + +

+
+
+ + + Result URL. + + + + + Result title. + + + + + Metadata associated with a YouTube playlist returned by a search query. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates search results returned by the specified query. + + + + + Enumerates video search results returned by the specified query. + + + + + Enumerates playlist search results returned by the specified query. + + + + + Enumerates channel search results returned by the specified query. + + + + + Filter applied to a YouTube search query. + + + + + No filter applied. + + + + + Only search for videos. + + + + + Only search for playlists. + + + + + Only search for channels. + + + + + Metadata associated with a YouTube video returned by a search query. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Individual closed caption contained within a track. + + + + + Text displayed by the caption. + + + + + Time at which the caption starts being displayed. + + + + + Duration of time for which the caption is displayed. + + + + + Caption parts (usually representing individual words). + + + May be empty because not all captions have parts. + + + + + Initializes an instance of . + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + Returns null if not found. + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + + + + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available closed caption tracks on the specified video. + + + + + Gets the closed caption track identified by the specified metadata. + + + + + Writes the closed caption track identified by the specified metadata to the specified writer. + + + Closed captions are written in the SRT file format. + + + + + Downloads the closed caption track identified by the specified metadata to the specified file. + + + Closed captions are written in the SRT file format. + + + + + Contains information about available closed caption tracks on a YouTube video. + + + + + Available closed caption tracks. + + + + + Initializes an instance of . + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + Returns null if not found. + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + + + + + Individual closed caption part contained within a track. + + + + + Text displayed by the caption part. + + + + + Time at which the caption part starts being displayed (relative to the caption's own offset). + + + + + Initializes an instance of . + + + + + + + + Contains closed captions in a specific language. + + + + + Closed captions included in the track. + + + + + Initializes an instance of . + + + + + Gets the caption displayed at the specified point in time. + Returns null if not found. + + + + + Gets the caption displayed at the specified point in time. + + + + + Metadata associated with a closed caption track of a YouTube video. + + + + + Track URL. + + + + + Track language. + + + + + Whether the track was automatically generated. + + + + + Initializes an instance of . + + + + + + + + Language information. + + + + + ISO 639-1 code of the language. + + + + + Full international name of the language. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Engagement statistics. + + + + + View count. + + + + + Like count. + + + + + Dislike count. + + + + + Average rating. + + + + + Initializes an instance of . + + + + + + + + Properties shared by video metadata resolved from different sources. + + + + + Video ID. + + + + + Video URL. + + + + + Video title. + + + + + Video author. + + + + + Video duration. + + + May be null if the video is a currently ongoing live stream. + + + + + Video thumbnails. + + + + + Metadata associated with an audio-only YouTube media stream. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Bitrate. + + + + + Bitrate in bits per second. + + + + + Bitrate in kilobits per second. + + + + + Bitrate in megabits per second. + + + + + Bitrate in gigabits per second + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Stream container. + + + + + Container name (e.g. mp4, webm, etc). + Can be used as file extension. + + + + + Whether this container is a known audio-only container. + + + This property only refers to the container's capabilities and not its actual contents. + If the container IS audio-only, it DOES NOT contain any video streams. + If the container IS NOT audio-only, it MAY contain video streams, but is not required to. + + + + + Initializes an instance of . + + + + + + + + MPEG-2 Audio Layer III (mp3). + + + + + MPEG-4 Part 14 (mp4). + + + + + Web Media (webm). + + + + + 3rd Generation Partnership Project (3gpp). + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + File size. + + + + + Size in bytes. + + + + + Size in kilobytes. + + + + + Size in megabytes. + + + + + Size in gigabytes. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a media stream that contains audio. + + + + + Audio codec. + + + + + Metadata associated with a media stream of a YouTube video. + + + + + Stream URL. + + + + + Stream container. + + + + + Stream size. + + + + + Stream bitrate. + + + + + Extensions for . + + + + + Gets the stream with the highest bitrate. + Returns null if the sequence is empty. + + + + + Gets the stream with the highest bitrate. + + + + + Metadata associated with a media stream that contains video. + + + + + Video codec. + + + + + Video quality. + + + + + Video resolution. + + + + + Extensions for . + + + + + Gets the video stream with the highest video quality (including framerate). + Returns null if the sequence is empty. + + + + + Gets the video stream with the highest video quality (including framerate). + + + + + Metadata associated with a muxed (audio + video combined) media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to media streams of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available streams on the specified video. + + + + + Gets the HTTP Live Stream (HLS) manifest URL for the specified video (if it is a livestream). + + + + + Gets the stream identified by the specified metadata. + + + + + Copies the stream identified by the specified metadata to the specified stream. + + + + + Downloads the stream identified by the specified metadata to the specified file. + + + + + Contains information about available media streams on a YouTube video. + + + + + Available streams. + + + + + Initializes an instance of . + + + + + Gets streams that contain audio (i.e. muxed and audio-only streams). + + + + + Gets streams that contain video (i.e. muxed and video-only streams). + + + + + Gets muxed streams (i.e. streams containing both audio and video). + + + + + Gets audio-only streams. + + + + + Gets video-only streams. + + + + + Metadata associated with a video-only media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Video stream quality. + + + + + Quality label as seen on YouTube (e.g. 1080p, 720p60, etc). + + + + + Maximum established height of the video stream. + Actual height can vary. + + + + + Video stream framerate (in frames per second). + + + + + Whether this is a high definition video quality (i.e. 1080p or above). + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a YouTube video. + + + + + + + + + + + + + + + + + Video upload date. + + + + + Video description. + + + + + + + + + + + Available search keywords for the video. + + + + + Engagement statistics for the video. + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube videos. + + + + + Operations related to media streams of YouTube videos. + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified video. + + + + + Represents a syntactically valid YouTube video ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a video ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube video ID or URL. + Throws an exception in case of failure. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Client for interacting with YouTube. + + + + + Operations related to YouTube videos. + + + + + Operations related to YouTube playlists. + + + + + Operations related to YouTube channels. + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + +
+
diff --git a/packages/YoutubeExplode.6.1.0/lib/net5.0/YoutubeExplode.dll b/packages/YoutubeExplode.6.1.0/lib/net5.0/YoutubeExplode.dll new file mode 100755 index 0000000..d958413 Binary files /dev/null and b/packages/YoutubeExplode.6.1.0/lib/net5.0/YoutubeExplode.dll differ diff --git a/packages/YoutubeExplode.6.1.0/lib/net5.0/YoutubeExplode.xml b/packages/YoutubeExplode.6.1.0/lib/net5.0/YoutubeExplode.xml new file mode 100755 index 0000000..b8e4c3b --- /dev/null +++ b/packages/YoutubeExplode.6.1.0/lib/net5.0/YoutubeExplode.xml @@ -0,0 +1,1762 @@ + + + + YoutubeExplode + + + + + Metadata associated with a YouTube channel. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube channels. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified channel. + + + + + Gets the metadata associated with the channel of the specified user. + + + + + Enumerates videos uploaded by the specified channel. + + + + + Represents a syntactically valid YouTube channel ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube channel ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube channel ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Properties shared by channel metadata resolved from different sources. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Channel thumbnails. + + + + + Represents a syntactically valid YouTube user name. + + + + + Raw user name value. + + + + + + + + Attempts to parse the specified string as a YouTube user name or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube user name. + + + + + Converts string to user name. + + + + + Converts user name to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Reference to a channel that owns a specific YouTube video or playlist. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Initializes an instance of . + + + + + + + + Generic collection of items returned by a single request. + + + + + Items included in the batch. + + + + + Initializes an instance of . + + + + + Represents an item that can be included in . + This interface is used as a marker to enable extension methods. + + + + + Extensions for . + + + + + Enumerates all items in the sequence and buffers them in memory. + + + + + Enumerates a subset of items in the sequence and buffers them in memory. + + + + + + + + Resolution of an image or a video. + + + + + Canvas width (in pixels). + + + + + Canvas height (in pixels). + + + + + Canvas area (width multiplied by height). + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Thumbnail image. + + + + + Thumbnail URL. + + + + + Thumbnail resolution. + + + + + Initializes an instance of . + + + + + + + + Extensions for . + + + + + Gets the thumbnail with the highest resolution (by area). + Returns null if the sequence is empty. + + + + + Gets the thumbnail with the highest resolution (by area). + + + + + Exception thrown when the requested playlist is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when YouTube denies a request because the client has exceeded rate limit. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video requires purchase. + + + + + ID of a free preview video which is used as promotion for the original video. + + + + + Initializes an instance of + + + + + Exception thrown when the requested video is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video is unplayable. + + + + + Initializes an instance of . + + + + + Exception thrown within . + + + + + Initializes an instance of . + + + + + + Properties shared by playlist metadata resolved from different sources. + + + + + Playlist ID. + + + + + Playlist URL. + + + + + Playlist title. + + + + + Playlist author. + + + May be null in case of auto-generated playlists (e.g. mixes, topics, etc). + + + + + Playlist thumbnails. + + + + + Metadata associated with a YouTube playlist. + + + + + + + + + + + + + + + + + Playlist description. + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube playlists. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified playlist. + + + + + Enumerates batches of videos included in the specified playlist. + + + + + Enumerates videos included in the specified playlist. + + + + + Represents a syntactically valid YouTube playlist ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube playlist ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube playlist ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Metadata associated with a YouTube video included in a playlist. + + + + + ID of the playlist that contains this video. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + Metadata associated with a YouTube channel returned by a search query. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + +

+ Abstract result returned by a search query. + Use pattern matching to handle specific instances of this type. +

+

+ Can be either one of the following: + + + + + +

+
+
+ + + Result URL. + + + + + Result title. + + + + + Metadata associated with a YouTube playlist returned by a search query. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates search results returned by the specified query. + + + + + Enumerates video search results returned by the specified query. + + + + + Enumerates playlist search results returned by the specified query. + + + + + Enumerates channel search results returned by the specified query. + + + + + Filter applied to a YouTube search query. + + + + + No filter applied. + + + + + Only search for videos. + + + + + Only search for playlists. + + + + + Only search for channels. + + + + + Metadata associated with a YouTube video returned by a search query. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Individual closed caption contained within a track. + + + + + Text displayed by the caption. + + + + + Time at which the caption starts being displayed. + + + + + Duration of time for which the caption is displayed. + + + + + Caption parts (usually representing individual words). + + + May be empty because not all captions have parts. + + + + + Initializes an instance of . + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + Returns null if not found. + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + + + + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available closed caption tracks on the specified video. + + + + + Gets the closed caption track identified by the specified metadata. + + + + + Writes the closed caption track identified by the specified metadata to the specified writer. + + + Closed captions are written in the SRT file format. + + + + + Downloads the closed caption track identified by the specified metadata to the specified file. + + + Closed captions are written in the SRT file format. + + + + + Contains information about available closed caption tracks on a YouTube video. + + + + + Available closed caption tracks. + + + + + Initializes an instance of . + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + Returns null if not found. + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + + + + + Individual closed caption part contained within a track. + + + + + Text displayed by the caption part. + + + + + Time at which the caption part starts being displayed (relative to the caption's own offset). + + + + + Initializes an instance of . + + + + + + + + Contains closed captions in a specific language. + + + + + Closed captions included in the track. + + + + + Initializes an instance of . + + + + + Gets the caption displayed at the specified point in time. + Returns null if not found. + + + + + Gets the caption displayed at the specified point in time. + + + + + Metadata associated with a closed caption track of a YouTube video. + + + + + Track URL. + + + + + Track language. + + + + + Whether the track was automatically generated. + + + + + Initializes an instance of . + + + + + + + + Language information. + + + + + ISO 639-1 code of the language. + + + + + Full international name of the language. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Engagement statistics. + + + + + View count. + + + + + Like count. + + + + + Dislike count. + + + + + Average rating. + + + + + Initializes an instance of . + + + + + + + + Properties shared by video metadata resolved from different sources. + + + + + Video ID. + + + + + Video URL. + + + + + Video title. + + + + + Video author. + + + + + Video duration. + + + May be null if the video is a currently ongoing live stream. + + + + + Video thumbnails. + + + + + Metadata associated with an audio-only YouTube media stream. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Bitrate. + + + + + Bitrate in bits per second. + + + + + Bitrate in kilobits per second. + + + + + Bitrate in megabits per second. + + + + + Bitrate in gigabits per second + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Stream container. + + + + + Container name (e.g. mp4, webm, etc). + Can be used as file extension. + + + + + Whether this container is a known audio-only container. + + + This property only refers to the container's capabilities and not its actual contents. + If the container IS audio-only, it DOES NOT contain any video streams. + If the container IS NOT audio-only, it MAY contain video streams, but is not required to. + + + + + Initializes an instance of . + + + + + + + + MPEG-2 Audio Layer III (mp3). + + + + + MPEG-4 Part 14 (mp4). + + + + + Web Media (webm). + + + + + 3rd Generation Partnership Project (3gpp). + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + File size. + + + + + Size in bytes. + + + + + Size in kilobytes. + + + + + Size in megabytes. + + + + + Size in gigabytes. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a media stream that contains audio. + + + + + Audio codec. + + + + + Metadata associated with a media stream of a YouTube video. + + + + + Stream URL. + + + + + Stream container. + + + + + Stream size. + + + + + Stream bitrate. + + + + + Extensions for . + + + + + Gets the stream with the highest bitrate. + Returns null if the sequence is empty. + + + + + Gets the stream with the highest bitrate. + + + + + Metadata associated with a media stream that contains video. + + + + + Video codec. + + + + + Video quality. + + + + + Video resolution. + + + + + Extensions for . + + + + + Gets the video stream with the highest video quality (including framerate). + Returns null if the sequence is empty. + + + + + Gets the video stream with the highest video quality (including framerate). + + + + + Metadata associated with a muxed (audio + video combined) media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to media streams of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available streams on the specified video. + + + + + Gets the HTTP Live Stream (HLS) manifest URL for the specified video (if it is a livestream). + + + + + Gets the stream identified by the specified metadata. + + + + + Copies the stream identified by the specified metadata to the specified stream. + + + + + Downloads the stream identified by the specified metadata to the specified file. + + + + + Contains information about available media streams on a YouTube video. + + + + + Available streams. + + + + + Initializes an instance of . + + + + + Gets streams that contain audio (i.e. muxed and audio-only streams). + + + + + Gets streams that contain video (i.e. muxed and video-only streams). + + + + + Gets muxed streams (i.e. streams containing both audio and video). + + + + + Gets audio-only streams. + + + + + Gets video-only streams. + + + + + Metadata associated with a video-only media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Video stream quality. + + + + + Quality label as seen on YouTube (e.g. 1080p, 720p60, etc). + + + + + Maximum established height of the video stream. + Actual height can vary. + + + + + Video stream framerate (in frames per second). + + + + + Whether this is a high definition video quality (i.e. 1080p or above). + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a YouTube video. + + + + + + + + + + + + + + + + + Video upload date. + + + + + Video description. + + + + + + + + + + + Available search keywords for the video. + + + + + Engagement statistics for the video. + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube videos. + + + + + Operations related to media streams of YouTube videos. + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified video. + + + + + Represents a syntactically valid YouTube video ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a video ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube video ID or URL. + Throws an exception in case of failure. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Client for interacting with YouTube. + + + + + Operations related to YouTube videos. + + + + + Operations related to YouTube playlists. + + + + + Operations related to YouTube channels. + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + +
+
diff --git a/packages/YoutubeExplode.6.1.0/lib/netcoreapp3.0/YoutubeExplode.dll b/packages/YoutubeExplode.6.1.0/lib/netcoreapp3.0/YoutubeExplode.dll new file mode 100755 index 0000000..bf8a1ba Binary files /dev/null and b/packages/YoutubeExplode.6.1.0/lib/netcoreapp3.0/YoutubeExplode.dll differ diff --git a/packages/YoutubeExplode.6.1.0/lib/netcoreapp3.0/YoutubeExplode.xml b/packages/YoutubeExplode.6.1.0/lib/netcoreapp3.0/YoutubeExplode.xml new file mode 100755 index 0000000..b8e4c3b --- /dev/null +++ b/packages/YoutubeExplode.6.1.0/lib/netcoreapp3.0/YoutubeExplode.xml @@ -0,0 +1,1762 @@ + + + + YoutubeExplode + + + + + Metadata associated with a YouTube channel. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube channels. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified channel. + + + + + Gets the metadata associated with the channel of the specified user. + + + + + Enumerates videos uploaded by the specified channel. + + + + + Represents a syntactically valid YouTube channel ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube channel ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube channel ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Properties shared by channel metadata resolved from different sources. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Channel thumbnails. + + + + + Represents a syntactically valid YouTube user name. + + + + + Raw user name value. + + + + + + + + Attempts to parse the specified string as a YouTube user name or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube user name. + + + + + Converts string to user name. + + + + + Converts user name to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Reference to a channel that owns a specific YouTube video or playlist. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Initializes an instance of . + + + + + + + + Generic collection of items returned by a single request. + + + + + Items included in the batch. + + + + + Initializes an instance of . + + + + + Represents an item that can be included in . + This interface is used as a marker to enable extension methods. + + + + + Extensions for . + + + + + Enumerates all items in the sequence and buffers them in memory. + + + + + Enumerates a subset of items in the sequence and buffers them in memory. + + + + + + + + Resolution of an image or a video. + + + + + Canvas width (in pixels). + + + + + Canvas height (in pixels). + + + + + Canvas area (width multiplied by height). + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Thumbnail image. + + + + + Thumbnail URL. + + + + + Thumbnail resolution. + + + + + Initializes an instance of . + + + + + + + + Extensions for . + + + + + Gets the thumbnail with the highest resolution (by area). + Returns null if the sequence is empty. + + + + + Gets the thumbnail with the highest resolution (by area). + + + + + Exception thrown when the requested playlist is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when YouTube denies a request because the client has exceeded rate limit. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video requires purchase. + + + + + ID of a free preview video which is used as promotion for the original video. + + + + + Initializes an instance of + + + + + Exception thrown when the requested video is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video is unplayable. + + + + + Initializes an instance of . + + + + + Exception thrown within . + + + + + Initializes an instance of . + + + + + + Properties shared by playlist metadata resolved from different sources. + + + + + Playlist ID. + + + + + Playlist URL. + + + + + Playlist title. + + + + + Playlist author. + + + May be null in case of auto-generated playlists (e.g. mixes, topics, etc). + + + + + Playlist thumbnails. + + + + + Metadata associated with a YouTube playlist. + + + + + + + + + + + + + + + + + Playlist description. + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube playlists. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified playlist. + + + + + Enumerates batches of videos included in the specified playlist. + + + + + Enumerates videos included in the specified playlist. + + + + + Represents a syntactically valid YouTube playlist ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube playlist ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube playlist ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Metadata associated with a YouTube video included in a playlist. + + + + + ID of the playlist that contains this video. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + Metadata associated with a YouTube channel returned by a search query. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + +

+ Abstract result returned by a search query. + Use pattern matching to handle specific instances of this type. +

+

+ Can be either one of the following: + + + + + +

+
+
+ + + Result URL. + + + + + Result title. + + + + + Metadata associated with a YouTube playlist returned by a search query. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates search results returned by the specified query. + + + + + Enumerates video search results returned by the specified query. + + + + + Enumerates playlist search results returned by the specified query. + + + + + Enumerates channel search results returned by the specified query. + + + + + Filter applied to a YouTube search query. + + + + + No filter applied. + + + + + Only search for videos. + + + + + Only search for playlists. + + + + + Only search for channels. + + + + + Metadata associated with a YouTube video returned by a search query. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Individual closed caption contained within a track. + + + + + Text displayed by the caption. + + + + + Time at which the caption starts being displayed. + + + + + Duration of time for which the caption is displayed. + + + + + Caption parts (usually representing individual words). + + + May be empty because not all captions have parts. + + + + + Initializes an instance of . + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + Returns null if not found. + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + + + + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available closed caption tracks on the specified video. + + + + + Gets the closed caption track identified by the specified metadata. + + + + + Writes the closed caption track identified by the specified metadata to the specified writer. + + + Closed captions are written in the SRT file format. + + + + + Downloads the closed caption track identified by the specified metadata to the specified file. + + + Closed captions are written in the SRT file format. + + + + + Contains information about available closed caption tracks on a YouTube video. + + + + + Available closed caption tracks. + + + + + Initializes an instance of . + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + Returns null if not found. + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + + + + + Individual closed caption part contained within a track. + + + + + Text displayed by the caption part. + + + + + Time at which the caption part starts being displayed (relative to the caption's own offset). + + + + + Initializes an instance of . + + + + + + + + Contains closed captions in a specific language. + + + + + Closed captions included in the track. + + + + + Initializes an instance of . + + + + + Gets the caption displayed at the specified point in time. + Returns null if not found. + + + + + Gets the caption displayed at the specified point in time. + + + + + Metadata associated with a closed caption track of a YouTube video. + + + + + Track URL. + + + + + Track language. + + + + + Whether the track was automatically generated. + + + + + Initializes an instance of . + + + + + + + + Language information. + + + + + ISO 639-1 code of the language. + + + + + Full international name of the language. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Engagement statistics. + + + + + View count. + + + + + Like count. + + + + + Dislike count. + + + + + Average rating. + + + + + Initializes an instance of . + + + + + + + + Properties shared by video metadata resolved from different sources. + + + + + Video ID. + + + + + Video URL. + + + + + Video title. + + + + + Video author. + + + + + Video duration. + + + May be null if the video is a currently ongoing live stream. + + + + + Video thumbnails. + + + + + Metadata associated with an audio-only YouTube media stream. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Bitrate. + + + + + Bitrate in bits per second. + + + + + Bitrate in kilobits per second. + + + + + Bitrate in megabits per second. + + + + + Bitrate in gigabits per second + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Stream container. + + + + + Container name (e.g. mp4, webm, etc). + Can be used as file extension. + + + + + Whether this container is a known audio-only container. + + + This property only refers to the container's capabilities and not its actual contents. + If the container IS audio-only, it DOES NOT contain any video streams. + If the container IS NOT audio-only, it MAY contain video streams, but is not required to. + + + + + Initializes an instance of . + + + + + + + + MPEG-2 Audio Layer III (mp3). + + + + + MPEG-4 Part 14 (mp4). + + + + + Web Media (webm). + + + + + 3rd Generation Partnership Project (3gpp). + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + File size. + + + + + Size in bytes. + + + + + Size in kilobytes. + + + + + Size in megabytes. + + + + + Size in gigabytes. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a media stream that contains audio. + + + + + Audio codec. + + + + + Metadata associated with a media stream of a YouTube video. + + + + + Stream URL. + + + + + Stream container. + + + + + Stream size. + + + + + Stream bitrate. + + + + + Extensions for . + + + + + Gets the stream with the highest bitrate. + Returns null if the sequence is empty. + + + + + Gets the stream with the highest bitrate. + + + + + Metadata associated with a media stream that contains video. + + + + + Video codec. + + + + + Video quality. + + + + + Video resolution. + + + + + Extensions for . + + + + + Gets the video stream with the highest video quality (including framerate). + Returns null if the sequence is empty. + + + + + Gets the video stream with the highest video quality (including framerate). + + + + + Metadata associated with a muxed (audio + video combined) media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to media streams of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available streams on the specified video. + + + + + Gets the HTTP Live Stream (HLS) manifest URL for the specified video (if it is a livestream). + + + + + Gets the stream identified by the specified metadata. + + + + + Copies the stream identified by the specified metadata to the specified stream. + + + + + Downloads the stream identified by the specified metadata to the specified file. + + + + + Contains information about available media streams on a YouTube video. + + + + + Available streams. + + + + + Initializes an instance of . + + + + + Gets streams that contain audio (i.e. muxed and audio-only streams). + + + + + Gets streams that contain video (i.e. muxed and video-only streams). + + + + + Gets muxed streams (i.e. streams containing both audio and video). + + + + + Gets audio-only streams. + + + + + Gets video-only streams. + + + + + Metadata associated with a video-only media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Video stream quality. + + + + + Quality label as seen on YouTube (e.g. 1080p, 720p60, etc). + + + + + Maximum established height of the video stream. + Actual height can vary. + + + + + Video stream framerate (in frames per second). + + + + + Whether this is a high definition video quality (i.e. 1080p or above). + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a YouTube video. + + + + + + + + + + + + + + + + + Video upload date. + + + + + Video description. + + + + + + + + + + + Available search keywords for the video. + + + + + Engagement statistics for the video. + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube videos. + + + + + Operations related to media streams of YouTube videos. + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified video. + + + + + Represents a syntactically valid YouTube video ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a video ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube video ID or URL. + Throws an exception in case of failure. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Client for interacting with YouTube. + + + + + Operations related to YouTube videos. + + + + + Operations related to YouTube playlists. + + + + + Operations related to YouTube channels. + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + +
+
diff --git a/packages/YoutubeExplode.6.1.0/lib/netstandard2.0/YoutubeExplode.dll b/packages/YoutubeExplode.6.1.0/lib/netstandard2.0/YoutubeExplode.dll new file mode 100755 index 0000000..b571c30 Binary files /dev/null and b/packages/YoutubeExplode.6.1.0/lib/netstandard2.0/YoutubeExplode.dll differ diff --git a/packages/YoutubeExplode.6.1.0/lib/netstandard2.0/YoutubeExplode.xml b/packages/YoutubeExplode.6.1.0/lib/netstandard2.0/YoutubeExplode.xml new file mode 100755 index 0000000..b8e4c3b --- /dev/null +++ b/packages/YoutubeExplode.6.1.0/lib/netstandard2.0/YoutubeExplode.xml @@ -0,0 +1,1762 @@ + + + + YoutubeExplode + + + + + Metadata associated with a YouTube channel. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube channels. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified channel. + + + + + Gets the metadata associated with the channel of the specified user. + + + + + Enumerates videos uploaded by the specified channel. + + + + + Represents a syntactically valid YouTube channel ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube channel ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube channel ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Properties shared by channel metadata resolved from different sources. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Channel thumbnails. + + + + + Represents a syntactically valid YouTube user name. + + + + + Raw user name value. + + + + + + + + Attempts to parse the specified string as a YouTube user name or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube user name. + + + + + Converts string to user name. + + + + + Converts user name to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Reference to a channel that owns a specific YouTube video or playlist. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Initializes an instance of . + + + + + + + + Generic collection of items returned by a single request. + + + + + Items included in the batch. + + + + + Initializes an instance of . + + + + + Represents an item that can be included in . + This interface is used as a marker to enable extension methods. + + + + + Extensions for . + + + + + Enumerates all items in the sequence and buffers them in memory. + + + + + Enumerates a subset of items in the sequence and buffers them in memory. + + + + + + + + Resolution of an image or a video. + + + + + Canvas width (in pixels). + + + + + Canvas height (in pixels). + + + + + Canvas area (width multiplied by height). + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Thumbnail image. + + + + + Thumbnail URL. + + + + + Thumbnail resolution. + + + + + Initializes an instance of . + + + + + + + + Extensions for . + + + + + Gets the thumbnail with the highest resolution (by area). + Returns null if the sequence is empty. + + + + + Gets the thumbnail with the highest resolution (by area). + + + + + Exception thrown when the requested playlist is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when YouTube denies a request because the client has exceeded rate limit. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video requires purchase. + + + + + ID of a free preview video which is used as promotion for the original video. + + + + + Initializes an instance of + + + + + Exception thrown when the requested video is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video is unplayable. + + + + + Initializes an instance of . + + + + + Exception thrown within . + + + + + Initializes an instance of . + + + + + + Properties shared by playlist metadata resolved from different sources. + + + + + Playlist ID. + + + + + Playlist URL. + + + + + Playlist title. + + + + + Playlist author. + + + May be null in case of auto-generated playlists (e.g. mixes, topics, etc). + + + + + Playlist thumbnails. + + + + + Metadata associated with a YouTube playlist. + + + + + + + + + + + + + + + + + Playlist description. + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube playlists. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified playlist. + + + + + Enumerates batches of videos included in the specified playlist. + + + + + Enumerates videos included in the specified playlist. + + + + + Represents a syntactically valid YouTube playlist ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube playlist ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube playlist ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Metadata associated with a YouTube video included in a playlist. + + + + + ID of the playlist that contains this video. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + Metadata associated with a YouTube channel returned by a search query. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + +

+ Abstract result returned by a search query. + Use pattern matching to handle specific instances of this type. +

+

+ Can be either one of the following: + + + + + +

+
+
+ + + Result URL. + + + + + Result title. + + + + + Metadata associated with a YouTube playlist returned by a search query. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates search results returned by the specified query. + + + + + Enumerates video search results returned by the specified query. + + + + + Enumerates playlist search results returned by the specified query. + + + + + Enumerates channel search results returned by the specified query. + + + + + Filter applied to a YouTube search query. + + + + + No filter applied. + + + + + Only search for videos. + + + + + Only search for playlists. + + + + + Only search for channels. + + + + + Metadata associated with a YouTube video returned by a search query. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Individual closed caption contained within a track. + + + + + Text displayed by the caption. + + + + + Time at which the caption starts being displayed. + + + + + Duration of time for which the caption is displayed. + + + + + Caption parts (usually representing individual words). + + + May be empty because not all captions have parts. + + + + + Initializes an instance of . + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + Returns null if not found. + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + + + + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available closed caption tracks on the specified video. + + + + + Gets the closed caption track identified by the specified metadata. + + + + + Writes the closed caption track identified by the specified metadata to the specified writer. + + + Closed captions are written in the SRT file format. + + + + + Downloads the closed caption track identified by the specified metadata to the specified file. + + + Closed captions are written in the SRT file format. + + + + + Contains information about available closed caption tracks on a YouTube video. + + + + + Available closed caption tracks. + + + + + Initializes an instance of . + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + Returns null if not found. + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + + + + + Individual closed caption part contained within a track. + + + + + Text displayed by the caption part. + + + + + Time at which the caption part starts being displayed (relative to the caption's own offset). + + + + + Initializes an instance of . + + + + + + + + Contains closed captions in a specific language. + + + + + Closed captions included in the track. + + + + + Initializes an instance of . + + + + + Gets the caption displayed at the specified point in time. + Returns null if not found. + + + + + Gets the caption displayed at the specified point in time. + + + + + Metadata associated with a closed caption track of a YouTube video. + + + + + Track URL. + + + + + Track language. + + + + + Whether the track was automatically generated. + + + + + Initializes an instance of . + + + + + + + + Language information. + + + + + ISO 639-1 code of the language. + + + + + Full international name of the language. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Engagement statistics. + + + + + View count. + + + + + Like count. + + + + + Dislike count. + + + + + Average rating. + + + + + Initializes an instance of . + + + + + + + + Properties shared by video metadata resolved from different sources. + + + + + Video ID. + + + + + Video URL. + + + + + Video title. + + + + + Video author. + + + + + Video duration. + + + May be null if the video is a currently ongoing live stream. + + + + + Video thumbnails. + + + + + Metadata associated with an audio-only YouTube media stream. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Bitrate. + + + + + Bitrate in bits per second. + + + + + Bitrate in kilobits per second. + + + + + Bitrate in megabits per second. + + + + + Bitrate in gigabits per second + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Stream container. + + + + + Container name (e.g. mp4, webm, etc). + Can be used as file extension. + + + + + Whether this container is a known audio-only container. + + + This property only refers to the container's capabilities and not its actual contents. + If the container IS audio-only, it DOES NOT contain any video streams. + If the container IS NOT audio-only, it MAY contain video streams, but is not required to. + + + + + Initializes an instance of . + + + + + + + + MPEG-2 Audio Layer III (mp3). + + + + + MPEG-4 Part 14 (mp4). + + + + + Web Media (webm). + + + + + 3rd Generation Partnership Project (3gpp). + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + File size. + + + + + Size in bytes. + + + + + Size in kilobytes. + + + + + Size in megabytes. + + + + + Size in gigabytes. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a media stream that contains audio. + + + + + Audio codec. + + + + + Metadata associated with a media stream of a YouTube video. + + + + + Stream URL. + + + + + Stream container. + + + + + Stream size. + + + + + Stream bitrate. + + + + + Extensions for . + + + + + Gets the stream with the highest bitrate. + Returns null if the sequence is empty. + + + + + Gets the stream with the highest bitrate. + + + + + Metadata associated with a media stream that contains video. + + + + + Video codec. + + + + + Video quality. + + + + + Video resolution. + + + + + Extensions for . + + + + + Gets the video stream with the highest video quality (including framerate). + Returns null if the sequence is empty. + + + + + Gets the video stream with the highest video quality (including framerate). + + + + + Metadata associated with a muxed (audio + video combined) media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to media streams of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available streams on the specified video. + + + + + Gets the HTTP Live Stream (HLS) manifest URL for the specified video (if it is a livestream). + + + + + Gets the stream identified by the specified metadata. + + + + + Copies the stream identified by the specified metadata to the specified stream. + + + + + Downloads the stream identified by the specified metadata to the specified file. + + + + + Contains information about available media streams on a YouTube video. + + + + + Available streams. + + + + + Initializes an instance of . + + + + + Gets streams that contain audio (i.e. muxed and audio-only streams). + + + + + Gets streams that contain video (i.e. muxed and video-only streams). + + + + + Gets muxed streams (i.e. streams containing both audio and video). + + + + + Gets audio-only streams. + + + + + Gets video-only streams. + + + + + Metadata associated with a video-only media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Video stream quality. + + + + + Quality label as seen on YouTube (e.g. 1080p, 720p60, etc). + + + + + Maximum established height of the video stream. + Actual height can vary. + + + + + Video stream framerate (in frames per second). + + + + + Whether this is a high definition video quality (i.e. 1080p or above). + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a YouTube video. + + + + + + + + + + + + + + + + + Video upload date. + + + + + Video description. + + + + + + + + + + + Available search keywords for the video. + + + + + Engagement statistics for the video. + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube videos. + + + + + Operations related to media streams of YouTube videos. + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified video. + + + + + Represents a syntactically valid YouTube video ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a video ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube video ID or URL. + Throws an exception in case of failure. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Client for interacting with YouTube. + + + + + Operations related to YouTube videos. + + + + + Operations related to YouTube playlists. + + + + + Operations related to YouTube channels. + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + +
+
diff --git a/packages/YoutubeExplode.6.1.0/lib/netstandard2.1/YoutubeExplode.dll b/packages/YoutubeExplode.6.1.0/lib/netstandard2.1/YoutubeExplode.dll new file mode 100755 index 0000000..7cfd5e3 Binary files /dev/null and b/packages/YoutubeExplode.6.1.0/lib/netstandard2.1/YoutubeExplode.dll differ diff --git a/packages/YoutubeExplode.6.1.0/lib/netstandard2.1/YoutubeExplode.xml b/packages/YoutubeExplode.6.1.0/lib/netstandard2.1/YoutubeExplode.xml new file mode 100755 index 0000000..b8e4c3b --- /dev/null +++ b/packages/YoutubeExplode.6.1.0/lib/netstandard2.1/YoutubeExplode.xml @@ -0,0 +1,1762 @@ + + + + YoutubeExplode + + + + + Metadata associated with a YouTube channel. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube channels. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified channel. + + + + + Gets the metadata associated with the channel of the specified user. + + + + + Enumerates videos uploaded by the specified channel. + + + + + Represents a syntactically valid YouTube channel ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube channel ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube channel ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Properties shared by channel metadata resolved from different sources. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Channel thumbnails. + + + + + Represents a syntactically valid YouTube user name. + + + + + Raw user name value. + + + + + + + + Attempts to parse the specified string as a YouTube user name or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube user name. + + + + + Converts string to user name. + + + + + Converts user name to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Reference to a channel that owns a specific YouTube video or playlist. + + + + + Channel ID. + + + + + Channel URL. + + + + + Channel title. + + + + + Initializes an instance of . + + + + + + + + Generic collection of items returned by a single request. + + + + + Items included in the batch. + + + + + Initializes an instance of . + + + + + Represents an item that can be included in . + This interface is used as a marker to enable extension methods. + + + + + Extensions for . + + + + + Enumerates all items in the sequence and buffers them in memory. + + + + + Enumerates a subset of items in the sequence and buffers them in memory. + + + + + + + + Resolution of an image or a video. + + + + + Canvas width (in pixels). + + + + + Canvas height (in pixels). + + + + + Canvas area (width multiplied by height). + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Thumbnail image. + + + + + Thumbnail URL. + + + + + Thumbnail resolution. + + + + + Initializes an instance of . + + + + + + + + Extensions for . + + + + + Gets the thumbnail with the highest resolution (by area). + Returns null if the sequence is empty. + + + + + Gets the thumbnail with the highest resolution (by area). + + + + + Exception thrown when the requested playlist is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when YouTube denies a request because the client has exceeded rate limit. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video requires purchase. + + + + + ID of a free preview video which is used as promotion for the original video. + + + + + Initializes an instance of + + + + + Exception thrown when the requested video is unavailable. + + + + + Initializes an instance of . + + + + + Exception thrown when the requested video is unplayable. + + + + + Initializes an instance of . + + + + + Exception thrown within . + + + + + Initializes an instance of . + + + + + + Properties shared by playlist metadata resolved from different sources. + + + + + Playlist ID. + + + + + Playlist URL. + + + + + Playlist title. + + + + + Playlist author. + + + May be null in case of auto-generated playlists (e.g. mixes, topics, etc). + + + + + Playlist thumbnails. + + + + + Metadata associated with a YouTube playlist. + + + + + + + + + + + + + + + + + Playlist description. + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube playlists. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified playlist. + + + + + Enumerates batches of videos included in the specified playlist. + + + + + Enumerates videos included in the specified playlist. + + + + + Represents a syntactically valid YouTube playlist ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a YouTube playlist ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube playlist ID or URL. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Metadata associated with a YouTube video included in a playlist. + + + + + ID of the playlist that contains this video. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + Metadata associated with a YouTube channel returned by a search query. + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + +

+ Abstract result returned by a search query. + Use pattern matching to handle specific instances of this type. +

+

+ Can be either one of the following: + + + + + +

+
+
+ + + Result URL. + + + + + Result title. + + + + + Metadata associated with a YouTube playlist returned by a search query. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates batches of search results returned by the specified query. + + + + + Enumerates search results returned by the specified query. + + + + + Enumerates video search results returned by the specified query. + + + + + Enumerates playlist search results returned by the specified query. + + + + + Enumerates channel search results returned by the specified query. + + + + + Filter applied to a YouTube search query. + + + + + No filter applied. + + + + + Only search for videos. + + + + + Only search for playlists. + + + + + Only search for channels. + + + + + Metadata associated with a YouTube video returned by a search query. + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Individual closed caption contained within a track. + + + + + Text displayed by the caption. + + + + + Time at which the caption starts being displayed. + + + + + Duration of time for which the caption is displayed. + + + + + Caption parts (usually representing individual words). + + + May be empty because not all captions have parts. + + + + + Initializes an instance of . + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + Returns null if not found. + + + + + Gets the caption part displayed at the specified point in time, relative to the caption's own offset. + + + + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available closed caption tracks on the specified video. + + + + + Gets the closed caption track identified by the specified metadata. + + + + + Writes the closed caption track identified by the specified metadata to the specified writer. + + + Closed captions are written in the SRT file format. + + + + + Downloads the closed caption track identified by the specified metadata to the specified file. + + + Closed captions are written in the SRT file format. + + + + + Contains information about available closed caption tracks on a YouTube video. + + + + + Available closed caption tracks. + + + + + Initializes an instance of . + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + Returns null if not found. + + + + + Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name). + + + + + Individual closed caption part contained within a track. + + + + + Text displayed by the caption part. + + + + + Time at which the caption part starts being displayed (relative to the caption's own offset). + + + + + Initializes an instance of . + + + + + + + + Contains closed captions in a specific language. + + + + + Closed captions included in the track. + + + + + Initializes an instance of . + + + + + Gets the caption displayed at the specified point in time. + Returns null if not found. + + + + + Gets the caption displayed at the specified point in time. + + + + + Metadata associated with a closed caption track of a YouTube video. + + + + + Track URL. + + + + + Track language. + + + + + Whether the track was automatically generated. + + + + + Initializes an instance of . + + + + + + + + Language information. + + + + + ISO 639-1 code of the language. + + + + + Full international name of the language. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Engagement statistics. + + + + + View count. + + + + + Like count. + + + + + Dislike count. + + + + + Average rating. + + + + + Initializes an instance of . + + + + + + + + Properties shared by video metadata resolved from different sources. + + + + + Video ID. + + + + + Video URL. + + + + + Video title. + + + + + Video author. + + + + + Video duration. + + + May be null if the video is a currently ongoing live stream. + + + + + Video thumbnails. + + + + + Metadata associated with an audio-only YouTube media stream. + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Bitrate. + + + + + Bitrate in bits per second. + + + + + Bitrate in kilobits per second. + + + + + Bitrate in megabits per second. + + + + + Bitrate in gigabits per second + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Stream container. + + + + + Container name (e.g. mp4, webm, etc). + Can be used as file extension. + + + + + Whether this container is a known audio-only container. + + + This property only refers to the container's capabilities and not its actual contents. + If the container IS audio-only, it DOES NOT contain any video streams. + If the container IS NOT audio-only, it MAY contain video streams, but is not required to. + + + + + Initializes an instance of . + + + + + + + + MPEG-2 Audio Layer III (mp3). + + + + + MPEG-4 Part 14 (mp4). + + + + + Web Media (webm). + + + + + 3rd Generation Partnership Project (3gpp). + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + File size. + + + + + Size in bytes. + + + + + Size in kilobytes. + + + + + Size in megabytes. + + + + + Size in gigabytes. + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a media stream that contains audio. + + + + + Audio codec. + + + + + Metadata associated with a media stream of a YouTube video. + + + + + Stream URL. + + + + + Stream container. + + + + + Stream size. + + + + + Stream bitrate. + + + + + Extensions for . + + + + + Gets the stream with the highest bitrate. + Returns null if the sequence is empty. + + + + + Gets the stream with the highest bitrate. + + + + + Metadata associated with a media stream that contains video. + + + + + Video codec. + + + + + Video quality. + + + + + Video resolution. + + + + + Extensions for . + + + + + Gets the video stream with the highest video quality (including framerate). + Returns null if the sequence is empty. + + + + + Gets the video stream with the highest video quality (including framerate). + + + + + Metadata associated with a muxed (audio + video combined) media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Operations related to media streams of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the manifest containing information about available streams on the specified video. + + + + + Gets the HTTP Live Stream (HLS) manifest URL for the specified video (if it is a livestream). + + + + + Gets the stream identified by the specified metadata. + + + + + Copies the stream identified by the specified metadata to the specified stream. + + + + + Downloads the stream identified by the specified metadata to the specified file. + + + + + Contains information about available media streams on a YouTube video. + + + + + Available streams. + + + + + Initializes an instance of . + + + + + Gets streams that contain audio (i.e. muxed and audio-only streams). + + + + + Gets streams that contain video (i.e. muxed and video-only streams). + + + + + Gets muxed streams (i.e. streams containing both audio and video). + + + + + Gets audio-only streams. + + + + + Gets video-only streams. + + + + + Metadata associated with a video-only media stream. + + + + + + + + + + + + + + + + + + + + + + + + + + Initializes an instance of . + + + + + + + + Video stream quality. + + + + + Quality label as seen on YouTube (e.g. 1080p, 720p60, etc). + + + + + Maximum established height of the video stream. + Actual height can vary. + + + + + Video stream framerate (in frames per second). + + + + + Whether this is a high definition video quality (i.e. 1080p or above). + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + + + + + + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Comparison. + + + + + Comparison. + + + + + Metadata associated with a YouTube video. + + + + + + + + + + + + + + + + + Video upload date. + + + + + Video description. + + + + + + + + + + + Available search keywords for the video. + + + + + Engagement statistics for the video. + + + + + Initializes an instance of . + + + + + + + + Operations related to YouTube videos. + + + + + Operations related to media streams of YouTube videos. + + + + + Operations related to closed captions of YouTube videos. + + + + + Initializes an instance of . + + + + + Gets the metadata associated with the specified video. + + + + + Represents a syntactically valid YouTube video ID. + + + + + Raw ID value. + + + + + + + + Attempts to parse the specified string as a video ID or URL. + Returns null in case of failure. + + + + + Parses the specified string as a YouTube video ID or URL. + Throws an exception in case of failure. + + + + + Converts string to ID. + + + + + Converts ID to string. + + + + + + + + + + + + + + Equality check. + + + + + Equality check. + + + + + Client for interacting with YouTube. + + + + + Operations related to YouTube videos. + + + + + Operations related to YouTube playlists. + + + + + Operations related to YouTube channels. + + + + + Operations related to YouTube search. + + + + + Initializes an instance of . + + + + + Initializes an instance of . + + +
+
diff --git a/youtube-downloader-api/MyClass.cs b/youtube-downloader-api/MyClass.cs new file mode 100644 index 0000000..8fe2c8f --- /dev/null +++ b/youtube-downloader-api/MyClass.cs @@ -0,0 +1,10 @@ +using System; +namespace youtubedownloaderapi +{ + public class MyClass + { + public MyClass() + { + } + } +} diff --git a/youtube-downloader-api/Properties/AssemblyInfo.cs b/youtube-downloader-api/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..0552800 --- /dev/null +++ b/youtube-downloader-api/Properties/AssemblyInfo.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("youtube-downloader-api")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("${AuthorCopyright}")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] diff --git a/youtube-downloader-api/TYTD.cs b/youtube-downloader-api/TYTD.cs new file mode 100644 index 0000000..9c732f5 --- /dev/null +++ b/youtube-downloader-api/TYTD.cs @@ -0,0 +1,10 @@ +using System; +namespace youtubedownloaderapi +{ + public class TYTD + { + public TYTD() + { + } + } +} diff --git a/youtube-downloader-api/obj/Release/youtube-downloader-api.csprojAssemblyReference.cache b/youtube-downloader-api/obj/Release/youtube-downloader-api.csprojAssemblyReference.cache new file mode 100644 index 0000000..fcb839c Binary files /dev/null and b/youtube-downloader-api/obj/Release/youtube-downloader-api.csprojAssemblyReference.cache differ diff --git a/youtube-downloader-api/youtube-downloader-api.csproj b/youtube-downloader-api/youtube-downloader-api.csproj new file mode 100644 index 0000000..88f8dc6 --- /dev/null +++ b/youtube-downloader-api/youtube-downloader-api.csproj @@ -0,0 +1,38 @@ + + + + Debug + AnyCPU + {53A600E2-E063-4137-BDE0-38348FC1B748} + Library + youtubedownloaderapi + youtube-downloader-api + v4.7 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + true + bin\Release + prompt + 4 + false + + + + + + + + + + + \ No newline at end of file diff --git a/youtube-downloader-api/youtube-downloader-api.csproj.user b/youtube-downloader-api/youtube-downloader-api.csproj.user new file mode 100644 index 0000000..9b53138 --- /dev/null +++ b/youtube-downloader-api/youtube-downloader-api.csproj.user @@ -0,0 +1,7 @@ + + + + Project + true + + \ No newline at end of file diff --git a/youtube-downloader.csproj b/youtube-downloader.csproj index 46d806e..ce18ecf 100644 --- a/youtube-downloader.csproj +++ b/youtube-downloader.csproj @@ -115,6 +115,9 @@ packages\PlaylistsNET.1.1.3\lib\net45\PlaylistsNET.dll + + packages\Hyperlinq.1.0.7\lib\net40-client\Hyperlinq.dll +