1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
use tokio::process::Command; use failure::format_err; #[derive(Debug, Clone, Default)] pub struct YoutubeDl; impl YoutubeDl { pub async fn get_audio_stream_url(&self, id: &str) -> Result<String, failure::Error> { let output = Command::new("youtube-dl").arg("-g").arg("-f").arg("bestaudio").arg(format!("https://www.youtube.com/watch?v={}", id)).output().await?; if !output.status.success() { let err = String::from_utf8(output.stderr)?; return Err(format_err!("{}", err)); } let url = String::from_utf8(output.stdout)?.trim().to_owned(); Ok(url) } } #[cfg(test)] mod test { use super::YoutubeDl; #[tokio::test] async fn stream_audio() { let youtube_dl = YoutubeDl::default(); let video_ids = vec![ "yfqTCWepx4U", "ZGIfJHeZKKE", "btecuyQKH-E", "uM7JjfHDuFM", "BgWpK28dt6I", "8xe6nLVXEC0", "O3WKbJLai1g" ]; for video_id in video_ids { let url = youtube_dl.get_audio_stream_url(video_id).await; println!("{:?}", url); assert!(url.is_ok()); } } }