{"id":3392,"library":"aiortc","title":"aiortc: WebRTC and ORTC Implementation for Python","description":"aiortc is a Python library that provides an implementation of Web Real-Time Communication (WebRTC) and Object Real-Time Communication (ORTC). Built on Python's asynchronous I/O framework asyncio, it enables the exchange of audio, video, and data channels. The library's API closely mirrors its JavaScript counterpart, utilizing coroutines instead of promises and `pyee.EventEmitter` for event handling. Currently at version 1.14.0, aiortc is actively maintained with regular updates to support WebRTC specification changes and introduce new codecs or features, and its interoperability is regularly tested against Chrome and Firefox.","status":"active","version":"1.14.0","language":"en","source_language":"en","source_url":"https://github.com/aiortc/aiortc","tags":["webrtc","ortc","asyncio","real-time","video","audio","data-channel","networking"],"install":[{"cmd":"pip install aiortc","lang":"bash","label":"Base installation"},{"cmd":"pip install aiohttp aiortc opencv-python","lang":"bash","label":"With common dependencies for server examples"}],"dependencies":[{"reason":"Security-related cryptographic operations.","package":"cryptography"},{"reason":"Secure Real-time Transport Protocol (SRTP) implementation.","package":"pylibsrtp"},{"reason":"Pythonic bindings for FFmpeg, used for media processing.","package":"av"},{"reason":"Fast CRC-32C computation.","package":"google-crc32c"},{"reason":"SSL/TLS toolkit.","package":"pyopenssl"},{"reason":"Interactive Connectivity Establishment (ICE) implementation.","package":"aioice"},{"reason":"Event emitter library, similar to Node.js EventEmitter.","package":"pyee"},{"reason":"Often used for signaling server implementations in examples.","package":"aiohttp","optional":true},{"reason":"Used in examples for video frame processing (e.g., computer vision).","package":"opencv-python","optional":true}],"imports":[{"symbol":"RTCPeerConnection","correct":"from aiortc import RTCPeerConnection"},{"symbol":"RTCSessionDescription","correct":"from aiortc import RTCSessionDescription"},{"symbol":"RTCConfiguration","correct":"from aiortc import RTCConfiguration"},{"symbol":"MediaStreamTrack","correct":"from aiortc.mediastreams import MediaStreamTrack"},{"symbol":"VideoStreamTrack","correct":"from aiortc.mediastreams import VideoStreamTrack"},{"symbol":"AudioStreamTrack","correct":"from aiortc.mediastreams import AudioStreamTrack"},{"symbol":"RTCDataChannel","correct":"from aiortc import RTCDataChannel"},{"symbol":"RTCCertificate","correct":"from aiortc import RTCCertificate"},{"note":"A class method of RTCCertificate, often imported alongside it.","symbol":"generateCertificate","correct":"from aiortc import RTCCertificate, generateCertificate"},{"note":"MediaRelay is in the 'contrib.media' submodule, not directly under 'aiortc'.","wrong":"from aiortc import MediaRelay","symbol":"MediaRelay","correct":"from aiortc.contrib.media import MediaRelay"},{"note":"MediaPlayer is in the 'contrib.media' submodule, not directly under 'aiortc'.","wrong":"from aiortc import MediaPlayer","symbol":"MediaPlayer","correct":"from aiortc.contrib.media import MediaPlayer"}],"quickstart":{"code":"import asyncio\nfrom aiortc import RTCPeerConnection, RTCSessionDescription\n\nasync def main():\n    pc = RTCPeerConnection()\n    print(\"RTCPeerConnection created.\")\n\n    # Example: Create an offer (typically this is exchanged via a signaling server)\n    offer = await pc.createOffer()\n    await pc.setLocalDescription(offer)\n    print(f\"Local SDP Offer:\\n{pc.localDescription.sdp}\")\n\n    # In a real application, you'd send pc.localDescription to a remote peer\n    # and receive their answer, then set it as remoteDescription.\n    # For this quickstart, we'll simulate a minimal answer (not fully functional for media).\n\n    # Simulate receiving an answer (replace with actual signaling in a real app)\n    # For a real peer, this would be generated by the remote peer's createAnswer()\n    # and contain media tracks if applicable.\n    # remote_sdp_answer = \"v=0\\r\\no=- 12345 12345 IN IP4 127.0.0.1\\r\\ns=-\\r\\nt=0 0\\r\\na=fingerprint:sha-256 A0:B1:C2:D3:E4:F5:G6:H7:I8:J9:K0:L1:M2:N3:O4:P5:Q6:R7:S8:T9:U0:V1:W2:X3:Y4\\r\\na=group:BUNDLE audio video\\r\\na=msid-semantic:WMS\\r\\nm=audio 9 UDP/TLS/RTP/SAVPF 111\\r\\na=rtcp-mux\\r\\na=rtpmap:111 OPUS/48000/2\\r\\na=mid:audio\\r\\nm=video 9 UDP/TLS/RTP/SAVPF 96\\r\\na=rtcp-mux\\r\\na=rtpmap:96 VP8/90000\\r\\na=mid:video\\r\\n\"\n    # remote_description = RTCSessionDescription(sdp=remote_sdp_answer, type=\"answer\")\n    # await pc.setRemoteDescription(remote_description)\n    # print(\"Remote SDP Answer set (simulated).\")\n\n    # Keep the connection alive for a short period or until closed by events\n    try:\n        while pc.connectionState != \"closed\" and pc.connectionState != \"failed\":\n            await asyncio.sleep(1)\n    except asyncio.CancelledError:\n        pass\n    finally:\n        print(\"Closing peer connection...\")\n        await pc.close()\n        print(\"Peer connection closed.\")\n\nif __name__ == \"__main__\":\n    # Ensure auth check passes for quickstart (not applicable for aiortc directly)\n    # For real use cases, replace os.environ.get with actual credentials if needed by signaling.\n    # Example: if you had a signaling server requiring a token:\n    # import os\n    # if not os.environ.get('WEBRTC_AUTH_TOKEN'):\n    #     print(\"Warning: WEBRTC_AUTH_TOKEN not set. Quickstart might fail in a real scenario.\")\n    asyncio.run(main())\n","lang":"python","description":"This quickstart demonstrates the basic setup of an `RTCPeerConnection` and the generation of an SDP offer. In a full WebRTC application, this offer would be exchanged with a remote peer via a signaling server, and an answer would be received and set as the remote description. The example includes placeholders for a simulated answer and a loop to keep the connection alive. It highlights the core `RTCPeerConnection` object and its `createOffer` and `setLocalDescription` methods. For practical examples with media and data channels, refer to the `aiortc` examples directory on GitHub, especially the `server` example."},"warnings":[{"fix":"Ensure `await` is used when calling `RTCDataChannel.send()` if you are on a version where it's a coroutine. Review the changelog for specific version behavior.","message":"The `RTCDataChannel.send` method has historically changed between being a regular function and a coroutine. While currently a coroutine, be aware of this breaking change if upgrading from older versions, particularly around 0.9.x.","severity":"breaking","affected_versions":"< 1.0.0 (specifically 0.9.0, 0.9.1, and subsequent changes before 1.0.0)"},{"fix":"Ensure your environment uses Python 3.10 or newer to be compatible with the latest aiortc releases.","message":"Older Python versions are no longer supported. aiortc dropped support for Python 3.5 (0.9.23), 3.6 (1.3.0), and 3.8 (1.10.0).","severity":"breaking","affected_versions":">= 0.9.23 for Python 3.5, >= 1.3.0 for Python 3.6, >= 1.10.0 for Python 3.8"},{"fix":"Explicitly configure the video size when initializing `MediaPlayer` or `MediaRecorder` if a different resolution is desired.","message":"When using `MediaRecorder` with `PyAV` for video, the default resolution can be hardcoded to 640x480, and `aiortc` might not automatically adjust it. This can lead to unexpected video sizes if not explicitly handled.","severity":"gotcha","affected_versions":"All versions (behavior tied to underlying PyAV defaults)"},{"fix":"Ensure your signaling logic properly synchronizes the addition of outgoing tracks with the exchange of ICE candidates and SDP answers.","message":"For outgoing media tracks, it is crucial to establish and add the track to the `RTCPeerConnection` *before* the server sends back the ICE response during the signaling process. Failing to do so can result in the peer connection opening in a 'recvonly' mode, preventing the sending of media.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For scenarios requiring robust recording of incoming tracks while also re-transmitting them, use a `MediaRelay` to duplicate the track and feed one stream to the `MediaRecorder` and the other to the outgoing peer connection. Implement custom logic to handle PTS adjustments if direct recording of lossy streams is necessary.","message":"The `MediaRecorder` consumes incoming tracks and does not natively manage presentation timestamp (PTS) gaps caused by network interruptions. Directly recording an incoming track with `MediaRecorder` can lead to reception halting if there are PTS discontinuities.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}