Video Streaming with Adaptive Bitrate with Scott Wachtmann & Jen Brissman
Processing Video Files for HLS
Here, we see what happens when we upload a video (with eager transformation), and how to set up a notification (using webhooks) when the processing has completed. We will also walk you through how to use this repo and set up your own credentials.
Link to Github repository: https://github.com/cloudinary-training/jamstack-explorer-video-abr
We are now ready to upload the video that we want to run with adaptive streaming. We are going to be using an eager transformation during this upload. Eager transformations allow you to maintain your original asset, and add on derivative files that implement the necessary transformations. The transformations implemented are needed for both HLS streaming and the adaptive bitrate.
Before you run any of your backend code, you need to make sure you've set up your environment variable with your credentials. To do this, you will need to create a free Cloudinary account, which offers up lots of bandwidth storage and the ability to create transformations. Once you've created your account and logged in, you will be brought to the Cloudinary dashboard. Here you'll see your cloud name, API key, API secret, and API environment variable. Locate your API environment variable, which is for the most part hidden because it contains a secret, and click on the clipboard to load it into your buffer. Now you're ready to go to your code. In the code, you will see a file called .env.sample.
In this file, you can see the format of the full Cloudinary URL. You can paste in yours, which should look just like this, and save it as a .env file. With these credentials in place, we are ready to run a script.
Let's take a look inside the file, upload.js, which you can find under scripts. First, we're using .env to load our credentials.
Then we load the Cloudinary node SDK. Here, you can see the options that we will be using for this upload. We are going to assign our video a unique public ID in Cloudinary. We will call this video: "mountain". Let's give it a resource type: "video", a type: "upload", which means it will be public. And then as we talked about, the eager transformation.
We will supply an array of two transformations. One of them will use the streaming profile that we looked at earlier called fullHD, with the format of m3u8. Recall that m3u8 is the HLS format. Then we will create a transformation of the MP4 file with quality auto. Quality auto sets up a compromise between best quality and lowest bandwidth. We create this MP4 as a fallback for the fullHD.
In other words, if we were to run this on a mobile device that didn't support HLS, but did run MP4, we would have that device covered. We're going to set eager async to true, which means we want this to run asynchronously --because the backend processing can take a while. We are also using an eager notification URL. This is because we are running async. We want to have some way to determine that the process has finished. We can do this using this URL. I've set up a webhook site. This is free to do. Let's take a look at where that's located. Cloudinary can send the response when the upload is complete to this webhook site.
If we go to webhook.site, we will be given a URL, and we can copy that into our buffer and paste it in the code. With that in place, we are now ready to use the Cloudinary upload API and request the upload of our video. We are asking for a video that is currently on Cloudinary training. We have the ability to request remote videos from another website like we're doing here, or from an S3 bucket, or even a local video.
And with that, we are passing in the options. The upload is going to return a promise. And if it is successful, we will log the results, or in the case that it is not successful, we will log the error. Let's run this. Again, since we have our credentials in place, we can run this from the root. Let's take a look at the response.
We get information back about the asset that we uploaded. We can see that the public ID was set as we requested and that it is set up to run processing eagerly. That processing is taking place right now. The next thing would be to go to the webhook site, and wait for this to complete. Let's take a look at the results.
We can see here that it created our m3u8 representations using the fullHD profile, and we also received our MP4 with q auto. Another way that we can see that the derivative files were created, is to go to the Cloudinary digital asset manager. In here, go to Media Library, and look at "mountain". Click on "edit", and then click "view derived videos". If we scroll down, we'll see that we created different files during the upload.
And we can see that it created all the resolutions for our m3u8 from our fullHD profile, and all of the .ts files needed to do this. We also have our MP4 with q auto. All right. We've got our two transformation sets back from the upload. At this point, we're ready to move to the front end, set up a video player, and start streaming.