
VStreamerMediaMtx C++ library
v5.1.2
Table of contents
- Overview
- Internal pipelining
- Versions
- Library files
- VStreamerMediaMtx class description
- VStreamerMediaMtx class declaration
- getVersion method
- initVStreamer method
- isVStreamerInit method
- setParam (string) method
- setParam (float) method
- getParams method
- executeCommand method
- setMediaMtxPath method
- sendFrame method
- closeVStreamer method
- decodeAndExecuteCommand method of VStreamer interface
- encodeSetParamCommand method of VStreamer interface
- encodeCommand method of VStreamer interface
- decodeCommand method of VStreamer interface
- Data structures
- VStreamerParams class description
- Simple example
- Test application
- Build and connect to your project
- mediamtx executable file
Overview
The VStreamerMediaMtx C++ library provides RTSP, WebRTC, SRT, RTMP, HLS video streaming and direct RTP streaming without audio. The library enables multiple video streams (different protocols simultaneously) compatible with all popular video clients. The library is based on the mediamtx video proxy server (run as an external process by the library). The library provides all necessary capabilities for video streaming devices: one video source → one/multiple video streams (RTSP, WebRTC, SRT, RTMP, HLS, direct RTP), multiple video sources → multiple video streams with different protocols. Work principle: the user feeds each video frame (frame-by-frame) in RAW or compressed format to the library, the library resizes the video and applies video overlay (if VOverlay implementation is provided by the user), encodes and then streams video to the mediamtx process with RTP protocol, the mediamtx process receives RTP streams and creates several streams with different protocols (RTSP, WebRTC, SRT, RTMP, HLS). Additionally, the library supports direct RTP streaming to a user-specified IP and port, bypassing mediamtx for low-latency unicast scenarios. The library will stream video frames as-is in the case of H264, HEVC or JPEG input frames. If the user provides RAW frames (not encoded), a VCodec implementation must be provided to the initVStreamer(…) method for video encoding. The library runs an external mediamtx process and restarts it when changing parameters. The library allows users to create multiple streams from different cameras. When the user creates multiple instances of the VStreamerMediaMtx C++ class, only one mediamtx process will be run. The library provides a simple interface and supports different platforms (x86, ARM, etc.). To support video encoding on a particular platform, the user must provide a video codec implementation according to the VCodec interface. The library provides easy integration of mediamtx server capabilities into C++ code. It is compatible with Linux operating systems only.
STANAG 4609 KLV metadata streaming (RTSP and SRT). The library carries MISB ST 0601 KLV metadata end-to-end to standard clients. For the server leg (delivered to clients through the mediamtx server) set serverStreamType = "mpegts-rtp-klv": the encoded video and the KLV are pushed to mediamtx as a STANAG 4609 MPEG-TS stream with synchronous KLV (MISB ST 0604, MPEG-TS stream_type 0x15) over the local loopback (RtpPusher streamType = "mpegts-klv-sync", read by mediamtx via udp+mpegts://); mediamtx demuxes the inner transport stream and re-serves the video together with the KLV track over RTSP (as a data track) and SRT (as a KLV track). Alternatively serverStreamType = "rtp-klv" delivers the KLV over RTSP/SRT as a secondary RTP application track (payload type 98). The same MISB KLV can also be sent on the direct point-to-point leg via directStreamType (mpegts-klv-async / mpegts-rtp-klv-async / mpegts-klv-sync / mpegts-rtp-klv-sync). The per-frame KLV buffer is supplied to sendFrame(…) as a complete UAS Datalink Local Set; in the MPEG-TS modes the library auto-refreshes the Precision Time Stamp (Tag 2) and recomputes the Checksum (Tag 1) on every frame.
Network binding and security controls (since 5.1.0). The library exposes the server-side network posture through the VStreamer 3.2.0 interface instead of leaving it to hand edits of mediamtx.yml: bindAddress confines every listener to one address on a multi-homed host, publicAddress is advertised to WebRTC clients in the ICE candidates so streaming works behind 1:1 NAT and inside containers, rtpPortMin/rtpPortMax keep every RTP/RTCP port inside a range a firewall has been opened for, webRtcMediaPort pins the WebRTC media port that used to be picked at random, corsAllowedOrigin replaces the wildcard CORS policy of the HLS and WebRTC endpoints with a single origin, and serverStreamMaxPayloadSize sizes the datagrams the media server itself emits. securityProfile = "strict" refuses, at initVStreamer(…) and on every setParam(…), any parameter set that would put media or credentials on the wire unprotected. See the VStreamerParam enum section for the exact contract of each one.
The library inherits its interface from VStreamer, mediamtx (provides video server, run as an external process, binary files included in code, will be embedded into library file, MIT license), cmrc (CMakeRC - A Standalone CMake-Based C++ Resource Compiler, cmake file to include mediamtx binaries into the library, MIT license), VCodec (defines video codec interface, source code included, Apache 2.0 license), VOverlay (defines video overlay interface, source code included, Apache 2.0 license), FormatConverter (provides methods to convert pixel formats, source code included), ChildProcess (provides functions to run child processes, source code included), RtpPusher (provides RTP pushing function to mediamtx process, source code included), ImageResizer (provides image resize function, source code included) and Logger (provides logging functions, source code included).
The library supports all necessary video streaming parameters. Additionally, mediamtx has a config file which includes many additional parameters that can be changed if necessary. The library works frame-by-frame and accepts video frames in the following formats: RGB24, BGR24, YUYV, UYVY, GRAY, YUV24, NV12, NV21, YU12, YV12, H264 (video resize and overlay not supported), HEVC (video resize and overlay not supported) and JPEG (video resize and overlay not supported). The following figure shows the workflow inside the library:

The user must provide the path to the mediamtx executable file (files for different platforms are included in the repository). The library reads the config file, runs the mediamtx external process, and controls it (restarting if necessary to implement necessary parameters). By default, the library runs only one mediamtx process (single mode), but some RTSP clients require a unique strict multicast IP address for each video stream which is not supported by mediamtx. To provide necessary functionality, the library can work in multiple mode (run several mediamtx processes). In case of single mediamtx process mode, all instances of the VStreamerMediaMtx class use the same port for all video streams for external clients. If the user changes one of these parameters in one instance, all other VStreamerMediaMtx instances in the user application will be restarted automatically with new parameters. The mediamtx process provides an RTSP server on the same port for all streams (difference only in stream name). For example: rtsp://127.0.0.1:7031/Camera1Stream1 (first instance of VStreamerMediaMtx), rtsp://127.0.0.1:7031/Camera1Stream2 (second instance of VStreamerMediaMtx), etc. In case of multiple mediamtx process mode, each instance of the VStreamerMediaMtx class uses its own port for external clients. If the user changes one of these parameters in one instance, only this instance will be restarted automatically with new parameters. The library provides automatic mediamtx configuration (creates config file) if the user provides a path to the mediamtx executable file. If the user doesn’t provide a path to the mediamtx executable file, the necessary parameters must be changed in the mediamtx configuration file (mediamtx.yml). To change any of them, the user must stop the mediamtx process, change the mediamtx.yml file, and run the mediamtx process again. The following figure shows the main difference between single mediamtx process mode and multiple mediamtx process mode:

Internal pipelining
Since v4.0.0 the internal worker is split into two threads so that preprocessing and encoding can overlap when the workload is CPU-heavy (e.g. high FPS, large resolution, GL-accelerated overlay). The handoff between the two stages is a single-slot blocking producer-consumer — no frames are lost between stages, and the producer naturally throttles to the slower stage.
Stage A — preprocess thread
- Pace at the target FPS, read the latest frame from the public
m_frame(set bysendFrame()). - Convert input to YUV24 (when input is RAW).
- Resize to
width × height(fitorcropmode perfitMode). - Apply the user-supplied VOverlay (when
overlayEnable == true). - Convert to NV12.
- Hand off the NV12 frame to the encoder thread (block until the slot is empty).
For already-encoded input frames (H264/HEVC/JPEG) Stage A skips steps 2–5 and forwards the frame as-is.
Stage B — encoder/send thread
- Wait for the slot to be full, copy the frame out, free the slot.
- Encode via
m_codec->transcode()when the input is NV12, or pass through when the input was already encoded. - Push to mediamtx via the local-loopback
RtpPusher(always paced at the local-network/high bitrate; the loopback RTP payload size is chosen automatically and optimised for localhost — a single standard-MTU packet, ~1452 bytes). KLV metadata is carried perserverStreamType. - If
directStreamEnableis on, push directly to the user via the secondRtpPusher. Transport and KLV are decided bydirectStreamType; pacing followsdirectStreamPacingMode(target bitrate fromdirectStreamBitrateKbpsin mode 0, back-pressure in mode 1).
Throughput, latency, drop policy.
- Throughput:
min(target_fps, 1 / max(time_StageA, time_StageB)). With a hardware codec and a heavy overlay the two stages are comparable in cost and can overlap, lifting throughput up to ~2× compared to sequential execution. - Latency: pipelining adds one frame of delay (~16.7 ms at 60 fps).
- Drop policy: between the two stages there are no frame drops — the producer waits for the consumer. At the input boundary (
sendFrame() → m_frame) intermediate frames are still overwritten if the caller produces faster than the slowest stage; this is unavoidable for any fixed-throughput pipeline.
Threading contract for VOverlay. m_overlay->overlay() is invoked exclusively from Stage A’s worker thread. If the overlay implementation uses OpenGL, its GL context must be made current on this thread (e.g. via eglMakeCurrent() on first call, or by passing a shared context).
Concurrency safety for RtpPusher. Both RtpPusher::send() and RtpPusher::stop() are protected by per-pusher mutexes (m_rtpPusherToMediamtxMutex, m_rtpPusherToUserMutex) so that runtime parameter changes (e.g. DIRECT_STREAM_IP, DIRECT_STREAM_PORT, DIRECT_STREAM_ENABLE) cannot race with the encoder thread’s send() calls.
Versions
Table 2 - Library versions.
| Version | Release date | What’s new |
|---|---|---|
| 1.0.0 | 15.12.2024 | - First version. |
| 1.1.0 | 14.01.2025 | - Add support of Nvidia Jetson platform. - Add start/stop control for mediamtx. |
| 1.1.1 | 28.01.2025 | - Fix resolution settings and restart issue of mediamtx. |
| 1.1.2 | 10.02.2025 | - Add streamer params to overlay engine. |
| 1.1.3 | 13.02.2025 | - Add check for odd multicast port value. |
| 1.1.4 | 18.02.2025 | - Fix encoding params table in documentation. |
| 1.1.5 | 27.03.2025 | - Fix mutex block according to FPS. |
| 1.1.6 | 23.06.2025 | - Add mtu size to rtspclientsink. |
| 1.1.7 | 29.06.2025 | - Add additional pipeline parameters to reduce latency. |
| 1.1.8 | 01.07.2025 | - Implement checking mediamtx’s RTSP ready status before running pipeline. |
| 1.1.9 | 17.07.2025 | - Set strict multicast IP. |
| 1.1.10 | 24.07.2025 | - Implement detection of multicast ip mask. |
| 1.2.0 | 08.08.2025 | - Add support for unique mediamtx for each stream. |
| 1.3.0 | 26.09.2025 | - Fix resolution change issue. - Add imx platform support. |
| 2.0.0 | 07.11.2025 | - Add support for WebRTC, SRT, RTMP and HLS streaming. - Exclude gstreamer dependency from library. - Implement rtp streaming to mediamtx. - Update VStreamer interface. - Implement metadata support. |
| 2.0.1 | 21.11.2025 | - Add custom MediaMTX fork information and executables for Onvif Profile S compliance. |
| 2.0.2 | 28.11.2025 | - Fix initialization. - Add missing metadata mode parameter. |
| 2.1.0 | 29.12.2025 | - Add fps control. - Add rtp stream support directly to user. |
| 2.1.1 | 17.01.2026 | - RtpPusher submodule updated. |
| 2.1.2 | 07.02.2026 | - RtpPusher submodule updated. |
| 2.2.0 | 12.02.2026 | - Add udpMaxPayloadSize control via CUSTOM1 parameter. - User name and password are now unique per stream (per-stream authentication). |
| 2.2.1 | 13.02.2026 | - Restrict metadataSuffix to two valid values: SMPTE336M (KLV metadata) and VND.ONVIF.METADATA (ONVIF metadata). - Fix metadataSuffix validation logic in setParam. - Update documentation with metadata streaming behavior details. |
| 2.3.0 | 15.02.2026 | - Add support for embedded mediamtx binary. - Update CMake configuration for mediamtx embedding. |
| 2.3.1 | 24.02.2026 | - Updated test application. - Fixed mistakes in code comments. |
| 2.3.2 | 24.02.2026 | - RtpPusher submodule updated. - Updated RTP streaming function. |
| 2.3.3 | 28.02.2026 | - RtpPusher submodule updated. - Fixed FPS control mechanism to reduce video jitter. |
| 2.3.4 | 21.03.2026 | - RtpPusher submodule updated. |
| 2.3.5 | 01.04.2026 | - Fixed RTSP stream restore after FPS change. |
| 3.0.0 | 05.04.2026 | - Removed OpenCV dependency. - Added new submodules: ImageResizer and FormatConverter. - Fixed wiping all used ports. - Fixed killing mediamtx processes. - Fixed infinite loop when restarting mediamtx process. - Fixed ending conditions for port-finding loop. |
| 3.0.1 | 13.04.2026 | - Fixed performance issue. - RtpPusher submodule updated. |
| 4.0.0 | 03.05.2026 | - Refactored to two-stage pipelined architecture (preprocess + encode/send threads) for sustained high-FPS workloads. - Migrated to new RtpPusher non-blocking send() API.- Fixed YAML quoting bug for *ServerKey/*ServerCert in mediamtx.yml. |
| 4.0.1 | 13.05.2026 | - Embedded mediamtx rebuilt from CR fork with RTSP-over-HTTP tunnel fixes for Live555-based clients (Genetec/Omnicast) and ONVIF Profile T compliance. - Updated MediaMTX section in README with build reproduction steps. |
| 4.1.0 | 15.06.2026 | - New directStreamType parameter to stream STANAG 4609 directly to the user: RTP, MPEG-TS (MISB ST 1402) or MPEG-TS over RTP (MISB ST 1403). - KLV metadata now carried on the direct MPEG-TS stream; max metadata size increased to 16384 bytes. |
| 4.2.0 | 16.06.2026 | - New KLV-signalling mode parameter to select KLV signalling on the MPEG-TS paths (direct mpegts/mpegts-rtp and the mediamtx loopback): 0 asynchronous (stream_type 0x06 + “KLVA” registration, raw KLV), 1 synchronous (stream_type 0x15 + metadata_descriptor + metadata_AU_cell), per MISB ST 0604. - KLV now reaches RTSP/SRT through mediamtx in MPEG-TS mode with no fork (mediamtx demuxes the KLV PID and re-serves it as a native KLV track). - directStreamMaxPayloadSize now accepts up to 65535 bytes (RtpPusher slot size scales with it). Keep ~1420 for normal use; large packets are recommended for localhost / trusted LAN only. Changing it restarts the direct pusher. - RtpPusher submodule updated to 2.0.1; VStreamer submodule updated to 2.2.0. |
| 5.0.0 | 17.06.2026 | - New parameters added. - Added support of STANAG 4609 via RTSP. - VSTreamer interface updated. |
| 5.0.1 | 07.07.2026 | - Fixed video timestamps mechanism to prevent latency increasing. |
| 5.0.2 | 14.07.2026 | - Hardened the default MediaMTX authentication in the generated mediamtx.yml: the anonymous publish permission is now restricted to the loopback (ips: ['127.0.0.1', '::1']) — only the library’s own local RTP push can publish, so a remote host can no longer inject or override a stream (rejected with 401 Unauthorized). Anonymous read/playback remain open for external viewers by default; set USER/PASSWORD to require a login for reading. - Set overridePublisher: no in the default path config so an active stream can no longer be taken over by a new publisher. |
| 5.0.3 | 14.08.2026 | - FormatConverter submodule updated. |
| 5.1.0 | 19.08.2026 | - VStreamer submodule updated to 3.2.0. - ImageResizer submodule updated. |
| 5.1.1 | 28.08.2026 | - ImageResizer submodule updated. - FormatConverter submodule updated. |
| 5.1.2 | 12.09.2026 | - ImageResizer submodule updated. - FormatConverter submodule updated. |
Library files
The library is supplied only by source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:
CMakeLists.txt --------------------- Main CMake file of the library.
3rdparty --------------------------- Folder with third-party libraries.
CMakeLists.txt ----------------- CMake file to include third-party libraries.
FormatConverter ---------------- Folder with FormatConverter library source code.
ImageResizer ------------------- Folder with ImageResizer library source code.
VStreamer ---------------------- Folder with VStreamer library source code.
ChildProcess ------------------- Folder with ChildProcess library source code.
RtpPusher ---------------------- Folder with RtpPusher library source code.
Logger ------------------------- Folder with Logger library source code.
cmrc --------------------------- Folder with CMakeRC library for embedding resources.
src -------------------------------- Folder with library source code.
CMakeLists.txt ----------------- CMake file of the library.
VStreamerMediaMtx.cpp ---------- C++ implementation file.
VStreamerMediaMtx.h ------------ Main library header file.
VStreamerMediaMtxVersion.h ----- Header file with library version.
VStreamerMediaMtxVersion.h.in -- CMake service file to generate version file.
DefaultMediaMtxConfigFileContent.h -- Default mediamtx config content.
example ---------------------------- Folder for example application files.
CMakeLists.txt ----------------- CMake file of example application.
main.cpp ----------------------- Source C++ file of example application.
test ------------------------------- Folder for test application files.
CMakeLists.txt ----------------- CMake file of test application.
main.cpp ----------------------- Source C++ file of interactive test application.
test_driver.cpp ---------------- Headless TCP-controlled driver for automated tests.
run_protocol_tests.py ---------- End-to-end protocol and parameter test runner.
static ----------------------------- Folder for mediamtx archives (embedded at compile time).
mediamtx_v1.15.1-linux_amd64.tar.gz -- MediaMTX archive for x86_64/amd64 platforms (CR fork build, see "Custom MediaMTX for ONVIF Profile S" below).
mediamtx_v1.15.1-linux_arm64.tar.gz -- MediaMTX archive for arm64/aarch64 platforms (CR fork build).
mediamtx_v1.15.1-linux_armv7.tar.gz -- MediaMTX archive for armv7 platforms (CR fork build).
mediamtx_v1.15.1-linux_armv6.tar.gz -- MediaMTX archive for armv6 platforms (CR fork build).
VStreamerMediaMtx class description
VStreamerMediaMtx class declaration
The VStreamerMediaMtx class is declared in the VStreamerMediaMtx.h file. Class declaration:
namespace cr
{
namespace video
{
/// Video streamer.
class VStreamerMediaMtx : public cr::video::VStreamer
{
public:
/// Get string of current library version.
static std::string getVersion();
/// Class destructor.
~VStreamerMediaMtx();
/// Init video streamer by set of parameters.
bool initVStreamer(cr::video::VStreamerParams ¶ms,
cr::video::VCodec *codec = nullptr,
cr::video::VOverlay *overlay = nullptr) override;
/// Get init status.
bool isVStreamerInit() override;
/// Close video streamer.
void closeVStreamer() override;
/// Send frame to video streamer.
bool sendFrame(cr::video::Frame& frame, uint8_t* userData = nullptr, int userDataSize = 0) override;
/// Set video streamer parameter.
bool setParam(cr::video::VStreamerParam id, float value) override;
/// Set video streamer parameter.
bool setParam(cr::video::VStreamerParam id, std::string value) override;
/// Get all video streamer parameters.
void getParams(cr::video::VStreamerParams& params) override;
/// Execute action command.
bool executeCommand(cr::video::VStreamerCommand id) override;
/// Set media mtx path.
static void setMediaMtxPath(std::string path, bool isSingleMediaMTX = true);
};
}
}
getVersion method
The getVersion() method returns a string of the current class version. Method declaration:
static std::string getVersion();
Method can be used without VStreamerMediaMtx class instance:
cout << "VStreamerMediaMtx version: " << VStreamerMediaMtx::getVersion();
Console output:
VStreamerMediaMtx version: 5.1.0
initVStreamer method
The initVStreamer(…) method initializes the video streamer. If the streamer is already initialized, the method returns TRUE without reinitializing. If video streamer parameters need to be changed after initialization, the user does not need to call the initVStreamer(…) method again (use the setParam(…) method instead). Method declaration:
bool initVStreamer(cr::video::VStreamerParams ¶ms,
cr::video::VCodec *codec = nullptr,
cr::video::VOverlay *overlay = nullptr) override;
| Parameter | Value |
|---|---|
| params | VStreamerParams object which includes all parameters for initialization. |
| codec | VCodec object pointer. It must be provided for video encoding if input video frames are raw frames (not encoded). |
| overlay | VOverlay object pointer for video overlay function. It should implement overlay in YUV format. |
Returns: TRUE if initialization is done or FALSE if not.
isVStreamerInit method
The isVStreamerInit() method returns video streamer initialization status. Method declaration:
bool isVStreamerInit() override;
Returns: TRUE if the video streamer is initialized or FALSE if not.
setParam (string parameter) method
The setParam(…) method sets a parameter with a string value. Some parameters require modification of the mediamtx.yml file as well. If the path that contains mediamtx is set by using the setMediaMtxPath method, the library will handle creating the required config file/files and all required modifications internally and restart mediamtx properly. If multiple mediamtx is set, mediamtx configuration files will be created in the form mediamtx-<stream_id>.yml where <stream_id> is the index of the instance from 0. For example, if there are two instances of mediamtx, the configuration files will be mediamtx-0.yml and mediamtx-1.yml. If this path is not set, the user is responsible for the configuration of mediamtx.yml and restarting mediamtx.
Method declaration:
bool setParam(cr::video::VStreamerParam id, std::string value) override;
| Parameter | Value |
|---|---|
| id | Parameter ID according to VStreamerParam enum. |
| value | Parameter value with string type. |
Returns: TRUE if parameter is set or FALSE if not.
setParam (float parameter) method
The setParam(…) method sets a parameter with a float value. Some parameters require modification of the mediamtx.yml file as well. If the path that contains mediamtx is set by using the setMediaMtxPath method, the library will handle all required modifications internally and restart mediamtx properly. See Table 5 for more information about changing parameters and the behavior of streams. Method declaration:
bool setParam(cr::video::VStreamerParam id, float value) override;
| Parameter | Value |
|---|---|
| id | Parameter ID according to VStreamerParam enum. |
| value | Parameter value with float type. |
Returns: TRUE if parameter is set or FALSE if not.
getParams method
The getParams(…) method gets all parameters that are defined in the form of VStreamerParams. Method declaration:
void getParams(cr::video::VStreamerParams& params) override;
| Parameter | Value |
|---|---|
| params | Reference to VStreamerParams object to store all video server parameters. |
executeCommand method
The executeCommand(…) method executes an action command. Method declaration:
bool executeCommand(cr::video::VStreamerCommand id) override;
| Parameter | Value |
|---|---|
| id | Command ID according to VStreamerCommand enum. |
Returns: TRUE if command is executed or FALSE if not.
setMediaMtxPath method
The setMediaMtxPath(…) is a static method to set the path to the mediamtx executable. The method must be called before the first instance of the VStreamerMediaMtx class is initialized. The library will run mediamtx as an additional process and handle all required modifications internally. If the path is not set, the initVStreamer(…) method will fail and return FALSE.
Embedded MediaMTX Binary
When the CMake option VSTREAMER_MEDIAMTX_EMBED_BINARY is enabled (default: ON), the library embeds the mediamtx executable directly into the compiled library using CMakeRC. When setMediaMtxPath(…) is called, the embedded binary is automatically extracted to the specified path. This eliminates the need to manually distribute the mediamtx executable with your application.
Supported architectures for embedded binary:
- x86_64/amd64 -
mediamtx_v1.15.1-linux_amd64.tar.gz - arm64/aarch64 -
mediamtx_v1.15.1-linux_arm64.tar.gz - armv7 -
mediamtx_v1.15.1-linux_armv7.tar.gz - armv6 -
mediamtx_v1.15.1-linux_armv6.tar.gz
The appropriate archive is automatically selected at compile time based on the target architecture.
To disable embedded binary and use an external mediamtx executable, set the CMake option:
SET(VSTREAMER_MEDIAMTX_EMBED_BINARY OFF)
Method declaration:
static void setMediaMtxPath(std::string path, bool isSingleMediaMTX = true);
| Parameter | Value |
|---|---|
| path | Path to the mediamtx executable. When embedded binary is enabled, the executable will be extracted to this path. For example: “/home/pi/mediamtx” will extract and place the executable at that location. When embedded binary is disabled, this should be the full path to an existing mediamtx executable. |
| isSingleMediaMTX | If true, the library will run a single instance of mediamtx for all streams. If false, the library will run a separate instance of mediamtx for each stream. Default value is true. |
sendFrame method
The sendFrame(…) method sends a video frame to the video streamer for streaming. The method copies the frame data to an internal buffer and returns immediately — actual processing (convert/resize/overlay/encode/RTP push) runs on the library’s two internal worker threads (see Internal pipelining). If the caller produces frames faster than the pipeline can consume them, the most recent frame in the internal buffer is overwritten on the next call. Method declaration:
bool sendFrame(cr::video::Frame& frame, uint8_t* userData = nullptr, int userDataSize = 0) override;
| Parameter | Value |
|---|---|
| frame | Frame object. The method accepts video frames in formats: RGB24, BGR24, YUYV, UYVY, GRAY, YUV24, NV12, NV21, YU12, YV12, H264, HEVC, and JPEG. |
| userData | Optional pointer to user data buffer (metadata, e.g. KLV). KLV is put on the wire whenever a non-empty userData buffer is supplied and the relevant leg’s stream type requests metadata (the metadataEnable parameter does not gate it). Delivery depends on the transport: • Through mediamtx the metadata is carried per serverStreamType: with “rtp-klv” it is muxed as a secondary RTP application track (payload type 98, clock rate 90000 Hz, SDP name = metadataSuffix) and reaches clients over RTSP (as a data track) and SRT (as a KLV track); with “mpegts-rtp-klv” it travels on its own MPEG-TS PID (STANAG 4609) which mediamtx demuxes and re-serves as native tracks. With “rtp” the server leg is video-only. • On the direct stream to the user it is carried whenever directStreamType is any “mpegts-*“ value (on its own KLV PID); with direct “rtp” the direct stream is video-only. In MPEG-TS modes the library refreshes the MISB ST 0601 Precision Time Stamp (Tag 2) and Checksum (Tag 1) automatically. Maximum size: 16384 bytes (effective limit ~2048 bytes over RTP, full buffer over MPEG-TS). Default: nullptr. |
| userDataSize | Size of user data buffer in bytes. Must be <= 16384 bytes. Default: 0. |
Returns: TRUE if the frame is sent or FALSE if not.
closeVStreamer method
The closeVStreamer() method closes the video server if it is open. Method declaration:
void closeVStreamer() override;
decodeAndExecuteCommand method of VStreamer interface
The decodeAndExecuteCommand(…) method decodes and executes a command encoded by the encodeSetParamCommand(…) and encodeCommand(…) methods on the video streamer side. It is a virtual method which means if the implementation does not define it, the default definition from the VStreamer class will be used. Each implementation of the video streamer must provide thread-safe setParam(…) and executeCommand(…) method calls to make the default definition of decodeAndExecuteCommand(…) thread-safe. This means that the decodeAndExecuteCommand(…) method can be safely called from any thread. Method declaration:
virtual bool decodeAndExecuteCommand(uint8_t* data, int size);
| Parameter | Description |
|---|---|
| data | Pointer to input command. |
| size | Size of command. |
Returns: TRUE if command decoded (SET_PARAM or COMMAND) and executed (action command or set param command).
encodeSetParamCommand method of VStreamer interface
The encodeSetParamCommand(…) static method encodes a command to change any parameter in a remote video streamer. To control a video streamer remotely, the developer has to design their own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the VStreamer class contains static methods for encoding the control command. The VStreamer class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeSetParamCommand(…) is designed to encode SET_PARAM commands. The method has two overloads: one for numeric parameters and one for string parameters. Method declaration:
static void encodeSetParamCommand(uint8_t* data, int& size, VStreamerParam id, std::string value);
static void encodeSetParamCommand(uint8_t *data, int &size, VStreamerParam id, float value);
| Parameter | Description |
|---|---|
| data | Pointer to data buffer for output command. Must be non-null. The float overload needs at least 11 bytes; the string overload needs 7 + value.size() + 1 bytes. A null pointer sets size to 0 and writes nothing. |
| size | Size of encoded data. 11 bytes for the float overload, 7 + value.size() + 1 for the string overload. |
| id | Parameter ID according to VStreamerParam enum. |
| value | Numeral video streamer parameter value. Only for non string parameters. For string parameters (see VStreamerParam enum) this parameters may have any values. |
| value | String parameter value (see VStreamerParam enum). |
Message families (VStreamer 3.2.0). The first byte identifies the message: 0x00 action command, 0x01 numeric set-param, 0x03 string set-param, 0x02 a serialized
VStreamerParamssnapshot. The string set-param moved from 0x02 to 0x03 in 3.2.0 precisely so that the four families no longer overlap — sharing 0x02 meantdecodeCommand(...)could misread a serialized parameters snapshot as a garbage string set-param. Encoders and decoders from 3.1.0 and 3.2.0 are therefore not interchangeable for string parameters.
encodeSetParamCommand(…) is a static method and can be used without a VStreamer class instance. This method is used on the client side (control system). Command encoding example:
// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Random parameter value.
float outValue = (float)(rand() % 20);
// Encode command.
VStreamer::encodeSetParamCommand(data, size, VStreamerParam::CUSTOM1, outValue);
encodeCommand method of VStreamer interface
The encodeCommand(…) static method encodes a command for a remote video streamer. To control a video streamer remotely, the developer has to design their own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the VStreamer class contains static methods for encoding the control command. The VStreamer class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeCommand(…) is designed to encode COMMAND (action command). Method declaration:
static void encodeCommand(uint8_t* data, int& size, VStreamerCommand id);
| Parameter | Description |
|---|---|
| data | Pointer to data buffer for output command. Must have size >= 7 bytes. |
| size | Size of encoded data. Will be 7 bytes. |
| id | Command ID according to VStreamerCommand enum. |
encodeCommand(…) is a static method and can be used without a VStreamer class instance. This method is used on the client side (control system). Command encoding example:
// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Encode command.
VStreamer::encodeCommand(data, size, VStreamerCommand::RESTART);
decodeCommand method of VStreamer interface
The decodeCommand(…) static method decodes a command on the video streamer side (edge device). Method declaration:
static int decodeCommand(uint8_t* data, int size, VStreamerParam& paramId,
VStreamerCommand& commandId, float& value,
std::string& strValue);
| Parameter | Description |
|---|---|
| data | Pointer to input command. Must be non-null. |
| size | Size of command. An action COMMAND must be exactly 7 bytes and a numeric SET_PARAM exactly 11; a string SET_PARAM must be at least 8 bytes and end with its null terminator. |
| paramId | Parameter ID according to VStreamerParam enum. After decoding SET_PARAM command the method will return parameter ID. |
| commandId | Command ID according to VStreamerCommand enum. After decoding COMMAND the method will return command ID. |
| value | Numeral video streamer parameter value. Only for non string parameters. For string parameters (see VStreamerParam enum) this parameters may have any values. |
| strValue | String parameter value (see VStreamerParam enum). |
Returns: 0 - action COMMAND decoded, 1 - SET_PARAM with a float value, 2 - SET_PARAM with a string value, -1 - error (null buffer, wrong version, unknown header byte, inexact COMMAND/float size, or a string payload missing its terminator or carrying trailing bytes). value and strValue are cleared before decoding, so they never carry over a previous call’s data when the method fails.
Stricter since VStreamer 3.2.0. A truncated or over-long datagram is now rejected instead of being decoded into a plausible-looking parameter: the previous implementation silently truncated a string payload at 511 bytes and would swallow whatever followed a missing terminator.
Data structures
VStreamer.h file defines IDs for parameters (VStreamerParam enum) and IDs for commands (VStreamerCommand enum).
VStreamerCommand enum
Enum declaration:
enum class VStreamerCommand
{
/// Restart.
RESTART = 1,
/// Enable. Equal to MODE param.
ON,
/// Disable. Equal to MODE param.
OFF,
/// Generate key frame command.
GENERATE_KEYFRAME
};
Table 3 - Video stream commands description.
| Command | Description |
|---|---|
| RESTART | Restarts streamer with last VStreamerParams. |
| ON | Enables streamer if it is disabled. |
| OFF | Disables streamer if it is enabled. |
| GENERATE_KEYFRAME | Not supported by VStreamerMediaMtx library. |
VStreamerParam enum
Enum declaration:
namespace cr
{
namespace video
{
enum class VStreamerParam
{
/// Mode: 0 - disabled, 1 - enabled.
MODE = 1,
/// Video stream width from 8 to 4096.
WIDTH,
/// Video stream height from 8 to 4096.
HEIGHT,
/// Destination IP of the direct stream (point-to-point, bypasses mediamtx).
DIRECT_STREAM_IP,
/// RTSP port.
RTSP_PORT,
/// RTSPS port.
RTSPS_PORT,
/// RTP port.
DIRECT_STREAM_PORT,
/// WebRTC port.
WEBRTC_PORT,
/// HLS port.
HLS_PORT,
/// SRT port.
SRT_PORT,
/// RTMP port.
RTMP_PORT,
/// RTMPS port.
RTMPS_PORT,
/// Metadata port.
METADATA_PORT,
/// RTSP protocol enable / disable.
RTSP_MODE,
/// RTP protocol enable / disable.
DIRECT_STREAM_ENABLE,
/// WebRTC protocol enable / disable.
WEBRTC_MODE,
/// HLS protocol enable / disable.
HLS_MODE,
/// SRT protocol enable / disable.
SRT_MODE,
/// RTMP protocol enable / disable.
RTMP_MODE,
/// Metadata protocol enable / disable.
METADATA_MODE,
/// RTSP multicast IP.
RTSP_MULTICAST_IP,
/// RTSP multicast port.
RTSP_MULTICAST_PORT,
/// Streamer user (unique per stream): "" - no user.
USER,
/// Streamer password (unique per stream): "" - no password.
PASSWORD,
/// Streamer suffix(for rtsp streaming, stream name).
SUFFIX,
/// Metadata suffix (stream name).
METADATA_SUFFIX,
/// Minimum bitrate for variable bitrate mode, kbps.
MIN_BITRATE_KBPS,
/// Maximum bitrate for variable bitrate mode, kbps.
MAX_BITRATE_KBPS,
/// Current bitrate, kbps.
BITRATE_KBPS,
/// Bitrate mode: 0 - constant bitrate, 1 - variable bitrate.
BITRATE_MODE,
/// FPS.
FPS,
/// GOP size for H264 and H265 codecs.
GOP,
/// H264 profile: 0 - baseline, 1 - main, 2 - high.
H264_PROFILE,
/// JPEG quality from 1 to 100% for JPEG codec.
JPEG_QUALITY,
/// Codec type: "H264", "HEVC" or "JPEG".
CODEC,
/// Scaling mode: 0 - fit, 1 - fill.
FIT_MODE,
/// Cycle time, microseconds. Calculated by RTSP server.
CYCLE_TIME_USEC,
/// Overlay mode: false - off, true - on.
OVERLAY_MODE,
/// Type of the streamer. Depends on implementation.
TYPE,
/// Custom parameter 1. Deprecated alias of SERVER_STREAM_MAX_PAYLOAD.
CUSTOM1,
/// Custom parameter 2. Deprecated alias of DIRECT_STREAM_BITRATE_KBPS.
CUSTOM2,
/// Custom parameter 3, float. Read only: 0 - one mediamtx for all
/// streams, 1 - a unique mediamtx per stream.
CUSTOM3,
/// Path to openssl key for RTSP, string.
RTSP_KEY,
/// Path to openssl certificate for RTSP, string.
RTSP_CERT,
/// Path to openssl key for WebRTC, string.
WEBRTC_KEY,
/// Path to openssl certificate for WebRTC, string.
WEBRTC_CERT,
/// Path to openssl key for HLS, string.
HLS_KEY,
/// Path to openssl certificate for HLS, string.
HLS_CERT,
/// Path to openssl key for RTMP, string.
RTMP_KEY,
/// Path to openssl certificate for RTMP, string.
RTMP_CERT,
/// RTSP encryption type, string: "no", "strict", "optional".
RTSP_ENCRYPTION,
/// WebRTC encryption type, string: "no", "yes".
WEBRTC_ENCRYPTION,
/// RTMP encryption type, string: "no", "strict", "optional".
RTMP_ENCRYPTION,
/// HLS encryption type, string: "no", "yes".
HLS_ENCRYPTION,
/// Logging mode. Values: 0 - Disable, 1 - Only file,
/// 2 - Only terminal, 3 - File and terminal.
LOG_LEVEL,
/// Direct stream transport, string: "rtp", "mpegts-klv-async",
/// "mpegts-rtp-klv-async", "mpegts-klv-sync", "mpegts-rtp-klv-sync".
DIRECT_STREAM_TYPE,
/// Target sending bitrate of the direct stream, integer kbps [500:1000000].
DIRECT_STREAM_BITRATE_KBPS,
/// Maximum RTP payload size of the direct stream, integer bytes [256:65535].
DIRECT_STREAM_MAX_PAYLOAD,
/// Pacing mode of the direct stream, integer: 0 - target bitrate,
/// 1 - push / back-pressure.
DIRECT_STREAM_PACING_MODE,
/// Server-delivered stream type, string: "rtp", "rtp-klv", "mpegts-rtp-klv".
SERVER_STREAM_TYPE,
/// Multicast TTL (scope) for every multicast leg, integer [0:255]:
/// 0 - implementation default.
MULTICAST_TTL,
/// Security/compliance profile, string: "no" (or "") - the implementation
/// default, "strict" - refuse anything unprotected. An unrecognised value
/// is rejected, never silently defaulted.
SECURITY_PROFILE,
/// Public (routed) address advertised to clients instead of the locally
/// detected one, string: "" or "no" - detect automatically.
PUBLIC_ADDRESS,
/// Local address every listener binds to, string: "" or "0.0.0.0" -
/// every interface.
BIND_ADDRESS,
/// Lowest port of the RTP/RTCP range, integer [0:65534]: 0 - any
/// ephemeral port.
RTP_PORT_MIN,
/// Highest port of the RTP/RTCP range, integer [0:65535]: 0 - any
/// ephemeral port.
RTP_PORT_MAX,
/// WebRTC media (UDP) port, integer [0:65535]: 0 - the implementation
/// chooses. Distinct from WEBRTC_PORT, which carries signalling only.
WEBRTC_MEDIA_PORT,
/// Single origin permitted to reach the HTTP-based signalling endpoints,
/// string "scheme://host[:port]": "" or "no" - the default policy.
CORS_ALLOWED_ORIGIN,
/// Maximum RTP payload size of the server-delivered stream, integer bytes.
SERVER_STREAM_MAX_PAYLOAD
};
}
}
Table 4 - Video streamer params description.
| Parameter | Description |
|---|---|
| MODE | Enable / disable streamer: 0 - disable, 1 - enable. |
| WIDTH | Frame width from 8 to 4096. Regardless of the resolution of the input video, the streamer will scale the images according to this parameter. |
| HEIGHT | Frame height from 8 to 4096. Regardless of the resolution of the input video, the streamer will scale the images according to this parameter. |
| DIRECT_STREAM_IP | Destination IP of the direct stream (transport set by directStreamType; bypasses mediamtx). Default 127.0.0.1. |
| RTSP_PORT | RTSP server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| RTSPS_PORT | RTSPS server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| DIRECT_STREAM_PORT | Destination port for direct RTP streaming to user (bypasses mediamtx). |
| WEBRTC_PORT | WebRTC server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| HLS_PORT | HLS server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| SRT_PORT | SRT server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| RTMP_PORT | RTMP server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| RTMPS_PORT | RTMPS server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| METADATA_PORT | Not used by VStreamerMediaMtx. Part of the VStreamer interface for compatibility; KLV metadata is not delivered on a dedicated port (it is muxed into the same stream session — see sendFrame). |
| RTSP_MODE | Enable / disable RTSP protocol: 0 - disable, 1 - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| DIRECT_STREAM_ENABLE | Enable / disable direct streaming to user (bypasses mediamtx): 0 - disable, 1 - enable. Uses DIRECT_STREAM_IP and DIRECT_STREAM_PORT parameters. Transport is set by DIRECT_STREAM_TYPE: with “rtp” the direct stream is video only; every “mpegts-*“ value also carries KLV metadata (STANAG 4609). |
| WEBRTC_MODE | Enable / disable WebRTC protocol: 0 - disable, 1 - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| HLS_MODE | Enable / disable HLS protocol: 0 - disable, 1 - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| SRT_MODE | Enable / disable SRT protocol: 0 - disable, 1 - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| RTMP_MODE | Enable / disable RTMP protocol: 0 - disable, 1 - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| METADATA_MODE | Accepted (0 - disable, 1 - enable) for VStreamer interface compatibility, but it does not gate KLV in VStreamerMediaMtx. Whether the userData buffer provided to the sendFrame(…) method is put on the wire is decided solely by the per-leg stream type — SERVER_STREAM_TYPE for the MediaMTX leg and DIRECT_STREAM_TYPE for the direct leg — combined with the presence of a non-empty buffer. Through mediamtx, KLV is carried with “rtp-klv” (secondary RTP application track, payload type 98) or “mpegts-rtp-klv” (own MPEG-TS PID) and reaches clients via RTSP and SRT; with “rtp” the server leg is video only. On the direct stream KLV is carried when DIRECT_STREAM_TYPE is any “mpegts-*“ value (STANAG 4609); with direct “rtp” the direct stream is video only. |
| RTSP_MULTICAST_IP | RTSP server multicast IP. Multicast RTSP streaming is enabled by default in mediamtx. IP can be set with a mask or without a mask. If a mask is not set, the default mask /16 will be used. Example of multicast IP: 239.255.0.1 (in this case /16 will be added by default) or 239.255.0.1/24. The library uses a unique multicast IP for each stream from the IP range set by the user. If changed, the mediamtx process will be restarted by the library automatically. |
| RTSP_MULTICAST_PORT | RTSP server multicast port. Multicast RTSP streaming is enabled by default in mediamtx. If the multicast port is changed, the mediamtx process will be restarted by the library automatically. The library uses one multicast port for all streams. |
| USER | User name for authentication (unique per stream). Each stream instance has its own user name. In single MediaMTX mode, changing credentials for one stream will restart the mediamtx process but other streams keep their own credentials. Access model (since 5.0.2): when USER/PASSWORD are left empty the stream is public — any client may read/playback it from any IP; set USER and PASSWORD to require a login for read/playback. Regardless of credentials, publish is always restricted to the loopback (127.0.0.1/::1): only the library’s own local RTP push feeds MediaMTX, so remote publishing / stream-override is rejected (401 Unauthorized). If external read access must also be closed, set USER/PASSWORD on the stream. Since 5.1.0 the credentials are written into mediamtx.yml as quoted YAML scalars, so a value containing #, @, * or & is carried through intact instead of truncating the entry. MediaMTX validates credentials itself and refuses to start on an unsupported character, so the library now rejects anything outside the set MediaMTX accepts — letters, digits and ! # $ & ( ) * + - . ; < = > @ [ ] ^ _ { }. That set was determined by probing the bundled binary with every printable ASCII character, because MediaMTX’s own error message is inaccurate (it lists ", which it rejects, and omits { }, which it accepts); the rejected punctuation is " % ' , / : ? \ | ~ plus space. The user name **any** is refused as well: MediaMTX reserves it for anonymous access and dies on it when a password is set (using a password with ‘any’ user is not supported`), while without a password it means exactly what leaving the credentials unset already means. Both setParam and initVStreamer enforce this. |
| PASSWORD | Password for authentication (unique per stream). Each stream instance has its own password. In single MediaMTX mode, changing credentials for one stream will restart the mediamtx process but other streams keep their own credentials. See USER for the full access model (empty credentials → public read/playback; publish is loopback-only in all cases). |
| SUFFIX | Stream name for RTSP server. Accepted characters (since 5.1.0): letters, digits and _ - . ~ / — the suffix becomes a YAML mapping key and an authentication path in the generated mediamtx.yml, so a value carrying YAML syntax (a space, a colon, a quote, a #, a newline) would either corrupt the file or silently change which paths the permissions apply to. Slashes are allowed because MediaMTX path names are hierarchical, but the value may not begin or end with one (invalid path name '/live': can't begin with a slash), may not begin with ~ (MediaMTX would read the name as a regular expression) and may not be all or all_others (both are reserved). Each of those makes MediaMTX refuse to start, not merely ignore the stream. A purely numeric or boolean-looking name such as 123 or no is accepted: the generated path key is written as a quoted YAML scalar, so it stays a string. If changed, the mediamtx process will be restarted by the library automatically. |
| METADATA_SUFFIX | RTP media track name for metadata within the same RTSP stream session. Only two values are allowed: “SMPTE336M” (for KLV metadata per SMPTE 336M standard) and “VND.ONVIF.METADATA” (for ONVIF metadata). Default: “SMPTE336M”. This value is used as the rtpmap attribute name for the secondary m=application media line in the SDP descriptor generated for mediamtx. The metadata is not streamed as a separate RTSP endpoint — it is a second RTP track (payload type 98, clock rate 90000 Hz) muxed alongside the video track within the same stream path defined by SUFFIX. The resulting SDP structure is: m=video ... <codec>, m=application ... <metadataSuffix>. If an invalid value is provided to initVStreamer, it will be silently corrected to “SMPTE336M”. If an invalid value is provided to setParam, the method will return FALSE. If changed, the mediamtx process will be restarted by the library automatically. Also used in the mediamtx authentication configuration to grant read permissions for the metadata path. |
| MIN_BITRATE_KBPS | Minimum bitrate for VBR mode (100..100000 kbps). Applied to codec if provided. |
| MAX_BITRATE_KBPS | Maximum bitrate for VBR mode (100..100000 kbps). Applied to codec if provided. |
| BITRATE_KBPS | Bitrate for H264 and H265 codecs (100..100000 kbps). Applied to codec if provided. |
| BITRATE_MODE | Bitrate mode: 0 CBR, 1 VBR. Applied to codec if provided. |
| FPS | Streamer’s FPS and also encoding FPS. The library paces the producer thread to maintain this rate regardless of input video frame rate. Valid range: 1..120 FPS. Note (since v4.0.0): changing FPS at runtime no longer restarts the RTP push or mediamtx — the new value is picked up on the very next frame. The codec implementation may still rebuild its internal pipeline if FPS is part of its caps; downstream RTSP/RTMP/HLS clients keep their session. |
| GOP | H264 or H265 codec GOP size (1..1000). Applied to codec if provided. |
| H264_PROFILE | H264 encoding profile: 0 - baseline, 1 - main, 2 - high. Applied to codec if provided. |
| JPEG_QUALITY | JPEG encoding quality from 1 to 100. Applied to codec if provided. |
| CODEC | Codec type: H264, HEVC or JPEG. If changed, the mediamtx process will be restarted by the library automatically. |
| FIT_MODE | Scaling mode: 0 - fit, 1 - fill. |
| OVERLAY_MODE | Overlay enable / disable: 0 - disable, 1 - enable. |
| CYCLE_TIME_USEC | Read only Cycle timeout, microseconds. |
| TYPE | Codec type selector: 0 - software codec, 1 - hardware codec. Applied to codec if provided. The actual behavior depends on the VCodec implementation. |
| CUSTOM1 | Deprecated alias of SERVER_STREAM_MAX_PAYLOAD (since 5.1.0). Same storage, same accepted range 204..1472 bytes, default 1472. Writing either parameter updates both, and getParams reports both with the same value. See SERVER_STREAM_MAX_PAYLOAD for the full description. |
| CUSTOM2 | Deprecated alias of DIRECT_STREAM_BITRATE_KBPS. Target bitrate for the direct pusher in kbps (500..1 000 000, default 5000). Used as the pacer target when DIRECT_STREAM_PACING_MODE is 0; ignored when it is 1 (push / back-pressure — the RtpPusher channel bitrate is 0). Does not affect the loopback push to mediamtx. Has no effect when DIRECT_STREAM_ENABLE is disabled. Updates take effect on the next outgoing frame — no restart of any stream. |
| CUSTOM3 | Read only. Reports how mediamtx is being run: 0 - one shared process for all streams, 1 - a process per stream. Which of the two applies is decided once by setMediaMtxPath(…), so since 5.1.0 setParam refuses a write to it (before, the write was accepted and only corrupted what getParams reported). |
| RTSP_KEY | Path to openssl key for RTSP, string: “no” for no key. If changed, the mediamtx process will be restarted by the library automatically. |
| RTSP_CERT | Path to openssl certificate for RTSP, string: “no” for no certificate. If changed, the mediamtx process will be restarted by the library automatically. |
| WEBRTC_KEY | Path to openssl key for WebRTC, string: “no” for no key. If changed, the mediamtx process will be restarted by the library automatically. |
| WEBRTC_CERT | Path to openssl certificate for WebRTC, string: “no” for no certificate. If changed, the mediamtx process will be restarted by the library automatically. |
| HLS_KEY | Path to openssl key for HLS, string: “no” for no key. If changed, the mediamtx process will be restarted by the library automatically. |
| HLS_CERT | Path to openssl certificate for HLS, string: “no” for no certificate. If changed, the mediamtx process will be restarted by the library automatically. |
| RTMP_KEY | Path to openssl key for RTMP, string: “no” for no key. If changed, the mediamtx process will be restarted by the library automatically. |
| RTMP_CERT | Path to openssl certificate for RTMP, string: “no” for no certificate. If changed, the mediamtx process will be restarted by the library automatically. |
| RTSP_ENCRYPTION | RTSP encryption type, string: “no”, “strict”, “optional”. If changed, the mediamtx process will be restarted by the library automatically. |
| WEBRTC_ENCRYPTION | WebRTC encryption type, string: “no”, “yes”. If changed, the mediamtx process will be restarted by the library automatically. |
| RTMP_ENCRYPTION | RTMP encryption type, string: “no”, “strict”, “optional”. If changed, the mediamtx process will be restarted by the library automatically. |
| HLS_ENCRYPTION | HLS encryption type, string: “no”, “yes”. If changed, the mediamtx process will be restarted by the library automatically. |
| LOG_LEVEL | Logging mode. Values: 0 - Disable, 1 - Only file, 2 - Only terminal, 3 - File and terminal. |
| DIRECT_STREAM_TYPE | Transport of the direct (user-facing, point-to-point) stream, mirrors the RtpPusher::send() streamType exactly. String values: “rtp” (default — codec RTP, video only, no KLV), “mpegts-klv-async” (MPEG-TS over UDP, asynchronous KLV; MISB ST 1402 / STANAG 4609, stream_type 0x06 + “KLVA”), “mpegts-rtp-klv-async” (MPEG-TS over RTP, asynchronous KLV; MISB ST 1403), “mpegts-klv-sync” (MPEG-TS over UDP, synchronous KLV; MISB ST 0604, stream_type 0x15 + metadata_AU_cell), “mpegts-rtp-klv-sync” (MPEG-TS over RTP, synchronous KLV). The value alone decides KLV: “rtp” is video-only; every “mpegts-*“ value carries KLV on its own TS PID. JPEG supports “rtp” only. Does not affect the mediamtx leg, whose transport is set separately by SERVER_STREAM_TYPE. |
| DIRECT_STREAM_BITRATE_KBPS | Target sending bitrate of the direct stream, kbps [500:1000000] (default 5000). Used as the pacer target when DIRECT_STREAM_PACING_MODE is 0; ignored when it is 1. CUSTOM2 is a deprecated alias with the same range. Takes effect on the next outgoing frame — no stream restart. |
| DIRECT_STREAM_MAX_PAYLOAD | Maximum RTP payload size of the direct stream, bytes [256:65535] (default 1472). Applies to the direct “rtp” transport only (the direct MPEG-TS modes emit fixed 1316/1328-byte datagrams). Changing it restarts the direct pusher so the new size can be re-latched. |
| DIRECT_STREAM_PACING_MODE | Pacing mode of the direct stream: 0 - target bitrate (token-bucket, uses DIRECT_STREAM_BITRATE_KBPS), 1 - push / back-pressure (kernel send-buffer occupancy; the bitrate is ignored). |
| SERVER_STREAM_TYPE | Transport/type of the MediaMTX-leg stream: “rtp” (codec RTP, video only), “rtp-klv” (codec RTP + KLV as a second RTP application track, payload type 98), “mpegts-rtp-klv” (raw MPEG-TS over UDP, STANAG 4609, synchronous KLV on its own PID). The value alone decides KLV. For JPEG only “rtp” / “rtp-klv” are valid. If changed, the mediamtx process will be restarted by the library automatically. |
| SERVER_STREAM_MAX_PAYLOAD | Maximum RTP payload size of the server-delivered stream, bytes [204:1472] (default 1472) — the counterpart of DIRECT_STREAM_MAX_PAYLOAD for the MediaMTX leg. Written into udpMaxPayloadSize in the MediaMTX config, i.e. the size of the UDP datagrams MediaMTX itself emits (RTSP/UDP, RTSP multicast, SRT). The 1472-byte upper bound is MediaMTX’s own: it refuses to start with a larger value ('udpMaxPayloadSize' must be less than 1472), so the library never writes a larger one. setParam rejects an out-of-range value; initVStreamer clamps it into range and logs a warning, because it must also absorb the 0 that deserialize() leaves for a cleared mask bit. Does not affect the loopback push to mediamtx (whose RTP payload size is chosen automatically and optimised for localhost, ~1452 bytes) nor the direct stream. In single MediaMTX mode this parameter is shared across all instances; in multiple mode each instance has its own value. Changing it restarts the mediamtx process. CUSTOM1 is a deprecated alias. **Note:** for the JPEG codec this parameter is recommended to be set to 1470. With a value <1470 the MJPEG stream may not be stable. |
| MULTICAST_TTL | Multicast TTL (scope) for every multicast leg, [0:255], 0 - implementation default. Documented implementation cap: the only multicast leg VStreamerMediaMtx owns is the RTSP one and it is served by mediamtx, whose 1.15.1 configuration exposes no multicast TTL key. The value is therefore validated, stored and reported back by getParams, but the TTL actually on the wire is the one MediaMTX picks; a non-zero value logs a warning saying so. |
| SECURITY_PROFILE | Security/compliance profile, string. Accepted values are implementation-defined; VStreamerMediaMtx defines exactly two: “no” (or ”“) — the default, imposes nothing; and “strict” — refuses any parameter set that would put media or credentials on the wire unprotected. Under “strict”: every enabled protocol must be encrypted (RTSP_ENCRYPTION = “strict”, RTMP_ENCRYPTION = “strict”, HLS_ENCRYPTION = “yes”, WEBRTC_ENCRYPTION = “yes”), SRT_MODE must be off (MediaMTX 1.15.1 offers no transport encryption for its SRT listener and this library does not configure SRT passphrases), DIRECT_STREAM_ENABLE must be off (the direct leg is plain RTP/UDP), USER and PASSWORD must both be set (empty credentials mean anonymous read for anyone), and CORS_ALLOWED_ORIGIN must name a single origin (the default policy is a wildcard). An unrecognised value is rejected by both initVStreamer and setParam, never mapped onto the default. The profile is a validation gate over this stream’s parameters, so it is per instance even in single MediaMTX mode, and it never on its own rewrites the config or restarts mediamtx. |
| PUBLIC_ADDRESS | Public (routed) address advertised to clients instead of the locally detected one, string: ”“ or “no” - detect automatically. Must be an IPv4/IPv6 address literal, never a hostname — the value reaches the wire verbatim, so a hostname is rejected. Written into webrtcAdditionalHosts in the MediaMTX config, which adds it to the ICE candidates MediaMTX advertises: this is what makes WebRTC work behind 1:1 NAT, in containers and on multi-homed hosts where the detected address is unroutable for the viewer. If changed, the mediamtx process will be restarted by the library automatically. |
| BIND_ADDRESS | Local address every listener binds to, string: ”“ or “0.0.0.0” (or ”::”) - every interface. Must be an IPv4/IPv6 address literal. Applied to every MediaMTX listener address — rtspAddress, rtspsAddress, rtpAddress, rtcpAddress, srtpAddress, srtcpAddress, rtmpAddress, rtmpsAddress, hlsAddress, webrtcAddress, webrtcLocalUDPAddress, srtAddress — so a multi-homed host can keep a stream off an interface it must not appear on. IPv6 literals are bracketed automatically and the whole value is written as a quoted YAML scalar (unquoted, a leading [ would open a YAML flow sequence and MediaMTX would refuse the entire config). The readiness probe the library uses to decide whether mediamtx has come up follows this address too — probing a fixed loopback would never succeed once the listeners move off it. If changed, the mediamtx process will be restarted by the library automatically. |
| RTP_PORT_MIN | Lowest port of the RTP/RTCP range, [0:65534]: 0 - any ephemeral port. Set together with RTP_PORT_MAX it confines the ports the library draws for the MediaMTX RTP/RTCP and SRTP/SRTCP listeners, for the multicast SRTP/SRTCP pair and (at initVStreamer time) for the WebRTC media port and the loopback push port. Should be even, because RTCP conventionally takes port+1; an odd value is rounded up when a pair is allocated. A firewall is opened for a range — without one the library would pick ephemeral ports nothing has been opened for. If changed, the mediamtx process will be restarted by the library automatically. |
| RTP_PORT_MAX | Highest port of the RTP/RTCP range, [0:65535]: 0 - any ephemeral port. See RTP_PORT_MIN. Both bounds must be set together and the range must hold at least 10 ports counted from the first even port at or above RTP_PORT_MIN. The allocator draws three even-aligned RTP/RTCP pairs from it (loopback RTP/RTCP, loopback SRTP/SRTCP, multicast SRTP/SRTCP) plus two single ports (the loopback push port and the WebRTC media port); each single port can land inside an aligned pair slot and spoil it, so five slots’ worth of room is required. A pair that cannot be reserved is fatal: MediaMTX exits with RTP (0) and RTCP (0) ports must be consecutive rather than picking an ephemeral port. Both initVStreamer and setParam reject a complete range that is too small; setParam additionally accepts each bound on its own — so the two can be set in either order — and logs a warning while the pair is still incomplete, during which the allocator keeps using ephemeral ports. If a valid range has run out of free ports at allocation time the library falls back to ports outside it and logs a warning, because a stream outside the range beats no stream at all. |
| WEBRTC_MEDIA_PORT | WebRTC media (UDP) port, [0:65535]: 0 - the implementation chooses. Distinct from WEBRTC_PORT, which carries signalling only. Written into webrtcLocalUDPAddress in the MediaMTX config. Before 5.1.0 this port was always chosen automatically and could not be pinned, which made it impossible to open a stable hole for it in a firewall. Setting 0 through setParam keeps the port currently in force rather than drawing a new one — re-drawing it would move the media port under the viewers connected through it. If changed, the mediamtx process will be restarted by the library automatically. |
| CORS_ALLOWED_ORIGIN | Single origin permitted to reach the HTTP-based signalling endpoints, string “scheme://host[:port]”: ”“ or “no” - the implementation’s default policy, which is MediaMTX’s wildcard '*'. Written into hlsAllowOrigin and webrtcAllowOrigin. Deliberately one origin: a wildcard, a list, a trailing slash, a path component or credentials in the value are all rejected, since replacing the wildcard is the entire point of the parameter. The authority is restricted to the RFC 3986 host/port character set, so control bytes cannot reach the config either — MediaMTX refuses to start on one, and a folded newline would leave an origin no browser could ever match. A bracketed IPv6 origin is accepted with or without a port (http://[::1], http://[::1]:8080). If changed, the mediamtx process will be restarted by the library automatically. |
All parameters can be updated in VStreamerMediaMtx via overloaded setParam methods that accept float or string values. However, the behavior of VStreamerMediaMtx depends on the parameter being updated and mediamtx instance (see setMediaMtxPath). For single mediamtx instance mode, some parameters are shared across all instances — updating these parameters will change the value for all instances and restart mediamtx. Other parameters are unique per instance but still require a mediamtx restart when changed (the new value only applies to the current instance). Some parameters can be updated without restarting mediamtx at all. The following table shows the groups of parameters based on their update behavior:
Table 5 - Parameter Groups
| Update Behavior | Parameters |
|---|---|
| Mediamtx restart, parameter shared across all instances | All video server ports (RTSP, RTSPS, RTMP, RTMPS, WebRTC, SRT, HLS), RTSP multicast port, protocol enable/disable flags (RTSP_MODE, RTMP_MODE, WEBRTC_MODE, HLS_MODE, SRT_MODE), RTSP multicast IP, SERVER_STREAM_MAX_PAYLOAD / CUSTOM1 (udpMaxPayloadSize), BIND_ADDRESS, PUBLIC_ADDRESS, CORS_ALLOWED_ORIGIN, RTP_PORT_MIN, RTP_PORT_MAX, WEBRTC_MEDIA_PORT, all encryption modes and SSL keys/certificates |
| Mediamtx restart, parameter unique per instance | user, password, suffix, metadata suffix, codec, SERVER_STREAM_TYPE |
| Update without mediamtx restart | width, height, fps, GOP, H264 profile, JPEG quality, bitrate, min/max bitrate, bitrate mode, overlay enable, fit mode, mode, type, METADATA_MODE, DIRECT_STREAM_IP, DIRECT_STREAM_PORT, DIRECT_STREAM_ENABLE, DIRECT_STREAM_BITRATE_KBPS / CUSTOM2 (direct stream bitrate), DIRECT_STREAM_TYPE, DIRECT_STREAM_MAX_PAYLOAD, DIRECT_STREAM_PACING_MODE, MULTICAST_TTL, SECURITY_PROFILE, log level |
MULTICAST_TTL and SECURITY_PROFILE are in the last group for different reasons. MULTICAST_TTL does not appear in the MediaMTX configuration at all (MediaMTX 1.15.1 has no such key), so regenerating the config would produce a byte-identical file and the restart would drop every connected client for nothing. SECURITY_PROFILE is a validation gate over this stream’s parameters rather than a value written into the configuration, which is also why it stays per instance even in single MediaMTX mode.
If restart of the related instance is required, all clients should also reconnect to the related stream.
If multiple mediamtx instances are used, each instance will have its own set of parameters, and updating any parameter will only affect the current instance. The behavior of the parameters remains the same as described above, but the changes will not affect other instances. In this case, the user should be aware that the same RTSP port and multicast port are not allowed for different instances, so the user should set a unique RTSP port and multicast port for each instance. If the same ports are set, the initVStreamer(…) method will adjust them automatically. However, the setParam method will not adjust them automatically and the user should handle this manually.
VStreamerParams class description
VStreamerParams class declaration
The VStreamerParams class is used for video stream initialization (initVStreamer(…) method) or to get all current params (getParams(…) method). The VStreamerParams class also provides a structure to write/read params from JSON files (see ConfigReader class description) and provides methods to serialize and deserialize params. Since VStreamer 3.2.0 the JSON conversion is hand-written (to_json / from_json) instead of the JSON_READABLE macro — see Read params from JSON file and write to JSON file. Class declaration:
namespace cr
{
namespace video
{
class VStreamerParams
{
public:
/// Streamer enable / disable (for all protocols): false - Off, true - On.
bool enable{true};
/// Video stream width from 8 to 4096.
int width{1280};
/// Video stream height from 8 to 4096.
int height{720};
/// Destination IP of the direct stream (point-to-point, bypasses mediamtx).
std::string directStreamIp{"127.0.0.1"};
/// RTSP port.
int rtspPort{8554};
/// RTSPS port.
int rtspsPort{8555};
/// RTP port.
int directStreamPort{5004};
/// WebRTC port.
int webRtcPort{7000};
/// HLS port.
int hlsPort{8080};
/// SRT port.
int srtPort{6000};
/// RTMP port.
int rtmpPort{1935};
/// RTMPS port.
int rtmpsPort{1936};
/// Metadata port.
int metadataPort{9000};
/// RTSP protocol enable / disable.
bool rtspEnable{true};
/// Direct RTP to user enable / disable.
bool directStreamEnable{true};
/// WebRTC protocol enable / disable.
bool webRtcEnable{true};
/// HLS protocol enable / disable.
bool hlsEnable{true};
/// SRT protocol enable / disable.
bool srtEnable{true};
/// RTMP protocol enable / disable.
bool rtmpEnable{true};
/// Metadata protocol enable / disable.
bool metadataEnable{false};
/// RTSP multicast IP.
std::string rtspMulticastIp{"224.1.0.1/16"};
/// RTSP multicast port.
int rtspMulticastPort{18000};
/// Streamer user (unique per stream): "" or "no" - no user.
std::string user{"no"};
/// Streamer password (unique per stream): "" or "no" - no password.
std::string password{"no"};
/// Stream suffix (for rtsp streaming) (stream name).
std::string suffix{"live"};
/// Metadata suffix (stream name). VStreamerMediaMtx accepts only
/// "SMPTE336M" or "VND.ONVIF.METADATA" and normalises anything else
/// (including this default) to "SMPTE336M" in initVStreamer().
std::string metadataSuffix{"metadata"};
/// Minimum bitrate for variable bitrate mode, kbps.
int minBitrateKbps{1000};
/// Maximum bitrate for variable bitrate mode, kbps.
int maxBitrateKbps{5000};
/// Current bitrate, kbps.
int bitrateKbps{3000};
/// Bitrate mode: 0 - constant bitrate, 1 - variable bitrate.
int bitrateMode{0};
/// FPS.
float fps{30.0f};
/// GOP size for H264 and H265 codecs.
int gop{30};
/// H264 profile: 0 - baseline, 1 - main, 2 - high.
int h264Profile{0};
/// JPEG quality from 1 to 100% for JPEG codec.
int jpegQuality{80};
/// Codec type: "H264", "HEVC" or "JPEG".
std::string codec{"H264"};
/// Scaling mode: 0 - fit, 1 - fill.
int fitMode{0};
/// Cycle time, microseconds. Calculated by RTSP server.
int cycleTimeUs{0};
/// Overlay enable / disable: false - off, true - on.
bool overlayEnable{true};
/// Type of the streamer. Depends on implementation.
int type{0};
/// Deprecated alias of serverStreamMaxPayloadSize (204..1472 bytes).
float custom1{0.0f};
/// Deprecated alias of directStreamBitrateKbps (500..1000000).
float custom2{0.0f};
/// Read only: 0 - one mediamtx for all streams, 1 - a unique mediamtx
/// per stream.
float custom3{0.0f};
/// Path to openssl key for RTSP, string.
std::string rtspKey{"no"};
/// Path to openssl certificate for RTSP, string.
std::string rtspCert{"no"};
/// Path to openssl key for WebRTC, string.
std::string webRtcKey{"no"};
/// Path to openssl certificate for WebRTC, string.
std::string webRtcCert{"no"};
/// Path to openssl key for HLS, string.
std::string hlsKey{"no"};
/// Path to openssl certificate for HLS, string.
std::string hlsCert{"no"};
/// Path to openssl key for RTMP, string.
std::string rtmpKey{"no"};
/// Path to openssl certificate for RTMP, string.
std::string rtmpCert{"no"};
/// RTSP encryption type, string: "" or "no", "strict", "optional".
std::string rtspEncryption{"no"};
/// WebRTC encryption type, string: "" or "no", "yes".
std::string webRtcEncryption{"no"};
/// RTMP encryption type, string: "" or "no", "strict", "optional".
std::string rtmpEncryption{"no"};
/// HLS encryption type, string: "" or "no", "yes".
std::string hlsEncryption{"no"};
/// Logging mode. Values: 0 - Disable, 1 - Only file,
/// 2 - Only terminal, 3 - File and terminal.
int logLevel{0};
/// Transport of the direct (user-facing) stream, mirrors the
/// RtpPusher::send() streamType: "rtp" (video only), "mpegts-klv-async"
/// (MISB ST 1402 / STANAG 4609), "mpegts-rtp-klv-async" (MISB ST 1403),
/// "mpegts-klv-sync" (MISB ST 0604), "mpegts-rtp-klv-sync". The value
/// alone decides KLV: "rtp" is video-only, every "mpegts-*" carries KLV
/// on its own TS PID. JPEG supports "rtp" only. The mediamtx leg
/// transport is selected separately by serverStreamType.
std::string directStreamType{"rtp"};
/// Target sending bitrate for the direct stream, integer kbps
/// [500:1000000]. Used as the pacer target when directStreamPacingMode
/// == 0; ignored when == 1 (RtpPusher channel bitrate is 0).
int directStreamBitrateKbps{5000};
/// Maximum UDP/RTP payload size for the direct stream, integer bytes
/// [256:65535]. Applies to the direct "rtp" transport only (mpegts
/// modes emit fixed 1316/1328-byte datagrams). Default 1472.
int directStreamMaxPayloadSize{1472};
/// Pacing mode of the direct stream, integer: 0 - target bitrate
/// (token-bucket, uses directStreamBitrateKbps), 1 - push /
/// back-pressure (kernel send-buffer occupancy, bitrate ignored).
int directStreamPacingMode{0};
/// MediaMTX-leg delivery mode, string: "rtp" (codec RTP, video only),
/// "rtp-klv" (codec RTP + KLV as a second RTP application track, payload
/// type 98, SDP name = metadataSuffix), "mpegts-rtp-klv" (raw MPEG-TS over
/// UDP, STANAG 4609, with synchronous KLV — MISB ST 0604 — on its own PID;
/// the loopback pusher uses RtpPusher "mpegts-klv-sync" and MediaMTX reads
/// it via udp+mpegts://, demuxing and re-serving video + KLV as native
/// tracks). The value alone decides KLV. For JPEG only "rtp"/"rtp-klv" are
/// valid ("mpegts-rtp-klv" is coerced to "rtp-klv"). Distinct from
/// rtspEnable (RTSP protocol enable/disable).
std::string serverStreamType{"rtp"};
/// Multicast TTL (scope) for every multicast leg, integer [0:255]:
/// 0 - implementation default.
int multicastTtl{0};
/// Security/compliance profile, string: "no" (or "") - the implementation
/// default, "strict" - refuse anything unprotected. An unrecognised value
/// is rejected, never silently defaulted.
std::string securityProfile{"no"};
/// Public (routed) address advertised to clients in SDP and ICE candidate
/// lines instead of the locally detected one, string: "" or "no" - detect
/// automatically. An address literal, NOT a hostname.
std::string publicAddress{"no"};
/// Local address every listener binds to, string: "" or "0.0.0.0" -
/// every interface.
std::string bindAddress{"0.0.0.0"};
/// Lowest port of the RTP/RTCP range, integer [0:65534]: 0 - any
/// ephemeral port. Should be even, because RTCP takes port+1.
int rtpPortMin{0};
/// Highest port of the RTP/RTCP range, integer [0:65535]: 0 - any
/// ephemeral port.
int rtpPortMax{0};
/// WebRTC media (UDP) port, integer [0:65535]: 0 - the implementation
/// chooses. Distinct from webRtcPort, which carries signalling only.
int webRtcMediaPort{0};
/// Single origin permitted to reach the HTTP-based signalling endpoints,
/// string "scheme://host[:port]": "" or "no" - the default policy.
std::string corsAllowedOrigin{"no"};
/// Maximum RTP payload size of the server-delivered stream, integer bytes.
/// The counterpart of directStreamMaxPayloadSize for the server leg.
int serverStreamMaxPayloadSize{1472};
/// JSON serialisation. Hand-written to_json()/from_json() replace the
/// JSON_READABLE macro as of VStreamer 3.2.0 (the macro's expansion is
/// capped at 63 fields). A key MISSING from the JSON now leaves the field
/// at its default instead of throwing, so a configuration file written for
/// an older version still loads.
friend void to_json(nlohmann::json& j, const VStreamerParams& p);
friend void from_json(const nlohmann::json& j, VStreamerParams& p);
/// Serialize params.
bool serialize(uint8_t* data, int bufferSize, int& size,
VStreamerParamsMask* mask = nullptr);
/// Deserialize params.
bool deserialize(uint8_t* data, int dataSize);
};
}
}
Parameter groups. VStreamerMediaMtx has two output legs plus shared parameters:
- Direct stream (point-to-point, bypasses mediamtx):
directStreamEnable,directStreamIp,directStreamPort,directStreamType,directStreamBitrateKbps,directStreamMaxPayloadSize,directStreamPacingMode. - Server stream (fed to the mediamtx media server, which fans it out to clients):
serverStreamType; plus the protocol endpointsrtspEnable/rtspPort/rtspsPort,srtEnable/srtPort,hlsEnable/hlsPort,rtmpEnable/rtmpPort/rtmpsPort,webRtcEnable/webRtcPort,rtspMulticastIp/rtspMulticastPort,user/password/suffix. - Metadata / KLV:
metadataSuffix(SDP track name for the KLV application track whenserverStreamType == "rtp-klv").metadataEnableis accepted for VStreamer interface compatibility but does not control KLV. Whether KLV is carried is decided per leg by the stream-type string value itself (serverStreamTypefor the MediaMTX leg,directStreamTypefor the direct leg) together with the presence of auserData/KLV buffer insendFrame(). - Network binding & security (server leg, added in 5.1.0):
bindAddress,publicAddress,corsAllowedOrigin,rtpPortMin,rtpPortMax,webRtcMediaPort,serverStreamMaxPayloadSize,multicastTtl,securityProfile. - Common / encoding:
enable,width,height,codec,fps,gop,bitrateKbps,minBitrateKbps,maxBitrateKbps,bitrateMode,h264Profile,jpegQuality,fitMode,overlayEnable,type,logLevel,custom1..3, SSL keys/certificates & encryption.
Note:
metadataPortis part of the VStreamer interface but is not used by VStreamerMediaMtx — KLV is delivered on the MPEG-TS KLV PID (mpegts modes) or as a muxed RTP metadata track (named bymetadataSuffix), not on a dedicated port.
Table 6 - Video streamer params description. Some params may be unsupported by particular video streamer class.
| Parameter | Description |
|---|---|
| enable | Enable/disable streamer: false - disable, true - enable. |
| width | Frame width from 8 to 4096. Regardless of the resolution of the input video, the streamer will scale the images according to this parameter. |
| height | Frame height from 8 to 4096. Regardless of the resolution of the input video, the streamer will scale the images according to this parameter. |
| directStreamIp | Destination IP of the direct stream (transport set by directStreamType; bypasses mediamtx). Default 127.0.0.1. |
| rtspPort | RTSP server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| rtspsPort | RTSPS server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| directStreamPort | Destination port for direct RTP streaming to user (bypasses mediamtx). |
| webRtcPort | WebRTC server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| hlsPort | HLS server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| srtPort | SRT server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| rtmpPort | RTMP server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| rtmpsPort | RTMPS server port. If the port is changed, the mediamtx process will be restarted by the library automatically. |
| metadataPort | Not used by VStreamerMediaMtx. Part of the VStreamer interface for compatibility. Metadata (KLV) is muxed into the same stream session (see sendFrame), not delivered on a separate port. |
| rtspEnable | RTSP protocol enable / disable: false - disable, true - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| directStreamEnable | Direct streaming to user enable / disable (bypasses mediamtx): false - disable, true - enable. Uses directStreamIp and directStreamPort parameters. Transport is set by directStreamType: with “rtp” the direct stream is video only; every “mpegts-*“ value (STANAG 4609) also carries KLV metadata. |
| webRtcEnable | WebRTC protocol enable / disable: false - disable, true - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| hlsEnable | HLS protocol enable / disable: false - disable, true - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| srtEnable | SRT protocol enable / disable: false - disable, true - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| rtmpEnable | RTMP protocol enable / disable: false - disable, true - enable. If changed, the mediamtx process will be restarted by the library automatically. |
| metadataEnable | Accepted (false / true) for VStreamer interface compatibility, but it does not control KLV in VStreamerMediaMtx. Whether the userData buffer provided via sendFrame(…) is put on the wire is decided solely by the per-leg stream type — serverStreamType for the MediaMTX leg and directStreamType for the direct leg — together with the presence of a non-empty buffer. Through mediamtx, KLV is carried with “rtp-klv” (secondary RTP application track, payload type 98, clock rate 90000 Hz) or “mpegts-rtp-klv” (own MPEG-TS PID) and reaches clients via RTSP and SRT; with “rtp” the server leg is video only. On the direct stream KLV is carried when directStreamType is any “mpegts-*“ value (STANAG 4609); with direct “rtp” the direct stream is video only. |
| rtspMulticastIp | RTSP server multicast IP. Multicast RTSP streaming is enabled by default in mediamtx. If multicast IP has been changed, the mediamtx process will be restarted by the library automatically. IP can be set with a mask or without a mask. If a mask is not set, the default mask /16 will be used. Example of multicast IP: 239.255.0.1 (in this case /16 will be added by default) or 239.255.0.1/24. |
| rtspMulticastPort | RTSP server multicast port. Multicast RTSP streaming is enabled by default in mediamtx. If the multicast port is changed, the mediamtx process will be restarted by the library automatically. |
| user | User name for authentication (unique per stream). Each stream instance has its own user name. In single MediaMTX mode, changing credentials for one stream will restart the mediamtx process but other streams keep their own credentials. If credentials are set for a stream, only authenticated clients can access that stream. Streams without credentials remain publicly accessible. |
| password | Password for authentication (unique per stream). Each stream instance has its own password. In single MediaMTX mode, changing credentials for one stream will restart the mediamtx process but other streams keep their own credentials. |
| suffix | Stream name for RTSP server. Accepted characters (since 5.1.0): letters, digits and _ - . ~ /; see SUFFIX in Table 4 for why. If changed, the mediamtx process will be restarted by the library automatically. |
| metadataSuffix | RTP media track name for metadata within the same RTSP stream. Only two values are allowed: “SMPTE336M” (for KLV metadata per SMPTE 336M standard) and “VND.ONVIF.METADATA” (for ONVIF metadata). Default: “SMPTE336M”. This value is used as the rtpmap attribute name for the secondary m=application media line (payload type 98, clock rate 90000 Hz) in the SDP descriptor. The metadata track is muxed with the video track in the same stream path — it is not a separate RTSP endpoint. The resulting SDP contains two media lines: m=video for the video codec and m=application for the metadata track named by this parameter. If an invalid value is provided to initVStreamer, it will be silently corrected to “SMPTE336M”. If an invalid value is provided to setParam, the method will return FALSE. If changed, the mediamtx process will be restarted by the library automatically. |
| minBitrateKbps | Minimum bitrate for VBR mode (100..100000 kbps). Adjusts maxBitrateKbps if higher. Applied to codec if present. |
| maxBitrateKbps | Maximum bitrate for VBR mode (100..100000 kbps). Adjusts minBitrateKbps if lower. Applied to codec if present. |
| bitrateKbps | Bitrate for H264 and H265 codecs (100..100000 kbps). Applied to codec if provided. |
| bitrateMode | Bitrate mode: 0 CBR, 1 VBR. Passed to codec when available. |
| fps | Streamer’s FPS and also encoding FPS. Valid range: 1..120 FPS. The library paces the producer thread to maintain this rate regardless of input video frame rate. Note (since v4.0.0): changing fps at runtime no longer restarts the RTP push or mediamtx; downstream clients keep their session. |
| gop | H264 or H265 codec GOP size (1..1000). Applied to codec if provided. |
| h264Profile | H264 encoding profile: 0 - baseline, 1 - main, 2 - high. Applied to codec if provided. |
| jpegQuality | JPEG encoding quality from 1 to 100. Applied to codec if provided. |
| codec | Codec type for encoding RAW frames: H264, HEVC or JPEG. If changed, the mediamtx process will be restarted by the library automatically. |
| fitMode | Scaling mode for RAW input video frames: 0 - fit (letterbox with black borders), 1 - fill (crop to fill). |
| overlayEnable | Overlay enable / disable: false - disable, true - enable. |
| cycleTimeUs | Read only Cycle timeout, microseconds. |
| type | Codec type selector: 0 - software codec, 1 - hardware codec. Applied to codec if provided. The actual behavior depends on the VCodec implementation. |
| custom1 | Deprecated alias of serverStreamMaxPayloadSize (since 5.1.0). Same storage, same accepted range 204..1472 bytes, default 1472. Writing either field updates both, and getParams reports both with the same value. See serverStreamMaxPayloadSize for the full description. |
| custom2 | Deprecated alias of directStreamBitrateKbps. Target bitrate for the direct pusher in kbps (500..1 000 000, default 5000). Used as the pacer target when directStreamPacingMode is 0; ignored when it is 1 (push / back-pressure — the RtpPusher channel bitrate is 0). Does not affect the loopback push to mediamtx. Has no effect when directStreamEnable is false. Updates take effect on the next outgoing frame — no stream restart. |
| custom3 | Read only. Reports how mediamtx is being run: 0 - one shared process for all streams, 1 - a process per stream, as decided by setMediaMtxPath(…). Since 5.1.0 a write through setParam is refused. |
| rtspKey | Path to openssl key for RTSP, string: “no” for no key. If changed, the mediamtx process will be restarted by the library automatically. |
| rtspCert | Path to openssl certificate for RTSP, string: “no” for no certificate. If changed, the mediamtx process will be restarted by the library automatically. |
| webRtcKey | Path to openssl key for WebRTC, string: “no” for no key. If changed, the mediamtx process will be restarted by the library automatically. |
| webRtcCert | Path to openssl certificate for WebRTC, string: “no” for no certificate. If changed, the mediamtx process will be restarted by the library automatically. |
| hlsKey | Path to openssl key for HLS, string: “no” for no key. If changed, the mediamtx process will be restarted by the library automatically. |
| hlsCert | Path to openssl certificate for HLS, string: “no” for no certificate. If changed, the mediamtx process will be restarted by the library automatically. |
| rtmpKey | Path to openssl key for RTMP, string: “no” for no key. If changed, the mediamtx process will be restarted by the library automatically. |
| rtmpCert | Path to openssl certificate for RTMP, string: “no” for no certificate. If changed, the mediamtx process will be restarted by the library automatically. |
| rtspEncryption | RTSP encryption type, string: “no”, “strict”, “optional”. If changed, the mediamtx process will be restarted by the library automatically. |
| webRtcEncryption | WebRTC encryption type, string: “no”, “yes”. If changed, the mediamtx process will be restarted by the library automatically. |
| rtmpEncryption | RTMP encryption type, string: “no”, “strict”, “optional”. If changed, the mediamtx process will be restarted by the library automatically. |
| hlsEncryption | HLS encryption type, string: “no”, “yes”. If changed, the mediamtx process will be restarted by the library automatically. |
| logLevel | Logging mode. Values: 0 - Disable, 1 - Only file, 2 - Only terminal, 3 - File and terminal. |
| directStreamType | Transport of the direct (user-facing, point-to-point) stream, mirrors the RtpPusher::send() streamType exactly. String values: “rtp” (default — codec RTP, video only, no KLV), “mpegts-klv-async” (MPEG-TS over UDP, asynchronous KLV; MISB ST 1402 / STANAG 4609, stream_type 0x06 + “KLVA”), “mpegts-rtp-klv-async” (MPEG-TS over RTP, asynchronous KLV; MISB ST 1403), “mpegts-klv-sync” (MPEG-TS over UDP, synchronous KLV; MISB ST 0604, stream_type 0x15 + metadata_AU_cell), “mpegts-rtp-klv-sync” (MPEG-TS over RTP, synchronous KLV). The value alone decides KLV: “rtp” is video-only; every “mpegts-*“ value carries KLV on its own TS PID. JPEG supports “rtp” only. The mediamtx leg transport is selected separately by serverStreamType. |
| directStreamBitrateKbps | Target sending bitrate for the direct stream, integer kbps [500:1000000] (default 5000). Used as the pacer target when directStreamPacingMode is 0; ignored when it is 1 (push / back-pressure — the RtpPusher channel bitrate is 0). custom2 is a deprecated alias with the same range. |
| directStreamMaxPayloadSize | Maximum UDP/RTP payload size for the direct stream, integer bytes [256:65535] (default 1472), user-readable and writable. Applies to the direct “rtp” transport only (the direct MPEG-TS modes emit fixed 1316/1328-byte datagrams). Changing it restarts the direct pusher. |
| directStreamPacingMode | Pacing mode of the direct stream, integer: 0 - target bitrate (token-bucket, uses directStreamBitrateKbps), 1 - push / back-pressure (kernel send-buffer occupancy; directStreamBitrateKbps ignored). |
| serverStreamType | Transport/type of the MediaMTX-leg stream — fed to the media server, which fans it out to clients (RTSP/SRT/HLS/RTMP/WebRTC). String: “rtp” (codec RTP, video only, no metadata), “rtp-klv” (codec RTP with KLV muxed as a second RTP application track, payload type 98, SDP name = metadataSuffix; MediaMTX re-serves it as a data track over RTSP / a KLV track over SRT), “mpegts-rtp-klv” (raw MPEG-TS over UDP, STANAG 4609, carrying synchronous KLV — MISB ST 0604, stream_type 0x15 — on its own PID; the loopback pusher always uses RtpPusher streamType “mpegts-klv-sync” and MediaMTX reads it via udp+mpegts://, demuxing the inner TS and re-serving video + KLV as native tracks). The value alone decides KLV. For JPEG only “rtp” / “rtp-klv” are valid (“mpegts-rtp-klv” is coerced to “rtp-klv”). The concrete media server is an implementation detail (MediaMTX in VStreamerMediaMtx). Distinct from rtspEnable (RTSP protocol enable/disable). |
| serverStreamMaxPayloadSize | Maximum RTP payload size of the server-delivered stream, bytes [204:1472] (default 1472) — the counterpart of directStreamMaxPayloadSize for the MediaMTX leg. Written into udpMaxPayloadSize in the MediaMTX config, i.e. the size of the UDP datagrams MediaMTX itself emits (RTSP/UDP, RTSP multicast, SRT). The 1472-byte upper bound is MediaMTX’s own: it refuses to start with a larger value, so the library never writes a larger one — setParam rejects an out-of-range value while initVStreamer clamps it into range and logs a warning. A value <= 0 (what deserialize() leaves when the mask bit is clear) means “keep the default”. Does not affect the loopback push to mediamtx (auto-sized for localhost, ~1452 bytes) nor the direct stream. Shared across instances in single MediaMTX mode. Changing it restarts the mediamtx process. custom1 is a deprecated alias. |
| multicastTtl | Multicast TTL (scope) for every multicast leg, [0:255], 0 - implementation default. Documented implementation cap: the only multicast leg VStreamerMediaMtx owns is the RTSP one, served by mediamtx, whose 1.15.1 configuration exposes no multicast TTL key. The value is validated, stored and reported back by getParams, but the TTL actually on the wire is the one MediaMTX picks; a non-zero value logs a warning saying so. It never triggers a mediamtx restart, because it cannot change the generated configuration. |
| securityProfile | Security/compliance profile, string. Accepted values are implementation-defined; VStreamerMediaMtx defines exactly two: “no” (or ”“) — the default, imposes nothing; and “strict” — refuses any parameter set that would put media or credentials on the wire unprotected. Under “strict”: every enabled protocol must be encrypted (rtspEncryption = “strict”, rtmpEncryption = “strict”, hlsEncryption = “yes”, webRtcEncryption = “yes”), srtEnable must be false (MediaMTX 1.15.1 offers no transport encryption for its SRT listener and this library does not configure SRT passphrases), directStreamEnable must be false (the direct leg is plain RTP/UDP), user and password must both be set, and corsAllowedOrigin must name a single origin. An unrecognised value is rejected by both initVStreamer and setParam, never mapped onto the default. Validated again on every setParam, so no later change can slip past the profile. Per instance even in single MediaMTX mode. |
| publicAddress | Public (routed) address advertised to clients instead of the locally detected one, string: ”“ or “no” - detect automatically. Must be an IPv4/IPv6 address literal, never a hostname — the value reaches the wire verbatim. Written into webrtcAdditionalHosts, which adds it to the ICE candidates MediaMTX advertises: this is what makes WebRTC work behind 1:1 NAT, in containers and on multi-homed hosts where the detected address is unroutable for the viewer. If changed, the mediamtx process will be restarted by the library automatically. |
| bindAddress | Local address every listener binds to, string: ”“ or “0.0.0.0” (or ”::”) - every interface. Must be an IPv4/IPv6 address literal. Applied to every MediaMTX listener address — rtspAddress, rtspsAddress, rtpAddress, rtcpAddress, srtpAddress, srtcpAddress, rtmpAddress, rtmpsAddress, hlsAddress, webrtcAddress, webrtcLocalUDPAddress, srtAddress — so a multi-homed host can keep a stream off an interface it must not appear on. IPv6 literals are bracketed automatically and the whole value is written as a quoted YAML scalar (unquoted, a leading [ would open a YAML flow sequence and MediaMTX would refuse the entire config). The readiness probe the library uses to decide whether mediamtx has come up follows this address too — probing a fixed loopback would never succeed once the listeners move off it. If changed, the mediamtx process will be restarted by the library automatically. |
| rtpPortMin | Lowest port of the RTP/RTCP range, [0:65534]: 0 - any ephemeral port. Set together with rtpPortMax it confines the ports the library draws for the MediaMTX RTP/RTCP and SRTP/SRTCP listeners, for the multicast SRTP/SRTCP pair and (at initVStreamer time) for the WebRTC media port and the loopback push port. Should be even, because RTCP conventionally takes port+1; an odd value is rounded up when a pair is allocated. If changed, the mediamtx process will be restarted by the library automatically. |
| rtpPortMax | Highest port of the RTP/RTCP range, [0:65535]: 0 - any ephemeral port. See rtpPortMin. Both bounds must be set together and the range must hold at least 10 ports counted from the first even port at or above rtpPortMin — three even-aligned RTP/RTCP pairs plus the loopback push port and the WebRTC media port, with room for the alignment the pairs need. Both initVStreamer and setParam reject a complete range that is too small (a pair that cannot be reserved makes MediaMTX exit); setParam accepts each bound on its own so the two can be set in either order, warning while the pair is still incomplete. When a valid range runs out of free ports at allocation time the library falls back to ports outside it and logs a warning. |
| webRtcMediaPort | WebRTC media (UDP) port, [0:65535]: 0 - the implementation chooses. Distinct from webRtcPort, which carries signalling only. Written into webrtcLocalUDPAddress. Before 5.1.0 this port was always chosen automatically and could not be pinned, which made it impossible to open a stable hole for it in a firewall. Setting 0 through setParam keeps the port currently in force rather than drawing a new one. getParams always reports the port actually in use. If changed, the mediamtx process will be restarted by the library automatically. |
| corsAllowedOrigin | Single origin permitted to reach the HTTP-based signalling endpoints, string “scheme://host[:port]”: ”“ or “no” - the implementation’s default policy, which is MediaMTX’s wildcard '*'. Written into hlsAllowOrigin and webrtcAllowOrigin. Deliberately one origin: a wildcard, a list, a trailing slash, a path component, credentials or any control byte in the value are all rejected; a bracketed IPv6 origin is accepted with or without a port. If changed, the mediamtx process will be restarted by the library automatically. |
Serialize video streamer params
The VStreamerParams class provides the serialize(…) method to serialize video streamer params (fields of the VStreamerParams class). Serialization of video streamer params is necessary when you need to send video streamer params via communication channels. The method provides options to exclude particular parameters from serialization. To do this, the method inserts a binary mask where each bit represents a particular parameter, and the deserialize(…) method recognizes it. Method declaration:
Wire format (VStreamer 3.2.0). The header is 13 bytes: 1 header byte, 2 version bytes (major, minor) and a 10-byte parameter mask. The mask grew from 8 to 10 bytes in 3.2.0 because the 3.1.0 mask had 60 of its 64 bits taken and could not describe the parameters added in 3.2.0. Growing it moves the start of the payload, so a 3.1.0 message and a 3.2.0 message are not interchangeable —
deserialize(...)rejects a message whose minor version does not match before it reaches the mask, which is what keeps the format extensible. The buffer passed toserialize(...)must therefore be at least 14 bytes (header plus one bool field); a smaller buffer than the selected parameters require simply serializes fewer of them.
bool serialize(uint8_t* data, int bufferSize, int& size, VStreamerParamsMask* mask = nullptr);
| Parameter | Value |
|---|---|
| data | Pointer to data buffer. |
| size | Size of serialized data. |
| bufferSize | Data buffer size. If buffer size smaller than required, buffer will be filled with fewer parameters. |
| mask | Parameters mask - pointer to VStreamerParamsMask structure. VStreamerParamsMask (declared in VStreamer.h file) determines flags for each field (parameter) declared in VStreamerParams class. If the user wants to exclude any parameters from serialization, he can put a pointer to the mask. If the user wants to exclude a particular parameter from serialization, he should set the corresponding flag in the VStreamerParams structure. |
VStreamerParamsMask structure declaration:
struct VStreamerParamsMask
{
bool enable{true};
bool width{true};
bool height{true};
bool directStreamIp{true};
bool rtspPort{true};
bool rtspsPort{true};
bool directStreamPort{true};
bool webRtcPort{true};
bool hlsPort{true};
bool srtPort{true};
bool rtmpPort{true};
bool rtmpsPort{true};
bool metadataPort{true};
bool rtspEnable{true};
bool directStreamEnable{true};
bool webRtcEnable{true};
bool hlsEnable{true};
bool srtEnable{true};
bool rtmpEnable{true};
bool metadataEnable{true};
bool rtspMulticastIp{true};
bool rtspMulticastPort{true};
bool user{true};
bool password{true};
bool suffix{true};
bool metadataSuffix{true};
bool minBitrateKbps{true};
bool maxBitrateKbps{true};
bool bitrateKbps{true};
bool bitrateMode{true};
bool fps{true};
bool gop{true};
bool h264Profile{true};
bool jpegQuality{true};
bool codec{true};
bool fitMode{true};
bool cycleTimeUs{true};
bool overlayEnable{true};
bool type{true};
bool custom1{true};
bool custom2{true};
bool custom3{true};
bool rtspKey{true};
bool rtspCert{true};
bool webRtcKey{true};
bool webRtcCert{true};
bool hlsKey{true};
bool hlsCert{true};
bool rtmpKey{true};
bool rtmpCert{true};
bool rtspEncryption{true};
bool webRtcEncryption{true};
bool rtmpEncryption{true};
bool hlsEncryption{true};
bool logLevel{true};
bool directStreamType{true};
bool directStreamBitrateKbps{true};
bool directStreamMaxPayloadSize{true};
bool directStreamPacingMode{true};
bool serverStreamType{true};
bool multicastTtl{true};
bool securityProfile{true};
bool publicAddress{true};
bool bindAddress{true};
bool rtpPortMin{true};
bool rtpPortMax{true};
bool webRtcMediaPort{true};
bool corsAllowedOrigin{true};
bool serverStreamMaxPayloadSize{true};
};
Example without parameters mask:
// Prepare random params.
VStreamerParams in;
in.directStreamIp = "alsfghljb";
in.rtspPort = 0;
// Serialize data.
uint8_t data[1024];
int size = 0;
in.serialize(data, 1024, size);
cout << "Serialized data size: " << size << " bytes" << endl;
Example with parameters mask:
// Prepare random params.
VStreamerParams in;
in.directStreamIp = "alsfghljb";
in.rtspPort = 0;
// Prepare params mask.
VStreamerParamsMask mask;
mask.rtspPort = false; // Exclude RTSP port only. Others included.
// Serialize data.
uint8_t data[1024];
int size = 0;
in.serialize(data, 1024, size, &mask);
cout << "Serialized data size: " << size << " bytes" << endl;
Deserialize video streamer params
The VStreamerParams class provides the deserialize(…) method to deserialize video streamer params (fields of the VStreamerParams class). Deserialization of video streamer params is necessary when you need to receive video streamer params via communication channels. The method automatically recognizes which parameters were serialized by the serialize(…) method. Method declaration:
The method replaces the WHOLE object, it is not a partial update. Every parameter whose mask bit is clear is reset to 0 / false / ”“ rather than left untouched. VStreamerMediaMtx treats those cleared values as “not set”: an empty
publicAddress/corsAllowedOrigin/securityProfilemeans the default, an emptybindAddressmeans every interface, and aserverStreamMaxPayloadSizeof 0 means the 1472-byte default. The method also rejects a message whose major or minor version does not match — a 3.1.0 message read with 3.2.0 offsets would decode garbage into every field.
bool deserialize(uint8_t* data, int dataSize);
| Parameter | Value |
|---|---|
| data | Pointer to serialized data buffer. |
| dataSize | Size of data. |
Returns: TRUE if data deserialized or FALSE if not.
Example:
// Serialize data.
VStreamerParams in;
uint8_t data[1024];
int size = 0;
in.serialize(data, 1024, size);
cout << "Serialized data size: " << size << " bytes" << endl;
// Deserialize data.
VStreamerParams out;
if (!out.deserialize(data, size))
cout << "Can't deserialize data" << endl;
Read params from JSON file and write to JSON file
The VStreamer library depends on the ConfigReader library, which provides methods to read params from a JSON file and to write params to a JSON file.
Since VStreamer 3.2.0 the JSON conversion of VStreamerParams is hand-written (to_json / from_json) rather than generated by the JSON_READABLE macro: that macro forwards to nlohmann’s NLOHMANN_DEFINE_TYPE_INTRUSIVE, whose expansion is capped at 63 fields, and the 3.2.0 structure is past that limit. One behaviour changed with it, deliberately: a key missing from the JSON leaves the field at its default instead of throwing. Previously a configuration file that did not list every single parameter failed to load at all — which is exactly the situation a file written for an older version creates. A configuration file written for 5.0.x therefore still loads in 5.1.0, and the parameters it does not mention take their defaults.
Example of writing and reading params to a JSON file:
// Write params to file.
VStreamerParams in;
cr::utils::ConfigReader inConfig;
inConfig.set(in, "vStreamerParams");
inConfig.writeToFile("TestVStreamerParams.json");
// Read params from file.
cr::utils::ConfigReader outConfig;
if(!outConfig.readFromFile("TestVStreamerParams.json"))
{
cout << "Can't open config file" << endl;
return false;
}
TestVStreamerParams.json will look like:
{
"vStreamerParams":
{
"bindAddress": "0.0.0.0",
"bitrateKbps": 45157,
"bitrateMode": 53395,
"codec": "dkgvmkrnjv",
"corsAllowedOrigin": "no",
"custom1": 16353.0,
"custom2": 30513.0,
"custom3": 16213.0,
"cycleTimeUs": 0,
"directStreamBitrateKbps": 5000,
"directStreamEnable": true,
"directStreamIp": "sfspfo9jbjnbjhklvllks",
"directStreamMaxPayloadSize": 1472,
"directStreamPacingMode": 0,
"directStreamPort": 31062,
"directStreamType": "rtp",
"enable": false,
"fitMode": 14594,
"fps": 12255.0,
"gop": 32446,
"h264Profile": 17051,
"height": 44304,
"hlsCert": "24kjcnnv",
"hlsEnable": false,
"hlsEncryption": "wieufjpowkf",
"hlsKey": "wqlovf;qb",
"hlsPort": 9365,
"jpegQuality": 22605,
"logLevel": 0,
"maxBitrateKbps": 11267,
"metadataEnable": false,
"metadataPort": 35074,
"metadataSuffix": "z.,nfpowe",
"minBitrateKbps": 6818,
"multicastTtl": 0,
"overlayEnable": true,
"password": "sddgoihw,",
"publicAddress": "no",
"rtmpCert": "wfpomv",
"rtmpEnable": true,
"rtmpEncryption": "skldfjdf",
"rtmpKey": "dkkkkjfkjdkjfkj2134",
"rtmpPort": 55981,
"rtmpsPort": 1936,
"rtpPortMax": 0,
"rtpPortMin": 0,
"rtspCert": "lkjrkjg",
"rtspEnable": true,
"rtspEncryption": "quyen",
"rtspKey": "dh;skcsf",
"rtspMulticastIp": "wpofuihifo",
"rtspMulticastPort": 47135,
"rtspPort": 42745,
"rtspsPort": 56847,
"securityProfile": "no",
"serverStreamMaxPayloadSize": 1472,
"serverStreamType": "rtp-klv",
"srtEnable": true,
"srtPort": 1963,
"suffix": "pisfhcowmfv",
"type": 5617,
"user": "slfljkv",
"webRtcCert": "erghshiAJ",
"webRtcEnable": false,
"webRtcEncryption": "l;uoykh",
"webRtcKey": "WERUHUHFE",
"webRtcMediaPort": 0,
"webRtcPort": 50955,
"width": 48849
}
}
Simple example
The application below shows VStreamerMediaMtx usage. The application creates a VStreamerMediaMtx object and initializes it. After initialization, the application reads H.264 frames from a file with VSourceFile and feeds them to the VStreamerMediaMtx video streamer. (The test application, described further down, is the one that generates synthetic frames.)
#include <iostream>
#include <chrono>
#include "VStreamerMediaMtx.h"
#include "VSourceFile.h"
int main(int argc, char **argv)
{
std::cout << "------------------------------------------" << std::endl;
std::cout << "VStreamerMediaMtx v" << cr::video::VStreamerMediaMtx::getVersion() << " example" << std::endl;
std::cout << "------------------------------------------" << std::endl;
// Set suffix (stream name).
std::string suffix = "live";
std::cout << "Set suffix: ";
std::cin >> suffix;
// Set RTSP server port.
int port = 8554;
std::cout << "Set RTSP server port: ";
std::cin >> port;
// Set mediamtx path
cr::video::VStreamerMediaMtx::setMediaMtxPath("/home/pi/Downloads/MediaMtx");
// Init video streamer params.
cr::video::VStreamerParams params;
params.enable = true;
params.rtspPort = port;
params.suffix = suffix;
params.directStreamEnable = false; // Direct RTP to user disabled, use RTSP via mediamtx.
cr::video::VStreamerMediaMtx streamer;
if (!streamer.initVStreamer(params))
{
std::cout << "Video streamer init failed" << std::endl;
return -1;
}
// Create frame.
cr::video::Frame frame;
// Open video source.
cr::video::VSourceFile videoSource;
std::string initString = "test.h264;1280;720;30";
if (!videoSource.openVSource(initString))
{
std::cout << "Open video source failed" << std::endl;
return -1;
}
// Main loop.
while (true)
{
// Get frame from video source.
if (!videoSource.getFrame(frame, 1000))
{
std::cout << "Get frame failed" << std::endl;
break;
}
// Add frame to streamer.
if (!streamer.sendFrame(frame))
{
std::cout << "Send frame failed" << std::endl;
break;
}
}
return 0;
}
Test application
VStreamerMediaMtx/test folder contains a test application which demonstrates VStreamerMediaMtx library usage with multiple instances. The application creates the necessary number of VStreamerMediaMtx objects and initializes them. The application generates synthetic video frames (a moving white rectangle on a patterned background) and feeds them to the VStreamerMediaMtx objects. The application initializes video streamers with default parameters. After starting, the user is able to change video streamer parameters at runtime — including the server stream type (serverStreamType, the MediaMTX leg), the full set of direct stream parameters (directStreamEnable, directStreamIp, directStreamPort, directStreamType, directStreamBitrateKbps, directStreamMaxPayloadSize, directStreamPacingMode) and the network binding / security parameters added in 5.1.0 (serverStreamMaxPayloadSize, multicastTtl, securityProfile, publicAddress, bindAddress, rtpPortMin/rtpPortMax, webRtcMediaPort, corsAllowedOrigin) — which also makes it possible to stream STANAG 4609 KLV metadata to RTSP/SRT clients (see options 10 and 11–25 below). The application feeds a complete UAS Datalink Local Set (MISB ST 0601) as the per-frame KLV. Output of the application will be like:
VStreamerMediaMtx v5.1.0 test
the application will initialize video
server with default parameters. The user
able to change any parameters after
start. The test application provides
basic parameters control
------------------------------------------
Set number streams: 2
after entering the number of video streams the application will create the necessary number of video streams, initialize them and show URLs to access the video streams:
------------------------------------------------
Stream 1 initialized. Access to stream:
RTSP: rtsp://<IP>:8554/live0
WebRTC (open in browser, encryption disabled): http://<IP>:8564/live0
------------------------------------------------
Stream 2 initialized. Access to stream:
RTSP: rtsp://<IP>:8554/live1
WebRTC (open in browser, encryption disabled): http://<IP>:8564/live1
After that, the user is able to change some parameters of each video stream:
Enter stream number (0-1, -1 - exit): 0
-1 - Exit
0 - Resolution
1 - FPS
2 - Bitrate
3 - JPEG quality
4 - GOP size
5 - User name and password
6 - Fit mode
7 - Codec
8 - RTSP and WebRTC ports
9 - Stream name
10 - Server stream type (MediaMTX leg)
11 - Direct stream enable / disable
12 - Direct stream IP
13 - Direct stream port
14 - Direct stream type
15 - Direct stream bitrate (kbps)
16 - Direct stream max payload size (bytes)
17 - Direct stream pacing mode
18 - Server stream max payload size (bytes)
19 - Multicast TTL
20 - Security profile
21 - Public (advertised) address
22 - Bind address
23 - RTP/RTCP port range
24 - WebRTC media (UDP) port
25 - CORS allowed origin
Choose option: 0
Current resolution: 1280x720
Set resolution:
1 - 1920x1080
2 - 1280x720
3 - 720x576
4 - 640x480
Option: 3
Options 10–25 let the user reconfigure both streaming legs and the server’s network posture at runtime (every change goes through setParam(…) — no object re-initialization):
- 10 — Server stream type (
serverStreamType, the MediaMTX leg):rtp(video only),rtp-klv(codec RTP + a KLV metadata track on payload type 98), ormpegts-rtp-klv(STANAG 4609 MPEG-TS over the loopback with synchronous KLV — MISB ST 0604; MediaMTX demuxes it and re-serves the KLV track over RTSP/SRT). To stream STANAG 4609 KLV to RTSP clients, choosertp-klvormpegts-rtp-klvhere (the test feeds a complete UAS Datalink Local Set per MISB ST 0601 on every frame). - 11 — Direct stream enable / disable (
directStreamEnable): turn the point-to-point RTP/MPEG-TS egress (bypassing MediaMTX) on or off. - 12 / 13 — Direct stream IP / port (
directStreamIp/directStreamPort): destination of the direct stream. - 14 — Direct stream type (
directStreamType, mirrorsRtpPusher::send()):rtp,mpegts-klv-async,mpegts-rtp-klv-async,mpegts-klv-sync,mpegts-rtp-klv-sync(the value alone decides whether KLV is carried). - 15 — Direct stream bitrate (
directStreamBitrateKbps, 500..1000000): pacer target when the pacing mode is 0. - 16 — Direct stream max payload size (
directStreamMaxPayloadSize, 256..65535): RTP packet size for the directrtptransport. - 17 — Direct stream pacing mode (
directStreamPacingMode):0— target bitrate (token-bucket),1— push / back-pressure. - 18 — Server stream max payload size (
serverStreamMaxPayloadSize, 204..1472): datagram size of the MediaMTX-delivered stream (udpMaxPayloadSize). Restarts mediamtx. - 19 — Multicast TTL (
multicastTtl, 0..255): accepted and reported, but not applied — MediaMTX 1.15.1 has no multicast TTL key (a warning is printed). - 20 — Security profile (
securityProfile):noorstrict. With the test application’s default parameters (the direct stream enabled, no TLS, no credentials)strictis refused, which is the intended demonstration. - 21 — Public (advertised) address (
publicAddress): an IP literal advertised in WebRTC ICE, ornoto detect automatically. Restarts mediamtx. - 22 — Bind address (
bindAddress): the address every listener binds to, or0.0.0.0for every interface. Restarts mediamtx. - 23 — RTP/RTCP port range (
rtpPortMin/rtpPortMax): asks for both bounds and sets the lower one first, because the range only takes effect once both are set.0/0returns to ephemeral ports. Restarts mediamtx. - 24 — WebRTC media (UDP) port (
webRtcMediaPort): pinswebrtcLocalUDPAddress;0keeps the port currently in force. Restarts mediamtx. - 25 — CORS allowed origin (
corsAllowedOrigin): a singlescheme://host[:port]origin for the HLS/WebRTC endpoints, ornofor the default wildcard policy. Restarts mediamtx.
Automated tests. test/test_driver.cpp is a headless driver that runs one streamer with every protocol enabled and exposes a TCP control socket (set_int, set_str, exec, get_fps, get_params, quit), and test/run_protocol_tests.py drives it end-to-end:
- it verifies its parameter-id table against
3rdparty/VStreamer/src/VStreamer.hbefore doing anything, so a future enum change fails the run instead of silently testing the wrong parameters; - a pre-flight stage starts short-lived drivers with
--rtp-port-min/--rtp-port-maxto exercise the RTP-range width validation that only initVStreamer(…) performs — a range too narrow for the ports the allocator draws must make the process exit non-zero, and a wide one must come up and report the range back; - it then probes RTSP (UDP/TCP/multicast), RTMP, HLS, SRT and the direct RTP egress with
ffmpeg/ffprobeacross sweeps of resolution, FPS, codec, bitrate, GOP, profile,serverStreamTypeand every direct-stream parameter; - and finally it checks every parameter added in 5.1.0 three ways — an out-of-contract value must be rejected, an accepted value must round-trip through getParams(…), and, where it maps onto a MediaMTX setting, it must appear in the generated
mediamtx.ymland leave the stream working (including an IPv6bindAddress, which is probed over IPv6). ThesecurityProfilegate is tested in both directions: refused on an unprotected configuration, accepted once nothing is exposed, and then refusing every later change that would re-expose something.
The runner exits non-zero if any probe or check failed. Run it with python3 test/run_protocol_tests.py (add --quick for shorter probe durations); ffmpeg, ffprobe and GStreamer must be installed.
Build and connect to your project
The VStreamerMediaMtx library supports only Linux. The library has no external dependencies beyond a C++17 compiler and CMake. The library works together with mediamtx, which runs as an external process managed automatically by the library (the user must set the path to the mediamtx executable using the setMediaMtxPath method).
Typical commands to build VStreamerMediaMtx library:
cd VStreamerMediaMtx
mkdir build
cd build
cmake ..
make
If you want to connect the VStreamerMediaMtx library to your CMake project as source code, you can do the following. For example, if your repository has this structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
Create a 3rdparty folder in your repository and place the VStreamerMediaMtx repository folder there. The new structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
VStreamerMediaMtx
Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should contain:
cmake_minimum_required(VERSION 3.13)
################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)
################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)
################################################################################
## CONFIGURATION
## 3rd-party configuration
################################################################################
# Embedded mediamtx binary is enabled by default. To disable it and use an
# external mediamtx executable, uncomment the following line:
# SET(${PARENT}_VSTREAMER_MEDIAMTX_EMBED_BINARY OFF CACHE BOOL "" FORCE)
################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
add_subdirectory(VStreamerMediaMtx)
File 3rdparty/CMakeLists.txt adds folder VStreamerMediaMtx to your project and excludes test application and examples from compiling (by default test application and examples excluded from compiling if VStreamerMediaMtx included as sub-repository). By default, the mediamtx binary is embedded into the library. To disable this and use an external mediamtx executable, set VSTREAMER_MEDIAMTX_EMBED_BINARY to OFF. Your repository new structure will be:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
VStreamerMediaMtx
Next, you need to include the 3rdparty folder in the main CMakeLists.txt file of your repository. Add the following line at the end of your main CMakeLists.txt:
add_subdirectory(3rdparty)
Next you have to include VStreamerMediaMtx library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} VStreamerMediaMtx)
Done!
MediaMTX executable file
Supported version: v1.15.1 (built from CR fork, see below)
Standard MediaMTX
The standard upstream MediaMTX application is available from the official MediaMTX releases. The default MediaMTX v1.15.1 from upstream is suitable for most permissive RTSP clients (ffprobe, VLC) but does not pass RTSP-over-HTTP tunneling tests with strict clients (Genetec/Omnicast 5.13, ONVIF Test Tool Profile T STEP 16). For those scenarios use the CR fork build described below; for everything else upstream is fine. See MediaMTX documentation for general installation.
Custom MediaMTX for ONVIF Profile S and Profile T
For applications requiring full ONVIF Profile S / Profile T compliance and compatibility with Live555-based RTSP clients (Genetec/Omnicast 5.13), the tarballs in this static/ folder are not stock upstream — they are built from the CR fork with two fixes on top of upstream bluenviron/gortsplib v5.0.1:
-
base64 stream reader CR/LF and EOF tolerance —
internal/base64streamreader/reader.go. ONVIF clients separate consecutive base64-encoded RTSP requests in a single long POST body with CR/LF line breaks; upstream’s parser does not strip them and silently drops the second/third request (typically the SETUP that follows DESCRIBE). The fix strips CR/LF from incoming bytes and tracks EOF so the last partial chunk is decoded instead of discarded. -
conditional POST response on RTSP-over-HTTP tunnel —
server_conn_reader.go. Apple’s RTSP-over-HTTP convention (an HTTP/1.0 spec) says the POST channel is write-only and the server must stay silent on it; strict Live555-based clients tear the tunnel down on a 200 OK to POST. Modern HTTP/1.1 clients and HTTP/1.1 reverse proxies (HAProxy in mode http) expect the opposite — strict request/response pairing — and HAProxy emits 502 if the backend stays silent. The fix makes the response conditional on HTTP version: silent on POST for HTTP/1.0, 200 OK on POST for HTTP/1.1.
The patched binary identifies itself as v1.15.1-cr-fix-tunnel-post:
./mediamtx --version
v1.15.1-cr-fix-tunnel-post
Reproducing the build
Source code lives in two CR forks:
ConstantRobotics-Ltd/gortsplib— tagv5.0.2-cr.tunnel.1(two commits on top of upstreambluenviron/gortsplib v5.0.1)ConstantRobotics-Ltd/mediamtx— branchcr-tunnel-fixes/v1.15.1(one commit on top of upstreambluenviron/mediamtx v1.15.1, pinning gortsplib via areplacedirective at the tag above)
Build commands (requires Go ≥ 1.25):
git clone --branch cr-tunnel-fixes/v1.15.1 https://github.com/ConstantRobotics-Ltd/mediamtx.git
cd mediamtx
go generate ./...
echo -n v1.15.1-cr-fix-tunnel-post > internal/core/VERSION
for arch in amd64 arm64; do
CGO_ENABLED=0 GOOS=linux GOARCH=$arch \
go build -trimpath -ldflags "-s -w" -o ../mediamtx-$arch .
done
GOARM=7 CGO_ENABLED=0 GOOS=linux GOARCH=arm \
go build -trimpath -ldflags "-s -w" -o ../mediamtx-armv7 .
GOARM=6 CGO_ENABLED=0 GOOS=linux GOARCH=arm \
go build -trimpath -ldflags "-s -w" -o ../mediamtx-armv6 .
Then pack each binary into the corresponding mediamtx_v1.15.1-linux_<arch>.tar.gz next to mediamtx.yml and LICENSE (preserving the original layout — three files in a flat tar archive).
Prebuilt binaries available in this folder
| Platform | Architecture | File |
|---|---|---|
| Linux AMD64 | x86_64 | static/mediamtx_v1.15.1-linux_amd64.tar.gz |
| Linux ARM64 | aarch64 | static/mediamtx_v1.15.1-linux_arm64.tar.gz |
| Linux ARMv6 | armhf | static/mediamtx_v1.15.1-linux_armv6.tar.gz |
| Linux ARMv7 | armhf | static/mediamtx_v1.15.1-linux_armv7.tar.gz |
To extract:
tar -xvzf mediamtx_v1.15.1-linux_amd64.tar.gz