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
                    
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.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ytdlp.NET" Version="3.0.0" />
                    
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.0
                    
#r "nuget: Ytdlp.NET, 3.0.0"
                    
#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.0
                    
#: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.0
                    
Install as a Cake Addin
#tool nuget:?package=Ytdlp.NET&version=3.0.0
                    
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("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 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.0 29 3/22/2026
2.2.0 94 3/17/2026
2.1.1 101 3/17/2026 2.1.1 is deprecated because it has critical bugs.
2.1.0 102 3/16/2026 2.1.0 is deprecated because it has critical bugs.
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.