ClipMate - MAUI.NET App - Download
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.
- 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
IAsyncDisposablesupport
Major redesign for reliability and modern .NET usage.
- Immutable fluent builder API
IAsyncDisposableimplemented- Thread‑safe usage
- Simplified event handling
- Improved metadata probing
- Better cancellation support
- Safer command building
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");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");await using var ytdlp = new Ytdlp()
.WithExtractAudio("mp3")
.WithOutputFolder("./audio");
await ytdlp.DownloadAsync(url);ytdlp.OnProgressDownload += (s, e) =>
{
Console.WriteLine($"{e.Percent:F1}% {e.Speed} ETA {e.ETA}");
};
ytdlp.OnCompleteDownload += (s, msg) =>
{
Console.WriteLine($"Finished: {msg}");
};await using var ytdlp = new Ytdlp();
var metadata = await ytdlp.GetMetadataAsync(url);
Console.WriteLine(metadata?.Title);
Console.WriteLine(metadata?.Duration);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);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);| Event | Description |
|---|---|
OnProgressDownload |
Download progress |
OnProgressMessage |
Informational messages |
OnCompleteDownload |
File finished |
OnPostProcessingComplete |
Post‑processing finished |
OnOutputMessage |
Raw output line |
OnErrorMessage |
Error message |
OnCommandCompleted |
Process finished |
WithOutputFolder()
WithTempFolder()
WithHomeFolder()
WithOutputTemplate()
WithFFmpegLocation()
WithFormat()
With720pOrBest()
WithExtractAudio()
GetMetadataAsync()
GetBestAudioFormatIdAsync()
GetBestVideoFormatIdAsync()
GetAvailableFormatsAsync()
WithEmbedMetadata()
WithEmbedThumbnail()
WithEmbedSubtitles()
WithSubtitles()
WithConcurrentFragments()
WithSponsorblockRemove()
WithProxy()
WithCookiesFile()
WithCookiesFromBrowser()
AddFlag()
AddOption()
AddCustomCommand()
v3 introduces a new immutable fluent API.
Old mutable commands were removed.
var ytdlp = new Ytdlp();
await ytdlp
.SetFormat("best")
.SetOutputFolder("./downloads")
.ExecuteAsync(url);await using var ytdlp = new Ytdlp()
.WithFormat("best")
.WithOutputFolder("./downloads");
await ytdlp.DownloadAsync(url);| v2 | v3 |
|---|---|
SetFormat() |
WithFormat() |
SetOutputFolder() |
WithOutputFolder() |
SetTempFolder() |
WithTempFolder() |
SetOutputTemplate() |
WithOutputTemplate() |
SetFFMpegLocation() |
WithFFmpegLocation() |
ExtractAudio() |
WithExtractAudio() |
UseProxy() |
WithProxy() |
Every WithXxx() call returns a new instance.
var baseYtdlp = new Ytdlp();
var download = baseYtdlp
.WithFormat("best")
.WithOutputFolder("./downloads");Attach events to the configured instance.
var download = baseYtdlp.WithFormat("best");
download.OnProgressDownload += ...Use await using for automatic cleanup.
await using var ytdlp = new Ytdlp();- ClipMate MAUI downloader
- Windows GUI downloader
- Console examples
Contributions are welcome!
Open issues or PRs on GitHub.
MIT License
See:
https://github.com/manusoft/yt-dlp-wrapper/blob/master/LICENSE.txt
Manoj Babu ManuHub

