initial prototype

This commit is contained in:
2025-07-19 15:35:04 +02:00
commit 673a0967b2
8 changed files with 1948 additions and 0 deletions

41
src/streamer.rs Normal file
View File

@@ -0,0 +1,41 @@
use crate::state::AppState;
use axum::{body::Body, extract::State, response::Response};
use std::sync::Arc;
use tokio_stream::Stream;
pub async fn stream_handler(State(state): State<Arc<AppState>>) -> Response {
let stream = create_chunk_stream(state);
let body = Body::from_stream(stream);
Response::builder()
.header("Content-Type", "audio/mpeg")
.header("Cache-Control", "no-cache")
.body(body)
.unwrap()
}
fn create_chunk_stream(
state: Arc<AppState>,
) -> impl Stream<Item = Result<bytes::Bytes, std::io::Error>> {
async_stream::stream! {
let mut position = 0;
loop {
// Send available chunks
let chunks = state.chunks.read().await;
while position < chunks.len() {
yield Ok(chunks[position].clone());
position += 1;
}
drop(chunks);
// Exit if download complete and all chunks sent
if state.is_complete().await && position >= state.chunk_count().await {
break;
}
// Wait for new chunks
state.notify.notified().await;
}
}
}