Jump to content

Mastering video watermarks in KVS


Recommended Posts

In KVS you can define watermark image for each video format in Settings -> Video formats. Typically this is PNG image with some transparency and your site logo / name.

 

How to make sure that watermark is stable for all video formats

Since in most cases videos are provided in multiple formats, there is a common problem of watermark scaling. For example, consider a video file that is only 800px in width and the one that is 1920px in width. If your screen size is 1920px also, the first video file will be upscaled 2.5 times when displaying on full screen, while the last file won't be scaled at all. How do you decide which size watermark image should be rendered for each of this format, so that it remain stable size whether user is watching 800px format or 1920px one?

The solution is very simple - you should upload watermark image with a big size in all formats, but configure it to take only specific % of video size. There are special options in video format settings:

watermark_max_width.thumb.png.7fd1db828ad9fed3c6fb9ff47e34270d.png

Having this set to 20% in all your video formats you will make sure despite of user chosen display format and user screen size the watermark will always be scaled to 20% of screen width.

NOTE: we are not recommending using 20% and 40% values, this is something that you should decide yourself. And this is correct that max width for vertical videos is bigger than for landscape - their width in pixels is smaller.

NOTE: KVS supports 2 different watermarks at the same time. Please note that for watermark #2 you specify max height, not width. This is on purpose for cases when you want to display running text; in some cases text length can be bigger than video file width, so in order to resize it correctly you will need to adjust max height for it.

 

Running texts

KVS allows showing running texts together with normal watermark images. We recommend using Watermark #2 for running text and Watermark for normal images. Running text should be still uploaded as image, e.g. you should first use image editor and create a text of your wish on transparent background; then save it into PNG and upload PNG into KVS.

Then as a Watermark position you should select Top scrolling, or Bottom scrolling. These choices will show several more options where you configure scrolling speed and video positions when scrolling starts. This screenshot defines a scrolling watermark at bottom that will appear 3 times per video: on 10% duration, on 50% and on 90%. Watermark will be visible for 20 seconds, and this defines how fast it will scroll by dividing video width per watermark width:

watermark_scrolling.thumb.png.69755ed81f891f936876beec0e4bd6da.png

NOTE: it was configured that watermark takes max 5% of video height for landscape videos and max 3% of video height for portrait videos in order to make its size consistent across all formats and devices.

 

Rendering customized watermarks

If you want to apply different watermarks for different videos, one of the possible ways is to use custom fields of content sources to provide different watermark images for videos from different content sources. In order to use this approach, you should have well defined way of adding / importing videos with content source for each video that needs custom watermarks. The idea is each content source can define its custom watermark image and all videos that are tagged with this content source will be converted with this custom watermark image.

In order to configure this approach, you should first go to Settings -> Customization and enable any available custom file field for content sources. Once enabled, go to each video format settings and select the activated custom field in Customize watermark for content sources field:

watermark_customization_content_source.png.45d90e28e65b3915d7a719c9b0905f51.png

After that you should go to each content source for which videos you want to customize watermark image and upload a custom image into Custom watermark field. Now, all videos that are created or imported with this content source, will have this custom watermark image.

If you want to programmatically generate watermarks (e.g. type username who uploaded this video, or any other custom text which can be different), you can create custom PHP script providing hook method for KVS to use custom watermark image.

The script should be put into /admin/include/kvs_watermark_video.php

Here is sample script implementation, which creates watermark image with the following text: Uploaded by <username>

<?php

function kvs_watermark_video($format_postfix, $video_data)
{
   global $config;

   // here you should create and return image path with your custom watermark text
   // this file will be deleted, so you need to create it each time

   // check $format_postfix if you need watermark to be limited to specific formats only, e.g.
   // if ($format_postfix == '.mp4' || $format_postfix == 'trailer.mp4')

   // for example you can query user data and render "uploaded by <username>" watermark
   $user_data = mr2array_single(sql_pr("select * from $config[tables_prefix]users where user_id=?", $video_data['user_id']));
   if ($user_data['user_id'] > 0)
   {
       $watermark_file = "$config[temporary_path]/custom_watermark.png";

       // settings: text, font, size and offset
       $watermark_text = "Uploaded by $user_data[display_name]";
       $font = "$config[project_path]/admin/data/system/verdanaz.ttf";
       $font_size = 10;
       $offset = 20;

       // rendering logic
       $box = imagettfbbox($font_size, 0, $font, $watermark_text);

       $im = imagecreatetruecolor(abs($box[2] - $box[0]) + 2 * $offset, abs($box[7] - $box[1]) + 2 * $offset);
       imagealphablending($im, false);
       imagefilledrectangle($im, 0, 0, abs($box[2] - $box[0]) + 2 * $offset, abs($box[7] - $box[1]) + 2 * $offset, imagecolorallocatealpha($im, 0, 0, 0, 127));
       imagealphablending($im, true);

       imagettftext($im, $font_size, 0, abs($box[0]) + $offset, abs($box[5]) + $offset, imagecolorallocate($im, 255, 255, 255), $font, $watermark_text);

       // save image to temp file
       imagesavealpha($im, true);
       imagepng($im, $watermark_file);
       imagedestroy($im);

       // return temp file back to KVS engine
       return $watermark_file;
   }
   return null;
}

 

If you need similar functionality (just plain text with custom wording), you can copy-paste this code and modify only these lines:

$watermark_text = "Uploaded by $user_data[display_name]"; // text will render "Uploaded by <username>"
$font = "$config[project_path]/admin/data/system/verdanaz.ttf"; // this font comes with KVS for captcha rendering, but you can use any other TTF font
$font_size = 10; // text size
$offset = 20; // offset from video edges, means 20 pixels from corner

 

Here is a sample watermark created by this code. You can see that the font is a bit specific, so you should better use other font: custom_watermark.png.8c8577ab1f3baa3823aecc6b761c094a.png

Some notes:

  • Please do not replace KVS font file with your custom font, or captcha functionality may not work correctly. If you want to use custom font, you can put it near by and correct font filename in the code.
  • This watermark will be applied to all video formats that are created by KVS. If you want to limit it to specific video format, you need to add "if" check on the $format_postfix value passed to this function and return null for formats where watermark is not needed.
  • The position of watermark will still be controlled by the Watermark position option of video format settings. By default it is set to Random, so if you don't change it then watermark will be positioned at random corner of the video.

 

Testing watermark function

You can test your watermark function by executing test_watermark.php script from your browser:

http://yourdomain.com/test_watermark.php

Here is code for test script:

<?php

require_once('admin/include/setup.php');
require_once('admin/include/setup_db.php');
require_once('admin/include/functions_base.php');
require_once('admin/include/functions.php');

error_reporting(E_ALL ^ E_NOTICE);
ini_set('display_errors', 1);

require_once('admin/include/kvs_watermark_video.php');

$video = mr2array_single(sql("select * from ktvs_videos order by rand() limit 1"));
$path = kvs_watermark_video(".mp4", $video);
if ($path)
{
   header("Content-Type: image/png");
   readfile($path);
}

Running this file will show you a watermark image created for random video and video format with ".mp4" postfix. If you want to test your code for another postfix, then change ".mp4" with another postfix you need.

  • Like 1
Link to comment
Share on other sites

  • Tech Support changed the title to Mastering video watermarks in KVS
  • 3 months later...

Another example: how to show watermark from a custom file of video channel. Unlike with content sources, there is no way to customize watermark via format settings. So if you want to render custom watermark image from a specific channel custom file, please use this custom watermark function:

<?php

function kvs_watermark_video($format_postfix, $video_data)
{
   global $config;

   // change custom file # if you plan to store watermark images in another file field

   $custom_file_field = 'custom_file1';
   $dvd_data = mr2array_single(sql_pr("select * from $config[tables_prefix]dvds where dvd_id=?", $video_data['dvd_id']));
   if ($dvd_data['dvd_id'] > 0 && $dvd_data[$custom_file_field])
   {
       $rnd = mt_rand(1000000, 9999999);
       $watermark_file = "$config[temporary_path]/$rnd.png";

       copy("$config[content_path_dvds]/$dvd_data[dvd_id]/$dvd_data[$custom_file_field]", $watermark_file);

       // return temp file back to KVS engine
       return $watermark_file;
   }

   return null;
}

 

  • Like 2
Link to comment
Share on other sites

  • 2 years later...

This can be done. In video format settings you need to upload some "default" image for each watermark and set other options that you want (position, offset and etc). Then you can use these customization scripts to customize both watermarks. The first watermark is customized by the above kvs_watermark_video.php script.

The 2nd watermark script is called kvs_watermark2_video.php, and its function name should be changed to kvs_watermark2_video as well.

  • Like 1
Link to comment
Share on other sites

11 hours ago, Tech Support said:

This can be done. In video format settings you need to upload some "default" image for each watermark and set other options that you want (position, offset and etc). Then you can use these customization scripts to customize both watermarks. The first watermark is customized by the above kvs_watermark_video.php script.

The 2nd watermark script is called kvs_watermark2_video.php, and its function name should be changed to kvs_watermark2_video as well.

I tried, I can't make it work

I did set "Customize watermark for content sources" for both of it

image.png.380dde7470c16d135cf2e3cd8232276e.png

Watermark (1) I chose my logo image, watermark2 I leave it empty because (I think) it generates text (uploaded by {{user}}) from kvs_watermark_video.php

And I copied 2 files like this to /admin/include/

image.png.2150010669e218528c012f1cf2e1c792.png

Its code like yours above

<?php

function kvs_watermark_video($format_postfix, $video_data)
{
   global $config;

   // here you should create and return image path with your custom watermark text
   // this file will be deleted, so you need to create it each time

   // check $format_postfix if you need watermark to be limited to specific formats only, e.g.
   // if ($format_postfix == '.mp4' || $format_postfix == 'trailer.mp4')

   // for example you can query user data and render "uploaded by <username>" watermark
   $user_data = mr2array_single(sql_pr("select * from $config[tables_prefix]users where user_id=?", $video_data['user_id']));
   if ($user_data['user_id'] > 0)
   {
       $watermark_file = "$config[temporary_path]/custom_watermark.png";

       // settings: text, font, size and offset
       $watermark_text = "This video was uploaded by $user_data[display_name] to XaTinh.com";
       $font = "$config[project_path]/admin/data/system/verdanab.ttf";
       $font_size = 10;
       $offset = 20;

       // rendering logic
       $box = imagettfbbox($font_size, 0, $font, $watermark_text);

       $im = imagecreatetruecolor(abs($box[2] - $box[0]) + 2 * $offset, abs($box[7] - $box[1]) + 2 * $offset);
       imagealphablending($im, false);
       imagefilledrectangle($im, 0, 0, abs($box[2] - $box[0]) + 2 * $offset, abs($box[7] - $box[1]) + 2 * $offset, imagecolorallocatealpha($im, 0, 0, 0, 127));
       imagealphablending($im, true);

       imagettftext($im, $font_size, 0, abs($box[0]) + $offset, abs($box[5]) + $offset, imagecolorallocate($im, 255, 255, 255), $font, $watermark_text);

       // save image to temp file
       imagesavealpha($im, true);
       imagepng($im, $watermark_file);
       imagedestroy($im);

       // return temp file back to KVS engine
       return $watermark_file;
   }
   return null;
}

Second kvs_watermark2_video.php

<?php

function kvs_watermark2_video($format_postfix, $video_data)
{
   global $config;

   // here you should create and return image path with your custom watermark text
   // this file will be deleted, so you need to create it each time

   // check $format_postfix if you need watermark to be limited to specific formats only, e.g.
   // if ($format_postfix == '.mp4' || $format_postfix == 'trailer.mp4')

   // for example you can query user data and render "uploaded by <username>" watermark
   $user_data = mr2array_single(sql_pr("select * from $config[tables_prefix]users where user_id=?", $video_data['user_id']));
   if ($user_data['user_id'] > 0)
   {
       $watermark_file = "$config[temporary_path]/custom_watermark.png";

       // settings: text, font, size and offset
       $watermark_text = "This video was uploaded by $user_data[display_name] to xatinh.com";
       $font = "$config[project_path]/admin/data/system/verdanab.ttf";
       $font_size = 10;
       $offset = 20;

       // rendering logic
       $box = imagettfbbox($font_size, 0, $font, $watermark_text);

       $im = imagecreatetruecolor(abs($box[2] - $box[0]) + 2 * $offset, abs($box[7] - $box[1]) + 2 * $offset);
       imagealphablending($im, false);
       imagefilledrectangle($im, 0, 0, abs($box[2] - $box[0]) + 2 * $offset, abs($box[7] - $box[1]) + 2 * $offset, imagecolorallocatealpha($im, 0, 0, 0, 127));
       imagealphablending($im, true);

       imagettftext($im, $font_size, 0, abs($box[0]) + $offset, abs($box[5]) + $offset, imagecolorallocate($im, 255, 255, 255), $font, $watermark_text);

       // save image to temp file
       imagesavealpha($im, true);
       imagepng($im, $watermark_file);
       imagedestroy($im);

       // return temp file back to KVS engine
       return $watermark_file;
   }
   return null;
}

 

I only set watermark in 480p video format but it also watermark-ed in preview mode and other videos format even though I didn't set anything at all

image.png.98ecd0c00258c6e0fb34b9a8308fae3e.png

 

Could you please specific more how to do it?

I'm appreciate your time and your support

Link to comment
Share on other sites

Update: I did it, but like I said above, I only set watermark in 480p video format but it also watermark-ed in preview mode and other videos format even though I didn't set anything at all (attached picture above)

Another (small) issue is the scrolling text is not smooth in 480p mode, it's like running at 10-15 fps (nothing wrong with video), is this fixable ?

 

Link to comment
Share on other sites

9 hours ago, Tanjiro said:

Update: I did it, but like I said above, I only set watermark in 480p video format but it also watermark-ed in preview mode and other videos format even though I didn't set anything at all (attached picture above)

This function is called for all video formats, but as you can see a format postfix is passed to it as a first parameter.

You can check it and switch off for some formats, e.g. for preview format:

if ($format_postfix == '_preview.mp4')
{
	// do not show this waternakr for preview format
	return null;
}

 

9 hours ago, Tanjiro said:

Another (small) issue is the scrolling text is not smooth in 480p mode, it's like running at 10-15 fps (nothing wrong with video), is this fixable ?

I guess this depends on speed (scrolling duration) and the length of watermark. The longer watermark is and the shorter scrolling duration, it will move faster. So you probably need to increase the duration.

  • Like 1
Link to comment
Share on other sites

  • 6 months later...

How to set font size based on resolution?

$font size = 10; // font size

I want to change it to $font_size = $video_height * 0.02;

But this $video_height function cannot be obtained.

 

Link to comment
Share on other sites

The video height is not known at this point and makes no sense to adjust font based on it. The watermark image should be the same for all video sizes, but then you should specify Watermark max width field in video format settings to make sure it will be resized to the same visual height.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...