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:

  1. Call enableAndUpdateVideoWatermarks and pass the watermark_configs array.

  2. Set the watermark type to LITERA:

    watermarks[i].type = agora::rtc::LITERA;
  3. 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:

  1. Call enableAndUpdateVideoWatermarks and pass the watermark_configs array.

  2. Set the watermark type to TIMESTAMPS:

    watermarks[i].type = agora::rtc::TIMESTAMPS;
  3. 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:

  1. Call enableAndUpdateVideoWatermarks and pass the watermark_configs array.

  2. Set the watermark type to PICTURE:

    watermarks[i].type = agora::rtc::PICTURE;
  3. 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.

API references