mxfuse
Rust-first MXF container primitives with Python and Node.js bindings, built on a statically linked bmx core.
Essence goes in and essence comes out. A frame is the KLV payload with the key and length stripped. You can reproduce any Generic Container mapping exactly — element key, BER length, descriptor class, and the writable descriptor fields — and read that mapping back: the coding UL and the descriptor survive a round trip. Pin product info, creation date, generation UID, and package UMIDs on write. The core is synchronous: one reader or writer per thread.
npm i mxfuse
uv add mxfuse
Wheels and napi prebuilds are the supported install path. They statically link
bmx, libMXF, libMXF++, expat, and uriparser. On Linux the C++ runtime
(libstdc++.so.6, libgcc_s.so.1) stays dynamic; both are on the manylinux
allowlist. The Rust crate is not on crates.io yet; use a git dependency
(cargo add --git https://github.com/patrickhulce/mxfuse mxfuse). That is a
source build and needs CMake plus a C++ toolchain. uriparser, expat, and
cmake-git-version-tracking are pre-vendored, and libuuid is replaced by a
shim-provided uuid_generate, so a source build does not need git at
configure time, network access, or uuid-dev.
v0.1.0 is an 0.x release: the API may change. Prebuilt artifacts cover
linux x64/arm64 (glibc), macOS x64/arm64, and Windows x64. musl, Windows
arm64, and other triples are source-build only.
Limitations
- OP1a, frame-wrapped only for v1. No AS-02, IMF flavour, RDD 9, D-10, Avid OP-Atom, or clip wrapping as a write target.
- No sub-descriptors. A private mapping that needs a registered
sub-descriptor set (JPEG 2000, JPEG XS, or a future
JXLPictureSubDescriptor) cannot write or read those items yet. - Display and sampled geometry follow stored width/height on write.
- Essence in, essence out. A frame is the KLV payload with the key and length stripped. No image codec decode or encode.
- Synchronous core. One reader or writer per thread.
Flavour.SINGLE_PASSneeds a known duration and a constant-bytes-per-element codec. Python and Rust can write that flavour to a pipe; NodewriteMxfaccepts a filesystem path only.WAVE_PCMis pinned to 48 kHz in OP1a.- Node custom
ByteSourceloads the whole file. Path and buffer opens use native range I/O. Remote / S3 range reads are a Python and Rust feature. - bmx and libMXF are BSD-3-Clause.
mxfuseis MIT; the combined binary carries both. SeeTHIRD_PARTY_NOTICES.md.
Usage
Python
from mxfuse import open_mxf, ReadOptions, TrackKind
options = ReadOptions(read_ahead=1 << 20, cache_bytes=64 << 20)
with open("input.mxf", "rb") as f:
with open_mxf(f, options=options) as clip:
print(clip.edit_rate, clip.duration)
for track in clip.tracks:
print(track.index, track.kind, track.essence_type, track.essence_container_ul)
clip.select(t for t in clip.tracks if t.kind is TrackKind.PICTURE)
clip.seek(0)
for package in clip.read(count=1):
for frame in package.frames:
frame.data
frame.element_key
frame.file_position
A custom byte source is any object that implements read, seek, tell, and
optionally size. Regular files infer size via seek(0, 2). Tune read_ahead
and cache_bytes for remote sources: make bench on a 61 MB synthetic OP1a
sought the last picture frame in 41,007 reads (127 KB) with both off, and 3
reads (1.2 MB) with the defaults. A 1 MB window overshoots into neighbouring
interleaved essence; set both to 0 for payload-level track isolation.
from mxfuse import ClipSpec, EssenceType, Flavour, TrackSpec, write_mxf
spec = ClipSpec(
edit_rate=(25, 1),
flavour=Flavour.DEFAULT,
duration=len(images),
tracks=[
TrackSpec(EssenceType.UNC_HD_1080P),
TrackSpec(EssenceType.WAVE_PCM, sampling_rate=48000),
],
)
with open("output.mxf", "wb") as f, write_mxf(f, spec) as clip:
for image, audio in zip(images, audios):
clip.write_unit(image, audio)
A private Generic Container mapping supplies the element key, BER length,
descriptor class, and descriptor fields. On read, track.coding_ul and the
picture descriptor identify the mapping.
from mxfuse import ClipSpec, DescriptorKind, EssenceType, PixelComponent, TrackSpec, write_mxf
spec = ClipSpec(
edit_rate=(24, 1),
duration=len(images),
system_item=True,
tracks=[
TrackSpec(
EssenceType.OPAQUE_PICTURE,
essence_container_ul="060e2b340401010d0d01030102700100",
coding_ul="060e2b340401010d0401020270000000",
stored_width=4096,
stored_height=2160,
element_type=0x70,
element_llen=8,
temporal_reordering=True,
descriptor=DescriptorKind.RGBA,
aspect_ratio=(16, 9),
video_line_map=(1, 0),
pixel_layout=(
PixelComponent(code=ord("R"), depth=32),
PixelComponent(code=ord("G"), depth=32),
PixelComponent(code=ord("B"), depth=32),
),
),
],
)
with open("output.mxf", "wb") as f, write_mxf(f, spec) as clip:
for image in images:
clip.write_unit(image)
Node
import { openMxf } from "mxfuse";
const clip = await openMxf("input.mxf", { readAhead: 1 << 20, cacheBytes: 64 << 20 });
const info = await clip.info();
await clip.select(info.tracks.filter((track) => track.kind === "picture"));
await clip.seek(0);
for (const package_ of await clip.read(1)) {
for (const frame of package_.frames) {
frame.data;
frame.elementKey;
frame.filePosition;
}
}
await clip.close();
Do not share one reader across concurrent tasks. openMxf on a custom
ByteSource (not a path or Uint8Array) reads the entire file into memory.
import { EssenceType, Flavour, writeMxf } from "mxfuse";
const writer = await writeMxf("output.mxf", {
editRate: [25, 1],
flavour: Flavour.DEFAULT,
duration: images.length,
tracks: [
{ essenceType: EssenceType.UNC_HD_1080P },
{ essenceType: EssenceType.WAVE_PCM, samplingRate: 48000 },
],
});
for (let i = 0; i < images.length; i++) {
await writer.write(0, images[i]);
await writer.write(1, audios[i]);
}
await writer.finish();
Rust
use mxfuse::{open_mxf, ReadOptions, TrackKind};
let file = std::fs::File::open("input.mxf")?;
let mut clip = open_mxf(file, ReadOptions::default())?;
let picture: Vec<_> = clip
.tracks()
.iter()
.filter(|track| track.kind == TrackKind::Picture)
.cloned()
.collect();
clip.select(picture.iter())?;
clip.seek(0)?;
for package in clip.read(1)? {
for frame in package.frames {
let _ = (frame.data, frame.element_key, frame.file_position);
}
}
use mxfuse::{write_mxf, ClipSpec, EssenceType, Flavour, Rational, TrackSpec};
let file = std::fs::File::create("output.mxf")?;
let spec = ClipSpec {
edit_rate: Rational { num: 25, den: 1 },
flavour: Flavour::DEFAULT,
duration: Some(images.len() as i64),
tracks: vec![
TrackSpec::new(EssenceType::UNC_HD_1080P),
TrackSpec {
sampling_rate: Some(48000),
..TrackSpec::new(EssenceType::WAVE_PCM)
},
],
xml: vec![],
..ClipSpec::default()
};
let mut writer = write_mxf(file, spec)?;
for (image, audio) in images.iter().zip(audios.iter()) {
writer.write(0, image)?;
writer.write(1, audio)?;
}
writer.finish()?;
file_position for frame-wrapped essence points at the KLV, with kl_size
giving the header length. Clip-wrapped essence points at the sample data and
kl_size is 0. Clip-level XML (ST 434 / generic stream) is ClipSpec.xml on
write and clip.xml on read; it is not an essence track.
Development
Prerequisites
Layout
src/
├── mxfuse-sys/ # CMake build of vendored bmx + C++ shim
├── rust-mxfuse/ # Core Rust library
├── python-mxfuse/ # PyO3 extension and Python API
└── node-mxfuse/ # napi-rs extension and TypeScript API
vendor/bmx/ # ebu/bmx v1.7 source release (offline, pristine)
patches/ # applied into gitignored src/mxfuse-sys/generated/bmx
Commands
make # build, lint, typecheck, test
make build # build all targets
make test # run all tests
make fixtures # generate tests/fixtures/sample_op1a.mxf
make bench # print read/byte costs across ReadOptions
make examples # JPEG XL Generic Container round-trip (needs .data/4KProRes.mov)
make package # materialize generated/bmx and list crate contents
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mxfuse-0.1.0.tar.gz.
File metadata
- Download URL: mxfuse-0.1.0.tar.gz
- Upload date:
- Size: 1.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eaf6a6c3e31f6b0c67b32ab486b5fb833eec7764775f10fb4e977d46b26fb52e
|
|
| MD5 |
26f76c6d83df1d6d3c86dd514a630c70
|
|
| BLAKE2b-256 |
1f749949b193039dafd286282a96ff7942feb852045e5e275b8a8474eb815df7
|
Provenance
The following attestation bundles were made for mxfuse-0.1.0.tar.gz:
Publisher:
release.yml on patrickhulce/mxfuse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mxfuse-0.1.0.tar.gz -
Subject digest:
eaf6a6c3e31f6b0c67b32ab486b5fb833eec7764775f10fb4e977d46b26fb52e - Sigstore transparency entry: 2520064163
- Sigstore integration time:
-
Permalink:
patrickhulce/mxfuse@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/patrickhulce
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mxfuse-0.1.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: mxfuse-0.1.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac412353cd3a6701628b927890ef91ed805069571689133b75425fce96b7ff8e
|
|
| MD5 |
1ac7012fb3ca3cf53eccd0dc7058ed8f
|
|
| BLAKE2b-256 |
381f5a8fab188afcfe6126161b116fa742966beb009602d3416537a062f2a727
|
Provenance
The following attestation bundles were made for mxfuse-0.1.0-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on patrickhulce/mxfuse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mxfuse-0.1.0-cp310-abi3-win_amd64.whl -
Subject digest:
ac412353cd3a6701628b927890ef91ed805069571689133b75425fce96b7ff8e - Sigstore transparency entry: 2520064736
- Sigstore integration time:
-
Permalink:
patrickhulce/mxfuse@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/patrickhulce
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mxfuse-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: mxfuse-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 1.3 MB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc1319f7ed135d52de579875c803b1aa758de4a69396e962513cdfb178c14d1a
|
|
| MD5 |
f73152c796a356d2675e61cf2b1a4102
|
|
| BLAKE2b-256 |
f19fb023298d162f053a2228c09577dad73935019de684191b601b26b1dd0920
|
Provenance
The following attestation bundles were made for mxfuse-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl:
Publisher:
release.yml on patrickhulce/mxfuse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mxfuse-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
cc1319f7ed135d52de579875c803b1aa758de4a69396e962513cdfb178c14d1a - Sigstore transparency entry: 2520065643
- Sigstore integration time:
-
Permalink:
patrickhulce/mxfuse@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/patrickhulce
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mxfuse-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: mxfuse-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 1.3 MB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ffa74719af118e32554ef71ed69924b658497d3eefbefc0673ed9faeea26d254
|
|
| MD5 |
e021097cea6dd0fb67f9089e4a4a237d
|
|
| BLAKE2b-256 |
54c0a17683bb596421f61bf2702651a67cefae70555199c4863695d2e742b129
|
Provenance
The following attestation bundles were made for mxfuse-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl:
Publisher:
release.yml on patrickhulce/mxfuse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mxfuse-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
ffa74719af118e32554ef71ed69924b658497d3eefbefc0673ed9faeea26d254 - Sigstore transparency entry: 2520064364
- Sigstore integration time:
-
Permalink:
patrickhulce/mxfuse@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/patrickhulce
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mxfuse-0.1.0-cp310-abi3-macosx_11_0_x86_64.whl.
File metadata
- Download URL: mxfuse-0.1.0-cp310-abi3-macosx_11_0_x86_64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.10+, macOS 11.0+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6101f137ae7897c9b33dd6c81722a6d7594944a6c4ccfbc789016bd89faa0919
|
|
| MD5 |
495ad7d295920c7fe9bc29ea727a6b9e
|
|
| BLAKE2b-256 |
2e2652d637962a16a9fb499c2be5bed628c6a406f93f3d971fdf3aefb725ff1e
|
Provenance
The following attestation bundles were made for mxfuse-0.1.0-cp310-abi3-macosx_11_0_x86_64.whl:
Publisher:
release.yml on patrickhulce/mxfuse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mxfuse-0.1.0-cp310-abi3-macosx_11_0_x86_64.whl -
Subject digest:
6101f137ae7897c9b33dd6c81722a6d7594944a6c4ccfbc789016bd89faa0919 - Sigstore transparency entry: 2520065047
- Sigstore integration time:
-
Permalink:
patrickhulce/mxfuse@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/patrickhulce
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mxfuse-0.1.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: mxfuse-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
336103a850a64d7c38b23ab9b65098f90cd7cda8e8462d80fe82c30e81ff1be9
|
|
| MD5 |
7b0449cb0af00cfa4b25a797dcc64048
|
|
| BLAKE2b-256 |
caf5e0a4a0a8af05f9949013a67645164de18030a2150d1f23bad9bbf91e572d
|
Provenance
The following attestation bundles were made for mxfuse-0.1.0-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on patrickhulce/mxfuse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mxfuse-0.1.0-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
336103a850a64d7c38b23ab9b65098f90cd7cda8e8462d80fe82c30e81ff1be9 - Sigstore transparency entry: 2520065368
- Sigstore integration time:
-
Permalink:
patrickhulce/mxfuse@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/patrickhulce
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7aa9c49d6f173dcec87598f3098711bffcc5ee31 -
Trigger Event:
push
-
Statement type: