Use redirection instead of streaming
This might solve some issues with clients that don't get the file type and size and don't know what to do? Also, we're not longer involved in the download, yay! (For now.)
This commit is contained in:
parent
1ab89f87c4
commit
a4546c1641
32
src/lib.rs
32
src/lib.rs
|
@ -7,19 +7,16 @@
|
|||
)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use std::process::Stdio;
|
||||
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use reqwest::Url;
|
||||
use rocket::fairing::AdHoc;
|
||||
use rocket::response::stream::ReaderStream;
|
||||
use rocket::response::Redirect;
|
||||
use rocket::serde::{Deserialize, Serialize};
|
||||
use rocket::{get, routes, Build, Responder, Rocket, State};
|
||||
use rss::extension::itunes::ITunesItemExtensionBuilder;
|
||||
use rss::{
|
||||
CategoryBuilder, ChannelBuilder, EnclosureBuilder, GuidBuilder, ImageBuilder, ItemBuilder,
|
||||
};
|
||||
use tokio::process::{ChildStdout, Command};
|
||||
|
||||
pub(crate) mod mixcloud;
|
||||
|
||||
|
@ -127,27 +124,12 @@ async fn feed(username: &str, config: &State<Config>) -> Option<RssFeed> {
|
|||
}
|
||||
|
||||
/// Retrieves a download using youtube-dl.
|
||||
#[get("/?<backend>&<url>")]
|
||||
pub(crate) async fn download(backend: &str, url: &str) -> Option<ReaderStream![ChildStdout]> {
|
||||
let parsed_url = Url::parse(url).ok()?;
|
||||
let mut cmd = Command::new("youtube-dl");
|
||||
cmd.args(&["--output", "-"])
|
||||
.arg(parsed_url.as_str())
|
||||
.stdout(Stdio::piped());
|
||||
|
||||
println!("▶️ Streaming enclosure from {parsed_url} using youtube-dl...");
|
||||
let mut child = cmd.spawn().ok()?;
|
||||
let stdout = child.stdout.take()?;
|
||||
|
||||
tokio::spawn(async move {
|
||||
let status = child
|
||||
.wait()
|
||||
.await
|
||||
.expect("child process encounterd an error");
|
||||
println!("✅ youtube-dl finished with {}", status);
|
||||
});
|
||||
|
||||
Some(ReaderStream::one(stdout))
|
||||
#[get("/?<backend>&<id>")]
|
||||
pub(crate) async fn download(backend: &str, id: &str) -> Option<Redirect> {
|
||||
match backend {
|
||||
"mixcloud" => mixcloud::redirect_url(id).await.map(Redirect::to),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets up Rocket.
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
//! It uses the Mixcloud API to retrieve the feed (user) and items (cloudcasts)).
|
||||
//! See also: <https://www.mixcloud.com/developers/>
|
||||
|
||||
use std::process::Stdio;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use reqwest::Url;
|
||||
use rocket::serde::Deserialize;
|
||||
use tokio::process::Command;
|
||||
|
||||
/// A Mixcloud user.
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -44,6 +47,9 @@ pub(crate) struct CloudcastData {
|
|||
#[derive(Debug, Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub(crate) struct Cloudcast {
|
||||
/// The key of the cloudcast.
|
||||
pub(crate) key: String,
|
||||
|
||||
/// The name of the cloudcast.
|
||||
pub(crate) name: String,
|
||||
|
||||
|
@ -80,6 +86,9 @@ pub(crate) struct Tag {
|
|||
/// The base URL for the Mixcloud API.
|
||||
const API_BASE_URL: &str = "https://api.mixcloud.com";
|
||||
|
||||
/// The base URL for downloading Mixcloud files.
|
||||
const FILES_BASE_URL: &str = "https://www.mixcloud.com";
|
||||
|
||||
/// The default bitrate used by
|
||||
const DEFAULT_BITRATE: u32 = 64 * 1024;
|
||||
|
||||
|
@ -127,3 +136,24 @@ pub(crate) async fn get_cloudcasts(username: &str) -> Option<Vec<Cloudcast>> {
|
|||
|
||||
Some(cloudcasts.data)
|
||||
}
|
||||
|
||||
/// Retrieves the redirect URL for the provided Mixcloud cloudcast key.
|
||||
pub(crate) async fn redirect_url(key: &str) -> Option<String> {
|
||||
let mut cmd = Command::new("youtube-dl");
|
||||
cmd.args(&["--format", "http"])
|
||||
.arg("--get-url")
|
||||
.arg(&format!("{FILES_BASE_URL}{key}"))
|
||||
.stdout(Stdio::piped());
|
||||
|
||||
let output = cmd.output().await.ok()?;
|
||||
if output.status.success() {
|
||||
let direct_url = String::from_utf8_lossy(&output.stdout)
|
||||
.trim_end()
|
||||
.to_owned();
|
||||
println!("🌍 Determined direct URL for {key}: {direct_url}...");
|
||||
|
||||
Some(direct_url)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue