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
    Facebook Open Graph META Tags

    It's no secret that Facebook has become a major traffic driver for all types of websites.  Nowadays even large corporations steer consumers toward their Facebook pages instead of the corporate websites directly.  And of course there are Facebook "Like" and "Recommend" widgets on every website.  One...

  • By
    Conquering Impostor Syndrome

    Two years ago I documented my struggles with Imposter Syndrome and the response was immense.  I received messages of support and commiseration from new web developers, veteran engineers, and even persons of all experience levels in other professions.  I've even caught myself reading the post...

Incredible Demos

  • By
    Fullscreen API

    As we move toward more true web applications, our JavaScript APIs are doing their best to keep up.  One very simple but useful new JavaScript API is the Fullscreen API.  The Fullscreen API provides a programmatic way to request fullscreen display from the user, and exit...

  • By
    Create a Simple News Scroller Using Dojo

    My journey into Dojo JavaScript has been exciting and I'm continuing to learn more as I port MooTools scripts to Dojo. My latest experiment is porting a simple new scroller from MooTools to Dojo. The code is very similar! The HTML The news items...

Discussion

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