Cloudinary Blog

How to Prepare Videos for Social Media: A Developer’s Guide

How to Prepare Videos for Social Media: A Developer’s Guide

Social media is now one of the most effective channels for attracting customers. That’s because not only is the content readily accessible worldwide, but also entrepreneurs are rapidly building products for global consumption. A visit to ProductHunt will show you that such a phenomenon is happening faster than you think. The richer and more captivating your content is, the more visitors enjoy engaging with your site, ultimately leading to an impressive expansion of your customer base over time.

Being adept with Cloudinary’s superb media-management capabilities, including its widgets and APIs, can give you as developers an edge in creating appealing content. Cloudinary’s APIs, in particular, can elevate content from being good or mediocre to being great in short order.

This article shows you how to prepare videos for social media with Cloudinary.

Uploading Videos

Your users can upload to your website or application videos from various sources at the same time with Cloudinary’s comprehensive, interactive upload widget. The widget requires just a couple of lines of code to integrate, saving you a tremendous amount of time and effort that are needed to develop a separate tool for video uploads.

Alternatively, you can upload videos with Cloudinary’s upload API.

With the Upload Widget

Upload Widget

To integrate Cloudinary’s upload widget, do the following:

  1. Add the widget script https://upload-widget.cloudinary.com/global/all.js to your HTML file.
  2. Call the createUploadWidget function and pass in an object with the parameters you want in the widget, as follows:
Copy to clipboard
<button id="upload_widget" class="cloudinary-button">Upload files</button>

<script src="https://upload-widget.cloudinary.com/global/all.js" type="text/javascript"></script>  

<script type="text/javascript">  
var myWidget = cloudinary.createUploadWidget({
  cloudName: 'my_cloud_name', 
  uploadPreset: 'my_preset'}, (error, result) => { 
    if (!error && result && result.event === "success") { 
      console.log('Done! Here is the image info: ', result.info); 
    }
  }
)

document.getElementById("upload_widget").addEventListener("click", function(){
    myWidget.open();
  }, false);
</script>

Note
Replace the variable my_cloud_name with the value in your Cloudinary account’s dashboard, and the variable my_preset with the value from the Upload settings of the dashboard.

See the code example below with two more parameters, folder and cropping, which ensure that all file uploads go into a certain folder and that Cloudinary crops them before storing them in the folder.

Copy to clipboard
var myWidget = cloudinary.createUploadWidget({
  cloudName: 'demo', uploadPreset: 'preset1', folder: 'widgetUpload', cropping: true}, 
  (error, result) => { console.log(error, result) })

With the Cloudinary Upload API

Cloudinary’s upload API offers a more effective, flexible, and comprehensive way to upload videos. Do either of the following:

After upload, you can do the following with the Cloudinary Admin API:

  • Organize videos in folders.
  • Transform and modify videos.
  • Delete videos.

Preparing Videos for Social Media

Managing, transforming, and delivering videos subsequent to their upload are workflows in which Cloudinary shines. You can enhance videos in numerous ways before posting them on social media, as described below.

Add Music to Videos

To add a voice track to a video before posting, overlay an audio file with an ID, as in the example below, which shows an overlay with the ID electronic for a video called hourglass_timer.

Ruby:
Copy to clipboard
cl_video_tag("hourglass_timer", :transformation=>[
  {:overlay=>"video:electronic"},
  {:flags=>"layer_apply"}
  ])
PHP v1:
Copy to clipboard
cl_video_tag("hourglass_timer", array("transformation"=>array(
  array("overlay"=>"video:electronic"),
  array("flags"=>"layer_apply")
  )))
PHP v2:
Copy to clipboard
(new VideoTag('hourglass_timer.mp4'))
  ->overlay(Overlay::source(Source::video('electronic')));
Python:
Copy to clipboard
CloudinaryVideo("hourglass_timer").video(transformation=[
  {'overlay': "video:electronic"},
  {'flags': "layer_apply"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("hourglass_timer", {transformation: [
  {overlay: "video:electronic"},
  {flags: "layer_apply"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .overlay(new Layer().publicId("video:electronic")).chain()
  .flags("layer_apply")).videoTag("hourglass_timer");
JS:
Copy to clipboard
cloudinary.videoTag('hourglass_timer', {transformation: [
  {overlay: new cloudinary.Layer().publicId("video:electronic")},
  {flags: "layer_apply"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("hourglass_timer", {transformation: [
  {overlay: new cloudinary.Layer().publicId("video:electronic")},
  {flags: "layer_apply"}
  ]})
React:
Copy to clipboard
<Video publicId="hourglass_timer" >
  <Transformation overlay="video:electronic" />
  <Transformation flags="layer_apply" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="hourglass_timer" >
  <cld-transformation :overlay="video:electronic" />
  <cld-transformation flags="layer_apply" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="hourglass_timer" >
  <cl-transformation overlay="video:electronic">
  </cl-transformation>
  <cl-transformation flags="layer_apply">
  </cl-transformation>
</cl-video>
.NET:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Overlay(new Layer().PublicId("video:electronic")).Chain()
  .Flags("layer_apply")).BuildVideoTag("hourglass_timer")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .overlay(new Layer().publicId("video:electronic")).chain()
  .flags("layer_apply")).resourceType("video").generate("hourglass_timer.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setOverlay("video:electronic").chain()
  .setFlags("layer_apply")).generate("hourglass_timer.mp4")

Boomerang Videos

To create a riveting boomerang effect for a video, add to its URL two parameters, e_boomerang and frame, the latter to specify the color and width. Here’s an example, which adds a gradually moving, yellow border to a video with a boomerang effect:

Ruby:
Copy to clipboard
cl_video_tag("secondflight", :transformation=>[
  {:effect=>"boomerang"},
  {:effect=>"progressbar:frame:yellow:12"}
  ])
PHP v1:
Copy to clipboard
cl_video_tag("secondflight", array("transformation"=>array(
  array("effect"=>"boomerang"),
  array("effect"=>"progressbar:frame:yellow:12")
  )))
PHP v2:
Copy to clipboard
This code example is not currently available.
Python:
Copy to clipboard
CloudinaryVideo("secondflight").video(transformation=[
  {'effect': "boomerang"},
  {'effect': "progressbar:frame:yellow:12"}
  ])
Node.js:
Copy to clipboard
cloudinary.video("secondflight", {transformation: [
  {effect: "boomerang"},
  {effect: "progressbar:frame:yellow:12"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .effect("boomerang").chain()
  .effect("progressbar:frame:yellow:12")).videoTag("secondflight");
JS:
Copy to clipboard
cloudinary.videoTag('secondflight', {transformation: [
  {effect: "boomerang"},
  {effect: "progressbar:frame:yellow:12"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("secondflight", {transformation: [
  {effect: "boomerang"},
  {effect: "progressbar:frame:yellow:12"}
  ]})
React:
Copy to clipboard
<Video publicId="secondflight" >
  <Transformation effect="boomerang" />
  <Transformation effect="progressbar:frame:yellow:12" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="secondflight" >
  <cld-transformation effect="boomerang" />
  <cld-transformation effect="progressbar:frame:yellow:12" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="secondflight" >
  <cl-transformation effect="boomerang">
  </cl-transformation>
  <cl-transformation effect="progressbar:frame:yellow:12">
  </cl-transformation>
</cl-video>
.NET:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Effect("boomerang").Chain()
  .Effect("progressbar:frame:yellow:12")).BuildVideoTag("secondflight")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .effect("boomerang").chain()
  .effect("progressbar:frame:yellow:12")).resourceType("video").generate("secondflight.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setEffect("boomerang").chain()
  .setEffect("progressbar:frame:yellow:12")).generate("secondflight.mp4")

Watermark Videos

You can watermark videos with any image, for example:

Ruby:
Copy to clipboard
cl_video_tag("concatenate", :overlay=>"bottomleaves", :opacity=>50, :effect=>"brightness:200")
PHP v1:
Copy to clipboard
cl_video_tag("concatenate", array("overlay"=>"bottomleaves", "opacity"=>50, "effect"=>"brightness:200"))
PHP v2:
Copy to clipboard
(new VideoTag('concatenate.mp4'))
  ->overlay(
      Overlay::source(Source::image('bottomleaves')
        ->transformation((new ImageTransformation())
          ->adjust(Adjust::opacity(50))
          ->adjust(Adjust::brightness()->level(200))
  )));
Python:
Copy to clipboard
CloudinaryVideo("concatenate").video(overlay="bottomleaves", opacity=50, effect="brightness:200")
Node.js:
Copy to clipboard
cloudinary.video("concatenate", {overlay: "bottomleaves", opacity: 50, effect: "brightness:200"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new Layer().publicId("bottomleaves")).opacity(50).effect("brightness:200")).videoTag("concatenate");
JS:
Copy to clipboard
cloudinary.videoTag('concatenate', {overlay: new cloudinary.Layer().publicId("bottomleaves"), opacity: 50, effect: "brightness:200"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.video("concatenate", {overlay: new cloudinary.Layer().publicId("bottomleaves"), opacity: 50, effect: "brightness:200"})
React:
Copy to clipboard
<Video publicId="concatenate" >
  <Transformation overlay="bottomleaves" opacity="50" effect="brightness:200" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="concatenate" >
  <cld-transformation :overlay="bottomleaves" opacity="50" effect="brightness:200" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="concatenate" >
  <cl-transformation overlay="bottomleaves" opacity="50" effect="brightness:200">
  </cl-transformation>
</cl-video>
.NET:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Overlay(new Layer().PublicId("bottomleaves")).Opacity(50).Effect("brightness:200")).BuildVideoTag("concatenate")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new Layer().publicId("bottomleaves")).opacity(50).effect("brightness:200")).resourceType("video").generate("concatenate.mp4");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setOverlay("bottomleaves").setOpacity(50).setEffect("brightness:200")).generate("concatenate.mp4")

Here, the video is watermarked with the bottom leaves image.

Apply Special Effects to Videos

To apply special effects to a video, add to its URL, for example, the e_noise and e_vignette parameters:

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

Resize and Crop Videos

Resizing and cropping videos is a common practice for meeting certain aspect-ratio, width, and height requirements. You can do that programmatically in many ways on Cloudinary. For example:

To resize a video to half its size while maintaining the aspect ratio:

Copy to clipboard
cloudinary.video("dog", {height: 100, width: 150, crop: "scale"})
Copy to clipboard
(new VideoTag('dog.mp4'))
  ->resize(Resize::scale()->width(150)->height(100));

To resize a video’s height only while maintaining the aspect ratio:

Copy to clipboard
     cloudinary.video("dog", {height: 200, crop: "scale"})
Copy to clipboard
      (new VideoTag('dog.mp4'))
        ->resize(Resize::scale()->height(200));

To resize a video’s width only while maintaining the aspect ratio:

Copy to clipboard
 (new VideoTag('dog.mp4'))
  ->resize(Resize::scale()->width(0.5));
Copy to clipboard
cloudinary.video("dog", {width: "0.5", crop: "scale"})

Crop Videos in a Content-Aware Manner

Cloudinary’s automatic content-aware cropping capability identifies the must-keep sections of videos by analyzing the footage through advanced AI and machine-learning techniques, churning out intelligently downsized videos in any aspect ratio. Consequently, you can deliver videos optimally according to the aspect ratios specified by social-media platforms for multiple devices. Whether people are watching your videos in portrait or landscape mode, you can rest assured that they are all optimized on the viewer’s device.

To intelligently crop videos, set the crop mode to fill and the gravity attribute to auto:

Copy to clipboard
cloudinary.video("ship", {width: 300, gravity: "auto", aspect_ratio: "1:1", crop: "fill"})
Copy to clipboard
(new VideoTag('ship.mp4'))
  ->resize(Resize::fill()->width(300)
    ->aspectRatio(AspectRatio::ar1X1())
    ->gravity(Gravity::autoGravity()));

Blur Videos

Blurring is a transformation technique that produces a nice viewing effect. Here’s an example URL with the parameter e_blur and an overlay with various widths specified:

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

Compress Videos Before Upload

Do consider compressing videos before taking them live. With Cloudinary, doing that is as simple as applying compression during upload. Here are two code examples:

Copy to clipboard
\Cloudinary\Uploader::upload("my_video.mp4", [ "resource_type" => "video", "quality" => "60"]);
Copy to clipboard
cloudinary.uploader.upload("cool_video.mp4", resource_type = "video", "quality" = "60")

Set the quality parameter to any value between 0 and 100 as you desire. Alternatively, set the parameter to auto instead to have Cloudinary automatically adjust the quality.

Transcribe Videos

Cloudinary can generate transcriptions and subtitles for videos with Google’s Cloud Speech API. Subtitles are important for videos that are targeted for viewers worldwide.

To generate transcripts and subtitles with Cloudinary, simply activate the transcription add-on. Afterwards, programmatically request for the generated transcript, like this:

Copy to clipboard
cloudinary.v2.uploader.upload("video.mp4",
   { resource_type: "video", public_id: "social-media", 
    notification_url: "https://requestb.in/abcd123yz", 
    raw_convert: "google_speech" },
    function(error, result) { console.log(result); });

Node.js

You can also specify the format for the subtitle file, e.g., srt, like this:

Copy to clipboard
cloudinary.v2.uploader.upload("video.mp4",
   { resource_type: "video", public_id: "social-media", 
    notification_url: "https://requestb.in/abcd123yz", 
    raw_convert: "google_speech:srt" },
    function(error, result) { console.log(result); });

Once generation is complete, the add-on performs these two steps:

  1. Create a file with a .transcript extension in your Cloudinary account with the same public ID as your video file.
  2. Send the transcript file to the URL as specified under notification_url in the code above.

Moving On

With Cloudinary, you can spiff up your social-media videos in countless ways. Let your imagination fly! I’ll be looking for links to your enhanced videos on social media.

Cloudinary also offers many useful features for managing video assets. Check out this summary of the amazing API capabilities you can integrate.

Recent Blog Posts

How to Apply Riveting Image Effects in Nuxt Applications With Cloudinary

Nowadays, no way can we build modern apps for the web without considering visuals, which are one of the most efficient ways of communicating online. However, improvements in image quality over the years have exacted a price in larger files, slowing down page loads, especially in low-bandwidth regions or on mobile devices. To resolve that conundrum, turn to Cloudinary, a platform that offers the infrastructure for managing images in web apps. Additionally, Cloudinary’s reliable APIs serve visuals through multiple, fast content delivery networks (CDNs).

Read more
The Pros and Cons of AVIF for Websites

AVIF is a 2019 spinoff from the AV1 video format developed by the Alliance for Open Media (AOM), whose members include Amazon, Apple, ARM, Facebook, Google, Huawei, Mozilla, Microsoft, Netflix, and Intel. As an open-source and royalty-free video codec, AVIF delivers much higher compression rates than the older image codecs like JPEG and WebP, and is on par with the brand-new JPEG-XL format, which does not work on any browser yet.

Read more
Get Your Media Moving Faster with Cloudinary’s Media Optimizer

So, your boss comes to you in a panic: he's just heard about Google's Core Web Vitals initiative and needs you to optimize the company website right now! "No problem," you say, hiding your fear that it's not something that can be done overnight. Just taking the first metric, Largest Contentful Paint (LCP), how can you possibly identify all the large elements - most likely images or video posters - of the many hundreds of pages that make up your site? There are already thousands of high-resolution (read massive) media files stored away, which marketing could use any time. How are you going to make sure they're all compressed to a size small enough to be delivered within the threshold? Not to mention all the new images and videos that will be created over time...

Read more
How to Tap Into the Value of User-Generated Content (UGC)

User-generated content (UGC) took off with, first of all, the advent of the internet and, subsequently, social networks. Everyday consumers were given keys to the kingdom, so to speak, so that they, too, could compose and post content, simultaneously engaging with others online. Twitter, Facebook, Instagram, Snapchat, TikTok—the networks through which we can create and publish content have grown exponentially, and brands are becoming aware of the benefits of tapping into the gold mines offered by those networks.

Read more