DEV Community

Cover image for Building a Serverless Live-streaming Platform with React & AWS
Nader Dabit for AWS

Posted on • Edited on

Building a Serverless Live-streaming Platform with React & AWS

Cover image by Caspar Camille Rubin

Live streaming is becoming more and more popular. Platforms like Twitch and YouTube allow you to stream using tools like OBS directly to your audience in real-time from your desktop or laptop.

What if you wanted to build your own custom streaming platform embedded directly into your own website or app? In this post, I'll show you how to do this in just a few steps using Amplify Video.

The main tutorial will cover how to do this with a React Front end, but I'll also show how to do this with React Native.

Unlike most other Amplify services, the video services used in this tutorial do not fall under the free tier. Be sure to stop your video stream and delete the project when you are done if you are not using this in production. See pricing for these services here

To view the completed project, click here

This tutorial shows you how to build the streaming platform itself. If you're interested in embedding your existing Twitch, YouTube, or Mixer stream in your website, check out the react-stream package from Ryan Harris

Overview

This post shows you how to use the Amplify CLI, AWS Elemental, and Amplify Video (an Amplify CLI plugin by Sam Patzer) to deploy a video streaming service embeddable into any website or app.

We'll then look at how to embed the video player into a React app and test it out.

Under the hood, Amplify Video uses AWS Media Services like Elemental MediaLive and Elemental MediaStore, but because the CLI does all of the heavy lifting you will only have to work locally from your CLI to set everything up.

Elemental MediaLive is a fully managed and Serverless service that allows you to encode live video for broadcast and streaming to any device. It lets you create high-quality video streams for delivery to broadcast televisions and internet-connected multiscreen devices, like connected TVs, tablets, smart phones, and set-top boxes. The service works by encoding your live video streams in real-time, taking a larger-sized live video source and compressing it into smaller versions for distribution to your viewers.

This tutorial should take a total of about 15 minutes from start to finish.

To follow along and test out the completed app in this tutorial, you will need have OBS installed

Getting started

The first think you should do is install the latest version of the Amplify CLI and configure it with a user if you have not already done so:

$ npm i -g @aws-amplify/cli

$ amplify configure

For a video walkthrough of how to configure the Amplify CLI, click here

Next, install the Amplify Video CLI plugin:

$ npm i -g amplify-category-video

Now that the Amplify dependencies are set up on your computer, create a new React project and install Video.js:

$ npx create-react-app my-streaming-app

$ cd my-streaming app

$ npm install video.js

Creating the Amplify project

From within the root of the project, initialize a new Amplify app:

$ amplify init

# Choose the project name, environment name, your preferred text editor, and the defaults for the rest of the options.

# When prompted for your AWS Profile, choose the profile you created when you configured the Amplify CLI

Add a video resource

Now that the Amplify project has been configured, we can add a video resource!

To do so, we will run the Amplify add command:

$ amplify add video

# Follow the prompts. Note that the default values will be sufficient for this tutorial.

To deploy the service, run the Amplify push command:

$ amplify push

When deployed, the streaming service will automatically be started. To turn it off, either run amplify video stop choosing Yes to all prompts, or run amplify delete to delete the project. Be sure not to leave the stream running when you are not using it as you will be billed for the usage.

Adding the video player to the React application

Next, open src/App.js and add the following:

import React from 'react'
import videojs from 'video.js'
import awsvideoconfig from './aws-video-exports'
import './App.css'
import 'video.js/dist/video-js.css'

class VideoPlayer extends React.Component {
  componentDidMount() {
    this.player = videojs(this.videoNode, this.props)
  }

  componentWillUnmount() {
    if (this.player) {
      this.player.dispose()
    }
  }

  render() {
    return (
      <>
        <div data-vjs-player style={{
            width: 960, height: 540
          }}>
          <video  ref={(node) => { this.videoNode = node; }} className="video-js" />
        </div>
      </>
    );
  }
}

const videoJsOptions = {
  autoplay: true,
  controls: true,
  sources: [{
    src: awsvideoconfig.awsOutputLiveLL,
  }]
}

function App() {
  return (
    <div>
      <nav style={nav}>
        <p style={navHeading}>Live Streaming with React & AWS</p>
      </nav>
      <div style={container}>
        <VideoPlayer { ...videoJsOptions } />
      </div>
    </div>
  );
}

const nav = { padding: '0px 40px', height: 60, borderBottom: '1px solid #ddd', display: 'flex', alignItems: 'center' }
const container = { paddingTop: 40, width: 960, margin: '0 auto' }
const navHeading = { margin: 0, fontSize: 18 }

export default App

Enable OBS

Open Broadcast Software (OBS) can be automatically configured through Amplify video. Download OBS, make sure it's closed, and run the following command to configure an OBS profile to push to your Video resource.

$ amplify video setup-obs

Running the app

To run the app, run the start command:

$ npm start

Stopping the stream

When you are done with your stream, run the stop command to shut down your stream so you do not incur any additional streaming charges.

$ amplify video stop

? overwrite .../mylivestream-livestream-workflow.template: Y
? Would you like to overwrite all files? Y
? Are you sure you want to continue? Y
? overwrite ./src/aws-video-exports.js? Y

When the stream is turned off, it will be in Idle state. In Elemental MediaLive, the Idle state costs a little under 0.01 per hour. If you'd like to no incur any charges at all, delete the services with amplify delete.

Restarting the stream

If you'd like to turn the stream back on, run the following commands.

$ amplify video start

? overwrite .../mylivestream-livestream-workflow.template: Y
? Would you like to overwrite all files? Y
? Are you sure you want to continue? Y
? overwrite ./src/aws-video-exports.js? Y

Deleting the services

To delete the services from your account, run the delete command:

$ amplify delete

React Native

Amplify Video also works with React Native. To implement the stream on the React Native client, first install React Native Video

npm install react-native-video

To link the native dependencies, follow the guide here.

Next, set the video URI as the MediaStore URL

import Video from 'react-native-video';

<Video source={{uri: awsvideoconfig.awsOutputLiveLL}}
  ref={(ref) => {
    this.videoNode = ref
  }}
/>

Pricing

To view pricing for MediaStore, click here.

To view pricing for MediaLive, click here

Top comments (21)

Collapse
 
gabanox_ profile image
Gabriel Ramírez

¡Thanks for the awesome tutorial Nader!, I'm getting this error. ./src/App.js
Module not found: Can't resolve 'video.js' in '/Users/gabriel/my-streaming-app/src' ¿Any ideas of what could I be doing wrong?

Collapse
 
dabit3 profile image
Nader Dabit

Hey, just updated the tutorial with the install step:

npm install video.js

Sorry for the inconvenience, and thanks for pointing this out!

Collapse
 
gabanox_ profile image
Gabriel Ramírez

Thanks man, ¡now it works wonderfully!. Nice job

Thread Thread
 
dabit3 profile image
Nader Dabit

Awesome!!

Collapse
 
mrsamsa42 profile image
Jonathan Adler • Edited

Remember to stop or delete your channel and associated resources when you're done! Otherwise, it'll cost you about $40/day.

docs.aws.amazon.com/medialive/late...

Collapse
 
dabit3 profile image
Nader Dabit

Yes, thank you, I've updated the tutorial to show the pricing!

Collapse
 
stefanmajiros profile image
Stefan Majiros

Folks, who are using React Native,

if you need to stream videos, without "OBS" directly from mobile device, you can try this library: github.com/NodeMedia/react-native-...

Its "API" looks like this:

NodeCameraView
style=height: 400
ref=(vb) => this.vb = vb
outputUrl = "rtmp://192.168.0.10/live/stream" ---> maybe AWS URL here ??
camera= cameraId: 1, cameraFrontMirror: true
audio= bitrate: 32000, profile: 1, samplerate: 44100
video= preset: 12, bitrate: 400000, profile: 1, fps: 15, videoFrontMirror: false
autopreview=true

After taking look at inputs formats at docs.aws.amazon.com/medialive/late... and
docs.aws.amazon.com/medialive/late...

I guess it should work.

***I removed the brackets ({,}) from the code because I could not submit comment with them - sorry.

Collapse
 
codewithninja profile image
Zia_full_stack_dev

How Will I deploy it to the server? And how my server will know about my PC? seems like anyone would be able to stream on this code, or the CLI installed on the laptop makes a connection? What about authorization?

Sincerely,
Muhammad

Collapse
 
crock profile image
Alex Crocker

Thanks for this great post! I've been heavily focused on learning and using serverless technologies and JAMstack for the past year because I see it as the future.

Collapse
 
dabit3 profile image
Nader Dabit

Great to hear, thank you for checking out my post 💯

Collapse
 
ponyjackal profile image
ponyjackal

This is exactly what I've been waiting for.
Thanks for this post.

Collapse
 
vongohren profile image
Snorre Lothar von Gohren Edwin

Is not this basically a copy paste of this readme? github.com/awslabs/amplify-video/b...

Collapse
 
dabit3 profile image
Nader Dabit

That’s the repo I linked to, no If you compare the two you’ll see they are different

Collapse
 
vongohren profile image
Snorre Lothar von Gohren Edwin

OK I will trust you. Just got a very deja vue when reading that readme. With alot of the similar code and similar wording. On the setup: copyleaks.com/businesses/report/dx...

Collapse
 
rudyhadoux profile image
rudyhadoux

Hi, does it work for RTSP webcams too ?

Collapse
 
capzman profile image
capzman

Keep getting this error on amplify push command.
Following resources failed

Resource Name: rLambdaFunction (AWS::Lambda::Function)
Event Type: create
Reason: Could not unzip uploaded file

Collapse
 
rmunjal123 profile image
rmunjal123

Any way you fixed the error? Having the same issue

Collapse
 
usu008 profile image
usu008 • Edited

i am a react native developer so kindly guide me to do this with react-native?