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.

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: sans-io fragmented-MP4 muxer (register video/audio tracks, begin() → live, push packets, flush, poll_bytes(); the muxer never touches files — the caller owns byte I/O) and demuxer (push_bytes, streams(), poll_packet(), optional ClearKey key). Fully real.
  2. Pipeline — auto video encode → fMP4: one call picks the best available OS/GPU encoder for a config, wires it into an internal MP4 muxer; finish() returns complete MP4 bytes. Video only — the audio encoder is separate (ABI v2, adr/0003): AudioEncoder.open() streams AAC packets for the caller's own muxer.
  3. Device — capture: camera (CPU frames), microphone/loopback (PCM), hotplug. Screen capture is UNSUPPORTED from C today (needs a GPU device handle with no C representation yet) — an honest gap, not a bug.

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.

  • 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 (96 packets → 27372 bytes fMP4)
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 (47 frames + 80 AAC packets → ~251 KB two-track MP4); 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 🚧 aspirational — VideoCapture.open(source="screen") raises CaptureUnsupportedError today
device/capture_screen.py screen capture only 🚧 same gap, capture-only

Testing

The release pipeline stages the built mediaway_ffi.dll at mediaway/_native/mediaway_ffi.dll (the wheel's native directory). The round-trip binding check validates that DLL against the documented ABI contract:

python tests/test_mux_roundtrip.py

Run from bindings/python/. Pure std-lib (no pytest), assert-based: it muxes 90 synthetic H.264 video + 90 synthetic AAC audio packets into a fragmented MP4, demuxes the bytes back, and asserts the 1:1 packet round-trip plus the recovered stream metadata (video codec/dimensions/frame rate, audio codec). A failed assertion exits nonzero, which is the CI job's failure signal. Pure CPU — no hardware required.

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.4.tar.gz (3.9 MB view details)

Uploaded Source

Built Distribution

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

mediaway-0.1.4-py3-none-win_amd64.whl (3.9 MB view details)

Uploaded Python 3Windows x86-64

File details

Details for the file mediaway-0.1.4.tar.gz.

File metadata

  • Download URL: mediaway-0.1.4.tar.gz
  • Upload date:
  • Size: 3.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mediaway-0.1.4.tar.gz
Algorithm Hash digest
SHA256 8538fec4495466014d3cbb5c7b6d01e51e3cdfbf28ddd6be0dabb401cc2dad50
MD5 1a2ec7a5d2ac09d972b830842e407ea8
BLAKE2b-256 c6b45653bbe745fe3163a2c0ea74cfb0c1c9babcac139e6f6662d2d3e04141e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for mediaway-0.1.4.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.4-py3-none-win_amd64.whl.

File metadata

  • Download URL: mediaway-0.1.4-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.9 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.4-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 831999bf2fc3ec365c0525ef0a573d2388b8e461cad2d286e8aec6152cc8a2e1
MD5 891e49d9db3be3020b89dece89bc76fb
BLAKE2b-256 9f45d2bdca8046711237d3ee513dda0aef4542a188bcd1a6cd05cec87b5d5f20

See more details on using hashes here.

Provenance

The following attestation bundles were made for mediaway-0.1.4-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.

Release history Release notifications | RSS feed

0.1.8

5 files

0.1.6

2 files

0.1.5

2 files

This release

0.1.4 This release

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