Skip to main content

Python binding

Status: ✅ verified — the mediaway package in mediaway/ is real (pure-Python ctypes over the C ABI) and the examples in examples/ 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):

  1. Container — mux + demux, all 8 mediaway-container formats: MP4/WebM share Muxer/Demuxer (format=ContainerFormat.MP4/.WEBM, typestated Open→Live via begin(), 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, consuming finish()); demux is the one-shot wav_parse() function, not a class at all. These 6 formats use RawPacket (ABI-native integer pts/dts, not Rational seconds) since none of them have MP4's per-track time base to convert against. Fully real, all formats run-verified.
  2. 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): DecodeSession wraps the best available video decoder (CPU output only; Windows/WMF today), AudioDecodeSession wraps the cross-platform Opus decoder — both single-step handles (the handle IS the decoder), NO_BACKEND raises DecoderUnavailableError gracefully.
  3. Device — capture: camera (CPU frames), microphone/loopback (PCM), hotplug. Screen capture is real (GPU-backed, DXGI Desktop Duplication) via the GpuDevice factory (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 through EncodeSession.write_frame_from_desktop_capture (adr/pipeline/0005). Window capture is still UNSUPPORTED from 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 / UNSUPPORTED are expected outcomes, not errors.
  • Ownership: borrowed inputs valid for the call only (the wrapper must copy in); owned outputs (poll_bytes buffers, demuxed packets/stream info, encode finish buffers, 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_open consumes the encoder unconditionally; mediaway_encode_session_finish consumes the session. Python can hide this by folding open into EncodeSession construction and making finish terminal.

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-with users.
  • Exceptions: a MediawayError base 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() returns LiveMuxer (push_packet / flush / poll_bytes). Calling track registration on a LiveMuxer is impossible, matching the ABI's INVALID_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 — no memoryview leaking into the API.
  • Rational(num, den) as a small dataclass(frozen=True); info structs as dataclasses.
  • EncodeSession(encoder) takes ownership of the encoder object; finish() -> bytes is terminal (no close() 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 ctypes types 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

mediaway-0.1.8.tar.gz (629.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

mediaway-0.1.8-py3-none-win_amd64.whl (4.1 MB view details)

Uploaded Python 3Windows x86-64

mediaway-0.1.8-py3-none-manylinux_2_39_x86_64.whl (984.5 kB view details)

Uploaded Python 3manylinux: glibc 2.39+ x86-64

mediaway-0.1.8-py3-none-macosx_11_0_x86_64.whl (651.5 kB view details)

Uploaded Python 3macOS 11.0+ x86-64

mediaway-0.1.8-py3-none-macosx_11_0_arm64.whl (631.8 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

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

Hashes for mediaway-0.1.8.tar.gz
Algorithm Hash digest
SHA256 3e76c421699e3843ed7fb41f74dbab796786e9db8b0b88ce003130d79f10ef78
MD5 a35380e7af6de5c84ad2dedeaa981139
BLAKE2b-256 b84bad7fbb7cba359ad5889d0c5bea158fdbace1ff7ca88063694cdcd1aea2a3

See more details on using hashes here.

Provenance

The following attestation bundles were made for mediaway-0.1.8.tar.gz:

Publisher: release.yml on nyxways/mediaway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for mediaway-0.1.8-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 78c538c2f671385814f9c715c62d71c346cc5a220af48dfe5ecaeb83d35a77b8
MD5 1849512d2c8152237139a2acee68cbba
BLAKE2b-256 b2df38d1923aa700fe414854f4714606a0427e0fcd50b453d45ad87fad179f17

See more details on using hashes here.

Provenance

The following attestation bundles were made for mediaway-0.1.8-py3-none-win_amd64.whl:

Publisher: release.yml on nyxways/mediaway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mediaway-0.1.8-py3-none-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for mediaway-0.1.8-py3-none-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 7edf039d971c304f57b69361f4e93604c5bc4eccf5c05acbaa34ca4c1d117553
MD5 7be322ffcb8592fac50bcbfd19054227
BLAKE2b-256 195dd944f3593b2abbde3ccb64992e1e9da4dd90aacf5cc00c8f7e55800a0865

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mediaway-0.1.8-py3-none-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for mediaway-0.1.8-py3-none-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 001c016959ad497f8c203baec32fbd72dc28273bfcc3bfc39609c68094f0d155
MD5 02a59459ad1a15e905fa0aca1413e7d4
BLAKE2b-256 17548dcfc7de206407617fc9ac4c38986aa8e6842891c006adfc2df882513d8c

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mediaway-0.1.8-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for mediaway-0.1.8-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 763c0d05ffdb4c5f6eb78d037d7b578bdf4aac4ca4309986a8a1d58bffd2c6ba
MD5 a914891ca0e8926f7f1ede544b1c26e7
BLAKE2b-256 fbfbda7f0c1d868fed9f6d9be1514fc1b433d088057dd4ac94a34e78d7e4922a

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.8 This release

5 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page