Python binding
Status: ✅ verified — the
mediawaypackage inmediaway/is real (pure-Pythonctypesover the C ABI) and the examples inexamples/run against the native libraries: mux/demux roundtrip, real H.264 encode, real camera + mic capture. This README is the DX contract the package implements: context managers, exceptions, Rational-second timestamps, bytes for buffers.
See the C binding README for the underlying C ABI contract (status enums, ownership, thread confinement) — the Python package translates that ABI into idiomatic Python.
The native library behind that ABI is 100% Rust — no libav*/GPL codec
dependencies, memory-safe by construction on the native side. This package is
a thin ctypes wrapper, not a reimplementation.
Platforms: Windows x64 is the fully hardware-verified platform (device/pipeline capture and encode). Linux x64 is container-verified (mux/demux); device/pipeline capability on Linux is untested here.
What Mediaway is (the capabilities)
A streaming-first media stack. The C ABI currently covers three capabilities (full
detail in ../c/README.md and docs/spec/c-ffi.md):
- Container — mux + demux, all 8
mediaway-containerformats: MP4/WebM shareMuxer/Demuxer(format=ContainerFormat.MP4/.WEBM, typestated Open→Live viabegin(), never touches files — the caller owns byte I/O). Ogg/ADTS/FLV/MPEG-TS/MP3 get dedicated classes (OggMuxer/OggDemuxer,AdtsMuxer/AdtsDemuxer,FlvMuxer/FlvDemuxer,TsMuxer/TsDemuxer,Mp3Muxer/Mp3Demuxer) reflecting each format's own C ABI shape — see each module's (_container_*.py) top comment. WAV is mux-only (WavMuxer, consumingfinish()); demux is the one-shotwav_parse()function, not a class at all. These 6 formats useRawPacket(ABI-native integer pts/dts, notRationalseconds) since none of them have MP4's per-track time base to convert against. Fully real, all formats run-verified. - Pipeline — auto video encode → fMP4, plus decode: one call picks the best
available OS/GPU encoder for a config, wires it into an internal MP4 muxer;
finish()returns complete MP4 bytes. The audio encoder is separate (ABI v2, adr/0003):AudioEncoder.open()streams AAC (or Opus) packets for the caller's own muxer. Decode is the mirror shape (adr/0004, adr/pipeline/0006):DecodeSessionwraps the best available video decoder (CPU output only; Windows/WMF today),AudioDecodeSessionwraps the cross-platform Opus decoder — both single-step handles (the handle IS the decoder),NO_BACKENDraisesDecoderUnavailableErrorgracefully. - Device — capture: camera (CPU frames), microphone/loopback (PCM), hotplug.
Screen capture is real (GPU-backed, DXGI Desktop Duplication) via the
GpuDevicefactory (adr/0007-gpu-device-factory.md) —VideoCapture.open(source= "screen")builds one internally, or share your own with an encoder. There is no CPU pixel readback path for Screen frames; real pixels only ever move throughEncodeSession.write_frame_from_desktop_capture(adr/pipeline/0005). Window capture is stillUNSUPPORTEDfrom C (no constructor this pass) — an honest gap.
The real ABI beneath (what the wrapper wraps)
DLLs: mediaway_ffi, mediaway_ffi, mediaway_ffi (built
for x86_64-pc-windows-gnu, see the C README's build recipe). Headers
crates/mediaway-*-ffi/include/mediaway/{container,pipeline,device}.h are the
authoritative layout.
- Opaque handles, all thread-confined (no concurrent calls on one handle).
- Every status is a per-crate enum,
OK = 0; a caught Rust panic poisons the handle.NO_BACKEND/UNSUPPORTEDare expected outcomes, not errors. - Ownership: borrowed inputs valid for the call only (the wrapper must copy in);
owned outputs (
poll_bytesbuffers, demuxed packets/stream info, encodefinishbuffers, polled device frames) must be released via the matching_free— the wrapper's job is to make this automatic (context managers / finalizers). - Handle-consumption traps the wrapper MUST hide:
mediaway_encode_session_openconsumes the encoder unconditionally;mediaway_encode_session_finishconsumes the session. Python can hide this by foldingopenintoEncodeSessionconstruction and makingfinishterminal.
Ideal API — the DX contract
A single mediaway package, pure-Python ctypes glue + idiomatic wrappers.
snake_case everywhere (Python convention beats the C names): Rational,
VideoStreamInfo, AudioStreamInfo, Packet, Codec (enum), VideoFrame;
classes Muxer, Demuxer, EncodeSession, AutoVideoEncoder, VideoCapture,
AudioCapture, GpuDevice.
- Context managers:
with Muxer() as m:,with Demuxer() as d:,with EncodeSession(...) as s:—__exit__closes the underlying handle (and, for capture sessions, joins the backend worker thread). This is the primary lifecycle shape; explicit.close()exists for non-withusers. - Exceptions: a
MediawayErrorbase carrying the raw status code, with subclasses for the expected outcomes (EncoderUnavailableError,DeviceUnavailableError,CaptureUnsupportedError) so examples can catch-and-continue rather than crash on missing hardware. No status-code checking in example bodies. - Typestate as two classes (mirrors C++):
Muxer(Open:add_video_track/add_audio_track) →.begin()returnsLiveMuxer(push_packet / flush / poll_bytes). Calling track registration on aLiveMuxeris impossible, matching the ABI'sINVALID_STATE. - bytes for byte buffers:
poll_bytes() -> bytes;push_bytes(bytes);packet.payload -> bytes;frame.data -> bytes(NV12/BGRA8). The wrapper copies out of borrowed/owned native buffers — nomemoryviewleaking into the API. Rational(num, den)as a smalldataclass(frozen=True); info structs as dataclasses.EncodeSession(encoder)takes ownership of the encoder object;finish() -> bytesis terminal (noclose()after it).
Example scenarios
examples/ mirrors the Rust examples/ layout — sector subfolders, one file per
scenario (English comments only; each file's header comment states real vs.
aspirational):
| File | Capability | Real today? |
|---|---|---|
container/mux_roundtrip.py |
mux 90 fake video + audio packets → fMP4 → demux back, count packets | ✅ run verified |
pipeline/encode_to_mp4.py |
auto H.264 encode of 90 synthetic NV12 frames → out.mp4 |
✅ run verified |
pipeline/encode_audio.py |
auto AAC encode of 96 synthetic F32 stereo frames → audio-only fMP4 (ABI v2) | ✅ run verified |
pipeline/decode_roundtrip.py |
auto H.264 decode (encode→mux→demux→decode) + Opus audio decode round trip | ✅ run verified |
device/camera_record.py |
camera + mic → H.264 + AAC → ONE two-track MP4 (remuxed; audio track registered with the encoder's AudioSpecificConfig) | ✅ run verified on real hardware; video-only fallback without mic/audio backend |
device/capture_microphone.py |
microphone capture, raw PCM | ✅ run verified (real mic) |
pipeline/screen_record.py |
screen + mic → encode → MP4, via GpuDevice + the capture-to-encode bridge |
✅ run verified on real hardware (GPU-input encode gracefully skips as a known driver/encoder limitation, not a bug); mic PCM drained, not muxed — see camera_record.py for two-track remux |
device/capture_screen.py |
screen capture only, via GpuDevice |
✅ run verified on real hardware |
Rules
- English comments only.
- Map existing Rust surfaces; do not invent capabilities the Rust side doesn't have.
- Wrap the ABI fully: no
ctypestypes or raw handles visible in examples. - Not part of the Cargo workspace; durable API changes require an ADR (ADR-0004).
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 mediaway-0.1.8.tar.gz.
File metadata
- Download URL: mediaway-0.1.8.tar.gz
- Upload date:
- Size: 629.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e76c421699e3843ed7fb41f74dbab796786e9db8b0b88ce003130d79f10ef78
|
|
| MD5 |
a35380e7af6de5c84ad2dedeaa981139
|
|
| BLAKE2b-256 |
b84bad7fbb7cba359ad5889d0c5bea158fdbace1ff7ca88063694cdcd1aea2a3
|
Provenance
The following attestation bundles were made for mediaway-0.1.8.tar.gz:
Publisher:
release.yml on nyxways/mediaway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mediaway-0.1.8.tar.gz -
Subject digest:
3e76c421699e3843ed7fb41f74dbab796786e9db8b0b88ce003130d79f10ef78 - Sigstore transparency entry: 2534743785
- Sigstore integration time:
-
Permalink:
nyxways/mediaway@131bd967187d323f03f08edec52d0ffa82b67267 -
Branch / Tag:
refs/heads/release/v0.1.8 - Owner: https://github.com/nyxways
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@131bd967187d323f03f08edec52d0ffa82b67267 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mediaway-0.1.8-py3-none-win_amd64.whl.
File metadata
- Download URL: mediaway-0.1.8-py3-none-win_amd64.whl
- Upload date:
- Size: 4.1 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78c538c2f671385814f9c715c62d71c346cc5a220af48dfe5ecaeb83d35a77b8
|
|
| MD5 |
1849512d2c8152237139a2acee68cbba
|
|
| BLAKE2b-256 |
b2df38d1923aa700fe414854f4714606a0427e0fcd50b453d45ad87fad179f17
|
Provenance
The following attestation bundles were made for mediaway-0.1.8-py3-none-win_amd64.whl:
Publisher:
release.yml on nyxways/mediaway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mediaway-0.1.8-py3-none-win_amd64.whl -
Subject digest:
78c538c2f671385814f9c715c62d71c346cc5a220af48dfe5ecaeb83d35a77b8 - Sigstore transparency entry: 2534743915
- Sigstore integration time:
-
Permalink:
nyxways/mediaway@131bd967187d323f03f08edec52d0ffa82b67267 -
Branch / Tag:
refs/heads/release/v0.1.8 - Owner: https://github.com/nyxways
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@131bd967187d323f03f08edec52d0ffa82b67267 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mediaway-0.1.8-py3-none-manylinux_2_39_x86_64.whl.
File metadata
- Download URL: mediaway-0.1.8-py3-none-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 984.5 kB
- Tags: Python 3, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7edf039d971c304f57b69361f4e93604c5bc4eccf5c05acbaa34ca4c1d117553
|
|
| MD5 |
7be322ffcb8592fac50bcbfd19054227
|
|
| BLAKE2b-256 |
195dd944f3593b2abbde3ccb64992e1e9da4dd90aacf5cc00c8f7e55800a0865
|
Provenance
The following attestation bundles were made for mediaway-0.1.8-py3-none-manylinux_2_39_x86_64.whl:
Publisher:
release.yml on nyxways/mediaway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mediaway-0.1.8-py3-none-manylinux_2_39_x86_64.whl -
Subject digest:
7edf039d971c304f57b69361f4e93604c5bc4eccf5c05acbaa34ca4c1d117553 - Sigstore transparency entry: 2534743847
- Sigstore integration time:
-
Permalink:
nyxways/mediaway@131bd967187d323f03f08edec52d0ffa82b67267 -
Branch / Tag:
refs/heads/release/v0.1.8 - Owner: https://github.com/nyxways
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@131bd967187d323f03f08edec52d0ffa82b67267 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mediaway-0.1.8-py3-none-macosx_11_0_x86_64.whl.
File metadata
- Download URL: mediaway-0.1.8-py3-none-macosx_11_0_x86_64.whl
- Upload date:
- Size: 651.5 kB
- Tags: Python 3, 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 |
001c016959ad497f8c203baec32fbd72dc28273bfcc3bfc39609c68094f0d155
|
|
| MD5 |
02a59459ad1a15e905fa0aca1413e7d4
|
|
| BLAKE2b-256 |
17548dcfc7de206407617fc9ac4c38986aa8e6842891c006adfc2df882513d8c
|
Provenance
The following attestation bundles were made for mediaway-0.1.8-py3-none-macosx_11_0_x86_64.whl:
Publisher:
release.yml on nyxways/mediaway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mediaway-0.1.8-py3-none-macosx_11_0_x86_64.whl -
Subject digest:
001c016959ad497f8c203baec32fbd72dc28273bfcc3bfc39609c68094f0d155 - Sigstore transparency entry: 2534744127
- Sigstore integration time:
-
Permalink:
nyxways/mediaway@131bd967187d323f03f08edec52d0ffa82b67267 -
Branch / Tag:
refs/heads/release/v0.1.8 - Owner: https://github.com/nyxways
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@131bd967187d323f03f08edec52d0ffa82b67267 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mediaway-0.1.8-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: mediaway-0.1.8-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 631.8 kB
- Tags: Python 3, 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 |
763c0d05ffdb4c5f6eb78d037d7b578bdf4aac4ca4309986a8a1d58bffd2c6ba
|
|
| MD5 |
a914891ca0e8926f7f1ede544b1c26e7
|
|
| BLAKE2b-256 |
fbfbda7f0c1d868fed9f6d9be1514fc1b433d088057dd4ac94a34e78d7e4922a
|
Provenance
The following attestation bundles were made for mediaway-0.1.8-py3-none-macosx_11_0_arm64.whl:
Publisher:
release.yml on nyxways/mediaway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mediaway-0.1.8-py3-none-macosx_11_0_arm64.whl -
Subject digest:
763c0d05ffdb4c5f6eb78d037d7b578bdf4aac4ca4309986a8a1d58bffd2c6ba - Sigstore transparency entry: 2534744019
- Sigstore integration time:
-
Permalink:
nyxways/mediaway@131bd967187d323f03f08edec52d0ffa82b67267 -
Branch / Tag:
refs/heads/release/v0.1.8 - Owner: https://github.com/nyxways
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@131bd967187d323f03f08edec52d0ffa82b67267 -
Trigger Event:
push
-
Statement type: