mirror of
https://github.com/alfg/mp4-rust.git
synced 2024-06-02 13:39:54 +00:00
Refactor BMFF
This commit is contained in:
parent
928fa66cf0
commit
75d5599a94
|
@ -10,23 +10,19 @@ fn main() {
|
|||
let filename = &args[1];
|
||||
let f = File::open(filename).unwrap();
|
||||
|
||||
let bmff = mp4::read_mp4(f).unwrap();
|
||||
let bmff = mp4::BMFF::read_from_file(f).unwrap();
|
||||
let moov = bmff.moov.unwrap();
|
||||
|
||||
// Print results.
|
||||
println!("File:");
|
||||
println!(" file size: {}", bmff.size);
|
||||
println!(
|
||||
" brands: {:?} {:?}\n",
|
||||
bmff.ftyp.major_brand, bmff.ftyp.compatible_brands
|
||||
);
|
||||
println!(" size: {}", bmff.size);
|
||||
println!(" brands: {:?} {:?}\n",
|
||||
bmff.ftyp.major_brand, bmff.ftyp.compatible_brands);
|
||||
|
||||
println!("Movie:");
|
||||
println!(" version: {:?}", moov.mvhd.version);
|
||||
println!(
|
||||
" creation time: {}",
|
||||
creation_time(moov.mvhd.creation_time)
|
||||
);
|
||||
println!(" creation time: {}",
|
||||
creation_time(moov.mvhd.creation_time));
|
||||
println!(" duration: {:?}", moov.mvhd.duration);
|
||||
println!(" timescale: {:?}\n", moov.mvhd.timescale);
|
||||
|
||||
|
@ -50,10 +46,8 @@ fn main() {
|
|||
.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!(" type: {:?}",
|
||||
get_handler_type(hdlr.handler_type.value.as_ref()));
|
||||
println!(" language: {:?}", mdhd.language);
|
||||
|
||||
println!(" media:");
|
||||
|
@ -61,20 +55,15 @@ fn main() {
|
|||
println!(" sample count: {:?}", s.entries[0].sample_count);
|
||||
}
|
||||
println!(" timescale: {:?}", mdhd.timescale);
|
||||
println!(
|
||||
" duration: {:?} (media timescale units)",
|
||||
mdhd.duration
|
||||
);
|
||||
println!(
|
||||
" duration: {:?} (ms)",
|
||||
get_duration_ms(mdhd.duration, 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()) == mp4::TrackType::Video {
|
||||
if let Some(ref s) = stts {
|
||||
println!(
|
||||
" frame rate: (computed): {:?}",
|
||||
get_framerate(s.entries[0].sample_count, mdhd.duration, mdhd.timescale)
|
||||
);
|
||||
println!(" frame rate: (computed): {:?}",
|
||||
get_framerate(s.entries[0].sample_count,
|
||||
mdhd.duration, mdhd.timescale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
96
src/lib.rs
96
src/lib.rs
|
@ -1,4 +1,4 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek};
|
||||
use std::io::{BufReader, Read, Seek, SeekFrom};
|
||||
use std::fs::File;
|
||||
use std::convert::TryInto;
|
||||
|
||||
|
@ -26,56 +26,58 @@ pub struct BMFF {
|
|||
}
|
||||
|
||||
impl BMFF {
|
||||
fn new() -> BMFF {
|
||||
pub fn new() -> BMFF {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_mp4(f: File) -> Result<BMFF> {
|
||||
pub fn read_from_file(f: File) -> Result<BMFF> {
|
||||
let size = f.metadata()?.len();
|
||||
let mut reader = BufReader::new(f);
|
||||
|
||||
// Open file and read boxes.
|
||||
let bmff = read_boxes(f)?;
|
||||
let mut bmff = BMFF::new();
|
||||
bmff.size = bmff.read(&mut reader, size)?;
|
||||
|
||||
Ok(bmff)
|
||||
}
|
||||
|
||||
fn read_boxes(f: File) -> Result<BMFF> {
|
||||
let filesize = f.metadata()?.len();
|
||||
let mut reader = BufReader::new(f);
|
||||
let mut bmff = BMFF::new();
|
||||
bmff.size = filesize;
|
||||
|
||||
let mut current = reader.seek(SeekFrom::Current(0))?;
|
||||
while current < filesize {
|
||||
// Get box header.
|
||||
let header = BoxHeader::read(&mut reader)?;
|
||||
let BoxHeader{ name, size } = header;
|
||||
|
||||
// Match and parse the atom boxes.
|
||||
match name {
|
||||
BoxType::FtypBox => {
|
||||
let ftyp = FtypBox::read_box(&mut reader, size)?;
|
||||
bmff.ftyp = ftyp;
|
||||
}
|
||||
BoxType::FreeBox => {
|
||||
skip_box(&mut reader, size)?;
|
||||
}
|
||||
BoxType::MdatBox => {
|
||||
skip_box(&mut reader, size)?;
|
||||
}
|
||||
BoxType::MoovBox => {
|
||||
let moov = MoovBox::read_box(&mut reader, size)?;
|
||||
bmff.moov = Some(moov);
|
||||
}
|
||||
BoxType::MoofBox => {
|
||||
skip_box(&mut reader, size)?;
|
||||
}
|
||||
_ => {
|
||||
// XXX warn!()
|
||||
skip_box(&mut reader, size)?;
|
||||
}
|
||||
}
|
||||
current = reader.seek(SeekFrom::Current(0))?;
|
||||
Ok(bmff)
|
||||
}
|
||||
|
||||
pub fn read<R: Read + Seek>(
|
||||
&mut self,
|
||||
reader: &mut BufReader<R>,
|
||||
size: u64
|
||||
) -> Result<u64> {
|
||||
let start = reader.seek(SeekFrom::Current(0))?;
|
||||
let mut current = start;
|
||||
while current < size {
|
||||
// Get box header.
|
||||
let header = BoxHeader::read(reader)?;
|
||||
let BoxHeader{ name, size: s } = header;
|
||||
|
||||
// Match and parse the atom boxes.
|
||||
match name {
|
||||
BoxType::FtypBox => {
|
||||
let ftyp = FtypBox::read_box(reader, s)?;
|
||||
self.ftyp = ftyp;
|
||||
}
|
||||
BoxType::FreeBox => {
|
||||
skip_box(reader, s)?;
|
||||
}
|
||||
BoxType::MdatBox => {
|
||||
skip_box(reader, s)?;
|
||||
}
|
||||
BoxType::MoovBox => {
|
||||
let moov = MoovBox::read_box(reader, s)?;
|
||||
self.moov = Some(moov);
|
||||
}
|
||||
BoxType::MoofBox => {
|
||||
skip_box(reader, s)?;
|
||||
}
|
||||
_ => {
|
||||
// XXX warn!()
|
||||
skip_box(reader, s)?;
|
||||
}
|
||||
}
|
||||
current = reader.seek(SeekFrom::Current(0))?;
|
||||
}
|
||||
Ok(current - start)
|
||||
}
|
||||
Ok(bmff)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::fs::File;
|
|||
fn test_read_mp4() {
|
||||
let filename = "tests/samples/minimal.mp4";
|
||||
let f = File::open(filename).unwrap();
|
||||
let bmff = mp4::read_mp4(f).unwrap();
|
||||
let bmff = mp4::BMFF::read_from_file(f).unwrap();
|
||||
|
||||
assert_eq!(2591, bmff.size);
|
||||
|
||||
|
@ -35,4 +35,4 @@ fn test_read_mp4() {
|
|||
assert_eq!(moov.mvhd.timescale, 1000);
|
||||
assert_eq!(moov.traks.len(), 2);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue