0
# RTP Transport
1
2
Real-time Transport Protocol implementation with senders, receivers, transceivers, and complete parameter configuration for audio/video streaming.
3
4
## Capabilities
5
6
### RTCRtpSender Class
7
8
Manages outgoing RTP streams for audio or video tracks.
9
10
```python { .api }
11
class RTCRtpSender:
12
"""RTP sender for outgoing media streams."""
13
14
@property
15
def kind(self) -> str:
16
"""Media kind: "audio" or "video" """
17
18
@property
19
def track(self) -> MediaStreamTrack:
20
"""Associated media track (None if no track)"""
21
22
@property
23
def transport(self) -> RTCDtlsTransport:
24
"""Associated DTLS transport"""
25
26
@classmethod
27
def getCapabilities(cls, kind: str) -> RTCRtpCapabilities:
28
"""
29
Get sender capabilities for media kind.
30
31
Parameters:
32
- kind (str): Media kind ("audio" or "video")
33
34
Returns:
35
RTCRtpCapabilities: Supported codecs and extensions
36
"""
37
38
async def getStats(self) -> RTCStatsReport:
39
"""
40
Get sender statistics.
41
42
Returns:
43
RTCStatsReport: Outbound RTP stream statistics
44
"""
45
46
async def replaceTrack(self, track: MediaStreamTrack) -> None:
47
"""
48
Replace the current track without renegotiation.
49
50
Parameters:
51
- track (MediaStreamTrack): New track to send (None to stop sending)
52
"""
53
54
async def send(self, parameters: RTCRtpParameters) -> None:
55
"""
56
Start sending with RTP parameters.
57
58
Parameters:
59
- parameters (RTCRtpParameters): RTP configuration
60
"""
61
62
def setStreams(self, streams) -> None:
63
"""
64
Set associated media streams.
65
66
Parameters:
67
- streams: List of media streams (currently unused)
68
"""
69
70
def stop(self) -> None:
71
"""Stop the sender"""
72
```
73
74
### RTCRtpReceiver Class
75
76
Manages incoming RTP streams for audio or video.
77
78
```python { .api }
79
class RTCRtpReceiver:
80
"""RTP receiver for incoming media streams."""
81
82
@property
83
def track(self) -> MediaStreamTrack:
84
"""Associated received media track"""
85
86
@property
87
def transport(self) -> RTCDtlsTransport:
88
"""Associated DTLS transport"""
89
90
@classmethod
91
def getCapabilities(cls, kind: str) -> RTCRtpCapabilities:
92
"""
93
Get receiver capabilities for media kind.
94
95
Parameters:
96
- kind (str): Media kind ("audio" or "video")
97
98
Returns:
99
RTCRtpCapabilities: Supported codecs and extensions
100
"""
101
102
def getContributingSources(self) -> list:
103
"""
104
Get contributing sources.
105
106
Returns:
107
list: List of RTCRtpContributingSource objects
108
"""
109
110
async def getStats(self) -> RTCStatsReport:
111
"""
112
Get receiver statistics.
113
114
Returns:
115
RTCStatsReport: Inbound RTP stream statistics
116
"""
117
118
def getSynchronizationSources(self) -> list:
119
"""
120
Get synchronization sources.
121
122
Returns:
123
list: List of RTCRtpSynchronizationSource objects
124
"""
125
126
async def receive(self, parameters: RTCRtpParameters) -> None:
127
"""
128
Start receiving with RTP parameters.
129
130
Parameters:
131
- parameters (RTCRtpParameters): RTP configuration
132
"""
133
134
def stop(self) -> None:
135
"""Stop the receiver"""
136
```
137
138
### RTCRtpTransceiver Class
139
140
Combined sender and receiver for bidirectional RTP communication.
141
142
```python { .api }
143
class RTCRtpTransceiver:
144
"""RTP transceiver combining sender and receiver."""
145
146
@property
147
def currentDirection(self) -> str:
148
"""Negotiated direction: "sendrecv", "sendonly", "recvonly", "inactive", or None"""
149
150
@property
151
def direction(self) -> str:
152
"""Preferred direction: "sendrecv", "sendonly", "recvonly", "inactive" """
153
154
@direction.setter
155
def direction(self, value: str) -> None:
156
"""Set preferred direction"""
157
158
@property
159
def kind(self) -> str:
160
"""Media kind: "audio" or "video" """
161
162
@property
163
def mid(self) -> str:
164
"""Media identifier (None if not negotiated)"""
165
166
@property
167
def receiver(self) -> RTCRtpReceiver:
168
"""Associated RTP receiver"""
169
170
@property
171
def sender(self) -> RTCRtpSender:
172
"""Associated RTP sender"""
173
174
@property
175
def stopped(self) -> bool:
176
"""Whether transceiver is stopped"""
177
178
def setCodecPreferences(self, codecs: list) -> None:
179
"""
180
Override codec preferences for this transceiver.
181
182
Parameters:
183
- codecs (list): List of RTCRtpCodecCapability objects in preferred order
184
"""
185
186
def stop(self) -> None:
187
"""Stop the transceiver"""
188
```
189
190
### RTP Source Information
191
192
Information about RTP stream sources for synchronization and identification.
193
194
```python { .api }
195
class RTCRtpSynchronizationSource:
196
"""Synchronization source information."""
197
198
@property
199
def audioLevel(self) -> float:
200
"""Audio level (0.0 to 1.0, None for video)"""
201
202
@property
203
def source(self) -> int:
204
"""SSRC identifier"""
205
206
@property
207
def timestamp(self) -> float:
208
"""Reception timestamp"""
209
210
class RTCRtpContributingSource:
211
"""Contributing source information."""
212
213
@property
214
def audioLevel(self) -> float:
215
"""Audio level (0.0 to 1.0, None for video)"""
216
217
@property
218
def source(self) -> int:
219
"""CSRC identifier"""
220
221
@property
222
def timestamp(self) -> float:
223
"""Reception timestamp"""
224
```
225
226
## Usage Examples
227
228
### Basic RTP Sender Usage
229
230
```python
231
import aiortc
232
import asyncio
233
234
async def basic_sender():
235
pc = aiortc.RTCPeerConnection()
236
237
# Create and add track
238
video_track = aiortc.VideoStreamTrack()
239
sender = pc.addTrack(video_track)
240
241
print(f"Sender kind: {sender.kind}")
242
print(f"Sender track: {sender.track}")
243
244
# Get sender capabilities
245
capabilities = aiortc.RTCRtpSender.getCapabilities("video")
246
print(f"Video codecs: {[codec.mimeType for codec in capabilities.codecs]}")
247
248
# Replace track with different one
249
new_track = aiortc.VideoStreamTrack()
250
await sender.replaceTrack(new_track)
251
print("Track replaced")
252
253
# Get statistics
254
stats = await sender.getStats()
255
print(f"Sender stats: {stats}")
256
```
257
258
### RTP Receiver Handling
259
260
```python
261
async def handle_receiver():
262
pc = aiortc.RTCPeerConnection()
263
264
@pc.on("track")
265
def on_track(track):
266
print(f"Received {track.kind} track")
267
268
# Get the receiver for this track
269
for transceiver in pc.getTransceivers():
270
if transceiver.receiver.track == track:
271
receiver = transceiver.receiver
272
break
273
274
# Get receiver capabilities
275
capabilities = aiortc.RTCRtpReceiver.getCapabilities(track.kind)
276
print(f"Receiver capabilities: {capabilities}")
277
278
# Monitor synchronization sources
279
async def monitor_sources():
280
while True:
281
sync_sources = receiver.getSynchronizationSources()
282
contrib_sources = receiver.getContributingSources()
283
284
if sync_sources:
285
print(f"Sync sources: {[s.source for s in sync_sources]}")
286
if contrib_sources:
287
print(f"Contributing sources: {[c.source for c in contrib_sources]}")
288
289
await asyncio.sleep(1)
290
291
# Start monitoring in background
292
asyncio.create_task(monitor_sources())
293
```
294
295
### Transceiver Management
296
297
```python
298
async def manage_transceivers():
299
pc = aiortc.RTCPeerConnection()
300
301
# Add transceiver for bidirectional audio
302
audio_transceiver = pc.addTransceiver("audio", direction="sendrecv")
303
print(f"Audio transceiver: {audio_transceiver.kind}, direction: {audio_transceiver.direction}")
304
305
# Add send-only video transceiver
306
video_track = aiortc.VideoStreamTrack()
307
video_transceiver = pc.addTransceiver(video_track, direction="sendonly")
308
print(f"Video transceiver: {video_transceiver.kind}, direction: {video_transceiver.direction}")
309
310
# Set codec preferences
311
video_capabilities = aiortc.RTCRtpSender.getCapabilities("video")
312
h264_codecs = [codec for codec in video_capabilities.codecs if "H264" in codec.mimeType]
313
if h264_codecs:
314
video_transceiver.setCodecPreferences(h264_codecs)
315
print("Set H.264 codec preference")
316
317
# List all transceivers
318
transceivers = pc.getTransceivers()
319
for i, t in enumerate(transceivers):
320
print(f"Transceiver {i}: {t.kind}, {t.direction}, mid: {t.mid}, stopped: {t.stopped}")
321
322
# Change direction after creation
323
audio_transceiver.direction = "recvonly"
324
print(f"Changed audio direction to: {audio_transceiver.direction}")
325
326
# Stop a transceiver
327
video_transceiver.stop()
328
print(f"Video transceiver stopped: {video_transceiver.stopped}")
329
```
330
331
### RTP Statistics Monitoring
332
333
```python
334
async def monitor_rtp_stats():
335
pc = aiortc.RTCPeerConnection()
336
337
# Add tracks
338
audio_track = aiortc.AudioStreamTrack()
339
video_track = aiortc.VideoStreamTrack()
340
341
audio_sender = pc.addTrack(audio_track)
342
video_sender = pc.addTrack(video_track)
343
344
async def print_stats():
345
while True:
346
# Get overall connection stats
347
all_stats = await pc.getStats()
348
349
# Get specific sender stats
350
audio_stats = await audio_sender.getStats()
351
video_stats = await video_sender.getStats()
352
353
print("=== RTP Statistics ===")
354
355
# Process audio stats
356
for stats in audio_stats.values():
357
if hasattr(stats, 'bytesSent'):
358
print(f"Audio - Bytes sent: {stats.bytesSent}, Packets sent: {stats.packetsSent}")
359
360
# Process video stats
361
for stats in video_stats.values():
362
if hasattr(stats, 'bytesSent'):
363
print(f"Video - Bytes sent: {stats.bytesSent}, Packets sent: {stats.packetsSent}")
364
365
await asyncio.sleep(5) # Update every 5 seconds
366
367
# Start monitoring
368
asyncio.create_task(print_stats())
369
```
370
371
### Advanced Codec Configuration
372
373
```python
374
async def advanced_codec_config():
375
pc = aiortc.RTCPeerConnection()
376
377
# Get available codecs
378
audio_caps = aiortc.RTCRtpSender.getCapabilities("audio")
379
video_caps = aiortc.RTCRtpSender.getCapabilities("video")
380
381
print("Available audio codecs:")
382
for codec in audio_caps.codecs:
383
print(f" {codec.mimeType}, clock rate: {codec.clockRate}, channels: {codec.channels}")
384
385
print("Available video codecs:")
386
for codec in video_caps.codecs:
387
print(f" {codec.mimeType}, clock rate: {codec.clockRate}")
388
389
# Create transceiver with specific codec preferences
390
video_transceiver = pc.addTransceiver("video")
391
392
# Prefer VP8 over other codecs
393
vp8_codecs = [codec for codec in video_caps.codecs if "VP8" in codec.mimeType]
394
if vp8_codecs:
395
video_transceiver.setCodecPreferences(vp8_codecs)
396
print("Set VP8 codec preference")
397
398
# Create audio transceiver preferring Opus
399
audio_transceiver = pc.addTransceiver("audio")
400
opus_codecs = [codec for codec in audio_caps.codecs if "opus" in codec.mimeType]
401
if opus_codecs:
402
audio_transceiver.setCodecPreferences(opus_codecs)
403
print("Set Opus codec preference")
404
```
405
406
### Track Replacement
407
408
```python
409
async def track_replacement():
410
pc = aiortc.RTCPeerConnection()
411
412
# Start with default video track
413
initial_track = aiortc.VideoStreamTrack()
414
sender = pc.addTrack(initial_track)
415
416
print(f"Initial track ID: {initial_track.id}")
417
418
# Create custom video track
419
class ColoredVideoTrack(aiortc.VideoStreamTrack):
420
def __init__(self, color="blue"):
421
super().__init__()
422
self.color = color
423
424
# Replace with colored track
425
colored_track = ColoredVideoTrack("red")
426
await sender.replaceTrack(colored_track)
427
428
print(f"Replaced with track ID: {colored_track.id}")
429
print(f"Sender now has track: {sender.track.id}")
430
431
# Replace with None to stop sending
432
await sender.replaceTrack(None)
433
print(f"Sender track after None replacement: {sender.track}")
434
```