arcly-stream 0.1.7

An open-extensible live-media streaming kernel: lock-free zero-copy frame fan-out, instant-start GOP cache, a pluggable multi-protocol ingestion layer (RTMP, RTSP, SRT, WHIP/WHEP shipped), and a feature-gated pure-Rust media plane (MPEG-TS/HLS/fMP4) — runtime, config, and metrics free.
Documentation
//! The stream bus: the live pub/sub core, plus the trait contracts that
//! decouple protocol/packager code from any concrete registry.
//!
//! `stream-center`'s protocol crates depended directly on the concrete
//! `ApplicationRegistry`. Here, ingest handlers depend on [`PublishRegistry`],
//! playback/packaging depends on [`PlaybackRegistry`], and event consumers
//! depend on [`EventBus`]. The bundled [`Engine`](crate::Engine) is one
//! implementation; a host can supply its own.

mod application;
mod events;
mod handle;

pub use application::Application;
pub use events::{StreamEvent, StreamEventKind};
pub(crate) use handle::{mono_ms, now_ms};
pub use handle::{FrameSink, Qos, StreamHandle, StreamMetadata, StreamState, Subscription};

use crate::{AppName, Result, StreamId, StreamKey};
use async_trait::async_trait;
use tokio::sync::broadcast;

/// The publish side of a stream registry: protocol *ingest* handlers depend on
/// this, never on the concrete [`Engine`](crate::Engine). Implement it to plug
/// a foreign media bus into existing protocol handlers.
#[async_trait]
pub trait PublishRegistry: Send + Sync + 'static {
    /// Claim a stream for publishing. Returns a handle the ingest loop pushes
    /// frames into. Fails with [`StreamAlreadyPublishing`] on a live duplicate,
    /// or [`PublisherLimitReached`] at capacity.
    ///
    /// [`StreamAlreadyPublishing`]: crate::StreamError::StreamAlreadyPublishing
    /// [`PublisherLimitReached`]: crate::StreamError::PublisherLimitReached
    async fn start_publish(&self, key: &StreamKey) -> Result<StreamHandle>;

    /// Release a publish session. Idempotent.
    async fn end_publish(&self, key: &StreamKey) -> Result<()>;
}

/// The playback side: HLS/DASH packagers, WebRTC SFUs, and recorders depend on
/// this to find a live stream and subscribe to its frames.
pub trait PlaybackRegistry: Send + Sync + 'static {
    /// Resolve a live stream handle, or [`StreamNotFound`].
    ///
    /// [`StreamNotFound`]: crate::StreamError::StreamNotFound
    fn get_stream(&self, key: &StreamKey) -> Result<StreamHandle>;

    /// Enumerate live stream IDs within an application.
    fn list_streams(&self, app: &AppName) -> Result<Vec<StreamId>>;
}

/// Lifecycle event subscription, decoupled from the concrete registry.
pub trait EventBus: Send + Sync + 'static {
    /// Subscribe to the [`StreamEvent`] feed for an application.
    fn subscribe_events(&self, app: &AppName) -> Result<broadcast::Receiver<StreamEvent>>;
}