# Add watermark to recordings (/en/realtime-media/on-premise-recording/build/customize-the-recording/watermark)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

<_PlatformTabsGroup groupMode="structured" canonicalPlatform="linux-cpp" platforms="[&#x22;linux-cpp&#x22;,&#x22;linux-java&#x22;]" showTabs="true">
  <_PlatformPanel platform="linux-cpp">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="linux-cpp" platform="linux-cpp" />

    This guide explains how to configure and apply watermarks when recording video with the On-Premise Recording SDK.

    ## Understand the tech [#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 [#prerequisites]

    Before adding watermarks, integrate the On-Premise Recording SDK and complete the [Quickstart](/en/realtime-media/on-premise-recording/quickstart) guide to ensure basic recording works as expected.

    ## Implementation [#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`.

    <CalloutContainer type="info">
      <CalloutDescription>
        To use watermarks in individual recording mode, call `enableAndUpdateVideoWatermarksByUid` and `disableVideoWatermarksByUid` instead.
      </CalloutDescription>
    </CalloutContainer>

    ### Add a text watermark [#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`:

       ```cpp
       watermarks[i].type = agora::rtc::LITERA;
       ```

    3. Configure the text, font path, and font size:

       ```cpp
       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 [#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`:

       ```cpp
       watermarks[i].type = agora::rtc::TIMESTAMPS;
       ```

    3. Configure the font path and size:

       ```cpp
       watermarks[i].timestampSource.fontFilePath = "path/to/font.ttf"; // Optional
       watermarks[i].timestampSource.fontSize = 20;
       ```

    ### Add an image watermark [#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`:

       ```cpp
       watermarks[i].type = agora::rtc::PICTURE;
       ```

    3. Set the image path:

       ```cpp
       watermarks[i].imageUrl = "path/to/watermark.png";
       ```

    ### Set the watermark position [#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) [#fixed-position-pixels]

    * Portrait mode

      ```cpp
      // 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

      ```cpp
      // 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) [#relative-position-ratio]

    ```cpp
    // 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 [#complete-sample]

    <details>
      <summary>
        Full example for adding watermarks
      </summary>

      ```cpp
      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());
      }
      ```
    </details>

    ## Reference [#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 [#api-references]

    * [`WatermarkLitera`](/en/api-reference/api-ref/on-premise-recording#watermarklitera)
    * [`enableAndUpdateVideoWatermarks`](/en/api-reference/api-ref/on-premise-recording#enableandupdatevideowatermarks)
    * [`WatermarkTimestamp`](/en/api-reference/api-ref/on-premise-recording#watermarktimestamp)
    * [`WatermarkOptions`](/en/api-reference/api-ref/on-premise-recording#watermarkoptions)
    * [`Rectangle`](/en/api-reference/api-ref/on-premise-recording#rectangle)
    * [`WatermarkRatio`](/en/api-reference/api-ref/on-premise-recording#watermarkratio)

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="linux-java">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="linux-cpp" platform="linux-java" />

    This guide explains how to configure and apply watermarks when recording video with the On-Premise Recording SDK.

    ## Understand the tech [#understand-the-tech-1]

    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 [#prerequisites-1]

    Before adding watermarks, integrate the On-Premise Recording SDK and complete the [Quickstart](/en/realtime-media/on-premise-recording/quickstart) guide to ensure basic recording works as expected.

    ## Implementation [#implementation-1]

    To add watermarks to your recordings, follow the platform-specific implementation instructions:

    To apply 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`.

    <CalloutContainer type="info">
      <CalloutDescription>
        To apply watermarks in individual recording mode, use `enableAndUpdateVideoWatermarksByUid` and `disableVideoWatermarksByUid` instead.
      </CalloutDescription>
    </CalloutContainer>

    ### Add a text watermark [#add-a-text-watermark-1]

    To add a text watermark:

    1. Call `enableAndUpdateVideoWatermarks()` and pass the `watermarkConfigs` array.

    2. Set the watermark type to `LITERA`:

       ```java
       watermarks[i].setType(Constants.WatermarkSourceType.LITERA);
       ```

    3. Configure the text content, font path, and font size:

       ```java
       WatermarkLitera textWatermark = new WatermarkLitera();
       textWatermark.setWmLitera("Agora Watermark Example");
       textWatermark.setFontFilePath("path/to/font.ttf"); // Optional
       textWatermark.setFontSize(24);

       watermarks[i].setLiteraSource(textWatermark);
       ```

    ### Add a timestamp watermark [#add-a-timestamp-watermark-1]

    To add a timestamp watermark:

    1. Call `enableAndUpdateVideoWatermarks()` and pass the `watermarkConfigs` array.

    2. Set the watermark type to `TIMESTAMPS`:

       ```java
       watermarks[i].setType(Constants.WatermarkSourceType.TIMESTAMPS);
       ```

    3. Configure the font and size:

       ```java
       WatermarkTimestamp timestamp = new WatermarkTimestamp();
       timestamp.setFontFilePath("path/to/font.ttf"); // Optional
       timestamp.setFontSize(20);

       watermarks[i].setTimestampSource(timestamp);
       ```

    ### Add an image watermark [#add-an-image-watermark-1]

    To add an image watermark:

    1. Call `enableAndUpdateVideoWatermarks()` and pass the `watermarkConfigs` array.

    2. Set the watermark type to `PICTURE`:

       ```java
       watermarks[i].setType(Constants.WatermarkSourceType.PICTURE);
       ```

    3. Set the image path:

       ```java
       watermarks[i].setImageUrl("path/to/watermark.png");
       ```

    ### Set the watermark position [#set-the-watermark-position-1]

    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) [#fixed-position-pixels-1]

    * Portrait mode

      ```java
      WatermarkOptions options = new WatermarkOptions();
      options.setMode(Constants.WatermarkFitMode.FIT_MODE_COVER_POSITION);
      options.setZOrder(1);

      Rectangle portrait = new Rectangle();
      portrait.setX(50);
      portrait.setY(50);
      portrait.setWidth(200);
      portrait.setHeight(100);

      options.setPositionInPortraitMode(portrait);
      watermarks[i].setOptions(options);
      ```

    * Landscape mode

      ```java
      Rectangle landscape = new Rectangle();
      landscape.setX(50);
      landscape.setY(50);
      landscape.setWidth(200);
      landscape.setHeight(100);

      options.setPositionInLandscapeMode(landscape);
      watermarks[i].setOptions(options);
      ```

    #### Relative position (ratios) [#relative-position-ratios]

    ```java
    WatermarkOptions options = new WatermarkOptions();
    options.setMode(Constants.WatermarkFitMode.FIT_MODE_USE_IMAGE_RATIO);
    options.setZOrder(1);

    WatermarkRatio ratio = new WatermarkRatio();
    ratio.setXRatio(0.5);
    ratio.setYRatio(0.5);
    ratio.setWidthRatio(0.6);

    options.setWatermarkRatio(ratio);
    watermarks[i].setOptions(options);
    ```

    ### Complete sample [#complete-sample-1]

    <details>
      <summary>
        Full example for adding watermarks
      </summary>

      ```java
      if (recorderConfig.getWaterMark() != null && !recorderConfig.getWaterMark().isEmpty()) {
        WatermarkConfig[] watermarks = new WatermarkConfig[recorderConfig.getWaterMark().size()];

        for (int i = 0; i < watermarks.length; i++) {
          WatermarkInfo info = recorderConfig.getWaterMark().get(i);
          watermarks[i] = new WatermarkConfig();
          watermarks[i].setIndex(i + 1);

          WatermarkSourceType type = Utils.convertToWatermarkSourceType(info.getType());
          watermarks[i].setType(type);

          if (type == WatermarkSourceType.LITERA) {
            WatermarkLitera litera = new WatermarkLitera();
            litera.setWmLitera(info.getLitera());
            litera.setFontFilePath(info.getFontFilePath());
            litera.setFontSize(info.getFontSize());
            watermarks[i].setLiteraSource(litera);

          } else if (type == WatermarkSourceType.TIMESTAMPS) {
            WatermarkTimestamp timestamp = new WatermarkTimestamp();
            timestamp.setFontFilePath(info.getFontFilePath());
            timestamp.setFontSize(info.getFontSize());
            watermarks[i].setTimestampSource(timestamp);

          } else if (type == WatermarkSourceType.PICTURE) {
            watermarks[i].setImageUrl(info.getImgUrl());
          }

          WatermarkOptions options = new WatermarkOptions();
          options.setMode(Constants.WatermarkFitMode.FIT_MODE_COVER_POSITION);
          options.setZOrder(info.getZorder());

          Rectangle portrait = new Rectangle();
          portrait.setX(info.getX());
          portrait.setY(info.getY());
          portrait.setWidth(info.getWidth());
          portrait.setHeight(info.getHeight());

          Rectangle landscape = new Rectangle();
          landscape.setX(info.getX());
          landscape.setY(info.getY());
          landscape.setWidth(info.getWidth());
          landscape.setHeight(info.getHeight());

          options.setPositionInPortraitMode(portrait);
          options.setPositionInLandscapeMode(landscape);
          watermarks[i].setOptions(options);
        }

        agoraMediaRtcRecorder.enableAndUpdateVideoWatermarks(watermarks);
      }
      ```
    </details>

    ## Reference [#reference-1]

    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 [#api-references-1]

    * [`WatermarkLitera`](/en/api-reference/api-ref/on-premise-recording#watermarklitera)
    * [`enableAndUpdateVideoWatermarks`](/en/api-reference/api-ref/on-premise-recording#enableandupdatevideowatermarks)
    * [`WatermarkTimestamp`](/en/api-reference/api-ref/on-premise-recording#watermarktimestamp)
    * [`WatermarkOptions`](/en/api-reference/api-ref/on-premise-recording#watermarkoptions)
    * [`Rectangle`](/en/api-reference/api-ref/on-premise-recording#rectangle)
    * [`WatermarkRatio`](/en/api-reference/api-ref/on-premise-recording#watermarkratio)

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>
</_PlatformTabsGroup>
