diff --git a/src-tauri/src/player.rs b/src-tauri/src/player.rs index d69bf89..f96c60e 100644 --- a/src-tauri/src/player.rs +++ b/src-tauri/src/player.rs @@ -575,7 +575,6 @@ impl Pipeline { let spawn = |codec: &str| -> Result { command_hidden(&ffmpeg) .arg("-nostdin") - .arg("-re") .arg("-hide_banner") .arg("-loglevel") .arg("warning") @@ -636,7 +635,7 @@ impl Pipeline { }); } - let (tx, rx) = mpsc::sync_channel::>(256); + let (tx, rx) = mpsc::sync_channel::>(1024); *self.cast_tx.lock().unwrap() = Some(tx); let writer_join = std::thread::spawn(move || { @@ -666,7 +665,7 @@ impl Pipeline { std::thread::spawn(move || { use std::io::Read; let mut ffmpeg_out = stdout; - let mut buffer = vec![0u8; 8192]; + let mut buffer = vec![0u8; 16384]; loop { if reader_stop.load(Ordering::SeqCst) { @@ -725,7 +724,7 @@ impl Pipeline { // Spawn handler for each client let stop_flag = Arc::clone(&server_stop_clone); - let (client_tx, client_rx) = mpsc::sync_channel::>(256); + let (client_tx, client_rx) = mpsc::sync_channel::>(1024); // Subscribe this client clients_server.lock().unwrap().push(client_tx); @@ -743,11 +742,28 @@ impl Pipeline { // Send HTTP response headers let mut writer = stream; - let headers = b"HTTP/1.1 200 OK\r\nContent-Type: audio/mpeg\r\nConnection: close\r\nCache-Control: no-cache\r\n\r\n"; + let headers = b"HTTP/1.1 200 OK\r\nContent-Type: audio/mpeg\r\nConnection: close\r\nCache-Control: no-cache\r\nAccept-Ranges: none\r\nicy-br: 128\r\n\r\n"; if writer.write_all(headers).is_err() { return; } + // Pre-buffer before streaming to prevent initial stuttering + let mut prebuffer = Vec::with_capacity(65536); + let prebuffer_start = std::time::Instant::now(); + while prebuffer.len() < 32768 && prebuffer_start.elapsed() < Duration::from_millis(500) { + match client_rx.recv_timeout(Duration::from_millis(50)) { + Ok(chunk) => prebuffer.extend_from_slice(&chunk), + _ => break, + } + } + + // Send prebuffered data + if !prebuffer.is_empty() { + if writer.write_all(&prebuffer).is_err() { + return; + } + } + // Stream chunks to client loop { if stop_flag.load(Ordering::SeqCst) {