Skip to content

Commit ca9da71

Browse files
committed
Allow adding additional box decoders in get_boxes
1 parent 257b5c1 commit ca9da71

9 files changed

Lines changed: 38 additions & 25 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ fn main() -> anyhow::Result<()> {
3535
let size = file.metadata()?.len();
3636

3737
// Parse all boxes without decoding
38-
let boxes = get_boxes(&mut file, size, false)?;
38+
let boxes = get_boxes(&mut file, size, false, |r| r)?;
3939
println!("Found {} top-level boxes", boxes.len());
4040

4141
// Parse with decoding for known box types
4242
let mut file = File::open("video.mp4")?;
43-
let decoded_boxes = get_boxes(&mut file, size, true)?;
43+
let decoded_boxes = get_boxes(&mut file, size, true, |r| r)?;
4444

4545
// Print decoded info for ftyp box
4646
if let Some(ftyp) = decoded_boxes.iter().find(|b| b.typ == "ftyp") {
@@ -105,7 +105,7 @@ use std::fs::File;
105105

106106
let mut file = File::open("video.mp4")?;
107107
let size = file.metadata()?.len();
108-
let boxes = get_boxes(&mut file, size, /*decode=*/ false)?;
108+
let boxes = get_boxes(&mut file, size, /*decode=*/ false, |r| r)?;
109109
println!("{} top-level boxes", boxes.len());
110110
```
111111

examples/boxes.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::env;
2+
use std::fs::File;
23

34
// Analyze an MP4 file and print the number of top-level boxes.
45
fn main() -> anyhow::Result<()> {
@@ -7,13 +8,14 @@ fn main() -> anyhow::Result<()> {
78
eprintln!("Usage: {} <file>", args[0]);
89
std::process::exit(1);
910
}
11+
let path = &args[1];
1012

11-
let mut file = std::fs::File::open(&args[1])?;
13+
let mut file = File::open(path)?;
1214
let size = file.metadata()?.len();
1315

14-
// Use the get_boxes function from the mp4box crate
15-
let boxes = mp4box::get_boxes(&mut file, size, /*decode=*/ false)?;
16-
println!("Top-level boxes: {}", boxes.len());
16+
let boxes = mp4box::get_boxes(&mut file, size, /*decode=*/ false, |r| r)?;
17+
18+
let _json = serde_json::to_string_pretty(&boxes)?;
1719

1820
// Example: print types of all top-level boxes
1921
let media_info = boxes.iter().find(|b| b.typ == "moov").and_then(|moov_box| {
@@ -38,4 +40,4 @@ fn main() -> anyhow::Result<()> {
3840
}
3941

4042
Ok(())
41-
}
43+
}

examples/samples.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() -> anyhow::Result<()> {
1414
let size = file.metadata()?.len();
1515

1616
// Parse with decoding enabled to get structured data
17-
let boxes = get_boxes(&mut file, size, true)?;
17+
let boxes = get_boxes(&mut file, size, true, |r| r)?;
1818

1919
println!("Analyzing sample tables in: {}", path);
2020
analyze_sample_tables(&boxes, 0);

src/api.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub struct Box {
3131
pub uuid: Option<String>,
3232
/// Version field for FullBox types
3333
pub version: Option<u8>,
34-
/// Flags field for FullBox types
34+
/// Flags field for FullBox types
3535
pub flags: Option<u32>,
3636
/// Box classification: "leaf", "full", "container", or "unknown"
3737
pub kind: String,
@@ -49,7 +49,7 @@ pub struct Box {
4949
///
5050
/// # Parameters
5151
/// - `r`: A reader that implements `Read + Seek` (e.g., `File`, `Cursor<Vec<u8>>`)
52-
/// - `size`: The total size of the MP4 data to parse (typically file length)
52+
/// - `size`: The total size of the MP4 data to parse (typically file length)
5353
/// - `decode`: Whether to decode known box types using the default registry
5454
///
5555
/// # Returns
@@ -63,10 +63,15 @@ pub struct Box {
6363
///
6464
/// let mut file = File::open("video.mp4")?;
6565
/// let size = file.metadata()?.len();
66-
/// let boxes = get_boxes(&mut file, size, true)?; // decode known boxes
66+
/// let boxes = get_boxes(&mut file, size, true, |r| r)?; // decode known boxes
6767
/// # Ok::<(), anyhow::Error>(())
6868
/// ```
69-
pub fn get_boxes<R: Read + Seek>(r: &mut R, size: u64, decode: bool) -> anyhow::Result<Vec<Box>> {
69+
pub fn get_boxes<R: Read + Seek>(
70+
r: &mut R,
71+
size: u64,
72+
decode: bool,
73+
additional_registrations: impl FnOnce(crate::Registry) -> crate::Registry,
74+
) -> anyhow::Result<Vec<Box>> {
7075
// let mut f = File::open(&path)?;
7176
// let file_len = f.metadata()?.len();
7277

@@ -114,7 +119,7 @@ pub fn get_boxes<R: Read + Seek>(r: &mut R, size: u64, decode: bool) -> anyhow::
114119
}
115120

116121
// build JSON tree
117-
let reg = default_registry();
122+
let reg = additional_registrations(default_registry());
118123
let json_boxes = boxes
119124
.iter()
120125
.map(|b| build_box(r, b, decode, &reg))

src/bin/mp4info.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ fn main() -> anyhow::Result<()> {
7272
let mut file = std::fs::File::open(&path)?;
7373
let size = file.metadata()?.len();
7474

75-
let boxes = get_boxes(&mut file, size, /*decode=*/ true)?;
75+
let boxes = get_boxes(&mut file, size, /*decode=*/ true, |r| r)?;
7676
let mut info = MediaInfo {
7777
file: path.display().to_string(),
7878
major_brand: None,

src/bin/mp4samples.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fn main() -> Result<()> {
6060
let size = file.metadata()?.len();
6161

6262
// Parse with structured decoding enabled
63-
let boxes = get_boxes(&mut file, size, true)?;
63+
let boxes = get_boxes(&mut file, size, true, |r| r)?;
6464

6565
if args.tables {
6666
print_sample_tables(&boxes, &args)?;

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@
3131
//! let size = file.metadata()?.len();
3232
//!
3333
//! // Parse structure only
34-
//! let boxes = get_boxes(&mut file, size, false)?;
34+
//! let boxes = get_boxes(&mut file, size, false, |r| r)?;
3535
//! println!("Found {} top-level boxes", boxes.len());
3636
//!
3737
//! // Parse with decoding of known box types
3838
//! let mut file = File::open("video.mp4")?;
39-
//! let decoded_boxes = get_boxes(&mut file, size, true)?;
39+
//! let decoded_boxes = get_boxes(&mut file, size, true, |r| r)?;
4040
//!
4141
//! // Print file type info
4242
//! if let Some(ftyp) = decoded_boxes.iter().find(|b| b.typ == "ftyp") {

src/samples.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,13 @@ pub fn track_samples_from_reader<R: Read + Seek>(
153153
let file_size = reader.seek(SeekFrom::End(0))?;
154154
reader.seek(SeekFrom::Start(0))?;
155155

156-
let boxes = crate::get_boxes(&mut reader, file_size, /*decode=*/ true)
157-
.context("getting boxes from reader")?;
156+
let boxes = crate::get_boxes(
157+
&mut reader,
158+
file_size,
159+
/*decode=*/ true,
160+
|registry| registry,
161+
)
162+
.context("getting boxes from reader")?;
158163

159164
let mut result = Vec::new();
160165

@@ -270,7 +275,7 @@ pub fn track_samples_from_path(path: impl AsRef<Path>) -> anyhow::Result<Vec<Tra
270275
/// fn main() -> Result<(), Box<dyn std::error::Error>> {
271276
/// let mut file = File::open("video.mp4")?;
272277
/// let file_size = file.metadata()?.len();
273-
/// let boxes = get_boxes(&mut file, file_size, true)?;
278+
/// let boxes = get_boxes(&mut file, file_size, true, |r| r)?;
274279
///
275280
/// // Find moov box and extract samples from each track
276281
/// for moov_box in boxes.iter().filter(|b| b.typ == "moov") {

tests/json_roundtrip.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ fn analyze_and_serialize_to_json() {
4343
let path = make_minimal_mp4_file();
4444

4545
// Parse structure (no decoders needed here)
46-
let mut file = File::open(&path).expect("open temp file failed");
47-
let size = file.metadata().expect("metadata failed").len();
48-
let boxes = get_boxes(&mut file, size, /*decode=*/ false).expect("get_boxes failed");
46+
let mut file = File::open(&path).expect("Failed to open test file");
47+
let size = file.metadata().expect("Failed to get metadata").len();
4948

50-
// We at least expect the first box to be our ftyp.
49+
let boxes = get_boxes(&mut file, size, /*decode=*/ false, |r| r).expect("get_boxes failed");
50+
51+
// Serialize to JSON
5152
assert!(!boxes.is_empty(), "no boxes returned from get_boxes");
5253
assert_eq!(boxes[0].typ, "ftyp");
5354

0 commit comments

Comments
 (0)