use std::net::SocketAddr;
use std::time::Duration;
use anyhow::Context;
use axum::http::Method;
use hang::moq_net;
use hang::moq_net::AsPath;
use crate::moq::notify_ready;
#[derive(clap::Args, Clone)]
pub struct ImportArgs {
pub playlist: String,
}
#[derive(clap::Args, Clone)]
pub struct ExportArgs {
#[arg(long, default_value = "[::]:8089")]
pub listen: SocketAddr,
#[command(flatten)]
pub tls: moq_native::tls::Server,
#[arg(long, default_value = "500ms", value_parser = humantime::parse_duration)]
pub part_target: Duration,
#[arg(long, default_value = "16s", value_parser = humantime::parse_duration)]
pub window: Duration,
#[arg(long = "latency-max", default_value = "10s", value_parser = humantime::parse_duration)]
pub latency_max: Duration,
#[command(flatten)]
pub cors: crate::web::Cors,
}
pub async fn import(origin: &moq_net::OriginProducer, name: String, playlist: String) -> anyhow::Result<()> {
let mut producer = moq_net::Broadcast::new().produce();
anyhow::ensure!(
origin.publish_broadcast(&name, producer.consume()),
"failed to publish broadcast"
);
let catalog = moq_mux::catalog::Producer::new(&mut producer)?;
let mut importer = moq_hls::import::Import::new(producer, catalog, moq_hls::import::Config::new(playlist))?;
tracing::info!(%name, "importing HLS");
importer.init().await?;
notify_ready();
Ok(importer.run().await?)
}
pub async fn export(origin: moq_net::OriginConsumer, args: ExportArgs, name: String) -> anyhow::Result<()> {
let scoped = origin
.scope(&[name.as_path()])
.with_context(|| format!("failed to scope origin to broadcast `{name}`"))?;
let config = moq_hls::export::Config {
part_target: args.part_target,
window: args.window,
latency: args.latency_max,
..Default::default()
};
let server = moq_hls::Server::new(scoped, config);
let app = server.router().layer(args.cors.layer([Method::GET])?);
let tls = if args.tls.cert.is_empty() && args.tls.generate.is_empty() {
None
} else {
let alpn = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
Some(args.tls.server_config(alpn)?)
};
let listener = moq_native::bind::tcp(args.listen)?;
tracing::info!(listen = %args.listen, "serving HLS");
notify_ready();
crate::web::serve(listener, app, tls).await
}