mirror of
https://github.com/alfg/mp4-rust.git
synced 2024-12-22 12:06:33 +00:00
Make the example tolerant of videos missing parts (#5)
* Make the example tolerant of videos missing parts Some videos are missing certain parts that the example was assuming would be present. This change makes all such access conditional on the parts being present. Also added the display of the box version and the creation time in a human-readable format. This serves to demonstrate the logic for converting the MP4 epoch (1904-01-01) to Unix epoch (1970-01-01). * Show creation time as Unix time only
This commit is contained in:
parent
e875c7da44
commit
958304a9b2
1 changed files with 60 additions and 24 deletions
|
@ -1,8 +1,8 @@
|
|||
extern crate mp4;
|
||||
|
||||
use mp4::TrackType;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use mp4::{TrackType};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
@ -17,44 +17,71 @@ fn main() {
|
|||
|
||||
// Print results.
|
||||
println!("File:");
|
||||
println!(" file size: {}", bmff.size);
|
||||
println!(" brands: {:?} {:?}\n", bmff.ftyp.major_brand, bmff.ftyp.compatible_brands);
|
||||
println!(" file size: {}", bmff.size);
|
||||
println!(
|
||||
" brands: {:?} {:?}\n",
|
||||
bmff.ftyp.major_brand, bmff.ftyp.compatible_brands
|
||||
);
|
||||
|
||||
println!("Movie:");
|
||||
println!(" duration: {:?}", moov.mvhd.duration);
|
||||
println!(" timescale: {:?}\n", moov.mvhd.timescale);
|
||||
println!(" version: {:?}", moov.mvhd.version);
|
||||
println!(
|
||||
" creation time: {}",
|
||||
creation_time(moov.mvhd.creation_time)
|
||||
);
|
||||
println!(" duration: {:?}", moov.mvhd.duration);
|
||||
println!(" timescale: {:?}\n", moov.mvhd.timescale);
|
||||
|
||||
println!("Found {} Tracks", moov.traks.len());
|
||||
for trak in moov.traks.iter() {
|
||||
let tkhd = trak.tkhd.as_ref().unwrap();
|
||||
let mdia = trak.mdia.as_ref().unwrap();
|
||||
let hdlr = mdia.hdlr.as_ref().unwrap();
|
||||
let mdhd = mdia.mdhd.as_ref().unwrap();
|
||||
let stts= mdia.minf.as_ref().unwrap()
|
||||
.stbl.as_ref().unwrap()
|
||||
.stts.as_ref().unwrap();
|
||||
|
||||
println!("Track: {:?}", tkhd.track_id);
|
||||
println!(" flags: {:?}", tkhd.flags);
|
||||
println!(" id: {:?}", tkhd.track_id);
|
||||
println!(" type: {:?}", get_handler_type(hdlr.handler_type.value.as_ref()));
|
||||
println!(" duration: {:?}", tkhd.duration);
|
||||
println!(" language: {:?}", mdhd.language_string);
|
||||
|
||||
println!(" media:");
|
||||
println!(" sample count: {:?}", stts.sample_counts[0]);
|
||||
println!(" timescale: {:?}", mdhd.timescale);
|
||||
println!(" duration: {:?} (media timescale units)", mdhd.duration);
|
||||
println!(" duration: {:?} (ms)", get_duration_ms(mdhd.duration, mdhd.timescale));
|
||||
if tkhd.width != 0 && tkhd.height != 0 {
|
||||
println!(" width: {:?}", tkhd.width);
|
||||
println!(" height: {:?}", tkhd.height);
|
||||
}
|
||||
if get_handler_type(hdlr.handler_type.value.as_ref()) == TrackType::Video {
|
||||
println!(" frame rate: (computed): {:?}", get_framerate(&stts.sample_counts, mdhd.duration, mdhd.timescale));
|
||||
if let Some(ref mdia) = trak.mdia {
|
||||
let hdlr = mdia.hdlr.as_ref().unwrap();
|
||||
let mdhd = mdia.mdhd.as_ref().unwrap();
|
||||
let stts = mdia
|
||||
.minf
|
||||
.as_ref()
|
||||
.map(|m| m.stbl.as_ref().map(|s| s.stts.as_ref()).flatten())
|
||||
.flatten();
|
||||
|
||||
println!(
|
||||
" type: {:?}",
|
||||
get_handler_type(hdlr.handler_type.value.as_ref())
|
||||
);
|
||||
println!(" language: {:?}", mdhd.language_string);
|
||||
|
||||
println!(" media:");
|
||||
if let Some(ref s) = stts {
|
||||
println!(" sample count: {:?}", s.sample_counts[0]);
|
||||
}
|
||||
println!(" timescale: {:?}", mdhd.timescale);
|
||||
println!(
|
||||
" duration: {:?} (media timescale units)",
|
||||
mdhd.duration
|
||||
);
|
||||
println!(
|
||||
" duration: {:?} (ms)",
|
||||
get_duration_ms(mdhd.duration, mdhd.timescale)
|
||||
);
|
||||
if get_handler_type(hdlr.handler_type.value.as_ref()) == TrackType::Video {
|
||||
if let Some(ref s) = stts {
|
||||
println!(
|
||||
" frame rate: (computed): {:?}",
|
||||
get_framerate(&s.sample_counts, mdhd.duration, mdhd.timescale)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
println!("Usage: mp4info <filename>");
|
||||
}
|
||||
|
@ -81,4 +108,13 @@ fn get_framerate(sample_counts: &Vec<u32>, duration: u32, timescale: u32) -> Str
|
|||
let sc = (sample_counts[0] as f64) * 1000.0;
|
||||
let ms = (duration as f64 / timescale as f64) * 1000.0;
|
||||
return format!("{:.2}", sc / ms.floor());
|
||||
}
|
||||
}
|
||||
|
||||
fn creation_time(creation_time: u32) -> u32 {
|
||||
// convert from MP4 epoch (1904-01-01) to Unix epoch (1970-01-01)
|
||||
if creation_time >= 2082844800 {
|
||||
creation_time - 2082844800
|
||||
} else {
|
||||
creation_time
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue