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;
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.
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
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 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;
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.
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.
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.
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;
$imageClip = new Clip();
$imageClip
-> setAsset($imageAsset)
-> setStart(0)
-> setLength(10.0)
-> setScale(0.25)
-> setPosition('bottomRight')
-> setOpacity(0.3);
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]);
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.
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);
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";
?>
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";
?>
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
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.
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";
}
?>
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.
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.
curl --request POST 'https://api.shotstack.io/v1/render' \
--header 'x-api-key: YOUR_API_KEY' \
--data-raw '{
"timeline": {
"tracks": [
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3.amazonaws.com/footage/beach-overhead.mp4"
},
"start": 0,
"length": "auto"
}
]
}
]
},
"output": {
"format": "mp4",
"size": {
"width": 1280,
"height": 720
}
}
}'