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

async-mp4

纯Rust编写的Async Mp4 Muxer和Demuxer

2个版本

0.1.1 2022年12月7日
0.1.0 2022年12月7日

#213 in 视频

MIT/ApacheGPL-3.0-or-later

125KB
3.5K SLoC

Async mp4

为MP4设计的MP4 Muxer Demuxer,适用于WASM和异步环境。

状态

  • Fragmented mp4标准
  • 易于使用的API
  • 高性能异步读取器(当前异步调用太多)

为什么不选择 mp4-rust ?

  • 他们的代码没有实现所有必要的Fragmented mp4流功能
  • 他们的读取器不是异步的
  • 我们根据数据自动设置标志
  • 我们使用非常干净的宏定义box,以便易于实现
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
    }
}

用法

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();

待办事项

  • 一旦知道大小,让异步读取器读取完整的box块,并使用同步读取器进行解码(这样我们就不需要为每个字节分配空间)
  • 让box宏生成box的View结构,以便可以读取现有数据而无需解码一切,并保留原始结构
  • 制作一个易于使用的构建器,从编码包装box和头的流中生成文件

依赖项

~6.5MB
~125K SLoC