An async, feature-rich Rust wrapper for yt-dlp.
- Async API: Built on top of
tokio. - Builder Pattern: Fluent API for configuring downloads.
- Structured Metadata: Extract video info as JSON via
serde. - Custom Arguments: Passthrough for any
yt-dlpflag.
You must have yt-dlp installed and available in your PATH.
use ytd_rs::YtDlp;
use std::path::PathBuf;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ytd = YtDlp::new("https://www.youtube.com/watch?v=uTO0KnDsVH0")
.output_dir(PathBuf::from("./downloads"))
.arg("--quiet");
let result = ytd.download().await?;
println!("Output: {}", result.output());
Ok(())
}use ytd_rs::YtDlp;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
YtDlp::new("https://www.youtube.com/watch?v=uTO0KnDsVH0")
.extract_audio_only("mp3")
.download()
.await?;
Ok(())
}use ytd_rs::YtDlp;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ytd = YtDlp::new("https://www.youtube.com/watch?v=uTO0KnDsVH0");
let infos = ytd.get_info().await?;
for info in infos {
println!("Title: {}", info.title);
println!("Duration: {:?}", info.duration);
}
Ok(())
}If you want to track the progress of a long-running download, you can stream the standard output line-by-line:
use ytd_rs::YtDlp;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut process = YtDlp::new("https://www.youtube.com/watch?v=uTO0KnDsVH0")
.download_process()
.await?;
while let Some(line) = process.next_line().await? {
// e.g. "[download] 10.0% of 50.00MiB at 1.00MiB/s ETA 00:50"
println!("yt-dlp output: {}", line);
}
process.wait().await?;
println!("Download finished successfully!");
Ok(())
}If you are building an application like a Discord bot, you often want to stream the raw binary audio data chunk-by-chunk to an engine like ffmpeg or songbird instead of downloading the whole file first.
use ytd_rs::YtDlp;
use tokio::io::AsyncReadExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut stream = YtDlp::new("https://www.youtube.com/watch?v=uTO0KnDsVH0")
.best_audio()
.download_to_stream()
.await?;
let mut buffer = [0; 1024];
loop {
let bytes_read = stream.stdout().read(&mut buffer).await?;
if bytes_read == 0 { break; } // EOF
// Process your raw chunk of audio data here
// e.g., send it to your bot's audio engine
// send_to_audio_engine(&buffer[..bytes_read]);
}
stream.wait().await?;
Ok(())
}Alternative for Discord Bots: You can also use .get_info().await? to extract the direct media URL (infos[0].url) and pass that directly to your audio engine, which saves bot bandwidth!
MIT