Expand description
This crate provides a safe high-level API to decrypt CENC/CENS/CBC1/CBCS protected MP4 content using Bento4.
§Environment Variables
The following environment variables can be used to configure the Bento4 library location:
| Variable | Description |
|---|---|
BENTO4_DIR | Directory of a Bento4 installation. Should contain lib and include subdirectories. |
BENTO4_VENDOR | If set, always build and link against the vendored Bento4 version. |
These variables can also be prefixed with the upper-cased target architecture
(e.g. X86_64_UNKNOWN_LINUX_GNU_BENTO4_DIR), which is useful for cross-compilation.
§Quick Start
use mp4decrypt::Ap4CencDecryptingProcessor;
use std::{error::Error, fs, io::Write};
fn main() -> Result<(), Box<dyn Error>> {
// Create a processor with decryption keys
let processor = Ap4CencDecryptingProcessor::new()
.key("eb676abbcb345e96bbcf616630f1a3da", "100b6c20940f779a4589152b57d2dacb")?
.build()?;
// Decrypt in memory
let init_data = fs::read("init.mp4")?;
let segment_data = fs::read("segment.m4s")?;
let decrypted = processor.decrypt(&segment_data, Some(&init_data))?;
// Write playable MP4 (init + decrypted segment)
let mut f = fs::File::create("output.mp4")?;
f.write_all(&init_data)?;
f.write_all(&decrypted)?;
Ok(())
}§Multithreaded Decryption
The processor is thread-safe and can be shared across multiple threads using Arc.
This is useful for decrypting multiple segments in parallel:
use mp4decrypt::Ap4CencDecryptingProcessor;
use std::{fs, sync::Arc, thread};
fn main() -> Result<(), mp4decrypt::Error> {
// Create a shared processor
let processor = Arc::new(
Ap4CencDecryptingProcessor::new()
.key("eb676abbcb345e96bbcf616630f1a3da", "100b6c20940f779a4589152b57d2dacb")?
.build()?
);
let init_data = Arc::new(fs::read("init.mp4").unwrap());
// Spawn multiple threads to decrypt segments in parallel
let handles: Vec<_> = (1..=10)
.map(|i| {
let processor = Arc::clone(&processor);
let init = Arc::clone(&init_data);
thread::spawn(move || {
let segment = fs::read(format!("segment_{}.m4s", i)).unwrap();
let decrypted = processor.decrypt(&segment, Some(&*init)).unwrap();
// Write playable MP4 (init + decrypted segment)
let mut f = fs::File::create(format!("decrypted_{}.mp4", i)).unwrap();
use std::io::Write;
f.write_all(&*init).unwrap();
f.write_all(&decrypted).unwrap();
})
})
.collect();
// Wait for all threads to complete
for handle in handles {
handle.join().expect("Thread panicked");
}
Ok(())
}§File-Based Decryption
For large files or when you want to avoid loading everything into memory:
use mp4decrypt::Ap4CencDecryptingProcessor;
fn main() -> Result<(), mp4decrypt::Error> {
let processor = Ap4CencDecryptingProcessor::new()
.key("eb676abbcb345e96bbcf616630f1a3da", "100b6c20940f779a4589152b57d2dacb")?
.build()?;
// Decrypt directly from file to file
processor.decrypt_file(
"encrypted_segment.m4s",
"decrypted_segment.m4s",
Some("init.mp4"),
)?;
Ok(())
}Structs§
- Ap4Cenc
Decrypting Processor - A CENC (Common Encryption) decrypting processor for MP4 files.
- Ap4Cenc
Decrypting Processor Builder - Builder for creating
Ap4CencDecryptingProcessorinstances.
Enums§
- Error
- Error types returned by the mp4decrypt operations.