Fix HTTP streaming lag warnings by adding TimerNode and increasing buffer

The streaming FLAC implementation was experiencing severe lag warnings
(clients skipping 700-2200 messages) because:
1. The broadcast channel capacity (512) was too small for network backpressure
2. The pipeline had no rate limiting, sending data faster than real-time

Changes:
- Increased BROADCAST_CAPACITY from 512 to 4096 (~5min buffer)
- Added TimerNode (3s lead time) to stream_block example pipeline
- Pipeline now: RadioParadiseStreamSource → TimerNode → StreamingFlacSink

This ensures data flows at real-time playback speed with sufficient
buffering for network jitter, eliminating client lag warnings.
This commit is contained in:
Claude
2025-11-11 23:15:11 +00:00
parent fe428301d0
commit 2b47f851b6

View File

@@ -6,13 +6,13 @@
//! //!
//! Architecture: //! Architecture:
//! ```text //! ```text
//! RadioParadiseStreamSource → StreamingFlacSink //! RadioParadiseStreamSource → TimerNode → StreamingFlacSink
//! ↓ //!
//! StreamHandle //! StreamHandle
//! ↓ //!
//! pmoserver (Axum) //! pmoserver (Axum)
//! ↓ //!
//! VLC / Media Player Client //! VLC / Media Player Client
//! ``` //! ```
//! //!
//! Usage: //! Usage:
@@ -33,7 +33,7 @@ use axum::{
http::{HeaderMap, StatusCode}, http::{HeaderMap, StatusCode},
response::{IntoResponse, Response}, response::{IntoResponse, Response},
}; };
use pmoaudio::AudioPipelineNode; use pmoaudio::{AudioPipelineNode, TimerNode};
use pmoaudio_ext::StreamingFlacSink; use pmoaudio_ext::StreamingFlacSink;
use pmoflac::EncoderOptions; use pmoflac::EncoderOptions;
use pmoparadise::{RadioParadiseClient, RadioParadiseStreamSource}; use pmoparadise::{RadioParadiseClient, RadioParadiseStreamSource};
@@ -183,6 +183,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
source.push_block_id(block.event); source.push_block_id(block.event);
tracing::debug!("RadioParadiseStreamSource created with block {}", block.event); tracing::debug!("RadioParadiseStreamSource created with block {}", block.event);
// Create timer node for real-time pacing (3 seconds buffer)
let mut timer = TimerNode::new(3.0);
tracing::debug!("TimerNode created with 3.0s max lead time");
// Create streaming FLAC sink // Create streaming FLAC sink
let encoder_options = EncoderOptions { let encoder_options = EncoderOptions {
compression_level: 5, compression_level: 5,
@@ -193,9 +197,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (streaming_sink, stream_handle) = StreamingFlacSink::new(encoder_options, 16); let (streaming_sink, stream_handle) = StreamingFlacSink::new(encoder_options, 16);
tracing::debug!("StreamingFlacSink created"); tracing::debug!("StreamingFlacSink created");
// Connect source → sink // Connect source → timer → sink
source.register(Box::new(streaming_sink)); timer.register(Box::new(streaming_sink));
tracing::info!("Pipeline connected: RadioParadiseStreamSource → StreamingFlacSink"); source.register(Box::new(timer));
tracing::info!("Pipeline connected: RadioParadiseStreamSource → TimerNode → StreamingFlacSink");
// ═══════════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════════
// Setup pmoserver with streaming routes // Setup pmoserver with streaming routes