### Integrate mp4parse via C FFI Source: https://context7.com/mozilla/mp4parse-rust/llms.txt Provides an example of using the mp4parse_capi to interact with the library from C code. It demonstrates setting up a read callback, initializing the parser, and querying track information. ```c #include "mp4parse.h" #include static isize read_callback(uint8_t* buf, size_t size, void* userdata) { FILE* file = (FILE*)userdata; size_t bytes_read = fread(buf, 1, size, file); return bytes_read > 0 ? (isize)bytes_read : -1; } int main() { FILE* file = fopen("video.mp4", "rb"); if (!file) return 1; Mp4parseIo io = { .read = read_callback, .userdata = file }; Mp4parseParser* parser = NULL; Mp4parseStatus status = mp4parse_new(&io, &parser); if (status == MP4PARSE_STATUS_OK) { uint32_t track_count = 0; mp4parse_get_track_count(parser, &track_count); printf("Found %u tracks\n", track_count); for (uint32_t i = 0; i < track_count; i++) { Mp4parseTrackInfo info = {0}; if (mp4parse_get_track_info(parser, i, &info) == MP4PARSE_STATUS_OK) { printf("Track %u: type=%d, duration=%llu\n", i, info.track_type, info.duration); } } mp4parse_free(parser); } fclose(file); return 0; } ``` -------------------------------- ### Accessing Video Codec Configuration in Rust Source: https://context7.com/mozilla/mp4parse-rust/llms.txt Demonstrates how to iterate through MP4 tracks to identify video sample entries and extract codec-specific configuration data such as AVC, HEVC, AV1, and VP9 parameters. ```rust use mp4parse::{read_mp4, ParseStrictness, SampleEntry, VideoCodecSpecific}; use std::fs::File; let mut file = File::open("video.mp4").expect("Failed to open file"); let context = read_mp4(&mut file, ParseStrictness::Normal).expect("Parse failed"); for track in &context.tracks { if let Some(ref stsd) = track.stsd { for desc in &stsd.descriptions { if let SampleEntry::Video(video) = desc { match &video.codec_specific { VideoCodecSpecific::AVCConfig(avc_data) => { println!("AVC config: {} bytes", avc_data.len()); } VideoCodecSpecific::HEVCConfig(hevc_data) => { println!("HEVC config: {} bytes", hevc_data.len()); } VideoCodecSpecific::AV1Config(av1c) => { println!("AV1 profile: {}, level: {}", av1c.profile, av1c.level); let config_obus = av1c.config_obus(); println!("Config OBUs: {} bytes", config_obus.len()); } VideoCodecSpecific::VPxConfig(vpx) => { println!("VP9 bit depth: {}", vpx.bit_depth); } _ => {} } } } } } ``` -------------------------------- ### Accessing Audio Codec Configuration in Rust Source: https://context7.com/mozilla/mp4parse-rust/llms.txt Demonstrates how to extract audio-specific metadata and decoder initialization data for formats like AAC, Opus, FLAC, and ALAC from an MP4 file. ```rust use mp4parse::{read_mp4, ParseStrictness, SampleEntry, AudioCodecSpecific, CodecType}; use std::fs::File; let mut file = File::open("audio.mp4").expect("Failed to open file"); let context = read_mp4(&mut file, ParseStrictness::Normal).expect("Parse failed"); for track in &context.tracks { if let Some(ref stsd) = track.stsd { for desc in &stsd.descriptions { if let SampleEntry::Audio(audio) = desc { match &audio.codec_specific { AudioCodecSpecific::ES_Descriptor(esds) => { println!("Decoder config: {} bytes", esds.decoder_specific_data.len()); } AudioCodecSpecific::OpusSpecificBox(opus) => { let mut opus_header = Vec::new(); mp4parse::serialize_opus_header(opus, &mut opus_header).expect("Failed to serialize"); println!("OpusHead: {} bytes", opus_header.len()); } AudioCodecSpecific::FLACSpecificBox(flac) => { if !flac.blocks.is_empty() { println!("FLAC STREAMINFO: {} bytes", flac.blocks[0].data.len()); } } AudioCodecSpecific::ALACSpecificBox(alac) => { println!("ALAC magic cookie: {} bytes", alac.data.len()); } _ => {} } } } } } ``` -------------------------------- ### Extract iTunes Metadata in Rust Source: https://context7.com/mozilla/mp4parse-rust/llms.txt Shows how to read iTunes-style metadata, including title, artist, album, track numbers, genre, and cover art, from the userdata box of an MP4 file. ```rust use mp4parse::{read_mp4, ParseStrictness, Genre, MediaType, AdvisoryRating}; use std::fs::File; let mut file = File::open("music.mp4").expect("Failed to open file"); let context = read_mp4(&mut file, ParseStrictness::Normal).expect("Parse failed"); if let Some(Ok(userdata)) = context.userdata { if let Some(meta) = userdata.meta { if let Some(ref title) = meta.title { println!("Title: {}", String::from_utf8_lossy(title)); } if let Some(ref artist) = meta.artist { println!("Artist: {}", String::from_utf8_lossy(artist)); } if let Some(ref album) = meta.album { println!("Album: {}", String::from_utf8_lossy(album)); } if let Some(track) = meta.track_number { print!("Track: {}", track); if let Some(total) = meta.total_tracks { print!("/{}", total); } println!(); } match &meta.genre { Some(Genre::StandardGenre(id)) => println!("Genre ID: {}", id), Some(Genre::CustomGenre(name)) => { println!("Genre: {}", String::from_utf8_lossy(name)); } None => {} } if let Some(ref covers) = meta.cover_art { for (i, cover) in covers.iter().enumerate() { println!("Cover art {}: {} bytes", i, cover.len()); } } } } ``` -------------------------------- ### Parse Encrypted Media Content in Rust Source: https://context7.com/mozilla/mp4parse-rust/llms.txt Demonstrates how to extract PSSH boxes and track encryption information (tenc) from an MP4 file using the mp4parse crate. It iterates through tracks to identify protection schemes and encryption parameters. ```rust use mp4parse::{read_mp4, ParseStrictness, SampleEntry}; use std::fs::File; let mut file = File::open("encrypted.mp4").expect("Failed to open file"); let context = read_mp4(&mut file, ParseStrictness::Normal).expect("Parse failed"); for pssh in &context.psshs { println!("System ID: {:02x?}", pssh.system_id.as_slice()); for kid in &pssh.kid { println!("Key ID: {:02x?}", kid.as_slice()); } println!("PSSH box: {} bytes", pssh.box_content.len()); } for track in &context.tracks { if let Some(ref stsd) = track.stsd { for desc in &stsd.descriptions { let protection_info = match desc { SampleEntry::Video(v) => &v.protection_info, SampleEntry::Audio(a) => &a.protection_info, _ => continue, }; for sinf in protection_info { if let Some(ref tenc) = sinf.tenc { println!("Original format: {:?}", sinf.original_format); if let Some(ref schm) = sinf.scheme_type { println!("Scheme: {:?}", schm.scheme_type); } println!("Encrypted: {}", tenc.is_encrypted > 0); println!("IV size: {}", tenc.iv_size); println!("Key ID: {:02x?}", tenc.kid.as_slice()); if let Some(crypt) = tenc.crypt_byte_block_count { println!("Crypt/Skip pattern: {}:{}", crypt, tenc.skip_byte_block_count.unwrap_or(0)); } } } } } } ``` -------------------------------- ### Configure Parse Strictness Levels in Rust Source: https://context7.com/mozilla/mp4parse-rust/llms.txt Demonstrates how to use the ParseStrictness enum to control validation behavior when parsing MP4 and AVIF files. It covers Permissive, Normal, and Strict modes to balance compatibility and standard compliance. ```rust use mp4parse::{read_mp4, read_avif, ParseStrictness}; use std::fs::File; // Permissive: Accept files with minor spec violations let mut file = File::open("possibly_broken.mp4").unwrap(); let result = read_mp4(&mut file, ParseStrictness::Permissive); // Normal (default): Error on "shall" requirements, warn on "should" let mut file = File::open("video.mp4").unwrap(); let result = read_mp4(&mut file, ParseStrictness::Normal); // Strict: Error on both "shall" and "should" requirements let mut file = File::open("video.mp4").unwrap(); let result = read_mp4(&mut file, ParseStrictness::Strict); // AVIF parsing with strictness let mut avif = File::open("image.avif").unwrap(); match read_avif(&mut avif, ParseStrictness::Normal) { Ok(context) => { if !context.unsupported_features.is_empty() { println!("Warning: Some features not fully supported"); } } Err(e) => println!("Parse error: {:?}", e), } ``` -------------------------------- ### Parse AVIF Images in Rust Source: https://context7.com/mozilla/mp4parse-rust/llms.txt Parses AVIF (AV1 Image File Format) files, including still images, animated sequences, and alpha channels, using the `read_avif` function. It returns an `AvifContext` providing access to primary image data, alpha channel information, spatial extents, and animation sequence details. ```rust use mp4parse::{read_avif, ParseStrictness, AvifContext}; use std::fs::File; let mut file = File::open("image.avif").expect("Failed to open AVIF"); let context: AvifContext = read_avif(&mut file, ParseStrictness::Normal) .expect("Failed to parse AVIF"); // Access primary image data (the main color image) if let Some(primary_data) = context.primary_item_coded_data() { println!("Primary image size: {} bytes", primary_data.len()); // primary_data contains raw AV1 OBU data ready for decoding } // Check for alpha channel if let Some(alpha_data) = context.alpha_item_coded_data() { println!("Alpha image size: {} bytes", alpha_data.len()); println!("Premultiplied alpha: {}", context.premultiplied_alpha); } // Get image spatial extents if let Ok(extents_ptr) = context.spatial_extents_ptr() { if !extents_ptr.is_null() { // Safe only if pointer is valid unsafe { let extents = &*extents_ptr; println!("Image dimensions available"); } } } // Check for animated sequence (AVIS) if let Some(ref sequence) = context.sequence { println!("Animated AVIF with {} tracks", sequence.tracks.len()); for track in &sequence.tracks { println!(" Track type: {:?}", track.track_type); } } ``` -------------------------------- ### Parse MP4 Files in Rust Source: https://context7.com/mozilla/mp4parse-rust/llms.txt Parses an MP4 file from any `Read` source using the `read_mp4` function. It returns a `MediaContext` containing track information such as timescales, durations, and codec-specific data. Supports various track types including video and audio. ```rust use mp4parse::{read_mp4, ParseStrictness, MediaContext, TrackType, SampleEntry}; use std::fs::File; use std::io::Cursor; // Parse from a file let mut file = File::open("video.mp4").expect("Failed to open file"); let context: MediaContext = read_mp4(&mut file, ParseStrictness::Normal) .expect("Failed to parse MP4"); // Access global timescale (ticks per second) if let Some(timescale) = context.timescale { println!("Movie timescale: {} ticks/second", timescale.0); } // Iterate through all tracks for track in &context.tracks { match track.track_type { TrackType::Video => { println!("Video track ID: {:?}", track.track_id); if let Some(ref stsd) = track.stsd { for desc in &stsd.descriptions { if let SampleEntry::Video(v) = desc { println!(" Resolution: {}x{}", v.width, v.height); println!(" Codec: {:?}", v.codec_type); } } } } TrackType::Audio => { println!("Audio track ID: {:?}", track.track_id); if let Some(ref stsd) = track.stsd { for desc in &stsd.descriptions { if let SampleEntry::Audio(a) = desc { println!(" Sample rate: {}", a.samplerate); println!(" Channels: {}", a.channelcount); println!(" Codec: {:?}", a.codec_type); } } } } _ => {} } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.