RTMP Push Driver¶
A Milestone XProtect device driver that receives direct RTMP push streams and passes H.264 video through to Milestone. Push from OBS, FFmpeg, drones, or any RTMP-capable source directly into XProtect. No intermediate media server required.
Quick Start¶
- Add hardware in Management Client (see Adding a Device)
- Point your RTMP source at
rtmp://<milestone-server>:<port>/<stream-path>(orrtmps://with TLS enabled)
Adding a New RTMP Device¶
After installing, add new hardware in the Management Client:
Credentials: Milestone requires a credential to connect, even though this driver does not verify them. Add any username/password combination (e.g. root / pass) and make sure it is checked.
Factory Default: If you use factory default as credentials, you need to manually select the driver (Hardware Model) in the Add Hardware tab.
Port = RTMP listening port
The port you enter in the Add Hardware tab becomes the RTMP listening port (e.g. 8783). The wizard defaults to port 80, so you must change it to your desired RTMP port.
Unique ports required
Each driver instance must use a unique port. If two instances share the same port, the second one will fail to add and show as not responding.
To add multiple instances, use localhost with a different port for each one.
Usage¶
Push an RTMP stream to rtmp://<milestone-server>:<port>/<stream-path> from any RTMP-capable source. The video encoder must be set to H.264.
OBS Studio¶
- Go to Settings > Stream
- Set Service to Custom...
- Set Server to
rtmp://<milestone-server>:8783 - Set Stream Key to
stream1 - Under Settings > Output, ensure the video encoder is set to x264 (H.264)
FFmpeg (Testing)¶
# Push a test pattern at 30fps
ffmpeg -re -f lavfi -i testsrc2=size=640x480:rate=30 \
-c:v libx264 -preset ultrafast -tune zerolatency -g 30 \
-f flv rtmp://localhost:8783/stream1
# Push a local file
ffmpeg -re -i input.mp4 -c:v libx264 -f flv rtmp://localhost:8783/stream1
Configuration¶
All settings are configured in the Management Client. Hardware settings apply to the entire driver; device settings are per-camera. Changes take effect immediately.
Hardware Settings¶
| Setting | Default | Description |
|---|---|---|
| Server Port | (from URI) | RTMP listening port |
| Show Stream Offline Info | true |
Show test pattern with device name and RTMP URL when offline |
| Max Concurrent Connections | 32 |
Maximum simultaneous RTMP connections (1–1000) |
| Enable Rate Limiter | true |
Per-IP connection rate limiting |
| Rate Limit Max Requests Per Second | 10 |
Max new connections per second per IP (1–1000) |
| TLS Enable (RTMPS) | false |
Wrap connections in TLS. Requires rtmp.pfx in driver folder. |
| TLS Certificate Password | (empty) | Password for the rtmp.pfx file |
Note
Make sure to open the Server Port (TCP) on Windows Firewall and any network firewalls between the stream source and the Milestone server.
Device Settings (Per-Camera)¶
| Setting | Default | Description |
|---|---|---|
| RTMP Push Stream Path | /stream1 – /stream16 |
The RTMP path this camera listens on |
Events¶
| Event | Triggered when |
|---|---|
| RTMP Stream Started | An RTMP source begins pushing to the stream path |
| RTMP Stream Stopped | The RTMP source disconnects or stops publishing |
Use these to trigger recordings, send notifications, activate outputs, or raise alarms via XProtect Rules.
Connection Timeouts¶
| Timeout | Duration | Description |
|---|---|---|
| Publish Timeout | 10 seconds | Clients that connect but never publish are disconnected |
| Video Data Timeout | 15 seconds | Publishers that stop sending video data are disconnected |
| TCP Receive Timeout | 30 seconds | Connections that stop sending any data are disconnected |
TLS / RTMPS¶
The driver supports RTMPS (RTMP over TLS) to encrypt connections.
Enabling TLS¶
- Place a
rtmp.pfx(PKCS#12) certificate file in the driver folder - In the Management Client, set TLS Enable (RTMPS) to
true - Set TLS Certificate Password to the password for the
.pfxfile - Clients must connect using
rtmps://instead ofrtmp://
Creating a Self-Signed Certificate (Testing)¶
$cert = New-SelfSignedCertificate `
-DnsName "localhost","<your-server-hostname>" `
-CertStoreLocation Cert:\LocalMachine\My `
-NotAfter (Get-Date).AddYears(1) `
-KeyExportPolicy Exportable
$password = ConvertTo-SecureString -String "YourPassword" -AsPlainText -Force
Export-PfxCertificate -Cert $cert `
-FilePath "C:\Program Files\Milestone\MIPDrivers\RTMPDriver\rtmp.pfx" `
-Password $password
Security Notes¶
- TLS encrypts the stream data in transit, preventing eavesdropping and tampering
- TLS does not add authentication, the stream path still acts as the stream key
- For production use, use a certificate from a trusted CA (e.g. Let's Encrypt)
- The driver supports TLS 1.2
- Changing any TLS setting restarts the RTMP server, momentarily disconnecting all active streams
Stream Statistics¶
While a publisher is connected, the driver writes a multi-line statistics block to the driver log every 30 seconds, plus one final block when the publisher disconnects. The block lets you tell whether an FPS shortfall is caused by the source, the driver, or the Recording Server, without instrumenting the source side.
Stats blocks are written to the standard driver log:
Search for RTMP Stream Stats: to jump straight to the latest block, or filter by stream path (e.g. RTMP Stream Stats: /stream1).
================ RTMP Stream Stats: /stream1 ================
Publisher : 192.168.1.10:54321
Uptime : 00:05:30 (since 2026-04-25 06:30:00 UTC)
Video codec : H.264 (profile=100 level=40)
Source declared : 1920x1080 @ 30 fps, video=4500 kbps
Source audio : codec=AAC rate=48000 Hz (160 kbps) (audio is ignored by the driver)
--- Last 30s window ---
Push (RTMP) : 900 frames (30.00 fps), 4.50 Mbit/s, avg 18.7 KB/frame, 30 keyframes (GOP~30.0)
Pop (XProtect) : 870 frames (29.00 fps)
Drops in window : overflow=0, SEI-only=0, non-H264=0
Queue depth : avg=1.5, max=12, capacity=300
Inter-frame ms : avg=33.3, min=30.1, max=41.8 (899 samples)
Pacing sleep : avg=2.1 ms (840 sleeps), driver throttled to publisher rate
--- Cumulative ---
Push total : 9900 frames, 167.8 MB
Pop total : 9870 frames (gap to push: 30)
Drops total : overflow=0, SEI-only=0, non-H264=0
=========================================================
What the fields mean¶
| Section | Field | Meaning |
|---|---|---|
| Header | Publisher |
Remote endpoint (IP:port) of the RTMP source |
| Header | Uptime |
Time since the publisher started this session |
| Header | Video codec |
Parsed from the AVC sequence header (profile + level) |
| Header | Source declared |
Resolution, framerate, and video bitrate the publisher advertised in onMetaData. Missing if the publisher does not send onMetaData. |
| Header | Source audio |
Audio metadata from onMetaData. The driver ignores audio at runtime; this field is informational. |
| Window | Push (RTMP) |
Frames received from the publisher during the last window, with derived FPS, bitrate, average frame size, keyframe count, and approximate GOP length |
| Window | Pop (XProtect) |
Frames the Recording Server pulled from the driver during the same window |
| Window | Drops in window |
overflow: queue was full, dropped to next keyframe. SEI-only: a frame contained only non-VCL NALUs (e.g. some DJI drones). non-H264: a frame arrived with a codec id other than AVC. |
| Window | Queue depth |
Frame queue occupancy (avg/max) and capacity. Sustained high values mean the consumer is slower than the producer. |
| Window | Inter-frame ms |
Distribution of arrival deltas between consecutive frames, derived from RTMP timestamps. High max with a normal avg indicates a publisher stall. |
| Window | Pacing sleep |
Time the driver slept to throttle delivery to the publisher's rate. Zero means the queue was empty most of the time, so no pacing was needed. |
| Cumulative | Push total / Pop total |
Counts since the publisher connected. The gap to push is pushed - popped; growing across blocks indicates the consumer is falling behind. |
Troubleshooting¶
| Problem | Solution |
|---|---|
| No video in Smart Client | Check stream path matches camera config. Check driver log. |
| Stream connects but no video | Ensure H.264 (not HEVC/H.265). Check log for SPS/PPS messages. |
| FPS lower than expected | Read the Stream Statistics block and compare Push fps, Pop fps, and Drops. |
| DLLs blocked / driver not loading | Unblock the ZIP before extracting. |
| "Hardware not responding" | Verify Recording Server is running and DLLs are in the correct path. |
| Port already in use | Each driver instance must use a unique port. Change Server Port. |
| "Stream is already being published to" | Only one source can push to a stream path at a time. |
| Connection rejected / rate limited | Increase Rate Limit Max Requests Per Second or disable rate limiter. |
| TLS handshake failure | Verify rtmp.pfx exists and password is correct. Ensure rtmps:// is used. |
Log Location¶
Known Limitations¶
- H.264 only: HEVC/H.265 and other codecs are not supported