SMPTE ST 2067 IMF parser and validator for Rust, Node.js, and the browser.
| Crate | Description |
|---|---|
imferno-core |
All parsing and validation logic |
imferno |
Command-line tool |
| Package | Description |
|---|---|
imferno |
CLI — prebuilt native binaries for all platforms |
@imferno/wasm |
WebAssembly bindings for JS/TS |
@imferno/node |
Native Node.js bindings (filesystem + hash verification) |
@imferno/schema |
JSON Schema definitions for all IMF types |
Platform binaries (installed automatically via imferno):
| Package | Platform |
|---|---|
@imferno/linux-x64-gnu |
Linux x64 |
@imferno/linux-arm64-gnu |
Linux ARM64 |
@imferno/darwin-x64 |
macOS x64 |
@imferno/darwin-arm64 |
macOS ARM64 |
@imferno/win32-x64-msvc |
Windows x64 |
@imferno/win32-arm64-msvc |
Windows ARM64 |
# CLI via npm
npm install -g imferno
# WASM bindings (browser + Node.js)
npm install @imferno/wasm
# Native Node.js bindings (filesystem access, hash verification)
npm install @imferno/node
# JSON schemas for validating imferno output
npm install @imferno/schema
# Rust crate
cargo add imferno-core# Validate an IMF package (hashes verified by default)
imferno validate ./my-imp
# JSON output
imferno validate ./my-imp --format json
# Skip hash verification for faster validation
imferno validate ./my-imp --skip-hashes
# Override rule severity
imferno validate ./my-imp --rule SegmentDuration=offimport { validatePath, formatReport } from '@imferno/node';
const result = validatePath('./my-imp');
console.log(result.validation.is_compliant);
console.log(formatReport(result));import { validate, formatReport } from '@imferno/wasm';
const result = await validate({
'ASSETMAP.xml': assetmapXml,
'PKL_abc.xml': pklXml,
'CPL_def.xml': cplXml,
});
console.log(result.validation.is_compliant);
console.log(await formatReport(result));use imferno_core::package::{read_dir, Imferno, ValidationOptions};
let files = read_dir("./my-imp")?;
let result = Imferno::parse_and_validate(files, &ValidationOptions::default());
for issue in &result.errors {
eprintln!("[{}] {}", issue.code, issue.message);
}The imferno_core::storage module abstracts where IMF packages live —
local filesystem (always on) and S3 (behind the aws-s3 feature flag).
Use package::read for cloud-aware reads:
use imferno_core::package::{read, Imferno};
use imferno_core::storage::{fs::FsStorage, StorageUri};
// Local filesystem (bare paths and file:// URIs both work)
let uri = StorageUri::parse("/path/to/imp")?;
let storage = FsStorage::new();
let files = read(&uri, &storage)?;
let package = Imferno::parse(files)?;S3 (requires --features aws-s3):
# #[cfg(feature = "aws-s3")] {
use imferno_core::storage::s3::S3Storage;
let uri = imferno_core::storage::StorageUri::parse("s3://my-bucket/path/to/imp/")?;
let storage = S3Storage::from_default()?; // uses default AWS credential chain
let files = imferno_core::package::read(&uri, &storage)?;
# }The CLI accepts the same URI forms:
imferno validate /path/to/imp
imferno validate file:///path/to/imp
imferno validate s3://my-bucket/path/to/imp/| Standard | Title | Status |
|---|---|---|
| ST 429-9 | Volume Index / Asset Map | Complete |
| ST 2067-2 | Core Constraints & Packing List | Complete |
| ST 2067-3 | Composition Playlist | Complete |
| ST 2067-9 | Sidecar Composition Map | Complete |
| ST 2067-21 | Application #2E (UHD/HDR) | Complete |
| ST 2067-201 | IAB Level 0 Plug-in | Complete |
| ST 2067-202 | ISXD Plug-in | Complete |
| ST 377-1 | MXF File Format | Partial — header partition only |
MXF test fixtures are stored as GitHub Release assets (not in git). Fetch them before running tests:
./scripts/fetch-test-data.sh
cargo test --workspacehttps://jpwesselink.github.io/imferno
If imferno is useful to your workflow, consider sponsoring the project.
MIT