Python implementation of WebRTC and ORTC for real-time peer-to-peer communication
87
Core WebRTC peer connection functionality providing the main entry point for establishing and managing real-time communication sessions between peers.
The main class for managing WebRTC peer connections, handling signaling, ICE candidates, media tracks, and data channels.
class RTCPeerConnection:
def __init__(self, configuration=None):
"""
Create a new RTCPeerConnection.
Parameters:
- configuration (RTCConfiguration, optional): Connection configuration
"""
# Properties
@property
def connectionState(self) -> str:
"""Current connection state: "new", "connecting", "connected", "disconnected", "failed", "closed" """
@property
def iceConnectionState(self) -> str:
"""ICE connection state: "new", "checking", "connected", "completed", "failed", "disconnected", "closed" """
@property
def iceGatheringState(self) -> str:
"""ICE gathering state: "new", "gathering", "complete" """
@property
def localDescription(self) -> RTCSessionDescription:
"""Local session description"""
@property
def remoteDescription(self) -> RTCSessionDescription:
"""Remote session description"""
@property
def signalingState(self) -> str:
"""Signaling state: "stable", "have-local-offer", "have-remote-offer", "have-local-pranswer", "have-remote-pranswer", "closed" """
@property
def sctp(self) -> Optional[RTCSctpTransport]:
"""SCTP transport for data channels, or None if not available"""
# Session Description Methods
async def createOffer(self) -> RTCSessionDescription:
"""
Create an offer session description.
Returns:
RTCSessionDescription: SDP offer
"""
async def createAnswer(self) -> RTCSessionDescription:
"""
Create an answer session description.
Returns:
RTCSessionDescription: SDP answer
"""
async def setLocalDescription(self, description: RTCSessionDescription) -> None:
"""
Set the local session description.
Parameters:
- description (RTCSessionDescription): Local SDP offer or answer
"""
async def setRemoteDescription(self, description: RTCSessionDescription) -> None:
"""
Set the remote session description.
Parameters:
- description (RTCSessionDescription): Remote SDP offer or answer
"""
# ICE Candidate Management
async def addIceCandidate(self, candidate: RTCIceCandidate) -> None:
"""
Add a remote ICE candidate.
Parameters:
- candidate (RTCIceCandidate): Remote ICE candidate
"""
# Media Track Management
def addTrack(self, track: MediaStreamTrack, *streams) -> RTCRtpSender:
"""
Add a media track to the connection.
Parameters:
- track (MediaStreamTrack): Audio or video track to add
- streams: Associated media streams (unused in current implementation)
Returns:
RTCRtpSender: RTP sender for the track
"""
def addTransceiver(self, trackOrKind, direction="sendrecv") -> RTCRtpTransceiver:
"""
Add an RTP transceiver.
Parameters:
- trackOrKind: MediaStreamTrack or media kind string ("audio", "video")
- direction (str): Transceiver direction ("sendrecv", "sendonly", "recvonly", "inactive")
Returns:
RTCRtpTransceiver: Created transceiver
"""
# Data Channel Management
def createDataChannel(self, label: str, **options) -> RTCDataChannel:
"""
Create a data channel.
Parameters:
- label (str): Channel label/name
- maxPacketLifeTime (int, optional): Maximum packet lifetime in milliseconds
- maxRetransmits (int, optional): Maximum retransmission attempts
- ordered (bool, optional): Whether to guarantee ordered delivery (default: True)
- protocol (str, optional): Subprotocol name
- negotiated (bool, optional): Whether channel is pre-negotiated (default: False)
- id (int, optional): Numeric channel identifier (0-65534)
Returns:
RTCDataChannel: Created data channel
"""
# Information Methods
def getReceivers(self) -> list:
"""
Get list of RTP receivers.
Returns:
list: List of RTCRtpReceiver objects
"""
def getSenders(self) -> list:
"""
Get list of RTP senders.
Returns:
list: List of RTCRtpSender objects
"""
def getTransceivers(self) -> list:
"""
Get list of RTP transceivers.
Returns:
list: List of RTCRtpTransceiver objects
"""
async def getStats(self) -> RTCStatsReport:
"""
Get connection statistics.
Returns:
RTCStatsReport: Statistics for all tracks and transports
"""
# Connection Management
async def close(self) -> None:
"""Close the peer connection and release resources."""Handle SDP offers and answers for session negotiation.
class RTCSessionDescription:
def __init__(self, sdp: str, type: str):
"""
Create a session description.
Parameters:
- sdp (str): Session Description Protocol string
- type (str): Description type ("offer", "answer", "pranswer", "rollback")
"""
@property
def sdp(self) -> str:
"""SDP string content"""
@property
def type(self) -> str:
"""Description type"""import aiortc
import asyncio
async def setup_peer_connection():
# Create configuration with STUN server
config = aiortc.RTCConfiguration(
iceServers=[aiortc.RTCIceServer("stun:stun.l.google.com:19302")]
)
# Create peer connection
pc = aiortc.RTCPeerConnection(configuration=config)
# Add event listeners
@pc.on("connectionstatechange")
def on_connectionstatechange():
print(f"Connection state: {pc.connectionState}")
@pc.on("icecandidate")
def on_icecandidate(candidate):
# Send candidate to remote peer
print(f"New ICE candidate: {candidate}")
return pc
pc = asyncio.run(setup_peer_connection())async def create_offer_answer():
pc1 = aiortc.RTCPeerConnection()
pc2 = aiortc.RTCPeerConnection()
# PC1 creates offer
offer = await pc1.createOffer()
await pc1.setLocalDescription(offer)
# PC2 processes offer and creates answer
await pc2.setRemoteDescription(offer)
answer = await pc2.createAnswer()
await pc2.setLocalDescription(answer)
# PC1 processes answer
await pc1.setRemoteDescription(answer)
# Connections are now established (pending ICE)
print(f"PC1 signaling state: {pc1.signalingState}")
print(f"PC2 signaling state: {pc2.signalingState}")async def add_media_and_data():
pc = aiortc.RTCPeerConnection()
# Add audio and video tracks
audio_track = aiortc.AudioStreamTrack()
video_track = aiortc.VideoStreamTrack()
pc.addTrack(audio_track)
pc.addTrack(video_track)
# Create data channel
channel = pc.createDataChannel("chat", ordered=True)
@channel.on("open")
def on_open():
print("Data channel opened")
channel.send("Hello WebRTC!")
@channel.on("message")
def on_message(message):
print(f"Received: {message}")
# Get connection info
senders = pc.getSenders()
receivers = pc.getReceivers()
transceivers = pc.getTransceivers()
print(f"Senders: {len(senders)}")
print(f"Receivers: {len(receivers)}")
print(f"Transceivers: {len(transceivers)}")from typing import Optional
from aiortc import RTCSctpTransport
# Optional type for nullable values
Optional[T] # Union of T and NoneInstall with Tessl CLI
npx tessl i tessl/pypi-aiortcdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10