use anyhow::Result;
use nab::stream::backend::{StreamBackend, StreamConfig, StreamProgress};
use nab::stream::backends::FfmpegBackend;
use tokio::io::AsyncWriteExt;
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt::init();
let args: Vec<String> = std::env::args().collect();
if args.len() < 2 {
eprintln!("Usage: {} <manifest_url>", args[0]);
eprintln!("Example: {} https://example.com/master.m3u8", args[0]);
std::process::exit(1);
}
let manifest_url = &args[1];
let backend = FfmpegBackend::new()?;
if !backend.check_available().await {
eprintln!("Error: ffmpeg not found in PATH");
eprintln!("Install with: brew install ffmpeg (macOS) or apt install ffmpeg (Linux)");
std::process::exit(1);
}
println!("Streaming {manifest_url} via ffmpeg...");
let config = StreamConfig {
quality: nab::stream::StreamQuality::Best,
headers: std::collections::HashMap::new(),
cookies: None,
};
let progress_cb = Box::new(|p: StreamProgress| {
#[allow(clippy::cast_precision_loss)] let mb = p.bytes_downloaded as f64 / 1_000_000.0;
eprintln!(
"\rDownloaded: {mb:.2} MB | Elapsed: {:.1}s",
p.elapsed_seconds
);
});
let mut stdout = tokio::io::stdout();
backend
.stream_to(manifest_url, &config, &mut stdout, Some(progress_cb))
.await?;
stdout.flush().await?;
eprintln!("\nStreaming complete!");
Ok(())
}