A master-slave video streaming system that streams video files over RTP/UDP to network-booted display clients. Slaves boot via iPXE/PXE into a live Linux environment and automatically connect to the master for synchronized multi-screen video playback.
┌─────────────────────┐ RTP/Opus/UDP ┌────────────────┐
│ │◄────────────────────────│ Slave 001 │
│ │ TCP commands (port 5000)│ (PXE booted) │
│ Master Server │────────────────────────►│ │
│ │ ├────────────────┤
│ ┌───────────────┐ │ RTP/Opus/UDP │ Slave 002 │
│ │ Playback │ │◄────────────────────────│ (PXE booted) │
│ │ Controller │ │ TCP commands │ │
│ ├───────────────┤ │────────────────────────►├────────────────┤
│ │ RTP Streamer │ │ RTP/Opus/UDP │ Slave 003 │
│ │ (GStreamer) │ │◄────────────────────────│ (PXE booted) │
│ ├───────────────┤ │ TCP commands │ │
│ │ ControlServer │ │────────────────────────►└────────────────┘
│ ├───────────────┤ │
│ │ Hand Tracker │ │ (optional) Webcam → MediaPipe → matrix coords
│ ├───────────────┤ │
│ │ ASCII │ │ (optional) Webcam → ASCII art → frame push
│ ├───────────────┤ │
│ │ HTTP API │ │ Port 8080: status, next, goto
│ └───────────────┘ │
│ │
│ PXE/DHCP/TFTP │ dnsmasq + nginx
│ ───────────────── │
│ Serves: vmlinuz, │
│ initrd.img, │
│ rootfs.squashfs, │
│ boot.ipxe │
└─────────────────────┘
# Terminal 1: Start the master
python3 master/master.py
# Terminal 2: Start a slave
python3 slave/slave.py 127.0.0.1 5000# Full boot server (includes slave OS + PXE)
./build.sh
# Master-only container
cd docker && ./build_master.sh├── master/ # Master server
│ ├── master.py # Entry point
│ ├── playback_controller.py # Playback orchestration
│ ├── simple_rtsp_server.py # RTP streaming (GStreamer)
│ ├── control_server.py # TCP command server (port 5000)
│ ├── api_server.py # HTTP API (port 8080)
│ ├── hand_tracker.py # MediaPipe hand tracking
│ ├── ascii_processor.py # Webcam → ASCII art
│ └── rules_parser.py # rules.conf parser
├── slave/ # Slave client
│ ├── slave.py # Main client with GStreamer display
│ ├── control_client.py # TCP client for master commands
│ └── matrix_rain.py # Matrix rain renderer
├── config/
│ ├── master.conf # Master configuration
│ └── mac_map.conf # MAC → slave ID mapping
├── videos/{001..NNN}/ # Video directories
│ ├── 001.mp4 # Video for slave 001
│ ├── 002.mp4 # Video for slave 002
│ └── rules.conf # Per-directory playback rules
├── Dockerfile # Full boot server image
├── Dockerfile.master # Master-only image
└── dnsmasq.conf # DHCP/TFTP for PXE boot
Each directory under videos/ uses a 3-digit ID (001, 002, ...). Playback proceeds in sorted order and wraps around.
[RULES]
LOOP=2 # Video play-throughs (default: 1)
AA=1 # ASCII art after video (default: 0)
MATRIX=1 # Matrix rain after video (default: 0)
PLAYBACK_TIME=60 # ASCII/Matrix duration in seconds (default: 60)
VIDEO_CODEC=h264 # 'mjpeg' or 'h264' (default: h264)- Video — Streams videos for LOOP × duration
- ASCII Art (if
AA=1) — Webcam → ASCII art broadcast to slaves - Matrix Rain (if
MATRIX=1) — Animated matrix rain (interactive via hand tracking) - Next directory — Advances to next 3-digit ID, wraps around
[MASTER]
CONTROL_PORT = 5000
RTSP_PORT = 8554
VIDEO_DIR = /path/to/videos
ASCII_FPS = 15
WEBCAM_DEVICE = 03C:97:0E:75:8E:5F=001
52:54:00:12:34:51=002
| Endpoint | Method | Description |
|---|---|---|
/api/status |
GET | Current playback status |
/api/next |
POST | Skip to next directory |
/api/goto/<dir_id> |
POST | Jump to specific directory |
The full boot server builds a squashfs root filesystem via debootstrap containing:
- Xorg + AwesomeWM
- GStreamer + Python slave client
- Automatic slave startup on boot
Slaves PXE boot via iPXE, download kernel/initrd/squashfs over HTTP, and auto-launch the slave client.
| Codec | Encoder | Decoder | Notes |
|---|---|---|---|
| MJPEG | jpegenc | jpegdec | Lower CPU, larger bandwidth |
| H.264 | x264enc | avdec_h264 | Higher CPU, smaller bandwidth |
Default is H.264. Set VIDEO_CODEC=mjpeg in rules.conf to override.
- Python 3 + GStreamer 1.0 (base, good, bad, ugly, libav)
- python3-gi, gir1.2-gstreamer-1.0
- python3-opencv, python3-pillow
- MediaPipe (optional, for hand tracking)
- dnsmasq, nginx, ipxe (for PXE boot server)