From a1ff05ef6f30c422291d3f0f8a10c13ca9b5542f Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Sun, 27 Jul 2025 12:53:13 -0400 Subject: [PATCH] Added endpoint to stream songs --- src/callers/song.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/callers/song.rs b/src/callers/song.rs index b752536..9825f38 100644 --- a/src/callers/song.rs +++ b/src/callers/song.rs @@ -1011,4 +1011,46 @@ pub mod endpoint { } } } + + + pub async fn stream_audio( + axum::Extension(pool): axum::Extension, + axum::extract::Path(id): axum::extract::Path, + ) -> impl IntoResponse { + match super::song_db::get_song(&pool, &id).await { + Ok(song) => { + let song_path = song.song_path().unwrap(); + let path = std::path::Path::new(&song_path); + + if !path.starts_with(&song.directory) || !path.exists() { + return Err((axum::http::StatusCode::NOT_FOUND, "File not found")); + } + + let file = match tokio::fs::File::open(&path).await { + Ok(file) => file, + Err(_) => return Err((axum::http::StatusCode::NOT_FOUND, "File not found")), + }; + + let file_size = match file.metadata().await { + Ok(meta) => meta.len(), + Err(_) => return Err((axum::http::StatusCode::INTERNAL_SERVER_ERROR, "Could not read file")), + }; + + let mime = mime_guess::from_path(&path).first_or_octet_stream(); + let stream = tokio_util::io::ReaderStream::new(file); + + let rep = axum::response::Response::builder() + .header("content-type", mime.to_string()) + .header("accept-ranges", "bytes") + .header("content-length", file_size.to_string()) + .body(axum::body::Body::from_stream(stream)) + .unwrap(); + + Ok(rep) + } + Err(_err) => { + return Err((axum::http::StatusCode::INTERNAL_SERVER_ERROR, "Could not find file")); + } + } + } }