using System.Collections.Concurrent;
using System.Net;
using NReco.VideoConverter;
using YouTubeApiSharp;

var gate = new SemaphoreSlim(1, 1);

var links = new ConcurrentQueue<string>(File.ReadAllLines("H:\\csharp\\PickAPick\\youtube.txt"));
var client = new HttpClient();
client.DefaultRequestHeaders.UserAgent.ParseAdd(
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0");
client.DefaultRequestHeaders.Add("Accept",
    "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br, zstd");
client.DefaultRequestHeaders.Add("Accept-Language", "ru,en;q=0.9,en-GB;q=0.8,en-US;q=0.7");
client.DefaultRequestHeaders.Add("Cache-Control", "max-age=0");
for (int i = 0; i < 30; i++)
{
    new Thread(() => Process()).Start();
}

Thread.Sleep(-1);

async Task Process()
{
    while (links!.TryDequeue(out var link))
    {
        var trueLink = link.Split("&")[0];
        while (true)
        {
            bool taken = true;
            await gate.WaitAsync();
            try
            {
                var videoInfos = DownloadUrlResolver.GetDownloadUrls(trueLink);

                /*
                File.WriteAllText("G:\\youtube\\YouTubeDownload\\YouTubeDownload\\bin\\Debug\\net8.0\\videos\\test.json",
                    JsonSerializer.Serialize(videoInfos, new JsonSerializerOptions()
                    {
                        WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                    }));*/

                var video = videoInfos
                    .Where(v => v.AudioBitrate >= 44100 && v.VideoType == VideoType.Mp4 /*&& v.Resolution != 0*/)
                    .MinBy(v => v.Resolution)!;
                Console.WriteLine(video.Resolution);
                Console.WriteLine(video.AudioType);
                if (video.RequiresDecryption)
                {
                    DownloadUrlResolver.DecryptDownloadUrl(video);
                }

                gate.Release();
                taken = false;
                Console.WriteLine(video.Title);

                var path = "G:\\youtube\\YouTubeDownload\\YouTubeDownload\\bin\\Debug\\net8.0\\videos\\" +
                           trueLink.Split('=')[1] +
                           video.VideoExtension;
                if (File.Exists(path))
                    return;
                Console.WriteLine(path);
                var response = await client.GetAsync(video.DownloadUrl, HttpCompletionOption.ResponseContentRead);
                Console.WriteLine(response.StatusCode);
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    continue;
                }

                var file = File.Create(path);
                await response.Content.ReadAsStream().CopyToAsync(file);
                file.Dispose();
                var ffMpeg = new FFMpegConverter();
                ffMpeg.ConvertMedia(path,
                    $"{path}.mp3", "mp3");

                File.WriteAllText(Path.ChangeExtension(path, ".txt"), video.Title);
                Console.WriteLine("Downloaded");
                break;
            }
            catch (Exception e)
            {
                Console.WriteLine($"{e}, {trueLink}");
                if (taken)
                    gate.Release();
            }
        }
    }
}



it cant download video that only visible by url, but other websites that downloads video from youtube somehow do that