pub struct Audio<S> { /* private fields */ }Expand description
Generic audio pipeline running in a separate thread.
Provides a simple interface for reading decoded PCM audio, compatible with cpal and rodio audio backends.
§Example
use kithara_audio::{Audio, AudioConfig};
use kithara_hls::{Hls, HlsConfig};
use kithara_stream::Stream;
let config = AudioConfig::<Hls>::new(hls_config)
.hint("mp3");
let audio = Audio::<Stream<Hls>>::new(config).await?;
// Get audio format
let spec = audio.spec();
println!("{}Hz, {} channels", spec.sample_rate, spec.channels);
// Read PCM samples
let mut buf = [0.0f32; 1024];
loop {
match audio.read(&mut buf)? {
ReadOutcome::Frames { count, .. } => play_samples(&buf[..count]),
ReadOutcome::Eof { .. } => break,
}
}Implementations§
Source§impl<S> Audio<S>
impl<S> Audio<S>
Sourcepub fn abr_handle(&self) -> Option<AbrHandle>
pub fn abr_handle(&self) -> Option<AbrHandle>
Runtime ABR handle (cloned from the stream’s source at
construction). Some for adaptive sources (HLS), None for
file/non-adaptive sources.
Sourcepub fn current_variant(&self) -> Option<VariantInfo>
pub fn current_variant(&self) -> Option<VariantInfo>
Current variant’s metadata. Pulled live from the ABR peer on
every call — no caching — so the UI never sees a stale label
after an ABR switch. None for non-adaptive sources or peers
that have not yet registered variants.
Sourcepub fn duration(&self) -> Option<Duration>
pub fn duration(&self) -> Option<Duration>
Get total duration of the audio stream.
Returns None for streaming sources where duration is unknown.
Sourcepub fn is_preloaded(&self) -> bool
pub fn is_preloaded(&self) -> bool
Whether non-blocking recv is active.
Returns false after seek() until preload() is called again.
Sourcepub fn metadata(&self) -> &TrackMetadata
pub fn metadata(&self) -> &TrackMetadata
Get track metadata (title, artist, album, artwork).
Sourcepub fn position(&self) -> Duration
pub fn position(&self) -> Duration
Get current playback position.
Calculated from samples read since last seek plus the seek base.
Sourcepub fn preload(&mut self) -> Result<(), DecodeError>
pub fn preload(&mut self) -> Result<(), DecodeError>
Enable non-blocking mode for read() and prime the first chunk.
After calling this, read() returns immediately from buffered
data without blocking. Must be called after construction so
that fill_buffer() calls from JS (via requestAnimationFrame)
don’t hang.
Returns Err(DecodeError) if the producer channel closed
during the initial fill_buffer (e.g. upstream decoder
reported TrackStep::Failed before any data). Natural EOF
encountered during preload is not surfaced here — the
subsequent read() / next_chunk() call will report
ReadOutcome::Eof.
§Errors
Returns DecodeError::Io if the producer channel closed during preload.
Sourcepub fn read(&mut self, buf: &mut [f32]) -> Result<ReadOutcome, DecodeError>
pub fn read(&mut self, buf: &mut [f32]) -> Result<ReadOutcome, DecodeError>
Read decoded PCM samples into buffer.
Samples are interleaved f32 (e.g., LRLRLR for stereo).
Returns ReadOutcome::Frames with a non-zero count when the
reader produced data, ReadOutcome::Pending with a typed
PendingReason when the reader is alive but produced no
frames this tick (buffering, seek-in-progress), or
ReadOutcome::Eof on natural end-of-stream. Decoder /
channel failures surface as DecodeError via the Err arm.
§Errors
Returns DecodeError::Io when the producer channel closed /
reported a failure (ConsumerPhase::Failed) before any frames
could be flushed.
Sourcepub fn seek(&mut self, position: Duration) -> Result<SeekOutcome, DecodeError>
pub fn seek(&mut self, position: Duration) -> Result<SeekOutcome, DecodeError>
Seek to position in the audio stream.
This method never blocks. Seek coordination flows entirely through
Timeline atomics (FLUSH_START/FLUSH_STOP pattern). The worker thread reads
the seek target and epoch from Timeline and applies the seek.
Returns SeekOutcome::Landed when the reader is now parked
at position; SeekOutcome::PastEof when the target is
beyond a known duration() (the subsequent read returns
ReadOutcome::Eof).
§Errors
Propagated from the underlying stream (currently infallible at
this layer — the worker thread surfaces errors lazily via
FetchKind::Failure, which becomes Err from a subsequent
read() / next_chunk()).
Source§impl<T> Audio<Stream<T>>where
T: StreamType<Events = EventBus>,
Specialized impl for Stream-based audio pipelines.
impl<T> Audio<Stream<T>>where
T: StreamType<Events = EventBus>,
Specialized impl for Stream-based audio pipelines.
Provides async constructor that creates Stream internally.
Uses StreamAudioSource for automatic format change detection on ABR switch.
Sourcepub async fn new(config: AudioConfig<T>) -> Result<Self, DecodeError>
pub async fn new(config: AudioConfig<T>) -> Result<Self, DecodeError>
Create audio pipeline from AudioConfig.
This is the target API for Stream sources.
Uses StreamAudioSource for automatic decoder recreation on format change.
§Errors
Returns DecodeError if the stream cannot be created, the initial probe
fails, or the decoder cannot be initialized.
§Example
let config = AudioConfig::<Hls>::new(hls_config);
let audio = Audio::new(config).await?;
sink.append(audio);Sourcepub fn event_bus(&self) -> &EventBus
pub fn event_bus(&self) -> &EventBus
Get a reference to the underlying EventBus.
Useful for passing to downstream components that also publish events.
Sourcepub fn events(&self) -> EventReceiver
pub fn events(&self) -> EventReceiver
Subscribe to unified events via the EventBus.
Returns a receiver for all events published to the bus.