How to watermark videos using PHP

Watermarking your videos is a great way to increase brand visibility. It helps create awareness and promotes your brand wherever your video is viewed or shared.

It's no big deal when you want to watermark one or a few videos. You can use a video editing software or a tool like the Shotstack watermark video tool. However scaling this process for hundreds or thousands of videos can be a hassle. In such cases, you need a way to automate the process.

This tutorial will show you a quick and easy solution using PHP and the Shotstack API. By the end of this article, you will know how to create a PHP script to do the following;

  • Add a watermark to a single video.
  • Batch add watermarks to many videos.

Requirements

  • A Shotstack API Key, which you get when you sign up for a free developer account.
  • PHP 7.3 (or higher version)
  • The Shotstack PHP SDK

The Shotstack API and SDK

Shotstack provides a cloud-based video editing API. Editing and producing videos at scale can take hours, and rendering them requires significant resources. Using Shotstack's rendering infrastructure, you can build scalable media applications and video features with a quick turnaround time.

The PHP SDK we will use in this tutorial gives you access to all of Shotstack's video editing features including cut and trim, stitching clips, transitions, filters, various effects and more.

Sign up for a free developer account to get your Shotstack API key.

Install and set up the PHP video editor SDK

To follow along, create a new PHP file. You can call it whatever you like. But for the sake of this tutorial, let's call it watermark.php.

In your terminal, navigate to the directory containing your watermark.php script. And run the following command to install the PHP video editor SDK.

composer require shotstack/shotstack-sdk-php

Watermark a single video using PHP

First, let's create a script to watermark one video. After that, you'll learn how to tweak the script to watermark many videos. Let's get started!

Import classes from the Shotstack SDK

Import the required classes for the script by adding the following to your watermark.php file.

require 'vendor/autoload.php';

use Shotstack\Client\Api\EditApi;
use Shotstack\Client\Configuration;
use Shotstack\Client\Model\Edit;
use Shotstack\Client\Model\Output;
use Shotstack\Client\Model\Timeline;
use Shotstack\Client\Model\Track;
use Shotstack\Client\Model\Clip;
use Shotstack\Client\Model\VideoAsset;
use Shotstack\Client\Model\ImageAsset;

Set up the API client

Then add the following code, to configure the API client with the API URL and your Shotstack API key.

$config = Configuration::getDefaultConfiguration()
->setHost('https://api.shotstack.io/stage')
->setApiKey('x-api-key', 'YOUR_API_KEY'); // use your API key

$client = new EditApi(null, $config);

Replace YOUR_API_KEY with the sandbox API key from the dashboard. It's free for testing and development.

Set up the video clip

You need a URL of a video file to set up the video clip. Your URL must be public or accessible.

The video below is a 10-second drone footage we will use for this tutorial. Feel free to use any video you want.

Add the following code to create a VideoAsset. And pass the image's URL as argument to the setSrc method.

$videoAsset = new VideoAsset();
$videoAsset
->setSrc('https://d1uej6xx5jo4cd.cloudfront.net/sydney.mp4');

Next, you need to create a Clip. A clip is a container for various types of assets like videos, images, titles, and more. You use clips to determine when and how long to display an asset on the timeline.

Create a clip for the video using the Clip class. You can set up various properties for the clip like the ones in the code below.

$videoClip = new Clip();
$videoClip
->setAsset($videoAsset)
->setLength(10)
->setStart(0);

The code sets $videoAsset from the previous step as the asset for $videoClip. It also sets the length (the amount of time the clip will play for in seconds). And setStart sets what time on the timeline the clip starts to play.

Set up the image clip

After creating your video clip, the next step is to create an image clip for the watermark logo.

The logo image below is what we will use for the watermark in this tutorial. Again, you can use any image of your choice. What you need is a correct and accessible image URL.

A simple watermark

Setting up the image asset is similar to setting up the video asset. Create a new instance of ImageAsset and pass the image's URL as an argument to the setSrc attribute.

$imageAsset = new ImageAsset();
$imageAsset
->setSrc("https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/logos/real-estate-black.png");

Use the $imageAsset to create an image clip by creating a new instance of a Clip. And pass $imageAsset as argument to the setAsset method. You can also set other clip properties including;

  • Start: starting time of the asset on the timeline.
  • Length: how long the clip should play, in seconds.
  • Scale: size of asset in relation to viewport
  • Position: where to place or display the asset
  • Opacity: level of transparency of the asset
$imageClip = new Clip();
$imageClip
-> setAsset($imageAsset)
-> setStart(0)
-> setLength(10.0)
-> setScale(0.25)
-> setPosition('bottomRight')
-> setOpacity(0.3);

Add the clips to tracks

Tracks are individual layers with content. They are placed one on top of another in a stacking order. And the order of the layers determines how your content is displayed.

For example, in this tutorial, we want the watermark image to appear on top of the video. So, we will set the imageClip on track1 (the topmost track) and the videoClip on track2.

$track1 = new Track();
$track1->setClips([$imageClip]);

$track2 = new Track();
$track2->setClips([$videoClip]);

Add the tracks to a timeline

The timeline is a representation of your entire video project. It contains all the tracks with the various contents that make up your project.

Add both tracks to a timeline using the code below.

$timeline = new Timeline();
$timeline->setTracks([$track1, $track2]);

The position of tracks in the array determines the order. The first track is the topmost track and its content will display above the content of tracks that come after it.

Set up the output and final edit

Next, you need to specify the output format and resolution.

$output = new Output();
$output
->setFormat('mp4')
->setResolution('hd');

Other output properties you can set include destinations, for setting export locations, thumbnail, aspectRatio, and more.

The final steps before making a request to the API is to create an instance of Edit and set the $timeline and $output.

$edit = new Edit();
$edit
->setTimeline($timeline)
->setOutput($output);

Send the edit to the API for rendering

Use the code below to send the $edit to the API. The Shotstack SDK will convert the objects to JSON, add your API key to the request header, and makes a POST request to the Shotstack API.

try {
$response = $client->postRender($edit)->getResponse();
} catch (ApiException $e) {
die('Request failed: ' . $e->getMessage() . $e->getResponseBody());
}

echo $response->getMessage() . "\n";
echo ">> render id: " . $response->getId() . "\n";
?>

Final PHP script to watermark a single video

Below is the final code. Your watermark.php file should now look like this.

<?php
require 'vendor/autoload.php';

use Shotstack\Client\Api\EditApi;
use Shotstack\Client\Configuration;
use Shotstack\Client\Model\Edit;
use Shotstack\Client\Model\Output;
use Shotstack\Client\Model\Timeline;
use Shotstack\Client\Model\Track;
use Shotstack\Client\Model\Clip;
use Shotstack\Client\Model\VideoAsset;
use Shotstack\Client\Model\ImageAsset;

$config = Configuration::getDefaultConfiguration()
->setHost('https://api.shotstack.io/stage')
->setApiKey('x-api-key', 'YOUR_API_KEY'); // use your API key

$client = new EditApi(null, $config);

$videoAsset = new VideoAsset();
$videoAsset
->setSrc('https://d1uej6xx5jo4cd.cloudfront.net/sydney.mp4');

$videoClip = new Clip();
$videoClip
->setAsset($videoAsset)
->setLength(10)
->setStart(0);

$imageAsset = new ImageAsset();
$imageAsset
->setSrc("https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/logos/real-estate-black.png");

$imageClip = new Clip();
$imageClip
->setAsset($imageAsset)
->setStart(0)
->setLength(10.0)
->setScale(0.25)
->setPosition('bottomRight')
->setOpacity(0.3);

$track1 = new Track();
$track1->setClips([$imageClip]);

$track2 = new Track();
$track2->setClips([$videoClip]);

$timeline = new Timeline();
$timeline->setTracks([$track1, $track2]);

$output = new Output();
$output
->setFormat('mp4')
->setResolution('hd');

$edit = new Edit();
$edit
->setTimeline($timeline)
->setOutput($output);

try {
$response = $client->postRender($edit)->getResponse();
} catch (ApiException $e) {
die('Request failed: ' . $e->getMessage() . $e->getResponseBody());
}

echo $response->getMessage() . "\n";
echo ">> render id: " . $response->getId() . "\n";
?>

Run the PHP watermark video script

Use the command below to the run the watermark.php script in your terminal.

php watermark.php

If the render request is successful, the API will return the render id, which you can use to get the render status. You should see something like this in your terminal.

Render Successfully Queued
>> render id: fe5126e4-a386-4a86-b3c4-7a0b198fb810

Check the render status and output URL

To check the render status, create another script status.php. Copy and paste the code below in the status.php file.

<?php
require 'vendor/autoload.php';

use Shotstack\Client\Api\EditApi;
use Shotstack\Client\Configuration;

$config = Configuration::getDefaultConfiguration()
->setHost('https://api.shotstack.io/stage')
->setApiKey('x-api-key', 'YOUR_API_KEY'); // use your API key

$client = new EditApi(null, $config);
$response = $client->getRender($argv[1], false, true)->getResponse();

echo "\nStatus: " . strtoupper($response->getStatus()) . "\n\n";

if ($response->getStatus() == 'done') {
echo ">> Asset URL: " . $response->getUrl() . "\n";
}
?>

Then run the script using the following command:

php status.php {RENDER_ID}

Replace {RENDER_ID} with the ID returned from running the watermark.php script.

You can run the status.php script every few seconds until the status is DONE and a URL is returned. Then, you will see a result like the one below with the URL of the rendered video.

Status: DONE

>> Asset URL: https://shotstack-api-stage-output.s3-ap-southeast-2.amazonaws.com/3zq6g23nf6/fe5126e4-a386-4a86-b3c4-7a0b198fb810.mp4

With the Asset URL, you can now open and view the watermarked video in your browser or download it.

Batch add watermarks to many videos

You have added a watermark to a single video using the Shotstack PHP SDK. Now, let's see how to scale the process to batch watermark a list of videos. We will use the same watermark image from the single video example.

Below is an array containing a list of URLs for different videos. Replace them with the URLs of your videos. You can also read the URLs from other data sources like a CSV file.

$videoLinks = [
'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'
];

Create a new file called batch.php (or whatever you like). Copy and paste the code below in the file.

It's the same code from the watermark.php script but tweaked slightly. The difference is the foreach loop that runs the code for each of the URL's in the $videoLinks array.

<?php
require 'vendor/autoload.php';

use Shotstack\Client\Api\EditApi;
use Shotstack\Client\Configuration;
use Shotstack\Client\Model\Edit;
use Shotstack\Client\Model\Output;
use Shotstack\Client\Model\Timeline;
use Shotstack\Client\Model\Track;
use Shotstack\Client\Model\Clip;
use Shotstack\Client\Model\VideoAsset;
use Shotstack\Client\Model\ImageAsset;

$config = Configuration::getDefaultConfiguration()
->setHost('https://api.shotstack.io/stage')
->setApiKey('x-api-key', 'YOUR_API_KEY'); // use your API key

$client = new EditApi(null, $config);

$videoLinks = [
'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'
];

foreach ($videoLinks as $link) {
$videoAsset = new VideoAsset();
$videoAsset->setSrc($link);

$videoClip = new Clip();
$videoClip
->setAsset($videoAsset)
->setLength(10)
->setStart(0);

$imageAsset = new ImageAsset();

$imageAsset->setSrc("https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/logos/real-estate-black.png");

$imageClip = new Clip();
$imageClip
->setAsset($imageAsset)
->setStart(0)
->setLength(10.0)
->setScale(0.25)
->setPosition('bottomRight')
->setOpacity(0.3);

$track1 = new Track();
$track1->setClips([$imageClip]);

$track2 = new Track();
$track2->setClips([$videoClip]);

$timeline = new Timeline();
$timeline->setTracks([$track1, $track2]);

$output = new Output();

$output
->setFormat('mp4')
->setResolution('hd');

$edit = new Edit();

$edit
->setTimeline($timeline)
->setOutput($output);

try {
$response = $client->postRender($edit)->getResponse();
} catch (ApiException $e) {
die('Request failed: ' . $e->getMessage() . $e->getResponseBody());
}

echo $response->getMessage() . "\n";
echo ">> render id: " . $response->getId() . "\n";
}
?>

Run the batch watermark script

Use the command below to the run the batch.php script in your terminal.

php batch.php

You should see a list of the rendered IDs like the one below

Render Successfully Queued
>> render id: fe5126e4-a386-4a86-b3c4-7a0b198fb810
Render Successfully Queued
>> render id: f69cdfa7-948e-40f7-9842-01e86fc8b1d5
Render Successfully Queued
>> render id: a027f247-a0cb-4ed2-8b40-02b4f99f549e
Render Successfully Queued
>> render id: 1ee31769-bf52-4560-bd46-43eba5c076bd
Render Successfully Queued
>> render id: 6c40dd0e-08c5-4cb5-aa35-e6f4238fa355

Run the status.php script we created earlier to check the render status:

php status.php {RENDER_ID}

Replace {RENDER_ID} with the IDs returned by the batch.php script.

Wrapping Up

You now know how to add watermark to videos using PHP and the Shotstack API. If you want a quick and easy way to watermark one or a few videos, check out this free watermark tool on our website. But if you're looking for a scalable way to handle the process of watermarking loads of videos, this tutorial has got you covered.

You should also check out our developer guides and documentation to learn more about video automation, building media applications, and other relevant topics.

Emad Bin Abid

BY EMAD BIN ABID
17th March, 2024

Become an Automated Video Editing Pro

Every month we share articles like this one to keep you up to speed with automated video editing.


You might also like

Convert MP4 video to GIF using PHP

Convert MP4 video to GIF using PHP

Emad Bin Abid
Convert MP4 video to MP3 audio using PHP

Convert MP4 video to MP3 audio using PHP

Emad Bin Abid