Files
bili-sync-ai/src/downloader.rs

74 lines
2.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use std::path::Path;
use futures_util::StreamExt;
use reqwest::Method;
use tokio::fs::{self, File};
use tokio::io;
use crate::bilibili::Client;
use crate::Result;
pub struct Downloader {
client: Client,
}
impl Downloader {
// Downloader 使用带有默认 Header 的 Client 构建
// 拿到 url 后下载文件不需要任何 cookie 作为身份凭证
// 但如果不设置默认 Header下载时会遇到 403 Forbidden 错误
pub fn new(client: Client) -> Self {
Self { client }
}
pub async fn fetch(&self, url: &str, path: &Path) -> Result<()> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).await?;
}
let mut file = File::create(path).await?;
let mut res = self
.client
.request(Method::GET, url, None)
.send()
.await?
.bytes_stream();
while let Some(item) = res.next().await {
io::copy(&mut item?.as_ref(), &mut file).await?;
}
Ok(())
}
pub async fn merge(
&self,
video_path: &Path,
audio_path: &Path,
output_path: &Path,
) -> Result<()> {
let output = tokio::process::Command::new("ffmpeg")
.args([
"-i",
video_path.to_str().unwrap(),
"-i",
audio_path.to_str().unwrap(),
"-c",
"copy",
output_path.to_str().unwrap(),
])
.output()
.await?;
if !output.status.success() {
return match String::from_utf8(output.stderr) {
Ok(err) => Err(err.into()),
_ => Err("ffmpeg error".into()),
};
}
let _ = fs::remove_file(video_path).await;
let _ = fs::remove_file(audio_path).await;
Ok(())
}
}
impl Default for Downloader {
fn default() -> Self {
Self::new(Client::new())
}
}