use std::time::Duration;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::prelude::*;
use anyhow::{Result, Context};
use clap::Arg;
use pssh_box::{find_iter, from_buffer, pprint};
#[tokio::main]
async fn main() -> Result<()> {
let fmt_layer = tracing_subscriber::fmt::layer()
.compact();
let filter_layer = EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new("info,reqwest=warn"))
.unwrap();
tracing_subscriber::registry()
.with(filter_layer)
.with(fmt_layer)
.init();
let clap = clap::Command::new("fetch-pssh-data")
.about("Parse DRM initialization data (a PSSH box) in an MP4 container.")
.version(clap::crate_version!())
.arg(Arg::new("url")
.value_name("URL")
.required(true)
.num_args(1)
.index(1)
.help("The URL of the MP4 initialization segment."));
let matches = clap.get_matches();
let url = matches.get_one::<String>("url").unwrap();
let client = reqwest::Client::builder()
.timeout(Duration::new(30, 0))
.build()
.context("creating HTTP client")?;
let req = client.get(url)
.header("Accept", "video/*");
if let Ok(mut resp) = req.send().await {
let mut chunk_counter = 0;
let mut segment_first_bytes = Vec::<u8>::new();
while let Ok(Some(chunk)) = resp.chunk().await {
segment_first_bytes.append(&mut chunk.to_vec());
chunk_counter += 1;
if chunk_counter > 20 {
break;
}
}
let positions: Vec<usize> = find_iter(&segment_first_bytes).collect();
for pos in positions {
let boxes = from_buffer(&segment_first_bytes[pos..]).unwrap();
for bx in boxes {
pprint(&bx);
}
}
}
Ok(())
}