How to Deliver a Smooth Playback without Interruptions (Buffering)

By  on  
Cloudinary

There's only one thing worse than no internet:  unreliable internet.  The frustration I feel when one page loads quickly, then the next very slow (if at all), and then a mixture is unmanageable.  Like...throw your device across the room frustrating.  This slowness is most apparent when trying to play media, more specifically video where it's visually janky and the sound is getting cut off and you're seething with fury.

Last week I wrote about HTML5 Video Best Practices and the awesome utilities provided by Cloudinary to place optimized and configurable videos within your site.  Cloudinary lets you customize the video poster, video controls, and even apply filters and transformations to the video itself.  Taking a deeper look, you can even control the bitrate and codecs levels, allowing for better customization of video delivery.

Uploading a Video

You can upload a video within the Cloudinary website but let's have some fun and use the Cloudinary Node.js API to upload a video:

cloudinary.uploader.upload('sample-video.mp4', function(result) {
  // Callback
  console.log('result: ', result);
}, {
  public_id: 'sample-video',
  resource_type: 'video'
});

Cloudinary provides PHP, Python, and a host of other API libraries.  Once  the video is uploaded, you can call the following method to retrieve the video's optimal HTML string:

cloudinary.video('sample-video');

/*
<video poster='http://res.cloudinary.com/david-wash-blog/video/upload/sample-video.jpg'>
    <source src='http://res.cloudinary.com/david-wash-blog/video/upload/sample-video.webm' type='video/webm'>
    <source src='http://res.cloudinary.com/david-wash-blog/video/upload/sample-video.mp4' type='video/mp4'>
    <source src='http://res.cloudinary.com/david-wash-blog/video/upload/sample-video.ogv' type='video/ogg'>
</video>
*/

Manipulating Video Quality & Bit Rate

Depending on the device, browser, traffic load, length of video, or a range of other variables, you may want to be able to modify the quality or bit rate of a video on your site.  Though quality and bit rate are two separate manipulations, remember that the higher the bit rate, the higher the quality.

Let's first set a desired quality:

cloudinary.video('sample-video', { quality: 50 });

Setting desired bit rate is just as easy:

cloudinary.video('sample-video', { bit_rate: '250k' });

The API is so easy to use, no surprises!

Adaptive Bitrate Streaming - HLS and MPEG

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

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

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

Setting up streaming is a multistep (but easy) process -- let's have a look at how to make that happen!

Step One:  Select a Streaming Profile

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

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

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

Step Two:  Upload Your Video with an Eager Transformation Including the Streaming Profile and Format

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

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

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

cloudinary.uploader.upload("big_buck_bunny.mp4", 
        function(result) {console.log(result); }, 
        { resource_type: "video", 
        eager: [
            { streaming_profile: "full_hd", format: "m3u8" }],                                   
        eager_async: true,
        eager_notification_url: "http://mysite/notify_endpoint",
        public_id: "bb_bunny"});

Step Three:  Video Delivery

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

cloudinary.video("bb_bunny.m3u8", {streaming_profile: "hd"})

Being able to change bit rate and quality on the fly is an awesome capability.  Sure, you could use your own utilities to generate files at various bit rates and qualities but that seems like a waste of time and energy when Cloudinary makes it so easy.  And when you can stream via Cloudinary as well?  What a bonus. When you add the ability to optimize and transform imagery, generate waveform images, remove photo backgrounds, tag images, and automate image updates,  using Cloudinary is an easy decision for multi-purpose media management!

Recent Features

  • By
    Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event...

  • By
    An Interview with Eric Meyer

    Your early CSS books were instrumental in pushing my love for front end technologies. What was it about CSS that you fell in love with and drove you to write about it? At first blush, it was the simplicity of it as compared to the table-and-spacer...

Incredible Demos

  • By
    Upload Photos to Flickr with PHP

    I have a bit of an obsession with uploading photos to different services thanks to Instagram. Instagram's iPhone app allows me to take photos and quickly filter them; once photo tinkering is complete, I can upload the photo to Instagram, Twitter, Facebook, and...

  • By
    Duplicate the jQuery Homepage Tooltips Using MooTools

    The jQuery homepage has a pretty suave tooltip-like effect as seen below: Here's how to accomplish this same effect using MooTools. The XHTML The above XHTML was taken directly from the jQuery homepage -- no changes. The CSS The above CSS has been slightly modified to match the CSS rules already...

Discussion

    Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!