Add watermark to recordings
Updated
How to add watermarks to video recordings using the On-Premise Recording SDK.
This guide explains how to configure and apply watermarks when recording video with the On-Premise Recording SDK.
Understand the tech
Use watermarks to display logos, timestamps, or custom text for branding, copyright, or verification. The On-Premise Recording SDK supports three types of watermarks in both individual and composite recording modes:
- Text watermark: Shows user-defined text with customizable font and size.
- Timestamp watermark: Displays the current time from the recording server.
- Image watermark: Renders a static image in PNG or JPG format.
Prerequisites
Before adding watermarks, integrate the On-Premise Recording SDK and complete the Quickstart guide to ensure basic recording works as expected.
Implementation
To add watermarks to your recordings, follow the platform-specific implementation instructions:
To add or update a watermark in composite recording mode, call enableAndUpdateVideoWatermarks and pass an array of watermark configuration objects. Each object defines one watermark, including its type, content, position, and appearance. To remove all watermarks, call disableVideoWatermarks.
To use watermarks in individual recording mode, call enableAndUpdateVideoWatermarksByUid and disableVideoWatermarksByUid instead.
Add a text watermark
To add a text watermark:
-
Call
enableAndUpdateVideoWatermarksand pass thewatermark_configsarray. -
Set the watermark type to
LITERA:watermarks[i].type = agora::rtc::LITERA; -
Configure the text, font path, and font size:
watermarks[i].literaSource.wmLitera = "Agora watermark example"; watermarks[i].literaSource.fontFilePath = "path/to/font.ttf"; // Optional watermarks[i].literaSource.fontSize = 24;
Add a timestamp watermark
To add a timestamp watermark:
-
Call
enableAndUpdateVideoWatermarksand pass thewatermark_configsarray. -
Set the watermark type to
TIMESTAMPS:watermarks[i].type = agora::rtc::TIMESTAMPS; -
Configure the font path and size:
watermarks[i].timestampSource.fontFilePath = "path/to/font.ttf"; // Optional watermarks[i].timestampSource.fontSize = 20;
Add an image watermark
To add an image watermark:
-
Call
enableAndUpdateVideoWatermarksand pass thewatermark_configsarray. -
Set the watermark type to
PICTURE:watermarks[i].type = agora::rtc::PICTURE; -
Set the image path:
watermarks[i].imageUrl = "path/to/watermark.png";
Set the watermark position
You can set watermark positions using either absolute pixels or relative ratios. You can also define separate positions for portrait and landscape orientations.
Fixed position (pixels)
-
Portrait mode
// Use fixed-pixel positioning watermarks[i].options.mode = agora::rtc::FIT_MODE_COVER_POSITION; watermarks[i].options.zOrder = 1; watermarks[i].options.positionInPortraitMode.x = 50; watermarks[i].options.positionInPortraitMode.y = 50; watermarks[i].options.positionInPortraitMode.width = 200; watermarks[i].options.positionInPortraitMode.height = 100; -
Landscape mode
// Use fixed-pixel positioning watermarks[i].options.mode = agora::rtc::FIT_MODE_COVER_POSITION; watermarks[i].options.zOrder = 1; watermarks[i].options.positionInLandscapeMode.x = 50; watermarks[i].options.positionInLandscapeMode.y = 50; watermarks[i].options.positionInLandscapeMode.width = 200; watermarks[i].options.positionInLandscapeMode.height = 100;
Relative position (ratio)
// Use ratio-based positioning
watermarks[i].options.mode = agora::rtc::FIT_MODE_USE_IMAGE_RATIO;
watermarks[i].options.zOrder = 1;
watermarks[i].options.watermarkRatio.xRatio = 0.5;
watermarks[i].options.watermarkRatio.yRatio = 0.5;
watermarks[i].options.watermarkRatio.widthRatio = 0.6;Complete sample
Full example for adding watermarks
if (!recorderConfig.waterMark.empty()) {
std::vector<WatermarkConfig> watermarks(recorderConfig.waterMark.size());
for (size_t i = 0; i < watermarks.size(); ++i) {
const WatermarkInfo& info = recorderConfig.waterMark[i];
watermarks[i].index = static_cast<int>(i + 1);
watermarks[i].type = convertToWatermarkSourceType(info.type);
if (watermarks[i].type == agora::rtc::LITERA) {
watermarks[i].literaSource.wmLitera = info.litera;
watermarks[i].literaSource.fontFilePath = info.fontFilePath;
watermarks[i].literaSource.fontSize = info.fontSize;
} else if (watermarks[i].type == agora::rtc::TIMESTAMPS) {
watermarks[i].timestampSource.fontFilePath = info.fontFilePath;
watermarks[i].timestampSource.fontSize = info.fontSize;
} else if (watermarks[i].type == agora::rtc::PICTURE) {
watermarks[i].imageUrl = info.imgUrl;
}
watermarks[i].options.mode = agora::rtc::FIT_MODE_COVER_POSITION;
watermarks[i].options.zOrder = info.zOrder;
watermarks[i].options.positionInPortraitMode = {
info.x, info.y, info.width, info.height
};
watermarks[i].options.positionInLandscapeMode = {
info.x, info.y, info.width, info.height
};
}
recorder->enableAndUpdateVideoWatermarks(watermarks.data(), watermarks.size());
}Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
