Repository navigation
Releases: StanfordFSL/moonlight-python
Releases · StanfordFSL/moonlight-python
Release list
v0.3.0
v0.3.0
New Features
- Audio capture — Sunshine's Opus stream is decoded to 48 kHz float32 PCM and
exposed through client.audio() (iterator) and client.latest_audio()
(latest-chunk buffer), mirroring the video frame APIs. On by default via
record_audio=True on start_stream() / stream(). - Audio in recordings — record() and start_recording() now include audio
automatically: a synced AAC track inside video files, or a companion audio.wav
next to image-directory captures. Pass with_audio=False to skip it for a
given recording. - New public types — AudioChunk (PCM + timing metadata), AudioDecoder
(PyAV/Opus, stereo and surround), and WavRecorder (16-bit PCM output). - VideoRecorder(audio=True) — Adds an AAC track to the same container, fed by
a thread-safe write_audio(), for direct use of the recorder classes. - version — The package now exposes its installed version.
Bug Fixes
- Fixed stretched video timelines — Video PTS moved from a 1/fps time base to
90 kHz, and from the local clock to the host's capture timestamps. Frames
arriving in bursts are no longer pushed forward a full frame period each,
which previously stretched recordings past wall clock. - Audio loss no longer shifts the timeline — Audio is positioned at
frame_index × samples_per_frame rather than appended, so packets lost on the
network, dropped by a full queue, or corrupt leave a gap of silence instead of
pulling all later audio earlier. - No truncated audio tail — On stop, in-flight audio gets a bounded drain
window and any remaining deficit is padded with silence, so both tracks end
together.
Breaking Changes
- VideoRecorder.write(frame, pts=) is now write(frame,
pts_us=). This only affects direct use of the recorder class;
the MoonlightClient API is unchanged. - Audio capture is enabled by default, so streams install audio callbacks and
run an Opus decode thread, and recordings gain an audio track. Pass
record_audio=False to start_stream() / stream() for the previous behavior.
Improvements
- Audio loss diagnostics are logged (packets lost or dropped, silence
inserted, gaps bridged) — enable logging at INFO to see them. - CI: full-history checkouts so setuptools-scm resolves version tags, macOS
runner pinned to macos-15, and the wheel matrix no longer fails fast.
v0.2.0
v0.2.0
New Features
- Shared stream architecture — New
start_stream()/stop_stream()lifecycle replaces per-call streaming. Once a stream is started,frames(),latest_frame(),record(), andcapture()all tap into the shared connection instead of creating their own. stream()context manager — Convenience wrapper aroundstart_stream()/stop_stream()for scoped usage.capture()method — Single-screenshot helper that grabs the latest frame and saves it as an image.start_recording()/stop_recording()— Background recording to video or image directory, running in a separate thread until explicitly stopped.frames()iterator — Dedicated method for iterating decoded frames from the shared stream.- Auto-pairing in
connect()—connect()now automatically pairs with the server if needed, removing the need to callpair()separately. - Windows and macOS wheel builds — CI workflows for building and publishing wheels on all three platforms.
Bug Fixes
- Fixed auto-pair detection — Pairing status is now checked via an authenticated HTTPS request (mutual TLS) instead of the HTTP
/serverinfoendpoint, which couldn't identify the client. Previously,connect()would trigger pairing on every call even for already-paired clients. - Fixed IDR frame requests — Resolved issues with IDR frame delivery when multiple clients connect, using a mouse-movement workaround.
- Fixed video aspect ratio — Corrected aspect ratio distortion in recorded video output.
- Fixed custom port handling — Non-default server ports now work correctly throughout the connection and streaming flow.
- Fixed black-start recording — Recordings now capture the latest available frame first to avoid starting with black frames.
- Fixed VFR recording — Video recording uses wall-clock PTS timestamps, producing correct playback timing for variable-framerate streams instead of assuming constant framerate.
Improvements
StreamNotActiveErrorexception — New exception raised when calling stream-dependent methods without an active stream, with a clear message to callstart_stream()first.
Initial Release
v0.1.0 — Initial Release
First public release of moonlight-python, a Python client for Moonlight/Sunshine game streaming that delivers decoded video frames as numpy arrays.
Features
- Server discovery — automatic mDNS discovery or direct IP connection
- Cryptographic pairing — PIN-based pairing compatible with Sunshine and NVIDIA GameStream
- Frame streaming — receive decoded H.264/HEVC/AV1 frames as numpy arrays via a simple generator API
- Latest frame buffer — thread-safe drop-oldest buffer for CV pipelines that process slower than the stream rate
- Recording — save to video files (MP4) or image sequences (PNG/JPEG)
- Codec support — H.264, HEVC, and AV1
Installation
pip install moonlight-python
Pre-built manylinux wheels are available for Python 3.10–3.13 on x86_64 Linux. No compiler or system dependencies required.
Built on
- moonlight-common-c — core streaming protocol via CFFI
- PyAV (FFmpeg) — hardware-accelerated video decoding