C# Исходник Софт Youtube Extractor

_=Gigant=_

Известный
Автор темы
144
222
console type program which you can use to manipulate with youtube videos
if for some reason you get message "Video {ID} not available" just paste link again and press enter
Screenshot_3.png

Screenshot_2.png


Update 2 https://www.mediafire.com/file/hvcmrv6zbpdvlvo/V2_.rar/file
no restrictions for russia in update 2 also works for other countries

Source

C:
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using YoutubeExplode;
using YoutubeExplode.Common;
using YoutubeExplode.Videos; //nuget
using YoutubeExplode.Videos.ClosedCaptions;
using YoutubeExplode.Videos.Streams;

namespace YouTubeVideoTool
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var youtube = new YoutubeClient();
            string videoUrl = "";

            while (true)
            {
                if (string.IsNullOrEmpty(videoUrl))
                {
                    Console.WriteLine("Please input your target video link then press 'ENTER' to proceed:");
                    videoUrl = Console.ReadLine();
                }

                try
                {
                    var videoId = VideoId.Parse(videoUrl);
                    var video = await youtube.Videos.GetAsync(videoId);

                    var maxResThumbnail = video.Thumbnails.GetWithHighestResolution();
                    string thumbnailUrl = maxResThumbnail.Url;

                    while (true)
                    {
                        // options ::))))))))))))))))))))))))))))))))))))))))))))))))))))))))
                        Console.WriteLine("\nWhat would you like to do?");
                        Console.WriteLine("1. Open HD thumbnail");
                        Console.WriteLine("2. Save thumbnail to desktop");
                        Console.WriteLine("3. Download audio as MP3");
                        Console.WriteLine("4. Download video as MP4");
                        Console.WriteLine("5. Download both video.mp4 and audio.mp3");
                        Console.WriteLine("6. Extract captions");
                        Console.WriteLine("7. Input a different video link");
                        Console.WriteLine("8. Exit");

                        ConsoleKeyInfo keyInfo = Console.ReadKey();
                        Console.WriteLine();

                        switch (keyInfo.Key)
                        {
                            case ConsoleKey.D1:
                            case ConsoleKey.NumPad1:
                                // Open thumbnail in browser
                                Process.Start(new ProcessStartInfo(thumbnailUrl) { UseShellExecute = true });
                                Console.WriteLine("Thumbnail opened in your default browser.");
                                break;

                            case ConsoleKey.D2:
                            case ConsoleKey.NumPad2:
                                // save thumbnail...
                                await SaveThumbnailToDesktopAsync(thumbnailUrl);
                                Console.WriteLine("Thumbnail saved to your desktop.");
                                break;

                            case ConsoleKey.D3:
                            case ConsoleKey.NumPad3:
                                // extract audio from the video
                                await ExtractAudioFromVideoProgressAsync(youtube, video);
                                Console.WriteLine("Audio extracted and saved to your desktop.");
                                break;

                            case ConsoleKey.D4:
                            case ConsoleKey.NumPad4:
                                // download video as mp4
                                await DownloadVideoAsMp4ProgressAsync(youtube, video);
                                Console.WriteLine("Video downloaded and saved to your desktop.");
                                break;

                            case ConsoleKey.D5:
                            case ConsoleKey.NumPad5:
                                // download both video and audio
                                await DownloadVideoAsMp4ProgressAsync(youtube, video);
                                await ExtractAudioFromVideoProgressAsync(youtube, video);
                                Console.WriteLine("Both video and audio downloaded to your desktop.");
                                break;

                            case ConsoleKey.D6:
                            case ConsoleKey.NumPad6:
                                // extract captions
                                await ExtractCaptionsAsync(youtube, video);
                                break;

                            case ConsoleKey.D7:
                            case ConsoleKey.NumPad7:
                                // allow new video link
                                Console.WriteLine("Input a new video link:");
                                videoUrl = Console.ReadLine();
                                break;

                            case ConsoleKey.D8:
                            case ConsoleKey.NumPad8:
                                // exit app men
                                Console.WriteLine("Goodbye and don't come back.");
                                return;

                            default:
                                Console.WriteLine("Invalid option selected.");
                                break;
                        }

                        // break loop
                        if (keyInfo.Key == ConsoleKey.D7 || keyInfo.Key == ConsoleKey.NumPad7)
                        {
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"An error occurred: {ex.Message}");
                    videoUrl = "";  // reset video URL
                }
            }
        }

        private static async Task SaveThumbnailToDesktopAsync(string thumbnailUrl)
        {
            string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string filePath = Path.Combine(desktopPath, "thumbnail.jpg");

            using (HttpClient client = new HttpClient())
            {
                var thumbnailData = await client.GetByteArrayAsync(thumbnailUrl);
                await File.WriteAllBytesAsync(filePath, thumbnailData);
            }
        }

        private static async Task ExtractAudioFromVideoProgressAsync(YoutubeClient youtube, Video video)
        {
            //desktop path
            string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string safeTitle = string.Join("_", video.Title.Split(Path.GetInvalidFileNameChars()));
            string audioPath = Path.Combine(desktopPath, $"{safeTitle}.mp3");

            var streamManifest = await youtube.Videos.Streams.GetManifestAsync(video.Id);
            var audioStreamInfo = streamManifest.GetAudioOnlyStreams().TryGetWithHighestBitrate();

            if (audioStreamInfo != null)
            {
                Console.WriteLine("Extracting audio...");

                await youtube.Videos.Streams.DownloadAsync(audioStreamInfo, audioPath, new Progress<double>(p =>
                {
                    Console.Write($"\rProgress: {p:P2}");
                }));

                Console.WriteLine("\nAudio extraction completed!");
            }
            else
            {
                Console.WriteLine("No audio stream found.");
            }
        }

        private static async Task DownloadVideoAsMp4ProgressAsync(YoutubeClient youtube, Video video)
        {
            string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string safeTitle = string.Join("_", video.Title.Split(Path.GetInvalidFileNameChars()));
            string videoPath = Path.Combine(desktopPath, $"{safeTitle}.mp4");

            var streamManifest = await youtube.Videos.Streams.GetManifestAsync(video.Id);
            var streamInfo = streamManifest.GetMuxedStreams().TryGetWithHighestVideoQuality();

            if (streamInfo != null)
            {
                Console.WriteLine("Downloading video...");

                await youtube.Videos.Streams.DownloadAsync(streamInfo, videoPath, new Progress<double>(p =>
                {
                    Console.Write($"\rProgress: {p:P2}");
                }));

                Console.WriteLine("\nVideo download completed!");
            }
            else
            {
                Console.WriteLine("No suitable video stream found.");
            }
        }

        private static async Task ExtractCaptionsAsync(YoutubeClient youtube, Video video)
        {
            var trackManifest = await youtube.Videos.ClosedCaptions.GetManifestAsync(video.Id);
            var tracks = trackManifest.Tracks.ToList();

            if (tracks.Count == 0)
            {
                Console.WriteLine("No captions available for this video.");
                return;
            }

            Console.WriteLine("Available captions:");
            for (int i = 0; i < tracks.Count; i++)
            {
                var track = tracks[i];
                Console.WriteLine($"{i + 1}. {track.Language.Name} ({track.Language.Code})");
            }

            Console.WriteLine("Enter the number of the caption you want to download:");
            string input = Console.ReadLine();

            if (int.TryParse(input, out int choice) && choice >= 1 && choice <= tracks.Count)
            {
                var selectedTrack = tracks[choice - 1];
                await DownloadCaptionAsync(youtube, selectedTrack, video.Title);
            }
            else
            {
                Console.WriteLine("Invalid selection.");
            }
        }

        private static async Task DownloadCaptionAsync(YoutubeClient youtube, ClosedCaptionTrackInfo trackInfo, string videoTitle)
        {
            try
            {
                var captionTrack = await youtube.Videos.ClosedCaptions.GetAsync(trackInfo);

                string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                string safeTitle = string.Join("_", videoTitle.Split(Path.GetInvalidFileNameChars()));
                string fileName = $"{safeTitle}_{trackInfo.Language.Code}.srt";
                string filePath = Path.Combine(desktopPath, fileName);
                var srt = CaptionToSrt(captionTrack);

                await File.WriteAllTextAsync(filePath, srt);
                Console.WriteLine($"Caption '{trackInfo.Language.Name}' downloaded to your desktop as '{fileName}'.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error occurred while downloading captions: {ex.Message}");
            }
        }

        private static string CaptionToSrt(ClosedCaptionTrack track)
        {
            var srt = "";
            int count = 1;

            foreach (var caption in track.Captions)
            {
                var start = TimeSpan.FromMilliseconds(caption.Offset.TotalMilliseconds);
                var end = TimeSpan.FromMilliseconds((caption.Offset + caption.Duration).TotalMilliseconds);

                srt += $"{count}\n";
                srt += $"{FormatTime(start)} --> {FormatTime(end)}\n";
                srt += $"{caption.Text}\n\n";
                count++;
            }

            return srt;
        }

        private static string FormatTime(TimeSpan time)
        {
            return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2},{time.Milliseconds:D3}";
        }
    }
}

Update 2 https://www.mediafire.com/file/hvcmrv6zbpdvlvo/V2_.rar/file
no restrictions for russia in update 2 also works for other countries
 
Последнее редактирование:

chromiusj

Известный
Модератор
5,651
3,954
Why isn’t this section of code with a warning about regional settings in the source code? Can’t this be considered hiding the code, and thereby bypassing pre-moderation for checking malware?
 
  • Нравится
Реакции: _=Gigant=_

Cremi

Новичок
16
2
Why isn’t this section of code with a warning about regional settings in the source code? Can’t this be considered hiding the code, and thereby bypassing pre-moderation for checking malware?
Причиной этому есть плагин, который использует автор. Я попробую переделать его в версию программы, а не консольного приложения с возможным фиксом данной проблемы.
 
  • Нравится
Реакции: _=Gigant=_

Cremi

Новичок
16
2
А чё длл файлы спрятаны?
Пересмотрев код самого разрешения Ютуба, который использует автор, нашёл много зашифрованных строчек, и зависимость DISCORD Webhook в настройках разрешений. Код автора чист, а вот кол разрешения - нет. Не советую качать. Доказательства с шифровкой постараюсь найти, строчку с DiscordWebhook(находиться в репозитории автора, в .github/workflows/main.yml прикреплю ниже:
Screenshot_2024-08-14-13-51-46-969_com.github.android.png
Вывод: в плагине есть скрытый код, который кроме подтягивания местоположения, создаёт конфиг файлы, и использует DiscordWebhook для отправки сообщений. (Может и больше делает) Так же было много обращений к Cookie файлам. Поэтому.. на свой страх и риск 😁
 
Последнее редактирование: