using System; using YoutubeExplode.Playlists; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using YoutubeExplode; using System.Text; using System.Net.Http.Headers; using System.Net.Http; using System.IO; using YoutubeExplode.Channels; using System.Net; using System.Text.RegularExpressions; using System.Drawing; using YoutubeExplode.Videos.Streams; using YoutubeExplode.Videos; using AngleSharp.Common; using System.Runtime.InteropServices; namespace DL.Controllers { [Route("Grabber")] [ApiController] public class YoutubeController : ControllerBase { private static bool ChannelIsValid(string id) { if (string.IsNullOrWhiteSpace(id)) return false; // Channel IDs should start with these characters if (!id.StartsWith("UC", StringComparison.Ordinal)) return false; // Channel IDs are always 24 characters if (id.Length != 24) return false; return !Regex.IsMatch(id, @"[^0-9a-zA-Z_\-]"); } public string fixstr(string inputString) { string pattern = " *[\\~#%&*{}/:<>?|\"-]+ *"; string replacement = "_"; Regex regEx = new Regex(pattern); string sanitized = regEx.Replace(inputString, replacement); string asAscii = Encoding.ASCII.GetString( Encoding.Convert( Encoding.UTF8, Encoding.GetEncoding( Encoding.ASCII.EncodingName, new EncoderReplacementFallback("_"), new DecoderExceptionFallback() ), Encoding.UTF8.GetBytes(sanitized) ) ); return asAscii.Replace(';', ' '); } [HttpGet("Video/{id}")] public async Task DownloadAsync(string id) { var YT = new YoutubeClient(); var videoname0 = await YT.Videos.GetAsync(id); var strs = await YT.Videos.Streams.GetManifestAsync(id); var high = strs.GetMuxedStreams().GetWithHighestVideoQuality(); string sanitized = fixstr(videoname0.Title); return File(YT.Videos.Streams.GetAsync(high).Result, $"video/{high.Container.Name}", $"{sanitized}.{high.Container.Name}", true); } [HttpGet("VideoHigh/{id}")] public async Task DownloadOnlyVideoAsync(string id) { var YT = new YoutubeClient(); var videoname0 = await YT.Videos.GetAsync(id); string sanitized = fixstr(videoname0.Title); var strs = await YT.Videos.Streams.GetManifestAsync(id); var high = strs.GetVideoStreams().GetWithHighestVideoQuality(); return File(YT.Videos.Streams.GetAsync(high).Result, $"video/{high.Container.Name}", $"{sanitized}.{high.Container.Name}", true); } [HttpGet("Audio/{id}")] public async Task DownloadAudioAsync(string id) { var YT = new YoutubeClient(); var videoname0 = await YT.Videos.GetAsync(id); string sanitized = fixstr(videoname0.Title); var strs = await YT.Videos.Streams.GetManifestAsync(id); var high = strs.GetAudioOnlyStreams().GetWithHighestBitrate(); return File(YT.Videos.Streams.GetAsync(high).Result, $"audio/{high.Container.Name}", $"{sanitized}.{high.Container.Name}", true); } [HttpGet("Search/{id}")] public async Task SearchAsync(string id) { var YT = new YoutubeClient(); string s = ""; await foreach(var v in YT.Search.GetVideosAsync(id)) { s += $"{v.Id}\n"; } return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "query.txt", true); } [HttpGet("ChannelNew2/{date}/{id}")] public async Task NewUser2VideosAsync(string date,string id) { var YT = new YoutubeClient(); var vids = ChannelIsValid(id) ? id : (await YT.Channels.GetByUserAsync(id)).Id.ToString(); int videos = 0; string s = ""; await foreach(var v in YT.Channels.GetUploadsAsync(vids)) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ', '*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Title.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Title.Replace(" ", "-").Length, 439))} {0} {0} 0 8/20/1992 ENDLINE\n"; videos++; } return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); }/* public async Task NewUser2VideosAsync(string date, string id) { var YT = new YoutubeClient(); var vids = ChannelIsValid(id) ? new ChannelId(id) : (await YT.Channels.GetByUserAsync(id)).Id; var ien = YT.Channels.GetUploadsAsync(vids); var vids2 = await ien.ToListAsync(); int videos = 0; string s = ""; foreach (YoutubeExplode.Playlists.PlaylistVideo v in vids2) { if (v.UploadDate.Date >= new DateTime(int.Parse(date.Split("-")[0]), int.Parse(date.Split("-")[1]), int.Parse(date.Split("-")[2]))) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ','*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Replace(" ", "-").Length, 439))} {v.Engagement.LikeCount} {v.Engagement.DislikeCount} {v.Engagement.ViewCount} {v.UploadDate.ToString("MM/dd/yyyy")} {v.Duration.Hours}:{v.Duration.Minutes}:{v.Duration.Seconds} ENDLINE\n"; videos++; } } return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); return await User2VideosAsync(id); }*/ [HttpGet("Channel2/{id}")] public async Task User2VideosAsync(string id) { var YT = new YoutubeClient(); var vids = ChannelIsValid(id) ? id : (await YT.Channels.GetByUserAsync(id)).Id.ToString(); int videos = 0; string s = ""; await foreach(var v in YT.Channels.GetUploadsAsync(vids)) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ', '*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Title.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Title.Replace(" ", "-").Length, 439))} {0} {0} 0 8/20/1992 ENDLINE\n"; videos++; }; return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); } [HttpGet("User/{id}")] public async Task UserVideosAsync(string id) { var YT = new YoutubeClient(); var vids = await YT.Channels.GetByUserAsync(id); int videos = 0; string s = ""; await foreach(var v in YT.Channels.GetUploadsAsync(vids.Id)) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ', '*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Title.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Title.Replace(" ", "-").Length, 439))} {0} {0} 0 8/20/1992 ENDLINE\n"; videos++; }; return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); } [HttpGet("UserNew/{date}/{id}")] public async Task NewUserVideosAsync(string date,string id) { var YT = new YoutubeClient(); var vids = await YT.Channels.GetByUserAsync(id); int videos = 0; string s = ""; await foreach(var v in YT.Channels.GetUploadsAsync(vids.Id)) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ', '*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Title.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Title.Replace(" ", "-").Length, 439))} {0} {0} 0 8/20/1992 ENDLINE\n"; videos++; }; return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); } /* public async Task NewUserVideosAsync(string date, string id) { var YT = new YoutubeClient(); var vids = await YT.Channels.GetByUserAsync(id); var ien = YT.Channels.GetUploadsAsync(vids.Id); var vids2 = await ien.ToListAsync(); int videos = 0; string s = ""; foreach (var v in vids2) { if (v.UploadDate.Date >= new DateTime(int.Parse(date.Split("-")[0]), int.Parse(date.Split("-")[1]), int.Parse(date.Split("-")[2]))) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ','*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Replace(" ", "-").Length, 439))} {v.Engagement.LikeCount} {v.Engagement.DislikeCount} {v.Engagement.ViewCount} {v.UploadDate.ToString("MM/dd/yyyy")} {v.Duration.Hours}:{v.Duration.Minutes}:{v.Duration.Seconds} ENDLINE\n"; videos++; } } return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); return await UserVideosAsync(id); }*/ [HttpGet("Channel/{id}")] public async Task ChannelVideosAsync(string id) { var YT = new YoutubeClient(); int videos = 0; string s = ""; await foreach(var v in YT.Channels.GetUploadsAsync(id)) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ', '*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Title.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Title.Replace(" ", "-").Length, 439))} {0} {0} 0 8/20/1992 ENDLINE\n"; videos++; }; return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); } [HttpGet("ChannelNew/{date}/{id}")] public async Task NewChannelVideosAsync(string date,string id) { var YT = new YoutubeClient(); int videos = 0; string s = ""; await foreach (YoutubeExplode.Playlists.PlaylistVideo v in YT.Channels.GetUploadsAsync(id)) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ', '*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.ChannelTitle.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Title.Replace(" ", "-").Length, 439))} {0} {0} 0 8/20/1992 ENDLINE\n"; videos++; } return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); } /* public async Task NewChannelVideosAsync(string date, string id) { var YT = new YoutubeClient(); var ien = YT.Channels.GetUploadsAsync(id); var vids2 = await ien.ToListAsync(); int videos = 0; string s = ""; foreach (var v in vids2) { if (v.UploadDate.Date >= new DateTime(int.Parse(date.Split("-")[0]), int.Parse(date.Split("-")[1]), int.Parse(date.Split("-")[2]))) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ','*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Replace(" ", "-").Length, 439))} {v.Engagement.LikeCount} {v.Engagement.DislikeCount} {v.Engagement.ViewCount} {v.UploadDate.ToString("MM/dd/yyyy")} {v.Duration.Hours}:{v.Duration.Minutes}:{v.Duration.Seconds} ENDLINE\n"; videos++; } } return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); return await ChannelVideosAsync(id); }*/ [HttpGet("searchinfo/{id}")] public async Task SearchInfoAsync(string id) { var YT = new YoutubeClient(); int videos = 0; string s = ""; await foreach(var v in YT.Search.GetVideosAsync(id)) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ', '*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Title.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Title.Replace(" ", "-").Length, 439))} {0} {0} 0 8/20/1992 ENDLINE\n"; videos++; }; return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); } [HttpGet("Playlist/{id}")] public async Task PlaylistAsync(string id) { var YT = new YoutubeClient(); string s = ""; await foreach(var v in YT.Search.GetVideosAsync(id)) { s += $"{v.Id}\n"; }; return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "query.txt", true); } [HttpGet("playlistinfo/{id}")] public async Task PlaylistInfoAsync(string id) { var YT = new YoutubeClient(); string s = ""; await foreach(var v in YT.Playlists.GetVideosAsync(id)) { var fileName = v.Title; string sanitized = fixstr(fileName).Replace(' ', '*'); s += $"{v.Id} {sanitized.Substring(0, Math.Min(sanitized.Length, 439))} {v.Author.Title.Replace("*", "_").Replace(" ", "*").Substring(0, Math.Min(v.Author.Title.Replace(" ", "-").Length, 439))} {0} {0} 0 8/20/1992 ENDLINE\n"; }; return File(ASCIIEncoding.Default.GetBytes(s), "text/plain", "info.txt", true); } [HttpGet("Info/{id}")] public async Task InfoAsync(string id) { var YT = new YoutubeClient(); var vids = await YT.Videos.GetAsync(id); return File(ASCIIEncoding.Default.GetBytes($"{vids.Title}\nhttps://i.ytimg.com/vi/{id}/default.jpg\n{vids.Author}"), "text/plain", "info.txt", true); } [HttpGet("jpg/{id}")] public async Task Jpg(string id) { return Redirect($"https://i.ytimg.com/vi/{id}/default.jpg"); } [HttpGet("ConvertString/{id}/{prefix}")] public async Task REDIR(string id, string prefix) { try{ VideoId v=id; string newid = v.ToString(); return Redirect(prefix + newid); }catch(Exception) { return NotFound("nope not avail"); } } [HttpGet("Descript/{id}")] public async Task DescAsync(string id) { var YT = new YoutubeClient(); var vids = await YT.Videos.GetAsync(id); return File(ASCIIEncoding.Default.GetBytes(vids.Description), "text/plain", "desc.txt"); } } }