In our previous blog post, Simple Simulcast Live Streaming With Cloudinary and OBS, we went over how to create a live video stream using Cloudinary Video Live Streaming API and OBS. Cloudinary’s Live Streaming provides an easy way to start and simulcast a live stream to popular platforms like YouTube and Twitch. Along with simulcasting, you can also publish your live stream anywhere you’d like on the web.
In this blog post, we’ll cover how to deliver a live stream on your own website using the Cloudinary Video Player.
Currently, the only way to manage your live streams is by using the Cloudinary API. Cloudinary provides excellent API documentation, which makes the process pretty straightforward. For a detailed guide on how to work with this API, be sure to check out our previous blog post.
There are a few things we need to do before we’re ready to start streaming video content. If you haven’t already, sign up for a Cloudinary account to get the following:
- Your Cloudinary cloud name. This is a unique identifier for your Cloudinary account. This can be found at the top-left corner of your Cloudinary console.
- Your API key. The public key is used to authenticate your requests to the Cloudinary API.
- Your API secret. The private key is used for secure connections with the Cloudinary API.
You can find your private and public API keys in the API Keys section on the settings page of your Cloudinary console.
First, let’s create our stream. Copy the curl command from the POST /live_streams
endpoint and run it in your terminal, use your cloud name, API key, and secret. With the default options, this will create a new RTMP live stream called “My first stream”.
In the response, what we care about the most (at least for now) are the input.uri
and the stream_key
{
"request_id": "2c41da07b90183b48c4f93b5a83ded20",
"data": {
"id": "[REDACTED]",
"name": "My first stream",
"input": {
"type": "rtmp",
"uri": "rtmp://live.cloudinary.com/streams",
"stream_key": "[REDACTED]"
},
"status": "idle",
"outputs": [
{
"id": "[REDACTED]",
"name": "default hls",
"type": "hls",
"uri": "https://res.cloudinary.com/{cloudName}/video/live/live_stream_{stream_id}_hls.m3u8",
"created_at": 1730130837173,
"updated_at": 1730130837173
},
],
}
}
Code language: JSON / JSON with Comments (json)
We’ll use OBS to start our stream, but remember that you can use any other RTMP client if you prefer.
In OBS, open the Settings and go to the Stream tab. Under Service, choose Custom. You’ll see two fields: “Server” and “Stream Key.” Enter your URI
value in the “Server” field, and your stream_key
in the “Stream Key” field.
After you do this, your OBS settings should look something like this:
You can now click Start Streaming in your OBS Controls, and you’ll broadcast live via Cloudinary Streaming.
In this demo, we’ll create a website to host our live stream with Nuxt, a Vue.js framework that comes with many features, like server-side rendering, which will come in handy. Cloudinary has an SDK for Nuxt. Helpful for integrating Cloudinary into our Nuxt app easily. If you prefer another framework, you can use one of the many other SDKs.
npx nuxi@latest init <my-app>
Code language: HTML, XML (xml)
Replace <my-app>
with the actual name of your app. After running the command, you’ll see a couple of prompts that will set the app’s details for you. The choice is up to you. In my case, I went for pnpm as my package manager and didn’t initialize my git repo.
Afterward, let’s go into our app:
cd <my-app>
Code language: HTML, XML (xml)
To integrate our videos smoothly, we’ll use the Nuxt Cloudinary module. To install it, let’s run the following command:
npx nuxi@latest module add @nuxtjs/cloudinary
Code language: JavaScript (javascript)
Now we can initiate our project with this command:
npx nuxi@latest init
Code language: CSS (css)
We’ll need to set up an environment variable to help us securely store key information for our app to communicate with Cloudinary:
-
NUXT_PUBLIC_CLOUDINARY_CLOUD_NAME
. This is your Cloudinary cloud name. -
NUXT_CLOUDINARY_API_SECRET
. The private key used for secure connections with the Cloudinary API. -
NUXT_PUBLIC_CLOUDINARY_API_KEY
. The public key used to authenticate your requests to the Cloudinary API.
Adding our Cloudinary Video Player is an easy process with Nuxt. After installing @nuxtjs/cloudinary
, we need to import the video player component:
<my-app>
↳app.vue
<script setup>
const streamUrl = null;
</script>
<template>
<section>
<div class="video-container">
<template v-if="streamUrl">
<CldVideoPlayer
width="1920"
height="1080"
:src="streamUrl"
/>
</template>
<template v-else>
<div class="offline-banner">Offline</div>
</template>
</div>
</section>
</template>
<style scoped>
.video-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50vw;
}
.offline-banner {
font-size: 2rem;
color: red;
text-align: center;
}
</style>
Code language: HTML, XML (xml)
Nuxt makes it simple to fetch our live stream on the server side. Doing this on the client side could risk exposing our Cloudinary API secret. To keep things secure, we’ll set up a server handler to retrieve the stream.
<my-app>
↳server
↳api
↳get-stream.ts
export default defineEventHandler(async (event) => {
const streamsRes = await $fetch(`https://api.cloudinary.com/v2/video/${process.env.CLOUDINARY_CLOUD_NAME}/live_streams`, {
method: 'GET',
headers: {
'Authorization': `Basic ${Buffer.from(`${process.env.CLOUDINARY_API_KEY}:${process.env.CLOUDINARY_API_SECRET}`).toString('base64')}`
}
});
// Find the first active stream
const activeStream = streamsRes.data.find((stream: any) => stream.status === 'active');
return {
status: 200,
streamUrl: activeStream?.outputs?.[0].uri || null
}
})
Code language: JavaScript (javascript)
For our example, we’ll fetch only the first active stream. However, you can adjust the criteria to filter for any stream you prefer. For example, you can update your stream and then fetch for the desired output name.
After defining our server handler, we’ll fetch the stream on the client side like this:
<script setup>
const { data } = await useFetch('/api/get-stream');
const streamUrl = data.value?.streamUrl;
</script>
<template>
<section>
<div class="video-container">
<template v-if="streamUrl">
<CldVideoPlayer
width="1920"
height="1080"
:src="streamUrl"
/>
</template>
<template v-else>
<div class="offline-banner">Offline</div>
</template>
</div>
</section>
</template>
<style scoped>
.video-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50vw;
}
.offline-banner {
font-size: 2rem;
color: red;
text-align: center;
}
</style>
Code language: HTML, XML (xml)
If we turn on our stream and refresh our page, we’ll see it in action!
Now you know how to set up and display a Cloudinary livestream on your own site. We kicked things off by creating a stream with Cloudinary’s Video Live Streaming API and OBS. Next, we created a Nuxt app using the Cloudinary Video Player. By adding a server handler, we kept our API secret safe and only fetched the stream link on the server side.
The integration was easy thanks to the Cloudinary Video Player, which handles all the complicated parts, like making sure your stream adapts to different devices and adjusting video quality based on the viewer’s internet speed. Setting up and delivering your stream with it is really straightforward.
Contact us today to learn more about how Cloudinary Video can help you manage, edit, and optimize the delivery of videos with AI-powered and API-based automation.