#mp4 #async #opus #decoding #mux #avc

async-mp4

Async Mp4 Muxer and Demuxer in pure rust

2 releases

0.1.1 Dec 7, 2022
0.1.0 Dec 7, 2022

#282 in Video

MIT/Apache and GPL-3.0-or-later

125KB
3.5K SLoC

Async mp4

An mp4 muxer demuxer for mp4, made to work in WASM and async contexts.

State

  • Standard for Fragmented mp4
  • Easy to use api
  • Performant async reader (too many async calls currently)

Why not mp4-rust ?

  • Their code does not implement all the necessary features for fragmented mp4 streams
  • Their reader is not async
  • We set flags automatically according to data
  • We use a very clean macro for box definition for easy implementation:
full_box! {
    box (b"mvhd", Mvhd, MvhdBox, u32)
    data {
        creation_time: Mp4DateTime,
        modification_time: Mp4DateTime,
        timescale: u32,
        duration: Mp4Duration,
        rate: I16F16,
        volume: I8F8,
        _r1: u16, // reserved
        _r2: [u32; 2], // reserved
        matrix: MP4Matrix,
        _r3: [u32; 6], // reserved
        next_track_id: u32
    }
}

Usage

let ftyp = FtypBox {
    major_brand: *b"iso5",
    minor_version: 1,
    compatible_brands: vec![*b"isom", *b"avc1", *b"iso2", *b"iso5"],
};
let moov: MoovBox = Moov {
    mvhd: Some(Default::default()),
    mvex: Some(Mvex {
        trex: traks.iter().map(|trak| {
            Trex {
                track_id: trak.tkhd.as_ref().map(|it|it.track_id).unwrap_or(0),
                default_sample_description_index: 1,
                default_sample_duration: 0,
                default_sample_size: 0,
                default_sample_flags: Default::default(),
            }.into()
        }).collect(),
    }.into()),
    traks: vec![Trak { /* trak info... */ }.into()],
}.into();

let mut buf = std::io::Cursor::new(vec![]);
ftyp.write(&mut buf)?;
moov.write(&mut buf)?;
return buf.into_inner();

Todo

  • Make async reader read full box chunks once the size is known and decode using a synchronous reader (so we don't allocate for every byte)
  • Make the box macro generate a View structure of the box so that existing data can be read without decoding everything and preserving the original structure
  • Make an easy-to-use builder to generate files from a stream of codec wrapping boxes and headers

Dependencies

~6MB
~106K SLoC