Last active
March 17, 2023 23:44
-
-
Save twfarland/857da418a195f7fbeb5438e252cc0bb6 to your computer and use it in GitHub Desktop.
Downloads youtube videos and converts them to mp3 via streaming. ChatpGPT 4 wrote most of this (with minor babysitting from me).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using NAudio.Wave; | |
using NAudio.Lame; | |
using YoutubeExplode; | |
using YoutubeExplode.Videos.Streams; | |
namespace YoutubeDownloader | |
{ | |
class Program | |
{ | |
static async Task Main(string[] args) | |
{ | |
// Check for the correct number of command-line arguments | |
if (args.Length != 2) | |
{ | |
Console.WriteLine("Usage: YoutubeDownloader <url_list_file> <output_dir>"); | |
return; | |
} | |
// Parse the command-line arguments | |
var urlListFile = args[0]; | |
var outputDir = args[1]; | |
// Read the list of URLs from the specified file | |
var urls = File.ReadAllLines(urlListFile).Distinct(); | |
// Create the output directory if it doesn't exist | |
Directory.CreateDirectory(outputDir); | |
var youtube = new YoutubeClient(); | |
// Define a function to download and convert a single video | |
async Task DownloadVideoAsync(string url) | |
{ | |
try | |
{ | |
Console.WriteLine($"Getting stream for {url}..."); | |
// Get the video information and stream URL | |
var video = await youtube.Videos.GetAsync(url); | |
var outputPath = Path.Combine(outputDir, $"{video.Title}.mp3"); | |
Console.WriteLine("Got stream for " + video.Title + " (" + video.Id + ")"); | |
if (File.Exists(outputPath)) | |
{ | |
Console.WriteLine($"Skipping {video.Title} - file already exists"); | |
return; | |
} | |
var streamInfoSet = await youtube.Videos.Streams.GetManifestAsync(video.Id); | |
var streamInfo = streamInfoSet.GetAudioOnlyStreams().GetWithHighestBitrate(); | |
var streamUrl = streamInfo.Url; | |
Console.WriteLine($"Downloading {video.Title}..."); | |
// Download the audio stream and convert it to MP3 | |
var inputStream = new MediaFoundationReader(streamUrl); | |
var outputStream = new LameMP3FileWriter(outputPath, inputStream.WaveFormat, LAMEPreset.STANDARD); | |
await inputStream.CopyToAsync(outputStream); | |
Console.WriteLine($"Saved {video.Title} as mp3"); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine($"Failed to download {url}: {ex.Message}"); | |
Console.WriteLine(ex.StackTrace); | |
Console.WriteLine(ex.InnerException); | |
} | |
} | |
// Download the videos with the specified degree of parallelism | |
var tasks = urls | |
.Select(url => | |
DownloadVideoAsync(url)) | |
.AsParallel() | |
.WithDegreeOfParallelism( | |
Environment.ProcessorCount); | |
await Task.WhenAll(tasks); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment