1
0
Fork 0
mirror of https://github.com/alfg/mp4-rust.git synced 2024-06-11 09:29:21 +00:00

Move Mp4Reader to reader.rs

This commit is contained in:
Ian Jun 2020-07-31 16:25:25 +09:00
parent db3defdd7c
commit c0fdbcf688
2 changed files with 122 additions and 117 deletions

View file

@ -1,15 +1,16 @@
use std::fmt;
use std::io::{Seek, SeekFrom, Read};
use std::convert::TryInto;
pub use bytes::Bytes;
mod atoms;
use crate::atoms::*;
mod error;
pub use error::Error;
mod atoms;
mod reader;
pub use reader::Mp4Reader;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, PartialEq)]
@ -47,116 +48,3 @@ impl fmt::Display for Mp4Sample {
self.bytes.len())
}
}
#[derive(Debug)]
pub struct Mp4Reader<R> {
reader: R,
pub ftyp: FtypBox,
pub moov: Option<MoovBox>,
size: u64,
}
impl<R: Read + Seek> Mp4Reader<R> {
pub fn new(reader: R) -> Self {
Mp4Reader {
reader,
ftyp: FtypBox::default(),
moov: None,
size: 0,
}
}
pub fn size(&self) -> u64 {
self.size
}
pub fn read(&mut self, size: u64) -> Result<()> {
let start = self.reader.seek(SeekFrom::Current(0))?;
let mut current = start;
while current < size {
// Get box header.
let header = BoxHeader::read(&mut self.reader)?;
let BoxHeader{ name, size: s } = header;
// Match and parse the atom boxes.
match name {
BoxType::FtypBox => {
let ftyp = FtypBox::read_box(&mut self.reader, s)?;
self.ftyp = ftyp;
}
BoxType::FreeBox => {
skip_box(&mut self.reader, s)?;
}
BoxType::MdatBox => {
skip_box(&mut self.reader, s)?;
}
BoxType::MoovBox => {
let moov = MoovBox::read_box(&mut self.reader, s)?;
self.moov = Some(moov);
}
BoxType::MoofBox => {
skip_box(&mut self.reader, s)?;
}
_ => {
// XXX warn!()
skip_box(&mut self.reader, s)?;
}
}
current = self.reader.seek(SeekFrom::Current(0))?;
}
self.size = current - start;
Ok(())
}
pub fn track_count(&self) -> Result<u32> {
if let Some(ref moov) = self.moov {
Ok(moov.traks.len() as u32)
} else {
Err(Error::BoxNotFound(MoovBox::box_type()))
}
}
pub fn sample_count(&self, track_id: u32) -> Result<u32> {
if track_id == 0 {
return Err(Error::TrakNotFound(track_id));
}
let moov = if let Some(ref moov) = self.moov {
moov
} else {
return Err(Error::BoxNotFound(MoovBox::box_type()));
};
let trak = if let Some(trak) = moov.traks.get(track_id as usize - 1) {
trak
} else {
return Err(Error::TrakNotFound(track_id));
};
trak.sample_count()
}
pub fn read_sample(
&mut self,
track_id: u32,
sample_id: u32,
) -> Result<Option<Mp4Sample>> {
if track_id == 0 {
return Err(Error::TrakNotFound(track_id));
}
let moov = if let Some(ref moov) = self.moov {
moov
} else {
return Err(Error::BoxNotFound(MoovBox::box_type()));
};
let trak = if let Some(trak) = moov.traks.get(track_id as usize - 1) {
trak
} else {
return Err(Error::TrakNotFound(track_id));
};
trak.read_sample(&mut self.reader, sample_id)
}
}

117
src/reader.rs Normal file
View file

@ -0,0 +1,117 @@
use std::io::{Seek, SeekFrom, Read};
use crate::{Result, Error, Mp4Sample};
use crate::atoms::*;
#[derive(Debug)]
pub struct Mp4Reader<R> {
reader: R,
pub ftyp: FtypBox,
pub moov: Option<MoovBox>,
size: u64,
}
impl<R: Read + Seek> Mp4Reader<R> {
pub fn new(reader: R) -> Self {
Mp4Reader {
reader,
ftyp: FtypBox::default(),
moov: None,
size: 0,
}
}
pub fn size(&self) -> u64 {
self.size
}
pub fn read(&mut self, size: u64) -> Result<()> {
let start = self.reader.seek(SeekFrom::Current(0))?;
let mut current = start;
while current < size {
// Get box header.
let header = BoxHeader::read(&mut self.reader)?;
let BoxHeader{ name, size: s } = header;
// Match and parse the atom boxes.
match name {
BoxType::FtypBox => {
let ftyp = FtypBox::read_box(&mut self.reader, s)?;
self.ftyp = ftyp;
}
BoxType::FreeBox => {
skip_box(&mut self.reader, s)?;
}
BoxType::MdatBox => {
skip_box(&mut self.reader, s)?;
}
BoxType::MoovBox => {
let moov = MoovBox::read_box(&mut self.reader, s)?;
self.moov = Some(moov);
}
BoxType::MoofBox => {
skip_box(&mut self.reader, s)?;
}
_ => {
// XXX warn!()
skip_box(&mut self.reader, s)?;
}
}
current = self.reader.seek(SeekFrom::Current(0))?;
}
self.size = current - start;
Ok(())
}
pub fn track_count(&self) -> Result<u32> {
if let Some(ref moov) = self.moov {
Ok(moov.traks.len() as u32)
} else {
Err(Error::BoxNotFound(MoovBox::box_type()))
}
}
pub fn sample_count(&self, track_id: u32) -> Result<u32> {
if track_id == 0 {
return Err(Error::TrakNotFound(track_id));
}
let moov = if let Some(ref moov) = self.moov {
moov
} else {
return Err(Error::BoxNotFound(MoovBox::box_type()));
};
let trak = if let Some(trak) = moov.traks.get(track_id as usize - 1) {
trak
} else {
return Err(Error::TrakNotFound(track_id));
};
trak.sample_count()
}
pub fn read_sample(
&mut self,
track_id: u32,
sample_id: u32,
) -> Result<Option<Mp4Sample>> {
if track_id == 0 {
return Err(Error::TrakNotFound(track_id));
}
let moov = if let Some(ref moov) = self.moov {
moov
} else {
return Err(Error::BoxNotFound(MoovBox::box_type()));
};
let trak = if let Some(trak) = moov.traks.get(track_id as usize - 1) {
trak
} else {
return Err(Error::TrakNotFound(track_id));
};
trak.read_sample(&mut self.reader, sample_id)
}
}