use crate::bus::PublishRegistry;
use crate::frame::CodecId;
use crate::{MediaFrame, Result, StreamError};
use async_trait::async_trait;
use bytes::Bytes;
use std::path::Path;
use std::sync::Arc;
#[async_trait]
pub trait MediaSource: Send + Sync {
async fn next_frame(&mut self) -> Result<Option<MediaFrame>>;
}
#[async_trait]
pub trait MediaSink: Send + Sync {
async fn send_frame(&mut self, frame: MediaFrame) -> Result<()>;
async fn flush(&mut self) -> Result<()> {
Ok(())
}
}
#[async_trait]
pub trait ProtocolHandler: Send + Sync {
fn name(&self) -> &'static str;
async fn run(
&self,
registry: Arc<dyn PublishRegistry>,
shutdown: tokio_util::sync::CancellationToken,
) -> Result<()>;
}
#[async_trait]
pub trait StorageBackend: Send + Sync + 'static {
async fn put(&self, key: &str, data: Bytes) -> Result<()>;
async fn get(&self, key: &str) -> Result<Bytes>;
async fn delete(&self, key: &str) -> Result<()>;
async fn list(&self, prefix: &str) -> Result<Vec<String>>;
async fn exists(&self, key: &str) -> Result<bool> {
match self.get(key).await {
Ok(_) => Ok(true),
Err(StreamError::StorageNotFound(_)) => Ok(false),
Err(e) => Err(e),
}
}
async fn put_file(&self, key: &str, path: &Path) -> Result<()> {
let data = tokio::fs::read(path)
.await
.map_err(|e| StreamError::storage(format!("put_file read failed: {e}")))?;
self.put(key, Bytes::from(data)).await?;
tokio::fs::remove_file(path).await.ok();
Ok(())
}
}
#[async_trait]
impl<B: StorageBackend> StorageBackend for Arc<B> {
async fn put(&self, key: &str, data: Bytes) -> Result<()> {
(**self).put(key, data).await
}
async fn get(&self, key: &str) -> Result<Bytes> {
(**self).get(key).await
}
async fn delete(&self, key: &str) -> Result<()> {
(**self).delete(key).await
}
async fn list(&self, prefix: &str) -> Result<Vec<String>> {
(**self).list(prefix).await
}
async fn exists(&self, key: &str) -> Result<bool> {
(**self).exists(key).await
}
async fn put_file(&self, key: &str, path: &Path) -> Result<()> {
(**self).put_file(key, path).await
}
}
pub trait HwAccelBackend: Send + Sync {
fn id(&self) -> &'static str;
fn is_available(&self) -> bool;
fn supported_encoders(&self) -> &[CodecId];
fn supported_decoders(&self) -> &[CodecId];
}