### Run MP4 Info Example Source: https://github.com/alfg/mp4-rust/blob/master/README.md Command to run the `mp4info` example provided with the mp4-rust library. This requires a movie file as an argument and will output information about the MP4 file. ```bash cargo run --example mp4info ``` -------------------------------- ### Run MP4 Dump Example Source: https://github.com/alfg/mp4-rust/blob/master/README.md Command to run the `mp4dump` example provided with the mp4-rust library. This requires a movie file as an argument and will likely dump the structure or content of the MP4 file. ```bash cargo run --example mp4dump ``` -------------------------------- ### Format Code with Cargo fmt Source: https://github.com/alfg/mp4-rust/blob/master/README.md Commands to install the `rustfmt` component and then run `cargo fmt` to format all code in the project according to standard Rust style guidelines. The `-- --check` flag can be used to only report formatting errors without applying changes. ```bash rustup component add rustfmt ``` ```bash cargo fmt --all -- --check ``` -------------------------------- ### Lint Code with Cargo Clippy Source: https://github.com/alfg/mp4-rust/blob/master/README.md Commands to install the `clippy` component and then run `cargo clippy` to check for common mistakes and style issues. The `--no-deps -- -D warnings` flags are used to lint only the project's own code and treat all warnings as errors. ```bash rustup component add clippy ``` ```bash cargo clippy --no-deps -- -D warnings ``` -------------------------------- ### Extract Track Information and Codec Details - Rust Source: https://context7.com/alfg/mp4-rust/llms.txt This example shows how to iterate through all tracks in an MP4 file and retrieve track-specific information including codec type, dimensions, frame rate, bitrate, sample rate, and channel configuration. It handles different track types (Video, Audio, Subtitle) with appropriate data extraction for each. ```rust use std::fs::File; use std::io::BufReader; use mp4::{Result, TrackType}; fn main() -> Result<()> { let f = File::open("video.mp4").unwrap(); let size = f.metadata()?.len(); let reader = BufReader::new(f); let mp4 = mp4::Mp4Reader::read_header(reader, size)?; // Iterate through all tracks for track in mp4.tracks().values() { println!( "track: #{}({}) {} : {}", track.track_id(), track.language(), track.track_type()?, track.box_type()?, ); // Track-specific information match track.track_type()? { TrackType::Video => { println!(" video: {}x{}", track.width(), track.height()); println!(" frame rate: {:.2} fps", track.frame_rate()); println!(" bitrate: {} kb/s", track.bitrate() / 1000); if let Ok(profile) = track.video_profile() { println!(" profile: {:?}", profile); } } TrackType::Audio => { if let Ok(freq_index) = track.sample_freq_index() { println!(" sample rate: {} Hz", freq_index.freq()); } if let Ok(chan_conf) = track.channel_config() { println!(" channels: {}", chan_conf); } println!(" bitrate: {} kb/s", track.bitrate() / 1000); } TrackType::Subtitle => { println!(" subtitle track"); } } println!(" duration: {:?}", track.duration()); println!(" sample count: {}", track.sample_count()); } Ok(()) } ``` -------------------------------- ### Parse MP4 File Headers and Access Metadata - Rust Source: https://context7.com/alfg/mp4-rust/llms.txt This example demonstrates how to open an MP4 file, parse its header information, and access file-level metadata including major brand, timescale, duration, and compatible brands. It uses mp4::Mp4Reader::read_header() to initialize the reader and provides methods to check if the file is fragmented. ```rust use std::fs::File; use std::io::BufReader; use mp4::Result; fn main() -> Result<()> { let f = File::open("video.mp4").unwrap(); let size = f.metadata()?.len(); let reader = BufReader::new(f); let mp4 = mp4::Mp4Reader::read_header(reader, size)?; // Access file-level metadata println!("major brand: {}", mp4.ftyp.major_brand); println!("timescale: {}", mp4.moov.mvhd.timescale); println!("size: {}", mp4.size()); println!("duration: {:?}", mp4.duration()); // Check if file is fragmented println!("is fragmented: {}", mp4.is_fragmented()); // Iterate through compatible brands let mut compatible_brands = String::new(); for brand in mp4.compatible_brands().iter() { compatible_brands.push_str(&brand.to_string()); compatible_brands.push(','); } println!("compatible brands: {}", compatible_brands); Ok(()) } ``` -------------------------------- ### Generate Documentation Source: https://github.com/alfg/mp4-rust/blob/master/README.md Command to generate API documentation for the Rust project. The documentation will be available in the `target/doc/` directory, typically at `target/doc/mp4/index.html`. ```bash cargo docs ``` -------------------------------- ### Run Benchmark Tests Source: https://github.com/alfg/mp4-rust/blob/master/README.md Command to execute benchmark tests for the project. This will generate an HTML report at `target/criterion/report/index.html` for analyzing benchmark results. ```bash cargo bench ``` -------------------------------- ### Create New MP4 File from Scratch Source: https://context7.com/alfg/mp4-rust/llms.txt Initializes a new MP4 writer with a specified configuration, allowing for the creation of MP4 files from scratch. Supports defining major brand, minor version, compatible brands, and timescale. Can write to an in-memory buffer or a file. Requires the 'mp4' crate. ```rust use mp4::{Mp4Config, Mp4Writer, Result}; use std::io::Cursor; fn main() -> Result<()> { let config = Mp4Config { major_brand: str::parse("isom").unwrap(), minor_version: 512, compatible_brands: vec![ str::parse("isom").unwrap(), str::parse("iso2").unwrap(), str::parse("avc1").unwrap(), str::parse("mp41").unwrap(), ], timescale: 1000, }; // Create in-memory writer (can also use File) let data = Cursor::new(Vec::::new()); let mut writer = Mp4Writer::write_start(data, &config)?; // Add tracks and samples here... // Finalize the file writer.write_end()?; // Retrieve the written data let data: Vec = writer.into_writer().into_inner(); println!("Created MP4 file: {} bytes", data.len()); Ok(()) } ``` -------------------------------- ### Build Project with Cargo Source: https://github.com/alfg/mp4-rust/blob/master/README.md Command to build the Rust project using Cargo. This compiles the source code and creates an executable or library in the `target/` directory. ```bash cargo build ``` -------------------------------- ### Add Video and Audio Tracks to MP4 Writer Source: https://context7.com/alfg/mp4-rust/llms.txt Configures and adds H.264 video and AAC audio tracks to an MP4 file being created. It specifies track types, media configurations (including codec-specific parameters like SPS/PPS for video and audio profile/sample rate for audio), and language. Requires the 'mp4' crate and standard library I/O. ```rust use mp4::{ Mp4Config, Mp4Writer, TrackConfig, MediaConfig, AvcConfig, AacConfig, TrackType, AudioObjectType, SampleFreqIndex, ChannelConfig, Result }; use std::fs::File; use std::io::BufWriter; fn main() -> Result<()> { let config = Mp4Config { major_brand: str::parse("isom").unwrap(), minor_version: 512, compatible_brands: vec![ str::parse("isom").unwrap(), str::parse("iso2").unwrap(), str::parse("avc1").unwrap(), str::parse("mp41").unwrap(), ], timescale: 1000, }; let file = File::create("output.mp4")?; let writer = BufWriter::new(file); let mut mp4_writer = Mp4Writer::write_start(writer, &config)?; // Add H.264 video track let video_config = TrackConfig { track_type: TrackType::Video, timescale: 1000, language: String::from("und"), media_conf: MediaConfig::AvcConfig(AvcConfig { width: 1920, height: 1080, seq_param_set: vec![0x67, 0x64, 0x00, 0x1f], // SPS NAL unit pic_param_set: vec![0x68, 0xee, 0x3c, 0x80], // PPS NAL unit }), }; mp4_writer.add_track(&video_config)?; // Add AAC audio track let audio_config = TrackConfig { track_type: TrackType::Audio, timescale: 1000, language: String::from("eng"), media_conf: MediaConfig::AacConfig(AacConfig { bitrate: 128000, profile: AudioObjectType::AacLowComplexity, freq_index: SampleFreqIndex::Freq48000, chan_conf: ChannelConfig::Stereo, }), }; mp4_writer.add_track(&audio_config)?; // Write samples... mp4_writer.write_end()?; Ok(()) } ``` -------------------------------- ### Read Media Samples from MP4 Track Source: https://context7.com/alfg/mp4-rust/llms.txt Reads individual media samples from a specified track in an MP4 file. It extracts sample data, timing information (start_time, duration), rendering offset, synchronization flags (is_sync), and sample size. Requires a valid MP4 file and the 'mp4' crate. ```rust use std::fs::File; use std::io::BufReader; use mp4::Result; fn main() -> Result<()> { let f = File::open("video.mp4").unwrap(); let size = f.metadata()?.len(); let reader = BufReader::new(f); let mut mp4 = mp4::Mp4Reader::read_header(reader, size)?; // Get track ID (usually 1 for first video track) let track_id = 1; // Get total sample count let sample_count = mp4.sample_count(track_id)?; println!("Total samples in track {}: {}", track_id, sample_count); // Read specific samples for sample_id in 1..=5 { if let Some(sample) = mp4.read_sample(track_id, sample_id)? { println!("Sample {}:", sample_id); println!(" start_time: {}", sample.start_time); println!(" duration: {}", sample.duration); println!(" rendering_offset: {}", sample.rendering_offset); println!(" is_sync: {}", sample.is_sync); println!(" size: {} bytes", sample.bytes.len()); // Access sample data let data: &[u8] = &sample.bytes; println!(" first 4 bytes: {:02x?}", &data[..4.min(data.len())]); } } // Get sample offset in file let sample_offset = mp4.sample_offset(track_id, 1)?; println!("Sample 1 offset: {} bytes", sample_offset); Ok(()) } ``` -------------------------------- ### Run Cargo Tests Source: https://github.com/alfg/mp4-rust/blob/master/README.md Command to run all tests defined within the Rust project. The `-- --nocapture` flag can be added to display output from `println!` statements within the tests. ```bash cargo test ``` ```bash cargo test -- --nocapture ``` -------------------------------- ### Quick MP4 File Reading with Convenience Function Source: https://context7.com/alfg/mp4-rust/llms.txt Provides a simplified API for quick MP4 file access without manual header parsing. It returns an MP4 object that allows easy retrieval of file duration and track information. Requires a valid MP4 file and the 'mp4' crate. ```rust use std::fs::File; use mp4::Result; fn main() -> Result<()> { let f = File::open("video.mp4")?; let mp4 = mp4::read_mp4(f)?; println!("Duration: {:?}", mp4.duration()); println!("Tracks: {}", mp4.tracks().len()); for track in mp4.tracks().values() { println!( "Track {}: {} - {}", track.track_id(), track.track_type()?, track.media_type()? ); } Ok(()) } ``` -------------------------------- ### Write Encoded Media Samples to MP4 Tracks in Rust Source: https://context7.com/alfg/mp4-rust/llms.txt Writes encoded media samples to MP4 tracks, including essential timing and synchronization information. This function requires the 'mp4' and 'bytes' crates. It takes MP4 configuration, track configuration, and individual sample data as input and outputs a valid MP4 file structure. ```rust use mp4::{Mp4Config, Mp4Writer, TrackConfig, MediaConfig, AvcConfig, TrackType, Mp4Sample, Result}; use bytes::Bytes; use std::io::Cursor; fn main() -> Result<()> { let config = Mp4Config { major_brand: str::parse("isom").unwrap(), minor_version: 512, compatible_brands: vec![str::parse("isom").unwrap()], timescale: 1000, }; let data = Cursor::new(Vec::::new()); let mut writer = Mp4Writer::write_start(data, &config)?; let video_config = TrackConfig { track_type: TrackType::Video, timescale: 1000, language: String::from("und"), media_conf: MediaConfig::AvcConfig(AvcConfig { width: 640, height: 480, seq_param_set: vec![0x67, 0x64, 0x00, 0x1f], pic_param_set: vec![0x68, 0xee, 0x3c, 0x80], }), }; writer.add_track(&video_config)?; let track_id = 1; // Write I-frame (sync sample) let sample1 = Mp4Sample { start_time: 0, duration: 33, // ~30 fps rendering_offset: 0, is_sync: true, // Keyframe bytes: Bytes::from(vec![0x00, 0x01, 0x02, 0x03]), // NAL unit data }; writer.write_sample(track_id, &sample1)?; // Write P-frame (non-sync sample) let sample2 = Mp4Sample { start_time: 33, duration: 33, rendering_offset: 0, is_sync: false, bytes: Bytes::from(vec![0x04, 0x05, 0x06, 0x07]), }; writer.write_sample(track_id, &sample2)?; writer.write_end()?; Ok(()) } ``` -------------------------------- ### Copy MP4 Files Preserving Tracks and Samples in Rust Source: https://context7.com/alfg/mp4-rust/llms.txt Reads an existing MP4 file and writes its contents to a new file, ensuring all tracks and samples are preserved. This function depends on the 'mp4' crate and standard library file I/O. It takes source and destination file paths as input and outputs a byte-for-byte identical copy of the MP4 file. ```rust use std::fs::File; use std::io::{BufReader, BufWriter}; use mp4::{ Mp4Config, MediaConfig, MediaType, TrackConfig, AvcConfig, AacConfig, HevcConfig, TtxtConfig, Vp9Config, Result }; fn copy_mp4(src_path: &str, dst_path: &str) -> Result<()> { // Open source file let src_file = File::open(src_path)?; let size = src_file.metadata()?.len(); let reader = BufReader::new(src_file); // Open destination file let dst_file = File::create(dst_path)?; let writer = BufWriter::new(dst_file); // Read source let mut mp4_reader = mp4::Mp4Reader::read_header(reader, size)?; // Create writer with same config let mut mp4_writer = mp4::Mp4Writer::write_start( writer, &Mp4Config { major_brand: *mp4_reader.major_brand(), minor_version: mp4_reader.minor_version(), compatible_brands: mp4_reader.compatible_brands().to_vec(), timescale: mp4_reader.timescale(), }, )?; // Copy tracks for track in mp4_reader.tracks().values() { let media_conf = match track.media_type()? { MediaType::H264 => MediaConfig::AvcConfig(AvcConfig { width: track.width(), height: track.height(), seq_param_set: track.sequence_parameter_set()?.to_vec(), pic_param_set: track.picture_parameter_set()?.to_vec(), }), MediaType::H265 => MediaConfig::HevcConfig(HevcConfig { width: track.width(), height: track.height(), }), MediaType::VP9 => MediaConfig::Vp9Config(Vp9Config { width: track.width(), height: track.height(), }), MediaType::AAC => MediaConfig::AacConfig(AacConfig { bitrate: track.bitrate(), profile: track.audio_profile()?, freq_index: track.sample_freq_index()?, chan_conf: track.channel_config()?, }), MediaType::TTXT => MediaConfig::TtxtConfig(TtxtConfig {}), }; let track_conf = TrackConfig { track_type: track.track_type()?, timescale: track.timescale(), language: track.language().to_string(), media_conf, }; mp4_writer.add_track(&track_conf)?; } // Copy all samples from all tracks for track_id in mp4_reader.tracks().keys().copied().collect::>() { let sample_count = mp4_reader.sample_count(track_id)?; for sample_idx in 0..sample_count { let sample_id = sample_idx + 1; if let Some(sample) = mp4_reader.read_sample(track_id, sample_id)? { mp4_writer.write_sample(track_id, &sample)?; } } } mp4_writer.write_end()?; Ok(()) } fn main() -> Result<()> { copy_mp4("input.mp4", "output.mp4")?; println!("File copied successfully"); Ok(()) } ``` -------------------------------- ### Parse Fragmented MP4 Streams with Movie Fragments in Rust Source: https://context7.com/alfg/mp4-rust/llms.txt Handle fragmented MP4 files by reading initialization segments and media fragments separately, then accessing samples from each fragment. Requires separate init and fragment files. Demonstrates iteration over tracks and samples with error handling for missing tracks. ```rust use std::fs::File; use std::io::BufReader; use mp4::Result; fn main() -> Result<()> { // Read initialization segment let init_file = File::open("init.mp4")?; let init_size = init_file.metadata()?.len(); let init_reader = BufReader::new(init_file); let mp4 = mp4::Mp4Reader::read_header(init_reader, init_size)?; if mp4.is_fragmented() { println!("File is fragmented"); println!("Movie fragments: {}", mp4.moofs.len()); } // Read fragment segment let frag_file = File::open("fragment1.m4s")?; let frag_size = frag_file.metadata()?.len(); let frag_reader = BufReader::new(frag_file); // Parse fragment using base MP4 header let mut frag_mp4 = mp4.read_fragment_header(frag_reader, frag_size)?; // Read samples from fragment for track_id in frag_mp4.tracks().keys().copied().collect::>() { let sample_count = frag_mp4.sample_count(track_id)?; println!("Fragment track {} has {} samples", track_id, sample_count); for sample_idx in 0..sample_count { let sample_id = sample_idx + 1; if let Some(sample) = frag_mp4.read_sample(track_id, sample_id)? { println!(" Sample {}: {} bytes", sample_id, sample.bytes.len()); } } } Ok(()) } ``` -------------------------------- ### Add mp4 Dependency to Cargo Project Source: https://github.com/alfg/mp4-rust/blob/master/README.md Instructions for adding the `mp4` library as a dependency to a Rust project using Cargo. This can be done either by directly modifying the `Cargo.toml` file or by using the `cargo add` command. ```toml [dependencies] mp4 = "0.14.0" ``` ```bash cargo add mp4 ``` -------------------------------- ### Read MP4 File Header and Metadata in Rust Source: https://github.com/alfg/mp4-rust/blob/master/README.md This Rust code snippet demonstrates how to read the header of an MP4 file using the `mp4` library. It opens a file, reads its metadata, parses the MP4 header, and then prints information such as the major brand, timescale, file size, compatible brands, duration, and details about each track within the MP4 file. It requires standard Rust file I/O and the `mp4` crate. ```rust 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(()) } ``` -------------------------------- ### Handle MP4 File Parsing Errors in Rust Source: https://context7.com/alfg/mp4-rust/llms.txt Implement comprehensive error handling for MP4 operations including file I/O, header parsing, and sample retrieval. Catches specific error types like BoxNotFound, InvalidData, and TrakNotFound with appropriate error messages. Essential for robust MP4 processing applications. ```rust use std::fs::File; use std::io::BufReader; use mp4::{Result, Error}; fn process_mp4(path: &str) -> Result<()> { let f = File::open(path)?; let size = f.metadata()?.len(); let reader = BufReader::new(f); let mp4 = match mp4::Mp4Reader::read_header(reader, size) { Ok(mp4) => mp4, Err(Error::BoxNotFound(box_type)) => { eprintln!("Required box not found: {:?}", box_type); return Err(Error::BoxNotFound(box_type)); } Err(Error::InvalidData(msg)) => { eprintln!("Invalid MP4 data: {}", msg); return Err(Error::InvalidData(msg)); } Err(e) => return Err(e), }; let track_id = 1; match mp4.sample_count(track_id) { Ok(count) => println!("Track {} has {} samples", track_id, count), Err(Error::TrakNotFound(id)) => { eprintln!("Track {} not found", id); return Err(Error::TrakNotFound(id)); } Err(e) => return Err(e), } Ok(()) } fn main() { match process_mp4("video.mp4") { Ok(_) => println!("Processing completed successfully"), Err(e) => eprintln!("Error processing MP4: {}", e), } } ``` -------------------------------- ### Extract and Display MP4 File Metadata in Rust Source: https://context7.com/alfg/mp4-rust/llms.txt Read and access movie-level metadata from MP4 files, including creation/modification times, duration, timescale, and iTunes-style metadata tags. Requires the mp4 crate and a valid MP4 file. Returns metadata or error if file is invalid or required boxes are missing. ```rust use std::fs::File; use std::io::BufReader; use mp4::Result; fn main() -> Result<()> { let f = File::open("video.mp4")?; let size = f.metadata()?.len(); let reader = BufReader::new(f); let mp4 = mp4::Mp4Reader::read_header(reader, size)?; // Access movie-level metadata println!("Creation time: {}", mp4.moov.mvhd.creation_time); println!("Modification time: {}", mp4.moov.mvhd.modification_time); println!("Duration: {:?}", mp4.duration()); println!("Timescale: {}", mp4.timescale()); // Access metadata tags (if available) if let Some(metadata) = mp4.metadata() { println!("Metadata found"); // Access iTunes-style metadata tags } // Access event message boxes (for fragmented MP4) if !mp4.emsgs.is_empty() { println!("Event messages: {}", mp4.emsgs.len()); for emsg in &mp4.emsgs { println!(" scheme_id_uri: {}", emsg.scheme_id_uri); println!(" value: {}", emsg.value); } } Ok(()) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.