Ytdlp.NET

Static Badge NuGet Version NuGet Downloads

Visitors

Ytdlp.NET

icon

ClipMate - MAUI.NET App - Download

image


Video Downloader - .NET App

Screenshot 2025-01-23 153252

Download the latest App


Ytdlp.NET

Ytdlp.NET is a modern .NET wrapper for yt-dlp that provides a fluent, strongly‑typed API for downloading videos, extracting audio, fetching metadata, and monitoring progress.

The library exposes event‑driven progress reporting, metadata probing, and safe command construction while staying very close to the native yt-dlp functionality.


✨ Features


🚀 New in v3.1

Major redesign for reliability and modern .NET usage.

Highlights


🔧 Required Tools

yt-dlp relies on external tools.

Recommended folder structure:

tools/
├─ yt-dlp.exe
├─ ffmpeg.exe
├─ ffprobe.exe
└─ deno.exe

Example usage:

var ytdlpPath = Path.Combine("tools", "yt-dlp.exe");

🔧 Basic Usage

Download a video

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");

🎧 Extract audio

await using var ytdlp = new Ytdlp()
    .WithExtractAudio("mp3")
    .WithOutputFolder("./audio");

await ytdlp.DownloadAsync(url);

📊 Monitor Progress

ytdlp.OnProgressDownload += (s, e) =>
{
    Console.WriteLine($"{e.Percent:F1}%  {e.Speed}  ETA {e.ETA}");
};

ytdlp.OnCompleteDownload += (s, msg) =>
{
    Console.WriteLine($"Finished: {msg}");
};

📦 Fetch Metadata

await using var ytdlp = new Ytdlp();

var metadata = await ytdlp.GetMetadataAsync(url);

Console.WriteLine(metadata?.Title);
Console.WriteLine(metadata?.Duration);

🎬 Auto‑Select Best Formats

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);

⚡ Parallel Downloads

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);

📡 Events

Event Description
OnProgressDownload Download progress
OnProgressMessage Informational messages
OnCompleteDownload File finished
OnPostProcessingStart Post‑processing start
OnPostProcessingComplete Post‑processing finished
OnOutputMessage Raw output line
OnErrorMessage Error message
OnCommandCompleted Process finished

🔧 Fluent API Methods

General Options

Network Options

Geo-restriction Options

Video Selection

Download Options

Filesystem Options

Thumbnail Options

Verbosity and Simulation Options

Workgrounds

Video Format Options

Subtitle Options

Authentication Options

Post-Processing Options

SponsorBlock Options

Advanced Options

Downloaders

AND MORE …


🔄 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();

🧪 Example Apps


🤝 Contributing

Contributions are welcome!

Open issues or PRs on GitHub.


📜 License

MIT License

See:

https://github.com/manusoft/yt-dlp-wrapper/blob/master/LICENSE.txt


👨‍💻 Author

Manoj Babu ManuHub