Fix stream_block buffer cycling issue with FFPlay
PROBLEM: When streaming Radio Paradise blocks via HTTP using FFPlay, the buffer would cycle between 0KB and ~130KB approximately once per second, causing audio dropouts and interruptions. VLC worked fine, but FFPlay was sensitive to the burst transmission pattern. ROOT CAUSE: In StreamingFlacSink::broadcast_flac_stream(), the broadcaster was reading 8KB (8192 bytes) at a time from the FLAC encoder and sending the entire chunk at once to all HTTP clients. This created a "burst" pattern: - Read 8KB from encoder - Send entire 8KB chunk to all clients - Sleep if ahead of real-time pacing - Repeat FFPlay's buffer would fill rapidly with each 8KB burst, then drain completely before the next burst arrived, causing the observed cycling behavior. SOLUTION: Reduced the HTTP broadcast buffer size from 8KB to 512 bytes in StreamingFlacSink::broadcast_flac_stream(). This creates a much smoother, more continuous data flow that FFPlay can handle without buffer cycling. The 512-byte buffer size is: - Small enough to prevent burst transmission - Large enough to avoid excessive overhead - Sufficient for smooth streaming with real-time pacing CHANGES: - Restore stream_block.rs example from git history - Restore StreamingFlacSink and StreamingOggFlacSink from git history - Add "streaming" feature to pmoaudio-ext - Reduce broadcast buffer from 8192 to 512 bytes - Update pmoparadise to use pmoaudio-ext streaming feature TESTING: Test with FFPlay to verify smooth buffering: ```bash cargo run --example stream_block --features full -- 0 # In another terminal: ffplay http://localhost:8080/test/stream ``` Watch the "aq=" value in FFPlay output. It should now remain stable instead of cycling between 0KB and 130KB.
This commit is contained in:
@@ -16,6 +16,11 @@ pmometadata = { path = "../pmometadata", optional = true }
|
||||
# Optional dependencies for playlist integration
|
||||
pmoplaylist = { path = "../pmoplaylist", optional = true }
|
||||
pmocache = { path = "../pmocache", optional = true }
|
||||
|
||||
# Optional dependencies for streaming feature
|
||||
bytes = { version = "1.5", optional = true }
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
|
||||
# Async runtime
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
tokio-util = { version = "0.7" }
|
||||
@@ -28,4 +33,5 @@ tracing = "0.1"
|
||||
default = []
|
||||
cache-sink = ["dep:pmoaudiocache", "dep:pmoflac", "dep:pmometadata"]
|
||||
playlist = ["cache-sink", "dep:pmoplaylist", "dep:pmocache"]
|
||||
all = ["cache-sink", "playlist"]
|
||||
streaming = ["dep:pmoflac", "dep:pmometadata", "dep:bytes", "dep:serde"]
|
||||
all = ["cache-sink", "playlist", "streaming"]
|
||||
|
||||
@@ -9,3 +9,15 @@ mod flac_cache_sink;
|
||||
|
||||
#[cfg(feature = "cache-sink")]
|
||||
pub use flac_cache_sink::{FlacCacheSink, FlacCacheSinkStats, TrackStats};
|
||||
|
||||
#[cfg(feature = "streaming")]
|
||||
mod streaming_flac_sink;
|
||||
|
||||
#[cfg(feature = "streaming")]
|
||||
mod streaming_ogg_flac_sink;
|
||||
|
||||
#[cfg(feature = "streaming")]
|
||||
pub use streaming_flac_sink::{StreamingFlacSink, StreamHandle, MetadataSnapshot};
|
||||
|
||||
#[cfg(feature = "streaming")]
|
||||
pub use streaming_ogg_flac_sink::{StreamingOggFlacSink, OggFlacStreamHandle};
|
||||
|
||||
1071
pmoaudio-ext/src/sinks/streaming_flac_sink.rs
Normal file
1071
pmoaudio-ext/src/sinks/streaming_flac_sink.rs
Normal file
File diff suppressed because it is too large
Load Diff
1067
pmoaudio-ext/src/sinks/streaming_ogg_flac_sink.rs
Normal file
1067
pmoaudio-ext/src/sinks/streaming_ogg_flac_sink.rs
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user