Skip to content

manusoft/Ytdlp.NET

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

115 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Static Badge NuGet Version NuGet Downloads

Visitors

Ytdlp.NET

icon

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.

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


ClipMate - MAUI.NET App - Download

image

Video Downloader - .NET App

Screenshot 2025-01-23 153252

Download the latest App


✨ Features

  • 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
  • IAsyncDisposable support

πŸš€ New in v3.2

  • New GetDeepMetadataAsync() method for comprehensive metadata extraction.
  • New GetDeepMetadataRawAsync() for raw JSON metadata.
  • New Metadata.Flatten() method to simplify nested metadata structures.
  • Improved progress download events for batch downloads with better tracking.
  • Improved Metadata model with more fields and better parsing.

Highlights

  • Improved UpdateAsync with specific version support
  • Immutable fluent builder API
  • IAsyncDisposable implemented
  • Thread‑safe usage
  • Simplified event handling
  • Improved metadata probing
  • Better cancellation support
  • Safer command building

πŸ”§ 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

πŸ›  Methods

  • VersionAsync(CancellationToken ct)
  • UpdateAsync(UpdateChannel channel, string specificVersion, CancellationToken ct)
  • ExtractorsAsync(CancellationToken ct, int bufferKb)
  • GetMetadataAsync(string url, CancellationToken ct, int bufferKb)
  • GetMetadataRawAsync(string url, CancellationToken ct, int bufferKb)
  • GetDeepMetadataAsync(string url, CancellationToken ct = default, bool tuneProcess = true, int bufferKb = 256)
  • GetDeepMetadataRawAsync(string url, CancellationToken ct = default, bool tuneProcess = true, int bufferKb = 256)
  • 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)

πŸ”§ Fluent API Methods

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()
  • .WithEmbedThumbnail()
  • .WithEmbedMetadata()
  • .WithEmbedChapters()
  • .WithEmbedInfoJson()
  • .WithNoEmbedInfoJson()
  • .WithReplaceInMetadata(string field, string regex, string replacement)
  • .WithConcatPlaylist(string policy = "always")
  • .WithFFmpegLocation(string? ffmpegPath)
  • .WithConvertSubtitles(string format = "none")
  • .WithConvertThumbnails(string format = "jpg")
  • .WithSplitChapters() => AddFlag("--split-chapters")
  • .WithRemoveChapters(string regex)
  • .WithForceKeyframesAtCuts()
  • .WithUsePostProcessor(PostProcessors postProcessor, string? postProcessorArgs = null)

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 ...


πŸ”„ 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

  • ClipMate MAUI downloader
  • Windows GUI downloader
  • Console examples

🀝 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

πŸ‘₯ Contributors

Thanks to all contributors ❀️

About

A .NET wrapper for the yt-dlp command-line tool, providing a fluent interface to build and execute commands for downloading videos, audio, subtitles, thumbnails, and more from YouTube and other supported platforms.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages