Ytdlp.NET 3.0.3

Prefix Reserved
dotnet add package Ytdlp.NET --version 3.0.3
                    
NuGet\Install-Package Ytdlp.NET -Version 3.0.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ytdlp.NET" Version="3.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ytdlp.NET" Version="3.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Ytdlp.NET" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ytdlp.NET --version 3.0.3
                    
#r "nuget: Ytdlp.NET, 3.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ytdlp.NET@3.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ytdlp.NET&version=3.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Ytdlp.NET&version=3.0.3
                    
Install as a Cake Tool

Static Badge NuGet Version NuGet Downloads

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 your using directives.
  • 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.Ytdlp
  • ManuHub.Deno
  • ManuHub.FFmpeg
  • ManuHub.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 IAsyncDisposable with await 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: Ytdlp implements IAsyncDisposable.

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:

  1. Always create a new instance per download for parallel operations.
  2. Always use await using for proper resource cleanup.
  3. 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(AudioFormat.Mp3, 5)
    .WithOutputFolder("./audio")
    .WithEmbedThumbnail()
    .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, int quality = 5)
  • .WithRemuxVideo(string format) usage 'mp4' or 'mp4>mkv'
  • .WithRecodeVideo(string format, 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.OnPostProcessingStart += (s, msg) => Console.WriteLine($"Post-processing-start: {msg}")
ytdlp.OnPostProcessingComplete += (s, msg) => Console.WriteLine($"Post-processing-complete: {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()
AddCustomCommand() AddFlag(string flag) or AddOption(string key, string value)

Custom commands

AddFlag("--no-check-certificate");
AddOption("--external-downloader", "aria2c");

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 using for 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • 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.3 208 4/10/2026
3.0.2 115 4/4/2026
3.0.1 126 4/3/2026
3.0.0 146 3/22/2026
2.2.0 117 3/17/2026
2.1.1 122 3/17/2026 2.1.1 is deprecated because it has critical bugs.
2.1.0 123 3/16/2026 2.1.0 is deprecated because it has critical bugs.
2.0.2 103 3/14/2026
2.0.1 165 2/19/2026
2.0.0 104 2/18/2026
2.0.0-preview1 102 2/15/2026
1.4.0 468 11/24/2025
1.3.0 244 11/15/2025
1.2.3 248 10/19/2025
1.2.2 316 8/8/2025
1.2.1 296 8/5/2025
1.2.0 289 8/5/2025
1.1.0 234 7/13/2025
1.0.0 162 7/5/2025

Ytdlp.NET v3.0 ✨ Major Redesign with Fluent API

- Complete rewrite using an immutable, fluent API (`WithXxx()` methods).
- Added `IAsyncDisposable` support for proper async cleanup of processes.
- Thread-safe design: safe to run multiple instances in parallel.
- Rich event system: OnProgressDownload, OnProgressMessage, OnCompleteDownload,
OnPostProcessingComplete, OnErrorMessage, OnCommandCompleted.
- Improved cancellation handling for both downloads and metadata probing.
- Enhanced probe methods: GetMetadataAsync, GetAvailableFormatsAsync,
GetBestVideoFormatIdAsync, GetBestAudioFormatIdAsync.
- Better output templates, FFmpeg/Deno integration, and safe custom command support.

🛠 Improvements in this update
- Better internal DownloadRunner and ProbeRunner for heavy JSON output and cancellation safety.
- Safer process killing and stream handling to prevent potential hangs.

🚀 New Features
- Fully chainable fluent API for downloads, audio extraction, subtitles, post-processing and more.
- Batch download support (sequential or parallel execution).
- Real-time progress tracking via events.
- Automatic resource cleanup with `await using`.
- Cross-platform (Windows, macOS, Linux).

⚠️ Breaking Change
- Improve progress parsing and cancellation handling, which may require adjustments in event handling and cancellation token usage.
- All old command methods (SetFormat, SetOutputFolder, etc.) have been removed.
- Only the new fluent `WithXxx()` style remains.
- Namespace changed to `ManuHub.Ytdlp.NET`.
- Always use a fresh instance per download for parallel scenarios.
- Use `await using` for proper async disposal.

🛠 Notes
- Companion packages recommended: ManuHub.Ytdlp, ManuHub.FFmpeg, ManuHub.FFprobe, ManuHub.Deno.
- All examples and documentation updated for v3.0.
- This release greatly improves reliability, cancellation, and maintainability.

See the repository for the full migration guide.