Cloudinary is a host for your digital assets like images and video. If you don’t already know them, you should, because you can build it into the asset management you almost certainly need to do if you run any size of website. Cloudinary helps you serve the assets as efficiently as technologically possible, meaning optimization, resizing, CDN hosting, and goes further in allowing interesting transforms on those assets.
If you already use it, unless you use it entirely through the APIs, you’ll know Cloudinary has a Media Library that gives you a UI dashboard for everything you’ve ever uploaded to Cloudinary. This is where you find your assets and open them up to play with the settings and transformations and such (e.g. blur it — then serve in the best possible format with automatic quality adjustments). You can always pop over to cloudinary.com to use this. But wouldn’t it be nice if this process was made a bit easier?
That clutch moment where you get the URL of the image you need.
There are all sorts of moments while bopping the web around doing our jobs as developers where you might need to get your fingers on an asset URL.
Gimme that URL!
Here’s a personal example: we have a little custom CMS thing for building our weekly email The CodePen Spark. It expects a URL to an image.
This is the exact kind of moment that the brand newChrome Media Library Extension could help. Essentially it gives you a context menu you can use right in the browser to snag a URL to an asset. Right click, Insert and Asset URL.
It pops up a UI right inline (where you are on the web) of your Media Library, and you pick an image from there. Find the one you want, open it up, and you can either “edit” it to customize it to your liking, or just Insert it straight away.
Then it plops the URL right onto the site (probably an input) where you need it.
You can set up defaults to your liking, but I really like how the defaults are f_auto and q_auto which are Cloudinary classics that you’ll almost surely want. They mean “serve in the best possible format” and “optimize it intelligently”.
Say your team creates social posts on a browser tab on an automated marketing application. To locate a media asset, you must open another tab to search for the asset within the Media Library, copy the related URL, and paste it into the app. In some cases, you even have to download an asset and then upload it into the app.
Talk about a classic example of menial, mundane, and repetitive chores!
Exactly. I like the idea of having tools to optimize workflows that should be easy. I’d also call Cloudinary a bit of a technical/developer tool, and there is an aspect to this that could be set up on anyone’s machine that would allow them to pick assets from your Media Library easily, without any access control worries.
Cloudinary (the media hosting and optimization service) has a brand new version (v3) of its WordPress plugin that has really nailed it. First, a high-level look at the biggest things this plugin does:
It takes over your media handling. Images and video are served by Cloudinary instead of your own server, which is good for a whole host of reasons. But don’t worry, your assets are also on your own server, so there is no lock-in.
It serves your images and video as performantly as possible. Everything is optimized, served in the best format, and use techniques like responsive images and lazy loading, all while providing a good loading experience. All together, those things are massive for performance.
It provides and image gallery block with lots of functionality.
Setting it up is as easy as copy and pasting from your Cloudinary account.
So, yes, you need a Cloudinary account. You can check out the programmable media plans here. There is a free tier that will likely work for many sites and paid plans that will cover sites that have heavy media needs, of which you’ll likely find the pricing amicable. Once you have your account, you pop the connection string (from your dashboard) into this quick onboarding wizard and you’re basically done. The default settings are good.
You could do literally nothing else and the plugin will work its magic, but it’s fun to look through all the settings.
Here are the general settings:
Those two (default) settings are important. Auto sync is nice in that all your images (even your entire existing media library) is synced up to Cloudinary and stays in sync. This is necessary to host your images (and do fancy optional stuff like “transforms”) but you could otherwise think of it as a backup. When you use “Cloudinary and WordPress” as the Storage setting, it means that media will be uploaded to your own server and Cloudinary. That’s what I would highly recommend, but if you’re in a situation where, say, you have very limited or no storage on your WordPress host, you could have the images go straight to Cloudinary (only).
In the Image settings, you can see two of Cloudinary’s most powerful weapons: f_auto and q_auto, standing for “auto image formatting” and “auto quality compression.” Those are defaults I’d highly recommend leaving alone. It means that any browser on any device gets the best possible format of the image, and Cloudinary adjusts the quality as appropriate for that image. Cloudinary has very good tech for doing this, so let it do it.
The “doing images right” checklist is a thing.
Remember, we blogged it just recently. Host them on a CDN. Optimze them. Serve them in the best possible format for the requesting browser. Use responsive images. Lazy load them. None of those things are trivial, and that’s just a partial list. The good news is: this plugin does all that stuff for you, does it well, and does it without you having to think too much about it.
I like seeing the output. This is where the rubber meets the road. From this I can see that responsive images are implemented correctly and lots of different sizes are available. I can see the the image sources are pointing at the Cloudinary CDN. I can see lazy loading is implemented and working. I can see the width and height attributes are there as they should be to ensure space is reserved for the images during loading. This is everything.
It goes the extra mile by hosting the images the used by the theme as well.
Heck, it replaces CSS background-images in your theme’s stylesheet with Cloudinary-hosted versions. That’s… amazing. There must be some real clever WordPress filter stuff going on.
The Gallery Block is just gravy.
I like seeing this in there:
Why? It shows that this plugin is part of modern WordPress. Block editor WordPress. The block itself is simple, but useful. It shows images in a variety of useful layouts with a “lightbox”-like effect (wow, it’s been a long time since I’ve typed the word lightbox). Hey, sometimes you just need a dang image gallery and you might as well use one that is well done.
Who am I to say?
Just a lowly blogger, I suppose. But I can tell you I’ve been watching this evolve for quite a while. A ways back, I had implemented a hand-rolled Cloudinary integration here on CSS-Tricks because I wanted all this stuff. I ultimately had to give up on it as it was more technical debt than I could maintain.
The previous versions of the WordPress plugin were better, but it’s not until now, v3, where this integration is truly nailed.
Shortly after that time I tore down my custom integration, I blogged “Workflow Considerations for Using an Image Management Service” and outlined what I thought the (rather high) bar would be for integrating a third-party image host. It was a lot to ask, and I wasn’t really sure if anyone would find the incentive and motivation to do it all. Well, Cloudinary has done it here. This is as perfect a media management plugin as I could imagine.
Creating video is time consuming. A well-made 5-minute video can take hours to plan, record, and edit — and that’s before we start talking about making that video consistent with all the other videos on your site.
When we took on the Jamstack Explorers project (a video-driven educational resource for web developers), we wanted to find the right balance of quality and shipping: what could we automate in our video production process to reduce the time and number of steps required to create video content without sacrificing quality?
With the help of Cloudinary, we were able to deliver a consistent branding approach in all our video content without adding a bunch of extra editing tasks for folks creating videos. And, as a bonus, if we update our branding in the future, we can update all the video branding across the whole site at once — no video editing required!
What does “video branding” mean?
To make every video on the Explorers site feel like it all fits together, we include a few common pieces in each video:
A title scene
A short intro bumper (video clip) that shows the Jamstack Explorers branding
A short outro bumper that either counts down to the next video or shows a “mission accomplished” if this is the last video in the mission
Skip to the end: here’s how a branded video looks
To show the impact of adding the branding, here’s one of the videos from Jamstack Explorers without any branding:
This video (and this Vue mission from Ben Hong) is legitimately outstanding! However, it starts and ends a little abruptly, and we don’t have a sense of where this video lives.
We worked with Adam Hald to create branded video assets that help give each video a sense of place. Check out the same video with all the Explorers branding applied:
We get the same great content, but now we’ve added a little extra va-va-voom that makes this feel like it’s part of a larger story.
In this article, we’ll walk through how we automatically customize every video using Cloudinary.
How does Cloudinary make this possible?
Cloudinary is a cloud-based asset delivery network that gives us a powerful, URL-based API to manipulate and transform media. It supports all sorts of asset types, but where it really shines is with images and video.
To use Cloudinary, you create a free account, then upload your asset. This asset then becomes available at a Cloudinary URL:
https://res.cloudinary.com/netlify/image/upload/v1605632851/explorers/avatar.jpg ^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ | | | V V V cloud (account) name version (optional) file name
This URL points to the original image and can be used in <img /> tags and other markup.
The original image size is 97.6kB.
Dynamically adjust file format and quality to reduce file sizes
If we’re using this image on a website and want to improve our site performance, we may decide to reduce the size of this image by using next-generation formats like WebP, AVIF, and so on. These new formats are much smaller, but aren’t supported by all browsers, which would usually mean using a tool to generate multiple versions of this image in different formats, then using a <picture> element or other specialized markup to provide modern options with the JPG fallback for older browsers.
With Cloudinary, all we have to do is add a transformation to the URL:
https://res.cloudinary.com/netlify/image/upload/q_auto,f_auto/v1605632851/explorers/avatar.jpg ^^^^^^^^^^^^ | V automatic quality & format transformations
What we see in the browser is visually identical:
The transformed image is 15.4kB.
By setting the file format and quality settings to automatic (f_auto,q_auto), Cloudinary is able to detect which formats are supported by the client and serves the most efficient format at a reasonable quality level. In Chrome, for example, this image transforms from a 97.6kB JPG to a 15.4kB WebP, and all we had to do was add a couple of things to the URL!
We can transform our images in lots of different ways!
We can go further with other transformations, including resizing (w_150 for “resize to 150px wide”) and color effects (e_grayscale for “apply the grayscale effect”):
There’s a Node SDK to make this a little more human-readable
For more advanced transformations like what we’re going to get into, writing the URLs by hand can get a little hard to read. We ended up using the Cloudinary Node SDK to give us the ability to add comments and explain what each transformation was doing, and that’s been extremely helpful as we maintain and evolve the platform.
To install it, get your Cloudinary API key and secret from your console, then install the SDK using npm:
# create a new directory mkdir cloudinary-video # move into the new directory cd cloudinary-video/ # initialize a new Node project npm init -y # install the Cloudinary Node SDK npm install cloudinary
Next, create a new file called index.js and initialize the SDK with your cloud_name and API credentials:
const cloudinary = require('cloudinary').v2; // TODO replace these values with your own Cloudinary credentials cloudinary.config({ cloud_name: 'your_cloud_name', api_key: 'your_api_key', api_secret: 'your_api_secret', });
Don’t commit your API credentials to GitHub or share them anywhere. Use environment variables to keep them safe! If you’re unfamiliar with environment variables, Colby Fayock has written a great introduction to using environment variables.
Next, we can create the same transformation as before using slightly more human-readable configuration settings:
cloudinary.uploader // the first argument should be the public ID (including folders!) of the // image we want to transform .explicit('explorers/avatar', { // these two properties match the beginning of the URL: // https://res.cloudinary.com/netlify/image/upload/... // ^^^^^^^^^^^^ resource_type: 'image', type: 'upload', // "eager" means we want to run these transformations ahead of time to avoid // a slow first load time eager: [ { fetch_format: 'auto', quality: 'auto', width: 150, effect: 'grayscale', }, ], // allow this transformed image to be cached to avoid re-running the same // transformations over and over again overwrite: false, }) .then((result) => { console.log(result); });
Let’s run this code by typing node index.js in our terminal. The output will look something like this:
Under the eager property, our transformations are shown along with the full URL to view the transformed image.
While the Node SDK is probably overkill for a straightforward transformation like this one, it becomes really handy when we start looking at the complex transformations required to add video branding.
Transforming videos with Cloudinary
To transform our videos in Jamstack Explorers, we follow the same approach: each video is uploaded to Cloudinary, and then we modify the URLs to resize, adjust quality, and insert the title card and bumpers.
There are a few major categories of transformation that we’ll be tackling to add the branding:
Overlays
Transitions
Text overlays
Splicing
Let’s look at each of these categories and see if we can’t reimplement the Jamstack Explorers branding on Ben’s video! Let’s get set up by setting up index.js to transform our base video:
cloudinary.uploader .explicit('explorers/bumper', { // these two properties match the beginning of the URL: // https://res.cloudinary.com/netlify/image/upload/... // ^^^^^^^^^^^^ resource_type: 'video', type: 'upload', // "eager" means we want to run these transformations ahead of time to avoid // a slow first load time eager: [ { fetch_format: 'auto', quality: 'auto', height: 360, width: 640, crop: 'fill', // avoid letterboxing if videos are different sizes }, ], // allow this transformed image to be cached to avoid re-running the same // transformations over and over again overwrite: false, }) .then((result) => { console.log(result); });
You may have noticed that we’re using a video called “bumper” instead of Ben’s original video. This is due to the way Cloudinary orders videos as we add them together. We’ll add Ben’s video in the next section!
Combine two videos with a custom transition using Cloudinary
To add our bumpers, we need to add a second transformation “layer” to the eager array that adds a second video as an overlay.
To do this, we use the overlay transformation and set it to video:publicID, where publicID is the Cloudinary public ID of the asset with any slashes (/) transformed to colons (:).
We also need to tell Cloudinary how to transition between the two videos, which we do using a special kind of video called a luma matte that lets us mask one video with the black area of the video, and a second video with the white area. This results in a stylized cross-fade.
Here’s what the luma matte looks like on its own:
The video and the transition both have their own transformations, which means that we need to treat them as different “layers” in the Cloudinary transform. This means splitting them into separate objects, then adding additional objects to “apply” each layer, which allows us to call that section done and continue adding more transformations to the main video.
To tell Cloudinary this this is a luma matte and not another video, we set the effect type to transition.
Make the following changes in index.js to put all of this in place:
const videoBaseTransformations = { fetch_format: 'auto', quality: 'auto', height: 360, width: 600, crop: 'fill', } cloudinary.uploader .explicit('explorers/bumper', { // these two properties match the beginning of the URL: // <https://res.cloudinary.com/netlify/image/upload/>... // resource_type: 'video', type: 'upload', // "eager" means we want to run these transformations ahead of time to avoid // a slow first load time eager: [ videoBaseTransformations, { overlay: 'video:explorers:LCA-07-lifecycle-hooks', ...videoBaseTransformations, }, { overlay: 'video:explorers:transition', effect: 'transition', }, { flags: 'layer_apply' }, // <= apply the transformation { flags: 'layer_apply' }, // <= apply the actual video ], // allow this transformed image to be cached to avoid re-running the same // transformations over and over again overwrite: false, }) .then((result) => { console.log(result); });
We need the same format, quality, and sizing transformations on all videos, so we pulled those out into a variable called videoBaseTransformations, then added a second object to contain the overlay.
If we run this with node index.js, the video we get back looks like this:
Not bad! This already looks like it’s part of the Jamstack Explorers site, and that transition adds a nice flow from the common bumper into the custom video.
Adding the outro bumper works exactly the same: we need to add another overlay for the ending bumper and a transition. We won’t show this code in the tutorial, but you can see it in the source code if you’re interested.
Add a title card to a video using text overlays
To add a title card, there are two distinct steps:
Extract a short video clip to serve as the title card background
Add a text overlay with the video’s title
The next two sections walk through each step individually so we can see the distinction between the two.
Extract a short video clip to use as the title card background
When Adam Hald created the Explorers video assets, he included a beautiful intro video that opens on a starry sky that’s perfect for a title card. Using Cloudinary, we can grab a few seconds of that starry sky and splice it into every video as a title card!
In index.js, add the following transformation blocks:
cloudinary.uploader .explicit('explorers/bumper', { // these two properties match the beginning of the URL: // https://res.cloudinary.com/netlify/image/upload/... // resource_type: 'video', type: 'upload', // "eager" means we want to run these transformations ahead of time to avoid // a slow first load time eager: [ videoBaseTransformations, { overlay: 'video:explorers:LCA-07-lifecycle-hooks', ...videoBaseTransformations, }, { overlay: 'video:explorers:transition', effect: 'transition', }, { flags: 'layer_apply' }, // <= apply the transformation { flags: 'layer_apply' }, // <= apply the actual video // add the outro bumper and a transition { overlay: 'video:explorers:countdown', ...videoBaseTransformations, }, { overlay: 'video:explorers:transition', effect: 'transition', }, { flags: 'layer_apply' }, { flags: 'layer_apply' }, // splice a title card at the beginning of the video { overlay: 'video:explorers:intro', flags: 'splice', // splice this into the video ...videoBaseTransformations, }, { audio_codec: 'none', // remove the audio end_offset: 3, // shorten to 3 seconds effect: 'accelerate:-25', // slow down 25% (to ~4 seconds) }, { flags: 'layer_apply', start_offset: 0, // put this at the beginning of the video }, ], // allow this transformed image to be cached to avoid re-running the same // transformations over and over again overwrite: false, }) .then((result) => { console.log(result); });
Using the splice flag, we tell Cloudinary to add this video directly without a transition.
In the next set of transformations, we add three transformations we haven’t seen before:
We set audio_codec to none to remove sound from this segment of video.
We set end_offset to 3, which means we’ll get only the first 3 seconds of the video.
We add the accelerate effect with a value of -25, which slows the video down by 25%.
Running node index.js will now give us a video that starts with just under 4 seconds of silent, starry skies:
Add text overlays to videos using Cloudinary
Our last step is to add a text overlay to show the video title!
Text overlays use the same overlay property as other overlays, but we pass an object with settings for the font. Cloudinary supports a wide variety of fonts — I haven’t been able to find a definitive list, but it seems to be a large number of Google Fonts — and if you’ve purchased a license to use a custom font, you can upload a custom font to Cloudinary for use in text overlays as well.
cloudinary.uploader .explicit('explorers/bumper', { // these two properties match the beginning of the URL: // <https://res.cloudinary.com/netlify/image/upload/>... // resource_type: 'video', type: 'upload', // "eager" means we want to run these transformations ahead of time to avoid // a slow first load time eager: [ videoBaseTransformations, { overlay: 'video:explorers:LCA-07-lifecycle-hooks', ...videoBaseTransformations, }, { overlay: 'video:explorers:transition', effect: 'transition', }, { flags: 'layer_apply' }, // <= apply the transformation { flags: 'layer_apply' }, // <= apply the actual video // add the outro bumper and a transition { overlay: 'video:explorers:countdown', ...videoBaseTransformations, }, { overlay: 'video:explorers:transition', effect: 'transition', }, { flags: 'layer_apply' }, { flags: 'layer_apply' }, // splice a title card at the beginning of the video { overlay: 'video:explorers:intro', flags: 'splice', // splice this into the video ...videoBaseTransformations, }, { audio_codec: 'none', // remove the audio end_offset: 3, // shorten to 3 seconds effect: 'accelerate:-25', // slow down 25% (to ~4 seconds) }, { overlay: { font_family: 'roboto', // lots of Google Fonts are supported font_size: 40, text_align: 'center', text: 'Lifecycle Hooks', // this can be any text you want }, width: 500, crop: 'fit', color: 'white', }, { flags: 'layer_apply' }, { flags: 'layer_apply', start_offset: 0, // put this at the beginning of the video }, ], // allow this transformed image to be cached to avoid re-running the same // transformations over and over again overwrite: false, }) .then((result) => { console.log(result); });
In addition to setting the font size and alignment, we also apply a width of 500px (which will be centered by default) to keep our title text from smashing into the side of the title card, and set the crop value to fit, which will wrap longer titles. Setting the color to white makes our text visible against the dark, starry background.
Run node index.js to generate the URL and we’ll see our fully branded video, including a title card and bumpers!
Build your video branding once; use it everywhere
Creating bumpers, transitions, and title cards is a lot of work. Creating high-quality video content is also a lot of work. If we had to manually edit every Jamstack Explorers video to insert these title cards and bumpers, it’s extremely unlikely that we would have actually done it.
We knew that the only realistic way for us to keep the videos consistently branded was to reduce the friction of adding the branding, and Cloudinary let us automate it entirely. This means that we can stay consistent without any manual steps!
As an added bonus, it also means that if we update our title cards or bumpers in the future, we can update all the branding for all the videos by changing the code in one place. This is a huge relief for us, because we know that Explorers is going to continue to grow and evolve over time.
What to do next
Now that you know how to use Cloudinary to add custom branding, here are some additional resources to help you keep learning.
What else can you automate using Cloudinary? How much time could you save by automating the repetitive parts of your video editing workflow? I am exactly the kind of nerd who loves to talk about this stuff, so send me your ideas on Twitter!
This is about a wildly specific combination of technologies — Eleventy, the static site generator, with pages with images on them that you ultimately want hosted by Cloudinary — but I just wanna document it as it sounds like a decent amount of people run into this situation.
The deal:
Cloudinary has a fetch URL feature, meaning you don’t actually have to learn anything (nice!) to use their service. You have to have an account, but after that you just prefix your images with a Cloudinary URL and then it is Cloudinary that optimizes, resizes, formats, and CDN serves your image. Sweet. It’s not the only service that does this, but it’s a good one.
But… the image needs to be on the live public internet. In development, your image URLs probably are not. They’re likely stored locally. So ideally we could keep using local URLs for images in development, and do the Cloudinary fetching on production.
Multiple people have solved this in different ways. I’m going to document how I did it (because I understand it best), but also link up how several other people have done it (which might be smarter, you be the judge).
The goal:
In development, images be like /images/image.png
In production, images be like https://res.cloudinary.com/css-tricks/image/fetch/w_1200,q_auto,f_auto/https://production-website.com/images/image.png
So if we were to template that (let’s assume Nunjucks here as it’s a nice templating language that Eleventy supports), we get something like this psuedo-code:
<img src=" {{CLOUDINARY_PREFIX}}{{FULLY_QUALIFIED_PRODUCTION_URL}}{{RELATIVE_IMAGE_URL}} " alt="Don't screw this up, fam." />
The trick then is getting those… I guess we’ll call them global variables?… set up. It’s probably just those first two. The relative image path you’d likely just write by hand as needed.
Eleventy has some magic available for this. Any *.js file we put in a _data folder will turn into variables we can use in templates. So if we made like /src/_data/sandwiches.js and it was:
module.exports = { ham: true }
In our template, we could use {{sandwiches.ham}} and that would be defined {{true}}.
Because this is JavaScript (Node), that means we have the ability to do some logic based on other variables. In our case, some other global variables will be useful, particularly the process.env variables that Node makes available. A lot of hosts (Netlify, Vercel, etc.) make “environment variables” a thing you can set up in their system, so that process.env has them available when build processes run on their system. We could do that, but that’s rather specific and tied to those hosts. Another way to set a Node global variable is to literally set it on the command line before you run a command, so if you were to do:
SANDWICH="ham" eleventy
Then process.env.SANDWICH would be ham anywhere in your Node JavaScript. Combining all that… let’s say that our production build process sets a variable indicating production, like:
PROD="true" eleventy
But on local development, we’ll run without that global variable. So let’s make use of that information while setting up some global variables to use to construct our image sources. In /src/_data/images.js (full real-world example) we’ll do:
You could also check process.env.CONTEXT === 'deploy-preview' to test for Netlify deploy preview URLs, in case you want to change the logic there one way or the other.
Now in any of our templates, we can use {{images.imageLocation}} and {{images.urlPrefix}} to build out the sources.
<img src=" {{images.urlPrefixLarge}}{{images.imageLocation}}/image.png " alt="Useful alternative text." />
And there we go. That will be a local/relative source on development, and then on production, it becomes this prefixed and full qualified URL from which Cloudinary’s fetch will work.
Now that it’s on Cloudinary, we can take it a step further. The prefix URL can be adjusted to resize images, meaning that even with just one source image, we can pull off a rather appropriate setup for responsive images. Here’s that setup, which makes multiple prefixes available, so they can be used for the full syntax.
The end result means locally relative image in development:
The multiple versions are a lie in development, but oh well, srcset is kind of a production concern.
…and Cloudinary fetch URLs in production:
Other People’s Ideas
Phil was showing off using Netlify redirects to do this the other day:
A nice trick to optimize your site's images without a build process or any library or framework cruft.
1. Upload & serve from @cloudinary in one step thanks to their Fetched URL API 2. Make it portable and simple with a @netlify CDN proxy
Then the trick to local development is catching the 404’s and redirecting them locally with more redirects.
If hand-crafting your own responsive images syntax is too big of a pain (it is), I highly recommend abstracting it. In Eleventy-land, Nicolas Hoizey has a project: eleventy-plugin-images-responsiver. Eric Portis has one as well, eleventy-respimg, which specifically uses Cloudinary as I have here.
Proving this stuff has really been on people’s minds, Tim Kadlec just blogged “Proxying Cloudinary Requests with Netlify.” He expands on Phil’s tweet, adding some extra performance context and gotchas.
I knew that Cloudinary worked with video as well as images but, the other day, I was curious if Cloudinary offered a video player embed just like other video hosts do (e.g. YouTube, Vimeo, etc). Like an <iframe> that comes with a special player.
I was curious because, as much as I appreciate the simplicity of just tossing a <video> on a page, there is one little hurdle that I always forget: you have to use a poster attribute if you want anything but a blank white rectangle on mobile browsers. Having to cut a special poster for every video I use is a step I’m frankly just too lazy to do most of the time.
Turns out Cloudinary does a have a player, and it allows for a bunch of nice customization, including handling the poster for you: Video Player Studio.
If I use this player instead, not only do I get a free configurable poster, but other advantages you’d expect from Cloudinary, like serving the video in the best possible format and optimizing the size.
But there is another thing that is a kind of big deal here, particularly for long videos: “adaptive bitrate streaming.” Behind the scenes, some library probably needs to be downloaded, but the bandwidth savings likely pay for that almost instantly. I’m not an expert on any of this by any means, but I’m referring to HLS and MPEG-DASH, which seem to be the big players, and this Cloudinary player offers both.
For the record, this post is not sponsored by Cloudinary. I was just thinking about all this the other day because we frequently embed video here on CSS-Tricks and I already use Cloudinary for all sorts of stuff.
Here’s an example:
In running this past the Cloudinary team, they said two things:
The player is built on top of VideoJS. Credit where credit is due.
They’ve got a blog post that goes far deeper into customizing the player than I talk about here.