How to Create a Video Watermarking App Using Python

Watermarking is a common method of labeling digital content. It enables brands and creators to add branding to their content. Especially in this hyper-connected era where videos are spread in the blink of an eye, it is important that brands can easily add branding to their work.

Of course, you can use the available video editors or web apps. They are certainly simple and easy to watermark one or a few videos. But what if you need to watermark thousands of videos? Even better, what if you could build an app that enables users to watermark videos?

That’s what this tutorial aims to teach – creating a program using Python to automatically watermark videos. After all, Python developers love to automate, don’t they?

There are two parts to this tutorial:

  1. single video watermarking
  2. Watermarking multiple videos using a list

Shotstack API and SDK

Shotstack provides cloud based video editing API. Rendering a video is very resource-intensive and it can take hours to edit and generate a large-scale video. Shotstack’s rendering infrastructure makes it possible to build and scale media applications in days, not months.

We will also be using the Shotstack Video Editing Python SDK for this
Tutorial. The SDK requires Python 3.

Install and Configure Shotstack SDK

You can find the source code for this guide in our GitHub repository if you wish to proceed. Otherwise, follow the steps below to install dependencies and set up your API key.

First, install the Shotstack Python SDK from the command line:

pip install shotstack_sdk
enter fullscreen mode

exit fullscreen mode

you may need to use pip3 Depends on how your environment is configured.

Then, set your API key as an environment variable (Linux/Mac):

export SHOTSTACK_KEY=your_key_here
enter fullscreen mode

exit fullscreen mode

Or, if using Windows (be sure to add SHOTSTACK_KEY for path):

set SHOTSTACK_KEY=your_key_here
enter fullscreen mode

exit fullscreen mode

To change your_key_here With the sandbox API key you provided which is free for testing and development.

Create a Python script to watermark a video

Create a file for the script in your favorite IDE or text editor. You can call it whatever you want, but for this tutorial, we created a file called watermark-video.py, Open the file and start editing.

import required modules

Let’s import the required modules for the project. We need to import modules from shotstack sdk for editing and rendering
Our videos and some built-in modules:

import shotstack_sdk as shotstack
import os
import sys

from shotstack_sdk.model.clip import Clip
from shotstack_sdk.api import edit_api
from shotstack_sdk.model.track import Track
from shotstack_sdk.model.timeline import Timeline
from shotstack_sdk.model.output import Output
from shotstack_sdk.model.edit import Edit
from shotstack_sdk.model.video_asset import VideoAsset
enter fullscreen mode

exit fullscreen mode

Configuring API Client

Next, add the following, which sets up the API client with the API URL and key, it should use the API key
your environment variables. If you want, you can hard code the API key here but we recommend using the environment
variable.

host = "https://api.shotstack.io/stage"
configuration = shotstack.Configuration(host = host)
configuration.api_key['DeveloperKey'] = os.getenv('SHOTSTACK_KEY')
with shotstack.ApiClient(configuration) as api_client:
    api_instance = edit_api.EditApi(api_client)
enter fullscreen mode

exit fullscreen mode

Understanding Timeline Architecture

The Shotstack API follows many of the principles of desktop editing software such as the use of timelines, tracks, and
clip. A timeline is like a container for multiple clips that contain
Various assets that move over time.
Tracks on the timeline allow us to layer clips on top of each other.

set video clip

Videos must be hosted online and accessible via a public or signed URL. We will be using the following 10-second drone footage as our video asset. You can replace it with your own video URL from any online source.

Add the following code to create a create VideoAsset Using video URL:

video_asset = VideoAsset(
    src = "https://d1uej6xx5jo4cd.cloudfront.net/sydney.mp4"
)
enter fullscreen mode

exit fullscreen mode

Next, create a Clip, A clip is a container for a variety of
property, including VideoAsset, We can configure different properties
Like length (duration for play) and start time (when on the timeline the clip will play). For our clips we use
video_asset We just created, a start of 0 seconds and a length of 10 seconds:

video_clip = Clip(
    asset = video_asset,
    start = 0.0,
    length = 10.0
)
enter fullscreen mode

exit fullscreen mode

set image clip

Next, we need to add an image which will be a watermark on the video. We will use the attached logo. You can replace it with your own image url.

similar to setting VideoAssetlet’s add ImageAsset By adding the following code.

image_asset = ImageAsset(
    src = "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/logos/real-estate-black.png"
)
enter fullscreen mode

exit fullscreen mode

Let’s configure clip properties which include ImageAsset, We will configure the length, start time, position (position.)
Of ImageAsset in viewport), scale (property size relative to viewport size), and opacity (transparency)
Property). To learn more about it visit the Clips documentation
clip properties.

image_clip = Clip(
    asset = image_asset,
    start = 0.0,
    length = 10.0,
    scale = 0.25,
    position = 'bottomRight',
    opacity = 0.3
)
enter fullscreen mode

exit fullscreen mode

Adding a Video Clip to the Timeline

Next, let’s create a timeline for adding our clips. Before that, we have to make two separate tracks. We shouldn’t be adding two clips on the same track in the same timeline because that won’t tell which asset will appear on top. This property causes the flicker.

let’s add image_clip Feather track_1 And this video_clip Feather track_2 By adding the following script.

track_1 = Track(clips=[image_clip])
track_2 = Track(clips=[video_clip])
enter fullscreen mode

exit fullscreen mode

Next, let’s add both tracks to our timeline. Make sure they are sorted chronologically based on how they are layered. If the track consist of image_clip second on the list, it will not appear on the video because it will be behind video_clip,

timeline = Timeline(
    background = "#000000",
    tracks = [track_1, track_2]
    )
enter fullscreen mode

exit fullscreen mode

Final editing and configuring output

Next, we need to configure our output. we set the output format To mp4, Let’s set the video resolution hd Which produces a video of 1280px x 720px @ 25fps. You can also configure other properties like repeat For auto-repeat used in GIF, thumbnail To generate a thumbnail from a specific point on the timeline, destinations to set export destinations, and more.

output = Output(
    format = "mp4",
    resolution = "hd"
)

edit = Edit(
    timeline = timeline,
    output   = output
)
enter fullscreen mode

exit fullscreen mode

Sending edits for rendering via API

Finally, we send the edits for processing and rendering using the API. The Shotstack SDK takes care of converting our objects to JSON, adding our keys to the request header, and posting everything to the API.

try:
    api_response = api_instance.post_render(edit)
    message = api_response['response']['message']
    id = api_response['response']['id']
    print(f"{message}\n")
    print(f">> render id: {id}")
except Exception as e:
    print(f"Unable to resolve API call: {e}")
enter fullscreen mode

exit fullscreen mode

final script

Below is the final script with some additional checks and balances:

import shotstack_sdk as shotstack
import os
import sys

from shotstack_sdk.api import edit_api
from shotstack_sdk.model.clip import Clip
from shotstack_sdk.model.track import Track
from shotstack_sdk.model.timeline import Timeline
from shotstack_sdk.model.output import Output
from shotstack_sdk.model.edit import Edit
from shotstack_sdk.model.video_asset import VideoAsset
from shotstack_sdk.model.image_asset import ImageAsset

if __name__ == "__main__":
    host = "https://api.shotstack.io/stage"

    configuration = shotstack.Configuration(host = host)

    configuration.api_key['DeveloperKey'] = os.getenv("SHOTSTACK_KEY")

    with shotstack.ApiClient(configuration) as api_client:
        api_instance = edit_api.EditApi(api_client)

        video_asset = VideoAsset(
        src = "https://d1uej6xx5jo4cd.cloudfront.net/sydney.mp4"
        )

        video_clip = Clip(
            asset = video_asset,
            start = 0.0,
            length= 10.0
        )

        image_asset = ImageAsset(
        src = "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/logos/real-estate-black.png"
        )

        image_clip = Clip(
            asset = image_asset,
            start = 0.0,
            length = 10.0,
            scale = 0.25,
            position = 'bottomRight',
            opacity = 0.3
        )

        track_1 = Track(clips=[image_clip])
        track_2 = Track(clips=[video_clip])

        timeline = Timeline(
            background = "#000000",
            tracks     = [track_1, track_2]
        )

        output = Output(
            format      = "mp4",
            resolution  = "hd"
        )

        edit = Edit(
            timeline = timeline,
            output   = output
        )

        try:
            api_response = api_instance.post_render(edit)

            message = api_response['response']['message']
            id = api_response['response']['id']

            print(f"{message}\n")
            print(f">> render id: {id}")
        except Exception as e:
            print(f"Unable to resolve API call: {e}")
enter fullscreen mode

exit fullscreen mode

run script

Use python commands to run the script.

python watermark-video.py
enter fullscreen mode

exit fullscreen mode

you may need to use python3 Instead python depending on your configuration.

If the render request is successful, the API will return the render id which we can use to retrieve the status
render.

Checking Render Status and Output URL

To check the status we need another script that will call the API to render the status endpoint. create a file called
Status.py and paste the following code:

import sys
import os
import shotstack_sdk as shotstack

from shotstack_sdk.api import edit_api

if __name__ == "__main__":
    host = "https://api.shotstack.io/stage"
    configuration = shotstack.Configuration(host = host)
    configuration.api_key['DeveloperKey'] = os.getenv("SHOTSTACK_KEY")

    with shotstack.ApiClient(configuration) as api_client:
        api_instance = edit_api.EditApi(api_client)
        api_response = api_instance.get_render(sys.argv[1], data=False, merged=True)

        status = api_response['response']['status']

        print(f"Status: {status}")

        if status == "done":
            url = api_response['response']['url']
            print(f">> Asset URL: {url}")
enter fullscreen mode

exit fullscreen mode

Then run the script using the command line:

python status.py {renderId}
enter fullscreen mode

exit fullscreen mode

To change {renderId} with id returned from watermark-video.py script. every 4-5. Rerun the script in status.py
seconds until the position is What happened? And a URL is returned. If something goes wrong the status will look like this fail,
If everything went well you should now have the URL of the final video, just like it was in the beginning
Tutorial.

watermark video example

We can see the watermarked video below:

Access your rendered videos using the dashboard

You can watch your rendered videos inside Shotstack Dashboard render, Videos are deleted after 24 hours and need to be transferred to your own storage provider. However all files are copied to Shotstack hosting and you can configure other destinations including S3 and Mux.

Shotstack Dashboard

Multiple video watermarking

As you can see how easy it is to watermark a video using the Shotstack Python SDK. However, the big advantage of using the Shotstack API is how easily we can scale without having to build and manage the rendering infrastructure.

To demonstrate scalability, we’ll watermark the following list of videos with the same logo we used above. You can also use other data resources such as CSV and other apps integrated with their API.

video_links = [
    'https://d1uej6xx5jo4cd.cloudfront.net/slideshow-with-audio.mp4',
    'https://cdn.shotstack.io/au/v1/msgtwx8iw6/d724e03c-1c4f-4ffa-805a-a47aab70a28f.mp4',
    'https://cdn.shotstack.io/au/v1/msgtwx8iw6/b03c7b50-07f3-4463-992b-f5241ea15c18.mp4',
    'https://cdn.shotstack.io/au/stage/c9npc4w5c4/d2552fc9-f05a-4e89-9749-a87d9a1ae9aa.mp4',
    'https://cdn.shotstack.io/au/v1/msgtwx8iw6/c900a02f-e008-4c37-969f-7c9578279100.mp4'
]
enter fullscreen mode

exit fullscreen mode

The following script watermarks the list of videos. If you want to test it, create a new file named
watermark-videos.pyPaste the script, and save it.

import shotstack_sdk as shotstack
import os
import sys

from shotstack_sdk.api import edit_api
from shotstack_sdk.model.clip import Clip
from shotstack_sdk.model.track import Track
from shotstack_sdk.model.timeline import Timeline
from shotstack_sdk.model.output import Output
from shotstack_sdk.model.edit import Edit
from shotstack_sdk.model.video_asset import VideoAsset
from shotstack_sdk.model.image_asset import ImageAsset

if __name__ == "__main__":

    host = "https://api.shotstack.io/stage"

    configuration = shotstack.Configuration(host = host)

    configuration.api_key['DeveloperKey'] = os.getenv("SHOTSTACK_KEY")

    video_links = ['https://d1uej6xx5jo4cd.cloudfront.net/slideshow-with-audio.mp4',
        'https://cdn.shotstack.io/au/v1/msgtwx8iw6/d724e03c-1c4f-4ffa-805a-a47aab70a28f.mp4',
        'https://cdn.shotstack.io/au/v1/msgtwx8iw6/b03c7b50-07f3-4463-992b-f5241ea15c18.mp4',
        'https://cdn.shotstack.io/au/stage/c9npc4w5c4/d2552fc9-f05a-4e89-9749-a87d9a1ae9aa.mp4',
        'https://cdn.shotstack.io/au/v1/msgtwx8iw6/c900a02f-e008-4c37-969f-7c9578279100.mp4'
    ]

    with shotstack.ApiClient(configuration) as api_client:
        for link in video_links:
            api_instance = edit_api.EditApi(api_client)

            video_asset = VideoAsset(
            src = link
            )

            video_clip = Clip(
                asset = video_asset,
                start = 0.0,
                length= 10.0
            )

            image_asset = ImageAsset(
                src = "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/logos/real-estate-black.png"
            )

            image_clip = Clip(
                asset = image_asset,
                start = 0.0,
                length = 10.0,
                scale = 0.25,
                position = 'bottomRight',
                opacity = 0.3
            )

            track_1 = Track(clips=[image_clip])
            track_2 = Track(clips=[video_clip])

            timeline = Timeline(
                background = "#000000",
                tracks     = [track_1, track_2]
            )

            output = Output(
                format      = "mp4",
                resolution  = "hd"
            )

            edit = Edit(
                timeline = timeline,
                output   = output
            )

            try:
                api_response = api_instance.post_render(edit)

                message = api_response['response']['message']
                id = api_response['response']['id']

                print(f"{message}\n")
                print(f">> render id: {id}")
            except Exception as e:
                print(f"Unable to resolve API call: {e}")
enter fullscreen mode

exit fullscreen mode

Then use python commands to run the script.

python watermark-videos.py
enter fullscreen mode

exit fullscreen mode

To check render status, run status.py file that we have created in the first part and run it using command line:

python status.py {renderId}
enter fullscreen mode

exit fullscreen mode

change renderId id returned from watermark-videos.py,

final thoughts

This tutorial should have given you a basic understanding of editing and generating videos programmatically using Python and the Shotstack video editing API. As a next step, you can learn how to combine other assets like text and images to create a simple media application. This is just an introductory tutorial for working with media programmatically but we can do much more. We can use it for many use cases like

You can check out our other Python tutorials and YouTube videos to learn programmatic media and build video apps faster.

Leave a Comment