Cloudinary Blog

Video Management Made Easy

By Christian Nwamba
Video Management Made Easy with Cloudinary

Like it or not, visuals tell better stories than words. But using images and videos on a website presents challenges. This article is a follow-up to Website Image Performance Improvement, in which we discussed how to upload, store, manipulate, optimize and deliver images, efficiently and effectively. Now, let's talk video.

Much like we talked in our previous article about the managing images on your website, you may also have a need to render video content. Trust me -- simply throwing a <video> tag with an accurate source to the browser does not deliver user satisfaction. At a high level, you need to consider the website layout, video quality and delivery, as well as address challenges, such as:

Adjusting video quality based on network conditions. For example, users in developing countries may have a slower internet connection compared to users in developed countries:

  • Delivering content to mobile users
  • Transcoding for different browsers
  • Manipulating video, such as resizing, cropping and adding visual effects

All these requirements make video complex. You cannot just take care of videos in few hours. In fact, you may find it difficult to find answers to certain questions on video management. But, there is one swift solution -- Cloudinary.

Cloudinary is an all-in-one media management solution. In this article, we are going to delve into using Cloudinary to easily upload, manipulate and deliver videos.

Let's see how we can use Cloudinary in our Node application.

Setup and Installation

Using Cloudinary in your existing application is easy:

  • Create a free Cloudinary account. You will receive an API key and secret. Store the key and your cloud name somewhere safe and easily accessible.
  • Install the Cloudinary SDK in your existing project: npm install --save cloudinary
  • Include and configure Cloudinary in your Node app using the credentials received after creating a new account:
Copy to clipboard
var cloudinary = require('cloudinary');

cloudinary.config({ 
    cloud_name: '<CLOUD_NAME>', 
    api_key: '<API_KEY>', 
    api_secret: '<API_SECRET>' 
});

The cloud_name is enough when making and opening API calls like delivering videos. The key and secret are needed for secure calls, such as video uploads.

Video Upload

All you need to start managing videos is to upload the best video quality you have. You can manipulate videos on-the-fly using Cloudinary's comprehensive API and easy to use manipulation URLs. Therefore, there is no need to do that before uploading. Let's see a simple code example from Node for making a video upload:

Copy to clipboard
cloudinary.uploader.upload("MLB_Vid.mp4", 
        function(result) {console.log(result); }, 
        { resource_type: "video" });

It’s the same API method for images, but this time you have to explicitly tell the uploader that the resource type is video by passing the following as the third argument for the upload method:

Copy to clipboard
{ resource_type: "video" }

Video Delivery

After uploading videos, you need to determine how they should be delivered. You can use the SDK's video API to achieve this:

Copy to clipboard
cloudinary.video("MLB_Vid")

Video Transformation

Transformation is the act of adjusting the existing properties and quality of the videos to achieve the desired output.

Manual transformations can be complex and time-consuming. Mitigating these challenges is not easy, but that is where Cloudinary comes in.

Video transformations come in a variety of forms:

  • Quality Optimization
  • Resizing and Cropping
  • Transcoding
  • Content manipulation
  • Audio adjustment
  • and a lot more

You can transform videos at one of two different stages:

  • When uploading (known as Eager Transformation)
  • While delivering (known as Lazy Transformation)

Eager Transformation

Eager transformation is best when you do not need to manipulate video dynamically. You just need to manipulate once, store and deliver to users.

Let's see an example of transforming videos while uploading:

Copy to clipboard
cloudinary.uploader.upload("MLB_Vid.mp4", 
    function(result) {console.log(result); }, 
    { resource_type: "video", 
      eager: [
      { width: 300, height: 300,
        crop: "pad", audio_codec: "none" }, 
      { width: 160, height: 100,
        crop: "crop", gravity: "south",
        audio_codec: "none" } ]});

The third argument, which is an object, is also used to specify the eager transformation using an eager property.

Lazy Transformation

In lazy transformation, the reverse becomes the case. Rather than manipulating videos during upload, you can store the best quality available and manipulate them on delivery.

Therefore, you have the control to dynamically generate a transformed variation of a given video when you are about to embed it in the browser:

Ruby:
Copy to clipboard
cl_video_tag("MLB_Vid", :transformation=>[
  {:width=>300, :height=>300, :crop=>"fill"},
  {:overlay=>"cloudinary_icon", :width=>0.8, :flags=>"relative", :effect=>"brightness:200", :opacity=>50}
  ])
PHP v1:
Copy to clipboard
cl_video_tag("MLB_Vid", array("transformation"=>array(
  array("width"=>300, "height"=>300, "crop"=>"fill"),
  array("overlay"=>"cloudinary_icon", "width"=>"0.8", "flags"=>"relative", "effect"=>"brightness:200", "opacity"=>50)
  )))
PHP v2:
Copy to clipboard
(new VideoTag('MLB_Vid.mp4'))
  ->resize(Resize::fill()->width(300)->height(300))
  ->overlay(
      Overlay::source(Source::image('cloudinary_icon')
        ->transformation((new ImageTransformation())
          ->resize(Resize::scale()->width(0.8)->relative())
          ->adjust(Adjust::opacity(50))
          ->adjust(Adjust::brightness()->level(200))
  )));
Python:
Copy to clipboard
CloudinaryVideo("MLB_Vid").video(transformation=[
  {'width': 300, 'height': 300, 'crop': "fill"},
  {'overlay': "cloudinary_icon", 'width': "0.8", 'flags': "relative", 'effect': "brightness:200", 'opacity': 50}
  ])
Node.js:
Copy to clipboard
cloudinary.video("MLB_Vid", {transformation: [
  {width: 300, height: 300, crop: "fill"},
  {overlay: "cloudinary_icon", width: "0.8", flags: "relative", effect: "brightness:200", opacity: 50}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(300).height(300).crop("fill").chain()
  .overlay(new Layer().publicId("cloudinary_icon")).width(0.8).flags("relative").effect("brightness:200").opacity(50)).videoTag("MLB_Vid");
JS:
Copy to clipboard
cloudinary.videoTag('MLB_Vid', {transformation: [
  {width: 300, height: 300, crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("cloudinary_icon"), width: "0.8", flags: "relative", effect: "brightness:200", opacity: 50}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("MLB_Vid", {transformation: [
  {width: 300, height: 300, crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("cloudinary_icon"), width: "0.8", flags: "relative", effect: "brightness:200", opacity: 50}
  ]})
React:
Copy to clipboard
<Video publicId="MLB_Vid" >
  <Transformation width="300" height="300" crop="fill" />
  <Transformation overlay="cloudinary_icon" width="0.8" flags="relative" effect="brightness:200" opacity="50" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="MLB_Vid" >
  <cld-transformation width="300" height="300" crop="fill" />
  <cld-transformation :overlay="cloudinary_icon" width="0.8" flags="relative" effect="brightness:200" opacity="50" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="MLB_Vid" >
  <cl-transformation width="300" height="300" crop="fill">
  </cl-transformation>
  <cl-transformation overlay="cloudinary_icon" width="0.8" flags="relative" effect="brightness:200" opacity="50">
  </cl-transformation>
</cl-video>
.NET:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Width(300).Height(300).Crop("fill").Chain()
  .Overlay(new Layer().PublicId("cloudinary_icon")).Width(0.8).Flags("relative").Effect("brightness:200").Opacity(50)).BuildVideoTag("MLB_Vid")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(300).height(300).crop("fill").chain()
  .overlay(new Layer().publicId("cloudinary_icon")).width(0.8).flags("relative").effect("brightness:200").opacity(50)).resourceType("video").generate("MLB_Vid.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setWidth(300).setHeight(300).setCrop("fill").chain()
  .setOverlay("cloudinary_icon").setWidth(0.8).setFlags("relative").setEffect("brightness:200").setOpacity(50)).generate("MLB_Vid.mp4")

Video Transformation Examples

Let's see five interesting techniques you can apply using video transformation:

1. Resizing and Cropping

You can adjust the size and width of your videos to fit the user’s screen, which will in turn reduce the amount of kilobytes that will need to be downloaded:

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

You also can retain the aspect ratio by providing only the width and using the scale crop type:

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

There are other scaling options that will help you gain full control over your videos' dimensions.

2. Format and Quality Control

It is possible to use a desired format or quality level that suites a given video delivery situation. The fact that you uploaded an .mp4 video does not mean you have to upload another .webm version of that video. Cloudinary uses a feature called transcoding that enables you upload a single video and deliver it dynamically in different formats:

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

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

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

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

You also can adjust the quality of the video:

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

Find out more about format and quality control here

3. Video Trimming

You can trim video content and discard the parts you don't need by telling Cloudinary which part of the videos you want to keep:

If you would like to start at 6.5sec and end after at 10sec:

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

See more on video trimming here

4. Video Effects

Cloudinary lets you add a variety of cool effects to your videos during playtime. Effects like fade in and fade out, visual noise, blur, saturation and lots more.

Let's see a simple example of using Cloudinary to apply fade in to a video at start and fade out at end:

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

The positive fade value controls fade in, while the negative fade value controls fade out.

5. Text Overlay

It is possible to add text content to your video at a given play time. Let's add a text, "Cool Video", at the down-middle part of our video. The text should be displayed after 2 seconds and should be removed after 5 seconds:

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

Adaptive Bitrate Streaming

Cloudinary can deliver videos optimally using a smart technique know as Adaptive Bitrate Streaming. This is a video delivery technique that adjusts the quality of a video stream in real time according to detected bandwidth and CPU capacity. With adaptive bitrate streaming, videos start quicker, with fewer buffering interruptions, and is delivered at the best possible quality for the current device and network connection, to maximize user experience.

Copy to clipboard
cloudinary.uploader.upload('MLB_Vid.mp4', 
        function(result) {console.log(result); }, 
        { resource_type: "video", 
        eager: [
            { streaming_profile: "full_hd", format: "m3u8" }],                                   
        eager_async: true,
        eager_notification_url: "http://mywebsite/upload_completed",
        public_id: "my_MLB"});

An eager transformation is initiated during upload. This transformation is an array that takes a streaming profile configuration. The MLB_Vid.mp4 video is encoded into HLS format using a Full HD streaming profile.

You can learn more about this technique in a previous article or via the documentation

Responsive Videos

Eliminate stretching or shrinking videos when adapting them for different screen dimensions. Based on the resizing and cropping transformation feature we have seen, you can perform automatic resizing and cropping to fit the graphic design and layout on any device, at any resolution, using Cloudinary’s powerful URL-based transformations.

Conclusion

Now is the time to step back and reflect. Compare what you could afford to do with your videos manually and how long it would take, to what you can accomplish with Cloudinary in your arsenal. With Cloudinary, you’ll improve your productivity with its robust features and be able to cater to whatever media management needs you might have. Get started by signing up if you haven't already!


Further Reading on Video Manipulation

Recent Blog Posts

Our $2B Valuation

By
Blackstone Growth Invests in Cloudinary

When we started our journey in 2012, we were looking to improve our lives as developers by making it easier for us to handle the arduous tasks of handling images and videos in our code. That initial line of developer code has evolved into a full suite of media experience solutions driven by a mission that gradually revealed itself over the course of the past 10 years: help companies unleash the full potential of their media to create the most engaging visual experiences.

Read more
Direct-to-Consumer E-Commerce Requires Compelling Visual Experiences

When brands like you adopt a direct–to-consumer (DTC) e-commerce approach with no involvement of retailers or marketplaces, you gain direct and timely insight into evolving shopping behaviors. Accordingly, you can accommodate shoppers’ preferences by continually adjusting your product offering and interspersing the shopping journey with moments of excitement and intrigue. Opportunities abound for you to cultivate engaging customer relationships.

Read more
Automatically Translating Videos for an International Audience

No matter your business focus—public service, B2B integration, recruitment—multimedia, in particular video, is remarkably effective in communicating with the audience. Before, making video accessible to diverse viewers involved tasks galore, such as eliciting the service of production studios to manually dub, transcribe, and add subtitles. Those operations were costly and slow, especially for globally destined content.

Read more
Cloudinary Helps Minted Manage Its Image-Generation Pipeline at Scale

Shoppers return time and again to Minted’s global online community of independent artists and designers because they know they can count on unique, statement-making products of the highest quality there. Concurrently, the visual imagery on Minted.com must do justice to the designs into which the creators have poured their hearts and souls. For Minted’s VP of Engineering David Lien, “Because we are a premium brand, we need to ensure that every single one of our product images matches the selected configuration exactly. For example, if you pick an 18x24 art print on blue canvas, we will show that exact combination on the hero images in the PDF.”

Read more
Highlights on ImageCon 2021 and a Preview of ImageCon 2022

New year, same trend! Visual media will continue to play a monumental role in driving online conversions. To keep up with visual-experience trends and best practices, Cloudinary holds an annual conference called ImageCon, a one-of-a-kind event that helps attendees create the most engaging visual experiences possible.

Read more