Watermarking your Video or Livestream

May 25, 2021 - Doug in live - create, Videos - Upload a Thumbnail, NodeJS, JavaScript

When publishing a video on the web, sometimes it is desirable to add a defining mark on the video, often called a watermark.

WHen you use api.video in the sandbox, we add a watermark to show that the videos are being played back in our test environment:

video watermarked from the sandbox

Clearly, this is a use of excessive watermarking. Perhaps you want to add your corporate logo in the corner of the video. Or perhaps the class name. There are a number of different reasons. you might want to add a watermark to your video, and in this post, I'll walk through two approaches to add a watermark to your videos.

The watermark

In this study, we'll be adding the api.video logo as our watermark. I (randomly) chose to insert the logo in the top right corner of the video.

Your watermark should be appropriately sized for the space in the video. In this case 100x100 pixels to fit inside a 1920x1080 video (~5%x10% of the screen).

I have adapted the record.a.video app to add a watermark (soon to be published at watermark.a.video), and in this app, I have provided 2 ways to add the watermark: the frontend and on the backend.

If the box is checked, the watermark is inserted on the frontend. If unchecked, the watermark is added on the backend. The field allows you to change the image being added as a watermark.

Frontend Watermark

In the watermark.a.video application, the screen (screenCaptureAPI) and the camera (MediaRecorded API) are drawn to a canvas. I've described this process in detail with code samples. The canvas is refreshed every 20ms, giving 50 FPS video on the canvas.

To add a watermark, I simply load the image into the app, and instead of only drawing the screen (videoElem) and the camera (cameraElem), I add the watermarkImg:

        console.log("FE watermark", canvasWatermark);
        //load watermark image
        var watermarkImg = new Image;
        watermarkImg.src = canvasWatermark;
            //draw the 2 streams to the canvas
            drawCanvas(videoElem, cameraElem,watermarkImg,ctx);

Inside the drawCanvas function, I draw the watermakrImg on top of the other 2 elements (by placing it last in the list of things drawn):

    function drawCanvas(screenIn, cameraIn,watermarkImg, canvas){
        var textLength = 60;
        canvas.drawImage(screenIn, screenX0,screenY0, screenX1, screenY1);
        canvas.drawImage(cameraIn, cameraX0, cameraY0, cameraX1, cameraY1);
        canvas.drawImage(watermarkImg, watermark_x, watermark_y);

For this demo, I have hardcoded the watermark to be in the upper right corner, so watermark_x = watermark_y = 25.

Backend Watermark

Perhaps the watermarking for your videos needs to be hardcoded into your process, or you do not want your users to be able to modify the watermark. Adding a processing step in the backend to insert a watermark makes this easy.

In the record.a.video app, livestreams are sent to a NodeJS server, where the WebRTC video recorded by the browser is converted to RTMP for ingestion into the api.video livestream server. This conversion is done with FFMPEG. WE can simply modify the FFMPEG command insert the watermark on top of the video while it is being transcoded.

			var ops = [
				'-i', socket._watermarkUrl,
         '-preset', 'ultrafast', '-tune', 'zerolatency', 
			       '-r', framerate, '-g', framerate*2, '-keyint_min',keyint_min, 
				'-filter_complex', '[1:v][0:v] overlay=25:25',
     				'-c:a', 'aac', '-b:a','44k', '-ar', 44100, 
			        '-f', 'flv', socket._rtmpDestination		

The FFMPEG options for watermarking has 2 lines added to the code from record.a.video.

				'-i', socket._watermarkUrl,

We have to give the URL of the image to add as the watermark.

	'-filter_complex', '[1:v][0:v] overlay=25:25',

The filter complex tells FFMPEG the order of the overlay. Since I add the watermark first (index 0), and then the video stream(index 1) - we place the video stream first, and then the watermark on top, with an offset of 25x25.

FFMPEG reads the image file and just inserts it on each frame encoded to the api.video server.

Watermark addition

In both cases, the live video that is sent to api.video has the watermark added. In the first case it is added in the browser as the video is being recorded, and in the second case, it is inserted by FFMPEG during a transcoding step.

Here's what the resulting video looks like:

In either case, you can see that we have successfully added the api.video logo as a watermark in the upper right corner. If you want to add watermarks to your videos - try out api.video, Feel free to fork the repo on Github and try it out yourself!


Developer Evangelist

Get started now

Connect your users with videos