Video transformations

Cloudinary is a cloud-based service that provides an end-to-end media management solution for images and videos, including upload, storage, administration, manipulation, optimization and delivery.

Using Cloudinary's comprehensive API and easy to use manipulation URLs, uploaded videos can be automatically transcoded to all relevant formats suitable for web viewing, optimized for web browsers and mobile devices, and normalized and manipulated in real time to fit your graphic design. The videos can be easily embedded in your website using HTML5 video tags (or Flash) and then streamed to your users via a fast CDN. Get the most out of all the video functionality described on this page by embedding your videos using Cloudinary's video player.

The Video Transformation Reference summarizes all parameters available for manipulating videos as well as video transformation flags that adjust the default behavior of certain transformations.

Note
Your account's pricing plan is in part dependent on the total number of transformation operations performed during a billing cycle. These are primarily counted when Cloudinary generates a new 'derived resource' from an asset based on a transformation URL. For complete details on how transformations are counted, see Transformation Counts.

On-the-fly video encoding and delivery

You deliver video using Cloudinary HTTP or HTTPS URLs. You can add transformations to any Cloudinary URL and deliver your video, encoded to the specified format, on-the-fly. Multiple users can then stream the video even while it is being encoded and delivered via CDN. You can also deliver videos that were encoded in advance with eager or explicit transformations. Furthermore Cloudinary supports HTTP progressive download for media players capable of progressive download playback.

Video URL structure

The Public ID is the unique identifier of the video, and is either specified when uploading the video to your Cloudinary account, or automatically assigned by Cloudinary. For more details on the options for specifying the public ID, see Public ID - the image identifier.

A basic video delivery URL takes the following structure:

https://res.cloudinary.com/<cloud name>/video/upload/<public ID>.<video format file extension>

For example, here's how you would deliver a video from Cloudinary’s demo account with a public ID of dog in mp4 format:

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

</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >

</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >

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

Manipulation (transformation) instructions are added in the delivery URL before the public ID. The video delivery URL with transformation parameters takes the following structure:

https://res.cloudinary.com/<cloud name>/video/upload/<manipulation parameters>/<public ID>.<video format file extension>

An example of a URL with video manipulation, where dog video is cropped to a width of 300 pixels and a height of 200 pixels, and encoded to mp4 format:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>300, :height=>200, :crop=>"crop")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>300, "height"=>200, "crop"=>"crop"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=300, height=200, crop="crop")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 300, height: 200, crop: "crop"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).height(200).crop("crop")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 300, height: 200, crop: "crop"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 300, height: 200, crop: "crop"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" height="200" crop="crop" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" height="200" crop="crop" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" height="200" crop="crop">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Height(200).Crop("crop")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).height(200).crop("crop")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setHeight(200).setCrop("crop")).generate("dog.mp4")

Notes

  • For details about other potential elements of the delivery URL, see Delivering media assets using dynamic URLs
  • You can deliver the video in other supported video formats by simply changing the video format file extension. For details, see Transcoding video to other formats.
  • You can append an SEO-friendly suffix to your URL by replacing the video/upload element of the URL with /videos and then appending the desired suffix with a slash (/) after the public ID. For example, if you have an instructional cooking video with a random public ID like: abc1def2, you can deliver your video as:
    https://res.cloudinary.com/<cloud name>/videos/abc1def2/my_cooking_video.mp4.
    For more details, see Dynamic SEO suffixes.
  • For customers with a Custom Domain Name (CNAME - available for Cloudinary's Advanced plan and above), the video delivery URL becomes: https://<custom domain name>/video/upload/<public ID>.<video format file extension>

Embedding videos in web pages

Cloudinary's video player is a JavaScript-based HTML5 video player bundled with many valuable customization and integration capabilities. If you use this video player to embed your videos, you'll define the source video or the playlist for your player as part of that process, and the video tags with all relevant video formats and other relevant settings are automatically generated. For details, see Video Player.

The easiest way to embed videos in your page without the Cloudinary video player is by using the video tag helper method available in the Cloudinary SDKs (e.g. cl_video_tag in Ruby on Rails). This method automatically generates an HTML5 video tag including the video source URLs of all relevant formats supported by web browsers (webm, mp4 and ogv), as well as a poster thumbnail image. The browser then automatically selects the video format it supports, while the video files are created dynamically and immediately streamed when first accessed by your users.

You can optionally control the generation of the HTML5 video tag and specify transformation parameters to manipulate the video to match your graphic design. The video tag helper method uses the following structure:

Copy to clipboard
cl_video_tag(public_id, options = {})

public_id: (required) the unique identifier of the uploaded video.

Where possible options are:

  • source_types: an ordered array of the video source types to include in the HTML5 tag, where the type is mapped to the mime type. Default: ['webm', 'mp4', 'ogv']
  • manipulation params: the manipulation(s) to carry out on the video, such as cropping, resizing, etc (see the Video transformations reference table for more details on possible parameters and values)
  • source_transformation: to override the default transformation instructions for each specific video format. The source_type is mapped to a transformation struct. e.g., { mp4: { quality: 70}}
  • poster: a URI to an image to be shown while the video is downloading or until the user hits the play button. The URI can be one of the following:
    • The URL to an image.
    • A struct including the transformations to apply to the default image (you can include the public_id of an uploaded image to use instead of the default image).
    • Set to nil or false to use no poster.
    • Default: the middle frame of the source video in jpg format.
  • fallback_content: an HTML string to display in the case that the browser does not support any of the video formats included.
  • Any attribute of the HTML5 video tag. e.g., autoplay, controls, height, loop, muted, preload (see w3schools for details on HTML5 attributes).
  • version: the asset version that is added to the delivery URL as explained in Asset versions.
  • Any Configuration parameters. Configuration parameters that you specify in the video tag override any that you have set globally.

Example 1: Simply creating an HTML5 video tag for the uploaded mp4 video named dog:

Ruby:
Copy to clipboard
cl_video_tag("dog")
PHP:
Copy to clipboard
<?php echo cl_video_tag("dog"); ?>
Python:
Copy to clipboard
cloudinary.CloudinaryVideo("dog").video()
Node.js:
Copy to clipboard
cloudinary.video("dog")
Java:
Copy to clipboard
<cl:video src="dog"/>

Generates the following HTML5 video tag:

Copy to clipboard
<video poster="https://res.cloudinary.com/demo/video/upload/dog.jpg">
  <source src="https://res.cloudinary.com/demo/video/upload/dog.webm" type="video/webm"/>
  <source src="https://res.cloudinary.com/demo/video/upload/dog.mp4" type="video/mp4"/>
  <source src="https://res.cloudinary.com/demo/video/upload/dog.ogv" type="video/ogg"/>
</video>

Example 2: Creating an HTML5 video tag for the uploaded mp4 video named dog, where the video is resized to a width of 300 pixels, a height of 300 pixels, padded with a blue background to fill the new dimensions, given a fallback string in the case that the video tag is not supported, specified that controls should be displayed and that the file should not be preloaded:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width => 300, :height => 300, 
  :crop => :pad, :background => "blue", 
  :preload => "none", :controls => true,
  :fallback_content => "Your browser does not support HTML5 video tags" )
PHP:
Copy to clipboard
<?php echo cl_video_tag("dog", 
  array("width" => 300, "height" => 300, 
    "crop" => "pad", "background" => "blue", 
    "preload" => "none", "controls" => true,
    "fallback_content" => "Your browser does not support HTML5 video tags")); ?>
Python:
Copy to clipboard
cloudinary.CloudinaryVideo("dog").video( 
  width = 300, height = 300, 
  crop = "pad", background = "blue", 
  preload = "none", controls = True,
  fallback_content = "Your browser does not support HTML5 video tags")
Node.js:
Copy to clipboard
cloudinary.video("dog" { width: 300, height: 300, 
  crop: "pad", background: "blue", 
  preload: "none", controls: true,
  fallback_content: "Your browser does not support HTML5 video tags" })
Java:
Copy to clipboard
<cl:video src="dog" width = "300", height = "300", 
  crop = "pad", background = "blue", 
  preload = "none", controls = "true",
  fallback_content = "Your browser does not support HTML5 video tags"/>

Generates the following HTML5 video tag:

Copy to clipboard
<video poster="https://res.cloudinary.com/demo/video/upload/dog.jpg" preload="none" controls>
  <source src="https://res.cloudinary.com/demo/video/upload/w_300,h_300,c_pad,b_blue/dog.webm" type="video/webm"/>
  <source src="https://res.cloudinary.com/demo/video/upload/w_300,h_300,c_pad,b_blue/dog.mp4" type="video/mp4"/>
  <source src="https://res.cloudinary.com/demo/video/upload/w_300,h_300,c_pad,b_blue/dog.ogv" type="video/ogg"/>
   Your browser does not support HTML5 video tags
</video>

Example 3: Creating an HTML5 video tag for the uploaded mp4 video named dog, where the video is cropped to a width of 200 pixels and a height of 150 pixels, given a fallback string in the case that the video tag is not supported, not to use a poster image and that the file should autoplay in a loop:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width => 200, :height => 150, :crop => :crop,  
  :loop => true, :autoplay => true, :poster => false,
  :fallback_content => "Your browser does not support HTML5 video tags" )
PHP:
Copy to clipboard
<?php echo cl_video_tag("dog", 
  array("width" => 200, "height" => 150, 
    "crop" => "crop", "loop" => true, 
    "autoplay" => true, "poster" => false,
    "fallback_content" => "Your browser does not support HTML5 video tags")); ?>
Python:
Copy to clipboard
cloudinary.CloudinaryVideo("dog").video( 
  width = 200, height = 150, 
  crop = "crop", loop = True, 
  autoplay = True, poster = False,
  fallback_content = "Your browser does not support HTML5 video tags")
Node.js:
Copy to clipboard
cloudinary.video("dog" { width: 200, height: 150, 
  crop: "crop", loop: true, 
  autoplay: true, poster: false,
  fallback_content: "Your browser does not support HTML5 video tags" })
Java:
Copy to clipboard
<cl:video src="dog" width = "200", height = "150", 
  crop = "crop", loop = "true", 
  autoplay = "true", poster = "false",
  fallback_content = "Your browser does not support HTML5 video tags"/>

Generates the following HTML5 video tag:

Copy to clipboard
<video loop autoplay>
  <source src="https://res.cloudinary.com/demo/video/upload/w_200,h_150,c_crop/dog.webm" type="video/webm"/>
  <source src="https://res.cloudinary.com/demo/video/upload/w_200,h_150,c_crop/dog.mp4" type="video/mp4"/>
  <source src="https://res.cloudinary.com/demo/video/upload/w_200,h_150,c_crop/dog.ogv" type="video/ogg"/>
   Your browser does not support HTML5 video tags
</video>

Transcoding video to other formats

Videos (and audio files) can be uploaded to Cloudinary in various formats (upload formats), and you can easily transcode these videos to other formats for displaying in your web site or application (delivery formats). Examples of situations where you might want to change the delivered video format:

  • Delivering a video where the original format is not supported for delivery by the browser. For example, you could deliver a 3PG (.3pg) video as an MPEG-4 (.mp4).
  • Delivering WebM if your users are on a Chrome browser or on a mobile app you control.

Transcoding the video to another format is done by simply specifying the new format as the file extension of the URL (client libraries can also use the format parameter to specify the new format). Furthermore, video files can be converted to audio files by stipulating a supported audio format.

For example, transcoding the format of the uploaded mp4 video named dog to WebM format by changing the file extension to .webm:

As a URL:

Via our SDKs:

Ruby:
Copy to clipboard
cl_video_tag("dog.webm")
PHP:
Copy to clipboard
cl_video_tag("dog.webm")
Python:
Copy to clipboard
CloudinaryVideo("dog.webm").video()
Node.js:
Copy to clipboard
cloudinary.video("dog.webm")
Java:
Copy to clipboard
script
cloudinary.videoTag('dog.webm').toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog.webm")
React:
Copy to clipboard
<Video publicId="dog.webm" >

</Video>
Angular:
Copy to clipboard
<cl-video public-id="dog.webm" >

</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.BuildVideoTag("dog.webm")
Android:
Copy to clipboard
MediaManager.get().url().resourceType("video").generate("dog.webm");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").generate("dog.webm")

Another way to transcode the format of an uploaded video is to use the format parameter (f for URLs). For example, transcoding the uploaded mp4 video named dog to WebM with a parameter:

Ruby:
Copy to clipboard
cl_video_tag("dog", :format=>"webm")
PHP:
Copy to clipboard
cl_video_tag("dog", array("format"=>"webm"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(format="webm")
Node.js:
Copy to clipboard
cloudinary.video("dog", {format: "webm"})
Java:
Copy to clipboard
cloudinary.url().format("webm").videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {format: "webm"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {format: "webm"})
React:
Copy to clipboard
<Video publicId="dog" format="webm">

</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" format="webm">

</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" format="webm">

</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Format("webm").BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().format("webm").resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setFormat("webm").setResourceType("video").generate("dog.mp4")

Supported video formats

The table below summarizes the supported video and audio format types.

Note
If a format is only supported for upload, then the delivery URL enables a user to download the original file in its original format, but you cannot apply transformation parameters.

Format Extensions Supported for Upload Supported for Delivery
3G2 3g2 Yes
3GP (3rd Generation Partnership) 3gp Yes
AVI (Audio Video Interleave) avi Yes
FLV (Flash Video) flv Yes Yes
HLS adaptive streaming m3u8 Yes Yes
MPEG-2 Transport Stream ts, m2ts, mts Yes Yes
MOV mov Yes Yes
MKV (Matroska Multimedia Container) mkv Yes Yes
MP4 mp4 Yes Yes
MPEG-2 mpeg Yes
MPEG-DASH adaptive streaming mpd Yes Yes
OGV (Ogg Video) ogv Yes Yes
WebM webm Yes Yes
WMV (Windows Media Video) wmv Yes

See also: Supported audio formats

Automatic format selection (f_auto)

Important
This feature is enabled for all new accounts, and is currently being automatically rolled out for existing accounts. If you are an existing customer and want access to this feature before it is rolled out to you, please contact support

There are a lot of formats and codecs for encoding videos, with some formats better than others at compression and reducing the file size without impairing visual quality. Since different browsers support different video formats and codecs, the best solution to save bandwidth and optimize delivery time would be to deliver the best format according to the browser used by each of your visitors.

The fetch_format parameter can be set to auto (f_auto in URLs) in order to perform automatic format and codec selection based on the requesting browser. For example, with the automatic format feature, in most cases Chrome users would receive a VP9-encoded WebM file, while Safari users would receive an HEVC-encoded MP4 file. If a browser does not support either of these formats then the video is delivered as an H.264-encoded MP4 file (which is supported by almost every browser).

For example, the uploaded video named dog scaled down to a width of 500 pixels and delivered as WebM (VP9) to Chrome browsers (482 KB), an MP4 (HEVC) to Safari browsers (520 KB), or as an MP4 (H.264) to browsers that support neither format (821 KB):

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>500, :fetch_format=>:auto, :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>500, "fetch_format"=>"auto", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=500, fetch_format="auto", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 500, fetch_format: "auto", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(500).fetchFormat("auto").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 500, fetchFormat: "auto", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 500, fetch_format: "auto", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="500" fetchFormat="auto" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="500" fetchFormat="auto" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="500" fetch-format="auto" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(500).FetchFormat("auto").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(500).fetchFormat("auto").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(500).setFetchFormat("auto").setCrop("scale")).generate("dog.mp4")

Note
This feature is also available on mobile native applications as long as the specified formats are included in the Accept Header.

Resizing and cropping videos

You can resize and crop videos in order to match the graphic design of your web site or mobile app. Whether videos are uploaded in your server-side code or by your users, the originals are stored in the cloud. You can then dynamically create multiple resized, cropped and manipulated videos on-the-fly and deliver them via dynamic URLs or use code to either add video tags or build the URLs.

Change the size of a video with the width and height parameters (w and h in URLs). You can resize the video by using both the width and height parameters or with only one of them (the other dimension is automatically updated to maintain the aspect ratio).

  • Using an integer value sets the new dimension to that number in pixels. For example, w_150 sets the width to exactly 150 pixels.
  • Using a decimal value sets the new dimension as a multiple of the original dimension. For example, w_0.5 sets the width to half the original width.

Examples of resizing the uploaded mp4 video named dog:

  1. Resizing to a width of 150 pixels and a height of 100 pixels:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :width=>150, :height=>100, :crop=>"scale")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("width"=>150, "height"=>100, "crop"=>"scale"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(width=150, height=100, crop="scale")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {width: 150, height: 100, crop: "scale"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().width(150).height(100).crop("scale")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {width: 150, height: 100, crop: "scale"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {width: 150, height: 100, crop: "scale"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation width="150" height="100" crop="scale" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation width="150" height="100" crop="scale" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation width="150" height="100" crop="scale">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(150).Height(100).Crop("scale")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().width(150).height(100).crop("scale")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(150).setHeight(100).setCrop("scale")).generate("dog.mp4")

  2. Resizing the width to half the original width, maintaining the aspect ratio:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :width=>0.5, :crop=>"scale")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("width"=>0.5, "crop"=>"scale"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(width=0.5, crop="scale")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {width: "0.5", crop: "scale"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().width(0.5).crop("scale")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {width: "0.5", crop: "scale"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {width: "0.5", crop: "scale"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation width="0.5" crop="scale" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation width="0.5" crop="scale" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation width="0.5" crop="scale">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(0.5).Crop("scale")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().width(0.5).crop("scale")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(0.5).setCrop("scale")).generate("dog.mp4")

  3. Resizing the height to 200 pixels, maintaining the aspect ratio:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :height=>200, :crop=>"scale")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("height"=>200, "crop"=>"scale"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(height=200, crop="scale")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {height: 200, crop: "scale"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().height(200).crop("scale")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {height: 200, crop: "scale"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {height: 200, crop: "scale"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation height="200" crop="scale" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation height="200" crop="scale" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation height="200" crop="scale">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().Height(200).Crop("scale")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().height(200).crop("scale")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setHeight(200).setCrop("scale")).generate("dog.mp4")

When changing the dimensions of an uploaded video by manipulating the video's height and/or width, you need to decide how to adapt or "crop" the video to fit into the requested size. Use the crop parameter for selecting the crop mode (c in URLs). Cloudinary supports the following video cropping modes: scale, fit, fill, limit, pad, lpad and crop.

scale

Change the size of the video exactly to the given width and height without necessarily retaining the original aspect ratio: all original video parts are visible but might be stretched or shrunk. If only the width or height is given, then the video is scaled to the new dimension while retaining the original aspect ratio (the other dimension is also scaled proportionately). This is the default cropping mode for resizing videos if the crop mode is not specified.

For example, the uploaded mp4 video named dog scaled to a width of 150 pixels while maintaining aspect ratio:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>150, :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>150, "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=150, crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 150, crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(150).crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 150, crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 150, crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="150" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="150" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="150" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(150).Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(150).crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(150).setCrop("scale")).generate("dog.mp4")

fit

Change video size to fit in the given width and height while retaining the original aspect ratio with all the original video parts visible. The new dimensions of the transformed video must not exceed the specified width and/or height, but may be enlarged if the video is smaller than the new dimensions. However, the video may be smaller than the specified values in order to keep the original proportions.

For example, the uploaded mp4 video named dog fitted to a width and height of 250 pixels while retaining the aspect ratio:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>250, :height=>250, :crop=>"fit")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>250, "height"=>250, "crop"=>"fit"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=250, height=250, crop="fit")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 250, height: 250, crop: "fit"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(250).height(250).crop("fit")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 250, height: 250, crop: "fit"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 250, height: 250, crop: "fit"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="250" height="250" crop="fit" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="250" height="250" crop="fit" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="250" height="250" crop="fit">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(250).Height(250).Crop("fit")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(250).height(250).crop("fit")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(250).setHeight(250).setCrop("fit")).generate("dog.mp4")

fill

Create a video with the exact given width and height while retaining original proportions. This option first scales up or down as much as needed to at least fill both of the given dimensions. If the requested aspect ratio is different than the original, cropping will occur on the dimension that exceeds the requested size after scaling. You can specify which part of the original video you want to keep if cropping occurs using the gravity parameter. Specify the gravity manually or use auto-gravity to automatically show the most interesting area.

For example, the uploaded mp4 video named dog filled to a width and height of 250 pixels while retaining the aspect ratio:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>250, :height=>250, :crop=>"fill")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>250, "height"=>250, "crop"=>"fill"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=250, height=250, crop="fill")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 250, height: 250, crop: "fill"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(250).height(250).crop("fill")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 250, height: 250, crop: "fill"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 250, height: 250, crop: "fill"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="250" height="250" crop="fill" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="250" height="250" crop="fill" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="250" height="250" crop="fill">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(250).Height(250).Crop("fill")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(250).height(250).crop("fill")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(250).setHeight(250).setCrop("fill")).generate("dog.mp4")

limit

The limit mode is used for creating a video that does not exceed the given width and height. If the original video is smaller than the given limits, the generated video uses the same dimensions as the original one. If the original is bigger than the given limits, it will be scaled down to fit the given dimensions while retaining original proportions (similar to the fit mode in this case).

For example, the uploaded mp4 video named dog limited to a width and height of 250 pixels while retaining the aspect ratio:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>250, :height=>250, :crop=>"limit")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>250, "height"=>250, "crop"=>"limit"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=250, height=250, crop="limit")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 250, height: 250, crop: "limit"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(250).height(250).crop("limit")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 250, height: 250, crop: "limit"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 250, height: 250, crop: "limit"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="250" height="250" crop="limit" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="250" height="250" crop="limit" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="250" height="250" crop="limit">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(250).Height(250).Crop("limit")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(250).height(250).crop("limit")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(250).setHeight(250).setCrop("limit")).generate("dog.mp4")

pad

Resize the video to fill the given width and height while retaining the original aspect ratio.

If the proportions of the original video do not match the required ones, padding is added to the video to reach the required size. You can also specify which part of the original video to use for filling the required dimensions in case the proportions do not match by using the gravity parameter, and specify the color of the background in the case that padding is added.

For example, the uploaded mp4 video named dog padded to a width and height of 250 pixels while retaining the aspect ratio:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>250, :height=>250, :background=>"black", :crop=>"pad")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>250, "height"=>250, "background"=>"black", "crop"=>"pad"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=250, height=250, background="black", crop="pad")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 250, height: 250, background: "black", crop: "pad"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(250).height(250).background("black").crop("pad")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 250, height: 250, background: "black", crop: "pad"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 250, height: 250, background: "black", crop: "pad"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="250" height="250" background="black" crop="pad" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="250" height="250" background="black" crop="pad" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="250" height="250" background="black" crop="pad">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(250).Height(250).Background("black").Crop("pad")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(250).height(250).background("black").crop("pad")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(250).setHeight(250).setBackground("black").setCrop("pad")).generate("dog.mp4")

pad with blurred video background

You may sometimes need to deliver a video with an aspect ratio very different than the target video player dimensions, for example delivering a portrait video in a landscape-oriented video player. In these cases, you can use a blurred version of the same video as the padding background. To do this, specify the blurred value instead of a color as the background. You can also optionally specify the intensity of the blur effect (range: 1-2000, default 100) and the brightness of the background video (range: -300-100, default 0).

For example, deliver this video of a talented kid solving a rubiks cube in a 320*480 HTML5 video player by padding the portrait video with a blurred version of the same video at an intensity of 400 and a brightness of 15.

Ruby:
Copy to clipboard
cl_video_tag("cld_rubiks_guy", :height=>320, :width=>480, :background=>"blurred:400:15", :crop=>"pad")
PHP:
Copy to clipboard
cl_video_tag("cld_rubiks_guy", array("height"=>320, "width"=>480, "background"=>"blurred:400:15", "crop"=>"pad"))
Python:
Copy to clipboard
CloudinaryVideo("cld_rubiks_guy").video(height=320, width=480, background="blurred:400:15", crop="pad")
Node.js:
Copy to clipboard
cloudinary.video("cld_rubiks_guy", {height: 320, width: 480, background: "blurred:400:15", crop: "pad"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().height(320).width(480).background("blurred:400:15").crop("pad")).videoTag("cld_rubiks_guy");
JS:
Copy to clipboard
cloudinary.videoTag('cld_rubiks_guy', {height: 320, width: 480, background: "blurred:400:15", crop: "pad"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("cld_rubiks_guy", {height: 320, width: 480, background: "blurred:400:15", crop: "pad"})
React:
Copy to clipboard
<Video publicId="cld_rubiks_guy" >
  <Transformation height="320" width="480" background="blurred:400:15" crop="pad" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="cld_rubiks_guy" >
  <cld-transformation height="320" width="480" background="blurred:400:15" crop="pad" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="cld_rubiks_guy" >
  <cl-transformation height="320" width="480" background="blurred:400:15" crop="pad">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Height(320).Width(480).Background("blurred:400:15").Crop("pad")).BuildVideoTag("cld_rubiks_guy")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().height(320).width(480).background("blurred:400:15").crop("pad")).resourceType("video").generate("cld_rubiks_guy.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setHeight(320).setWidth(480).setBackground("blurred:400:15").setCrop("pad")).generate("cld_rubiks_guy.mp4")

lpad

Same as the pad mode above, but doesn't scale the video up if your requested dimensions are larger than the original video's.

For example, the uploaded mp4 video named dog lpadded to a width and height of 250 pixels while retaining the aspect ratio and limiting the size to no larger than the original video:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>250, :height=>250, :background=>"black", :crop=>"lpad")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>250, "height"=>250, "background"=>"black", "crop"=>"lpad"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=250, height=250, background="black", crop="lpad")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 250, height: 250, background: "black", crop: "lpad"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(250).height(250).background("black").crop("lpad")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 250, height: 250, background: "black", crop: "lpad"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 250, height: 250, background: "black", crop: "lpad"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="250" height="250" background="black" crop="lpad" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="250" height="250" background="black" crop="lpad" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="250" height="250" background="black" crop="lpad">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(250).Height(250).Background("black").Crop("lpad")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(250).height(250).background("black").crop("lpad")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(250).setHeight(250).setBackground("black").setCrop("lpad")).generate("dog.mp4")

crop

Extract only part of a given width and height out of the original video. The original proportions are retained and you can also specify which part of the original video to use for filling the required dimensions by giving the x and y coordinates of the top left corner, or by using the gravity parameter.

For example, cropping the uploaded mp4 video named dog to a width of 350 pixels and a height of 200 pixels, starting at the x = 230 pixels and y = 20 pixels coordinate:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>350, :height=>200, :x=>230, :y=>20, :crop=>"crop")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>350, "height"=>200, "x"=>230, "y"=>20, "crop"=>"crop"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=350, height=200, x=230, y=20, crop="crop")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 350, height: 200, x: 230, y: 20, crop: "crop"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(350).height(200).x(230).y(20).crop("crop")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 350, height: 200, x: 230, y: 20, crop: "crop"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 350, height: 200, x: 230, y: 20, crop: "crop"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="350" height="200" x="230" y="20" crop="crop" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="350" height="200" x="230" y="20" crop="crop" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="350" height="200" x="230" y="20" crop="crop">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(350).Height(200).X(230).Y(20).Crop("crop")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(350).height(200).x(230).y(20).crop("crop")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(350).setHeight(200).setX(230).setY(20).setCrop("crop")).generate("dog.mp4")

Aspect ratio

Use the aspect_ratio parameter (ar in URLs) to resize the video to a new aspect ratio. This parameter is used together with a specified crop mode that determines how the video is adjusted to the new dimensions. This parameter can also be used when changing the dimensions of a video with only the width or height parameters (w and h in URLs) - the other dimension is then automatically updated to maintain the given aspect ratio.

The aspect_ratio parameter accepts a value in one of the following forms:

  • a:b where a signifies the relative width and b the relative height (e.g., 4:3 or 16:9).
  • a decimal value representing the ratio of the width divided by the height (e.g., 1.33 or 2.5).

Examples with the uploaded mp4 video named dog:

  1. Cropped to an aspect ratio of 2.5:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :aspect_ratio=>"2.5", :crop=>"crop")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("aspect_ratio"=>"2.5", "crop"=>"crop"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(aspect_ratio="2.5", crop="crop")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {aspect_ratio: "2.5", crop: "crop"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().aspectRatio("2.5").crop("crop")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {aspectRatio: "2.5", crop: "crop"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {aspect_ratio: "2.5", crop: "crop"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation aspectRatio="2.5" crop="crop" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation aspectRatio="2.5" crop="crop" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation aspect-ratio="2.5" crop="crop">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().AspectRatio("2.5").Crop("crop")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().aspectRatio("2.5").crop("crop")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setAspectRatio("2.5").setCrop("crop")).generate("dog.mp4")

  2. Filled to a width of 400 pixels with an aspect ratio of 4:3:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :width=>400, :aspect_ratio=>"4:3", :crop=>"fill")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("width"=>400, "aspect_ratio"=>"4:3", "crop"=>"fill"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(width=400, aspect_ratio="4:3", crop="fill")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {width: 400, aspect_ratio: "4:3", crop: "fill"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().width(400).aspectRatio("4:3").crop("fill")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {width: 400, aspectRatio: "4:3", crop: "fill"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {width: 400, aspect_ratio: "4:3", crop: "fill"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation width="400" aspectRatio="4:3" crop="fill" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation width="400" aspectRatio="4:3" crop="fill" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation width="400" aspect-ratio="4:3" crop="fill">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(400).AspectRatio("4:3").Crop("fill")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().width(400).aspectRatio("4:3").crop("fill")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(400).setAspectRatio("4:3").setCrop("fill")).generate("dog.mp4")

Set Device Pixel Ratio (DPR)

Different devices support different DPR values, which is defined as the ratio between physical pixels and logical pixels. This means that a device with support for a higher DPR uses more physical pixels for displaying a video, resulting in a clearer, sharper video.

DPR illustration

Use the dpr parameter to set the DPR value of the delivered video. The parameter accepts a float value specifying the DPR multiplier.

For example, the following URL dynamically generates the video named dog scaled to a width of 100 pixels. Setting the dpr value to 1.0, 2.0 (as in the code example) or 3.0 generates the following videos, while resizing the video to match the required DPR.

Ruby:
Copy to clipboard
cl_video_tag("dog", :transformation=>[
  {:width=>100, :crop=>"scale"},
  {:dpr=>2.0}
  ])
PHP:
Copy to clipboard
cl_video_tag("dog", array("transformation"=>array(
  array("width"=>100, "crop"=>"scale"),
  array("dpr"=>2.0)
  )))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(transformation=[
  {'width': 100, 'crop': "scale"},
  {'dpr': 2.0}
  ])
Node.js:
Copy to clipboard
cloudinary.video("dog", {transformation: [
  {width: 100, crop: "scale"},
  {dpr: "2.0"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(100).crop("scale").chain()
  .dpr(2.0)).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {transformation: [
  {width: 100, crop: "scale"},
  {dpr: "2.0"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {transformation: [
  {width: 100, crop: "scale"},
  {dpr: "2.0"}
  ]})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="100" crop="scale" />
  <Transformation dpr="2.0" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="100" crop="scale" />
  <cld-transformation dpr="2.0" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="100" crop="scale">
  </cl-transformation>
  <cl-transformation dpr="2.0">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(100).Crop("scale").Chain()
  .Dpr(2.0)).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(100).crop("scale").chain()
  .dpr(2.0)).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(100).setCrop("scale").chain()
  .setDpr(2.0)).generate("dog.mp4")

    DPR 1.0                                        DPR 2.0                                                               DPR 3.0

Now you can create a HTML video tag with the required dimensions and deliver a video with the resolution that best matches the specified pixel density of your users' devices. The three videos below are all displayed with a width of 200 pixels using the <video> tag width attribute, while you see more details and a better visual result for the last two videos (dpr 2 and dpr 3 respectively) if you view this documentation using a device that supports a higher DPR.

Copy to clipboard
<video poster="https://res.cloudinary.com/demo/video/upload/w_200,dpr_2.0/dog.jpg" width="200">
  <source src="https://res.cloudinary.com/demo/video/upload/w_200,dpr_2.0/dog.webm" type="video/webm"/>
  <source src="https://res.cloudinary.com/demo/video/upload/w_200,dpr_2.0/dog.mp4" type="video/mp4"/>
  <source src="https://res.cloudinary.com/demo/video/upload/w_200,dpr_2.0/dog.ogv" type="video/ogg"/>
</video>

   DPR 1.0 (200 width, 331KB)              DPR 2.0 (400 width, 437KB)               DPR 3.0 (600 width, 474KB)

Gravity

Gravity specifies which part of the original video to use for certain cropping modes, for filling the required dimensions in case the proportions do not match. This is accomplished by using the gravity parameter (g in URLs). The supported fixed location gravity values are: north_east, north, north_west, west, south_west, south, south_east, east, or center (the default value). You can also specify a gravity value of auto to automatically crop your video.

For example, the uploaded mp4 video named dog filled to a width and height of 250 pixels while retaining the aspect ratio, with gravity set to north:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>250, :height=>250, :gravity=>"north", :crop=>"fill")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>250, "height"=>250, "gravity"=>"north", "crop"=>"fill"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=250, height=250, gravity="north", crop="fill")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 250, height: 250, gravity: "north", crop: "fill"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(250).height(250).gravity("north").crop("fill")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 250, height: 250, gravity: "north", crop: "fill"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 250, height: 250, gravity: "north", crop: "fill"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="250" height="250" gravity="north" crop="fill" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="250" height="250" gravity="north" crop="fill" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="250" height="250" gravity="north" crop="fill">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(250).Height(250).Gravity("north").Crop("fill")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(250).height(250).gravity("north").crop("fill")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(250).setHeight(250).setGravity("north").setCrop("fill")).generate("dog.mp4")

Automatic Cropping

Automatic gravity selection ensures that the most interesting areas are selected as the main focus throughout the duration of each video. Each video is analyzed to find the optimal region, allowing you to adjust the size or aspect ratio to fit all of your requirements. As the optimal region of the video could be moving from frame to frame, the cropped area will adjust accordingly.

Apply automatic content-aware gravity by cropping your video with the fill crop mode and setting the gravity transformation parameter to auto (g_auto in URLs).

For example, to crop this video to a square aspect ratio whilst keeping the ship as the main focus throughout:

Ruby:
Copy to clipboard
cl_video_tag("ship", :width=>300, :gravity=>"auto", :aspect_ratio=>"1:1", :crop=>"fill")
PHP:
Copy to clipboard
cl_video_tag("ship", array("width"=>300, "gravity"=>"auto", "aspect_ratio"=>"1:1", "crop"=>"fill"))
Python:
Copy to clipboard
CloudinaryVideo("ship").video(width=300, gravity="auto", aspect_ratio="1:1", crop="fill")
Node.js:
Copy to clipboard
cloudinary.video("ship", {width: 300, gravity: "auto", aspect_ratio: "1:1", crop: "fill"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).gravity("auto").aspectRatio("1:1").crop("fill")).videoTag("ship");
JS:
Copy to clipboard
cloudinary.videoTag('ship', {width: 300, gravity: "auto", aspectRatio: "1:1", crop: "fill"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("ship", {width: 300, gravity: "auto", aspect_ratio: "1:1", crop: "fill"})
React:
Copy to clipboard
<Video publicId="ship" >
  <Transformation width="300" gravity="auto" aspectRatio="1:1" crop="fill" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="ship" >
  <cld-transformation width="300" gravity="auto" aspectRatio="1:1" crop="fill" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="ship" >
  <cl-transformation width="300" gravity="auto" aspect-ratio="1:1" crop="fill">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Gravity("auto").AspectRatio("1:1").Crop("fill")).BuildVideoTag("ship")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).gravity("auto").aspectRatio("1:1").crop("fill")).resourceType("video").generate("ship.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setGravity("auto").setAspectRatio("1:1").setCrop("fill")).generate("ship.mp4")

Comparison with default gravity

Below is a comparison between the original video of a dog catching a frisbee, and the same video with the aspect ratio inverted. The left video was cropped using default center gravity and the other using automatic gravity. Watch how the auto cropped (right-hand) video keeps the main subject (the dog) in view at all times, even as it moves across the frame in the original video.

Click any video below to see the comparison in action or use our automatic cropping demo to try it on a variety of samples or on your own videos.

Original video
Default crop
(Center gravity)
Auto-gravity

Notes and Tips:

  • The automatic cropping algorithm analyzes the entire video to determine the areas to focus on, which means it can take several seconds or minutes, depending on the length of the original video (an HTTP 423 error will be returned until the analysis is complete). Therefore, it's recommended to generate the transformation eagerly during upload or using an explicit method call for existing videos, along with an eager_notification_url parameter to notify your application when the content aware cropping transformation is ready for delivery.
  • Once a video has been analyzed by the automatic cropping algorithm, any subsequent transformations will happen on-the-fly as usual. This includes adjusting the size and aspect ratio.
  • Automatic cropping works best when there's a single subject in your video.
  • You can only use automatic gravity once per transformation and not within a layer.

Background color

Use the background parameter (b in URLs) to set the color in the case of padding added with the “pad” crop mode. The color can be set as an RGB hex triplet (e.g. b_rgb:3e2222), a 3 character RGB hex (e.g. b_rgb:777) or a named color (e.g. b_green). Cloudinary's client libraries also support a # shortcut for RGB (e.g. setting background to #3e2222 which is then translated to b_rgb:3e2222).

For example, the uploaded mp4 video named dog padded to a width and height of 300 pixels with a green background:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>300, :height=>300, :background=>"green", :crop=>"pad")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>300, "height"=>300, "background"=>"green", "crop"=>"pad"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=300, height=300, background="green", crop="pad")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 300, height: 300, background: "green", crop: "pad"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).height(300).background("green").crop("pad")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 300, height: 300, background: "green", crop: "pad"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 300, height: 300, background: "green", crop: "pad"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" height="300" background="green" crop="pad" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" height="300" background="green" crop="pad" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" height="300" background="green" crop="pad">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Height(300).Background("green").Crop("pad")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).height(300).background("green").crop("pad")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setHeight(300).setBackground("green").setCrop("pad")).generate("dog.mp4")

Trimming videos

Trim a video (and discard the rest) by using a combination of the following 3 parameters to specify the section of video to keep after trimming:

  • start_offset (so in URLs) specifies the start.
  • end_offset (eo in URLs) specifies the end.
  • duration (du in URLs) specifies the duration.

Possible values:

  • A float representing the time in seconds e.g. 5.44 (5 seconds and 440 milliseconds)
  • A string representing the percentage of the video length. This string consists of a number with a p appended e.g. 35p (0p is the first frame and 100p is the last frame). The client libraries also support appending a % instead of a p.

Examples with the uploaded mp4 video named dog:

  1. Trimming the video to the section that starts at 6.5 seconds and ends at 10 seconds:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :start_offset=>"6.5", :end_offset=>"10")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("start_offset"=>"6.5", "end_offset"=>"10"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(start_offset="6.5", end_offset="10")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {start_offset: "6.5", end_offset: "10"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().startOffset("6.5").endOffset("10")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {startOffset: "6.5", endOffset: "10"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {start_offset: "6.5", end_offset: "10"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation startOffset="6.5" endOffset="10" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation startOffset="6.5" endOffset="10" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation start-offset="6.5" end-offset="10">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("6.5").EndOffset("10")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().startOffset("6.5").endOffset("10")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("6.5").setEndOffset("10")).generate("dog.mp4")

  2. Trimming the video to the section that starts at 10 percent with a duration of 30 percent (effectively from the 10 percent mark to the 40 percent mark):

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :start_offset=>"10p", :duration=>"30p")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("start_offset"=>"10p", "duration"=>"30p"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(start_offset="10p", duration="30p")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {start_offset: "10p", duration: "30p"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().startOffset("10p").duration("30p")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {startOffset: "10p", duration: "30p"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {start_offset: "10p", duration: "30p"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation startOffset="10p" duration="30p" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation startOffset="10p" duration="30p" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation start-offset="10p" duration="30p">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("10p").Duration("30p")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().startOffset("10p").duration("30p")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("10p").setDuration("30p")).generate("dog.mp4")

Client libraries also support the offset shortcut parameter to combine the 2 values representing the start and end of the video to keep e.g. [2.5, 9.5] or ['10p', '30p']. In frameworks that support ranges you can use: 2.66..3.21 or '35%..70%'. An equivalent of the offset shortcut is not available for URLs.

For example, trimming the uploaded mp4 video named dog to the section that starts at 6.5 seconds and ends at 10 seconds:

Ruby:
Copy to clipboard
cl_video_tag("dog", :start_offset=>"6.5", :end_offset=>"10")
PHP:
Copy to clipboard
cl_video_tag("dog", array("start_offset"=>"6.5", "end_offset"=>"10"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(start_offset="6.5", end_offset="10")
Node.js:
Copy to clipboard
cloudinary.video("dog", {start_offset: "6.5", end_offset: "10"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().startOffset("6.5").endOffset("10")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {startOffset: "6.5", endOffset: "10"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {start_offset: "6.5", end_offset: "10"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation startOffset="6.5" endOffset="10" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation startOffset="6.5" endOffset="10" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation start-offset="6.5" end-offset="10">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("6.5").EndOffset("10")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().startOffset("6.5").endOffset("10")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("6.5").setEndOffset("10")).generate("dog.mp4")

Concatenating videos

Cloudinary supports the concatenation of videos by using the overlay video parameter (l_video: in URLs) to specify the name of another uploaded video and then the splice flag (fl_splice in URLs) to indicate that the video should be concatenated on to the container video and not added as an overlay.

You can also concatenate videos with custom transitions using the transition effect (e_transition in URLs).

Note
Videos spliced together or concatenated with a custom transition must be the same width and height. You can use size transformation parameters to ensure that both videos match in size (w and h). If using a transition video, this will be automatically scaled to the same size.

For example, to concatenate the video named dog on to the end of the video named kitten_fighting, with both videos set to a width of 300 pixels and a height of 200 pixels:

Ruby:
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:width=>300, :height=>200, :crop=>"fill"},
  {:overlay=>"video:dog", :flags=>"splice", :width=>300, :height=>200, :crop=>"fill"}
  ])
PHP:
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("width"=>300, "height"=>200, "crop"=>"fill"),
  array("overlay"=>"video:dog", "flags"=>"splice", "width"=>300, "height"=>200, "crop"=>"fill")
  )))
Python:
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'width': 300, 'height': 200, 'crop': "fill"},
  {'overlay': "video:dog", 'flags': "splice", 'width': 300, 'height': 200, 'crop': "fill"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {width: 300, height: 200, crop: "fill"},
  {overlay: "video:dog", flags: "splice", width: 300, height: 200, crop: "fill"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(300).height(200).crop("fill").chain()
  .overlay(new Layer().publicId("video:dog")).flags("splice").width(300).height(200).crop("fill")).videoTag("kitten_fighting");
JS:
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {width: 300, height: 200, crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), flags: "splice", width: 300, height: 200, crop: "fill"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {width: 300, height: 200, crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), flags: "splice", width: 300, height: 200, crop: "fill"}
  ]})
React:
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation width="300" height="200" crop="fill" />
  <Transformation overlay="video:dog" flags="splice" width="300" height="200" crop="fill" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="kitten_fighting" >
  <cld-transformation width="300" height="200" crop="fill" />
  <cld-transformation overlay="video:dog" flags="splice" width="300" height="200" crop="fill" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation width="300" height="200" crop="fill">
  </cl-transformation>
  <cl-transformation overlay="video:dog" flags="splice" width="300" height="200" crop="fill">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(300).Height(200).Crop("fill").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Flags("splice").Width(300).Height(200).Crop("fill")).BuildVideoTag("kitten_fighting")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(300).height(200).crop("fill").chain()
  .overlay(new Layer().publicId("video:dog")).flags("splice").width(300).height(200).crop("fill")).resourceType("video").generate("kitten_fighting.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(300).setHeight(200).setCrop("fill").chain()
  .setOverlay("video:dog").setFlags("splice").setWidth(300).setHeight(200).setCrop("fill")).generate("kitten_fighting.mp4")

By default, the video is spliced on to the end of the container video: to splice the video on to the beginning, add the start_offset parameter and set it to 0 (so_0 in URLs). For example, to concatenate the video named dog on to the beginning of the video named kitten_fighting, with both videos set to a width of 300 pixels and a height of 200 pixels:

Ruby:
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:width=>300, :height=>200, :crop=>"fill"},
  {:overlay=>"video:dog", :flags=>"splice", :width=>300, :height=>200, :start_offset=>"0", :crop=>"fill"}
  ])
PHP:
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("width"=>300, "height"=>200, "crop"=>"fill"),
  array("overlay"=>"video:dog", "flags"=>"splice", "width"=>300, "height"=>200, "start_offset"=>"0", "crop"=>"fill")
  )))
Python:
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'width': 300, 'height': 200, 'crop': "fill"},
  {'overlay': "video:dog", 'flags': "splice", 'width': 300, 'height': 200, 'start_offset': "0", 'crop': "fill"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {width: 300, height: 200, crop: "fill"},
  {overlay: "video:dog", flags: "splice", width: 300, height: 200, start_offset: "0", crop: "fill"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(300).height(200).crop("fill").chain()
  .overlay(new Layer().publicId("video:dog")).flags("splice").width(300).height(200).startOffset("0").crop("fill")).videoTag("kitten_fighting");
JS:
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {width: 300, height: 200, crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), flags: "splice", width: 300, height: 200, startOffset: "0", crop: "fill"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {width: 300, height: 200, crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), flags: "splice", width: 300, height: 200, start_offset: "0", crop: "fill"}
  ]})
React:
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation width="300" height="200" crop="fill" />
  <Transformation overlay="video:dog" flags="splice" width="300" height="200" startOffset="0" crop="fill" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="kitten_fighting" >
  <cld-transformation width="300" height="200" crop="fill" />
  <cld-transformation overlay="video:dog" flags="splice" width="300" height="200" startOffset="0" crop="fill" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation width="300" height="200" crop="fill">
  </cl-transformation>
  <cl-transformation overlay="video:dog" flags="splice" width="300" height="200" start-offset="0" crop="fill">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(300).Height(200).Crop("fill").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Flags("splice").Width(300).Height(200).StartOffset("0").Crop("fill")).BuildVideoTag("kitten_fighting")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(300).height(200).crop("fill").chain()
  .overlay(new Layer().publicId("video:dog")).flags("splice").width(300).height(200).startOffset("0").crop("fill")).resourceType("video").generate("kitten_fighting.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(300).setHeight(200).setCrop("fill").chain()
  .setOverlay("video:dog").setFlags("splice").setWidth(300).setHeight(200).setStartOffset("0").setCrop("fill")).generate("kitten_fighting.mp4")

To concatenate only a section of a video on to another video use the offset parameters (see Trimming videos for more information on the parameters and their possible values) together with the layer_apply flag (fl_layer_apply in URLs). For example, to splice the first 5 seconds of the video named dog to the end of the same video named dog rotated by 180 degrees, with both videos set to a width of 300 pixels and a height of 200 pixels.

Ruby:
Copy to clipboard
cl_video_tag("dog", :transformation=>[
  {:angle=>180},
  {:width=>300, :height=>200, :crop=>"fill"},
  {:overlay=>"video:dog", :flags=>"splice", :width=>300, :height=>200, :start_offset=>"0", :duration=>"5", :crop=>"fill"},
  {:flags=>"layer_apply"}
  ])
PHP:
Copy to clipboard
cl_video_tag("dog", array("transformation"=>array(
  array("angle"=>180),
  array("width"=>300, "height"=>200, "crop"=>"fill"),
  array("overlay"=>"video:dog", "flags"=>"splice", "width"=>300, "height"=>200, "start_offset"=>"0", "duration"=>"5", "crop"=>"fill"),
  array("flags"=>"layer_apply")
  )))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(transformation=[
  {'angle': 180},
  {'width': 300, 'height': 200, 'crop': "fill"},
  {'overlay': "video:dog", 'flags': "splice", 'width': 300, 'height': 200, 'start_offset': "0", 'duration': "5", 'crop': "fill"},
  {'flags': "layer_apply"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("dog", {transformation: [
  {angle: 180},
  {width: 300, height: 200, crop: "fill"},
  {overlay: "video:dog", flags: "splice", width: 300, height: 200, start_offset: "0", duration: "5", crop: "fill"},
  {flags: "layer_apply"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .angle(180).chain()
  .width(300).height(200).crop("fill").chain()
  .overlay(new Layer().publicId("video:dog")).flags("splice").width(300).height(200).startOffset("0").duration("5").crop("fill").chain()
  .flags("layer_apply")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {transformation: [
  {angle: 180},
  {width: 300, height: 200, crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), flags: "splice", width: 300, height: 200, startOffset: "0", duration: "5", crop: "fill"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {transformation: [
  {angle: 180},
  {width: 300, height: 200, crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), flags: "splice", width: 300, height: 200, start_offset: "0", duration: "5", crop: "fill"},
  {flags: "layer_apply"}
  ]})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation angle="180" />
  <Transformation width="300" height="200" crop="fill" />
  <Transformation overlay="video:dog" flags="splice" width="300" height="200" startOffset="0" duration="5" crop="fill" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation angle="180" />
  <cld-transformation width="300" height="200" crop="fill" />
  <cld-transformation overlay="video:dog" flags="splice" width="300" height="200" startOffset="0" duration="5" crop="fill" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation angle="180">
  </cl-transformation>
  <cl-transformation width="300" height="200" crop="fill">
  </cl-transformation>
  <cl-transformation overlay="video:dog" flags="splice" width="300" height="200" start-offset="0" duration="5" crop="fill">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Angle(180).Chain()
  .Width(300).Height(200).Crop("fill").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Flags("splice").Width(300).Height(200).StartOffset("0").Duration("5").Crop("fill").Chain()
  .Flags("layer_apply")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .angle(180).chain()
  .width(300).height(200).crop("fill").chain()
  .overlay(new Layer().publicId("video:dog")).flags("splice").width(300).height(200).startOffset("0").duration("5").crop("fill").chain()
  .flags("layer_apply")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setAngle(180).chain()
  .setWidth(300).setHeight(200).setCrop("fill").chain()
  .setOverlay("video:dog").setFlags("splice").setWidth(300).setHeight(200).setStartOffset("0").setDuration("5").setCrop("fill").chain()
  .setFlags("layer_apply")).generate("dog.mp4")

Concatenate videos with images

Cloudinary also supports the concatenation of videos with images by using the following combination of parameters:

  • overlay (l: in URLs) to specify the name of an uploaded image,
  • splice flag (fl_splice in URLs) to indicate that the image should be concatenated on to the container video and not added as an overlay,
  • duration parameter (du in URLs) to specify the amount of time in seconds to display the image.
  • start_offset (optional) set to 0 (so_0 in URLs) to concatenate the image at the beginning of the video instead of at the end.
  • layer_apply flag (fl_layer_apply) to indicate that the above parameters are applied to the image (with the overlay parameter) and not the base video.

For example, to concatenate the image named sample to the start of the video named dog for a duration of 3 seconds (both the video and image are scaled to a width of 300 pixels and a height of 200 pixels):

Ruby:
Copy to clipboard
cl_video_tag("dog", :transformation=>[
  {:width=>300, :height=>200, :crop=>"scale"},
  {:width=>300, :height=>200, :overlay=>"sample", :flags=>"splice", :duration=>"3"},
  {:start_offset=>"0", :flags=>"layer_apply"}
  ])
PHP:
Copy to clipboard
cl_video_tag("dog", array("transformation"=>array(
  array("width"=>300, "height"=>200, "crop"=>"scale"),
  array("width"=>300, "height"=>200, "overlay"=>"sample", "flags"=>"splice", "duration"=>"3"),
  array("start_offset"=>"0", "flags"=>"layer_apply")
  )))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(transformation=[
  {'width': 300, 'height': 200, 'crop': "scale"},
  {'width': 300, 'height': 200, 'overlay': "sample", 'flags': "splice", 'duration': "3"},
  {'start_offset': "0", 'flags': "layer_apply"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("dog", {transformation: [
  {width: 300, height: 200, crop: "scale"},
  {width: 300, height: 200, overlay: "sample", flags: "splice", duration: "3"},
  {start_offset: "0", flags: "layer_apply"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(300).height(200).crop("scale").chain()
  .width(300).height(200).overlay(new Layer().publicId("sample")).flags("splice").duration("3").chain()
  .startOffset("0").flags("layer_apply")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {transformation: [
  {width: 300, height: 200, crop: "scale"},
  {width: 300, height: 200, overlay: new cloudinary.Layer().publicId("sample"), flags: "splice", duration: "3"},
  {startOffset: "0", flags: "layer_apply"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {transformation: [
  {width: 300, height: 200, crop: "scale"},
  {width: 300, height: 200, overlay: new cloudinary.Layer().publicId("sample"), flags: "splice", duration: "3"},
  {start_offset: "0", flags: "layer_apply"}
  ]})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" height="200" crop="scale" />
  <Transformation width="300" height="200" overlay="sample" flags="splice" duration="3" />
  <Transformation startOffset="0" flags="layer_apply" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" height="200" crop="scale" />
  <cld-transformation width="300" height="200" overlay="sample" flags="splice" duration="3" />
  <cld-transformation startOffset="0" flags="layer_apply" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" height="200" crop="scale">
  </cl-transformation>
  <cl-transformation width="300" height="200" overlay="sample" flags="splice" duration="3">
  </cl-transformation>
  <cl-transformation start-offset="0" flags="layer_apply">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(300).Height(200).Crop("scale").Chain()
  .Width(300).Height(200).Overlay(new Layer().PublicId("sample")).Flags("splice").Duration("3").Chain()
  .StartOffset("0").Flags("layer_apply")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(300).height(200).crop("scale").chain()
  .width(300).height(200).overlay(new Layer().publicId("sample")).flags("splice").duration("3").chain()
  .startOffset("0").flags("layer_apply")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(300).setHeight(200).setCrop("scale").chain()
  .setWidth(300).setHeight(200).setOverlay("sample").setFlags("splice").setDuration("3").chain()
  .setStartOffset("0").setFlags("layer_apply")).generate("dog.mp4")

Concatenate videos with custom transitions

Cloudinary supports the concatenation of videos with a custom transition by including a transition video as an additional layer and specifying the transition effect (e_transition in URLs).

Note
The splice flag is not required when concatenating with a custom transition.

To add a custom transition:

  1. Add your base video as normal.
  2. Add the second video using the overlay video parameter (l_video: in URLs), ensuring height and width are the same as the base video.
  3. Specify the video to use as a transition as follows:
    1. Add a luma matte transition video using the overlay video parameter (l_video: in URLs).
    2. Specify the transition effect to indicate that this video overlay is to be used as a transition between the base and second video.
    3. Add the layer_apply flag (fl_layer_apply) to close the transition layer.
  4. Add a second layer_apply flag to close the second video layer. For more information, see the documentation on layer_apply.

Here's an example showing the kitten_fighting video transitioning to the dog video:

Ruby:
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:width=>300, :height=>200, :duration=>"5", :crop=>"scale"},
  {:overlay=>"video:dog", :width=>300, :height=>200},
  {:duration=>"5"},
  {:overlay=>"video:transition1", :effect=>"transition"},
  {:flags=>"layer_apply"},
  {:flags=>"layer_apply"}
  ])
PHP:
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("width"=>300, "height"=>200, "duration"=>"5", "crop"=>"scale"),
  array("overlay"=>"video:dog", "width"=>300, "height"=>200),
  array("duration"=>"5"),
  array("overlay"=>"video:transition1", "effect"=>"transition"),
  array("flags"=>"layer_apply"),
  array("flags"=>"layer_apply")
  )))
Python:
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'width': 300, 'height': 200, 'duration': "5", 'crop': "scale"},
  {'overlay': "video:dog", 'width': 300, 'height': 200},
  {'duration': "5"},
  {'overlay': "video:transition1", 'effect': "transition"},
  {'flags': "layer_apply"},
  {'flags': "layer_apply"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {width: 300, height: 200, duration: "5", crop: "scale"},
  {overlay: "video:dog", width: 300, height: 200},
  {duration: "5"},
  {overlay: "video:transition1", effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(300).height(200).duration("5").crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).width(300).height(200).chain()
  .duration("5").chain()
  .overlay(new Layer().publicId("video:transition1")).effect("transition").chain()
  .flags("layer_apply").chain()
  .flags("layer_apply")).videoTag("kitten_fighting");
JS:
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {width: 300, height: 200, duration: "5", crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 300, height: 200},
  {duration: "5"},
  {overlay: new cloudinary.Layer().publicId("video:transition1"), effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {width: 300, height: 200, duration: "5", crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 300, height: 200},
  {duration: "5"},
  {overlay: new cloudinary.Layer().publicId("video:transition1"), effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]})
React:
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation width="300" height="200" duration="5" crop="scale" />
  <Transformation overlay="video:dog" width="300" height="200" />
  <Transformation duration="5" />
  <Transformation overlay="video:transition1" effect="transition" />
  <Transformation flags="layer_apply" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="kitten_fighting" >
  <cld-transformation width="300" height="200" duration="5" crop="scale" />
  <cld-transformation overlay="video:dog" width="300" height="200" />
  <cld-transformation duration="5" />
  <cld-transformation overlay="video:transition1" effect="transition" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation width="300" height="200" duration="5" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:dog" width="300" height="200">
  </cl-transformation>
  <cl-transformation duration="5">
  </cl-transformation>
  <cl-transformation overlay="video:transition1" effect="transition">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(300).Height(200).Duration("5").Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Width(300).Height(200).Chain()
  .Duration("5").Chain()
  .Overlay(new Layer().PublicId("video:transition1")).Effect("transition").Chain()
  .Flags("layer_apply").Chain()
  .Flags("layer_apply")).BuildVideoTag("kitten_fighting")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(300).height(200).duration("5").crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).width(300).height(200).chain()
  .duration("5").chain()
  .overlay(new Layer().publicId("video:transition1")).effect("transition").chain()
  .flags("layer_apply").chain()
  .flags("layer_apply")).resourceType("video").generate("kitten_fighting.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(300).setHeight(200).setDuration("5").setCrop("scale").chain()
  .setOverlay("video:dog").setWidth(300).setHeight(200).chain()
  .setDuration("5").chain()
  .setOverlay("video:transition1").setEffect("transition").chain()
  .setFlags("layer_apply").chain()
  .setFlags("layer_apply")).generate("kitten_fighting.mp4")

A luma matte transition video is a grayscale video that uses lightness values to indicate the transparency (alpha channel) of two transitioning videos. For example, the base video will be transparent in the completely white areas and opaque in the completely black areas of the matte. The second video will then be visible in the areas of transparency of the base video; anywhere between will show both videos with the opacity of each determined by the lightness values.

You need to add your own luma matte transition videos to your account. The example below has been uploaded to the Cloudinary demo account (and used in the example above):

Ruby:
Copy to clipboard
cl_video_tag("transition1", :width=>300, :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("transition1", array("width"=>300, "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("transition1").video(width=300, crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("transition1", {width: 300, crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).crop("scale")).videoTag("transition1");
JS:
Copy to clipboard
cloudinary.videoTag('transition1', {width: 300, crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("transition1", {width: 300, crop: "scale"})
React:
Copy to clipboard
<Video publicId="transition1" >
  <Transformation width="300" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="transition1" >
  <cld-transformation width="300" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="transition1" >
  <cl-transformation width="300" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Crop("scale")).BuildVideoTag("transition1")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).crop("scale")).resourceType("video").generate("transition1.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setCrop("scale")).generate("transition1.mp4")

The transition you see above starts black and adds increasing areas of white. When applied as a transition video, the base video will display first and the second video will take up increasing space until none of the base video is visible.

As the luma matte is a video itself, you can also add transformations in the same way you would with any other uploaded video. For example, you can use the accelerate effect (e_accelerate) to adjust the speed of the transition or flip the transition using the angle parameter (a in URLs). You'll need to be careful when applying transformations to the matte as this could cause issues with the transition, particularly if you change the aspect ratio. Here's the same video as above with the transition slowed to 5 seconds and flipped 180 degrees:

Ruby:
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:duration=>"5", :width=>300, :height=>200, :crop=>"scale"},
  {:overlay=>"video:dog", :width=>300, :height=>200},
  {:duration=>"5"},
  {:overlay=>"video:transition1", :effect=>"transition"},
  {:effect=>"accelerate:5s", :angle=>180},
  {:flags=>"layer_apply"},
  {:flags=>"layer_apply"}
  ])
PHP:
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("duration"=>"5", "width"=>300, "height"=>200, "crop"=>"scale"),
  array("overlay"=>"video:dog", "width"=>300, "height"=>200),
  array("duration"=>"5"),
  array("overlay"=>"video:transition1", "effect"=>"transition"),
  array("effect"=>"accelerate:5s", "angle"=>180),
  array("flags"=>"layer_apply"),
  array("flags"=>"layer_apply")
  )))
Python:
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'duration': "5", 'width': 300, 'height': 200, 'crop': "scale"},
  {'overlay': "video:dog", 'width': 300, 'height': 200},
  {'duration': "5"},
  {'overlay': "video:transition1", 'effect': "transition"},
  {'effect': "accelerate:5s", 'angle': 180},
  {'flags': "layer_apply"},
  {'flags': "layer_apply"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {duration: "5", width: 300, height: 200, crop: "scale"},
  {overlay: "video:dog", width: 300, height: 200},
  {duration: "5"},
  {overlay: "video:transition1", effect: "transition"},
  {effect: "accelerate:5s", angle: 180},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .duration("5").width(300).height(200).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).width(300).height(200).chain()
  .duration("5").chain()
  .overlay(new Layer().publicId("video:transition1")).effect("transition").chain()
  .effect("accelerate:5s").angle(180).chain()
  .flags("layer_apply").chain()
  .flags("layer_apply")).videoTag("kitten_fighting");
JS:
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {duration: "5", width: 300, height: 200, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 300, height: 200},
  {duration: "5"},
  {overlay: new cloudinary.Layer().publicId("video:transition1"), effect: "transition"},
  {effect: "accelerate:5s", angle: 180},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {duration: "5", width: 300, height: 200, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 300, height: 200},
  {duration: "5"},
  {overlay: new cloudinary.Layer().publicId("video:transition1"), effect: "transition"},
  {effect: "accelerate:5s", angle: 180},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]})
React:
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation duration="5" width="300" height="200" crop="scale" />
  <Transformation overlay="video:dog" width="300" height="200" />
  <Transformation duration="5" />
  <Transformation overlay="video:transition1" effect="transition" />
  <Transformation effect="accelerate:5s" angle="180" />
  <Transformation flags="layer_apply" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="kitten_fighting" >
  <cld-transformation duration="5" width="300" height="200" crop="scale" />
  <cld-transformation overlay="video:dog" width="300" height="200" />
  <cld-transformation duration="5" />
  <cld-transformation overlay="video:transition1" effect="transition" />
  <cld-transformation effect="accelerate:5s" angle="180" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation duration="5" width="300" height="200" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:dog" width="300" height="200">
  </cl-transformation>
  <cl-transformation duration="5">
  </cl-transformation>
  <cl-transformation overlay="video:transition1" effect="transition">
  </cl-transformation>
  <cl-transformation effect="accelerate:5s" angle="180">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Duration("5").Width(300).Height(200).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Width(300).Height(200).Chain()
  .Duration("5").Chain()
  .Overlay(new Layer().PublicId("video:transition1")).Effect("transition").Chain()
  .Effect("accelerate:5s").Angle(180).Chain()
  .Flags("layer_apply").Chain()
  .Flags("layer_apply")).BuildVideoTag("kitten_fighting")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .duration("5").width(300).height(200).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).width(300).height(200).chain()
  .duration("5").chain()
  .overlay(new Layer().publicId("video:transition1")).effect("transition").chain()
  .effect("accelerate:5s").angle(180).chain()
  .flags("layer_apply").chain()
  .flags("layer_apply")).resourceType("video").generate("kitten_fighting.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setDuration("5").setWidth(300).setHeight(200).setCrop("scale").chain()
  .setOverlay("video:dog").setWidth(300).setHeight(200).chain()
  .setDuration("5").chain()
  .setOverlay("video:transition1").setEffect("transition").chain()
  .setEffect("accelerate:5s").setAngle(180).chain()
  .setFlags("layer_apply").chain()
  .setFlags("layer_apply")).generate("kitten_fighting.mp4")

You can concatenate multiple videos with (and without) transitions by chaining additional videos and transition overlays. Here's an example of two transitions followed by a standard fl_splice concatenation (with no transition):

Ruby:
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:width=>300, :height=>200, :duration=>"5", :crop=>"scale"},
  {:overlay=>"video:dog", :width=>300, :height=>200},
  {:duration=>"5"},
  {:overlay=>"video:transition1", :effect=>"transition"},
  {:flags=>"layer_apply"},
  {:flags=>"layer_apply"},
  {:overlay=>"video:snow_deer", :width=>300, :height=>200},
  {:duration=>"5"},
  {:overlay=>"video:transition2", :effect=>"transition"},
  {:flags=>"layer_apply"},
  {:flags=>"layer_apply"},
  {:overlay=>"video:dog", :flags=>"splice", :width=>300, :height=>200},
  {:duration=>"5"},
  {:flags=>"layer_apply"}
  ])
PHP:
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("width"=>300, "height"=>200, "duration"=>"5", "crop"=>"scale"),
  array("overlay"=>"video:dog", "width"=>300, "height"=>200),
  array("duration"=>"5"),
  array("overlay"=>"video:transition1", "effect"=>"transition"),
  array("flags"=>"layer_apply"),
  array("flags"=>"layer_apply"),
  array("overlay"=>"video:snow_deer", "width"=>300, "height"=>200),
  array("duration"=>"5"),
  array("overlay"=>"video:transition2", "effect"=>"transition"),
  array("flags"=>"layer_apply"),
  array("flags"=>"layer_apply"),
  array("overlay"=>"video:dog", "flags"=>"splice", "width"=>300, "height"=>200),
  array("duration"=>"5"),
  array("flags"=>"layer_apply")
  )))
Python:
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'width': 300, 'height': 200, 'duration': "5", 'crop': "scale"},
  {'overlay': "video:dog", 'width': 300, 'height': 200},
  {'duration': "5"},
  {'overlay': "video:transition1", 'effect': "transition"},
  {'flags': "layer_apply"},
  {'flags': "layer_apply"},
  {'overlay': "video:snow_deer", 'width': 300, 'height': 200},
  {'duration': "5"},
  {'overlay': "video:transition2", 'effect': "transition"},
  {'flags': "layer_apply"},
  {'flags': "layer_apply"},
  {'overlay': "video:dog", 'flags': "splice", 'width': 300, 'height': 200},
  {'duration': "5"},
  {'flags': "layer_apply"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {width: 300, height: 200, duration: "5", crop: "scale"},
  {overlay: "video:dog", width: 300, height: 200},
  {duration: "5"},
  {overlay: "video:transition1", effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: "video:snow_deer", width: 300, height: 200},
  {duration: "5"},
  {overlay: "video:transition2", effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: "video:dog", flags: "splice", width: 300, height: 200},
  {duration: "5"},
  {flags: "layer_apply"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(300).height(200).duration("5").crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).width(300).height(200).chain()
  .duration("5").chain()
  .overlay(new Layer().publicId("video:transition1")).effect("transition").chain()
  .flags("layer_apply").chain()
  .flags("layer_apply").chain()
  .overlay(new Layer().publicId("video:snow_deer")).width(300).height(200).chain()
  .duration("5").chain()
  .overlay(new Layer().publicId("video:transition2")).effect("transition").chain()
  .flags("layer_apply").chain()
  .flags("layer_apply").chain()
  .overlay(new Layer().publicId("video:dog")).flags("splice").width(300).height(200).chain()
  .duration("5").chain()
  .flags("layer_apply")).videoTag("kitten_fighting");
JS:
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {width: 300, height: 200, duration: "5", crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 300, height: 200},
  {duration: "5"},
  {overlay: new cloudinary.Layer().publicId("video:transition1"), effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: new cloudinary.Layer().publicId("video:snow_deer"), width: 300, height: 200},
  {duration: "5"},
  {overlay: new cloudinary.Layer().publicId("video:transition2"), effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), flags: "splice", width: 300, height: 200},
  {duration: "5"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {width: 300, height: 200, duration: "5", crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 300, height: 200},
  {duration: "5"},
  {overlay: new cloudinary.Layer().publicId("video:transition1"), effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: new cloudinary.Layer().publicId("video:snow_deer"), width: 300, height: 200},
  {duration: "5"},
  {overlay: new cloudinary.Layer().publicId("video:transition2"), effect: "transition"},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), flags: "splice", width: 300, height: 200},
  {duration: "5"},
  {flags: "layer_apply"}
  ]})
React:
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation width="300" height="200" duration="5" crop="scale" />
  <Transformation overlay="video:dog" width="300" height="200" />
  <Transformation duration="5" />
  <Transformation overlay="video:transition1" effect="transition" />
  <Transformation flags="layer_apply" />
  <Transformation flags="layer_apply" />
  <Transformation overlay="video:snow_deer" width="300" height="200" />
  <Transformation duration="5" />
  <Transformation overlay="video:transition2" effect="transition" />
  <Transformation flags="layer_apply" />
  <Transformation flags="layer_apply" />
  <Transformation overlay="video:dog" flags="splice" width="300" height="200" />
  <Transformation duration="5" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="kitten_fighting" >
  <cld-transformation width="300" height="200" duration="5" crop="scale" />
  <cld-transformation overlay="video:dog" width="300" height="200" />
  <cld-transformation duration="5" />
  <cld-transformation overlay="video:transition1" effect="transition" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation overlay="video:snow_deer" width="300" height="200" />
  <cld-transformation duration="5" />
  <cld-transformation overlay="video:transition2" effect="transition" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation overlay="video:dog" flags="splice" width="300" height="200" />
  <cld-transformation duration="5" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation width="300" height="200" duration="5" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:dog" width="300" height="200">
  </cl-transformation>
  <cl-transformation duration="5">
  </cl-transformation>
  <cl-transformation overlay="video:transition1" effect="transition">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation overlay="video:snow_deer" width="300" height="200">
  </cl-transformation>
  <cl-transformation duration="5">
  </cl-transformation>
  <cl-transformation overlay="video:transition2" effect="transition">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation overlay="video:dog" flags="splice" width="300" height="200">
  </cl-transformation>
  <cl-transformation duration="5">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(300).Height(200).Duration("5").Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Width(300).Height(200).Chain()
  .Duration("5").Chain()
  .Overlay(new Layer().PublicId("video:transition1")).Effect("transition").Chain()
  .Flags("layer_apply").Chain()
  .Flags("layer_apply").Chain()
  .Overlay(new Layer().PublicId("video:snow_deer")).Width(300).Height(200).Chain()
  .Duration("5").Chain()
  .Overlay(new Layer().PublicId("video:transition2")).Effect("transition").Chain()
  .Flags("layer_apply").Chain()
  .Flags("layer_apply").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Flags("splice").Width(300).Height(200).Chain()
  .Duration("5").Chain()
  .Flags("layer_apply")).BuildVideoTag("kitten_fighting")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(300).height(200).duration("5").crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).width(300).height(200).chain()
  .duration("5").chain()
  .overlay(new Layer().publicId("video:transition1")).effect("transition").chain()
  .flags("layer_apply").chain()
  .flags("layer_apply").chain()
  .overlay(new Layer().publicId("video:snow_deer")).width(300).height(200).chain()
  .duration("5").chain()
  .overlay(new Layer().publicId("video:transition2")).effect("transition").chain()
  .flags("layer_apply").chain()
  .flags("layer_apply").chain()
  .overlay(new Layer().publicId("video:dog")).flags("splice").width(300).height(200).chain()
  .duration("5").chain()
  .flags("layer_apply")).resourceType("video").generate("kitten_fighting.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(300).setHeight(200).setDuration("5").setCrop("scale").chain()
  .setOverlay("video:dog").setWidth(300).setHeight(200).chain()
  .setDuration("5").chain()
  .setOverlay("video:transition1").setEffect("transition").chain()
  .setFlags("layer_apply").chain()
  .setFlags("layer_apply").chain()
  .setOverlay("video:snow_deer").setWidth(300).setHeight(200).chain()
  .setDuration("5").chain()
  .setOverlay("video:transition2").setEffect("transition").chain()
  .setFlags("layer_apply").chain()
  .setFlags("layer_apply").chain()
  .setOverlay("video:dog").setFlags("splice").setWidth(300).setHeight(200).chain()
  .setDuration("5").chain()
  .setFlags("layer_apply")).generate("kitten_fighting.mp4")

Note
Total video duration is calculated as the combined duration of all videos minus the duration of the transitions (as two videos are playing during the transition).

Rotating videos

Rotate the video by any arbitrary angle in degrees with the angle parameter (a in URLs). If the angle is not a multiple of 90 then a rectangular bounding box is added containing the rotated video and empty space.

Examples with the uploaded mp4 video named dog:

  1. Rotating the video by 90 degrees:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :angle=>90)
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("angle"=>90))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(angle=90)
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {angle: 90})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().angle(90)).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {angle: 90}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {angle: 90})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation angle="90" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation angle="90" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation angle="90">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().Angle(90)).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().angle(90)).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setAngle(90)).generate("dog.mp4")

  2. Rotating the video by 20 degrees (automatically adds a bounding box):

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :angle=>20)
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("angle"=>20))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(angle=20)
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {angle: 20})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().angle(20)).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {angle: 20}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {angle: 20})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation angle="20" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation angle="20" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation angle="20">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().Angle(20)).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().angle(20)).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setAngle(20)).generate("dog.mp4")

Rounding corners and creating circular videos

Transforming a video to a rounded version is done using the radius parameter (r in URLs) set to the number of pixels the radius of all four corners should be. For example, the uploaded mp4 video named dog resized to a width of 300 pixels and with rounded corners set to a radius of 20 pixels:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>300, :radius=>30, :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>300, "radius"=>30, "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=300, radius=30, crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 300, radius: 30, crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).radius(30).crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 300, radius: 30, crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 300, radius: 30, crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" radius="30" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" radius="30" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" radius="30" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Radius(30).Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).radius(30).crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setRadius(30).setCrop("scale")).generate("dog.mp4")

Cloudinary also supports cropping videos to the shape of an ellipse. Simply pass max as the value of the radius parameter. For example, the uploaded mp4 video named dog resized to a width of 300 pixels and with maximum radius cropping:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>300, :radius=>"max", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>300, "radius"=>"max", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=300, radius="max", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 300, radius: "max", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).radius("max").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 300, radius: "max", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 300, radius: "max", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" radius="max" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" radius="max" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" radius="max" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Radius("max").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).radius("max").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setRadius("max").setCrop("scale")).generate("dog.mp4")

You can also change the background color of the video from the default white color using the background parameter. Likewise, if the width and height of the video are identical (i.e., the same value) then setting the radius parameter to max generates a circular video. For example, the uploaded mp4 video named dog with width and height set to 300 pixels, and with maximum radius cropping using a blue background:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>300, :height=>300, :background=>"blue", :radius=>"max", :crop=>"fill")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>300, "height"=>300, "background"=>"blue", "radius"=>"max", "crop"=>"fill"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=300, height=300, background="blue", radius="max", crop="fill")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 300, height: 300, background: "blue", radius: "max", crop: "fill"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).height(300).background("blue").radius("max").crop("fill")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 300, height: 300, background: "blue", radius: "max", crop: "fill"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 300, height: 300, background: "blue", radius: "max", crop: "fill"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" height="300" background="blue" radius="max" crop="fill" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" height="300" background="blue" radius="max" crop="fill" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" height="300" background="blue" radius="max" crop="fill">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Height(300).Background("blue").Radius("max").Crop("fill")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).height(300).background("blue").radius("max").crop("fill")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setHeight(300).setBackground("blue").setRadius("max").setCrop("fill")).generate("dog.mp4")

The radius parameter can also be used to round the corners of overlays, which are then also given a transparent background. For example, the uploaded mp4 video named dog overlaid on the same video named dog with width set to 100 pixels, maximum radius cropping and north east gravity:

Ruby:
Copy to clipboard
cl_video_tag("dog", :transformation=>[
  {:width=>300, :crop=>"scale"},
  {:overlay=>"video:dog", :width=>100, :gravity=>"north_east", :radius=>"max"}
  ])
PHP:
Copy to clipboard
cl_video_tag("dog", array("transformation"=>array(
  array("width"=>300, "crop"=>"scale"),
  array("overlay"=>"video:dog", "width"=>100, "gravity"=>"north_east", "radius"=>"max")
  )))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(transformation=[
  {'width': 300, 'crop': "scale"},
  {'overlay': "video:dog", 'width': 100, 'gravity': "north_east", 'radius': "max"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("dog", {transformation: [
  {width: 300, crop: "scale"},
  {overlay: "video:dog", width: 100, gravity: "north_east", radius: "max"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(300).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).width(100).gravity("north_east").radius("max")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {transformation: [
  {width: 300, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 100, gravity: "north_east", radius: "max"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {transformation: [
  {width: 300, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 100, gravity: "north_east", radius: "max"}
  ]})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" crop="scale" />
  <Transformation overlay="video:dog" width="100" gravity="north_east" radius="max" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" crop="scale" />
  <cld-transformation overlay="video:dog" width="100" gravity="north_east" radius="max" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:dog" width="100" gravity="north_east" radius="max">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(300).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Width(100).Gravity("north_east").Radius("max")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(300).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).width(100).gravity("north_east").radius("max")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(300).setCrop("scale").chain()
  .setOverlay("video:dog").setWidth(100).setGravity("north_east").setRadius("max")).generate("dog.mp4")

Video settings

The video settings are used for adjusting the video properties of the delivered video including:

For all available video settings, see the Video settings section of the Video Transformation Reference.

Quality control

Control the video quality with the quality parameter (q in URLs). This parameter represents a mapping between the actual low-level settings of each different video format normalized to a quality value between 1 (lowest) and 100 (highest). Reducing the quality is a tradeoff between visual quality and file size. See video_codec in the Video transformations reference table for the default settings for each format.

For example, reducing the quality of the uploaded mp4 video named dog to 50 results in a file size of 1.1 MB compared to the original file size of 9.8MB:

Ruby:
Copy to clipboard
cl_video_tag("dog", :quality=>50)
PHP:
Copy to clipboard
cl_video_tag("dog", array("quality"=>50))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(quality=50)
Node.js:
Copy to clipboard
cloudinary.video("dog", {quality: 50})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().quality(50)).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {quality: 50}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {quality: 50})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation quality="50" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation quality="50" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation quality="50">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Quality(50)).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().quality(50)).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setQuality(50)).generate("dog.mp4")

Automatic quality

Instead of defining a specific quality value, you can use Cloudinary's intelligent quality and encoding algorithm. The algorithm analyses each video to decide on the optimal encoding characteristics that will produce the best visual quality while minimizing the file size.

The quality transformation parameter can be set to auto (q_auto in URLs) in order to perform automatic quality encoding. Further control of the automatic quality selection is supported as follows:

  • q_auto - The optimal balance between file size and visual quality. By default, this is the same as q_auto:good.
  • q_auto:best - Less aggressive algorithm. Generates bigger files with potentially better visual quality.
  • q_auto:good - Ensuring a relatively small file size with good visual quality. Example of a target audience: stock media sites that display videos with a high visual quality.
  • q_auto:eco - More aggressive algorithm, which results in smaller files of slightly lower visual quality. Example of a target audience: popular sites and social networks with a huge amount of traffic.
  • q_auto:low - Most aggressive algorithm, which results in the smallest files of low visual quality. Example of a target audience: sites using thumbnail preview videos that then link to higher quality videos.

Examples of the resulting file size when encoding a video, using various regular and automatic quality parameter values:

Notes

  • Automatic quality is supported for videos using the h264, h265 and VP9 codecs.
  • Cloudinary already performs some basic content-aware encoding when delivering a transformed video. See the video_codec section of the Video transformations reference table for the default settings for each format, which includes setting quality to 70. Using q_auto overrides this default setting, producing slightly different results depending on the complexity of the video.
  • q_auto cannot be used within named transformations, however q_auto:[Mode] (e.g., q_auto:good) is supported within named transformations.

Control the quality of WEBM transcoding

In some cases, transcoding videos from mp4 to webm (VP8/9 encoding) may give a pixelated result. In these cases, you can control the final quality by setting a maximum quantization percentage (1-100 range) value:qmax in addition to a fixed quality value. This can help ensure that the video is not over-quantized.

For example, you could set the quality parameter to: "80:qmax_90" to ensure that the transcoded video is quantized no more than 90% of the maximum possible quantization. When you set a qmax value, the quality value is relative to the quantization value.

For example, if you transcode the video below to .webm format without setting a max quantization value, the quality drops fairly significantly compared to its .mp4 counterpart, but by setting the max quantization to 70, you get a better visual quality.

Ruby:
Copy to clipboard
cl_video_tag("Liverpool_vs_Roma_full", :duration=>"30", :quality=>"70:qmax_20")
PHP:
Copy to clipboard
cl_video_tag("Liverpool_vs_Roma_full", array("duration"=>"30", "quality"=>"70:qmax_20"))
Python:
Copy to clipboard
CloudinaryVideo("Liverpool_vs_Roma_full").video(duration="30", quality="70:qmax_20")
Node.js:
Copy to clipboard
cloudinary.video("Liverpool_vs_Roma_full", {duration: "30", quality: "70:qmax_20"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().duration("30").quality("70:qmax_20")).videoTag("Liverpool_vs_Roma_full");
JS:
Copy to clipboard
cloudinary.videoTag('Liverpool_vs_Roma_full', {duration: "30", quality: "70:qmax_20"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("Liverpool_vs_Roma_full", {duration: "30", quality: "70:qmax_20"})
React:
Copy to clipboard
<Video publicId="Liverpool_vs_Roma_full" >
  <Transformation duration="30" quality="70:qmax_20" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="Liverpool_vs_Roma_full" >
  <cld-transformation duration="30" quality="70:qmax_20" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="Liverpool_vs_Roma_full" >
  <cl-transformation duration="30" quality="70:qmax_20">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Duration("30").Quality("70:qmax_20")).BuildVideoTag("Liverpool_vs_Roma_full")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().duration("30").quality("70:qmax_20")).resourceType("video").generate("Liverpool_vs_Roma_full.webm");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setDuration("30").setQuality("70:qmax_20")).generate("Liverpool_vs_Roma_full.webm")

Keep in mind that the lower you set the qmax value, the higher the bitrate, and the larger the resulting file size.

If you don't supply a qmax value, then the maximum quantization is 100%, although the actual applied quantization will be determined by other factors such as the quality value you set (or your account's default quality setting), the content of the actual video, and other transformation and optimization options you include.

Bitrate control

Use the bit_rate parameter (br in URLs) for advanced control of the video bitrate. This parameter controls the number of bits used to represent the video data. By default, the br_ value uses variable bitrate (VBR), where the specified value indicates the maximum bitrate. The actual bitrate and quality are optimized according to the video content, to conserve bandwidth and storage. You can also specify a constant bitrate value (CBR): br_[value]:constant in URLs. In this case, the specified bitrate will be used even in cases where that high of a rate is not necessary for good quality viewing. When you specify a constant bitrate, the quality parameter is ignored.

bit_rate can take one of the following values:

  • An integer e.g. 120000.
  • A string supporting ‘k’ and ‘m’ (kilobits and megabits respectively) e.g. 250k or 2m.

For example, setting the maximum bitrate of the uploaded mp4 video named dog to 250 kilobits (also reducing file size down to ~550 KB):

Ruby:
Copy to clipboard
cl_video_tag("dog", :bit_rate=>"250k")
PHP:
Copy to clipboard
cl_video_tag("dog", array("bit_rate"=>"250k"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(bit_rate="250k")
Node.js:
Copy to clipboard
cloudinary.video("dog", {bit_rate: "250k"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().bitRate("250k")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {bitRate: "250k"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {bit_rate: "250k"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation bitRate="250k" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation bitRate="250k" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation bit-rate="250k">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().BitRate("250k")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().bitRate("250k")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setBitRate("250k")).generate("dog.mp4")

Note
If you define a maximum or constant bitrate as well as a maximum quantization (qmax), and there is a conflict between these two settings, the maximum or constant bitrate will take precedence.

Video codec settings

The video_codec parameter (vc in URLs) is used to determine the video codec, video profile and level to use in the form <codec>[:<profile>:[<level>]] e.g. vc_h264:baseline:3.1 or vc_h264 or vc_h264:high. You can set this parameter to auto instead, to normalize and optimize the video for web (including audio settings).

By default, any transformation applied to the video (e.g., resizing) implicitly also uses the auto settings when delivering the transformed video, so using the auto setting is only needed when delivering the same format as originally uploaded with optimization but without any additional transformations. See video_codec in the Video transformations reference table for the default settings for each format.

Examples with the uploaded mp4 video named dog:

  1. Setting the video codec to h264, the profile to baseline and the level to 3.1:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :video_codec=>"h264:baseline:3.1")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("video_codec"=>"h264:baseline:3.1"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(video_codec="h264:baseline:3.1")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {video_codec: "h264:baseline:3.1"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().videoCodec("h264:baseline:3.1")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {videoCodec: "h264:baseline:3.1"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {video_codec: "h264:baseline:3.1"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation videoCodec="h264:baseline:3.1" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation videoCodec="h264:baseline:3.1" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation video-codec="h264:baseline:3.1">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().VideoCodec("h264:baseline:3.1")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().videoCodec("h264:baseline:3.1")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setVideoCodec("h264:baseline:3.1")).generate("dog.mp4")

  2. Normalizing the video for web with the default settings:

    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :video_codec=>"auto")
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("video_codec"=>"auto"))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(video_codec="auto")
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {video_codec: "auto"})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().videoCodec("auto")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {videoCodec: "auto"}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {video_codec: "auto"})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation videoCodec="auto" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation videoCodec="auto" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation video-codec="auto">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().VideoCodec("auto")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().videoCodec("auto")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setVideoCodec("auto")).generate("dog.mp4")

Notes

  • Supported for: vp9, prores, h264 or h265. Only the h264 codec (mp4) has profile or level parameters, with profile: baseline, main or high and level: 3.0,3.1,4.0,4.1, 4.2, 5.0, 5.1 or 5.2.
  • The prores parameter value delivers videos encoded with the Apple ProRes 422HQ codec.
  • Client libraries can optionally enter the parameter as a structure. For example, in Ruby: video_codec: { codec: 'h264', profile: 'baseline', level: '3.1' }

Control access to videos

When uploading videos to Cloudinary, both the original videos and their transformed versions are publicly available through a CDN, by default. You can use random Public IDs to make it harder to guess video URLs, but you might want more than that. Controlling access to your videos is identical to controlling access to your images - see Controlling access to assets for more information on:

Video Effects

Video effects can be applied to an uploaded video file and allow you to manipulate the appearance of the delivered video file. For example, you can:

For all video effects, see the Effects section of the Video Transformation Reference

Change video playback speed

Use the accelerate video effect (e_accelerate in URLs) to either speed up or slow down the video playback speed. The effect accepts an integer value between -50 and 100 that determines how to change the playback speed (in percent), with a positive value for speeding up the video, and a negative value for slowing down the video.

For example, the uploaded mp4 video named dog resized to a width of 300 pixels and accelerated by 100% (twice normal speed):

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>300, :effect=>"accelerate:100", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>300, "effect"=>"accelerate:100", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=300, effect="accelerate:100", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 300, effect: "accelerate:100", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).effect("accelerate:100").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 300, effect: "accelerate:100", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 300, effect: "accelerate:100", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" effect="accelerate:100" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" effect="accelerate:100" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" effect="accelerate:100" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Effect("accelerate:100").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).effect("accelerate:100").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setEffect("accelerate:100").setCrop("scale")).generate("dog.mp4")

Reverse playback

Use the reverse effect (e_reverse in URLs) to play a video or audio file backwards.

For example, in the following reversed video, you can watch a woman un-sketch her phone design:

Ruby:
Copy to clipboard
cl_video_tag("pencil_sketch", :width=>500, :effect=>"reverse", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("pencil_sketch", array("width"=>500, "effect"=>"reverse", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("pencil_sketch").video(width=500, effect="reverse", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("pencil_sketch", {width: 500, effect: "reverse", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(500).effect("reverse").crop("scale")).videoTag("pencil_sketch");
JS:
Copy to clipboard
cloudinary.videoTag('pencil_sketch', {width: 500, effect: "reverse", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("pencil_sketch", {width: 500, effect: "reverse", crop: "scale"})
React:
Copy to clipboard
<Video publicId="pencil_sketch" >
  <Transformation width="500" effect="reverse" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="pencil_sketch" >
  <cld-transformation width="500" effect="reverse" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="pencil_sketch" >
  <cl-transformation width="500" effect="reverse" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(500).Effect("reverse").Crop("scale")).BuildVideoTag("pencil_sketch")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(500).effect("reverse").crop("scale")).resourceType("video").generate("pencil_sketch.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(500).setEffect("reverse").setCrop("scale")).generate("pencil_sketch.mp4")

Create a boomerang video clip

A boomerang video is a (usually very short) video clip that plays forwards and then backwards. This effect has become quite popular on many social media and video editing apps. You can create a boomerang effect on any video by adding the boomerang effect to your transformation.

To ensure your video is short enough to produce the desired effect, you can use the boomerang effect in conjunction with the duration, start_offset, or end_offset trimming parameters. Keep in mind that the total length of a single repetition of the boomerang effect will be double the length you set for the video using the trimming parameters.

By default, the boomerang effect runs a single time. To get the repetitive effect that is characteristic of boomerang videos, you need to add looping functionality. To do this, you can either:

  • Include the HTML5 loop attribute in the relevant video_tag SDK method call or when embedding a Cloudinary video player in your webpage. If delivering your boomerang clip in a video format, this is the recommended method.

  • Use the loop transformation effect. If delivering your boomerang video as an animated gif, this is the recommended method.

For example, the following transformation delivers a selected 2 second clip of the snow_deer video as an animated gif with an infinitely looping boomerang effect:

Ruby:
Copy to clipboard
cl_image_tag("snow_deer.gif", :resource_type=>"video", :transformation=>[
  {:width=>480, :start_offset=>"3", :end_offset=>"5", :effect=>"boomerang", :crop=>"scale"},
  {:effect=>"loop"}
  ])
PHP:
Copy to clipboard
cl_image_tag("snow_deer.gif", array("resource_type"=>"video", "transformation"=>array(
  array("width"=>480, "start_offset"=>"3", "end_offset"=>"5", "effect"=>"boomerang", "crop"=>"scale"),
  array("effect"=>"loop")
  )))
Python:
Copy to clipboard
CloudinaryVideo("snow_deer.gif").image(transformation=[
  {'width': 480, 'start_offset': "3", 'end_offset': "5", 'effect': "boomerang", 'crop': "scale"},
  {'effect': "loop"}
  ])
Node.js:
Copy to clipboard
cloudinary.image("snow_deer.gif", {resource_type: "video", transformation: [
  {width: 480, start_offset: "3", end_offset: "5", effect: "boomerang", crop: "scale"},
  {effect: "loop"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(480).startOffset("3").endOffset("5").effect("boomerang").crop("scale").chain()
  .effect("loop")).resourceType("video").imageTag("snow_deer.gif");
JS:
Copy to clipboard
cloudinary.videoTag('snow_deer.gif', {transformation: [
  {width: 480, startOffset: "3", endOffset: "5", effect: "boomerang", crop: "scale"},
  {effect: "loop"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("snow_deer.gif", {resource_type: "video", transformation: [
  {width: 480, start_offset: "3", end_offset: "5", effect: "boomerang", crop: "scale"},
  {effect: "loop"}
  ]})
React:
Copy to clipboard
<Video publicId="snow_deer.gif" resourceType="video">
  <Transformation width="480" startOffset="3" endOffset="5" effect="boomerang" crop="scale" />
  <Transformation effect="loop" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="snow_deer.gif" resourceType="video">
  <cld-transformation width="480" startOffset="3" endOffset="5" effect="boomerang" crop="scale" />
  <cld-transformation effect="loop" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="snow_deer.gif" resource-type="video">
  <cl-transformation width="480" start-offset="3" end-offset="5" effect="boomerang" crop="scale">
  </cl-transformation>
  <cl-transformation effect="loop">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(480).StartOffset("3").EndOffset("5").Effect("boomerang").Crop("scale").Chain()
  .Effect("loop")).BuildImageTag("snow_deer.gif")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(480).startOffset("3").endOffset("5").effect("boomerang").crop("scale").chain()
  .effect("loop")).resourceType("video").generate("snow_deer.gif");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(480).setStartOffset("3").setEndOffset("5").setEffect("boomerang").setCrop("scale").chain()
  .setEffect("loop")).generate("snow_deer.gif")
boomerang animated gif

Control video looping

Use the loop effect (e_loop in URLs) to deliver a video that loops a specified number of times. The loop parameter value indicates the number of times the video repeats (after the initial run). For example, if you want to deliver a video that plays a total of 3 times in a row, set the loop value to 2.

Note
This parameter differs from the loop attribute of the HTML5 tag, which instructs the video player to play the delivered video in an infinite loop.

For example, delivering a video that contains 3 iterations of the ski_jump video. The original video is 5 seconds long. This delivered video is 15 seconds:

Ruby:
Copy to clipboard
cl_video_tag("ski_jump", :effect=>"loop:2")
PHP:
Copy to clipboard
cl_video_tag("ski_jump", array("effect"=>"loop:2"))
Python:
Copy to clipboard
CloudinaryVideo("ski_jump").video(effect="loop:2")
Node.js:
Copy to clipboard
cloudinary.video("ski_jump", {effect: "loop:2"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().effect("loop:2")).videoTag("ski_jump");
JS:
Copy to clipboard
cloudinary.videoTag('ski_jump', {effect: "loop:2"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("ski_jump", {effect: "loop:2"})
React:
Copy to clipboard
<Video publicId="ski_jump" >
  <Transformation effect="loop:2" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="ski_jump" >
  <cld-transformation effect="loop:2" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="ski_jump" >
  <cl-transformation effect="loop:2">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Effect("loop:2")).BuildVideoTag("ski_jump")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().effect("loop:2")).resourceType("video").generate("ski_jump.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setEffect("loop:2")).generate("ski_jump.mp4")

Tip
You can also use the loop parameter when you convert a video to an animated gif so that it will run infinitely (or a specified number of times). For details, see Delivering animated GIFs.

Apply video transparency

You can convert any relatively solid color in a video overlay to be fully transparent, thus making the base video visible in the transparent areas. This means you can remove plain colored backgrounds from a video overlay or remove a solid colored element from the subject of a video overlay, such that the content of the video behind that element shows through. This functionality works like a green-screen effect, but can be applied to any HEX color.

To make a color transparent in your video overlay, apply both the make_transparent effect (e_make_transparent in URLs) and the color parameter (co_ in URLs) to your video overlay component. You can also specify a tolerance value for the make_transparent effect to allow for minor differences in the shade of the specified color.

Note
The make_transparent parameter is supported only for videos within an overlay component. You cannot apply this parameter to a video without an overlay.

For example, suppose you have the following product video that was produced with a blue screen background:

You could use that product video as an overlay on top of a video showing a nice background scene. You could then make the blue background of your overlay video transparent using the make_transparent parameter together with the color parameter set to the Hex color #0e80d8 (the specific shade of blue used in this video).

Ruby:
Copy to clipboard
cl_video_tag("docs/sunset_waves", :transformation=>[
  {:width=>500, :crop=>"scale"},
  {:overlay=>"video:docs:bluescreen_watches", :effect=>"make_transparent:20", :color=>"#0e80d8", :width=>0.6, :flags=>"relative", :gravity=>"north"},
  {:duration=>"15"}
  ])
PHP:
Copy to clipboard
cl_video_tag("docs/sunset_waves", array("transformation"=>array(
  array("width"=>500, "crop"=>"scale"),
  array("overlay"=>"video:docs:bluescreen_watches", "effect"=>"make_transparent:20", "color"=>"#0e80d8", "width"=>0.6, "flags"=>"relative", "gravity"=>"north"),
  array("duration"=>"15")
  )))
Python:
Copy to clipboard
CloudinaryVideo("docs/sunset_waves").video(transformation=[
  {'width': 500, 'crop': "scale"},
  {'overlay': "video:docs:bluescreen_watches", 'effect': "make_transparent:20", 'color': "#0e80d8", 'width': 0.6, 'flags': "relative", 'gravity': "north"},
  {'duration': "15"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("docs/sunset_waves", {transformation: [
  {width: 500, crop: "scale"},
  {overlay: "video:docs:bluescreen_watches", effect: "make_transparent:20", color: "#0e80d8", width: "0.6", flags: "relative", gravity: "north"},
  {duration: "15"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(500).crop("scale").chain()
  .overlay(new Layer().publicId("video:docs:bluescreen_watches")).effect("make_transparent:20").color("#0e80d8").width(0.6).flags("relative").gravity("north").chain()
  .duration("15")).videoTag("docs/sunset_waves");
JS:
Copy to clipboard
cloudinary.videoTag('docs/sunset_waves', {transformation: [
  {width: 500, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:docs:bluescreen_watches"), effect: "make_transparent:20", color: "#0e80d8", width: "0.6", flags: "relative", gravity: "north"},
  {duration: "15"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("docs/sunset_waves", {transformation: [
  {width: 500, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:docs:bluescreen_watches"), effect: "make_transparent:20", color: "#0e80d8", width: "0.6", flags: "relative", gravity: "north"},
  {duration: "15"}
  ]})
React:
Copy to clipboard
<Video publicId="docs/sunset_waves" >
  <Transformation width="500" crop="scale" />
  <Transformation overlay="video:docs:bluescreen_watches" effect="make_transparent:20" color="#0e80d8" width="0.6" flags="relative" gravity="north" />
  <Transformation duration="15" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="docs/sunset_waves" >
  <cld-transformation width="500" crop="scale" />
  <cld-transformation overlay="video:docs:bluescreen_watches" effect="make_transparent:20" color="#0e80d8" width="0.6" flags="relative" gravity="north" />
  <cld-transformation duration="15" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="docs/sunset_waves" >
  <cl-transformation width="500" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:docs:bluescreen_watches" effect="make_transparent:20" color="#0e80d8" width="0.6" flags="relative" gravity="north">
  </cl-transformation>
  <cl-transformation duration="15">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(500).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:docs:bluescreen_watches")).Effect("make_transparent:20").Color("#0e80d8").Width(0.6).Flags("relative").Gravity("north").Chain()
  .Duration("15")).BuildVideoTag("docs/sunset_waves")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(500).crop("scale").chain()
  .overlay(new Layer().publicId("video:docs:bluescreen_watches")).effect("make_transparent:20").color("#0e80d8").width(0.6).flags("relative").gravity("north").chain()
  .duration("15")).resourceType("video").generate("docs/sunset_waves.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(500).setCrop("scale").chain()
  .setOverlay("video:docs:bluescreen_watches").setEffect("make_transparent:20").setColor("#0e80d8").setWidth(0.6).setFlags("relative").setGravity("north").chain()
  .setDuration("15")).generate("docs/sunset_waves.mp4")

Tip
It's often useful to set the size of your overlay video to be relative to the base video. For example, note the use of w_0.6 and fl_relative, along with g_north in the URL above, which makes the overlay video 60% smaller than the background video and places the overlay over the north part of the background video, in order to get the desired effect.

The make_transparent parameter is not limited to removing backgrounds. For example, in the above video, instead of setting the transparency color to the blue background color, you could set it to the color of the green stripe inside the watches, and then the background video would show only in place of the green stripes.
(For this use case, w_1.0, fl_relative was used so that the overlay video would completely cover the background video, except where the overlay is transparent.)

Ruby:
Copy to clipboard
cl_video_tag("docs/sunset_waves", :transformation=>[
  {:width=>500, :crop=>"scale"},
  {:overlay=>"video:docs:bluescreen_watches", :effect=>"make_transparent:10", :color=>"#3d8d48", :width=>1.0, :flags=>"relative"},
  {:duration=>"15"}
  ])
PHP:
Copy to clipboard
cl_video_tag("docs/sunset_waves", array("transformation"=>array(
  array("width"=>500, "crop"=>"scale"),
  array("overlay"=>"video:docs:bluescreen_watches", "effect"=>"make_transparent:10", "color"=>"#3d8d48", "width"=>1.0, "flags"=>"relative"),
  array("duration"=>"15")
  )))
Python:
Copy to clipboard
CloudinaryVideo("docs/sunset_waves").video(transformation=[
  {'width': 500, 'crop': "scale"},
  {'overlay': "video:docs:bluescreen_watches", 'effect': "make_transparent:10", 'color': "#3d8d48", 'width': 1.0, 'flags': "relative"},
  {'duration': "15"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("docs/sunset_waves", {transformation: [
  {width: 500, crop: "scale"},
  {overlay: "video:docs:bluescreen_watches", effect: "make_transparent:10", color: "#3d8d48", width: "1.0", flags: "relative"},
  {duration: "15"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(500).crop("scale").chain()
  .overlay(new Layer().publicId("video:docs:bluescreen_watches")).effect("make_transparent:10").color("#3d8d48").width(1.0).flags("relative").chain()
  .duration("15")).videoTag("docs/sunset_waves");
JS:
Copy to clipboard
cloudinary.videoTag('docs/sunset_waves', {transformation: [
  {width: 500, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:docs:bluescreen_watches"), effect: "make_transparent:10", color: "#3d8d48", width: "1.0", flags: "relative"},
  {duration: "15"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("docs/sunset_waves", {transformation: [
  {width: 500, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:docs:bluescreen_watches"), effect: "make_transparent:10", color: "#3d8d48", width: "1.0", flags: "relative"},
  {duration: "15"}
  ]})
React:
Copy to clipboard
<Video publicId="docs/sunset_waves" >
  <Transformation width="500" crop="scale" />
  <Transformation overlay="video:docs:bluescreen_watches" effect="make_transparent:10" color="#3d8d48" width="1.0" flags="relative" />
  <Transformation duration="15" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="docs/sunset_waves" >
  <cld-transformation width="500" crop="scale" />
  <cld-transformation overlay="video:docs:bluescreen_watches" effect="make_transparent:10" color="#3d8d48" width="1.0" flags="relative" />
  <cld-transformation duration="15" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="docs/sunset_waves" >
  <cl-transformation width="500" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:docs:bluescreen_watches" effect="make_transparent:10" color="#3d8d48" width="1.0" flags="relative">
  </cl-transformation>
  <cl-transformation duration="15">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(500).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:docs:bluescreen_watches")).Effect("make_transparent:10").Color("#3d8d48").Width(1.0).Flags("relative").Chain()
  .Duration("15")).BuildVideoTag("docs/sunset_waves")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(500).crop("scale").chain()
  .overlay(new Layer().publicId("video:docs:bluescreen_watches")).effect("make_transparent:10").color("#3d8d48").width(1.0).flags("relative").chain()
  .duration("15")).resourceType("video").generate("docs/sunset_waves.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(500).setCrop("scale").chain()
  .setOverlay("video:docs:bluescreen_watches").setEffect("make_transparent:10").setColor("#3d8d48").setWidth(1.0).setFlags("relative").chain()
  .setDuration("15")).generate("docs/sunset_waves.mp4")

Generate an AI-based video preview

A video preview is a short excerpt from a video that can be used to engage your audience and help them select the video content that interests them.

The preview transformation effect (e_preview in URLs) generates video previews automatically by activating deep learning algorithms that identify the most interesting video segments. You can optionally control the length of the generated preview using the duration option (default: 5 seconds), and the number and duration of the video segments using the max_seg and min_seg_dur parameters. The three parameters are separated with a colon.

The default number of segments changes if you specify a longer duration, the table below shows the default values:

Preview duration Max segments Minimum segment duration
up to 5 seconds 1 = duration
6 to 10 seconds 3 3 seconds
11 to 15 seconds 4 3 seconds
16 to 20 seconds 5 4 seconds
21 seconds and greater 6 5 seconds

The following transformation generates a single 5 second preview of this video of elephants walking:

Ruby:
Copy to clipboard
cl_video_tag("elephants", :effect=>"preview:duration_5")
PHP:
Copy to clipboard
cl_video_tag("elephants", array("effect"=>"preview:duration_5"))
Python:
Copy to clipboard
CloudinaryVideo("elephants").video(effect="preview:duration_5")
Node.js:
Copy to clipboard
cloudinary.video("elephants", {effect: "preview:duration_5"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().effect("preview:duration_5")).videoTag("elephants");
JS:
Copy to clipboard
cloudinary.videoTag('elephants', {effect: "preview:duration_5"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("elephants", {effect: "preview:duration_5"})
React:
Copy to clipboard
<Video publicId="elephants" >
  <Transformation effect="preview:duration_5" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="elephants" >
  <cld-transformation effect="preview:duration_5" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="elephants" >
  <cl-transformation effect="preview:duration_5">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Effect("preview:duration_5")).BuildVideoTag("elephants")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().effect("preview:duration_5")).resourceType("video").generate("elephants.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setEffect("preview:duration_5")).generate("elephants.mp4")

The following transformation generates a 12 second preview with a maximum of 3 segments and a minimum segment duration of 3 seconds from this ImageCon lecture about responsive images by Jason Grigsby:

Ruby:
Copy to clipboard
cl_video_tag("imagecon_grigsby_intro", :effect=>"preview:duration_12:max_seg_3:min_seg_dur_3")
PHP:
Copy to clipboard
cl_video_tag("imagecon_grigsby_intro", array("effect"=>"preview:duration_12:max_seg_3:min_seg_dur_3"))
Python:
Copy to clipboard
CloudinaryVideo("imagecon_grigsby_intro").video(effect="preview:duration_12:max_seg_3:min_seg_dur_3")
Node.js:
Copy to clipboard
cloudinary.video("imagecon_grigsby_intro", {effect: "preview:duration_12:max_seg_3:min_seg_dur_3"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().effect("preview:duration_12:max_seg_3:min_seg_dur_3")).videoTag("imagecon_grigsby_intro");
JS:
Copy to clipboard
cloudinary.videoTag('imagecon_grigsby_intro', {effect: "preview:duration_12:max_seg_3:min_seg_dur_3"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("imagecon_grigsby_intro", {effect: "preview:duration_12:max_seg_3:min_seg_dur_3"})
React:
Copy to clipboard
<Video publicId="imagecon_grigsby_intro" >
  <Transformation effect="preview:duration_12:max_seg_3:min_seg_dur_3" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="imagecon_grigsby_intro" >
  <cld-transformation effect="preview:duration_12:max_seg_3:min_seg_dur_3" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="imagecon_grigsby_intro" >
  <cl-transformation effect="preview:duration_12:max_seg_3:min_seg_dur_3">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Effect("preview:duration_12:max_seg_3:min_seg_dur_3")).BuildVideoTag("imagecon_grigsby_intro")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().effect("preview:duration_12:max_seg_3:min_seg_dur_3")).resourceType("video").generate("imagecon_grigsby_intro.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setEffect("preview:duration_12:max_seg_3:min_seg_dur_3")).generate("imagecon_grigsby_intro.mp4")

Use case: Thumbnail previews and embedded video player

A common use-case for video previews is to display a selection of different videos as thumbnails, which display a short video preview on hover and open the full video in a video player on click.

The following Code Pen demonstrates this use case where any clicked thumbnail plays in a <div> containting the Cloudinary Video Player. Click the HTML, CSS, or JS tabs to see the code behind this demo.

See the Pen HTML5 Video with Preview Thumbnails by Jackie Rosenzveig (@jackieros) on CodePen.

Tip
This demo does not address mobile browsers that do not support 'hover' functionality. If you want to offer hover previews to web users, it's recommended to capture the device and implement alternative functionality for mobile users. For example, you might add links for mobile users under each thumbnail for 'activate preview' and 'watch video'.

Return video importance histogram

As part of generating the preview, a video importance histogram is created. This histogram is a JSON representation of the importance score for each frame of the video. You can return this histogram and pass it to an external application or to pick out your own key parts of a video using the importance scores.

To return the histogram, use the fl_getinfo flag with e_preview and remove the file extension. Ensure that you don't include any other transformations. For example, to return the importance histogram for the ImageCon video we used above:

Video preview tips and guidelines

  • The preview algorithm analyzes the entire video to determine the ideal segment(s) to use, which means it can take several seconds or minutes, depending on the length of the original video, to generate your preview. Therefore, it's recommended to generate the preview effect transformation eagerly during upload or using an explicit method call for existing videos, along with an eager_notification_url parameter to notify your application when the video preview transformation is ready for delivery.

  • As explained above, dynamic delivery of this transformation is not relevant in production. However, for experimentation purposes, you can add the e_preview parameter directly to a URL in your browser. In most cases, the immediate result will be a broken video (An HTTP 423 error will be returned). Refresh your browser after several seconds or minutes to see the result. Once the initial analysis has been completed, any subsequent transformations will happen on-the-fly as usual.

  • When generating video previews, keep in mind that the AI algorithm takes the requested preview duration into account when selecting the most relevant content. Therefore, when you set a different preview duration for the same video, different segments of your video may be selected.

  • As with any video, you can transcode your generated preview to an animated image (.gif or animated .webp) by changing the URL extension or using the format SDK parameter. Remember that animated images that were transcoded from video (and thus have a resource_type of video) only run a single time by default. If you want the animated image to loop, add a new component to your transformation chain with the loop effect. For example:

    Ruby:
    Copy to clipboard
    cl_image_tag("Marketing/digital-asset-management-with-cloudinary.gif", :resource_type=>"video", :transformation=>[
      {:effect=>"preview:duration_8"},
      {:width=>1600, :height=>800, :effect=>"loop", :crop=>"crop"}
      ])
    PHP:
    Copy to clipboard
    cl_image_tag("Marketing/digital-asset-management-with-cloudinary.gif", array("resource_type"=>"video", "transformation"=>array(
      array("effect"=>"preview:duration_8"),
      array("width"=>1600, "height"=>800, "effect"=>"loop", "crop"=>"crop")
      )))
    Python:
    Copy to clipboard
    CloudinaryVideo("Marketing/digital-asset-management-with-cloudinary.gif").image(transformation=[
      {'effect': "preview:duration_8"},
      {'width': 1600, 'height': 800, 'effect': "loop", 'crop': "crop"}
      ])
    Node.js:
    Copy to clipboard
    cloudinary.image("Marketing/digital-asset-management-with-cloudinary.gif", {resource_type: "video", transformation: [
      {effect: "preview:duration_8"},
      {width: 1600, height: 800, effect: "loop", crop: "crop"}
      ]})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation()
      .effect("preview:duration_8").chain()
      .width(1600).height(800).effect("loop").crop("crop")).resourceType("video").imageTag("Marketing/digital-asset-management-with-cloudinary.gif");
    JS:
    Copy to clipboard
    cloudinary.videoTag('Marketing/digital-asset-management-with-cloudinary.gif', {transformation: [
      {effect: "preview:duration_8"},
      {width: 1600, height: 800, effect: "loop", crop: "crop"}
      ]}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.image("Marketing/digital-asset-management-with-cloudinary.gif", {resource_type: "video", transformation: [
      {effect: "preview:duration_8"},
      {width: 1600, height: 800, effect: "loop", crop: "crop"}
      ]})
    React:
    Copy to clipboard
    <Video publicId="Marketing/digital-asset-management-with-cloudinary.gif" resourceType="video">
      <Transformation effect="preview:duration_8" />
      <Transformation width="1600" height="800" effect="loop" crop="crop" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="Marketing/digital-asset-management-with-cloudinary.gif" resourceType="video">
      <cld-transformation effect="preview:duration_8" />
      <cld-transformation width="1600" height="800" effect="loop" crop="crop" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="Marketing/digital-asset-management-with-cloudinary.gif" resource-type="video">
      <cl-transformation effect="preview:duration_8">
      </cl-transformation>
      <cl-transformation width="1600" height="800" effect="loop" crop="crop">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation()
      .Effect("preview:duration_8").Chain()
      .Width(1600).Height(800).Effect("loop").Crop("crop")).BuildImageTag("Marketing/digital-asset-management-with-cloudinary.gif")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation()
      .effect("preview:duration_8").chain()
      .width(1600).height(800).effect("loop").crop("crop")).resourceType("video").generate("Marketing/digital-asset-management-with-cloudinary.gif");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
      .setEffect("preview:duration_8").chain()
      .setWidth(1600).setHeight(800).setEffect("loop").setCrop("crop")).generate("Marketing/digital-asset-management-with-cloudinary.gif")
    animated gif preview

Add visual noise

Use the noise video effect (e_noise in URLs) to add visual noise to a video. Noise is a random pattern superimposed on the video, visible as a random flicker of "dots" or "snow". The amount of noise added to the video is set by adding an integer value to the parameter, ranging from 0 (no noise) up to 100.

For example, applying the noise effect with a value of 50 to the mp4 video named dog, resized to a width of 300 pixels:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>300, :effect=>"noise:50", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>300, "effect"=>"noise:50", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=300, effect="noise:50", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 300, effect: "noise:50", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).effect("noise:50").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 300, effect: "noise:50", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 300, effect: "noise:50", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="300" effect="noise:50" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="300" effect="noise:50" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="300" effect="noise:50" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Effect("noise:50").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).effect("noise:50").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setEffect("noise:50").setCrop("scale")).generate("dog.mp4")

Remove small motion shifts

The deshake video effect (e_deshake in URLs) applies a filter that attempts to fix small changes in horizontal and vertical motion shift. This filter helps remove camera shake from hand-holding a camera, bumping a tripod, moving on a vehicle, etc. A value between 0-64 can also be specified that determines the maximum extent of movement in the horizontal and/or vertical direction in pixels, with the default set to 16 pixels.

For example, applying the deshake effect with a maximum motion shift of 32 pixels to the mp4 video named dog:

Ruby:
Copy to clipboard
cl_video_tag("dog", :effect=>"deshake:32")
PHP:
Copy to clipboard
cl_video_tag("dog", array("effect"=>"deshake:32"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(effect="deshake:32")
Node.js:
Copy to clipboard
cloudinary.video("dog", {effect: "deshake:32"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().effect("deshake:32")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {effect: "deshake:32"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {effect: "deshake:32"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation effect="deshake:32" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation effect="deshake:32" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation effect="deshake:32">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Effect("deshake:32")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().effect("deshake:32")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setEffect("deshake:32")).generate("dog.mp4")

Fade in and out

Use the fade video effect (e_fade in URLs) to either fade in at the beginning of a video or fade out at the end. The effect accepts a parameter that determines the duration of the fade effect in milliseconds, with a positive value for fading in at the beginning of the video, and a negative value for fading out at the end of the video. The fade effect can also be chained to allow for both fading in and then fading out of a video.

For example, applying the fade effect to the mp4 video named dog, first by fading in at the beginning of the video over 2 seconds and then fading out at the end of the video over 4 seconds:

Ruby:
Copy to clipboard
cl_video_tag("dog", :transformation=>[
  {:effect=>"fade:2000"},
  {:effect=>"fade:-4000"}
  ])
PHP:
Copy to clipboard
cl_video_tag("dog", array("transformation"=>array(
  array("effect"=>"fade:2000"),
  array("effect"=>"fade:-4000")
  )))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(transformation=[
  {'effect': "fade:2000"},
  {'effect': "fade:-4000"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("dog", {transformation: [
  {effect: "fade:2000"},
  {effect: "fade:-4000"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .effect("fade:2000").chain()
  .effect("fade:-4000")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {transformation: [
  {effect: "fade:2000"},
  {effect: "fade:-4000"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {transformation: [
  {effect: "fade:2000"},
  {effect: "fade:-4000"}
  ]})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation effect="fade:2000" />
  <Transformation effect="fade:-4000" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation effect="fade:2000" />
  <cld-transformation effect="fade:-4000" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation effect="fade:2000">
  </cl-transformation>
  <cl-transformation effect="fade:-4000">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Effect("fade:2000").Chain()
  .Effect("fade:-4000")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .effect("fade:2000").chain()
  .effect("fade:-4000")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setEffect("fade:2000").chain()
  .setEffect("fade:-4000")).generate("dog.mp4")

The fade effect is also useful for fading in and out of video overlays. For example, adding an overlay of kitten_fighting scaled to a width of 100 pixels to the mp4 video named dog, that fades in over 3 seconds:

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>"video:kitten_fighting", :effect=>"fade:3000", :width=>100)
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>"video:kitten_fighting", "effect"=>"fade:3000", "width"=>100))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay="video:kitten_fighting", effect="fade:3000", width=100)
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: "video:kitten_fighting", effect: "fade:3000", width: 100})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("video:kitten_fighting")).effect("fade:3000").width(100)).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.Layer().publicId("video:kitten_fighting"), effect: "fade:3000", width: 100}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.Layer().publicId("video:kitten_fighting"), effect: "fade:3000", width: 100})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay="video:kitten_fighting" effect="fade:3000" width="100" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay="video:kitten_fighting" effect="fade:3000" width="100" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="video:kitten_fighting" effect="fade:3000" width="100">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("video:kitten_fighting")).Effect("fade:3000").Width(100)).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("video:kitten_fighting")).effect("fade:3000").width(100)).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("video:kitten_fighting").setEffect("fade:3000").setWidth(100)).generate("dog.mp4")

Blur your video

Use the blur video effect to add a level of blurriness to a video. You can control the strength of the blur with a parameter (range: 1 to 2000). When working with video overlays, you can also add the blur to the container or to the overlay.

For example, the container video plays a blurred version of the video, while a smaller overlay plays the video clearly:

Ruby:
Copy to clipboard
cl_video_tag("dog", :transformation=>[
  {:effect=>"blur:500"},
  {:overlay=>"video:dog", :width=>600},
  {:width=>500, :crop=>"scale"}
  ])
PHP:
Copy to clipboard
cl_video_tag("dog", array("transformation"=>array(
  array("effect"=>"blur:500"),
  array("overlay"=>"video:dog", "width"=>600),
  array("width"=>500, "crop"=>"scale")
  )))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(transformation=[
  {'effect': "blur:500"},
  {'overlay': "video:dog", 'width': 600},
  {'width': 500, 'crop': "scale"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("dog", {transformation: [
  {effect: "blur:500"},
  {overlay: "video:dog", width: 600},
  {width: 500, crop: "scale"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .effect("blur:500").chain()
  .overlay(new Layer().publicId("video:dog")).width(600).chain()
  .width(500).crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {transformation: [
  {effect: "blur:500"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 600},
  {width: 500, crop: "scale"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {transformation: [
  {effect: "blur:500"},
  {overlay: new cloudinary.Layer().publicId("video:dog"), width: 600},
  {width: 500, crop: "scale"}
  ]})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation effect="blur:500" />
  <Transformation overlay="video:dog" width="600" />
  <Transformation width="500" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation effect="blur:500" />
  <cld-transformation overlay="video:dog" width="600" />
  <cld-transformation width="500" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation effect="blur:500">
  </cl-transformation>
  <cl-transformation overlay="video:dog" width="600">
  </cl-transformation>
  <cl-transformation width="500" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Effect("blur:500").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Width(600).Chain()
  .Width(500).Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .effect("blur:500").chain()
  .overlay(new Layer().publicId("video:dog")).width(600).chain()
  .width(500).crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setEffect("blur:500").chain()
  .setOverlay("video:dog").setWidth(600).chain()
  .setWidth(500).setCrop("scale")).generate("dog.mp4")

Tip
There's also an option to use a blurred version of your video in the background when the video's aspect ratio is different than the video player dimensions you specify. To do this, use the pad cropping option and set the background value to blurred. For details, see pad with blurred video background

Calibrate contrast

Use the contrast video effect (e_contrast in URLs) to either increase or decrease the contrast level in a video. Contrast is determined by the difference in brightness and color that makes objects within the video distinguishable from other objects within the same video. The contrast level can be decreased down to -300 or increased up to +100, with a default level of 0.

For example, applying the contrast effect to the mp4 video named dog, by increasing the contrast level by 50:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>500, :effect=>"contrast:50", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>500, "effect"=>"contrast:50", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=500, effect="contrast:50", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 500, effect: "contrast:50", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(500).effect("contrast:50").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 500, effect: "contrast:50", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 500, effect: "contrast:50", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="500" effect="contrast:50" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="500" effect="contrast:50" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="500" effect="contrast:50" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(500).Effect("contrast:50").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(500).effect("contrast:50").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(500).setEffect("contrast:50").setCrop("scale")).generate("dog.mp4")

Control brightness

Use the brightness video effect (e_brightness in URLs) to either increase or decrease the brightness level in a video. Brightness determines how much the objects in a video appear to be radiating light. The brightness level can be decreased down to -100 or increased up to +100, with a default level of 0.

For example, applying the brightness effect to the mp4 video named dog, by increasing the brightness level by 30:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>500, :effect=>"brightness:30", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>500, "effect"=>"brightness:30", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=500, effect="brightness:30", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 500, effect: "brightness:30", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(500).effect("brightness:30").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 500, effect: "brightness:30", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 500, effect: "brightness:30", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="500" effect="brightness:30" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="500" effect="brightness:30" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="500" effect="brightness:30" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(500).Effect("brightness:30").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(500).effect("brightness:30").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(500).setEffect("brightness:30").setCrop("scale")).generate("dog.mp4")

Balance saturation

Use the saturation video effect (e_saturation in URLs) to either increase or decrease the saturation level in a video. Saturation determines the colorfulness of objects relative to their brightness. The saturation level can be decreased down to -200 or increased up to +100, with a default level of 0.

For example, applying the saturation effect to the mp4 video named dog, by decreasing the saturation level by -50:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>500, :effect=>"saturation:-50", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>500, "effect"=>"saturation:-50", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=500, effect="saturation:-50", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 500, effect: "saturation:-50", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(500).effect("saturation:-50").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 500, effect: "saturation:-50", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 500, effect: "saturation:-50", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="500" effect="saturation:-50" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="500" effect="saturation:-50" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="500" effect="saturation:-50" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(500).Effect("saturation:-50").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(500).effect("saturation:-50").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(500).setEffect("saturation:-50").setCrop("scale")).generate("dog.mp4")

Regulate gamma

Use the gamma video effect (e_gamma in URLs) to either increase or decrease the gamma level in a video. Gamma determines the relative luminance of objects within the video. The gamma level can be decreased down to a -100 or increased up to +100, with a default level of 0.

For example, applying the gamma effect to the mp4 video named dog, by decreasing the gamma level to -20:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>500, :effect=>"gamma:-20", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>500, "effect"=>"gamma:-20", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=500, effect="gamma:-20", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 500, effect: "gamma:-20", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(500).effect("gamma:-20").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 500, effect: "gamma:-20", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 500, effect: "gamma:-20", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="500" effect="gamma:-20" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="500" effect="gamma:-20" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="500" effect="gamma:-20" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(500).Effect("gamma:-20").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(500).effect("gamma:-20").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(500).setEffect("gamma:-20").setCrop("scale")).generate("dog.mp4")

Apply vignette

Use the vignette video effect (e_vignette in URLs) to apply a vignette filter to a video. The vignette filter creates an effect where the video is clear in the center and fades out towards the edges. The vignette effect parameter accepts a value between 0 and 100 to determine how quickly the video fades out from a clear center.

For example, applying the vignette effect with a level of 50 to the mp4 video named dog:

Ruby:
Copy to clipboard
cl_video_tag("dog", :width=>500, :effect=>"vignette:50", :crop=>"scale")
PHP:
Copy to clipboard
cl_video_tag("dog", array("width"=>500, "effect"=>"vignette:50", "crop"=>"scale"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(width=500, effect="vignette:50", crop="scale")
Node.js:
Copy to clipboard
cloudinary.video("dog", {width: 500, effect: "vignette:50", crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(500).effect("vignette:50").crop("scale")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {width: 500, effect: "vignette:50", crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {width: 500, effect: "vignette:50", crop: "scale"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation width="500" effect="vignette:50" crop="scale" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation width="500" effect="vignette:50" crop="scale" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation width="500" effect="vignette:50" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(500).Effect("vignette:50").Crop("scale")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(500).effect("vignette:50").crop("scale")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(500).setEffect("vignette:50").setCrop("scale")).generate("dog.mp4")

Generating video thumbnails

Cloudinary makes it easy to deliver image thumbnails of any frame within an uploaded video by simply specifying the image format needed as the file extension of the URL (e.g. jpg, png, webp, wdp).

For example, generating a JPG image thumbnail URL of the uploaded mp4 video named dog:

Ruby:
Copy to clipboard
cl_image_tag("dog.jpg", :resource_type=>"video")
PHP:
Copy to clipboard
cl_image_tag("dog.jpg", array("resource_type"=>"video"))
Python:
Copy to clipboard
CloudinaryVideo("dog.jpg").image()
Node.js:
Copy to clipboard
cloudinary.image("dog.jpg", {resource_type: "video"})
Java:
Copy to clipboard
cloudinary.url().resourceType("video").imageTag("dog.jpg");
JS:
Copy to clipboard
cloudinary.videoTag('dog.jpg').toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("dog.jpg", {resource_type: "video"})
React:
Copy to clipboard
<Video publicId="dog.jpg" resourceType="video">

</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog.jpg" resourceType="video">

</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog.jpg" resource-type="video">

</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.BuildImageTag("dog.jpg")
Android:
Copy to clipboard
MediaManager.get().url().resourceType("video").generate("dog.jpg");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").generate("dog.jpg")
JPG thumbnail from dog.mp4

To control which frame is captured from the video as a thumbnail (the middle frame is selected by default), use the start_offset parameter (so in URLs) with one of the following values:

  • A float representing the time in seconds from the beginning of the video e.g. 5.44.
  • A string representing the percentage of the video from the beginning. This string consists of a number with a p appended e.g. 35p (0p is the first frame and 100p is the last frame). The client libraries also support appending a % instead of a p.
  • A value of auto which automatically selects a frame that best matches the average value of a color distribution analysis of the first few seconds of the video, making it more likely to display a typical frame.

For example, generating a JPG image thumbnail of the frame at 8.5 seconds in the uploaded mp4 video named dog:

Ruby:
Copy to clipboard
cl_image_tag("dog.jpg", :start_offset=>"8.5", :resource_type=>"video")
PHP:
Copy to clipboard
cl_image_tag("dog.jpg", array("start_offset"=>"8.5", "resource_type"=>"video"))
Python:
Copy to clipboard
CloudinaryVideo("dog.jpg").image(start_offset="8.5")
Node.js:
Copy to clipboard
cloudinary.image("dog.jpg", {start_offset: "8.5", resource_type: "video"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().startOffset("8.5")).resourceType("video").imageTag("dog.jpg");
JS:
Copy to clipboard
cloudinary.videoTag('dog.jpg', {startOffset: "8.5"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("dog.jpg", {start_offset: "8.5", resource_type: "video"})
React:
Copy to clipboard
<Video publicId="dog.jpg" resourceType="video">
  <Transformation startOffset="8.5" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog.jpg" resourceType="video">
  <cld-transformation startOffset="8.5" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog.jpg" resource-type="video">
  <cl-transformation start-offset="8.5">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("8.5")).BuildImageTag("dog.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().startOffset("8.5")).resourceType("video").generate("dog.jpg");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("8.5")).generate("dog.jpg")
JPG thumbnail of dog.mp4 at 5.5 seconds

Once generated, the thumbnail image supports further manipulation as any other image (see image transformations for more details).

For example, generating a cropped JPG image thumbnail with a width and height of 350 pixels, of the frame at 4 seconds in the uploaded mp4 video named dog. The image is also rendered in gray scale, with rounded corners and a 5 pixel wide black border:

Ruby:
Copy to clipboard
cl_image_tag("dog.jpg", :start_offset=>"4", :width=>350, :height=>350, :radius=>20, :effect=>"grayscale", :border=>"5px_solid_black", :crop=>"crop", :resource_type=>"video")
PHP:
Copy to clipboard
cl_image_tag("dog.jpg", array("start_offset"=>"4", "width"=>350, "height"=>350, "radius"=>20, "effect"=>"grayscale", "border"=>"5px_solid_black", "crop"=>"crop", "resource_type"=>"video"))
Python:
Copy to clipboard
CloudinaryVideo("dog.jpg").image(start_offset="4", width=350, height=350, radius=20, effect="grayscale", border="5px_solid_black", crop="crop")
Node.js:
Copy to clipboard
cloudinary.image("dog.jpg", {start_offset: "4", width: 350, height: 350, radius: 20, effect: "grayscale", border: "5px_solid_black", crop: "crop", resource_type: "video"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().startOffset("4").width(350).height(350).radius(20).effect("grayscale").border("5px_solid_black").crop("crop")).resourceType("video").imageTag("dog.jpg");
JS:
Copy to clipboard
cloudinary.videoTag('dog.jpg', {startOffset: "4", width: 350, height: 350, radius: 20, effect: "grayscale", border: "5px_solid_black", crop: "crop"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("dog.jpg", {start_offset: "4", width: 350, height: 350, radius: 20, effect: "grayscale", border: "5px_solid_black", crop: "crop", resource_type: "video"})
React:
Copy to clipboard
<Video publicId="dog.jpg" resourceType="video">
  <Transformation startOffset="4" width="350" height="350" radius="20" effect="grayscale" border="5px_solid_black" crop="crop" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog.jpg" resourceType="video">
  <cld-transformation startOffset="4" width="350" height="350" radius="20" effect="grayscale" border="5px_solid_black" crop="crop" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog.jpg" resource-type="video">
  <cl-transformation start-offset="4" width="350" height="350" radius="20" effect="grayscale" border="5px_solid_black" crop="crop">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("4").Width(350).Height(350).Radius(20).Effect("grayscale").Border("5px_solid_black").Crop("crop")).BuildImageTag("dog.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().startOffset("4").width(350).height(350).radius(20).effect("grayscale").border("5px_solid_black").crop("crop")).resourceType("video").generate("dog.jpg");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("4").setWidth(350).setHeight(350).setRadius(20).setEffect("grayscale").setBorder("5px_solid_black").setCrop("crop")).generate("dog.jpg")
300x300 JPG thumbnail of dog.mp4 at 4 seconds

Adding image overlays

Add an overlay image over the video with the overlay parameter (l in URLs) and the public ID of a previously uploaded PNG image (e.g. l_watermark for an image with the public ID of watermark). You can determine the dimension and position of the overlay using the width, height, x, y and gravity parameters the same way as used for images (see Adding watermarks, credits, badges and text overlays to images for more details). Furthermore, it is possible to control when the overlay is displayed by using any combination of the 3 offset parameters (see Trimming videos for more information on the parameters and their possible values). The overlay can also be further manipulated like any other image uploaded to Cloudinary

For example, adding an overlay of a PNG image called cloudinary_icon to the mp4 video named dog, that appears after 6.5 seconds and disappears at the 10 second mark. The overlay is also made into a watermark by reducing the opacity to 50 using the o parameter and increasing the brightness to 200% using the e_brightness effect:

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>"cloudinary_icon", :start_offset=>"6.5", :end_offset=>"10", :opacity=>50, :effect=>"brightness:200")
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>"cloudinary_icon", "start_offset"=>"6.5", "end_offset"=>"10", "opacity"=>50, "effect"=>"brightness:200"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay="cloudinary_icon", start_offset="6.5", end_offset="10", opacity=50, effect="brightness:200")
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: "cloudinary_icon", start_offset: "6.5", end_offset: "10", opacity: 50, effect: "brightness:200"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("cloudinary_icon")).startOffset("6.5").endOffset("10").opacity(50).effect("brightness:200")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.Layer().publicId("cloudinary_icon"), startOffset: "6.5", endOffset: "10", opacity: 50, effect: "brightness:200"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.Layer().publicId("cloudinary_icon"), start_offset: "6.5", end_offset: "10", opacity: 50, effect: "brightness:200"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay="cloudinary_icon" startOffset="6.5" endOffset="10" opacity="50" effect="brightness:200" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay="cloudinary_icon" startOffset="6.5" endOffset="10" opacity="50" effect="brightness:200" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="cloudinary_icon" start-offset="6.5" end-offset="10" opacity="50" effect="brightness:200">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("cloudinary_icon")).StartOffset("6.5").EndOffset("10").Opacity(50).Effect("brightness:200")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("cloudinary_icon")).startOffset("6.5").endOffset("10").opacity(50).effect("brightness:200")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("cloudinary_icon").setStartOffset("6.5").setEndOffset("10").setOpacity(50).setEffect("brightness:200")).generate("dog.mp4")

Adding video overlays

Add another video as an overlay over the container video by using the overlay video parameter (l_video: in URLs) and the public ID of a previously uploaded video (e.g. l_video:dog for a video with the public ID of dog). You can determine the dimension and position of the video overlay using the width, height, x, y and gravity parameters the same way as used for images (see Adding image overlays for more details). Furthermore, it is possible to control when the video overlay is displayed by using any combination of the 3 offset parameters (see Trimming videos for more information on the parameters and their possible values). The overlay can also be further manipulated like any other video uploaded to Cloudinary.

For example, adding an overlay of a video named dog to the same mp4 video named dog, that appears after 4.5 seconds and disappears at the 8 second mark. The overlay is also rotated by 90 degrees, set with a gravity of 'east' and scaled to a width of 200 pixels.

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>"video:dog", :start_offset=>"4.5", :end_offset=>"8", :angle=>90, :width=>200, :gravity=>"east")
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>"video:dog", "start_offset"=>"4.5", "end_offset"=>"8", "angle"=>90, "width"=>200, "gravity"=>"east"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay="video:dog", start_offset="4.5", end_offset="8", angle=90, width=200, gravity="east")
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: "video:dog", start_offset: "4.5", end_offset: "8", angle: 90, width: 200, gravity: "east"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("video:dog")).startOffset("4.5").endOffset("8").angle(90).width(200).gravity("east")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.Layer().publicId("video:dog"), startOffset: "4.5", endOffset: "8", angle: 90, width: 200, gravity: "east"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.Layer().publicId("video:dog"), start_offset: "4.5", end_offset: "8", angle: 90, width: 200, gravity: "east"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay="video:dog" startOffset="4.5" endOffset="8" angle="90" width="200" gravity="east" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay="video:dog" startOffset="4.5" endOffset="8" angle="90" width="200" gravity="east" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="video:dog" start-offset="4.5" end-offset="8" angle="90" width="200" gravity="east">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("video:dog")).StartOffset("4.5").EndOffset("8").Angle(90).Width(200).Gravity("east")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("video:dog")).startOffset("4.5").endOffset("8").angle(90).width(200).gravity("east")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("video:dog").setStartOffset("4.5").setEndOffset("8").setAngle(90).setWidth(200).setGravity("east")).generate("dog.mp4")

Adding text captions

Add a text caption over the video with the text: property of the overlay parameter ( l_text: in URLs), followed by the font name and size (separated with an underscore), a colon, and then the text string to display. For example, to overlay the text string "Sample Video" in the Arial font with a size of 40 pixels:l_text:arial_40:Sample Video.

As for displaying image overlays, you can also determine the dimension and position of the text caption using the width, height, x, y and gravity parameters and control when the caption is displayed by using any combination of the 3 offset parameters (see Trimming videos for more information on the parameters and their possible values). The resulting caption is actually an image created on the fly and can be further manipulated like any other image uploaded to Cloudinary.

For example, adding the text string "Cool Video" in 60 pt Arial font at a distance of 80 pixels from the bottom of the mp4 video named dog, that appears after 2 seconds and disappears at the 5 second mark:

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>{:font_family=>"arial", :font_size=>60, :text=>"Cool%20Video"}, :gravity=>"south", :y=>80, :start_offset=>"2", :end_offset=>"5")
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>array("font_family"=>"arial", "font_size"=>60, "text"=>"Cool%20Video"), "gravity"=>"south", "y"=>80, "start_offset"=>"2", "end_offset"=>"5"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay={'font_family': "arial", 'font_size': 60, 'text': "Cool%20Video"}, gravity="south", y=80, start_offset="2", end_offset="5")
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: {font_family: "arial", font_size: 60, text: "Cool%20Video"}, gravity: "south", y: 80, start_offset: "2", end_offset: "5"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new TextLayer().fontFamily("arial").fontSize(60).text("Cool%20Video")).gravity("south").y(80).startOffset("2").endOffset("5")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.TextLayer().fontFamily("arial").fontSize(60).text("Cool%20Video"), gravity: "south", y: 80, startOffset: "2", endOffset: "5"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.TextLayer().fontFamily("arial").fontSize(60).text("Cool%20Video"), gravity: "south", y: 80, start_offset: "2", end_offset: "5"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay={{fontFamily: "arial", fontSize: 60, text: "Cool%20Video"}} gravity="south" y="80" startOffset="2" endOffset="5" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay={{fontFamily: "arial", fontSize: 60, text: "Cool%20Video"}} gravity="south" y="80" startOffset="2" endOffset="5" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="text:arial_60:Cool%20Video" gravity="south" y="80" start-offset="2" end-offset="5">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new TextLayer().FontFamily("arial").FontSize(60).Text("Cool%20Video")).Gravity("south").Y(80).StartOffset("2").EndOffset("5")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new TextLayer().fontFamily("arial").fontSize(60).text("Cool%20Video")).gravity("south").y(80).startOffset("2").endOffset("5")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("text:arial_60:Cool%20Video").setGravity("south").setY(80).setStartOffset("2").setEndOffset("5")).generate("dog.mp4")

Multiple overlays can easily be added to a video. The following example adds both an image overlay and a text caption to the mp4 video named dog as follows:

  1. An overlay of a PNG image called cloudinary_icon with a width of 200 pixels on the east side of the video, that appears after 1 second, and disappears at the 11 second mark.
  2. The text string "Sample Video" in 40 pt Arial font at a distance of 60 pixels from the bottom of the video, that appears after 2 seconds.
    Ruby:
    Copy to clipboard
    cl_video_tag("dog", :transformation=>[
      {:overlay=>"cloudinary_icon", :width=>200, :gravity=>"east", :start_offset=>"1", :end_offset=>"11"},
      {:overlay=>{:font_family=>"arial", :font_size=>40, :text=>"Sample%20Video"}, :gravity=>"south", :y=>60, :start_offset=>"2"}
      ])
    PHP:
    Copy to clipboard
    cl_video_tag("dog", array("transformation"=>array(
      array("overlay"=>"cloudinary_icon", "width"=>200, "gravity"=>"east", "start_offset"=>"1", "end_offset"=>"11"),
      array("overlay"=>array("font_family"=>"arial", "font_size"=>40, "text"=>"Sample%20Video"), "gravity"=>"south", "y"=>60, "start_offset"=>"2")
      )))
    Python:
    Copy to clipboard
    CloudinaryVideo("dog").video(transformation=[
      {'overlay': "cloudinary_icon", 'width': 200, 'gravity': "east", 'start_offset': "1", 'end_offset': "11"},
      {'overlay': {'font_family': "arial", 'font_size': 40, 'text': "Sample%20Video"}, 'gravity': "south", 'y': 60, 'start_offset': "2"}
      ])
    Node.js:
    Copy to clipboard
    cloudinary.video("dog", {transformation: [
      {overlay: "cloudinary_icon", width: 200, gravity: "east", start_offset: "1", end_offset: "11"},
      {overlay: {font_family: "arial", font_size: 40, text: "Sample%20Video"}, gravity: "south", y: 60, start_offset: "2"}
      ]})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation()
      .overlay(new Layer().publicId("cloudinary_icon")).width(200).gravity("east").startOffset("1").endOffset("11").chain()
      .overlay(new TextLayer().fontFamily("arial").fontSize(40).text("Sample%20Video")).gravity("south").y(60).startOffset("2")).videoTag("dog");
    JS:
    Copy to clipboard
    cloudinary.videoTag('dog', {transformation: [
      {overlay: new cloudinary.Layer().publicId("cloudinary_icon"), width: 200, gravity: "east", startOffset: "1", endOffset: "11"},
      {overlay: new cloudinary.TextLayer().fontFamily("arial").fontSize(40).text("Sample%20Video"), gravity: "south", y: 60, startOffset: "2"}
      ]}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.video("dog", {transformation: [
      {overlay: new cloudinary.Layer().publicId("cloudinary_icon"), width: 200, gravity: "east", start_offset: "1", end_offset: "11"},
      {overlay: new cloudinary.TextLayer().fontFamily("arial").fontSize(40).text("Sample%20Video"), gravity: "south", y: 60, start_offset: "2"}
      ]})
    React:
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation overlay="cloudinary_icon" width="200" gravity="east" startOffset="1" endOffset="11" />
      <Transformation overlay={{fontFamily: "arial", fontSize: 40, text: "Sample%20Video"}} gravity="south" y="60" startOffset="2" />
    </Video>
    Vue.js:
    Copy to clipboard
    <cld-video publicId="dog" >
      <cld-transformation overlay="cloudinary_icon" width="200" gravity="east" startOffset="1" endOffset="11" />
      <cld-transformation overlay={{fontFamily: "arial", fontSize: 40, text: "Sample%20Video"}} gravity="south" y="60" startOffset="2" />
    </cld-video>
    Angular:
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation overlay="cloudinary_icon" width="200" gravity="east" start-offset="1" end-offset="11">
      </cl-transformation>
      <cl-transformation overlay="text:arial_40:Sample%20Video" gravity="south" y="60" start-offset="2">
      </cl-transformation>
    </cl-video>
    .Net:
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation()
      .Overlay(new Layer().PublicId("cloudinary_icon")).Width(200).Gravity("east").StartOffset("1").EndOffset("11").Chain()
      .Overlay(new TextLayer().FontFamily("arial").FontSize(40).Text("Sample%20Video")).Gravity("south").Y(60).StartOffset("2")).BuildVideoTag("dog")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation()
      .overlay(new Layer().publicId("cloudinary_icon")).width(200).gravity("east").startOffset("1").endOffset("11").chain()
      .overlay(new TextLayer().fontFamily("arial").fontSize(40).text("Sample%20Video")).gravity("south").y(60).startOffset("2")).resourceType("video").generate("dog.mp4");
    iOS:
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
      .setOverlay("cloudinary_icon").setWidth(200).setGravity("east").setStartOffset("1").setEndOffset("11").chain()
      .setOverlay("text:arial_40:Sample%20Video").setGravity("south").setY(60).setStartOffset("2")).generate("dog.mp4")

Adding subtitles

You can add subtitles to videos from SRT or WebVTT files previously uploaded to Cloudinary as raw files with the subtitles: property of the overlay parameter ( l_subtitles: in URLs), followed by the public ID (including the .srt or .vtt extension).

For example, to overlay the subtitles in the sample_sub_en.srt file to the mp4 video named dog:

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>{:public_id=>"sample_sub_en.srt"})
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>array("public_id"=>"sample_sub_en.srt")))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay={'public_id': "sample_sub_en.srt"})
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: {public_id: "sample_sub_en.srt"}})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new SubtitlesLayer().publicId("sample_sub_en.srt"))).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.SubtitlesLayer().publicId("sample_sub_en.srt")}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.SubtitlesLayer().publicId("sample_sub_en.srt")})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay={{publicId: "sample_sub_en.srt"}} />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay={{publicId: "sample_sub_en.srt"}} />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="subtitles:sample_sub_en.srt">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new SubtitlesLayer().PublicId("sample_sub_en.srt"))).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new SubtitlesLayer().publicId("sample_sub_en.srt"))).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("subtitles:sample_sub_en.srt")).generate("dog.mp4")

You can also optionally include font and size settings (separated with an underscore) before the subtitles file name. For example, to overlay the subtitles in the sample_sub_en.srt file to the mp4 video named dog, using the Arial font with a size of 20 pixels:

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>{:font_family=>"arial", :font_size=>20, :public_id=>"sample_sub_en.srt"})
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>array("font_family"=>"arial", "font_size"=>20, "public_id"=>"sample_sub_en.srt")))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay={'font_family': "arial", 'font_size': 20, 'public_id': "sample_sub_en.srt"})
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: {font_family: "arial", font_size: 20, public_id: "sample_sub_en.srt"}})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new SubtitlesLayer().fontFamily("arial").fontSize(20).publicId("sample_sub_en.srt"))).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.SubtitlesLayer().fontFamily("arial").fontSize(20).publicId("sample_sub_en.srt")}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.SubtitlesLayer().fontFamily("arial").fontSize(20).publicId("sample_sub_en.srt")})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay={{fontFamily: "arial", fontSize: 20, publicId: "sample_sub_en.srt"}} />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay={{fontFamily: "arial", fontSize: 20, publicId: "sample_sub_en.srt"}} />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="subtitles:arial_20:sample_sub_en.srt">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new SubtitlesLayer().FontFamily("arial").FontSize(20).PublicId("sample_sub_en.srt"))).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new SubtitlesLayer().fontFamily("arial").fontSize(20).publicId("sample_sub_en.srt"))).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("subtitles:arial_20:sample_sub_en.srt")).generate("dog.mp4")

You can also control the color of the text by adding the color property (co in URLs) to change the fill color of the text, and adding the background property (b in URLs) to change the color of the text background. Colors can be set as an RGB hex triplet (e.g. b_rgb:3e2222), a 3 character RGB hex (e.g. co_rgb:777) or a named color (e.g. b_green). You can also use a RGB hex quadruplet, where the 4th value represents the opacity (e.g. b_rgb:3e222266). Cloudinary's client libraries also support a # shortcut for RGB (e.g. setting the color to #3e2222 which is then translated to b_rgb:3e2222).

For example, to overlay the subtitles in the sample_sub_en.srt file on to the mp4 video named dog, using the Arial font with a size of 70 pixels, in yellow text (FFFF00) with a black background:

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>{:font_family=>"arial", :font_size=>70, :public_id=>"sample_sub_en.srt"}, :color=>"#ffff00", :background=>"black")
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>array("font_family"=>"arial", "font_size"=>70, "public_id"=>"sample_sub_en.srt"), "color"=>"#ffff00", "background"=>"black"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay={'font_family': "arial", 'font_size': 70, 'public_id': "sample_sub_en.srt"}, color="#ffff00", background="black")
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: {font_family: "arial", font_size: 70, public_id: "sample_sub_en.srt"}, color: "#ffff00", background: "black"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new SubtitlesLayer().fontFamily("arial").fontSize(70).publicId("sample_sub_en.srt")).color("#ffff00").background("black")).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.SubtitlesLayer().fontFamily("arial").fontSize(70).publicId("sample_sub_en.srt"), color: "#ffff00", background: "black"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.SubtitlesLayer().fontFamily("arial").fontSize(70).publicId("sample_sub_en.srt"), color: "#ffff00", background: "black"})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay={{fontFamily: "arial", fontSize: 70, publicId: "sample_sub_en.srt"}} color="#ffff00" background="black" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay={{fontFamily: "arial", fontSize: 70, publicId: "sample_sub_en.srt"}} color="#ffff00" background="black" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="subtitles:arial_70:sample_sub_en.srt" color="#ffff00" background="black">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new SubtitlesLayer().FontFamily("arial").FontSize(70).PublicId("sample_sub_en.srt")).Color("#ffff00").Background("black")).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new SubtitlesLayer().fontFamily("arial").fontSize(70).publicId("sample_sub_en.srt")).color("#ffff00").background("black")).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("subtitles:arial_70:sample_sub_en.srt").setColor("#ffff00").setBackground("black")).generate("dog.mp4")

Applying 3D LUTs to video

3D lookup tables (3D LUTs) are used to map one color space to another. They can be used to adjust colors, contrast, and/or saturation, so that you can correct contrast of flat footage, fix a camera’s inability to see a particular color shade, or give a final finished look or a particular style to your video.

After uploading a .3dl file to your account as a raw file, you can apply it to any video using the lut: property of the overlay parameter ( l_lut: in URLs), followed by the LUT public ID (including the .3dl extension).

Below you can see the dog.mp4 video file in it's original color, compared to the video with different LUT files applied.

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

</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >

</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >

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

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>"lut:iwltbap_aspen.3dl")
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>"lut:iwltbap_aspen.3dl"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay="lut:iwltbap_aspen.3dl")
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: "lut:iwltbap_aspen.3dl"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("lut:iwltbap_aspen.3dl"))).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.Layer().publicId("lut:iwltbap_aspen.3dl")}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.Layer().publicId("lut:iwltbap_aspen.3dl")})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay="lut:iwltbap_aspen.3dl" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay="lut:iwltbap_aspen.3dl" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="lut:iwltbap_aspen.3dl">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("lut:iwltbap_aspen.3dl"))).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("lut:iwltbap_aspen.3dl"))).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("lut:iwltbap_aspen.3dl")).generate("dog.mp4")

Ruby:
Copy to clipboard
cl_video_tag("dog", :overlay=>"lut:iwltbap_sedona.3dl")
PHP:
Copy to clipboard
cl_video_tag("dog", array("overlay"=>"lut:iwltbap_sedona.3dl"))
Python:
Copy to clipboard
CloudinaryVideo("dog").video(overlay="lut:iwltbap_sedona.3dl")
Node.js:
Copy to clipboard
cloudinary.video("dog", {overlay: "lut:iwltbap_sedona.3dl"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("lut:iwltbap_sedona.3dl"))).videoTag("dog");
JS:
Copy to clipboard
cloudinary.videoTag('dog', {overlay: new cloudinary.Layer().publicId("lut:iwltbap_sedona.3dl")}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("dog", {overlay: new cloudinary.Layer().publicId("lut:iwltbap_sedona.3dl")})
React:
Copy to clipboard
<Video publicId="dog" >
  <Transformation overlay="lut:iwltbap_sedona.3dl" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="dog" >
  <cld-transformation overlay="lut:iwltbap_sedona.3dl" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation overlay="lut:iwltbap_sedona.3dl">
  </cl-transformation>
</cl-video>
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("lut:iwltbap_sedona.3dl"))).BuildVideoTag("dog")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("lut:iwltbap_sedona.3dl"))).resourceType("video").generate("dog.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("lut:iwltbap_sedona.3dl")).generate("dog.mp4")

Adaptive bitrate streaming - HLS and MPEG-DASH

Adaptive bitrate streaming is a video delivery technique that adjusts the quality of a video stream in real time according to detected bandwidth and CPU capacity. This enables videos to start quicker, with fewer buffering interruptions, and at the best possible quality for the current device and network connection, to maximize user experience.

For example, as a video begins to download, the client can play the first few seconds of the movie at a low quality to get started quickly. When the user’s video buffer is full and assuming CPU utilization is low, the client player may switch to a higher quality stream to enhance the viewing experience. If the buffer later drops below certain levels, or CPU utilization jumps above certain thresholds, the client may switch to a lower quality stream.

At the start of the streaming session, the client software downloads a master playlist file containing the metadata for the various sub-streams that are available. The client software then decides what to download from the available media files, based on predefined factors such as device type, resolution, current bandwidth, size, etc.

To deliver videos using adaptive streaming, you need multiple copies of your video prepared at different resolutions, qualities, and data rates. These are called video representations (also sometimes known as variants). You also need index and streaming files for each representation. The master file references the available representations, provides information required for the client to choose between them, and includes other required metadata, depending on the delivery protocol.

Cloudinary can automatically generate and deliver all of these files from a single original video, transcoded to either or both of the following protocols:

  • HTTP Live Streaming (HLS)
  • Dynamic Adaptive Streaming over HTTP (MPEG-DASH)

See also: HTTP Live Streaming feature overview.

To deliver videos using HLS or MPEG-DASH Adaptive Streaming:

  1. Select a predefined streaming profile
  2. Upload your video with an eager transformation including the selected streaming profile and format
  3. Deliver the video

Note
If you have a special use-case that does not enable you to use the built-in streaming profiles to automatically generate the master playlist file and all the relevant representations, you can still have Cloudinary create the index and streaming files for each streaming transformation (representation) that you define, and then you can create the master playlist file manually. For details, see Manually creating representations and master files.

Step 1. Select a streaming profile

Cloudinary provides a collection of predefined streaming profiles, where each profile defines a set of representations according to suggested best practices.

For example, the 4k profile creates 8 different representations in 16x9 aspect ratio, from extremely high quality to audio only, while the sd profile creates only 3 representations, all in 4:3 aspect ratio. Other commonly used profiles include the hd and full_hd profiles.

To view the full list of available predefined streaming profiles and the settings for each representation, see Predefined streaming profiles.

If none of the predefined profiles exactly answers your needs, you can also optionally define custom streaming profiles or even fine-tune the predefined options. You might want a different number of representations, different divisions of quality, different codecs or a different aspect ratio. Or, you might want to apply special transformations for different representations within the profile.

For example, if you want to make use of the more advanced video encoding provided by the vp9 and h265 codecs, or audio encoding provided by the opus codec, you can create your own streaming profiles (or update the predefined ones). You can use the h265 codec with both HLS and MPEG-DASH, however the vp9 and opus codecs can only be used with MPEG-DASH. You can combine codecs when creating your streaming profiles to ensure the widest support across different browsers and devices.

Use the streaming_profiles method of the Admin API to create, update, list, delete, or get details of streaming profiles.

Step 2. Upload your video with an eager transformation including the streaming profile and format

A single streaming profile is comprised of many derived files, so it can take a while for Cloudinary to generate them all. Therefore, when you upload your video (or later, explicitly), you should include eager, asynchronous transformations with the required streaming profile and video format.

You can even eagerly prepare your videos for streaming in both formats and you can include other video transformations as well. However, make sure the streaming_profile is provided as a separate component of chained transformations.

For example, this upload command encodes the big_buck_bunny.mp4 video to HLS format using the full_hd streaming profile:

Ruby:
Copy to clipboard
Cloudinary::Uploader.upload("big_buck_bunny.mp4", :resource_type => :video, 
          :eager => [{:streaming_profile => "full_hd", :format => "m3u8"}], 
          :eager_async => true,
          :eager_notification_url => "https://mysite.example.com/notify_endpoint",
          :public_id => "bb_bunny")
PHP:
Copy to clipboard
\Cloudinary\Uploader::upload("big_buck_bunny.mp4", array(
            "resource_type" => "video", 
            "eager" => array("streaming_profile" => "full_hd", "format" => "m3u8"),
            "eager_async" => true,
            "eager_notification_url" => "https://mysite.example.com/notify_endpoint"
            "public_id" => "bb_bunny"
            );
Python:
Copy to clipboard
cloudinary.uploader.upload("big_buck_bunny.mp4", resource_type = "video",
            eager = [
              {"streaming_profile": "full_hd", "format": "m3u8"}]
            eager_async = true,
            eager_notification_url = "https://mysite.example.com/notify_endpoint")
            public_id = "bb_bunny")
Node.js:
Copy to clipboard
var up_options = 
   {resource_type: "video", 
    eager: [
      { streaming_profile: "full_hd", format: "m3u8" }],                                   
    eager_async: true,
    eager_notification_url: "https://mysite.example.com/notify_endpoint",
    public_id: "bb_bunny"};
cloudinary.v2.uploader.upload("big_buck_bunny.mp4", up_options, function(result) {console.log(result); };
Java:
Copy to clipboard
cloudinary.uploader().upload("big_buck_bunny.mp4", 
        ObjectUtils.asMap("resource_type", "video",
        "eager", Arrays.asList(
              new Transformation().streamingProfile("full_hd").format("m3u8"),
            "eager_async", true,
            "eager_notification_url", "https://mysite.example.com/notify_endpoint"
            "public_id", "bb_bunny"));

The eager transformation response includes the delivery URLs for each requested encoding.

See more adaptive streaming upload examples.

Step 3. Deliver the video

After the eager transformation is complete, deliver your video using the .m3u8 (HLS) or .mpd (MPEG-DASH) file format (extension) and include the streaming_profile (sp_<profilename>) and other transformations exactly matching those you provided in your eager transformation (as per the URL that was returned in the upload response).

For example, the delivery code for the video that was uploaded in Step 2 above is:

Ruby:
Copy to clipboard
cloudinary_url("bb_bunny.m3u8", :streaming_profile=>"hd", :resource_type=>"video")
PHP:
Copy to clipboard
Cloudinary::cloudinary_url("bb_bunny.m3u8", array("streaming_profile"=>"hd", "resource_type"=>"video"))
Python:
Copy to clipboard
cloudinary.utils.cloudinary_url("bb_bunny.m3u8", streaming_profile="hd", resource_type="video")
Node.js:
Copy to clipboard
cloudinary.url("bb_bunny.m3u8", {streaming_profile: "hd", resource_type: "video"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().streamingProfile("hd")).resourceType("video").generate("bb_bunny.m3u8")
JS:
Copy to clipboard
cloudinary.url('bb_bunny.m3u8', {streamingProfile: "hd"}, {resource_type: 'video'});
jQuery:
Copy to clipboard
$.cloudinary.url("bb_bunny.m3u8", {streaming_profile: "hd", resource_type: "video"})
React:
Copy to clipboard
cloudinary.url('bb_bunny.m3u8', {streamingProfile: "hd"}, {resource_type: 'video'});
Vue.js:
Copy to clipboard
cloudinary.url('bb_bunny.m3u8', {streamingProfile: "hd"}, {resource_type: 'video'});
Angular:
Copy to clipboard
cloudinary.url('bb_bunny.m3u8', {streamingProfile: "hd"}, {resource_type: 'video'});
.Net:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().StreamingProfile("hd")).BuildUrl("bb_bunny.m3u8")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().streamingProfile("hd")).resourceType("video").generate("bb_bunny.m3u8");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStreamingProfile("hd")).generate("bb_bunny.m3u8")

Important
Not all browsers and mobile devices natively support MPEG-DASH and HLS. For example, Chrome does not natively support DASH or HLS. Both HLS and DASH are supported in Microsoft Edge and some SmartTVs. HLS is natively supported on all Apple devices, Safari, and the latest versions of the Chrome for Android browsers.

To ensure that your encoded video can adaptively stream in all environments, you can embed the Cloudinary Video Player in your application. The Cloudinary video player supports video delivery in both HLS and MPEG-DASH.

Delivering HLS version 3

By default, HLS transcoding uses HLS v4 If you need to deliver HLS v3, add the hlsv3 flag parameter (fl_hlsv3 in URLs) when setting the video file format (extension) to .m3u8. Cloudinary will then automatically create the fragmented video files (all with a .ts extension), each with a duration of 10 seconds, as well as the required .m3u8 index files for each of the fragmented files.

Important
Supporting HLS v3 requires a private CDN configuration. CDN distributions are available for Cloudinary's Advanced plan and above, and require a small setup on Cloudinary's side. For details, submit a support request.

Notes and guidelines for adaptive streaming

  • For small videos, where all of the derived files combined are less than 60 MB, you can deliver the transformation URL on-the-fly (instead of as an eager transformation), but this should be used only for demo or debugging purposes. In a production environment, we recommend to always eagerly transform your video representations.

  • The adaptive streaming files for small videos (where all of the derived files combined are less than 60 MB) are derived synchronously if you do not set the asynch parameter. Larger videos are prepared asynchronously. Notification (webhook) of completion is sent to the eager_notification_url parameter.

  • By default, video sampling is per 2 seconds. You can define a custom sampling rate by specifying it as a chained transformation prior to the streaming profile. For example (in Ruby):

Copy to clipboard
   Cloudinary::Uploader.upload("big_buck_bunny.mp4", :resource_type => :video,
     :eager => [{:format => "mpd", :transformation => 
      [{:video_sampling => 3}, {:streaming_profile => "hd"}] }]
     :public_id => "bb_bunny")
  • All the generated files are considered derived files of the original video. For example, when performing invalidate on a video, the corresponding derived adaptive streaming files are also invalidated.

  • If the profile you select includes any representations larger resolution than the original, those representations will not be created. However, at minimum, one representation will be created.

  • If the aspect ratio of the original video does not match the aspect ratio of the selected streaming profile, then the c_limit cropping transformation is applied to make the video fit the required size. If you don’t want to use this cropping method, use a base transformation to crop the video to the relevant aspect ratio.

  • If you prepare streaming for a lower-level profile, and then in the future, you want to prepare the same video with a higher-level profile, the new high-quality representations will be created, while any already existing representations that match will be reused.

Examples

Step 2 above includes a simple example for uploading a video and using a streaming profile to prepare the required files for delivering the video in adaptive streaming format. This section provides some additional examples.

Request several encodings and formats at once

Ruby:
Copy to clipboard
Cloudinary::Uploader.upload("big_buck_bunny.mp4", :resource_type => :video, 
  :eager => [
     {:streaming_profile => "full_hd", :format => "m3u8"},
     {:streaming_profile => "sd", :format => "m3u8"},
     {:streaming_profile => "hd", :format => "mpd"}], 
  :eager_async => true
  :eager_notification_url => "https://mysite.example.com/notify_endpoint",
  :public_id => "bb_bunny")
PHP:
Copy to clipboard
\Cloudinary\Uploader::upload("big_buck_bunny.mp4", array(
            "resource_type" => "video", 
            "eager" => array(
              array("streaming_profile" => "full_hd", "format" => "m3u8"),
              array("streaming_profile" => "sd", "format" => "m3u8"),
              array("streaming_profile" => "hd", "format" => "mpd")),
            "eager_async" => true,
            "eager_notification_url" => "https://mysite.example.com/notify_endpoint",
            "public_id => "bb_bunny"
            ));
Python:
Copy to clipboard
cloudinary.uploader.upload("big_buck_bunny.mp4", resource_type = "video",
            eager = [
              {"streaming_profile": "full_hd", "format": "m3u8"},
              {"streaming_profile": "sd", "format": "m3u8"},
              {"streaming_profile": "hd", "format": "mpd"}],
            eager_async = true,
            eager_notification_url = "https://mysite.example.com/notify_endpoint",
            public_id = "bb_bunny")
Node.js:
Copy to clipboard
var up_options = 
  { resource_type: "video", 
    eager: [
      {streaming_profile: "full_hd", format: "m3u8"}, 
      {streaming_profile: "sd", format: "m3u8"}, 
      {streaming_profile: "hd", format: "mpd"} ],                                   
    eager_async: true,
    eager_notification_url: "https://mysite.example.com/notify_endpoint",
    public_id: "bb_bunny" };
cloudinary.v2.uploader.upload("big_buck_bunny.mp4", up_options, function(result) {console.log(result); });
Java:
Copy to clipboard
cloudinary.uploader().upload("big_buck_bunny.mp4", 
        ObjectUtils.asMap("resource_type", "video",
        "eager", Arrays.asList(
              new Transformation().streamingProfile("full_hd").format("m3u8"),
              new Transformation().streamingProfile("sd").format("m3u8"),
              new Transformation().streamingProfile("hd").format("mpd")),
            "eager_async", true,
            "eager_notification_url", "https://mysite.example.com/notify_endpoint,
            "public_id", "bb_bunny"));

Use chained transformations with a streaming profile

Ruby:
Copy to clipboard
Cloudinary::Uploader.upload("big_buck_bunny.mp4", 
  :resource_type => :video,
  :eager => 
      [{:format => "m3u8", :transformation => 
        [  
          {:crop => "crop", :aspect_ratio => "16:9"},
          {:streaming_profile => "hd"},
          {:overlay => "logowatermark", :width => 100}
        ] }],
  :eager_async => true, 
  :eager_notification_url => "https://mysite.example.com/notify_endpoint",
  :public_id => "bb_bunny")
PHP:
Copy to clipboard
\Cloudinary\Uploader::upload("big_buck_bunny.mp4", array(
            "resource_type" => "video", 
            "eager" => array(
              "format" => "m3u8",
              "transformation" => array(
                array("crop" => "crop", "aspect_ratio" => "16:9"),
                array("streaming_profile" => "hd"),
                array("overlay" => "logowatermark", "width" => 100))),
            "eager_async" => true,
            "eager_notification_url" => "https://mysite.example.com/notify_endpoint",
            "public_id => "bb_bunny"
            ));
Python:
Copy to clipboard
cloudinary.uploader.upload("big_buck_bunny.mp4", 
            resource_type = "video",
            eager = [
              {"format": "m3u8", 
              "transformation": [
                {"crop":"crop", aspect_ratio:"16:9"}
                {"streaming_profile": "hd"},
                {"overlay": "logowatermark", ":"width": 100}]
               }],
            eager_async = true,
            eager_notification_url = "https://mysite.example.com/notify_endpoint",
            public_id = "bb_bunny")
Node.js:
Copy to clipboard
var up_options = 
  { resource_type: "video", 
    eager: [
      {format: "m3u8", 
       transformation: [
         {crop: "crop", aspect_ratio: "16:9"},
         {streaming_profile: "hd"},
         {:overlay: "logowatermark", width: 100}
     ]}, 
    ],                                   
    eager_async: true,
    eager_notification_url: "https://mysite.example.com/notify_endpoint",
    public_id: "bb_bunny" };
cloudinary.v2.uploader.upload("big_buck_bunny.mp4", up_options, function(result) {console.log(result); });
Java:
Copy to clipboard
cloudinary.uploader().upload("big_buck_bunny.mp4", 
        ObjectUtils.asMap("resource_type", "video",
        "eager", Arrays.asList(
              new Transformation()
                .format("m3u8").chain()
                .crop("crop").aspectRatio("16:9").chain()
                .streamingProfile("hd").chain()
                .overlay("logowatermark").width(100)
                )        
        "eager_async", true,
        "eager_notification_url", "https://mysite.example.com/notify_endpoint,
        "public_id", "bb_bunny"));

Encode an already uploaded video using Explicit

Ruby:
Copy to clipboard
Cloudinary::Uploader.explicit("bb_bunny", 
  :resource_type => :video, :type => "upload",
  :eager => [
    {:streaming_profile => "hd", :format => "m3u8"}])
PHP:
Copy to clipboard
\Cloudinary\Uploader::explicit("bb_bunny", array(
            "resource_type" => "video", "type" => "upload"
            "eager" => array(
              array("streaming_profile" => "hd", "format" => "m3u8"),
              )));
Python:
Copy to clipboard
cloudinary.uploader.explicit("bb_bunny", 
  resource_type = "video", type = "upload", 
  eager = 
   [
     {"streaming_profile": "hd", "format": "m3u8"},
   ])
Node.js:
Copy to clipboard
var up_options = 
  {resource_type: "video", type: "upload",
   eager: [
    { streaming_profile: "hd", format: "m3u8" }, 
   ] };
cloudinary.v2.uploader.explicit("bb_bunny", up_options, function(result) {console.log(result); } );
Java:
Copy to clipboard
cloudinary.uploader().explicit("bb_bunny", ObjectUtils.asMap(
            "resource_type", "video", "type", "upload", 
            "eager", Arrays.asList(
              new Transformation().streaming_profile("hd").format("m3u8"),
              )));

Eager response example

Copy to clipboard
{
  "public_id": "bb_bunny",
  "version": 1466426766,
  "signature": "245679585758d518703ab50142b1c88685e17777",
  "width": 640,
  "height": 360,
  "format": "mp4",
  "resource_type": "video",
  "created_at": "2017-06-20T12:46:06Z",
  "bytes": 5510872,
  "type": "upload",
  "url": "http://res.cloudinary.com/demo/video/upload/v1466426766/bb_bunny.mp4",
  "secure_url": "https://res.cloudinary.com/demo/video/upload/v1466426766/bb_bunny.mp4",
  "eager": [
    {
      "transformation": "sp_hd/m3u8",
      "url": "http://res.cloudinary.com/demo/video/upload/sp_hd/v1466426766/bb_bunny.m3u8",
      "secure_url": "https://res.cloudinary.com/demo/video/upload/sp_hd/v1466426766/bb_bunny.m3u8"
    }
  ]
}

Predefined streaming profiles

The following tables summarize the possible representations, and the actual representations that are included for each predefined streaming profile.

Possible representations

ID Width Height Video Codec/Profile
(video_codec)
Video Bitrate
(bit_rate)
0 320 240 (Audio only) 192k
1 480 270
(360 in 4:3 ratio)
h264:baseline:3.0 800k
2 640 360
(480 in 4:3 ratio)
h264:baseline:3.0 2m
3 960 540 h264:main:3.1 3500k
4 1280 720 h264:main:3.1 5500k
5 1920 1080 h264:high:4.0 8500k
6 2560 1440 h264:high:4.0 16m
7 3840 2160 h264:high:4.0 35m

Representations generated for each profile

Profile Name Aspect Ratio 0 1 2 3 4 5 6 7
4k 16:9 + + + + + + + +
full_hd 16:9 + + + + + +
hd 16:9 + + + + +
sd 4:3 + + +
full_hd_wifi 16:9 + + +
full_hd_lean 16:9 + + +
hd_lean 16:9 + + +

Derived adaptive streaming files

When the encoding process is complete for all representations, the derived files will include:

HLS

  • A fragmented video streaming file (.ts) 1 for each representation
  • An index file (.m3u8) of references to the fragments for each representation
  • A single master playlist file (.m3u8) containing references to the representation files above and other required metadata

DASH

  • A fragmented video streaming file (.mp4dv) for each representation
  • An audio stream file (.mp4da) for each representation
  • An index file (.mpd) containing references to the fragments of each streaming file as well as a master playlist containing references to the representation files above and other required metadata

1 If working with HLS v.3, a separate video streaming file (.ts) is derived for each fragment of each representation. To work with HLS v.3, you need a private CDN configuration and you need to add a special hlsv3 flag to your video transformations.

Manually creating representations and master files

If you have a special use-case that does not enable you to use the built-in streaming profiles to automatically generate master playlist file and all the relevant representations, you can still have Cloudinary create the index and streaming files for each streaming transformation you define, and then you can create the master playlist file manually.

Step 1. Upload your video with eager transformations for each desired representation

When you upload your video, provide eager transformations for each representation (resolution, quality, data rate) that you want to create. Also make sure to define the format for each transformation as .m3u8 (HLS) or .mpd (DASH) in a separate component of the chain.

When you define the format of your transformation as .m3u8 or .mpd, Cloudinary automatically generates the following derived files:

  • A fragmented video streaming file (.ts1 or .mp4dv)
  • An index file (.m3u8 or .mpd) of references to the fragments
  • For DASH only: an audio stream file (.mp4da)

For example:

Ruby:
Copy to clipboard
Cloudinary::Uploader.upload("big_buck_bunny.mp4", 
    :resource_type => :video,
    :eager => 
       [{:format => "m3u8", :transformation => 
            [
              {:width => 960, :height => 540, :crop => :limit, :video_codec => "h264:main:3.1", :bit_rate =>"3500k"},
              {:overlay => "watermark", :width => 100}
            ] 
        }], 
     :eager_async => true, 
     :eager_notification_url => "https://mysite.example.com/notify_endpoint")
     :public_id => "bb_bunny"
PHP:
Copy to clipboard
\Cloudinary\Uploader::upload("big_buck_bunny.mp4", array(
            "resource_type" => "video", 
            "eager" => array(
              array("format" => "m3u8", "width" => 960, "height" => 540, "crop" => "limit", "video_codec" => "h264:main:3.1", "bit_rate" =>"3500k")
              ),
            "eager_async" => true,
            "eager_notification_url" => "https://mysite.example.com/notify_endpoint"
            ״public_id => "bb_bunny" ));
Python:
Copy to clipboard
cloudinary.uploader.upload("big_buck_bunny.mp4", 
    resource_type = "video",
    eager = 
      [
        {"format": "m3u8", "width": 960, "height": 540, "crop": "limit", "video_codec": "h264:main:3.1", "bit_rate": "3500k"}
      ],
    eager_async = true,
    eager_notification_url = "https://mysite.example.com/notify_endpoint"
    public_id = "bb_bunny" )
Node.js:
Copy to clipboard
var up_options = 
  { 
    resource_type: "video", 
    eager: 
    [
      { format: "m3u8", width: 960, height: 540, crop: "limit", video_codec: "h264:main:3.1", bit_rate: "3500k" }
    ],                                   
    eager_async: true,
    eager_notification_url: "https://mysite.example.com/notify_endpoint", 
    public_id: "bb_bunny"    
   };
cloudinary.v2.uploader.upload("big_buck_bunny.mp4", up_options, function(result) {console.log(result); });
Java:
Copy to clipboard
cloudinary.uploader().upload("big_buck_bunny.mp4", 
        ObjectUtils.asMap("resource_type", "video",
        "eager", Arrays.asList(
              new Transformation().format("m3u8").width(960).height(540).crop("limit").videoCodec("h264:main:3.1").bitRate("3500k")),
        "eager_async", true,
        "eager_notification_url", "https://mysite.example.com/notify_endpoint"
        "public_id", "bb_bunny"));

Note
It is possible to create adaptive streaming transformations on the fly, but recommended to you create all the required transformations eagerly when uploading the original video file or explicitly, so that there is no delay when first accessed by your users.

1If working with HLS v.3, a separate video streaming file (.ts) is derived for each fragment of each representation. To work with HLS v.3, you need a private CDN configuration and you need to add a special hlsv3 flag to your video transformations.

Step 2. Manually create the master playlist file

If you are not using streaming profiles, you need to create your master playlist file manually.

HLS Master Playlist (m3u8)

Each item in the m3u8 master index file points to a Cloudinary dynamic manipulation URL, which represents the pair of auto-generated m3u8 index and ts video files that were created in the preceding step.

For example, the following m3u8 master playlist file contains information on 2 versions of the dog.mp4 video, one high resolution suitable for iPhone 4s and the other lower resolution suitable for iPhone 1s:

Copy to clipboard
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=480x320,NAME="Nice Dog - iPhone 4"    https://res.cloudinary.com/demo/video/upload/c_lpad,w_960,h_640,vs_2,q_70,br_5m,vc_h264:main:3.1/dog.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=1500000,RESOLUTION=480x320,NAME="Nice Dog - iPhone 1"    https://res.cloudinary.com/demo/video/upload/c_lpad,w_480,h_320,vs_2,q_70,br_1400k,vc_h264:baseline:3.0/dog.m3u8
MPEG-DASH Master Playlist

The .mpd master file is an XML document. For details on creating the .mpd master file, see: The Structure of an MPEG-DASH MPD.

Advanced transformations

In addition to the commonly used video transformation options described on this page, the following pages describe a variety of additional video transformation options:

The Video Transformation Reference table provides the complete list of parameters available for manipulating videos.