From 5d11bf9c78f73dc9fb65606f094296d2f1d90fa9 Mon Sep 17 00:00:00 2001 From: Alf Date: Tue, 7 Jan 2020 21:34:01 -0800 Subject: [PATCH] Basic example of parsing mp4 atom boxes in rust. --- .gitignore | 5 +++++ Cargo.lock | 6 ++++++ Cargo.toml | 9 ++++++++ src/main.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..250314e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/target +**/*.rs.bk +*.exe +*.pdb +*.mp4 diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..d013301 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "mp4" +version = "0.1.0" + diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..799be7e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "mp4" +version = "0.1.0" +authors = ["Alf "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..3c65da4 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,60 @@ +use std::io::prelude::*; +use std::io::{BufReader, Read, SeekFrom}; +use std::fs::File; +use std::convert::TryInto; + +// struct Box { +// name: String, +// size: u32, +// offset: u32, +// } + +fn main() -> std::io::Result<()> { + + // Using BufReader. + let mut f = File::open("tears-of-steel-2s.mp4")?; + let filesize = f.metadata().unwrap().len(); + println!("{:?}", filesize); + let mut reader = BufReader::new(f); + + let mut offset = 0u64; + + while offset < filesize { + + // reader.seek(SeekFrom::Current(40 + 2872360)); + reader.seek(SeekFrom::Current(offset as i64)); + + let mut buf = [0u8;8]; + let n = reader.read(&mut buf); + + let s = buf[0..4].try_into().unwrap(); + let size = u32::from_be_bytes(s); + + let t = buf[4..8].try_into().unwrap(); + let typ = match std::str::from_utf8(t) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; + + // Exit loop if size is 0. + if size == 0 { break; } + + // println!("{}", buf.len()); + // println!("{:?}", buf); + println!("{:?}", size); + println!("{:?}", typ); + + // This will find all boxes, including nested boxes. + // let mut offset = match size { + // 1 => 4 + 4 + 8, + // _ => 4 + 4, + // }; + // assert!(offset <= size); + + offset = (size - 8) as u64; + println!("skip {:?}\n", offset); + } + + println!("done"); + Ok(()) +} \ No newline at end of file