Ytdlp.NET
3.0.0
Prefix Reserved
dotnet add package Ytdlp.NET --version 3.0.0
NuGet\Install-Package Ytdlp.NET -Version 3.0.0
<PackageReference Include="Ytdlp.NET" Version="3.0.0" />
<PackageVersion Include="Ytdlp.NET" Version="3.0.0" />
<PackageReference Include="Ytdlp.NET" />
paket add Ytdlp.NET --version 3.0.0
#r "nuget: Ytdlp.NET, 3.0.0"
#:package Ytdlp.NET@3.0.0
#addin nuget:?package=Ytdlp.NET&version=3.0.0
#tool nuget:?package=Ytdlp.NET&version=3.0.0
Ytdlp.NET
v3.0
Ytdlp.NET is a fluent, strongly-typed .NET wrapper around yt-dlp. It provides a fully async, event-driven interface for downloading videos, extracting audio, retrieving metadata, and post-processing media from YouTube and hundreds of other platforms.
⚠️ Important Notes
- 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");
✨ Features
- Fluent API: Build yt-dlp commands with
WithXxx()methods. - Immutable & thread-safe: Each method returns a new instance, safe for parallel usage.
- Async & IAsyncDisposable: Automatic cleanup of child processes.
- Progress & Events: Real-time progress tracking and post-processing notifications.
- Format Listing: Retrieve and parse available formats.
- Batch Downloads: Sequential or parallel execution.
- Output Templates: Flexible naming with yt-dlp placeholders.
- Custom Command Injection: Add extra yt-dlp options safely.
- Cross-platform: Windows, macOS, Linux (where yt-dlp is supported).
🚀 New in v3.0
- Full support for
IAsyncDisposablewithawait using. - Immutable builder (
WithXxx) for safe instance reuse. - Updated examples for event-driven downloads.
- Simplified metadata fetching & format selection.
- High-performance probe methods with optional buffer size.
- Improved cancellation & error handling.
🛠 Methods
VersionAsync(CancellationToken ct)UpdateAsync(UpdateChannel channel, CancellationToken ct)ExtractorsAsync(CancellationToken ct, int bufferKb)GetMetadataAsync(string url, CancellationToken ct, int bufferKb)GetMetadataRawAsync(string url, CancellationToken ct, int bufferKb)GetFormatsAsync(string url, CancellationToken ct, int bufferKb)GetMetadataLiteAsync(string url, CancellationToken ct, int bufferKb)GetMetadataLiteAsync(string url, IEnumerable<string> fields, CancellationToken ct, int bufferKb)GetBestAudioFormatIdAsync(string url, CancellationToken ct, int bufferKb)GetBestVideoFormatIdAsync(string url, int maxHeight, CancellationToken ct, int bufferKb)ExecuteAsync(string url, CancellationToken ct)ExecuteBatchAsync(IEnumerable<string> urls, int maxConcurrency, CancellationToken ct)
🔧 Thread Safety & Disposal
- Immutable & thread-safe: Each
WithXxx()call returns a new instance. - Async disposal:
YtdlpimplementsIAsyncDisposable.
Sequential download example:
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");
Parallel download example:
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);
Key points:
- Always create a new instance per download for parallel operations.
- Always use
await usingfor proper resource cleanup. - Attach events after the
WithXxx()call.
📦 Basic Usage
Download a Single Video
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe", new ConsoleLogger())
.WithFormat("best")
.WithOutputFolder("./downloads")
.WithEmbedMetadata()
.WithEmbedThumbnail();
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");
Extract Audio
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe")
.WithExtractAudio("mp3")
.WithOutputFolder("./audio")
.WithEmbedMetadata();
await ytdlp.DownloadAsync("https://www.youtube.com/watch?v=RGg-Qx1rL9U");
Fetch Metadata
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe");
var metadata = await ytdlp.GetMetadataAsync("https://www.youtube.com/watch?v=abc123");
Console.WriteLine($"Title: {metadata?.Title}, Duration: {metadata?.Duration}");
Fetch Formats
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe");
var formats = await ytdlp.GetFormatsAsync("https://www.youtube.com/watch?v=abc123");
foreach(var format in formats)
Console.WriteLine($"Id: {metadata?.Id}, Extension: {metadata?.Extension}");
Best Format Selection
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe");
string bestAudio = await ytdlp.GetBestAudioFormatIdAsync(url);
string bestVideo = await ytdlp.GetBestVideoFormatIdAsync(url, maxHeight: 720);
await ytdlp
.WithFormat($"{bestVideo}+{bestAudio}/best")
.WithOutputFolder("./downloads")
.DownloadAsync(url);
Batch Downloads
var urls = new[] { "https://youtu.be/vid1", "https://youtu.be/vid2" };
var tasks = urls.Select(async url =>
{
await using var ytdlp = new Ytdlp("tools\\yt-dlp.exe")
.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);
Fluent Methods (v3.0)
General Options
.WithIgnoreErrors().WithAbortOnError().WithIgnoreConfig().WithConfigLocations(string path).WithPluginDirs(string path).WithNoPluginDirs(string path).WithJsRuntime(Runtime runtime, string runtimePath).WithNoJsRuntime().WithFlatPlaylist()WithLiveFromStart().WithWaitForVideo(TimeSpan? maxWait = null).WithMarkWatched()
Network Options
.WithProxy(string? proxy).WithSocketTimeout(TimeSpan timeout).WithForceIpv4().WithForceIpv6().WithEnableFileUrls()
Geo-restriction Options
.WithGeoVerificationProxy(string url).WithGeoBypassCountry(string countryCode)
Video Selection
.WithPlaylistItems(string items).WithMinFileSize(string size).WithMaxFileSize(string size).WithDate(string date).WithDateBefore(string date).WithDateAfter(string date).WithMatchFilter(string filterExpression).WithNoPlaylist().WithYesPlaylist().WithAgeLimit(int years).WithDownloadArchive(string archivePath = "archive.txt").WithMaxDownloads(int count).WithBreakOnExisting()
Download Options
.WithConcurrentFragments(int count = 8).WithLimitRate(string rate).WithThrottledRate(string rate).WithRetries(int maxRetries).WithFileAccessRetries(int maxRetries).WithFragmentRetries(int retries).WithSkipUnavailableFragments().WithAbortOnUnavailableFragments().WithKeepFragments().WithBufferSize(string size).WithNoResizeBuffer().WithPlaylistRandom().WithHlsUseMpegts().WithNoHlsUseMpegts().WithDownloadSections(string regex)
Filesystem Options
.WithHomeFolder(string path).WithTempFolder(string path).WithOutputFolder(string path).WithFFmpegLocation(string path).WithOutputTemplate(string template).WithRestrictFilenames().WithWindowsFilenames().WithTrimFilenames(int length).WithNoOverwrites().WithForceOverwrites().WithNoContinue().WithNoPart().WithMtime().WithWriteDescription().WithWriteInfoJson().WithNoWritePlaylistMetafiles().WithNoCleanInfoJson().WriteComments().WithNoWriteComments().WithLoadInfoJson(string path).WithCookiesFile(string path).WithCookiesFromBrowser(string browser).WithNoCacheDir().WithRemoveCacheDir()
Thumbnail Options
.WithThumbnails(bool allSizes = false)
Verbosity and Simulation Options
.WithQuiet().WithNoWarnings().WithSimulate().WithNoSimulate().WithSkipDownload().WithVerbose()
Workgrounds
.WithAddHeader(string header, string value).WithSleepInterval(double seconds, double? maxSeconds = null).WithSleepSubtitles(double seconds)
Video Format Options
.WithFormat(string format).WithMergeOutputFormat(string format)
Subtitle Options
.WithSubtitles(string languages = "all", bool auto = false)
Authentication Options
.WithAuthentication(string username, string password).WithTwoFactor(string code)
Post-Processing Options
.WithExtractAudio(string format = "mp3", int quality = 5).WithRemuxVideo(MediaFormat format = MediaFormat.Mp4).WithRecodeVideo(MediaFormat format = MediaFormat.Mp4, string? videoCodec = null, string? audioCodec = null).WithPostprocessorArgs(PostProcessors postprocessor, string args).WithKeepVideo().WithNoPostOverwrites().WithEmbedSubtitles(string languages = "all", string? convertTo = null).WithEmbedThumbnail().WithEmbedMetadata().WithEmbedChapters().WithEmbedInfoJson().WithNoEmbedInfoJson().WithReplaceInMetadata(string field, string regex, string replacement).WithConcatPlaylist(string policy = "always").WithFFmpegLocation(string? ffmpegPath).WithConvertThumbnails(string format = "jpg").WithForceKeyframesAtCuts()
SponsorBlock Options
.WithSponsorblockMark(string categories = "all").WithSponsorblockRemove(string categories = "all").WithNoSponsorblock()
Advanced Options
.AddFlag(string flag).AddOption(string key, string value)
Downloaders
.WithExternalDownloader(string downloaderName, string? downloaderArgs = null).WithAria2(int connections = 16).WithHlsNative().WithFfmpegAsLiveDownloader(string? extraFfmpegArgs = null)
AND MORE ...
Events
ytdlp.OnProgressDownload += (s, e) => Console.WriteLine($"Progress: {e.Percent:F2}%");
ytdlp.OnProgressMessage += (s, msg) => Console.WriteLine(msg);
ytdlp.OnCompleteDownload += (s, msg) => Console.WriteLine($"Done: {msg}");
ytdlp.OnPostProcessingComplete += (s, msg) => Console.WriteLine($"Post-processing: {msg}");
ytdlp.OnErrorMessage += (s, err) => Console.WriteLine($"Error: {err}");
ytdlp.OnOutputMessage += (s, msg) => Console.WriteLine(msg);
ytdlp.OnCommandCompleted += (s, e) => Console.WriteLine($"Command finished: {e.Command}");
🔄 Upgrade Guide (v2 → v3)
v3 introduces a new immutable fluent API.
Old mutable commands were removed.
❌ Old API (v2)
var ytdlp = new Ytdlp();
await ytdlp
.SetFormat("best")
.SetOutputFolder("./downloads")
.ExecuteAsync(url);
✅ New API (v3)
await using var ytdlp = new Ytdlp()
.WithFormat("best")
.WithOutputFolder("./downloads");
await ytdlp.DownloadAsync(url);
Method changes
| v2 | v3 |
|---|---|
SetFormat() |
WithFormat() |
SetOutputFolder() |
WithOutputFolder() |
SetTempFolder() |
WithTempFolder() |
SetOutputTemplate() |
WithOutputTemplate() |
SetFFMpegLocation() |
WithFFmpegLocation() |
ExtractAudio() |
WithExtractAudio() |
UseProxy() |
WithProxy() |
Important behavior changes
Instances are immutable
Every WithXxx() call returns a new instance.
var baseYtdlp = new Ytdlp();
var download = baseYtdlp
.WithFormat("best")
.WithOutputFolder("./downloads");
Event subscription
Attach events to the configured instance.
var download = baseYtdlp.WithFormat("best");
download.OnProgressDownload += ...
Proper disposal
Use await using for automatic cleanup.
await using var ytdlp = new Ytdlp();
✅ Notes
- All commands now start with
WithXxx(). - Immutable: no shared state; safe for parallel usage.
- Always
await usingfor proper disposal. - Deprecated old methods removed.
- Probe methods remain the same (
GetMetadataAsync,GetFormatsAsync,GetBestVideoFormatIdAsync, etc.).
License
MIT License — see LICENSE
Author: Manojbabu (ManuHub)
Repository: Ytdlp.NET
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 3.0.0 | 29 | 3/22/2026 | |
| 2.2.0 | 94 | 3/17/2026 | |
| 2.1.1 | 101 | 3/17/2026 | |
| 2.1.0 | 102 | 3/16/2026 | |
| 2.0.2 | 89 | 3/14/2026 | |
| 2.0.1 | 146 | 2/19/2026 | |
| 2.0.0 | 94 | 2/18/2026 | |
| 2.0.0-preview1 | 93 | 2/15/2026 | |
| 1.4.0 | 449 | 11/24/2025 | |
| 1.3.0 | 237 | 11/15/2025 | |
| 1.2.3 | 242 | 10/19/2025 | |
| 1.2.2 | 313 | 8/8/2025 | |
| 1.2.1 | 291 | 8/5/2025 | |
| 1.2.0 | 286 | 8/5/2025 | |
| 1.1.0 | 229 | 7/13/2025 | |
| 1.0.0 | 153 | 7/5/2025 |
Ytdlp.NET v3.0
✨ Major Updates:
- Complete v3.0 redesign with immutable, fluent API (`WithXxx()` methods).
- Added IAsyncDisposable support for proper async cleanup of child processes.
- Thread-safe usage: safe for parallel downloads using multiple instances.
- Events fully supported: OnProgressDownload, OnProgressMessage, OnCompleteDownload, OnPostProcessingComplete, OnErrorMessage, OnCommandCompleted.
- All old command methods removed; only `WithXxx()` methods remain.
- Improved cancellation handling for downloads and metadata fetching.
- Enhanced metadata probe methods: GetMetadataAsync, GetAvailableFormatsAsync, GetBestVideoFormatIdAsync, GetBestAudioFormatIdAsync.
- Flexible output templates and FFmpeg/Deno integration.
- Custom command injection (`AddCustomCommand`) validated safely.
🚀 Features:
- Fluent, chainable API for downloads, audio extraction, subtitles, and post-processing.
- Supports batch downloads with sequential or parallel execution.
- Real-time progress tracking with events.
- Automatic cleanup of resources when disposed asynchronously.
- Cross-platform: Windows, macOS, Linux (yt-dlp supported).
⚠️ Breaking Changes:
- Old SetFormat/SetOutputFolder methods removed; replace with `WithFormat()`, `WithOutputFolder()`, etc.
- Deprecated events/methods removed.
- Always use a new instance per download for parallel execution.
- Use `await using` with Ytdlp for async disposal.
🛠 Notes:
- Namespace migrated to `ManuHub.Ytdlp.NET`.
- Recommended: Use companion NuGet packages for yt-dlp, FFmpeg, FFprobe, and Deno.
- All examples updated for fluent v3.0 API.