Skip to main content

Watermark (Beta)

The Watermark extension works with Web SDK v4.24.0 or later to add image watermarks to video streams. The extension supports customizable watermark properties such as position, size, and transparency, and can be applied to both local and remote video tracks.

Understand the tech

The Watermark extension integrates into the Web SDK's video processing pipeline to overlay images onto video streams in real-time. When enabled, the extension processes each video frame by compositing the watermark image at the specified position with the configured transparency level.

Prerequisites

To use the Watermark extension, ensure that:

  • You are using the latest version of Chrome (recommended), Edge, or Firefox desktop browser.
  • You have implemented the SDK quickstart in your project using the Web SDK version 4.24.0 or later.

Implementation

Follow these steps to integrate the Watermark extension and add watermarks to your video streams.

Integrate the extension

Use npm to integrate the agora-extension-video-watermark package into your project.

  1. Install the Watermark extension:


    _1
    npm install agora-extension-video-watermark

  2. Import the watermark module in your .js file:


    _3
    import AgoraRTC from "agora-rtc-sdk-ng";
    _3
    import { VideoWatermarkExtension, AgoraWatermarkImage } from "agora-extension-video-watermark";
    _3
    import type { IVWProcessor } from "agora-extension-video-watermark";

Register the extension

Call AgoraRTC.registerExtensions and pass the created VideoWatermarkExtension instance to register the Watermark extension.

Note

Agora recommends creating only one VideoWatermarkExtension instance.


_8
import AgoraRTC from "agora-rtc-sdk-ng";
_8
import { VideoWatermarkExtension } from "agora-extension-video-watermark";
_8
_8
// Create VideoWatermarkExtension instance
_8
const extension = new VideoWatermarkExtension();
_8
_8
// Register the extension
_8
AgoraRTC.registerExtensions([extension]);

Enable the extension

Follow these steps to enable the Watermark extension:

  1. Call createProcessor to create an IVWProcessor instance:


    _2
    // Create IVWProcessor instance
    _2
    const processor = extension.createProcessor();

  2. Call the SDK's pipe method and specify the processorDestination property to inject the extension into the video processing pipeline:


    _4
    // Create a video track (local or remote)
    _4
    const videoTrack = await AgoraRTC.createCameraVideoTrack();
    _4
    // Inject the extension into the video processing pipeline
    _4
    videoTrack.pipe(processor).pipe(videoTrack.processorDestination);

Add watermarks

The Watermark extension supports two methods for creating watermark images:

  • Use an existing HTMLImageElement

    If you already have an image element in the DOM (for example, from an <img> tag), you can use it directly:


    _12
    const image = document.getElementById('watermark-image') as HTMLImageElement;
    _12
    const watermark = new AgoraWatermarkImage(
    _12
    image,
    _12
    10, // x coordinate
    _12
    10, // y coordinate
    _12
    100, // width
    _12
    50, // height
    _12
    0.8 // opacity (0.0-1.0)
    _12
    );
    _12
    _12
    // Add watermark to processor
    _12
    processor.addVideoWatermark(watermark);

  • Use an image URL (asynchronous)

    You can also create a watermark from an image URL. This method loads the image asynchronously, so you must wait for the .ready Promise to complete before use:


    _14
    const watermark = new AgoraWatermarkImage(
    _14
    'https://example.com/watermark.png',
    _14
    10, // x coordinate
    _14
    10, // y coordinate
    _14
    100, // width (-1 uses original image width)
    _14
    50, // height (-1 uses original image height)
    _14
    0.8 // opacity (0.0-1.0)
    _14
    );
    _14
    _14
    // Wait for image to load
    _14
    await watermark.ready;
    _14
    _14
    // Add watermark to processor
    _14
    processor.addVideoWatermark(watermark);

    Note
    • When loading images from URLs, the operation may fail due to Cross-Origin Resource Policy (CORP) restrictions. If image loading fails, the ready Promise is rejected with an error.
    • To use the original image dimensions, set both width and height to -1.

Enable the processor

After adding watermarks, call enable to activate the processor:


_8
const enable = async () => {
_8
const enabled = processor.enabled;
_8
if (!enabled) {
_8
await processor.enable();
_8
}
_8
};
_8
_8
await enable();

Manage watermarks

You can dynamically enable or disable the watermark as follows:


_15
// Enable watermark
_15
const enable = async () => {
_15
const enabled = processor.enabled;
_15
if (!enabled) {
_15
await processor.enable();
_15
}
_15
};
_15
_15
// Disable watermark
_15
const disable = async () => {
_15
const enabled = processor.enabled;
_15
if (enabled) {
_15
await processor.disable();
_15
}
_15
};

Release resources

When you no longer need the Watermark extension, properly release resources:


_13
const release = async () => {
_13
// Unpipe connections
_13
processor.unpipe();
_13
videoTrack.unpipe();
_13
_13
// Reconnect to original destination
_13
videoTrack.pipe(videoTrack.processorDestination);
_13
_13
// Release processor resources
_13
await processor.release();
_13
};
_13
_13
await release();

Complete sample code

The following example demonstrates complete usage of the Watermark extension:

Sample code

_64
import AgoraRTC from "agora-rtc-sdk-ng";
_64
import { VideoWatermarkExtension, AgoraWatermarkImage } from "agora-extension-video-watermark";
_64
import type { IVWProcessor } from "agora-extension-video-watermark";
_64
_64
// Create and register Watermark extension
_64
const extension = new VideoWatermarkExtension();
_64
AgoraRTC.registerExtensions([extension]);
_64
_64
// Create processor
_64
const processor = extension.createProcessor();
_64
_64
async function setupWatermark() {
_64
try {
_64
// Create video track
_64
const videoTrack = await AgoraRTC.createCameraVideoTrack();
_64
_64
// Inject extension into video processing pipeline
_64
videoTrack.pipe(processor).pipe(videoTrack.processorDestination);
_64
_64
// Create watermark (using URL method)
_64
const watermark = new AgoraWatermarkImage(
_64
'https://example.com/logo.png',
_64
20, // x coordinate
_64
20, // y coordinate
_64
120, // width
_64
60, // height
_64
0.7 // opacity
_64
);
_64
_64
// Wait for watermark image to load
_64
await watermark.ready;
_64
_64
// Add watermark to processor
_64
processor.addVideoWatermark(watermark);
_64
_64
// Enable processor
_64
await processor.enable();
_64
_64
console.log("Watermark extension successfully enabled");
_64
_64
// Play video track
_64
videoTrack.play("video-container");
_64
_64
} catch (error) {
_64
console.error("Error setting up watermark:", error);
_64
}
_64
}
_64
_64
// Cleanup function
_64
async function cleanup() {
_64
try {
_64
await processor.disable();
_64
processor.unpipe();
_64
videoTrack.unpipe();
_64
videoTrack.pipe(videoTrack.processorDestination);
_64
await processor.release();
_64
console.log("Resources cleaned up");
_64
} catch (error) {
_64
console.error("Error cleaning up resources:", error);
_64
}
_64
}
_64
_64
// Call setup function
_64
setupWatermark();

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 reference

This section provides the core API reference for the Watermark extension.

addVideoWatermark

Adds a watermark image to the video stream.


_1
addVideoWatermark(watermark: AgoraWatermarkImage): number;

Parameters

  • watermark: An AgoraWatermarkImage instance.

Returns

The watermark ID for subsequent watermark management. Returns -1 if the operation fails.

clearVideoWatermarks

Removes all added video watermarks.


_1
clearVideoWatermarks(): boolean;

Returns

  • true: Successfully removed all watermarks.
  • false: Failed to remove watermarks.

removeVideoWatermark

Removes a specific video watermark by ID.


_1
removeVideoWatermark(id: number): boolean;

Parameters

  • id: The ID of the watermark to remove.

Returns

  • true: Successfully removed the specified watermark.
  • false: Failed to remove the watermark.

release

Releases the IVWProcessor resources.


_1
release(): Promise<void>;

AgoraWatermarkImage

Creates a watermark image instance.


_10
export class AgoraWatermarkImage {
_10
public image: HTMLImageElement | null;
_10
public x: number;
_10
public y: number;
_10
public width: number;
_10
public height: number;
_10
public alpha: number;
_10
public ready: Promise<void>;
_10
public imageReady: boolean = false;
_10
}

Parameters

  • image: The HTMLImageElement to use as the watermark. If null, no image is used.
  • url: The image URL to use as the watermark. If null or an empty string, no image is used.
  • x: The x-coordinate (in pixels) of the image on the video, relative to the top-left corner. Default is 0.
  • y: The y-coordinate (in pixels) of the image on the video, relative to the top-left corner. Default is 0.
  • width: The desired width (in pixels) of the watermark image. Default is -1, which uses the original width after the image loads.
  • height: The desired height (in pixels) of the watermark image. Default is -1, which uses the original height after the image loads.
  • alpha: The image opacity, from 0.0 (completely transparent) to 1.0 (completely opaque). Default is 1.0.