Install the mp4 library
masterYou can add the mp4 library to your Rust project using cargo add or by manually editing your Cargo.toml file.
cargo add mp4Or add this to your Cargo.toml:
mp4 = "0.14.0"repository·master·Indexed 43 days ago
https://github.com/alfg/mp4-rustA Rust library for reading and writing ISO-MP4 files, supporting specifications ISO/IEC 14496-12, 14496-14, and 14496-17. Version 0.14.0 provides tools for parsing MP4 box data (such as CttsBox, ElstBox, StscBox, and TkhdBox), managing track references, and extracting metadata via Mp4Reader and Mp4Track.
You can add the mp4 library to your Rust project using cargo add or by manually editing your Cargo.toml file.
cargo add mp4Or add this to your Cargo.toml:
mp4 = "0.14.0"When creating a new track (e.g., for writing a new MP4 file), use TrackConfig to define the track's properties. TrackConfig is constructed from a MediaConfig which specifies the codec-specific parameters.
Common TrackType values include Video, Audio, and Subtitle. The timescale determines the temporal resolution of the track.
// Example: Configuring a video track with H264
let media_conf = MediaConfig::AvcConfig(AvcConfig {
width: 1920,
height: 1080,
// ... other AvcConfig fields
});
let config = TrackConfig {
track_type: TrackType::Video,
timescale: 1000,
language: String::from("eng"),
media_conf,
};The repository includes example CLI tools that you can run directly using cargo run. These are useful for inspecting MP4 files from the command line.
mp4info: Displays information about a movie file.mp4dump: Dumps the contents of an MP4 file.# Run mp4info
cargo run --example mp4info <movie.mp4>
# Run mp4dump
cargo run --example mp4dump <movie.mp4>To read an MP4 file, use mp4::Mp4Reader::read_header. This requires a reader that implements Read + Seek (such as std::io::BufReader) and the total size of the file in bytes.
Once initialized, you can access metadata such as the major_brand from the ftyp box, the timescale from the moov.mvhd box, the file size(), duration(), and compatible_brands(). You can also iterate through tracks using the tracks() method to inspect track IDs, languages, types, and box types.
use std::fs::File;
use std::io::{BufReader};
use mp4::{Result};
fn main() -> Result<()> {
let f = File::open("tests/samples/minimal.mp4").unwrap();
let size = f.metadata()?.len();
let reader = BufReader::new(f);
let mp4 = mp4::Mp4Reader::read_header(reader, size)?;
// Print boxes.
println!("major brand: {}", mp4.ftyp.major_brand);
println!("timescale: {}", mp4.moov.mvhd.timescale);
// Use available methods.
println!("size: {}", mp4.size());
let mut compatible_brands = String::new();
for brand in mp4.compatible_brands().iter() {
compatible_brands.push_str(&brand.to_string());
compatible_brands.push_str(",");
}
println!("compatible brands: {}", compatible_brands);
println!("duration: {:?}", mp4.duration());
// Track info.
for track in mp4.tracks().values() {
println!(
"track: #{}({}) {} : {}",
track.track_id(),
track.language(),
track.track_type()?,
track.box_type()?,
);
}
Ok(())
}Use Mp4Config to define the global metadata for your MP4 file. This includes the brand identifiers and the timescale used for all tracks.
Fields:
major_brand: A FourCC representing the primary brand (e.g., isom).minor_version: A u32 version number.compatible_brands: A Vec<FourCC> of other brands the file is compatible with.timescale: A u32 value defining the number of units per second, used to calculate durations.The Mp4TrackWriter (internal/utility) is used to build a track by feeding it Mp4Sample objects. It manages the underlying MP4 boxes like stsz (sample sizes), stts (time-to-sample), and co64 (chunk offsets) automatically.
To complete a track, you must call write_end, which flushes any remaining buffered data and returns the final TrakBox required to finalize the MP4 container.
// Note: Mp4TrackWriter is marked pub(crate) in this file,
// implying it is used by higher-level components in the mp4 crate.
// The pattern for usage is:
// 1. Initialize writer with TrackConfig
// 2. Loop: writer.write_sample(writer, &sample, movie_timescale)?
// 3. Finalize: writer.write_end(writer)?The UrlBox is used within a DrefBox to provide a string-based location (URL or file path) for track data.
Fields:
version: u8flags: u32location: String (The actual path or URL)Key methods:
get_type(): Returns BoxType::UrlBox.get_size(): Returns the size including the header and the null-terminated location string.to_json(): Serializes the box to a JSON string.summary(): Returns a summary string in the format location=<location_string>.use mp4::mp4box::UrlBox;
let url_box = UrlBox {
version: 0,
flags: 1,
location: "/path/to/track.mp4".to_string(),
};
println!("{}", url_box.summary()); // Outputs: location=/path/to/track.mp4The CttsBox (Composition Time to Sample) and CttsEntry types are used to handle MP4 box data that defines the composition time offsets for samples.
Represents the ctts box. It contains:
version: u8flags: u32entries: A Vec<CttsEntry> (Note: this field is skipped during JSON serialization).Represents an individual entry within the box:
sample_count: u32sample_offset: i32 (The offset applied to the sample's composition time).use crate::mp4box::CttsBox;
use crate::mp4box::CttsEntry;
let ctts = CttsBox {
version: 0,
flags: 0,
entries: vec![
CttsEntry {
sample_count: 1,
sample_offset: 200,
},
CttsEntry {
sample_count: 2,
sample_offset: -100,
},
],
};add_track to register a new media track within the MP4 container. This method takes a TrackConfig and assigns a unique track_id (starting from 1) to the track.MP4 files use an epoch starting from 1904-01-01. Use the creation_time function to convert these values to the standard Unix epoch (1970-01-01).
let mp4_time: u64 = 2082844800; // Example value
let unix_time = creation_time(mp4_time);SttsBox implements Serialize via serde. You can convert a SttsBox instance into a JSON string using the to_json() method provided by the Mp4Box trait implementation. Note that the entries field is marked with #[serde(skip_serializing)], meaning the resulting JSON will only contain the version and flags fields.The ElstBox represents the 'Edit List Box' in an MP4 container, which defines how a track's media should be played (e.g., offsets, durations, and rates). It contains a collection of ElstEntry objects.
version: The version of the box (0 or 1).flags: Box flags.entries: A Vec<ElstEntry> containing the edit list entries. Note that entries is skipped during serialization to JSON.segment_duration: The duration of the segment.media_time: The time in the media.media_rate: The integer part of the media rate.media_rate_fraction: The fractional part of the media rate.segment_duration and media_time.segment_duration and media_time.ElstBox implements the Mp4Box, ReadBox, and WriteBox traits, allowing it to be read from or written to any type implementing Read + Seek or Write.
use crate::mp4box::ElstBox;
use crate::mp4box::ElstEntry;
let elst = ElstBox {
version: 1,
flags: 0,
entries: vec![ElstEntry {
segment_duration: 634634,
media_time: 0,
media_rate: 1,
media_rate_fraction: 0,
}],
};
// To write the box to a buffer:
let mut buf = Vec::new();
elst.write_box(&mut buf).unwrap();
// To read the box from a reader:
// let elst = ElstBox::read_box(reader, size).unwrap();