diff --git a/rust-libs/ease-client-backend/src/controllers/playlist.rs b/rust-libs/ease-client-backend/src/controllers/playlist.rs index 60f125e..c220c2c 100644 --- a/rust-libs/ease-client-backend/src/controllers/playlist.rs +++ b/rust-libs/ease-client-backend/src/controllers/playlist.rs @@ -75,7 +75,7 @@ pub(crate) async fn cc_create_playlist( if let Some(cx) = cx.upgrade() { for id in music_ids { cx.player_delegate() - .request_total_duration(id, cx.asset_server().serve_music_url(id)); + .request_total_duration(id, cx.asset_server().serve_music_meta_url(id)); } } }) @@ -121,7 +121,7 @@ pub(crate) async fn cu_add_musics_to_playlist( if let Some(cx) = cx.upgrade() { for id in music_ids { cx.player_delegate() - .request_total_duration(id, cx.asset_server().serve_music_url(id)); + .request_total_duration(id, cx.asset_server().serve_music_meta_url(id)); } } }) diff --git a/rust-libs/ease-client-backend/src/services/server/asset.rs b/rust-libs/ease-client-backend/src/services/server/asset.rs index d9d0bd0..8f0326a 100644 --- a/rust-libs/ease-client-backend/src/services/server/asset.rs +++ b/rust-libs/ease-client-backend/src/services/server/asset.rs @@ -37,7 +37,7 @@ pub struct AssetServer { source_id_alloc: AtomicU64, chunks_cache: RwLock>>>, server_handle: RwLock>>, - db: RwLock)>>, + db: RwLock>)>>, } fn parse_request_range(headers: &HeaderMap) -> Option { @@ -103,6 +103,20 @@ async fn handle_music_download( } } +#[axum::debug_handler] +async fn handle_music_meta( + axum::extract::State(cx): axum::extract::State, + axum::extract::Path(id): axum::extract::Path, +) -> axum::response::Response { + let id = MusicId::wrap(id); + + if let Some(cx) = cx.upgrade() { + cx.asset_server().handle_got_stream_meta(&cx, id).await + } else { + StatusCode::NOT_FOUND.into_response() + } +} + impl Drop for AssetServer { fn drop(&mut self) { { @@ -134,6 +148,12 @@ impl AssetServer { format!("http://127.0.0.1:{}/music/{}", port, id) } + pub fn serve_music_meta_url(&self, id: MusicId) -> String { + let port = self.port.load(std::sync::atomic::Ordering::Relaxed); + let id = *id.as_ref(); + format!("http://127.0.0.1:{}/music-meta/{}", port, id) + } + pub fn start(&self, cx: &BackendContext, dir: String) { self.start_db(cx, dir); self.start_server(cx); @@ -164,13 +184,14 @@ impl AssetServer { .set_cache_size(20 << 20) .create(&p) .expect("failed to init database"); - *w = Some((p, Arc::new(db))); + *w = Some((p, Arc::new(RwLock::new(db)))); } } fn start_server(&self, cx: &BackendContext) { let router_svc = axum::Router::new() .route("/music/:id", axum::routing::get(handle_music_download)) + .route("/music-meta/:id", axum::routing::get(handle_music_meta)) .with_state(cx.weak()) .into_make_service(); @@ -267,6 +288,36 @@ impl AssetServer { return (status, headers, body).into_response(); } + async fn handle_got_stream_meta( + self: &Arc, + cx: &BackendContext, + id: MusicId, + ) -> Response { + let file = load_asset(&cx, DataSourceKey::Music { id }, 0).await; + if file.is_err() { + return StatusCode::INTERNAL_SERVER_ERROR.into_response(); + } + let file = file.unwrap(); + if file.is_none() { + return StatusCode::NOT_FOUND.into_response(); + } + let file = file.unwrap(); + + let mut headers = HeaderMap::new(); + headers.append( + header::CONTENT_TYPE, + HeaderValue::from_str("application/octet-stream").unwrap(), + ); + if let Some(size) = file.size() { + headers.append( + header::CONTENT_LENGTH, + HeaderValue::from_str(size.to_string().as_str()).unwrap(), + ); + } + let body = axum::body::StreamBody::new(file.into_stream()); + return (headers, body).into_response(); + } + async fn build_chunks_reader( self: &Arc, cx: &BackendContext, diff --git a/rust-libs/ease-client-backend/src/services/server/chunks.rs b/rust-libs/ease-client-backend/src/services/server/chunks.rs index 82a58ec..0e088e8 100644 --- a/rust-libs/ease-client-backend/src/services/server/chunks.rs +++ b/rust-libs/ease-client-backend/src/services/server/chunks.rs @@ -26,7 +26,7 @@ pub enum AssetChunkData { #[derive(Clone)] pub struct AssetChunksSource { key: String, - db: Arc, + db: Arc>, } pub struct AssetChunksReader { @@ -47,7 +47,7 @@ pub struct AssetChunks { } impl AssetChunksSource { - pub fn new(source_id: u64, db: Arc) -> Self { + pub fn new(source_id: u64, db: Arc>) -> Self { Self { key: source_id.to_string(), db, @@ -59,7 +59,7 @@ impl AssetChunksSource { } fn read_chunk(&self, index: u64) -> BResult> { - let db = self.db.begin_read()?; + let db = self.db.read().unwrap().begin_read()?; let table_definition = Self::def(&self.key); let table = db.open_table(table_definition); if let Err(e) = &table { @@ -82,7 +82,7 @@ impl AssetChunksSource { } fn add_chunk(&self, index: u64, chunk: AssetChunkData) -> BResult<()> { - let w_txn = self.db.begin_write()?; + let w_txn = self.db.read().unwrap().begin_write()?; let table_definition = Self::def(&self.key); { let mut table = w_txn.open_table(table_definition)?; @@ -96,7 +96,7 @@ impl AssetChunksSource { } fn remove(&self) -> BResult<()> { - let w_txn = self.db.begin_write()?; + let w_txn = self.db.read().unwrap().begin_write()?; let table_definition = Self::def(&self.key); w_txn.delete_table(table_definition)?; w_txn.commit()?;