Adding Video Watermark as an Overlay

Adding Watermarks (Static Images, Animated GIFs, and Videos) to Videos

Adding watermarks to videos on Cloudinary yields many enhancements, involving only a few simple steps. The sections below describe the various scenarios along with examples.

Images Overlayed Onto Videos

With Cloudinary, you can add a watermark as an overlay on top of a video with the overlay parameter. Simply set overlay (l in the URL) as your watermark’s public ID. You can also customize the overlaid image's size and position, offset, color effects, opacity, and other properties.

As mentioned in the article, Adding Watermarks as an Overlay, you can easily add watermarks to videos as well. Watermarks and overlays are ideal for displaying logos, price tags, discounts, custom badges, and so forth. Take this video:

Ruby:
cl_video_tag("celenarae")
PHP:
cl_video_tag("celenarae")
Python:
CloudinaryVideo("celenarae").video()
Node.js:
cloudinary.video("celenarae")
Java:
cloudinary.url().videoTag("celenarae");
JS:
cloudinary.videoTag('celenarae').toHtml();
jQuery:
$.cloudinary.video("celenarae")
React:
<Video publicId="celenarae" >

</Video>
Angular:
<cl-video public-id="celenarae" >

</cl-video>
.Net:
cloudinary.Api.UrlVideoUp.BuildVideoTag("celenarae")
Android:
MediaManager.get().url().resourceType("video").generate("celenarae.mp4");
iOS:
cloudinary.createUrl().setResourceType("video").generate("celenarae.mp4")

Here’s how it looks with a Cloudinary logo called cloudlogo2 on top :

Ruby:
cl_video_tag("celenarae", :overlay=>"cloudlogo2")
PHP:
cl_video_tag("celenarae", array("overlay"=>"cloudlogo2"))
Python:
CloudinaryVideo("celenarae").video(overlay="cloudlogo2")
Node.js:
cloudinary.video("celenarae", {overlay: "cloudlogo2"})
Java:
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("cloudlogo2"))).videoTag("celenarae");
JS:
cloudinary.videoTag('celenarae', {overlay: new cloudinary.Layer().publicId("cloudlogo2")}).toHtml();
jQuery:
$.cloudinary.video("celenarae", {overlay: new cloudinary.Layer().publicId("cloudlogo2")})
React:
<Video publicId="celenarae" >
  <Transformation overlay="cloudlogo2" />
</Video>
Angular:
<cl-video public-id="celenarae" >
  <cl-transformation overlay="cloudlogo2">
  </cl-transformation>
</cl-video>
.Net:
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("cloudlogo2"))).BuildVideoTag("celenarae")
Android:
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("cloudlogo2"))).resourceType("video").generate("celenarae.mp4");
iOS:
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("cloudlogo2")).generate("celenarae.mp4")
You can adjust the logo’s size, its position, its distance from the edges, and the transparency. See this example:
Ruby:
cl_video_tag("celenarae", :overlay=>"cloudlogo2", :width=>200, :gravity=>"north_east", :x=>5, :y=>5, :opacity=>40)
PHP:
cl_video_tag("celenarae", array("overlay"=>"cloudlogo2", "width"=>200, "gravity"=>"north_east", "x"=>5, "y"=>5, "opacity"=>40))
Python:
CloudinaryVideo("celenarae").video(overlay="cloudlogo2", width=200, gravity="north_east", x=5, y=5, opacity=40)
Node.js:
cloudinary.video("celenarae", {overlay: "cloudlogo2", width: 200, gravity: "north_east", x: 5, y: 5, opacity: 40})
Java:
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("cloudlogo2")).width(200).gravity("north_east").x(5).y(5).opacity(40)).videoTag("celenarae");
JS:
cloudinary.videoTag('celenarae', {overlay: new cloudinary.Layer().publicId("cloudlogo2"), width: 200, gravity: "north_east", x: 5, y: 5, opacity: 40}).toHtml();
jQuery:
$.cloudinary.video("celenarae", {overlay: new cloudinary.Layer().publicId("cloudlogo2"), width: 200, gravity: "north_east", x: 5, y: 5, opacity: 40})
React:
<Video publicId="celenarae" >
  <Transformation overlay="cloudlogo2" width="200" gravity="north_east" x="5" y="5" opacity="40" />
</Video>
Angular:
<cl-video public-id="celenarae" >
  <cl-transformation overlay="cloudlogo2" width="200" gravity="north_east" x="5" y="5" opacity="40">
  </cl-transformation>
</cl-video>
.Net:
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("cloudlogo2")).Width(200).Gravity("north_east").X(5).Y(5).Opacity(40)).BuildVideoTag("celenarae")
Android:
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("cloudlogo2")).width(200).gravity("north_east").x(5).y(5).opacity(40)).resourceType("video").generate("celenarae.mp4");
iOS:
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("cloudlogo2").setWidth(200).setGravity("north_east").setX(5).setY(5).setOpacity(40)).generate("celenarae.mp4")

Animated GIFs Overlayed Onto Videos

One way to boost the visual effect of videos is to , watermark them with animated GIFs. Think here the animations on live television with “Breaking News” or a spinning logo of the broadcasting network. The process involves replacing the logo reference cloudlogo2 with a transparent, animated GIF and introducing a loop effect (with the parameter e_loop) that causes the animated GIF to spin for the entire duration of the video, not just its initial number of frames. For details on the loop effect, see this Cloudinary product update. Also, you can eliminate opacity control by setting the o parameter with GIFs.

Ruby:
cl_video_tag("celenarae", :overlay=>"comodo", :gravity=>"south_east", :effect=>"loop")
PHP:
cl_video_tag("celenarae", array("overlay"=>"comodo", "gravity"=>"south_east", "effect"=>"loop"))
Python:
CloudinaryVideo("celenarae").video(overlay="comodo", gravity="south_east", effect="loop")
Node.js:
cloudinary.video("celenarae", {overlay: "comodo", gravity: "south_east", effect: "loop"})
Java:
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("comodo")).gravity("south_east").effect("loop")).videoTag("celenarae");
JS:
cloudinary.videoTag('celenarae', {overlay: new cloudinary.Layer().publicId("comodo"), gravity: "south_east", effect: "loop"}).toHtml();
jQuery:
$.cloudinary.video("celenarae", {overlay: new cloudinary.Layer().publicId("comodo"), gravity: "south_east", effect: "loop"})
React:
<Video publicId="celenarae" >
  <Transformation overlay="comodo" gravity="south_east" effect="loop" />
</Video>
Angular:
<cl-video public-id="celenarae" >
  <cl-transformation overlay="comodo" gravity="south_east" effect="loop">
  </cl-transformation>
</cl-video>
.Net:
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("comodo")).Gravity("south_east").Effect("loop")).BuildVideoTag("celenarae")
Android:
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("comodo")).gravity("south_east").effect("loop")).resourceType("video").generate("celenarae.mp4");
iOS:
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("comodo").setGravity("south_east").setEffect("loop")).generate("celenarae.mp4")

Here is another example:

Ruby:
cl_video_tag("celenarae", :overlay=>"USflag", :width=>200, :gravity=>"north_east", :x=>5, :y=>5)
PHP:
cl_video_tag("celenarae", array("overlay"=>"USflag", "width"=>200, "gravity"=>"north_east", "x"=>5, "y"=>5))
Python:
CloudinaryVideo("celenarae").video(overlay="USflag", width=200, gravity="north_east", x=5, y=5)
Node.js:
cloudinary.video("celenarae", {overlay: "USflag", width: 200, gravity: "north_east", x: 5, y: 5})
Java:
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("USflag")).width(200).gravity("north_east").x(5).y(5)).videoTag("celenarae");
JS:
cloudinary.videoTag('celenarae', {overlay: new cloudinary.Layer().publicId("USflag"), width: 200, gravity: "north_east", x: 5, y: 5}).toHtml();
jQuery:
$.cloudinary.video("celenarae", {overlay: new cloudinary.Layer().publicId("USflag"), width: 200, gravity: "north_east", x: 5, y: 5})
React:
<Video publicId="celenarae" >
  <Transformation overlay="USflag" width="200" gravity="north_east" x="5" y="5" />
</Video>
Angular:
<cl-video public-id="celenarae" >
  <cl-transformation overlay="USflag" width="200" gravity="north_east" x="5" y="5">
  </cl-transformation>
</cl-video>
.Net:
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("USflag")).Width(200).Gravity("north_east").X(5).Y(5)).BuildVideoTag("celenarae")
Android:
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("USflag")).width(200).gravity("north_east").x(5).y(5)).resourceType("video").generate("celenarae.mp4");
iOS:
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("USflag").setWidth(200).setGravity("north_east").setX(5).setY(5)).generate("celenarae.mp4")

Videos Overlayed Onto Videos

You can actually overlay videos onto other videos. Isn’t that cool? First, add a video watermark by setting the overlay parameter (l_video in the URL) as your video’s public ID. The example below shows how you can control the watermark’s size and position, as demonstrated earlier, also the duration of the overlayed video, the starting offset, and such.

As an interesting use case, add American Sign Language (ASL or others) to a video or presentation to support deaf communities in English-speaking countries. In the U. S. A. alone, that community numbers as high as 15 million. In the U. K., ASL or its equivalent, British Sign Language (BSL), can also be instrumental in communicating with autism-afflicted children and adults. Similarly, as described in this article, you can embed subtitles generated by Cloudinary with your videos .

Ruby:
cl_video_tag("celenarae", :transformation=>[
  {:overlay=>"video:asltranslation", :width=>0.3, :height=>0.3, :radius=>20, :start_offset=>"5.8", :audio_codec=>"none"},
  {:gravity=>"south_east", :x=>0.2, :y=>0.2, :flags=>"layer_apply"}
  ])
PHP:
cl_video_tag("celenarae", array("transformation"=>array(
  array("overlay"=>"video:asltranslation", "width"=>0.3, "height"=>0.3, "radius"=>20, "start_offset"=>"5.8", "audio_codec"=>"none"),
  array("gravity"=>"south_east", "x"=>0.2, "y"=>0.2, "flags"=>"layer_apply")
  )))
Python:
CloudinaryVideo("celenarae").video(transformation=[
  {'overlay': "video:asltranslation", 'width': 0.3, 'height': 0.3, 'radius': 20, 'start_offset': "5.8", 'audio_codec': "none"},
  {'gravity': "south_east", 'x': 0.2, 'y': 0.2, 'flags': "layer_apply"}
  ])
Node.js:
cloudinary.video("celenarae", {transformation: [
  {overlay: "video:asltranslation", width: "0.3", height: "0.3", radius: 20, start_offset: "5.8", audio_codec: "none"},
  {gravity: "south_east", x: "0.2", y: "0.2", flags: "layer_apply"}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .overlay(new Layer().publicId("video:asltranslation")).width(0.3).height(0.3).radius(20).startOffset("5.8").audioCodec("none").chain()
  .gravity("south_east").x(0.2).y(0.2).flags("layer_apply")).videoTag("celenarae");
JS:
cloudinary.videoTag('celenarae', {transformation: [
  {overlay: new cloudinary.Layer().publicId("video:asltranslation"), width: "0.3", height: "0.3", radius: 20, startOffset: "5.8", audioCodec: "none"},
  {gravity: "south_east", x: "0.2", y: "0.2", flags: "layer_apply"}
  ]}).toHtml();
jQuery:
$.cloudinary.video("celenarae", {transformation: [
  {overlay: new cloudinary.Layer().publicId("video:asltranslation"), width: "0.3", height: "0.3", radius: 20, start_offset: "5.8", audio_codec: "none"},
  {gravity: "south_east", x: "0.2", y: "0.2", flags: "layer_apply"}
  ]})
React:
<Video publicId="celenarae" >
  <Transformation overlay="video:asltranslation" width="0.3" height="0.3" radius="20" startOffset="5.8" audioCodec="none" />
  <Transformation gravity="south_east" x="0.2" y="0.2" flags="layer_apply" />
</Video>
Angular:
<cl-video public-id="celenarae" >
  <cl-transformation overlay="video:asltranslation" width="0.3" height="0.3" radius="20" start-offset="5.8" audio-codec="none">
  </cl-transformation>
  <cl-transformation gravity="south_east" x="0.2" y="0.2" flags="layer_apply">
  </cl-transformation>
</cl-video>
.Net:
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Overlay(new Layer().PublicId("video:asltranslation")).Width(0.3).Height(0.3).Radius(20).StartOffset("5.8").AudioCodec("none").Chain()
  .Gravity("south_east").X(0.2).Y(0.2).Flags("layer_apply")).BuildVideoTag("celenarae")
Android:
MediaManager.get().url().transformation(new Transformation()
  .overlay(new Layer().publicId("video:asltranslation")).width(0.3).height(0.3).radius(20).startOffset("5.8").audioCodec("none").chain()
  .gravity("south_east").x(0.2).y(0.2).flags("layer_apply")).resourceType("video").generate("celenarae.mp4");
iOS:
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setOverlay("video:asltranslation").setWidth(0.3).setHeight(0.3).setRadius(20).setStartOffset("5.8").setAudioCodec("none").chain()
  .setGravity("south_east").setX(0.2).setY(0.2).setFlags("layer_apply")).generate("celenarae.mp4")
In the example above:

  • The size of the overlaid ASL video is represented in percentages, not pixels, with the setting w_0.30.
  • The corners of the video are rounded due to the settings for radius control (r) and for the number of degrees (20).
  • Because the two videos are similar but of different lengths, the audio channel is disabled with ac_none, the timeline of the overlay is corrected with start offset (so), and the number of seconds to skip from the beginning is set at 5.8. Another use case for overlaying a video onto another is to show both the speaker and the intended keynote PowerPoint presentation. No need for sophisticated video editors or time-sensitive events, such as conferences. For more information and examples of watermark embedding and manipulation by Cloudinary, see these two blog posts:

  • Image Opacity Manipulation and Dynamic Watermark Generation.

  • Adding Watermarks, Credits, Badges, and Text Overlays to Images

by George Bontea