-
Notifications
You must be signed in to change notification settings - Fork 2
Home
Manojbabu edited this page Mar 24, 2026
·
10 revisions
Ytdlp.NET is an open-source, modern .NET wrapper library for yt-dlp, the popular command-line audio/video downloader and metadata extractor.
It provides a fluent, strongly-typed API to build yt-dlp commands, fetch rich metadata, list formats, monitor progress, and execute downloads with full event support.
| Ytdlp.NET | |
|---|---|
| Developer | Manojbabu (manusoft/manuhub) |
| Initial release | 2025 |
| Stable release | 3.0.0 |
| Repository | github.com/manusoft/Ytdlp.NET |
| Written in | C# (.NET 8.0 or later) |
| License | MIT |
| Website | https://github.com/manusoft/Ytdlp.NET |
- Fluent API (
WithXxx()methods) - Immutable design (thread‑safe instances)
- Real‑time progress events
- Metadata & format probing
- Batch downloads
- Cancellation support
- Cross‑platform support
- Strongly typed event system
- Async execution
-
IAsyncDisposablesupport
-
Namespace migrated:
ManuHub.Ytdlp.NET— update yourusingdirectives. - External JS runtime: yt-dlp requires an external JS runtime like deno.exe (from denoland/deno) for YouTube downloads with JS challenges.
- Required tools:
Tools/
├─ yt-dlp.exe
├─ deno.exe
├─ ffmpeg.exe
└─ ffprobe.exe
Recommended: Use companion NuGet packages:
ManuHub.YtdlpManuHub.DenoManuHub.FFmpegManuHub.FFprobe
Example path resolution in .NET:
var ytdlpPath = Path.Combine(AppContext.BaseDirectory, "tools", "yt-dlp.exe");
var ffmpegPath = Path.Combine(AppContext.BaseDirectory, "tools");await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe")
.WithFormat("best")
.WithOutputFolder("./downloads")
.WithOutputTemplate("%(title)s.%(ext)s");
ytdlp.OnProgressDownload += (s, e) =>
Console.WriteLine($"{e.Percent:F1}% {e.Speed} ETA {e.ETA}");
await ytdlp.DownloadAsync("https://www.youtube.com/watch?v=VIDEO_ID");await using var ytdlp = new Ytdlp()
.WithExtractAudio("mp3")
.WithOutputFolder("./audio");
await ytdlp.DownloadAsync(url);ytdlp.OnProgressDownload += (s, e) =>
{
Console.WriteLine($"{e.Percent:F1}% {e.Speed} ETA {e.ETA}");
};
ytdlp.OnCompleteDownload += (s, msg) =>
{
Console.WriteLine($"Finished: {msg}");
};await using var ytdlp = new Ytdlp();
var metadata = await ytdlp.GetMetadataAsync(url);
Console.WriteLine(metadata?.Title);
Console.WriteLine(metadata?.Duration);await using var ytdlp = new Ytdlp();
string bestVideo = await ytdlp.GetBestVideoFormatIdAsync(url, 1080);
string bestAudio = await ytdlp.GetBestAudioFormatIdAsync(url);
await ytdlp
.WithFormat($"{bestVideo}+{bestAudio}/best")
.DownloadAsync(url);var urls = new[]
{
"https://youtu.be/video1",
"https://youtu.be/video2"
};
var tasks = urls.Select(async url =>
{
await using var ytdlp = new Ytdlp()
.WithFormat("best")
.WithOutputFolder("./batch");
await ytdlp.DownloadAsync(url);
});
await Task.WhenAll(tasks);OR
var urls = new[] { "https://youtu.be/vid1", "https://youtu.be/vid2" };
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe")
.WithFormat("best")
.WithOutputFolder("./batch");
await ytdlp.DownloadBatchAsync(urls, maxConcurrency: 3);| Event | Description |
|---|---|
OnProgressDownload |
Download progress |
OnProgressMessage |
Informational messages |
OnCompleteDownload |
File finished |
OnPostProcessingComplete |
Post‑processing finished |
OnOutputMessage |
Raw output line |
OnErrorMessage |
Error message |
OnCommandCompleted |
Process finished |
-
Immutable & thread-safe: Each
WithXxx()call returns a new instance. -
Async disposal:
YtdlpimplementsIAsyncDisposable.
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe", new ConsoleLogger())
.WithFormat("best")
.WithOutputFolder("./downloads");
ytdlp.OnProgressDownload += (s, e) => Console.WriteLine($"Progress: {e.Percent:F2}%");
ytdlp.OnCompleteDownload += (s, msg) => Console.WriteLine($"Download complete: {msg}");
await ytdlp.DownloadAsync("https://www.youtube.com/watch?v=RGg-Qx1rL9U");var urls = new[] { "https://youtu.be/video1", "https://youtu.be/video2" };
var tasks = urls.Select(async url =>
{
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe", new ConsoleLogger())
.WithFormat("best")
.WithOutputFolder("./batch");
ytdlp.OnProgressDownload += (s, e) => Console.WriteLine($"[{url}] {e.Percent:F2}%");
ytdlp.OnCompleteDownload += (s, msg) => Console.WriteLine($"[{url}] Download complete: {msg}");
await ytdlp.DownloadAsync(url);
});
await Task.WhenAll(tasks);- Always create a new instance per download for parallel operations.
- Always use
await usingfor proper resource cleanup. - Attach events after the
WithXxx()call.
- .NET 8.0 or later
- yt-dlp executable (required)
- FFmpeg / FFprobe (recommended for merging, audio extraction, thumbnails)
- yt-dlp — upstream project
- Ytdlp.NET GitHub Repository
- .NET Package Manager (NuGet)
- GitHub repository: https://github.com/manusoft/Ytdlp.NET
- yt-dlp releases: https://github.com/yt-dlp/yt-dlp/releases
- FFmpeg builds: https://www.gyan.dev/ffmpeg/builds/
This page was last edited on MArch 24, 2026.
Copyright (C) 2025-2026 Manojbabu, Manuhub