CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-aiortc

Python implementation of WebRTC and ORTC for real-time peer-to-peer communication

87

1.02x
Overview
Eval results
Files

configuration.mddocs/

Configuration

WebRTC configuration objects, RTP parameters, codec capabilities, and session description handling for connection setup and media negotiation.

Capabilities

RTCConfiguration Class

Configuration options for RTCPeerConnection setup.

class RTCConfiguration:
    """Configuration for RTCPeerConnection."""
    
    def __init__(self, iceServers=None, bundlePolicy=RTCBundlePolicy.BALANCED):
        """
        Create RTCConfiguration.
        
        Parameters:
        - iceServers (list, optional): List of RTCIceServer objects
        - bundlePolicy (RTCBundlePolicy, optional): Media bundling policy (default: BALANCED)
        """
    
    @property
    def iceServers(self) -> list:
        """List of RTCIceServer objects for STUN/TURN servers"""
    
    @property
    def bundlePolicy(self) -> RTCBundlePolicy:
        """Media bundling policy"""

RTCIceServer Class

STUN/TURN server configuration for ICE connectivity.

class RTCIceServer:
    """STUN/TURN server configuration."""
    
    def __init__(self, urls, username=None, credential=None, credentialType="password"):
        """
        Create ICE server configuration.
        
        Parameters:
        - urls (str or list): STUN/TURN server URLs
        - username (str, optional): Authentication username (required for TURN)
        - credential (str, optional): Authentication credential (required for TURN)
        - credentialType (str, optional): Credential type (default: "password")
        """
    
    @property
    def urls(self) -> list:
        """List of server URLs"""
    
    @property
    def username(self) -> str:
        """Authentication username"""
    
    @property
    def credential(self) -> str:
        """Authentication credential"""
    
    @property
    def credentialType(self) -> str:
        """Credential type"""

RTCBundlePolicy Enum

Media bundling policy options for ICE candidate gathering.

class RTCBundlePolicy:
    """Media bundling policy enumeration."""
    
    BALANCED = "balanced"      # Gather ICE candidates per media type
    MAX_COMPAT = "max-compat"  # Gather ICE candidates per track
    MAX_BUNDLE = "max-bundle"  # Gather ICE candidates for single track only

RTP Parameters and Capabilities

Configuration objects for RTP media negotiation.

class RTCRtpParameters:
    """RTP connection parameters."""
    
    @property
    def codecs(self) -> list:
        """List of RTCRtpCodecParameters"""
    
    @property
    def headerExtensions(self) -> list:
        """List of RTCRtpHeaderExtensionParameters"""
    
    @property
    def rtcp(self) -> RTCRtcpParameters:
        """RTCP parameters"""

class RTCRtpCapabilities:
    """RTP codec and extension capabilities."""
    
    @property
    def codecs(self) -> list:
        """List of RTCRtpCodecCapability objects"""
    
    @property
    def headerExtensions(self) -> list:
        """List of RTCRtpHeaderExtensionCapability objects"""

class RTCRtpCodecCapability:
    """Individual codec capability."""
    
    @property
    def mimeType(self) -> str:
        """Codec MIME type (e.g., "audio/opus", "video/VP8")"""
    
    @property
    def clockRate(self) -> int:
        """Codec clock rate in Hz"""
    
    @property
    def channels(self) -> int:
        """Number of audio channels (None for video)"""
    
    @property
    def parameters(self) -> dict:
        """Codec-specific parameters"""

class RTCRtpCodecParameters:
    """Codec configuration parameters."""
    
    @property
    def mimeType(self) -> str:
        """Codec MIME type"""
    
    @property
    def clockRate(self) -> int:
        """Codec clock rate"""
    
    @property
    def channels(self) -> int:
        """Number of channels"""
    
    @property
    def payloadType(self) -> int:
        """RTP payload type (96-127 for dynamic types)"""
    
    @property
    def parameters(self) -> dict:
        """Codec parameters"""

class RTCRtpHeaderExtensionCapability:
    """Header extension capability."""
    
    @property
    def uri(self) -> str:
        """Extension URI"""

class RTCRtpHeaderExtensionParameters:
    """Header extension parameters."""
    
    @property
    def uri(self) -> str:
        """Extension URI"""
    
    @property
    def id(self) -> int:
        """Extension ID (1-14)"""

class RTCRtcpParameters:
    """RTCP configuration parameters."""
    
    @property
    def cname(self) -> str:
        """Canonical name for RTCP"""
    
    @property
    def reducedSize(self) -> bool:
        """Whether to use reduced-size RTCP"""

Session Description

SDP session description handling for offer/answer exchange.

class RTCSessionDescription:
    """Session Description Protocol representation."""
    
    def __init__(self, sdp: str, type: str):
        """
        Create session description.
        
        Parameters:
        - sdp (str): SDP string content
        - type (str): Description type ("offer", "answer", "pranswer", "rollback")
        """
    
    @property
    def sdp(self) -> str:
        """SDP string content"""
    
    @property
    def type(self) -> str:
        """Description type"""

Usage Examples

Basic Configuration

import aiortc

# Create basic configuration with STUN server
config = aiortc.RTCConfiguration(
    iceServers=[
        aiortc.RTCIceServer("stun:stun.l.google.com:19302")
    ]
)

# Create peer connection with configuration
pc = aiortc.RTCPeerConnection(configuration=config)

print(f"Bundle policy: {config.bundlePolicy}")
print(f"ICE servers: {[server.urls for server in config.iceServers]}")

Advanced ICE Server Configuration

# Multiple STUN/TURN servers with authentication
config = aiortc.RTCConfiguration(
    iceServers=[
        # Public STUN servers
        aiortc.RTCIceServer([
            "stun:stun.l.google.com:19302",
            "stun:stun1.l.google.com:19302"
        ]),
        
        # TURN server with authentication
        aiortc.RTCIceServer(
            urls="turn:turnserver.example.com:3478",
            username="myusername",
            credential="mypassword"
        ),
        
        # TURN server with TCP transport
        aiortc.RTCIceServer(
            urls="turn:turnserver.example.com:443?transport=tcp",
            username="myusername", 
            credential="mypassword"
        )
    ],
    bundlePolicy=aiortc.RTCBundlePolicy.MAX_BUNDLE
)

pc = aiortc.RTCPeerConnection(configuration=config)

# Access configuration details
for i, server in enumerate(config.iceServers):
    print(f"Server {i+1}:")
    print(f"  URLs: {server.urls}")
    print(f"  Username: {server.username}")
    print(f"  Credential type: {server.credentialType}")

Bundle Policy Configuration

# Different bundle policies
configs = {
    "balanced": aiortc.RTCConfiguration(
        bundlePolicy=aiortc.RTCBundlePolicy.BALANCED
    ),
    "max_compat": aiortc.RTCConfiguration(
        bundlePolicy=aiortc.RTCBundlePolicy.MAX_COMPAT
    ),
    "max_bundle": aiortc.RTCConfiguration(
        bundlePolicy=aiortc.RTCBundlePolicy.MAX_BUNDLE
    )
}

for policy_name, config in configs.items():
    print(f"{policy_name}: {config.bundlePolicy}")
    
    # Different bundle policies affect ICE candidate gathering
    pc = aiortc.RTCPeerConnection(configuration=config)
    # ... use peer connection

RTP Capabilities Inspection

# Get available codec capabilities
audio_caps = aiortc.RTCRtpSender.getCapabilities("audio")
video_caps = aiortc.RTCRtpSender.getCapabilities("video")

print("Audio Codecs:")
for codec in audio_caps.codecs:
    print(f"  {codec.mimeType}")
    print(f"    Clock rate: {codec.clockRate} Hz")
    print(f"    Channels: {codec.channels}")
    print(f"    Parameters: {codec.parameters}")

print("\nVideo Codecs:")
for codec in video_caps.codecs:
    print(f"  {codec.mimeType}")
    print(f"    Clock rate: {codec.clockRate} Hz")
    print(f"    Parameters: {codec.parameters}")

print("\nAudio Header Extensions:")
for ext in audio_caps.headerExtensions:
    print(f"  {ext.uri}")

print("\nVideo Header Extensions:")
for ext in video_caps.headerExtensions:
    print(f"  {ext.uri}")

Session Description Handling

async def handle_session_descriptions():
    pc1 = aiortc.RTCPeerConnection()
    pc2 = aiortc.RTCPeerConnection()
    
    # PC1 creates offer
    offer = await pc1.createOffer()
    print(f"Offer type: {offer.type}")
    print(f"Offer SDP length: {len(offer.sdp)} characters")
    
    # Set local description on PC1
    await pc1.setLocalDescription(offer)
    print(f"PC1 signaling state: {pc1.signalingState}")
    
    # Send offer to PC2 and set as remote description
    await pc2.setRemoteDescription(offer)
    print(f"PC2 signaling state: {pc2.signalingState}")
    
    # PC2 creates answer
    answer = await pc2.createAnswer()
    print(f"Answer type: {answer.type}")
    
    # Set local description on PC2
    await pc2.setLocalDescription(answer)
    print(f"PC2 signaling state: {pc2.signalingState}")
    
    # Send answer to PC1 and set as remote description
    await pc1.setRemoteDescription(answer)
    print(f"PC1 signaling state: {pc1.signalingState}")
    
    # Access session descriptions
    print(f"PC1 local: {pc1.localDescription.type}")
    print(f"PC1 remote: {pc1.remoteDescription.type}")
    print(f"PC2 local: {pc2.localDescription.type}")
    print(f"PC2 remote: {pc2.remoteDescription.type}")

Custom RTP Parameters

async def custom_rtp_parameters():
    pc = aiortc.RTCPeerConnection()
    
    # Add transceiver to get RTP parameters
    transceiver = pc.addTransceiver("video")
    
    # Get current parameters (after negotiation)
    # Note: This would typically be done after setLocalDescription
    try:
        # Create a mock RTP parameters object for demonstration
        class MockRtpParameters:
            def __init__(self):
                self.codecs = []
                self.headerExtensions = []
                self.rtcp = None
        
        # In real usage, you'd get this from the transceiver after negotiation
        params = MockRtpParameters()
        
        # Example of how you might inspect codec parameters
        video_caps = aiortc.RTCRtpSender.getCapabilities("video")
        
        print("Available video codecs:")
        for codec in video_caps.codecs:
            print(f"  {codec.mimeType} - Clock: {codec.clockRate}")
        
    except Exception as e:
        print(f"Could not get RTP parameters: {e}")

Configuration Validation

def validate_configuration():
    """Validate RTCConfiguration settings."""
    
    # Test various configuration scenarios
    test_configs = [
        # Valid configuration
        {
            "name": "Valid STUN only",
            "config": aiortc.RTCConfiguration(
                iceServers=[aiortc.RTCIceServer("stun:stun.l.google.com:19302")]
            )
        },
        
        # Valid TURN configuration
        {
            "name": "Valid TURN with auth",
            "config": aiortc.RTCConfiguration(
                iceServers=[aiortc.RTCIceServer(
                    "turn:turnserver.example.com:3478",
                    username="user",
                    credential="pass"
                )]
            )
        },
        
        # No ICE servers (valid, will use defaults)
        {
            "name": "No ICE servers",
            "config": aiortc.RTCConfiguration()
        }
    ]
    
    for test in test_configs:
        try:
            pc = aiortc.RTCPeerConnection(configuration=test["config"])
            print(f"✓ {test['name']}: Valid")
            
            # Access configuration properties
            config = test["config"]
            print(f"  Bundle policy: {config.bundlePolicy}")
            print(f"  ICE servers: {len(config.iceServers) if config.iceServers else 0}")
            
        except Exception as e:
            print(f"✗ {test['name']}: Invalid - {e}")

Dynamic Configuration Updates

async def dynamic_configuration():
    """Demonstrate dynamic configuration scenarios."""
    
    # Start with basic configuration
    initial_config = aiortc.RTCConfiguration(
        iceServers=[aiortc.RTCIceServer("stun:stun.l.google.com:19302")]
    )
    
    pc = aiortc.RTCPeerConnection(configuration=initial_config)
    
    print("Initial configuration:")
    print(f"  ICE servers: {len(pc.configuration.iceServers)}")
    print(f"  Bundle policy: {pc.configuration.bundlePolicy}")
    
    # Note: RTCPeerConnection doesn't support configuration changes after creation
    # You would need to create a new peer connection with updated configuration
    
    updated_config = aiortc.RTCConfiguration(
        iceServers=[
            aiortc.RTCIceServer("stun:stun.l.google.com:19302"),
            aiortc.RTCIceServer(
                "turn:turnserver.example.com:3478",
                username="newuser",
                credential="newpass"
            )
        ],
        bundlePolicy=aiortc.RTCBundlePolicy.MAX_BUNDLE
    )
    
    # Create new peer connection with updated config
    new_pc = aiortc.RTCPeerConnection(configuration=updated_config)
    
    print("Updated configuration:")
    print(f"  ICE servers: {len(new_pc.configuration.iceServers)}")
    print(f"  Bundle policy: {new_pc.configuration.bundlePolicy}")
    
    # Clean up original connection
    await pc.close()

Install with Tessl CLI

npx tessl i tessl/pypi-aiortc

docs

configuration.md

data-channels.md

index.md

media-streaming.md

network-transport.md

peer-connection.md

rtp-transport.md

statistics.md

tile.json