Add youtube.rs for YouTube support
This commit is contained in:
62
src/input/youtube.rs
Normal file
62
src/input/youtube.rs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
//! YouTube URL 輸入
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
pub struct YouTubeInput {
|
||||||
|
url: Option<String>,
|
||||||
|
title: Option<String>,
|
||||||
|
duration: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl YouTubeInput {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
url: None,
|
||||||
|
title: None,
|
||||||
|
duration: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(&mut self, url: &str) -> Result<String> {
|
||||||
|
if !Self::is_youtube_url(url) {
|
||||||
|
anyhow::bail!("Not a valid YouTube URL");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.url = Some(url.to_string());
|
||||||
|
|
||||||
|
let info = self.get_video_info(url)?;
|
||||||
|
self.title = Some(info.0);
|
||||||
|
self.duration = Some(info.1);
|
||||||
|
|
||||||
|
Ok(url.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_youtube_url(url: &str) -> bool {
|
||||||
|
url.contains("youtube.com") || url.contains("youtu.be")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_video_info(&self, url: &str) -> Result<(String, u64)> {
|
||||||
|
let output = Command::new("yt-dlp")
|
||||||
|
.args(["--dump-json", "--no-download", url])
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
anyhow::bail!("Failed to get video info");
|
||||||
|
}
|
||||||
|
|
||||||
|
let json: serde_json::Value = serde_json::from_slice(&output.stdout)?;
|
||||||
|
let title = json["title"].as_str().unwrap_or("Unknown").to_string();
|
||||||
|
let duration = json["duration"].as_u64().unwrap_or(0);
|
||||||
|
|
||||||
|
Ok((title, duration))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_title(&self) -> Option<&str> {
|
||||||
|
self.title.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_duration(&self) -> Option<u64> {
|
||||||
|
self.duration
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user