Recording Video¶
MediaX provides built-in recording capabilities to save video streams to Matroska (MKV) files.
Overview¶
Recording can be enabled on both payloaders (transmitters) and depayloaders (receivers), allowing you to:
- Record locally generated video to file
- Capture incoming RTP streams to disk
- Stream and record simultaneously
- Record with different codecs (raw, H.264)
Output Modes¶
MediaX supports three output modes:
| Mode | Description |
|---|---|
kStreamOnly |
Stream only, no recording (default) |
kRecordOnly |
Record only, no network streaming |
kStreamAndRecord |
Both stream and record simultaneously |
Recording with Payloaders¶
Uncompressed (Raw) Recording¶
#include "uncompressed/rtp_uncompressed_payloader.h"
mediax::rtp::uncompressed::RtpUncompressedPayloader payloader;
// Configure stream info
mediax::rtp::StreamInformation stream_info;
stream_info.session_name = "RawRecording";
stream_info.hostname = "127.0.0.1"; // Can be dummy for record-only mode
stream_info.port = 5004;
stream_info.width = 640;
stream_info.height = 480;
stream_info.framerate = 25;
stream_info.encoding = mediax::rtp::ColourspaceType::kColourspaceRgb24;
payloader.SetStreamInfo(stream_info);
// Configure recording
payloader.SetOutputMode(mediax::rtp::OutputMode::kRecordOnly);
payloader.SetRecordingFilename("output_raw.mkv");
payloader.Open();
// Send frames - they will be written to file
std::vector<uint8_t> rgb_buffer(640 * 480 * 3);
// Fill buffer with video frame...
payloader.Transmit(rgb_buffer.data(), true);
payloader.Close(); // Finalizes the recording
H.264 Recording with OpenH264¶
#include "h264/openh264/rtp_h264_openh264_payloader.h"
mediax::rtp::h264::openh264::RtpH264OpenH264Payloader payloader;
// Configure encoder
mediax::rtp::h264::openh264::EncoderConfig config;
config.width = 1920;
config.height = 1080;
config.framerate = 30;
config.bitrate = 4000000; // 4 Mbps
config.keyframe_interval = 30; // IDR every second
payloader.SetEncoderConfig(config);
// Configure stream info
mediax::rtp::StreamInformation stream_info;
stream_info.session_name = "H264Recording";
stream_info.hostname = "127.0.0.1";
stream_info.port = 5004;
stream_info.width = 1920;
stream_info.height = 1080;
stream_info.framerate = 30;
stream_info.encoding = mediax::rtp::ColourspaceType::kColourspaceRgb24;
payloader.SetStreamInfo(stream_info);
// Record only (no network streaming)
payloader.SetOutputMode(mediax::rtp::OutputMode::kRecordOnly);
payloader.SetRecordingFilename("output_h264.mkv");
payloader.Open();
// Transmit RGB frames - encoder compresses and writes to file
std::vector<uint8_t> rgb_buffer(1920 * 1080 * 3);
// Fill buffer with video frame...
payloader.Transmit(rgb_buffer.data(), true);
payloader.Close();
H.264 Recording with VAAPI (Hardware Accelerated)¶
#include "h264/vaapi/rtp_h264_vaapi_payloader.h"
// Check if VAAPI is available
if (!mediax::rtp::h264::vaapi::RtpH264VaapiPayloader::IsVaapiAvailable()) {
std::cerr << "VAAPI not available on this system\n";
return 1;
}
mediax::rtp::h264::vaapi::RtpH264VaapiPayloader payloader;
// Configure VAAPI encoder
mediax::rtp::h264::vaapi::VaapiEncoderConfig config;
config.width = 1920;
config.height = 1080;
config.framerate = 30;
config.bitrate = 4000000; // 4 Mbps
config.keyframe_interval = 30; // IDR every second
payloader.SetEncoderConfig(config);
// Configure stream info
mediax::rtp::StreamInformation stream_info;
stream_info.session_name = "VaapiRecording";
stream_info.hostname = "127.0.0.1";
stream_info.port = 5004;
stream_info.width = 1920;
stream_info.height = 1080;
stream_info.framerate = 30;
stream_info.encoding = mediax::rtp::ColourspaceType::kColourspaceRgb24;
payloader.SetStreamInfo(stream_info);
// Stream and record simultaneously
payloader.SetOutputMode(mediax::rtp::OutputMode::kStreamAndRecord);
payloader.SetRecordingFilename("output_vaapi.mkv");
payloader.Open();
// Transmit frames
std::vector<uint8_t> rgb_buffer(1920 * 1080 * 3);
payloader.Transmit(rgb_buffer.data(), true);
payloader.Close();
Recording with Depayloaders¶
You can also record incoming RTP streams directly:
Recording Incoming H.264 Stream¶
#include "h264/openh264/rtp_h264_openh264_depayloader.h"
mediax::rtp::h264::openh264::RtpH264OpenH264Depayloader depayloader;
mediax::rtp::StreamInformation stream_info;
stream_info.hostname = "239.192.1.1";
stream_info.port = 5004;
stream_info.width = 1920;
stream_info.height = 1080;
stream_info.encoding = mediax::rtp::ColourspaceType::kColourspaceH264Part10;
depayloader.SetStreamInfo(stream_info);
// Enable recording while receiving
depayloader.SetOutputMode(mediax::rtp::OutputMode::kStreamAndRecord);
depayloader.SetRecordingFilename("captured_stream.mkv");
depayloader.Open();
depayloader.Start();
// Receive and display frames while also recording
std::vector<uint8_t> rgb_buffer(1920 * 1080 * 3);
while (running) {
depayloader.Receive(rgb_buffer.data(), 1000);
// Display or process the frame...
}
depayloader.Stop();
depayloader.Close();
Recording Incoming Raw Stream¶
#include "uncompressed/rtp_uncompressed_depayloader.h"
mediax::rtp::uncompressed::RtpUncompressedDepayloader depayloader;
mediax::rtp::StreamInformation stream_info;
stream_info.hostname = "239.192.1.1";
stream_info.port = 5004;
stream_info.width = 640;
stream_info.height = 480;
stream_info.encoding = mediax::rtp::ColourspaceType::kColourspaceRgb24;
depayloader.SetStreamInfo(stream_info);
// Record only mode - capture to file without processing
depayloader.SetOutputMode(mediax::rtp::OutputMode::kRecordOnly);
depayloader.SetRecordingFilename("captured_raw.mkv");
depayloader.Open();
depayloader.Start();
// Recording happens automatically during Receive()
std::vector<uint8_t> buffer(640 * 480 * 3);
while (running) {
depayloader.Receive(buffer.data(), 1000);
}
depayloader.Stop();
depayloader.Close();
API Reference¶
OutputMode Enum¶
enum class OutputMode {
kStreamOnly, // Stream only, no recording (default)
kRecordOnly, // Record only, no streaming
kStreamAndRecord // Both stream and record
};
Recording Methods¶
Both RtpPayloader and RtpDepayloader provide:
| Method | Description |
|---|---|
SetOutputMode(mode) |
Set the output mode |
GetOutputMode() |
Get the current output mode |
SetRecordingFilename(filename) |
Set the output MKV filename |
GetRecordingFilename() |
Get the recording filename |
IsStreamingEnabled() |
Check if streaming is enabled |
IsRecordingEnabled() |
Check if recording is enabled |
File Format¶
Recordings are saved in Matroska (MKV) format:
| Codec | MKV Codec ID | Description |
|---|---|---|
| Raw | V_MS/VFW/FOURCC | Uncompressed RGB24 video |
| H.264 | V_MPEG4/ISO/AVC | MPEG-4 AVC with AVCC format |
MKV files can be played with:
- VLC media player
- ffplay (
ffplay recording.mkv) - mpv
- Most modern video players
Recording Example¶
A complete recording example is included in the examples:
# Build the recording example
cd build
make recording-example
# Record 10 seconds of uncompressed video
./bin/recording-example --duration=10 --encoder=0 --output=my_video
# Record with OpenH264
./bin/recording-example --duration=10 --encoder=1 --output=my_video
# Record with VAAPI (if available)
./bin/recording-example --duration=10 --encoder=2 --output=my_video
Example Options¶
| Option | Description | Default |
|---|---|---|
--width |
Video width | 640 |
--height |
Video height | 480 |
--framerate |
Frame rate | 25 |
--duration |
Recording duration (seconds) | 10 |
--output |
Output filename base | rotating_cube |
--encoder |
0=Raw, 1=OpenH264, 2=VAAPI | 0 |
Best Practices¶
- Always call Close(): This finalizes the MKV file structure
- Use H.264 for large recordings: Raw video uses significant disk space
- Hardware encoding: Use VAAPI when available for better performance
- Check VAAPI availability: Call
IsVaapiAvailable()before using VAAPI encoder - Set keyframe interval: For H.264, set a reasonable keyframe interval for seeking
Troubleshooting¶
Recording not playing¶
- Ensure
Close()was called to finalize the file - Check that frames were actually transmitted/received
- Verify the output file size is reasonable
Large file sizes¶
- Use H.264 encoding instead of raw
- Reduce resolution or framerate
- Adjust H.264 bitrate
VAAPI not available¶
- Install VAAPI drivers (
vainfoto check) - Ensure your GPU supports VAAPI
- Try OpenH264 as an alternative