Cloudinary Blog
How to Generate Video Preview Clips

Before deciding whether to watch a movie, you would likely check out its reviews and ratings on sites such as Rotten Tomatoes, IMDB, or Metacritic. You’re not alone. Online reviews figure prominently as a factor that influences viewers’ decisions on which movies to see. In addition, filmmakers always produce trailers to be shown as previews that showcase the highlights of their movies in the hope of stirring a buzz and anticipation for the debut.

Toward that end, suppose you as an app developer are tasked with generating a preview clip for a playlist of videos. Do take advantage of Cloudinary, a cloud-based, end-to-end solution for uploading, storing, transforming, optimizing, and delivering images and videos, with which you can manage media by way of a simple process. You can then focus on your primary tasks.

The Process

In this article, I’ll show you how to create video preview clips in two simple steps with Cloudinary.

Step 1: Upload the Video

In the console, click the Media Library tab and then click My File in the pane that opens. Drag and drop the video file to the pane.

Alternatively, click Browse in the My File pane and select and open the video file in your file system.

Upload

Tip: Embed the upload widget in your app to enable quick video upload from multiple channels.

Step 2: Build the Clip

Animated previews for any videos, including films, are often eye-catching and captivating. Because time is of the essence, you might want to produce multiple previews with different themes for various audiences.

The following procedure creates an approximately four-and-a-half-minute-long clip from a video, which stars a bunny.

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

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

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

  1. Specify the duration (in seconds) of the preview video, for example, du_20.
  2. Specify the desired dimension (in pixels) of the preview video, for example w_400.
  3. Specify the first video section (so for start_offset) and the last one (eo for end_offset).
  4. Assign a name (public_id) for the videos to be concatenated with the overlay video parameter l_video.
  5. Activate the flag fl_layer_apply, which concatenates a section of the video on to another video by means of the offset parameters.
  6. Set splice so that Cloudinary concatenates the video section instead of adding it as an overlay.

Afterwards, perform the above six steps for the other sections of the video that contain the remaining scenes of the preview video. No overlays are necessary. It’s a cinch.

There you have it: a 20-second preview video:

Ruby:
cl_video_tag("bb_bunny", :transformation=>[
  {:width=>400, :duration=>"20", :crop=>"scale"},
  {:overlay=>"video:bb_bunny", :start_offset=>"3", :end_offset=>"7"},
  {:start_offset=>"0", :flags=>["layer_apply", "splice"], :width=>400, :crop=>"scale"},
  {:overlay=>"video:bb_bunny", :start_offset=>"25", :end_offset=>"30"},
  {:start_offset=>"4", :flags=>["layer_apply", "splice"], :width=>400, :crop=>"scale"},
  {:overlay=>"video:bb_bunny", :start_offset=>"240", :end_offset=>"280"},
  {:start_offset=>"8", :flags=>["layer_apply", "splice"], :width=>400, :crop=>"scale"}
  ])
PHP:
cl_video_tag("bb_bunny", array("transformation"=>array(
  array("width"=>400, "duration"=>"20", "crop"=>"scale"),
  array("overlay"=>"video:bb_bunny", "start_offset"=>"3", "end_offset"=>"7"),
  array("start_offset"=>"0", "flags"=>array("layer_apply", "splice"), "width"=>400, "crop"=>"scale"),
  array("overlay"=>"video:bb_bunny", "start_offset"=>"25", "end_offset"=>"30"),
  array("start_offset"=>"4", "flags"=>array("layer_apply", "splice"), "width"=>400, "crop"=>"scale"),
  array("overlay"=>"video:bb_bunny", "start_offset"=>"240", "end_offset"=>"280"),
  array("start_offset"=>"8", "flags"=>array("layer_apply", "splice"), "width"=>400, "crop"=>"scale")
  )))
Python:
CloudinaryVideo("bb_bunny").video(transformation=[
  {"width": 400, "duration": "20", "crop": "scale"},
  {"overlay": "video:bb_bunny", "start_offset": "3", "end_offset": "7"},
  {"start_offset": "0", "flags": ["layer_apply", "splice"], "width": 400, "crop": "scale"},
  {"overlay": "video:bb_bunny", "start_offset": "25", "end_offset": "30"},
  {"start_offset": "4", "flags": ["layer_apply", "splice"], "width": 400, "crop": "scale"},
  {"overlay": "video:bb_bunny", "start_offset": "240", "end_offset": "280"},
  {"start_offset": "8", "flags": ["layer_apply", "splice"], "width": 400, "crop": "scale"}
  ])
Node.js:
cloudinary.video("bb_bunny", {transformation: [
  {width: 400, duration: "20", crop: "scale"},
  {overlay: "video:bb_bunny", start_offset: "3", end_offset: "7"},
  {start_offset: "0", flags: ["layer_apply", "splice"], width: 400, crop: "scale"},
  {overlay: "video:bb_bunny", start_offset: "25", end_offset: "30"},
  {start_offset: "4", flags: ["layer_apply", "splice"], width: 400, crop: "scale"},
  {overlay: "video:bb_bunny", start_offset: "240", end_offset: "280"},
  {start_offset: "8", flags: ["layer_apply", "splice"], width: 400, crop: "scale"}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(400).duration("20").crop("scale").chain()
  .overlay("video:bb_bunny").startOffset("3").endOffset("7").chain()
  .startOffset("0").flags("layer_apply", "splice").width(400).crop("scale").chain()
  .overlay("video:bb_bunny").startOffset("25").endOffset("30").chain()
  .startOffset("4").flags("layer_apply", "splice").width(400).crop("scale").chain()
  .overlay("video:bb_bunny").startOffset("240").endOffset("280").chain()
  .startOffset("8").flags("layer_apply", "splice").width(400).crop("scale")).videoTag("bb_bunny");
JS:
cloudinary.videoTag('bb_bunny', {transformation: [
  {width: 400, duration: "20", crop: "scale"},
  {overlay: "video:bb_bunny", startOffset: "3", endOffset: "7"},
  {startOffset: "0", flags: ["layer_apply", "splice"], width: 400, crop: "scale"},
  {overlay: "video:bb_bunny", startOffset: "25", endOffset: "30"},
  {startOffset: "4", flags: ["layer_apply", "splice"], width: 400, crop: "scale"},
  {overlay: "video:bb_bunny", startOffset: "240", endOffset: "280"},
  {startOffset: "8", flags: ["layer_apply", "splice"], width: 400, crop: "scale"}
  ]}).toHtml();
jQuery:
$.cloudinary.video("bb_bunny", {transformation: [
  {width: 400, duration: "20", crop: "scale"},
  {overlay: "video:bb_bunny", start_offset: "3", end_offset: "7"},
  {start_offset: "0", flags: ["layer_apply", "splice"], width: 400, crop: "scale"},
  {overlay: "video:bb_bunny", start_offset: "25", end_offset: "30"},
  {start_offset: "4", flags: ["layer_apply", "splice"], width: 400, crop: "scale"},
  {overlay: "video:bb_bunny", start_offset: "240", end_offset: "280"},
  {start_offset: "8", flags: ["layer_apply", "splice"], width: 400, crop: "scale"}
  ]})
React:
<Video publicId="bb_bunny" >
  <Transformation width="400" duration="20" crop="scale" />
  <Transformation overlay="video:bb_bunny" startOffset="3" endOffset="7" />
  <Transformation startOffset="0" flags={["layer_apply", "splice"]} width="400" crop="scale" />
  <Transformation overlay="video:bb_bunny" startOffset="25" endOffset="30" />
  <Transformation startOffset="4" flags={["layer_apply", "splice"]} width="400" crop="scale" />
  <Transformation overlay="video:bb_bunny" startOffset="240" endOffset="280" />
  <Transformation startOffset="8" flags={["layer_apply", "splice"]} width="400" crop="scale" />
</Video>
Angular:
<cl-video public-id="bb_bunny" >
  <cl-transformation width="400" duration="20" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:bb_bunny" start-offset="3" end-offset="7">
  </cl-transformation>
  <cl-transformation start-offset="0" flags={{["layer_apply", "splice"]}} width="400" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:bb_bunny" start-offset="25" end-offset="30">
  </cl-transformation>
  <cl-transformation start-offset="4" flags={{["layer_apply", "splice"]}} width="400" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="video:bb_bunny" start-offset="240" end-offset="280">
  </cl-transformation>
  <cl-transformation start-offset="8" flags={{["layer_apply", "splice"]}} width="400" crop="scale">
  </cl-transformation>
</cl-video>
.Net:
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(400).Duration("20").Crop("scale").Chain()
  .Overlay("video:bb_bunny").StartOffset("3").EndOffset("7").Chain()
  .StartOffset("0").Flags("layer_apply", "splice").Width(400).Crop("scale").Chain()
  .Overlay("video:bb_bunny").StartOffset("25").EndOffset("30").Chain()
  .StartOffset("4").Flags("layer_apply", "splice").Width(400).Crop("scale").Chain()
  .Overlay("video:bb_bunny").StartOffset("240").EndOffset("280").Chain()
  .StartOffset("8").Flags("layer_apply", "splice").Width(400).Crop("scale")).BuildVideoTag("bb_bunny")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(400).duration("20").crop("scale").chain()
  .overlay("video:bb_bunny").startOffset("3").endOffset("7").chain()
  .startOffset("0").flags("layer_apply", "splice").width(400).crop("scale").chain()
  .overlay("video:bb_bunny").startOffset("25").endOffset("30").chain()
  .startOffset("4").flags("layer_apply", "splice").width(400).crop("scale").chain()
  .overlay("video:bb_bunny").startOffset("240").endOffset("280").chain()
  .startOffset("8").flags("layer_apply", "splice").width(400).crop("scale")).resourceType("video").generate("bb_bunny.mp4");
iOS:
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(400).setDuration("20").setCrop("scale").chain()
  .setOverlay("video:bb_bunny").setStartOffset("3").setEndOffset("7").chain()
  .setStartOffset("0").setFlags("layer_apply", "splice").setWidth(400).setCrop("scale").chain()
  .setOverlay("video:bb_bunny").setStartOffset("25").setEndOffset("30").chain()
  .setStartOffset("4").setFlags("layer_apply", "splice").setWidth(400).setCrop("scale").chain()
  .setOverlay("video:bb_bunny").setStartOffset("240").setEndOffset("280").chain()
  .setStartOffset("8").setFlags("layer_apply", "splice").setWidth(400).setCrop("scale")).generate("bb_bunny.mp4")
, complete with shots that highlight the fetching parts of the video.

Bonus Step: Remove the Audio

Depending on the context in which the preview video is shown, the associated audio might not apply. In that case, remove the audio by adding the ac_none parameter to the URL, like this:

https://res.cloudinary.com/demo/video/upload/w_400,du_72/l_video:bb_bunny,so_3,eo_7/so_0,fl_layer_apply.splice,w_400/l_video:bb_bunny,so_25,eo_30/so_4,fl_layer_apply.splice,w_400/l_video:bb_bunny,so_240,eo_290/so_8,fl_layer_apply.splice,w_400/ac_none/w_400/bb_bunny.mp4

A Cinch Indeed

As promised, the process calls for no coding at all. You could, however, polish up the preview clip, as follows:

  • Add text or an image overlay with a UI tip, such as “Click to play the full preview.”

  • Add an image to the end of the video with a suggestion or catchy message, for example, “Coming soon to a cinema near you.”

  • Add a quick flash between sections as a hint on what’s coming up in the clip!

Note
Videos spliced together must share the same width and height. To achieve that uniformity, set the size-transformation parameters.

Conclusion

For simplicity, this tutorial employs URLs to illustrate the Cloudinary capabilities in question. Do check out Cloudinary’s many useful libraries:

PHP, Ruby, Ruby, JavaScript, iOS, Android, and others.

For details on trimming videos, check out the Trimming Videos section of the Cloudinary documentation.

Again, creating video preview clips with Cloudinary is painless, intuitive, and efficient. Have a try!

Recent Blog Posts

How to Make Boomerang Video Effect With Cloudinary

When you see the term boomerang, what is the first thing that comes to mind?

A thrown tool made of wood that returns to its thrower? Another definition is reversal, logically portraying the aim of the tool itself. Based on this definition, the term boomerang videos” came into play to depict videos that loop back and forth.

Read more
Shortening the Development Cycle of Media-Related apps with Cloudinary

Currently, the Android platform boasts the highest demand for mobile solutions, as evidenced by Google’s announcement in 2017 that there were two billion monthly active Android devices, a number that is likely to increase in the years ahead. For app developers like you, now is the right time to build and release solutions for Android. you might have also noticed that a higher percentage of apps being developed nowadays are filled with visual media: images and videos.

Read more
Build Your Own Image Storyboard Android App

Globally, approximately two billion people now own smartphones, which also feature cameras capable of capturing photos and videos of a tonal richness and quality unimaginable even five years ago. Until recently, those cameras behaved mostly as optical sensors, catching light that determines the resulting image's pixels. The next generation of cameras, however, can blend hardware and computer-vision algorithms that apply to an image's semantic content, spawning creative mobile photo and video apps.

Read more
Cloudinary Delivers Simplified Image Management Workflow for Fairfax Media's Digital Transformation

Fairfax Media Limited [ASX:FXJ] is one of the largest media companies in Australia and New Zealand that engages audiences and communities via print and digital media. It includes recognizable mastheads including The Australian Financial Review, The Sydney Morning Herald and The Age. Fairfax Media operates numerous news and information websites, as well as tablet and smartphone apps, for online news sites.

Read more
Bleacher Report Scores with Real-Time Video Highlights Delivered by Cloudinary

Bleacher Report is a global digital destination for sports fans, creating and collaborating on content at the intersection of sports and culture. Owned by Turner, a division of Time Warner, Bleacher Report's website and social channels focus on sports culture for the next generation of fans. Bleacher Report also has a five-star mobile app and popular email newsletters, which are part of the company’s strategy for instantly delivering in-depth articles, results and video highlights personalized for users’ favorite teams, players and leagues.

Read more