Stream song #164
@@ -1011,4 +1011,46 @@ pub mod endpoint {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn stream_audio(
|
||||
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
||||
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
|
||||
) -> 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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user