use anyhow::{anyhow, Result}; use log::{error, info}; use std::ffi::OsStr; use tokio::process; pub struct YtDlpWrapper { use_aria2c: bool, } impl YtDlpWrapper { pub async fn new() -> Option { if !command_exists("yt-dlp").await { return None; } Some(Self { use_aria2c: command_exists("aria2c").await, }) } pub async fn spawn_yt_dlp_task(&self, url: &str) -> Result<()> { info!("Spawning yt-dlp task for URL: {}", url); let mut builder = process::Command::new("yt-dlp"); if self.use_aria2c { builder.arg("--downloader=aria2c"); } let mut yt_dlp_cmd = builder.arg(url).spawn()?; let status = yt_dlp_cmd.wait().await?; if status.success() { info!("yt-dlp task completed successfully"); Ok(()) } else { error!("yt-dlp task failed with status: {}", status); Err(anyhow!("yt-dlp task failed")) } } } async fn command_exists>(name: S) -> bool { process::Command::new(name) .arg("--version") .output() .await .map(|output| output.status.success()) .unwrap_or(false) }