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:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user