Change Log

Version 0.0.1

12.10.2026

πŸ”Œ The whole WebRTC API is bound. Every interface, every method, every dictionary: all 154 binding issues of the tracker are done, and the API goes beyond them

🎞 Media processing that not every browser ships yet: MediaStreamTrackProcessor, VideoTrackGenerator and MediaStreamTrackGenerator, with the VideoFrame and AudioData of WebCodecs

πŸ” WebRTC Encoded Transform: the encoded frames of senders and receivers in Python with RTCRtpScriptTransform, and end-to-end encryption with SFrame

πŸŽ₯ H.264 without bundling it: VideoToolbox on macOS, offered by default, and Cisco’s OpenH264 binary on request elsewhere

πŸš€ Field trials and WARP: DTLS 1.3, SNAP and SPED cut round trips off connection setup

⚑ libwebrtc M152, pre-built wheels for Linux (x86_64 and aarch64), macOS and Windows, CPython 3.9 – 3.15, free-threaded 3.14t and 3.15t too

πŸ§ͺ The public API follows the WebIDL of the specifications and runs the original web-platform-tests

πŸ“š Fully reworked docs website: a new theme, guides, examples and the full API reference

What is bound, by specification:

  • WebRTC: RTCPeerConnection, RTCDataChannel, RTCRtpTransceiver, RTCRtpSender, RTCRtpReceiver, RTCDtlsTransport, RTCIceTransport, RTCSctpTransport, RTCDTMFSender, RTCCertificate, RTCIceCandidate, RTCSessionDescription, with every method, attribute, event and dictionary

  • WebRTC Extensions: standalone RTCIceTransport, RTP header encryption, and more

  • WebRTC Statistics: 19 typed stats objects in RTCStatsReport

  • WebRTC Encoded Transform: RTCRtpScriptTransform, RTCEncodedVideoFrame, RTCEncodedAudioFrame, and SFrame (RFC 9605)

  • Media Capture and Streams: MediaStream, MediaStreamTrack with constraints, settings and capabilities, and MediaDevices with a synthetic camera and microphone

  • MediaStreamTrack Insertable Media Processing: MediaStreamTrackProcessor, VideoTrackGenerator, and MediaStreamTrackGenerator

  • WebCodecs: VideoFrame and AudioData

  • Streams: ReadableStream, WritableStream and TransformStream, with piping and async iteration

In numbers: 229 public classes, 50 enums with the string values of the specifications, 18 exceptions named after their DOMException, and the camelCase names of the specifications next to the snake_case ones.

  • Migrate to prebuilt libwebrtc M152, scikit-build-core and single cibuildwheel CI by @MarshalX in #191

  • Split wheel builds per Python version and cache libwebrtc by @MarshalX in #196

  • Add Linux aarch64 wheels by @MarshalX in #207

  • Support free-threaded Python with cp314t and cp315t wheels, add CPython 3.15 by @MarshalX in #232

  • Implement WebRTC spec APIs and event ordering for WPT by @MarshalX in #195

  • Add MediaStreamTrackProcessor, track generators and WebCodecs frames by @MarshalX in #197

  • Align WebIDL dictionaries with the spec as typed models by @MarshalX in #212

  • Align the public API with the WPT WebIDL by @MarshalX in #214

  • Type event handlers per event, add listener management methods by @MarshalX in #215

  • Add H.264 through Cisco’s OpenH264 binary, downloaded on request by @MarshalX in #218

  • Add H.264 on macOS through VideoToolbox, offered by default by @MarshalX in #219

  • Encode H.264 with our own VideoToolbox session: AutoLevel, no rate freeze, High for Chrome by @MarshalX in #233

  • Match browsers on SDP munging, connection states, setParameters and close by @MarshalX in #227

  • Replace to_async with call_native, drop its timeout by @MarshalX in #206

  • Add the OpenAI GPT-Live voice chat example by @MarshalX in #198

  • Add field trials, connect the GPT-Live example with WARP, skip loopback candidates by @MarshalX in #225

  • Add the Janus streaming example by @MarshalX in #205

  • Play Janus streams in stereo by munging the Opus answer by @MarshalX in #234

  • Rework the docs website with guides, examples and the API reference by @MarshalX in #217

  • Rewrite the API docs with MDN links by @MarshalX in #221

  • Run original web-platform-tests through a PythonMonkey shim by @MarshalX in #193

  • Sync tests with web-platform-tests by @MarshalX in #192

  • Compare the public API with the WPT WebIDL by @MarshalX in #211

  • Add Atheris fuzz targets, fix findings by @MarshalX in #204

  • Add strict clang-format and clang-tidy, fix all findings by @MarshalX in #203

  • Enable all ruff rules, fix findings by @MarshalX in #210

  • Type check with Pyrefly at full strictness, fix findings by @MarshalX in #213

  • Run tests on GitHub Actions by @MarshalX in #187

  • Build on Ubuntu 22.04 in CI by @MarshalX in #189

  • Make CI wheel builds and PyPI publish safe to retry by @MarshalX in #226

  • Retry and cache CI downloads, build the sdist in each wheel job by @MarshalX in #230

  • Run isolated tests as functions instead of code strings by @MarshalX in #228

  • Add an unattended bug hunt with stacks, crash triage and C++/Python coverage by @MarshalX in #231

  • Update the licence holder and headers, rebuild third-party licences for M152 by @MarshalX in #220

  • Fix wrapper ownership: shared_ptr lifetimes, no factory leaks or dangling observers by @MarshalX in #194

  • Fix the GC deadlock by releasing wrappers off libwebrtc threads by @MarshalX in #199

  • Fix deadlocks, leaks and crashes found by sanitizers and chaos tests by @MarshalX in #200

  • Fix set_parameters hanging when libwebrtc drops the callback by @MarshalX in #208

  • Fix sender and receiver leaks by releasing handlers of ended tracks by @MarshalX in #216

  • Fix spec bugs found by a stricter WPT by @MarshalX in #222

  • Fix callback crashes, exit hangs and thread churn in the native layer by @MarshalX in #223

  • Fix stream, track and event-loop bugs, and a wrapper deadlock by @MarshalX in #224

  • Release tasks stranded by a closed test loop by @MarshalX in #229

  • Rebuild object lifetime: unreferenced connections, channels and live tracks stay alive while they have handlers or pending work, native threads never run Python, wrappers take no attributes by @MarshalX in #232

  • Fire ended on remote tracks when a connection closes, keep a failed RTCIceTransport for an ICE restart by @MarshalX in #232

  • Fix a cancelled operation of a connection breaking the operations queued before and after it by @MarshalX in #217

  • Fix the docs build with the current sphinx-favicon by @MarshalX in #217, closes #186

Version 0.0.0.dev9

03.03.2022

  • Add RTCDtlsTransport and RTCPeerConnection.add_transceiver, with RtpEncodingParameters, RtpTransceiverInit and MediaType

  • transport of RTCRtpSender and RTCRtpReceiver

  • MediaStreamTrack.kind is a MediaType

Version 0.0.0.dev8

02.03.2022

  • Add RTCRtpTransceiver, RTCRtpReceiver and RTCIceTransport

  • get_transceivers, get_senders and get_receivers of RTCPeerConnection

  • Unified Plan is the default SDP semantics

Version 0.0.0.dev7

26.02.2022

  • Fix a segfault of the MediaStream from get_user_media

  • Compare Python wrappers by their native objects

  • Add the test suite with pytest

Version 0.0.0.dev6

10.02.2022

  • Bind RTCError, SdpParseError and the common exceptions; failed async calls raise them

  • Fix a segfault in RTCPeerConnection.close

  • Add the security policy

Version 0.0.0.dev5

09.02.2022

  • Fix a segfault of RTCSessionDescription (double destruction)

  • Publish the sdist, include third-party licences in the package

Version 0.0.0.dev4

06.02.2022

  • Keep one Python wrapper per native object, which fixes many segfaults and bus errors

  • Fix MediaStream pointers and the creation of RTCRtpSender

  • Docs: favicons, OpenGraph, keyboard navigation and mobile layout

Version 0.0.0.dev3

03.02.2022

  • Docs on Read the Docs, a README with the logo

Version 0.0.0.dev2

03.02.2022

  • RTCPeerConnection with create_offer, create_answer, set_local_description, set_remote_description, add_track and close

  • MediaStream, MediaStreamTrack and get_user_media

  • RTCRtpSender, and RTCAudioSource to send PCM from Python

  • The pure Python webrtc module over the native wrtc, with docs

  • Wheels for Linux, macOS (Intel and Apple Silicon) and Windows

Version 0.0.0.dev1

03.01.2022

  • The first upload: the package skeleton