A Python-based WebRTC master that receives video from a WebRTC viewer and uploads it to Amazon Kinesis Video Streams (KVS) for ingestion, storage, and playback.
This application extracts H.264 frames from RTP packets, packages them into MKV format, and streams them to KVS using the PutMedia API.
- WebRTC Master: Acts as signaling master, waiting for viewer connections
- H.264 RTP Parsing: Extracts and reassembles H.264 frames from RTP packets
- MKV Packaging: Packages H.264 frames into MKV format with proper timecodes
- KVS Integration: Streams packaged video to Kinesis Video Streams via PutMedia
- Event System: Built-in event bus for monitoring stream lifecycle
- Configuration Presets: Pre-configured settings for different use cases
- Multi-stream Support: Manage multiple concurrent streams
Browser (Viewer) --> WebRTC --> Master --> H.264 RTP Parser --> MKV Packager --> KVS PutMedia
- Python 3.13
-
Clone the repository
cd python/kvs_web_streamer -
Create virtual environment (once)
python3 -m venv venv
-
Activate virtual environment
source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies (once)
pip install -r requirements.txt
Create a .env file in the project root:
# Required
KVS_CHANNEL_NAME=your-webrtc-channel-name
KVS_STREAM_NAME=your-kvs-stream-name
AWS_REGION=us-west-2
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_SESSION_TOKEN=...
# Optional - Video Settings
VIDEO_WIDTH=640
VIDEO_HEIGHT=480
VIDEO_FPS=30
# Optional - Streaming Settings
CLUSTER_DURATION_MS=2000
QUEUE_SIZE=100
# Optional - Logging
LOG_LEVEL=WARNINGSee the .env.example. Create a copy, edit the fields, and rename the copy to .env.
python sample_ingestion_client.pyThis runs the simple example that:
- Loads configuration from
.env - Initializes WebRTC master
- Waits for viewer connection
- Streams received video to KVS
See also: limitations for this demo application.
- Open https://awslabs.github.io/amazon-kinesis-video-streams-webrtc-sdk-js/examples/index.html and fill in the details to the same signaling channel. The signaling channel must be in the same region, and configured for peer-to-peer mode (not WebRTC ingestion mode).
- Enable "Send video"
- Use "STUN/TURN" for NAT traversal
- Enable Trickle ICE
- Click "Start viewer"
- Allow webcam access when prompted
- Open https://aws-samples.github.io/amazon-kinesis-video-streams-media-viewer
- Configure to access the same stream configured in the Python
- Choose either HLS or DASH
- Use "LIVE" timestamp selector
- Click "Start playback". It may take a few seconds for the media to appear, click the button again
The sample_ingestion_client.py contains various usage examples.
See also: limitations for this demo application.
Use various preset configurations.
from common.config import ConfigPresets
# Low latency (1s clusters)
config = ConfigPresets.low_latency("channel", "stream")
# High quality (720p)
config = ConfigPresets.high_quality("channel", "stream")
# Mobile optimized (low bandwidth)
config = ConfigPresets.mobile_optimized("channel", "stream")See also: limitations for this demo application.
kvs_web_streamer/
├── common/
│ ├── config.py # Configuration management
│ └── events.py # Event bus and metrics
├── streaming/
│ ├── kvs_streaming_client.py # Main streaming client
│ ├── mkv_packager.py # MKV packaging logic
│ ├── sigv4_signer.py # AWS SigV4 signing
│ └── stream_manager.py # Multi-stream management
├── webrtc/
│ ├── h264_rtp_parser.py # H.264 RTP parsing
│ └── webrtc_kvs_master.py # WebRTC master implementation
├── sample_ingestion_client.py # Usage examples
├── requirements.txt
└── README.md
- WebRTC Signaling: Master connects to KVS signaling channel and waits for viewer
- Peer Connection: Establishes WebRTC connection with browser viewer
- Keyframe Management: Sends PLI (Picture Loss Indication / FIR) requests to browser to generate keyframes more frequently, as browser defaults produce intervals too large for KVS fragment requirements
- RTP Reception: Receives H.264 encoded video via RTP
- Frame Extraction: Parses RTP packets to extract complete H.264 frames
- MKV Packaging: Packages frames into MKV clusters with timecodes
- KVS Upload: Streams MKV data to KVS via PutMedia API
Subscribe to stream events:
from common.events import EventBus, StreamEvent
bus = EventBus()
bus.subscribe(StreamEvent.CONNECTED,
lambda e: print(f"Connected: {e.stream_id}"))
bus.subscribe(StreamEvent.KEYFRAME_RECEIVED,
lambda e: print(f"Keyframe: {e.data}"))
bus.subscribe(StreamEvent.ERROR,
lambda e: print(f"Error: {e.data}"))See also: limitations for this demo application.
- Verify AWS credentials are configured correctly
- Check KVS channel and stream names exist and in the same region
- Ensure proper IAM permissions
- Check the browser supports H.264, Constrained Baseline Level 3.1 Profile (42e01f)
- Check firewall rules
- Adjust
CLUSTER_DURATION_MS - Modify video dimensions in
.env
- Increase
QUEUE_SIZEfor high bitrate streams - Use
ConfigPresets.mobile_optimized()for bandwidth-constrained scenarios - Monitor metrics with
StreamMetrics
- Video Only: Current implementation supports video ingestion only
- H.264 Only: Only H.264 codec is supported
- Browser Compatibility: Requires WebRTC-compatible browser, not guaranteed to work across all browsers.
- Demo Status: This is a demo; additional testing required for production use
See LICENSE.md for details.
See CONTRIBUTING.md for details.