1
0
Fork 0
mirror of https://github.com/alfg/mp4-rust.git synced 2024-05-19 16:58:04 +00:00

Box summary and to_json traits. (#29)

* Add Mp4Box traits for getting json or text summary for each box.

* fix test and serde version.

* skip serializing entries

* skip serializing sample_sizes

* Add custom serializer for FixedPoint types.
This commit is contained in:
Alfred Gutierrez 2020-09-08 22:24:34 -07:00 committed by GitHub
parent 0330a8eda7
commit 0f373b03db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 518 additions and 62 deletions

View file

@ -5,16 +5,11 @@ authors = ["Alf <alf.g.jr@gmail.com>"]
edition = "2018"
description = """
MP4 Reader and Writer in Rust
`mp4rs` is a Rust library to read and write ISO-MP4 files.
This package contains MPEG-4 specifications defined in parts:
* ISO/IEC 14496-12 - ISO Base Media File Format (QuickTime, MPEG-4, etc)
* ISO/IEC 14496-14 - MP4 file format
* ISO/IEC 14496-17 - Streaming text format
MP4 reader and writer library in Rust.
"""
documentation = "https://docs.rs/mp4rs"
readme = "README.md"
homepage = "https://github.com/alfg/mp4rs"
repository = "https://github.com/alfg/mp4rs"
@ -26,7 +21,9 @@ license = "MIT"
thiserror = "^1.0"
byteorder = "1"
bytes = "0.5"
num-rational = "0.3"
num-rational = { version = "0.3", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[dev-dependencies]
criterion = "0.3"

View file

@ -25,7 +25,7 @@ fn dump<P: AsRef<Path>>(filename: &P) -> Result<()> {
// print out boxes
for b in boxes.iter() {
println!("[{}] size={}", b.name, b.size);
println!("[{}] size={} {}", b.name, b.size, b.summary);
}
Ok(())
@ -35,6 +35,7 @@ fn dump<P: AsRef<Path>>(filename: &P) -> Result<()> {
pub struct Box {
name: String,
size: u64,
summary: String,
indent: u32,
}
@ -125,6 +126,7 @@ fn build_box<M: Mp4Box + std::fmt::Debug>(ref m: &M) -> Box {
return Box{
name: m.box_type().to_string(),
size: m.box_size(),
summary: m.summary().unwrap(),
indent: 0,
};
}
}

View file

@ -1,14 +1,19 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct Avc1Box {
pub data_reference_index: u16,
pub width: u16,
pub height: u16,
#[serde(with = "value_u32")]
pub horizresolution: FixedPointU16,
#[serde(with = "value_u32")]
pub vertresolution: FixedPointU16,
pub frame_count: u16,
pub depth: u16,
@ -61,6 +66,16 @@ impl Mp4Box for Avc1Box {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("data_reference_index={} width={} height={} frame_count={}",
self.data_reference_index, self.width, self.height, self.frame_count);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for Avc1Box {
@ -136,7 +151,7 @@ impl<W: Write> WriteBox<&mut W> for Avc1Box {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct AvcCBox {
pub configuration_version: u8,
pub avc_profile_indication: u8,
@ -176,6 +191,16 @@ impl Mp4Box for AvcCBox {
}
size
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("avc_profile_indication={}",
self.avc_profile_indication);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for AvcCBox {
@ -236,7 +261,7 @@ impl<W: Write> WriteBox<&mut W> for AvcCBox {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct NalUnit {
pub bytes: Vec<u8>,
}

View file

@ -1,12 +1,15 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct Co64Box {
pub version: u8,
pub flags: u32,
#[serde(skip_serializing)]
pub entries: Vec<u64>,
}
@ -28,6 +31,15 @@ impl Mp4Box for Co64Box {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("entries_count={}", self.entries.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for Co64Box {

View file

@ -1,12 +1,15 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct CttsBox {
pub version: u8,
pub flags: u32,
#[serde(skip_serializing)]
pub entries: Vec<CttsEntry>,
}
@ -20,7 +23,7 @@ impl CttsBox {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct CttsEntry {
pub sample_count: u32,
pub sample_offset: i32,
@ -34,6 +37,15 @@ impl Mp4Box for CttsBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("entries_count={}", self.entries.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for CttsBox {

View file

@ -1,9 +1,10 @@
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::elst::ElstBox;
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct EdtsBox {
pub elst: Option<ElstBox>,
}
@ -34,6 +35,15 @@ impl Mp4Box for EdtsBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for EdtsBox {

View file

@ -1,16 +1,19 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct ElstBox {
pub version: u8,
pub flags: u32,
#[serde(skip_serializing)]
pub entries: Vec<ElstEntry>,
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct ElstEntry {
pub segment_duration: u64,
pub media_time: u64,
@ -43,6 +46,15 @@ impl Mp4Box for ElstBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("elst_entries={}", self.entries.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for ElstBox {

View file

@ -1,9 +1,10 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct FtypBox {
pub major_brand: FourCC,
pub minor_version: u32,
@ -28,6 +29,20 @@ impl Mp4Box for FtypBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let mut compatible_brands = Vec::new();
for brand in self.compatible_brands.iter() {
compatible_brands.push(brand.to_string());
}
let s = format!("major_brand={} minor_version={} compatible_brands={}",
self.major_brand, self.minor_version, compatible_brands.join("-"));
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for FtypBox {

View file

@ -1,9 +1,10 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct HdlrBox {
pub version: u8,
pub flags: u32,
@ -29,6 +30,15 @@ impl Mp4Box for HdlrBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("handler_type={} name={}", self.handler_type.to_string(), self.name);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for HdlrBox {

View file

@ -1,14 +1,19 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct Hev1Box {
pub data_reference_index: u16,
pub width: u16,
pub height: u16,
#[serde(with = "value_u32")]
pub horizresolution: FixedPointU16,
#[serde(with = "value_u32")]
pub vertresolution: FixedPointU16,
pub frame_count: u16,
pub depth: u16,
@ -61,6 +66,16 @@ impl Mp4Box for Hev1Box {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("data_reference_index={} width={} height={} frame_count={}",
self.data_reference_index, self.width, self.height, self.frame_count);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for Hev1Box {
@ -136,7 +151,7 @@ impl<W: Write> WriteBox<&mut W> for Hev1Box {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct HvcCBox {
pub configuration_version: u8,
}
@ -158,6 +173,16 @@ impl Mp4Box for HvcCBox {
let size = HEADER_SIZE + 1;
size
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("configuration_version={}",
self.configuration_version);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for HvcCBox {

View file

@ -1,10 +1,11 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct MdhdBox {
pub version: u8,
pub flags: u32,
@ -56,6 +57,16 @@ impl Mp4Box for MdhdBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("creation_time={} timescale={} duration={} language={}",
self.creation_time, self.timescale, self.duration, self.language);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for MdhdBox {

View file

@ -1,9 +1,10 @@
use std::io::{Read, Seek, SeekFrom, Write};
use serde::{Serialize};
use crate::mp4box::*;
use crate::mp4box::{hdlr::HdlrBox, mdhd::MdhdBox, minf::MinfBox};
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct MdiaBox {
pub mdhd: MdhdBox,
pub hdlr: HdlrBox,
@ -28,6 +29,15 @@ impl Mp4Box for MdiaBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for MdiaBox {

View file

@ -1,9 +1,10 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct MfhdBox {
pub version: u8,
pub flags: u32,
@ -38,6 +39,15 @@ impl Mp4Box for MfhdBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("sequence_number={}", self.sequence_number);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for MfhdBox {

View file

@ -1,9 +1,10 @@
use std::io::{Read, Seek, SeekFrom, Write};
use serde::{Serialize};
use crate::mp4box::*;
use crate::mp4box::{smhd::SmhdBox, stbl::StblBox, vmhd::VmhdBox};
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct MinfBox {
pub vmhd: Option<VmhdBox>,
pub smhd: Option<SmhdBox>,
@ -36,6 +37,15 @@ impl Mp4Box for MinfBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for MinfBox {

View file

@ -114,6 +114,8 @@ boxtype! {
pub trait Mp4Box: Sized {
fn box_type(&self) -> BoxType;
fn box_size(&self) -> u64;
fn to_json(&self) -> Result<String>;
fn summary(&self) -> Result<String>;
}
pub trait ReadBox<T>: Sized {
@ -220,6 +222,52 @@ pub fn write_zeros<W: Write>(writer: &mut W, size: u64) -> Result<()> {
Ok(())
}
mod value_u32 {
use crate::types::FixedPointU16;
use serde::{self, Serializer};
pub fn serialize<S>(
fixed: &FixedPointU16,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u16(fixed.value())
}
}
mod value_i16 {
use crate::types::FixedPointI8;
use serde::{self, Serializer};
pub fn serialize<S>(
fixed: &FixedPointI8,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_i8(fixed.value())
}
}
mod value_u8 {
use crate::types::FixedPointU8;
use serde::{self, Serializer};
pub fn serialize<S>(
fixed: &FixedPointU8,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u8(fixed.value())
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -229,7 +277,7 @@ mod tests {
let ftyp_fcc = 0x66747970;
let ftyp_value = FourCC::from(ftyp_fcc);
assert_eq!(ftyp_value.value, "ftyp");
let ftyp_fcc2 = ftyp_value.into();
let ftyp_fcc2: u32 = ftyp_value.into();
assert_eq!(ftyp_fcc, ftyp_fcc2);
}
}

View file

@ -1,9 +1,10 @@
use std::io::{Read, Seek, SeekFrom, Write};
use serde::{Serialize};
use crate::mp4box::*;
use crate::mp4box::{mfhd::MfhdBox, traf::TrafBox};
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct MoofBox {
pub mfhd: MfhdBox,
pub trafs: Vec<TrafBox>,
@ -31,6 +32,15 @@ impl Mp4Box for MoofBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("trafs={}", self.trafs.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for MoofBox {

View file

@ -1,9 +1,10 @@
use std::io::{Read, Seek, SeekFrom, Write};
use serde::{Serialize};
use crate::mp4box::*;
use crate::mp4box::{mvhd::MvhdBox, trak::TrakBox};
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct MoovBox {
pub mvhd: MvhdBox,
pub traks: Vec<TrakBox>,
@ -31,6 +32,15 @@ impl Mp4Box for MoovBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("traks={}", self.traks.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for MoovBox {

View file

@ -1,13 +1,16 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct Mp4aBox {
pub data_reference_index: u16,
pub channelcount: u16,
pub samplesize: u16,
#[serde(with = "value_u32")]
pub samplerate: FixedPointU16,
pub esds: Option<EsdsBox>,
}
@ -56,6 +59,16 @@ impl Mp4Box for Mp4aBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("channel_count={} sample_size={} sample_rate={}",
self.channelcount, self.samplesize, self.samplerate.value());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for Mp4aBox {
@ -114,7 +127,7 @@ impl<W: Write> WriteBox<&mut W> for Mp4aBox {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct EsdsBox {
pub version: u8,
pub flags: u32,
@ -139,6 +152,15 @@ impl Mp4Box for EsdsBox {
fn box_size(&self) -> u64 {
HEADER_SIZE + HEADER_EXT_SIZE + ESDescriptor::desc_size() as u64
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for EsdsBox {
@ -247,7 +269,7 @@ fn write_desc<W: Write>(writer: &mut W, tag: u8, size: u32) -> Result<u64> {
Ok(1 + nbytes)
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct ESDescriptor {
pub es_id: u16,
@ -327,7 +349,7 @@ impl<W: Write> WriteDesc<&mut W> for ESDescriptor {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct DecoderConfigDescriptor {
pub object_type_indication: u8,
pub stream_type: u8,
@ -422,7 +444,7 @@ impl<W: Write> WriteDesc<&mut W> for DecoderConfigDescriptor {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct DecoderSpecificDescriptor {
pub profile: u8,
pub freq_index: u8,
@ -478,7 +500,7 @@ impl<W: Write> WriteDesc<&mut W> for DecoderSpecificDescriptor {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct SLConfigDescriptor {}
impl SLConfigDescriptor {

View file

@ -1,9 +1,10 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct MvhdBox {
pub version: u8,
pub flags: u32,
@ -11,6 +12,8 @@ pub struct MvhdBox {
pub modification_time: u64,
pub timescale: u32,
pub duration: u64,
#[serde(with = "value_u32")]
pub rate: FixedPointU16,
}
@ -54,6 +57,16 @@ impl Mp4Box for MvhdBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("creation_time={} timescale={} duration={} rate={}",
self.creation_time, self.timescale, self.duration, self.rate.value());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for MvhdBox {

View file

@ -1,12 +1,15 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct SmhdBox {
pub version: u8,
pub flags: u32,
#[serde(with = "value_i16")]
pub balance: FixedPointI8,
}
@ -38,6 +41,15 @@ impl Mp4Box for SmhdBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("balance={}", self.balance.value());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for SmhdBox {

View file

@ -1,20 +1,35 @@
use std::io::{Read, Seek, SeekFrom, Write};
use serde::{Serialize};
use crate::mp4box::*;
use crate::mp4box::{
co64::Co64Box, ctts::CttsBox, stco::StcoBox, stsc::StscBox, stsd::StsdBox, stss::StssBox,
stsz::StszBox, stts::SttsBox,
co64::Co64Box,
ctts::CttsBox,
stco::StcoBox,
stsc::StscBox,
stsd::StsdBox,
stss::StssBox,
stsz::StszBox,
stts::SttsBox,
};
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct StblBox {
pub stsd: StsdBox,
pub stts: SttsBox,
#[serde(skip_serializing_if = "Option::is_none")]
pub ctts: Option<CttsBox>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stss: Option<StssBox>,
pub stsc: StscBox,
pub stsz: StszBox,
#[serde(skip_serializing_if = "Option::is_none")]
pub stco: Option<StcoBox>,
#[serde(skip_serializing_if = "Option::is_none")]
pub co64: Option<Co64Box>,
}
@ -53,6 +68,15 @@ impl Mp4Box for StblBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for StblBox {

View file

@ -1,12 +1,15 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct StcoBox {
pub version: u8,
pub flags: u32,
#[serde(skip_serializing)]
pub entries: Vec<u32>,
}
@ -28,6 +31,15 @@ impl Mp4Box for StcoBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("entries={}", self.entries.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for StcoBox {

View file

@ -1,12 +1,15 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct StscBox {
pub version: u8,
pub flags: u32,
#[serde(skip_serializing)]
pub entries: Vec<StscEntry>,
}
@ -20,7 +23,7 @@ impl StscBox {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct StscEntry {
pub first_chunk: u32,
pub samples_per_chunk: u32,
@ -36,6 +39,15 @@ impl Mp4Box for StscBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("entries={}", self.entries.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for StscBox {

View file

@ -1,16 +1,25 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
use crate::mp4box::{avc1::Avc1Box, hev1::Hev1Box, mp4a::Mp4aBox, tx3g::Tx3gBox};
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct StsdBox {
pub version: u8,
pub flags: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub avc1: Option<Avc1Box>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hev1: Option<Hev1Box>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mp4a: Option<Mp4aBox>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tx3g: Option<Tx3gBox>,
}
@ -42,6 +51,15 @@ impl Mp4Box for StsdBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for StsdBox {

View file

@ -1,12 +1,15 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct StssBox {
pub version: u8,
pub flags: u32,
#[serde(skip_serializing)]
pub entries: Vec<u32>,
}
@ -28,6 +31,15 @@ impl Mp4Box for StssBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("entries={}", self.entries.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for StssBox {

View file

@ -1,14 +1,17 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct StszBox {
pub version: u8,
pub flags: u32,
pub sample_size: u32,
pub sample_count: u32,
#[serde(skip_serializing)]
pub sample_sizes: Vec<u32>,
}
@ -30,6 +33,16 @@ impl Mp4Box for StszBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("sample_size={} sample_count={} sample_sizes={}",
self.sample_size, self.sample_count, self.sample_sizes.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for StszBox {

View file

@ -1,12 +1,15 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct SttsBox {
pub version: u8,
pub flags: u32,
#[serde(skip_serializing)]
pub entries: Vec<SttsEntry>,
}
@ -20,7 +23,7 @@ impl SttsBox {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct SttsEntry {
pub sample_count: u32,
pub sample_delta: u32,
@ -34,6 +37,15 @@ impl Mp4Box for SttsBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("entries={}", self.entries.len());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for SttsBox {

View file

@ -1,9 +1,10 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct TfhdBox {
pub version: u8,
pub flags: u32,
@ -38,6 +39,15 @@ impl Mp4Box for TfhdBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("track_id={}", self.track_id);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for TfhdBox {

View file

@ -1,9 +1,10 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct TkhdBox {
pub version: u8,
pub flags: u32,
@ -13,9 +14,15 @@ pub struct TkhdBox {
pub duration: u64,
pub layer: u16,
pub alternate_group: u16,
#[serde(with = "value_u8")]
pub volume: FixedPointU8,
pub matrix: Matrix,
#[serde(with = "value_u32")]
pub width: FixedPointU16,
#[serde(with = "value_u32")]
pub height: FixedPointU16,
}
@ -38,7 +45,7 @@ impl Default for TkhdBox {
}
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct Matrix {
pub a: i32,
pub b: i32,
@ -85,6 +92,17 @@ impl Mp4Box for TkhdBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("creation_time={} track_id={} duration={} layer={} volume={} width={} height={}",
self.creation_time, self.track_id, self.duration, self.layer,
self.volume.value(), self.width.value(), self.height.value());
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for TkhdBox {

View file

@ -1,9 +1,10 @@
use std::io::{Read, Seek, SeekFrom, Write};
use serde::{Serialize};
use crate::mp4box::*;
use crate::mp4box::{tfhd::TfhdBox};
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct TrafBox {
pub tfhd: TfhdBox,
}
@ -28,6 +29,15 @@ impl Mp4Box for TrafBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for TrafBox {

View file

@ -1,9 +1,10 @@
use std::io::{Read, Seek, SeekFrom, Write};
use serde::{Serialize};
use crate::mp4box::*;
use crate::mp4box::{edts::EdtsBox, mdia::MdiaBox, tkhd::TkhdBox};
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct TrakBox {
pub tkhd: TkhdBox,
pub edts: Option<EdtsBox>,
@ -34,6 +35,15 @@ impl Mp4Box for TrakBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for TrakBox {

View file

@ -1,9 +1,10 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct Tx3gBox {
pub data_reference_index: u16,
pub display_flags: u32,
@ -14,7 +15,7 @@ pub struct Tx3gBox {
pub style_record: [u8; 12],
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct RgbaColor {
pub red: u8,
pub green: u8,
@ -59,6 +60,18 @@ impl Mp4Box for Tx3gBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("data_reference_index={} horizontal_justification={} vertical_justification={} rgba={}{}{}{}",
self.data_reference_index, self.horizontal_justification,
self.vertical_justification, self.bg_color_rgba.red,
self.bg_color_rgba.green, self.bg_color_rgba.blue, self.bg_color_rgba.alpha);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for Tx3gBox {

View file

@ -1,9 +1,10 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, Write};
use serde::{Serialize};
use crate::mp4box::*;
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct VmhdBox {
pub version: u8,
pub flags: u32,
@ -11,7 +12,7 @@ pub struct VmhdBox {
pub op_color: RgbColor,
}
#[derive(Debug, Clone, PartialEq, Default)]
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
pub struct RgbColor {
pub red: u16,
pub green: u16,
@ -36,6 +37,20 @@ impl Mp4Box for VmhdBox {
fn box_size(&self) -> u64 {
return self.get_size();
}
fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self).unwrap())
}
fn summary(&self) -> Result<String> {
let s = format!("graphics_mode={} op_color={}{}{}",
self.graphics_mode,
self.op_color.red,
self.op_color.green,
self.op_color.blue
);
Ok(s)
}
}
impl<R: Read + Seek> ReadBox<&mut R> for VmhdBox {

View file

@ -1,5 +1,6 @@
use std::convert::TryFrom;
use std::fmt;
use serde::{Serialize};
use crate::mp4box::*;
use crate::*;
@ -7,7 +8,7 @@ use crate::*;
pub use bytes::Bytes;
pub use num_rational::Ratio;
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
pub struct FixedPointU8(Ratio<u16>);
impl FixedPointU8 {
@ -28,7 +29,7 @@ impl FixedPointU8 {
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
pub struct FixedPointI8(Ratio<i16>);
impl FixedPointI8 {
@ -49,7 +50,7 @@ impl FixedPointI8 {
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
pub struct FixedPointU16(Ratio<u32>);
impl FixedPointU16 {
@ -84,7 +85,7 @@ impl fmt::Display for BoxType {
}
}
#[derive(Default, PartialEq, Clone)]
#[derive(Default, PartialEq, Clone, Serialize)]
pub struct FourCC {
pub value: String,
}