H.264/MPEG-TS Video Publisher for Constellation Overwatch
Quick Start β’ Configuration β’ Architecture β’ Development
FFmpeg2Constellation is a high-performance video streaming bridge that captures video from local devices or RTSP streams and publishes H.264/MPEG-TS to NATS JetStream. It serves as the video ingestion layer for Constellation Overwatch, enabling real-time video streaming from edge devices to WebRTC receivers.
- H.264 Encoding - WebRTC-compatible baseline profile with ultrafast preset
- Universal Input - Auto-discovers USB cameras, RTSP streams, and virtual devices
- NATS JetStream - Reliable publishing with backpressure handling
- Low Latency - Zero-latency tuning, 1-second keyframe intervals
- Resilient - Auto-reconnects and restarts on failure
- Cross-Platform - macOS (AVFoundation) and Linux (V4L2)
- Go 1.21+
- FFmpeg with libx264 support
- Task (optional) - taskfile.dev
- Constellation Overwatch
git clone https://github.com/Constellation-Overwatch/ffmpeg2constellation.git
cd ffmpeg2constellationCreate a .env file with your settings:
# Required
CONSTELLATION_ENTITY_ID=drone-01
NATS_URL=nats://localhost:4222
NATS_TOKEN=your_token_here
ENABLE_FRAME_STREAMING=true
# Video Input (optional - auto-discovered if not set)
# RTSP_URL=rtsp://192.168.1.100:554/stream
# DEVICE_PATH=/dev/video0
# Encoding (optional - sensible defaults)
# TARGET_FPS=15
# BITRATE=1500k
# MAX_BITRATE=2000k
# MAX_DIMENSION=1280# Using Task
task run
# Or directly
go run ./cmd/microlithExpected Output:
=== FFmpeg2Constellation Video Publisher ===
Entity ID: drone-01
NATS URL: nats://localhost:4222
Connected to Constellation Overwatch NATS server
Stream 'CONSTELLATION_VIDEO' ready for publishing
Video source: [-f avfoundation -framerate 30 -pixel_format yuyv422 -i 0]
Publishing to: constellation.video.drone-01
Encoding: H.264 baseline @ 1500k (2000k max), 15 fps
Starting video stream...
Publishing MPEG-TS stream...
[STREAM] 500 chunks | 1521 kbps | dropped: 0 | uptime: 30s
| Variable | Description | Required | Default |
|---|---|---|---|
CONSTELLATION_ENTITY_ID |
Unique identifier for this video source | Yes | - |
NATS_URL |
NATS server URL | No | nats://localhost:4222 |
NATS_TOKEN |
NATS authentication token | No | - |
ENABLE_FRAME_STREAMING |
Enable/disable streaming | No | false |
RTSP_URL |
RTSP stream URL (priority over device) | No | - |
DEVICE_PATH |
Specific device path | No | Auto-discovered |
TARGET_FPS |
Target framerate | No | 15 |
BITRATE |
Target bitrate | No | 1500k |
MAX_BITRATE |
Maximum bitrate cap | No | 2000k |
BUF_SIZE |
Encoder buffer size | No | 500k |
MAX_DIMENSION |
Max width (height auto-scales) | No | 1280 |
RTSP_URLenvironment variableDEVICE_PATHenvironment variable- Auto-discovered devices
- Test pattern fallback
flowchart LR
subgraph Edge["Edge Device"]
CAM[("π· Camera\nRTSP / USB")]
FF["FFmpeg\nlibx264"]
PUB["FFmpeg2Constellation\nNATS Publisher"]
CAM -->|Raw Video| FF
FF -->|"MPEG-TS\nH.264"| PUB
end
subgraph Constellation["Constellation Overwatch"]
NATS[("NATS\nJetStream")]
BRIDGE["Video Bridge\nMPEG-TS β RTP"]
WEB["WebRTC\nClients"]
NATS -->|Subscribe| BRIDGE
BRIDGE -->|RTP/WebRTC| WEB
end
PUB -->|"Publish\nconstellation.video.*"| NATS
style CAM fill:#1a1a2e,stroke:#00ff88,color:#00ff88
style FF fill:#1a1a2e,stroke:#00ff88,color:#fff
style PUB fill:#1a1a2e,stroke:#00ff88,color:#fff
style NATS fill:#1a1a2e,stroke:#00ff88,color:#00ff88
style BRIDGE fill:#1a1a2e,stroke:#00ff88,color:#fff
style WEB fill:#1a1a2e,stroke:#00ff88,color:#fff
ffmpeg -hide_banner -loglevel error \
-f avfoundation -framerate 30 -pixel_format yuyv422 -i 0 \
-vf "fps=15,scale='min(1280,iw)':-1" \
-c:v libx264 \
-preset ultrafast \
-tune zerolatency \
-profile:v baseline \
-level 3.1 \
-pix_fmt yuv420p \
-g 15 -keyint_min 15 -sc_threshold 0 \
-b:v 1500k -maxrate 2000k -bufsize 500k \
-f mpegts \
-mpegts_flags +initial_discontinuity \
-constellation.video.{CONSTELLATION_ENTITY_ID}
Example: constellation.video.drone-01
task # Show available tasks
task build # Build binary to bin/
task run # Build and run
task clean # Clean build artifacts
task docker-build # Build Docker image
task docker-run # Start with Docker Compose
task docker-stop # Stop Docker Composeffmpeg2constellation/
βββ cmd/
β βββ microlith/
β βββ main.go # Entry point
βββ pkg/
β βββ config/
β β βββ init.go # Configuration loader
β βββ services/
β β βββ discovery/
β β β βββ discovery.go # Device auto-discovery
β β βββ ffmpeg/
β β βββ ffmpeg.go # FFmpeg runner & publisher
β βββ shared/
β βββ constants.go # Constants & defaults
βββ public/
β βββ overwatch.svg # Logo
βββ .env.example # Example configuration
βββ Taskfile.yml # Task runner config
βββ README.md
--- Constellation Overwatch Connection Help ---
Unable to connect to Constellation Overwatch NATS server.
Troubleshooting steps:
1. Verify Constellation Overwatch is running
2. Check NATS_URL is correct (default: nats://localhost:4222)
3. Verify NATS_TOKEN matches your Constellation Overwatch configuration
4. Ensure network connectivity to the NATS server
5. Check firewall rules allow port 4222
- macOS: Grant camera permissions in System Preferences β Security & Privacy β Camera
- Linux: Ensure user is in
videogroup:sudo usermod -aG video $USER
- Ensure receiver waits for keyframe (IDR) before decoding
- Check network stability - dropped packets cause decoder artifacts
- Increase
BITRATEif quality is poor
MIT License - see LICENSE for details.
Part of the Constellation Overwatch ecosystem