ClipMate - MAUI.NET App - Download
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. Ytdlp.NET simplifies interaction with yt-dlp by offering a strongly-typed API, progress parsing, and event-based feedback for real-time monitoring.
- Fluent Interface: Build
yt-dlpcommands with a chainable, intuitive API. - Progress Tracking: Parse and monitor download progress, errors, and completion events.
- Batch Downloading: Download multiple videos or playlists in a single operation.
- Format Selection: Easily select video/audio formats, resolutions, and other options.
- Event-Driven: Subscribe to events for progress, errors, and command completion.
- Customizable: Support for custom
yt-dlpoptions and advanced configurations. - Cross-Platform: Compatible with Windows, macOS, and Linux (requires
yt-dlpinstalled).
- .NET: Requires .NET 8.0 or later.
- yt-dlp: The
yt-dlpcommand-line tool must be installed and accessible in your system’s PATH or specified explicitly.- Install
yt-dlpvia pip:pip install -U yt-dlp
- Verify installation:
yt-dlp --version
- Install
- FFmpeg (optional): Required for certain operations like merging formats or extracting audio. Install via your package manager or download from FFmpeg.org.
Download a video with the best quality to a specified folder:
using System;
using System.Threading.Tasks;
using YtdlpDotNet;
class Program
{
static async Task Main()
{
var ytdlp = new Ytdlp("yt-dlp", new ConsoleLogger());
// Subscribe to progress events
ytdlp.OnProgressMessage += (sender, message) => Console.WriteLine($"Progress: {message}");
ytdlp.OnCompleteDownload += (sender, message) => Console.WriteLine($"Complete: {message}");
ytdlp.OnErrorMessage += (sender, message) => Console.WriteLine($"Error: {message}");
try
{
await ytdlp
.SetFormat("b") // Best quality
.SetOutputFolder("./downloads")
.DownloadThumbnails() // Include thumbnails
.ExecuteAsync("https://www.youtube.com/watch?v=RGg-Qx1rL9U");
}
catch (YtdlpException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
private class ConsoleLogger : ILogger
{
public void Log(LogType type, string message)
{
Console.WriteLine($"[{type}] {message}");
}
}
}Download multiple videos in a batch:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using YtdlpDotNet;
class Program
{
static async Task Main()
{
var ytdlp = new Ytdlp("yt-dlp", new ConsoleLogger());
// Subscribe to events
ytdlp.OnProgressMessage += (sender, message) => Console.WriteLine($"Progress: {message}");
ytdlp.OnCompleteDownload += (sender, message) => Console.WriteLine($"Complete: {message}");
ytdlp.OnErrorMessage += (sender, message) => Console.WriteLine($"Error: {message}");
var videoUrls = new List<string>
{
"https://www.youtube.com/watch?v=RGg-Qx1rL9U",
"https://www.youtube.com/watch?v=iBVxogg5QwE"
};
try
{
await ytdlp
.SetFormat("b")
.SetOutputFolder("./batch_downloads")
.ExecuteBatchAsync(videoUrls);
}
catch (YtdlpException ex)
{
Console.WriteLine($"Failed to batch download: {ex.Message}");
}
}
private class ConsoleLogger : ILogger
{
public void Log(LogType type, string message)
{
Console.WriteLine($"[{type}] {message}");
}
}
}Retrieve available formats for a video:
using System;
using System.Threading.Tasks;
using YtdlpDotNet;
class Program
{
static async Task Main()
{
var ytdlp = new Ytdlp("yt-dlp", new ConsoleLogger());
try
{
var formats = await ytdlp.GetAvailableFormatsAsync("https://www.youtube.com/watch?v=RGg-Qx1rL9U");
foreach (var format in formats)
{
Console.WriteLine($"ID: {format.ID}, Extension: {format.Extension}, Resolution: {format.Resolution}, VCodec: {format.VCodec}");
}
}
catch (YtdlpException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
private class ConsoleLogger : ILogger
{
public void Log(LogType type, string message)
{
Console.WriteLine($"[{type}] {message}");
}
}
}Extract audio in MP3 format and embed metadata:
using System;
using System.Threading.Tasks;
using YtdlpDotNet;
class Program
{
static async Task Main()
{
var ytdlp = new Ytdlp("yt-dlp", new ConsoleLogger());
try
{
await ytdlp
.ExtractAudio("mp3")
.EmbedMetadata()
.SetOutputFolder("./audio_downloads")
.ExecuteAsync("https://www.youtube.com/watch?v=RGg-Qx1rL9U");
}
catch (YtdlpException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
private class ConsoleLogger : ILogger
{
public void Log(LogType type, string message)
{
Console.WriteLine($"[{type}] {message}");
}
}
}-
Custom yt-dlp Path: Specify a custom path to the
yt-dlpexecutable if it’s not in the system PATH:var ytdlp = new Ytdlp("/path/to/yt-dlp");
-
Custom Logger: Implement a custom
ILoggerfor logging:public class CustomLogger : ILogger { public void Log(LogType type, string message) { // Custom logging logic (e.g., write to file or logging framework) Console.WriteLine($"[{type}] {message}"); } } var ytdlp = new Ytdlp("yt-dlp", new CustomLogger());
-
Event Subscriptions: Subscribe to events for real-time feedback:
ytdlp.OnProgressDownload += (sender, args) => Console.WriteLine($"Progress: {args.Percent}% of {args.Size}"); ytdlp.OnError += (message) => Console.WriteLine($"Error: {message}"); ytdlp.OnCommandCompleted += (success, message) => Console.WriteLine($"Command: {message}");
Ytdlp.NET supports a wide range of yt-dlp options, including:
--extract-audio,--audio-format--format,--playlist-items--write-subs,--write-thumbnail--live-from-start,--download-sections--user-agent,--cookies,--referer- And more (see the
Ytdlpclass for full list).
Use AddCustomCommand for unsupported options, ensuring they are valid yt-dlp commands.
The library throws YtdlpException for errors during execution. Always wrap calls in a try-catch block:
try
{
await ytdlp.ExecuteAsync("https://www.youtube.com/watch?v=invalid");
}
catch (YtdlpException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}- Thread Safety: The
Ytdlp.NETclass is not thread-safe. Create a new instance for concurrent operations. - Performance: Batch downloads are executed sequentially. For parallel downloads, manage multiple
Ytdlp.NETinstances. - Version Compatibility: Tested with
yt-dlpversion 2025.06.30 and later. RunGetVersionAsyncto verify:string version = await ytdlp.GetVersionAsync(); Console.WriteLine($"yt-dlp version: {version}");
Contributions are welcome! Please submit issues or pull requests to the GitHub repository. Ensure code follows the project’s style guidelines and includes unit tests.
This project is licensed under the MIT License. See the LICENSE file for details.
This library is licensed under the MIT License. See LICENSE for more information.

