1
0
Fork 0
mirror of https://github.com/alfg/mp4-rust.git synced 2024-12-22 12:06:33 +00:00
mp4-rust/examples/mp4dump.rs

143 lines
3.7 KiB
Rust
Raw Normal View History

use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::Path;
use mp4::{Mp4Box, Result};
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
println!("Usage: mp4dump <filename>");
std::process::exit(1);
}
if let Err(err) = dump(&args[1]) {
let _ = writeln!(io::stderr(), "{}", err);
}
}
fn dump<P: AsRef<Path>>(filename: &P) -> Result<()> {
let f = File::open(filename)?;
let boxes = get_boxes(f)?;
// print out boxes
for b in boxes.iter() {
println!("[{}] size={} {}", b.name, b.size, b.summary);
}
Ok(())
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Box {
name: String,
size: u64,
summary: String,
indent: u32,
}
fn get_boxes(file: File) -> Result<Vec<Box>> {
let size = file.metadata()?.len();
let reader = BufReader::new(file);
let mp4 = mp4::Mp4Reader::read_header(reader, size)?;
// collect known boxes
let mut boxes = vec![
build_box(&mp4.ftyp),
build_box(&mp4.moov),
build_box(&mp4.moov.mvhd),
];
if let Some(ref mvex) = &mp4.moov.mvex {
boxes.push(build_box(mvex));
if let Some(mehd) = &mvex.mehd {
boxes.push(build_box(mehd));
}
boxes.push(build_box(&mvex.trex));
}
// trak.
for track in mp4.tracks().values() {
boxes.push(build_box(&track.trak));
boxes.push(build_box(&track.trak.tkhd));
if let Some(ref edts) = track.trak.edts {
boxes.push(build_box(edts));
if let Some(ref elst) = edts.elst {
boxes.push(build_box(elst));
}
}
// trak.mdia
let mdia = &track.trak.mdia;
boxes.push(build_box(mdia));
boxes.push(build_box(&mdia.mdhd));
boxes.push(build_box(&mdia.hdlr));
boxes.push(build_box(&track.trak.mdia.minf));
// trak.mdia.minf
let minf = &track.trak.mdia.minf;
if let Some(ref vmhd) = &minf.vmhd {
boxes.push(build_box(vmhd));
}
if let Some(ref smhd) = &minf.smhd {
boxes.push(build_box(smhd));
}
// trak.mdia.minf.stbl
let stbl = &track.trak.mdia.minf.stbl;
boxes.push(build_box(stbl));
boxes.push(build_box(&stbl.stsd));
if let Some(ref avc1) = &stbl.stsd.avc1 {
boxes.push(build_box(avc1));
}
2020-09-02 03:49:55 +00:00
if let Some(ref hev1) = &stbl.stsd.hev1 {
boxes.push(build_box(hev1));
}
if let Some(ref mp4a) = &stbl.stsd.mp4a {
boxes.push(build_box(mp4a));
}
boxes.push(build_box(&stbl.stts));
if let Some(ref ctts) = &stbl.ctts {
boxes.push(build_box(ctts));
}
if let Some(ref stss) = &stbl.stss {
boxes.push(build_box(stss));
}
boxes.push(build_box(&stbl.stsc));
boxes.push(build_box(&stbl.stsz));
if let Some(ref stco) = &stbl.stco {
boxes.push(build_box(stco));
}
if let Some(ref co64) = &stbl.co64 {
boxes.push(build_box(co64));
}
}
// If fragmented, add moof boxes.
for moof in mp4.moofs.iter() {
boxes.push(build_box(moof));
boxes.push(build_box(&moof.mfhd));
for traf in moof.trafs.iter() {
boxes.push(build_box(traf));
boxes.push(build_box(&traf.tfhd));
if let Some(ref trun) = &traf.trun {
boxes.push(build_box(trun));
}
}
}
Ok(boxes)
}
fn build_box<M: Mp4Box + std::fmt::Debug>(m: &M) -> Box {
Box {
name: m.box_type().to_string(),
size: m.box_size(),
summary: m.summary().unwrap(),
indent: 0,
}
}