every.channel/third_party/iroh-live/iroh-live/examples/push.rs
2026-02-15 16:17:27 -05:00

71 lines
1.9 KiB
Rust

use std::{path::PathBuf, pin::Pin};
use clap::Parser;
use iroh::EndpointId;
use iroh_live::LiveNode;
use moq_lite::BroadcastProducer;
use n0_error::Result;
use tokio::io::AsyncRead;
use tracing::warn;
mod common;
use self::common::import::{Import, ImportType, transcode};
#[derive(Debug, Parser)]
struct Cli {
#[clap(short, long)]
target: EndpointId,
#[clap(short, long, default_value = "anon/bbb")]
path: String,
/// The format of the input media.
#[clap(long, value_enum, default_value_t = ImportType::Cmaf)]
format: ImportType,
/// Input file.
#[clap(short, long)]
file: Option<PathBuf>,
/// Transcode the video with ffmpeg.
#[clap(long)]
transcode: bool,
}
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt::init();
let cli = Cli::parse();
let node = LiveNode::spawn_from_env().await?;
let session = node.live.connect(cli.target).await?;
let mut input: Pin<Box<dyn AsyncRead + Send + 'static>> = match (cli.file, cli.transcode) {
(Some(path), true) => Box::pin(transcode(path.clone(), cli.format).await?),
(Some(path), false) => Box::pin(tokio::fs::File::open(path).await?),
(None, false) => Box::pin(tokio::io::stdin()),
(None, true) => panic!("transcoding stdin is not supported"),
};
let broadcast = BroadcastProducer::default();
session.publish(cli.path, broadcast.consume());
let import = async move {
let mut import = Import::new(broadcast.into(), cli.format);
import.init_from(&mut input).await?;
import.read_from(&mut input).await?;
n0_error::Ok(())
};
tokio::pin!(import);
tokio::select! {
res = &mut import => {
if let Err(err) = res {
warn!("Import failed: {err:#}");
}
}
_ = tokio::signal::ctrl_c() => {}
};
drop(import);
node.shutdown().await?;
Ok(())
}