Video trimming and concatenating

When transforming and editing your videos, you will often want to trim parts of the video to adjust the length or concatenate different videos together. You can use Cloudinary's trimming and concatenating functionality to achieve this.

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 (cloudinary 1.x):
    Copy to clipboard
    cl_video_tag("dog", :end_offset=>"10", :start_offset=>"6.5")
    PHP (cloudinary_php 2.x):
    Copy to clipboard
    (new VideoTag('dog.mp4'))
      ->videoEdit(VideoEdit::trim()->startOffset(6.5)
    ->endOffset(10.0));
    PHP (cloudinary_php 1.x (legacy)):
    Copy to clipboard
    cl_video_tag("dog", array("end_offset"=>"10", "start_offset"=>"6.5"))
    Python (cloudinary 1.x):
    Copy to clipboard
    CloudinaryVideo("dog").video(end_offset="10", start_offset="6.5")
    Node.js (cloudinary 1.x):
    Copy to clipboard
    cloudinary.video("dog", {end_offset: "10", start_offset: "6.5"})
    Java (cloudinary 1.x):
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().endOffset("10").startOffset("6.5")).videoTag("dog");
    JS (@cloudinary/url-gen 1.x):
    Copy to clipboard
    new CloudinaryVideo("dog.mp4").videoEdit(
      trim().startOffset(6.5).endOffset("10.0")
    );
    JS (cloudinary-core 2.x (legacy)):
    Copy to clipboard
    cloudinary.videoTag('dog', {endOffset: "10", startOffset: "6.5"}).toHtml();
    jQuery (cloudinary-jquery 2.x):
    Copy to clipboard
    $.cloudinary.video("dog", {end_offset: "10", start_offset: "6.5"})
    React (@cloudinary/react 1.x):
    Copy to clipboard
    //React SDK transformations are created using @cloudinary/url-gen.
    new CloudinaryVideo("dog.mp4").videoEdit(
      trim().startOffset(6.5).endOffset("10.0")
    );
    React (cloudinary-react 1.x):
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation endOffset="10" startOffset="6.5" />
    </Video>
    Vue.js (cloudinary-vue 1.x):
    Copy to clipboard
    <cld-video public-id="dog" >
      <cld-transformation end-offset="10" start-offset="6.5" />
    </cld-video>
    Angular (@cloudinary/ng 1.x):
    Copy to clipboard
    //Angular SDK transformations are created using @cloudinary/url-gen.
    new CloudinaryVideo("dog.mp4").videoEdit(
      trim().startOffset(6.5).endOffset("10.0")
    );
    Angular (@cloudinary/angular-5.x 1.x (legacy)):
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation end-offset="10" start-offset="6.5">
      </cl-transformation>
    </cl-video>
    .NET (CloudinaryDotNet 1.x):
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().EndOffset("10").StartOffset("6.5")).BuildVideoTag("dog")
    iOS (cloudinary 3.x):
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setEndOffset("10").setStartOffset("6.5")).generate("dog.mp4")
    Android (cloudinary-android 1.x):
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().endOffset("10").startOffset("6.5")).resourceType("video").generate("dog.mp4");
    Kotlin (kotlin-url-gen 1.x):
    Copy to clipboard
    cloudinary.video {
      publicId("dog.mp4")
       videoEdit(VideoEdit.trim() { startOffset(6.5F)
     endOffset(10.0F) }) 
    }.generate()

  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 (cloudinary 1.x):
    Copy to clipboard
    cl_video_tag("dog", :duration=>"30p", :start_offset=>"10p")
    PHP (cloudinary_php 2.x):
    Copy to clipboard
    (new VideoTag('dog.mp4'))
      ->videoEdit(VideoEdit::trim()->startOffset("10%")
    ->duration("30%"));
    PHP (cloudinary_php 1.x (legacy)):
    Copy to clipboard
    cl_video_tag("dog", array("duration"=>"30p", "start_offset"=>"10p"))
    Python (cloudinary 1.x):
    Copy to clipboard
    CloudinaryVideo("dog").video(duration="30p", start_offset="10p")
    Node.js (cloudinary 1.x):
    Copy to clipboard
    cloudinary.video("dog", {duration: "30p", start_offset: "10p"})
    Java (cloudinary 1.x):
    Copy to clipboard
    cloudinary.url().transformation(new Transformation().duration("30p").startOffset("10p")).videoTag("dog");
    JS (@cloudinary/url-gen 1.x):
    Copy to clipboard
    new CloudinaryVideo("dog.mp4").videoEdit(
      trim().startOffset("10%").duration("30%")
    );
    JS (cloudinary-core 2.x (legacy)):
    Copy to clipboard
    cloudinary.videoTag('dog', {duration: "30p", startOffset: "10p"}).toHtml();
    jQuery (cloudinary-jquery 2.x):
    Copy to clipboard
    $.cloudinary.video("dog", {duration: "30p", start_offset: "10p"})
    React (@cloudinary/react 1.x):
    Copy to clipboard
    //React SDK transformations are created using @cloudinary/url-gen.
    new CloudinaryVideo("dog.mp4").videoEdit(
      trim().startOffset("10%").duration("30%")
    );
    React (cloudinary-react 1.x):
    Copy to clipboard
    <Video publicId="dog" >
      <Transformation duration="30p" startOffset="10p" />
    </Video>
    Vue.js (cloudinary-vue 1.x):
    Copy to clipboard
    <cld-video public-id="dog" >
      <cld-transformation duration="30p" start-offset="10p" />
    </cld-video>
    Angular (@cloudinary/ng 1.x):
    Copy to clipboard
    //Angular SDK transformations are created using @cloudinary/url-gen.
    new CloudinaryVideo("dog.mp4").videoEdit(
      trim().startOffset("10%").duration("30%")
    );
    Angular (@cloudinary/angular-5.x 1.x (legacy)):
    Copy to clipboard
    <cl-video public-id="dog" >
      <cl-transformation duration="30p" start-offset="10p">
      </cl-transformation>
    </cl-video>
    .NET (CloudinaryDotNet 1.x):
    Copy to clipboard
    cloudinary.Api.UrlVideoUp.Transform(new Transformation().Duration("30p").StartOffset("10p")).BuildVideoTag("dog")
    iOS (cloudinary 3.x):
    Copy to clipboard
    cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setDuration("30p").setStartOffset("10p")).generate("dog.mp4")
    Android (cloudinary-android 1.x):
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation().duration("30p").startOffset("10p")).resourceType("video").generate("dog.mp4");
    Kotlin (kotlin-url-gen 1.x):
    Copy to clipboard
    cloudinary.video {
      publicId("dog.mp4")
       videoEdit(VideoEdit.trim() { startOffset("10%")
     duration("30%") }) 
    }.generate()

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 (cloudinary 1.x):
Copy to clipboard
cl_video_tag("dog", :end_offset=>"10.0", :start_offset=>"6.5")
PHP (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('dog.mp4'))
  ->videoEdit(VideoEdit::trim()->startOffset(6.5)
->endOffset(10.0));
PHP (cloudinary_php 1.x (legacy)):
Copy to clipboard
cl_video_tag("dog", array("end_offset"=>"10.0", "start_offset"=>"6.5"))
Python (cloudinary 1.x):
Copy to clipboard
CloudinaryVideo("dog").video(end_offset="10.0", start_offset="6.5")
Node.js (cloudinary 1.x):
Copy to clipboard
cloudinary.video("dog", {end_offset: "10.0", start_offset: "6.5"})
Java (cloudinary 1.x):
Copy to clipboard
cloudinary.url().transformation(new Transformation().endOffset("10.0").startOffset("6.5")).videoTag("dog");
JS (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("dog.mp4").videoEdit(
  trim().startOffset(6.5).endOffset("10.0")
);
JS (cloudinary-core 2.x (legacy)):
Copy to clipboard
cloudinary.videoTag('dog', {endOffset: "10.0", startOffset: "6.5"}).toHtml();
jQuery (cloudinary-jquery 2.x):
Copy to clipboard
$.cloudinary.video("dog", {end_offset: "10.0", start_offset: "6.5"})
React (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("dog.mp4").videoEdit(
  trim().startOffset(6.5).endOffset("10.0")
);
React (cloudinary-react 1.x):
Copy to clipboard
<Video publicId="dog" >
  <Transformation endOffset="10.0" startOffset="6.5" />
</Video>
Vue.js (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="dog" >
  <cld-transformation end-offset="10.0" start-offset="6.5" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("dog.mp4").videoEdit(
  trim().startOffset(6.5).endOffset("10.0")
);
Angular (@cloudinary/angular-5.x 1.x (legacy)):
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation end-offset="10.0" start-offset="6.5">
  </cl-transformation>
</cl-video>
.NET (CloudinaryDotNet 1.x):
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().EndOffset("10.0").StartOffset("6.5")).BuildVideoTag("dog")
iOS (cloudinary 3.x):
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setEndOffset("10.0").setStartOffset("6.5")).generate("dog.mp4")
Android (cloudinary-android 1.x):
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().endOffset("10.0").startOffset("6.5")).resourceType("video").generate("dog.mp4");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("dog.mp4")
   videoEdit(VideoEdit.trim() { startOffset(6.5F)
 endOffset(10.0F) }) 
}.generate()

Tip
If you want a video to play at a certain position but not trim the rest of the video out, you can make use of the HTML5 t parameter in the video source.

For example, this URL starts playback of the dog video at 6.5 seconds and stops it again at 10 seconds:

Concatenating media

Concatenate videos together

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 (cloudinary 1.x):
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:height=>200, :width=>300, :crop=>"fill"},
  {:flags=>"splice", :overlay=>"video:dog"},
  {:height=>200, :width=>300, :crop=>"fill"},
  {:flags=>"layer_apply"}
  ])
PHP (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('kitten_fighting.mp4'))
  ->resize(Resize::fill()->width(300)
->height(200))
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::videoSource("dog")
  ->transformation((new Transformation())
  ->resize(Resize::fill()->width(300)
->height(200)))
  ));
PHP (cloudinary_php 1.x (legacy)):
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("height"=>200, "width"=>300, "crop"=>"fill"),
  array("flags"=>"splice", "overlay"=>"video:dog"),
  array("height"=>200, "width"=>300, "crop"=>"fill"),
  array("flags"=>"layer_apply")
  )))
Python (cloudinary 1.x):
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'height': 200, 'width': 300, 'crop': "fill"},
  {'flags': "splice", 'overlay': "video:dog"},
  {'height': 200, 'width': 300, 'crop': "fill"},
  {'flags': "layer_apply"}
  ])
Node.js (cloudinary 1.x):
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {height: 200, width: 300, crop: "fill"},
  {flags: "splice", overlay: "video:dog"},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply"}
  ]})
Java (cloudinary 1.x):
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .height(200).width(300).crop("fill").chain()
  .flags("splice").overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("fill").chain()
  .flags("layer_apply")).videoTag("kitten_fighting");
JS (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("kitten_fighting.mp4")
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation().resize(fill().width(300).height(200))
      )
    )
  );
JS (cloudinary-core 2.x (legacy)):
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {height: 200, width: 300, crop: "fill"},
  {flags: "splice", overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery (cloudinary-jquery 2.x):
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {height: 200, width: 300, crop: "fill"},
  {flags: "splice", overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply"}
  ]})
React (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation().resize(fill().width(300).height(200))
      )
    )
  );
React (cloudinary-react 1.x):
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation height="200" width="300" crop="fill" />
  <Transformation flags="splice" overlay="video:dog" />
  <Transformation height="200" width="300" crop="fill" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="kitten_fighting" >
  <cld-transformation height="200" width="300" crop="fill" />
  <cld-transformation flags="splice" :overlay="video:dog" />
  <cld-transformation height="200" width="300" crop="fill" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation().resize(fill().width(300).height(200))
      )
    )
  );
Angular (@cloudinary/angular-5.x 1.x (legacy)):
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation height="200" width="300" crop="fill">
  </cl-transformation>
  <cl-transformation flags="splice" overlay="video:dog">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="fill">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.NET (CloudinaryDotNet 1.x):
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Height(200).Width(300).Crop("fill").Chain()
  .Flags("splice").Overlay(new Layer().PublicId("video:dog")).Chain()
  .Height(200).Width(300).Crop("fill").Chain()
  .Flags("layer_apply")).BuildVideoTag("kitten_fighting")
iOS (cloudinary 3.x):
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setHeight(200).setWidth(300).setCrop("fill").chain()
  .setFlags("splice").setOverlay("video:dog").chain()
  .setHeight(200).setWidth(300).setCrop("fill").chain()
  .setFlags("layer_apply")).generate("kitten_fighting.mp4")
Android (cloudinary-android 1.x):
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .height(200).width(300).crop("fill").chain()
  .flags("splice").overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("fill").chain()
  .flags("layer_apply")).resourceType("video").generate("kitten_fighting.mp4");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("kitten_fighting.mp4")
   resize(Resize.fill() { width(300)
 height(200) })
   videoEdit(VideoEdit.concatenate(
  Concatenate.videoSource("dog") {
   transformation(Transformation {
   resize(Resize.fill() { width(300)
 height(200) }) })
   })) 
}.generate()

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 (cloudinary 1.x):
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:height=>200, :width=>300, :crop=>"fill"},
  {:flags=>"splice", :overlay=>"video:dog"},
  {:height=>200, :width=>300, :crop=>"fill"},
  {:flags=>"layer_apply", :start_offset=>"0"}
  ])
PHP (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('kitten_fighting.mp4'))
  ->resize(Resize::fill()->width(300)
->height(200))
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::videoSource("dog")
  ->transformation((new Transformation())
  ->resize(Resize::fill()->width(300)
->height(200)))
  )
  ->prepend()
  );
PHP (cloudinary_php 1.x (legacy)):
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("height"=>200, "width"=>300, "crop"=>"fill"),
  array("flags"=>"splice", "overlay"=>"video:dog"),
  array("height"=>200, "width"=>300, "crop"=>"fill"),
  array("flags"=>"layer_apply", "start_offset"=>"0")
  )))
Python (cloudinary 1.x):
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'height': 200, 'width': 300, 'crop': "fill"},
  {'flags': "splice", 'overlay': "video:dog"},
  {'height': 200, 'width': 300, 'crop': "fill"},
  {'flags': "layer_apply", 'start_offset': "0"}
  ])
Node.js (cloudinary 1.x):
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {height: 200, width: 300, crop: "fill"},
  {flags: "splice", overlay: "video:dog"},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply", start_offset: "0"}
  ]})
Java (cloudinary 1.x):
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .height(200).width(300).crop("fill").chain()
  .flags("splice").overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("fill").chain()
  .flags("layer_apply").startOffset("0")).videoTag("kitten_fighting");
JS (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("kitten_fighting.mp4")
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation().resize(fill().width(300).height(200))
      )
    ).prepend()
  );
JS (cloudinary-core 2.x (legacy)):
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {height: 200, width: 300, crop: "fill"},
  {flags: "splice", overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply", startOffset: "0"}
  ]}).toHtml();
jQuery (cloudinary-jquery 2.x):
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {height: 200, width: 300, crop: "fill"},
  {flags: "splice", overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply", start_offset: "0"}
  ]})
React (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation().resize(fill().width(300).height(200))
      )
    ).prepend()
  );
React (cloudinary-react 1.x):
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation height="200" width="300" crop="fill" />
  <Transformation flags="splice" overlay="video:dog" />
  <Transformation height="200" width="300" crop="fill" />
  <Transformation flags="layer_apply" startOffset="0" />
</Video>
Vue.js (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="kitten_fighting" >
  <cld-transformation height="200" width="300" crop="fill" />
  <cld-transformation flags="splice" :overlay="video:dog" />
  <cld-transformation height="200" width="300" crop="fill" />
  <cld-transformation flags="layer_apply" start-offset="0" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation().resize(fill().width(300).height(200))
      )
    ).prepend()
  );
Angular (@cloudinary/angular-5.x 1.x (legacy)):
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation height="200" width="300" crop="fill">
  </cl-transformation>
  <cl-transformation flags="splice" overlay="video:dog">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="fill">
  </cl-transformation>
  <cl-transformation flags="layer_apply" start-offset="0">
  </cl-transformation>
</cl-video>
.NET (CloudinaryDotNet 1.x):
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Height(200).Width(300).Crop("fill").Chain()
  .Flags("splice").Overlay(new Layer().PublicId("video:dog")).Chain()
  .Height(200).Width(300).Crop("fill").Chain()
  .Flags("layer_apply").StartOffset("0")).BuildVideoTag("kitten_fighting")
iOS (cloudinary 3.x):
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setHeight(200).setWidth(300).setCrop("fill").chain()
  .setFlags("splice").setOverlay("video:dog").chain()
  .setHeight(200).setWidth(300).setCrop("fill").chain()
  .setFlags("layer_apply").setStartOffset("0")).generate("kitten_fighting.mp4")
Android (cloudinary-android 1.x):
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .height(200).width(300).crop("fill").chain()
  .flags("splice").overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("fill").chain()
  .flags("layer_apply").startOffset("0")).resourceType("video").generate("kitten_fighting.mp4");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("kitten_fighting.mp4")
   resize(Resize.fill() { width(300)
 height(200) })
   videoEdit(VideoEdit.concatenate(
  Concatenate.videoSource("dog") {
   transformation(Transformation {
   resize(Resize.fill() { width(300)
 height(200) }) })
   }) {
   prepend()
   }) 
}.generate()

To concatenate only a section of a video to the end of 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 kitten_fighting to the end of the video named dog rotated by 180 degrees, with both videos set to a width of 300 pixels and a height of 200 pixels.

Ruby (cloudinary 1.x):
Copy to clipboard
cl_video_tag("dog", :transformation=>[
  {:angle=>180},
  {:height=>200, :width=>300, :crop=>"fill"},
  {:duration=>"5", :flags=>"splice", :overlay=>"video:kitten_fighting", :start_offset=>"0"},
  {:height=>200, :width=>300, :crop=>"fill"},
  {:flags=>"layer_apply"}
  ])
PHP (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('dog.mp4'))
  ->rotate(Rotate::byAngle(180))
  ->resize(Resize::fill()->width(300)
->height(200))
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::videoSource("kitten_fighting")
  ->transformation((new Transformation())
  ->videoEdit(VideoEdit::trim()->startOffset(0.0)
->duration(5.0))
  ->resize(Resize::fill()->width(300)
->height(200)))
  ));
PHP (cloudinary_php 1.x (legacy)):
Copy to clipboard
cl_video_tag("dog", array("transformation"=>array(
  array("angle"=>180),
  array("height"=>200, "width"=>300, "crop"=>"fill"),
  array("duration"=>"5", "flags"=>"splice", "overlay"=>"video:kitten_fighting", "start_offset"=>"0"),
  array("height"=>200, "width"=>300, "crop"=>"fill"),
  array("flags"=>"layer_apply")
  )))
Python (cloudinary 1.x):
Copy to clipboard
CloudinaryVideo("dog").video(transformation=[
  {'angle': 180},
  {'height': 200, 'width': 300, 'crop': "fill"},
  {'duration': "5", 'flags': "splice", 'overlay': "video:kitten_fighting", 'start_offset': "0"},
  {'height': 200, 'width': 300, 'crop': "fill"},
  {'flags': "layer_apply"}
  ])
Node.js (cloudinary 1.x):
Copy to clipboard
cloudinary.video("dog", {transformation: [
  {angle: 180},
  {height: 200, width: 300, crop: "fill"},
  {duration: "5", flags: "splice", overlay: "video:kitten_fighting", start_offset: "0"},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply"}
  ]})
Java (cloudinary 1.x):
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .angle(180).chain()
  .height(200).width(300).crop("fill").chain()
  .duration("5").flags("splice").overlay(new Layer().publicId("video:kitten_fighting")).startOffset("0").chain()
  .height(200).width(300).crop("fill").chain()
  .flags("layer_apply")).videoTag("dog");
JS (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("dog.mp4")
  .rotate(byAngle(180))
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("kitten_fighting").transformation(
        new Transformation()
          .videoEdit(trim().startOffset("0.0").duration("5.0"))
          .resize(fill().width(300).height(200))
      )
    )
  );
JS (cloudinary-core 2.x (legacy)):
Copy to clipboard
cloudinary.videoTag('dog', {transformation: [
  {angle: 180},
  {height: 200, width: 300, crop: "fill"},
  {duration: "5", flags: "splice", overlay: new cloudinary.Layer().publicId("video:kitten_fighting"), startOffset: "0"},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery (cloudinary-jquery 2.x):
Copy to clipboard
$.cloudinary.video("dog", {transformation: [
  {angle: 180},
  {height: 200, width: 300, crop: "fill"},
  {duration: "5", flags: "splice", overlay: new cloudinary.Layer().publicId("video:kitten_fighting"), start_offset: "0"},
  {height: 200, width: 300, crop: "fill"},
  {flags: "layer_apply"}
  ]})
React (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("dog.mp4")
  .rotate(byAngle(180))
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("kitten_fighting").transformation(
        new Transformation()
          .videoEdit(trim().startOffset("0.0").duration("5.0"))
          .resize(fill().width(300).height(200))
      )
    )
  );
React (cloudinary-react 1.x):
Copy to clipboard
<Video publicId="dog" >
  <Transformation angle="180" />
  <Transformation height="200" width="300" crop="fill" />
  <Transformation duration="5" flags="splice" overlay="video:kitten_fighting" startOffset="0" />
  <Transformation height="200" width="300" crop="fill" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="dog" >
  <cld-transformation angle="180" />
  <cld-transformation height="200" width="300" crop="fill" />
  <cld-transformation duration="5" flags="splice" :overlay="video:kitten_fighting" start-offset="0" />
  <cld-transformation height="200" width="300" crop="fill" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("dog.mp4")
  .rotate(byAngle(180))
  .resize(fill().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("kitten_fighting").transformation(
        new Transformation()
          .videoEdit(trim().startOffset("0.0").duration("5.0"))
          .resize(fill().width(300).height(200))
      )
    )
  );
Angular (@cloudinary/angular-5.x 1.x (legacy)):
Copy to clipboard
<cl-video public-id="dog" >
  <cl-transformation angle="180">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="fill">
  </cl-transformation>
  <cl-transformation duration="5" flags="splice" overlay="video:kitten_fighting" start-offset="0">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="fill">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.NET (CloudinaryDotNet 1.x):
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Angle(180).Chain()
  .Height(200).Width(300).Crop("fill").Chain()
  .Duration("5").Flags("splice").Overlay(new Layer().PublicId("video:kitten_fighting")).StartOffset("0").Chain()
  .Height(200).Width(300).Crop("fill").Chain()
  .Flags("layer_apply")).BuildVideoTag("dog")
iOS (cloudinary 3.x):
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setAngle(180).chain()
  .setHeight(200).setWidth(300).setCrop("fill").chain()
  .setDuration("5").setFlags("splice").setOverlay("video:kitten_fighting").setStartOffset("0").chain()
  .setHeight(200).setWidth(300).setCrop("fill").chain()
  .setFlags("layer_apply")).generate("dog.mp4")
Android (cloudinary-android 1.x):
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .angle(180).chain()
  .height(200).width(300).crop("fill").chain()
  .duration("5").flags("splice").overlay(new Layer().publicId("video:kitten_fighting")).startOffset("0").chain()
  .height(200).width(300).crop("fill").chain()
  .flags("layer_apply")).resourceType("video").generate("dog.mp4");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("dog.mp4")
   rotate(Rotate.byAngle(180))
   resize(Resize.fill() { width(300)
 height(200) })
   videoEdit(VideoEdit.concatenate(
  Concatenate.videoSource("kitten_fighting") {
   transformation(Transformation {
   videoEdit(VideoEdit.trim() { startOffset(0.0F)
 duration(5.0F) })
   resize(Resize.fill() { width(300)
 height(200) }) })
   })) 
}.generate()

The layer_apply flag in the above example instructs Cloudinary to apply the so_0 parameter in the layer component as a regular start offset transformation parameter applied to the layer, and not in its special concatenate-to-beginning usage for fl_splice. To use the so_0 with fl_splice for concatenating to the beginning, in a case where fl_layer_apply is also used, specify the so_0 in the fl_layer_apply component: /l_...../fl_layer_apply,so_0).

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 (cloudinary 1.x):
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 (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('dog.mp4'))
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::imageSource("sample")
  ->transformation((new Transformation())
  ->videoEdit(VideoEdit::trim()->duration(3.0))
  ->resize(Resize::scale()->width(300)
->height(200)))
  )
  ->prepend()
  );
PHP (cloudinary_php 1.x (legacy)):
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 (cloudinary 1.x):
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 (cloudinary 1.x):
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 (cloudinary 1.x):
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 (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("dog.mp4")
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      imageSource("sample").transformation(
        new Transformation()
          .videoEdit(trim().duration("3.0"))
          .resize(scale().width(300).height(200))
      )
    ).prepend()
  );
JS (cloudinary-core 2.x (legacy)):
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 (cloudinary-jquery 2.x):
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 (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("dog.mp4")
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      imageSource("sample").transformation(
        new Transformation()
          .videoEdit(trim().duration("3.0"))
          .resize(scale().width(300).height(200))
      )
    ).prepend()
  );
React (cloudinary-react 1.x):
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 (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="dog" >
  <cld-transformation width="300" height="200" crop="scale" />
  <cld-transformation width="300" height="200" :overlay="sample" flags="splice" duration="3" />
  <cld-transformation start-offset="0" flags="layer_apply" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("dog.mp4")
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      imageSource("sample").transformation(
        new Transformation()
          .videoEdit(trim().duration("3.0"))
          .resize(scale().width(300).height(200))
      )
    ).prepend()
  );
Angular (@cloudinary/angular-5.x 1.x (legacy)):
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 (CloudinaryDotNet 1.x):
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")
iOS (cloudinary 3.x):
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")
Android (cloudinary-android 1.x):
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");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("dog.mp4")
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.concatenate(
  Concatenate.imageSource("sample") {
   transformation(Transformation {
   videoEdit(VideoEdit.trim() { duration(3.0F) })
   resize(Resize.scale() { width(300)
 height(200) }) })
   }) {
   prepend()
   }) 
}.generate()

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 should not be used when concatenating with a custom transition.

To add a custom transition:

  1. Add your base video as usual.
  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 transition video 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 (cloudinary 1.x):
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:duration=>"5.0"},
  {:height=>200, :width=>300, :crop=>"scale"},
  {:overlay=>"video:dog"},
  {:height=>200, :width=>300, :crop=>"scale"},
  {:duration=>"5.0"},
  {:effect=>"transition", :overlay=>"video:transition1"},
  {:flags=>"layer_apply"},
  {:flags=>"layer_apply"}
  ])
PHP (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('kitten_fighting.mp4'))
  ->videoEdit(VideoEdit::trim()->duration(5.0))
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::videoSource("dog")
  ->transformation((new Transformation())
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::trim()->duration(5.0)))
  )
  ->transition(
  Transition::videoSource("transition1"))
  );
PHP (cloudinary_php 1.x (legacy)):
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("duration"=>"5.0"),
  array("height"=>200, "width"=>300, "crop"=>"scale"),
  array("overlay"=>"video:dog"),
  array("height"=>200, "width"=>300, "crop"=>"scale"),
  array("duration"=>"5.0"),
  array("effect"=>"transition", "overlay"=>"video:transition1"),
  array("flags"=>"layer_apply"),
  array("flags"=>"layer_apply")
  )))
Python (cloudinary 1.x):
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'duration': "5.0"},
  {'height': 200, 'width': 300, 'crop': "scale"},
  {'overlay': "video:dog"},
  {'height': 200, 'width': 300, 'crop': "scale"},
  {'duration': "5.0"},
  {'effect': "transition", 'overlay': "video:transition1"},
  {'flags': "layer_apply"},
  {'flags': "layer_apply"}
  ])
Node.js (cloudinary 1.x):
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: "video:dog"},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: "video:transition1"},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]})
Java (cloudinary 1.x):
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .duration("5.0").chain()
  .height(200).width(300).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .effect("transition").overlay(new Layer().publicId("video:transition1")).chain()
  .flags("layer_apply").chain()
  .flags("layer_apply")).videoTag("kitten_fighting");
JS (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition1"))
  );
JS (cloudinary-core 2.x (legacy)):
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: new cloudinary.Layer().publicId("video:transition1")},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery (cloudinary-jquery 2.x):
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: new cloudinary.Layer().publicId("video:transition1")},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]})
React (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition1"))
  );
React (cloudinary-react 1.x):
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation duration="5.0" />
  <Transformation height="200" width="300" crop="scale" />
  <Transformation overlay="video:dog" />
  <Transformation height="200" width="300" crop="scale" />
  <Transformation duration="5.0" />
  <Transformation effect="transition" overlay="video:transition1" />
  <Transformation flags="layer_apply" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="kitten_fighting" >
  <cld-transformation duration="5.0" />
  <cld-transformation height="200" width="300" crop="scale" />
  <cld-transformation :overlay="video:dog" />
  <cld-transformation height="200" width="300" crop="scale" />
  <cld-transformation duration="5.0" />
  <cld-transformation effect="transition" :overlay="video:transition1" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition1"))
  );
Angular (@cloudinary/angular-5.x 1.x (legacy)):
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation duration="5.0">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:dog">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="scale">
  </cl-transformation>
  <cl-transformation duration="5.0">
  </cl-transformation>
  <cl-transformation effect="transition" overlay="video:transition1">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.NET (CloudinaryDotNet 1.x):
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Duration("5.0").Chain()
  .Height(200).Width(300).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Chain()
  .Height(200).Width(300).Crop("scale").Chain()
  .Duration("5.0").Chain()
  .Effect("transition").Overlay(new Layer().PublicId("video:transition1")).Chain()
  .Flags("layer_apply").Chain()
  .Flags("layer_apply")).BuildVideoTag("kitten_fighting")
iOS (cloudinary 3.x):
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setDuration("5.0").chain()
  .setHeight(200).setWidth(300).setCrop("scale").chain()
  .setOverlay("video:dog").chain()
  .setHeight(200).setWidth(300).setCrop("scale").chain()
  .setDuration("5.0").chain()
  .setEffect("transition").setOverlay("video:transition1").chain()
  .setFlags("layer_apply").chain()
  .setFlags("layer_apply")).generate("kitten_fighting.mp4")
Android (cloudinary-android 1.x):
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .duration("5.0").chain()
  .height(200).width(300).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .effect("transition").overlay(new Layer().publicId("video:transition1")).chain()
  .flags("layer_apply").chain()
  .flags("layer_apply")).resourceType("video").generate("kitten_fighting.mp4");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("kitten_fighting.mp4")
   videoEdit(VideoEdit.trim() { duration(5.0F) })
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.concatenate(
  Concatenate.videoSource("dog") {
   transformation(Transformation {
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.trim() { duration(5.0F) }) })
   }) {
   transition(
  Transition.videoSource("transition1"))
   }) 
}.generate()

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 (cloudinary 1.x):
Copy to clipboard
cl_video_tag("transition1", :width=>300, :crop=>"scale")
PHP (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('transition1.mp4'))
  ->resize(Resize::scale()->width(300));
PHP (cloudinary_php 1.x (legacy)):
Copy to clipboard
cl_video_tag("transition1", array("width"=>300, "crop"=>"scale"))
Python (cloudinary 1.x):
Copy to clipboard
CloudinaryVideo("transition1").video(width=300, crop="scale")
Node.js (cloudinary 1.x):
Copy to clipboard
cloudinary.video("transition1", {width: 300, crop: "scale"})
Java (cloudinary 1.x):
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).crop("scale")).videoTag("transition1");
JS (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("transition1.mp4").resize(scale().width(300));
JS (cloudinary-core 2.x (legacy)):
Copy to clipboard
cloudinary.videoTag('transition1', {width: 300, crop: "scale"}).toHtml();
jQuery (cloudinary-jquery 2.x):
Copy to clipboard
$.cloudinary.video("transition1", {width: 300, crop: "scale"})
React (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("transition1.mp4").resize(scale().width(300));
React (cloudinary-react 1.x):
Copy to clipboard
<Video publicId="transition1" >
  <Transformation width="300" crop="scale" />
</Video>
Vue.js (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="transition1" >
  <cld-transformation width="300" crop="scale" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("transition1.mp4").resize(scale().width(300));
Angular (@cloudinary/angular-5.x 1.x (legacy)):
Copy to clipboard
<cl-video public-id="transition1" >
  <cl-transformation width="300" crop="scale">
  </cl-transformation>
</cl-video>
.NET (CloudinaryDotNet 1.x):
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Width(300).Crop("scale")).BuildVideoTag("transition1")
iOS (cloudinary 3.x):
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setWidth(300).setCrop("scale")).generate("transition1.mp4")
Android (cloudinary-android 1.x):
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).crop("scale")).resourceType("video").generate("transition1.mp4");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("transition1.mp4")
   resize(Resize.scale() { width(300) }) 
}.generate()

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 (cloudinary 1.x):
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:duration=>"5.0"},
  {:height=>200, :width=>300, :crop=>"scale"},
  {:overlay=>"video:dog"},
  {:height=>200, :width=>300, :crop=>"scale"},
  {:duration=>"5.0"},
  {:effect=>"transition", :overlay=>"video:transition1"},
  {:angle=>180},
  {:effect=>"accelerate:5s"},
  {:flags=>"layer_apply"},
  {:flags=>"layer_apply"}
  ])
PHP (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('kitten_fighting.mp4'))
  ->videoEdit(VideoEdit::trim()->duration(5.0))
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::videoSource("dog")
  ->transformation((new Transformation())
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::trim()->duration(5.0)))
  )
  ->transition(
  Transition::videoSource("transition1")
  ->transformation((new Transformation())
  ->rotate(Rotate::byAngle(180))
  ->effect(Effect::accelerate()->rate("5s")))
  )
  );
PHP (cloudinary_php 1.x (legacy)):
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("duration"=>"5.0"),
  array("height"=>200, "width"=>300, "crop"=>"scale"),
  array("overlay"=>"video:dog"),
  array("height"=>200, "width"=>300, "crop"=>"scale"),
  array("duration"=>"5.0"),
  array("effect"=>"transition", "overlay"=>"video:transition1"),
  array("angle"=>180),
  array("effect"=>"accelerate:5s"),
  array("flags"=>"layer_apply"),
  array("flags"=>"layer_apply")
  )))
Python (cloudinary 1.x):
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'duration': "5.0"},
  {'height': 200, 'width': 300, 'crop': "scale"},
  {'overlay': "video:dog"},
  {'height': 200, 'width': 300, 'crop': "scale"},
  {'duration': "5.0"},
  {'effect': "transition", 'overlay': "video:transition1"},
  {'angle': 180},
  {'effect': "accelerate:5s"},
  {'flags': "layer_apply"},
  {'flags': "layer_apply"}
  ])
Node.js (cloudinary 1.x):
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: "video:dog"},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: "video:transition1"},
  {angle: 180},
  {effect: "accelerate:5s"},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]})
Java (cloudinary 1.x):
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .duration("5.0").chain()
  .height(200).width(300).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .effect("transition").overlay(new Layer().publicId("video:transition1")).chain()
  .angle(180).chain()
  .effect("accelerate:5s").chain()
  .flags("layer_apply").chain()
  .flags("layer_apply")).videoTag("kitten_fighting");
JS (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(
      videoSource("transition1").transformation(
        new Transformation()
          .rotate(byAngle(180))
          .effect(accelerate().rate("5s"))
      )
    )
  );
JS (cloudinary-core 2.x (legacy)):
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: new cloudinary.Layer().publicId("video:transition1")},
  {angle: 180},
  {effect: "accelerate:5s"},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery (cloudinary-jquery 2.x):
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: new cloudinary.Layer().publicId("video:transition1")},
  {angle: 180},
  {effect: "accelerate:5s"},
  {flags: "layer_apply"},
  {flags: "layer_apply"}
  ]})
React (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(
      videoSource("transition1").transformation(
        new Transformation()
          .rotate(byAngle(180))
          .effect(accelerate().rate("5s"))
      )
    )
  );
React (cloudinary-react 1.x):
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation duration="5.0" />
  <Transformation height="200" width="300" crop="scale" />
  <Transformation overlay="video:dog" />
  <Transformation height="200" width="300" crop="scale" />
  <Transformation duration="5.0" />
  <Transformation effect="transition" overlay="video:transition1" />
  <Transformation angle="180" />
  <Transformation effect="accelerate:5s" />
  <Transformation flags="layer_apply" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="kitten_fighting" >
  <cld-transformation duration="5.0" />
  <cld-transformation height="200" width="300" crop="scale" />
  <cld-transformation :overlay="video:dog" />
  <cld-transformation height="200" width="300" crop="scale" />
  <cld-transformation duration="5.0" />
  <cld-transformation effect="transition" :overlay="video:transition1" />
  <cld-transformation angle="180" />
  <cld-transformation effect="accelerate:5s" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(
      videoSource("transition1").transformation(
        new Transformation()
          .rotate(byAngle(180))
          .effect(accelerate().rate("5s"))
      )
    )
  );
Angular (@cloudinary/angular-5.x 1.x (legacy)):
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation duration="5.0">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:dog">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="scale">
  </cl-transformation>
  <cl-transformation duration="5.0">
  </cl-transformation>
  <cl-transformation effect="transition" overlay="video:transition1">
  </cl-transformation>
  <cl-transformation angle="180">
  </cl-transformation>
  <cl-transformation effect="accelerate:5s">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.NET (CloudinaryDotNet 1.x):
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Duration("5.0").Chain()
  .Height(200).Width(300).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Chain()
  .Height(200).Width(300).Crop("scale").Chain()
  .Duration("5.0").Chain()
  .Effect("transition").Overlay(new Layer().PublicId("video:transition1")).Chain()
  .Angle(180).Chain()
  .Effect("accelerate:5s").Chain()
  .Flags("layer_apply").Chain()
  .Flags("layer_apply")).BuildVideoTag("kitten_fighting")
iOS (cloudinary 3.x):
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setDuration("5.0").chain()
  .setHeight(200).setWidth(300).setCrop("scale").chain()
  .setOverlay("video:dog").chain()
  .setHeight(200).setWidth(300).setCrop("scale").chain()
  .setDuration("5.0").chain()
  .setEffect("transition").setOverlay("video:transition1").chain()
  .setAngle(180).chain()
  .setEffect("accelerate:5s").chain()
  .setFlags("layer_apply").chain()
  .setFlags("layer_apply")).generate("kitten_fighting.mp4")
Android (cloudinary-android 1.x):
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .duration("5.0").chain()
  .height(200).width(300).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .effect("transition").overlay(new Layer().publicId("video:transition1")).chain()
  .angle(180).chain()
  .effect("accelerate:5s").chain()
  .flags("layer_apply").chain()
  .flags("layer_apply")).resourceType("video").generate("kitten_fighting.mp4");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("kitten_fighting.mp4")
   videoEdit(VideoEdit.trim() { duration(5.0F) })
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.concatenate(
  Concatenate.videoSource("dog") {
   transformation(Transformation {
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.trim() { duration(5.0F) }) })
   }) {
   transition(
  Transition.videoSource("transition1") {
   transformation(Transformation {
   rotate(Rotate.byAngle(180))
   effect(Effect.accelerate() { rate("5s") }) })
   })
   }) 
}.generate()

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 (cloudinary 1.x):
Copy to clipboard
cl_video_tag("kitten_fighting", :transformation=>[
  {:duration=>"5.0"},
  {:height=>200, :width=>300, :crop=>"scale"},
  {:overlay=>"video:dog"},
  {:height=>200, :width=>300, :crop=>"scale"},
  {:duration=>"5.0"},
  {:effect=>"transition", :overlay=>"video:transition1"},
  {:flags=>"layer_apply"},
  {:flags=>"layer_apply"},
  {:overlay=>"video:snow_deer"},
  {:height=>200, :width=>300, :crop=>"scale"},
  {:duration=>"5.0"},
  {:effect=>"transition", :overlay=>"video:transition2"},
  {:flags=>"layer_apply"},
  {:flags=>"layer_apply"},
  {:flags=>"splice", :overlay=>"video:dog"},
  {:height=>200, :width=>300, :crop=>"scale"},
  {:duration=>"5.0"},
  {:flags=>"layer_apply"}
  ])
PHP (cloudinary_php 2.x):
Copy to clipboard
(new VideoTag('kitten_fighting.mp4'))
  ->videoEdit(VideoEdit::trim()->duration(5.0))
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::videoSource("dog")
  ->transformation((new Transformation())
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::trim()->duration(5.0)))
  )
  ->transition(
  Transition::videoSource("transition1"))
  )
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::videoSource("snow_deer")
  ->transformation((new Transformation())
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::trim()->duration(5.0)))
  )
  ->transition(
  Transition::videoSource("transition2"))
  )
  ->videoEdit(VideoEdit::concatenate(
  Concatenate::videoSource("dog")
  ->transformation((new Transformation())
  ->resize(Resize::scale()->width(300)
->height(200))
  ->videoEdit(VideoEdit::trim()->duration(5.0)))
  ));
PHP (cloudinary_php 1.x (legacy)):
Copy to clipboard
cl_video_tag("kitten_fighting", array("transformation"=>array(
  array("duration"=>"5.0"),
  array("height"=>200, "width"=>300, "crop"=>"scale"),
  array("overlay"=>"video:dog"),
  array("height"=>200, "width"=>300, "crop"=>"scale"),
  array("duration"=>"5.0"),
  array("effect"=>"transition", "overlay"=>"video:transition1"),
  array("flags"=>"layer_apply"),
  array("flags"=>"layer_apply"),
  array("overlay"=>"video:snow_deer"),
  array("height"=>200, "width"=>300, "crop"=>"scale"),
  array("duration"=>"5.0"),
  array("effect"=>"transition", "overlay"=>"video:transition2"),
  array("flags"=>"layer_apply"),
  array("flags"=>"layer_apply"),
  array("flags"=>"splice", "overlay"=>"video:dog"),
  array("height"=>200, "width"=>300, "crop"=>"scale"),
  array("duration"=>"5.0"),
  array("flags"=>"layer_apply")
  )))
Python (cloudinary 1.x):
Copy to clipboard
CloudinaryVideo("kitten_fighting").video(transformation=[
  {'duration': "5.0"},
  {'height': 200, 'width': 300, 'crop': "scale"},
  {'overlay': "video:dog"},
  {'height': 200, 'width': 300, 'crop': "scale"},
  {'duration': "5.0"},
  {'effect': "transition", 'overlay': "video:transition1"},
  {'flags': "layer_apply"},
  {'flags': "layer_apply"},
  {'overlay': "video:snow_deer"},
  {'height': 200, 'width': 300, 'crop': "scale"},
  {'duration': "5.0"},
  {'effect': "transition", 'overlay': "video:transition2"},
  {'flags': "layer_apply"},
  {'flags': "layer_apply"},
  {'flags': "splice", 'overlay': "video:dog"},
  {'height': 200, 'width': 300, 'crop': "scale"},
  {'duration': "5.0"},
  {'flags': "layer_apply"}
  ])
Node.js (cloudinary 1.x):
Copy to clipboard
cloudinary.video("kitten_fighting", {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: "video:dog"},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: "video:transition1"},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: "video:snow_deer"},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: "video:transition2"},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {flags: "splice", overlay: "video:dog"},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {flags: "layer_apply"}
  ]})
Java (cloudinary 1.x):
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .duration("5.0").chain()
  .height(200).width(300).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .effect("transition").overlay(new Layer().publicId("video:transition1")).chain()
  .flags("layer_apply").chain()
  .flags("layer_apply").chain()
  .overlay(new Layer().publicId("video:snow_deer")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .effect("transition").overlay(new Layer().publicId("video:transition2")).chain()
  .flags("layer_apply").chain()
  .flags("layer_apply").chain()
  .flags("splice").overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .flags("layer_apply")).videoTag("kitten_fighting");
JS (@cloudinary/url-gen 1.x):
Copy to clipboard
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition1"))
  )
  .videoEdit(
    concatenate(
      videoSource("snow_deer").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition2"))
  )
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    )
  );
JS (cloudinary-core 2.x (legacy)):
Copy to clipboard
cloudinary.videoTag('kitten_fighting', {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: new cloudinary.Layer().publicId("video:transition1")},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: new cloudinary.Layer().publicId("video:snow_deer")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: new cloudinary.Layer().publicId("video:transition2")},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {flags: "splice", overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery (cloudinary-jquery 2.x):
Copy to clipboard
$.cloudinary.video("kitten_fighting", {transformation: [
  {duration: "5.0"},
  {height: 200, width: 300, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: new cloudinary.Layer().publicId("video:transition1")},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {overlay: new cloudinary.Layer().publicId("video:snow_deer")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {effect: "transition", overlay: new cloudinary.Layer().publicId("video:transition2")},
  {flags: "layer_apply"},
  {flags: "layer_apply"},
  {flags: "splice", overlay: new cloudinary.Layer().publicId("video:dog")},
  {height: 200, width: 300, crop: "scale"},
  {duration: "5.0"},
  {flags: "layer_apply"}
  ]})
React (@cloudinary/react 1.x):
Copy to clipboard
//React SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition1"))
  )
  .videoEdit(
    concatenate(
      videoSource("snow_deer").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition2"))
  )
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    )
  );
React (cloudinary-react 1.x):
Copy to clipboard
<Video publicId="kitten_fighting" >
  <Transformation duration="5.0" />
  <Transformation height="200" width="300" crop="scale" />
  <Transformation overlay="video:dog" />
  <Transformation height="200" width="300" crop="scale" />
  <Transformation duration="5.0" />
  <Transformation effect="transition" overlay="video:transition1" />
  <Transformation flags="layer_apply" />
  <Transformation flags="layer_apply" />
  <Transformation overlay="video:snow_deer" />
  <Transformation height="200" width="300" crop="scale" />
  <Transformation duration="5.0" />
  <Transformation effect="transition" overlay="video:transition2" />
  <Transformation flags="layer_apply" />
  <Transformation flags="layer_apply" />
  <Transformation flags="splice" overlay="video:dog" />
  <Transformation height="200" width="300" crop="scale" />
  <Transformation duration="5.0" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js (cloudinary-vue 1.x):
Copy to clipboard
<cld-video public-id="kitten_fighting" >
  <cld-transformation duration="5.0" />
  <cld-transformation height="200" width="300" crop="scale" />
  <cld-transformation :overlay="video:dog" />
  <cld-transformation height="200" width="300" crop="scale" />
  <cld-transformation duration="5.0" />
  <cld-transformation effect="transition" :overlay="video:transition1" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation :overlay="video:snow_deer" />
  <cld-transformation height="200" width="300" crop="scale" />
  <cld-transformation duration="5.0" />
  <cld-transformation effect="transition" :overlay="video:transition2" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="layer_apply" />
  <cld-transformation flags="splice" :overlay="video:dog" />
  <cld-transformation height="200" width="300" crop="scale" />
  <cld-transformation duration="5.0" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular (@cloudinary/ng 1.x):
Copy to clipboard
//Angular SDK transformations are created using @cloudinary/url-gen.
new CloudinaryVideo("kitten_fighting.mp4")
  .videoEdit(trim().duration("5.0"))
  .resize(scale().width(300).height(200))
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition1"))
  )
  .videoEdit(
    concatenate(
      videoSource("snow_deer").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    ).transition(videoSource("transition2"))
  )
  .videoEdit(
    concatenate(
      videoSource("dog").transformation(
        new Transformation()
          .resize(scale().width(300).height(200))
          .videoEdit(trim().duration("5.0"))
      )
    )
  );
Angular (@cloudinary/angular-5.x 1.x (legacy)):
Copy to clipboard
<cl-video public-id="kitten_fighting" >
  <cl-transformation duration="5.0">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:dog">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="scale">
  </cl-transformation>
  <cl-transformation duration="5.0">
  </cl-transformation>
  <cl-transformation effect="transition" overlay="video:transition1">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation overlay="video:snow_deer">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="scale">
  </cl-transformation>
  <cl-transformation duration="5.0">
  </cl-transformation>
  <cl-transformation effect="transition" overlay="video:transition2">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
  <cl-transformation flags="splice" overlay="video:dog">
  </cl-transformation>
  <cl-transformation height="200" width="300" crop="scale">
  </cl-transformation>
  <cl-transformation duration="5.0">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.NET (CloudinaryDotNet 1.x):
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Duration("5.0").Chain()
  .Height(200).Width(300).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("video:dog")).Chain()
  .Height(200).Width(300).Crop("scale").Chain()
  .Duration("5.0").Chain()
  .Effect("transition").Overlay(new Layer().PublicId("video:transition1")).Chain()
  .Flags("layer_apply").Chain()
  .Flags("layer_apply").Chain()
  .Overlay(new Layer().PublicId("video:snow_deer")).Chain()
  .Height(200).Width(300).Crop("scale").Chain()
  .Duration("5.0").Chain()
  .Effect("transition").Overlay(new Layer().PublicId("video:transition2")).Chain()
  .Flags("layer_apply").Chain()
  .Flags("layer_apply").Chain()
  .Flags("splice").Overlay(new Layer().PublicId("video:dog")).Chain()
  .Height(200).Width(300).Crop("scale").Chain()
  .Duration("5.0").Chain()
  .Flags("layer_apply")).BuildVideoTag("kitten_fighting")
iOS (cloudinary 3.x):
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setDuration("5.0").chain()
  .setHeight(200).setWidth(300).setCrop("scale").chain()
  .setOverlay("video:dog").chain()
  .setHeight(200).setWidth(300).setCrop("scale").chain()
  .setDuration("5.0").chain()
  .setEffect("transition").setOverlay("video:transition1").chain()
  .setFlags("layer_apply").chain()
  .setFlags("layer_apply").chain()
  .setOverlay("video:snow_deer").chain()
  .setHeight(200).setWidth(300).setCrop("scale").chain()
  .setDuration("5.0").chain()
  .setEffect("transition").setOverlay("video:transition2").chain()
  .setFlags("layer_apply").chain()
  .setFlags("layer_apply").chain()
  .setFlags("splice").setOverlay("video:dog").chain()
  .setHeight(200).setWidth(300).setCrop("scale").chain()
  .setDuration("5.0").chain()
  .setFlags("layer_apply")).generate("kitten_fighting.mp4")
Android (cloudinary-android 1.x):
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .duration("5.0").chain()
  .height(200).width(300).crop("scale").chain()
  .overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .effect("transition").overlay(new Layer().publicId("video:transition1")).chain()
  .flags("layer_apply").chain()
  .flags("layer_apply").chain()
  .overlay(new Layer().publicId("video:snow_deer")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .effect("transition").overlay(new Layer().publicId("video:transition2")).chain()
  .flags("layer_apply").chain()
  .flags("layer_apply").chain()
  .flags("splice").overlay(new Layer().publicId("video:dog")).chain()
  .height(200).width(300).crop("scale").chain()
  .duration("5.0").chain()
  .flags("layer_apply")).resourceType("video").generate("kitten_fighting.mp4");
Kotlin (kotlin-url-gen 1.x):
Copy to clipboard
cloudinary.video {
  publicId("kitten_fighting.mp4")
   videoEdit(VideoEdit.trim() { duration(5.0F) })
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.concatenate(
  Concatenate.videoSource("dog") {
   transformation(Transformation {
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.trim() { duration(5.0F) }) })
   }) {
   transition(
  Transition.videoSource("transition1"))
   })
   videoEdit(VideoEdit.concatenate(
  Concatenate.videoSource("snow_deer") {
   transformation(Transformation {
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.trim() { duration(5.0F) }) })
   }) {
   transition(
  Transition.videoSource("transition2"))
   })
   videoEdit(VideoEdit.concatenate(
  Concatenate.videoSource("dog") {
   transformation(Transformation {
   resize(Resize.scale() { width(300)
 height(200) })
   videoEdit(VideoEdit.trim() { duration(5.0F) }) })
   })) 
}.generate()

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).

✔️ Feedback sent!

Rate this page: