Photo by Caspar Camille Rubin on Unsplash

In this post, we will look at how to implement a feature similar to Instagram Live in a React Native app. We were recently tasked with building a live streaming feature for a client that wanted the ability to go live for his users. So we got to looking for possible solutions. Our initial research leads us to possibly using Youtube’s Live platform and then rendering that in-app, but we didn’t want our client to have to go to Youtube and go live and mess around with private URLs there. We wanted it to be all in one place, so he can go live through an admin portal in the app itself. Another option we looked at was Twilio, but we quickly found out Twilio has a max participant to their video stream platform of 50.

Eventually, we stumbled on a service called Mux. Mux describes themselves on their website as an API-first platform, powered by data and designed by video experts to make beautiful video possible for every development team. They also say they can support thousands of streams and millions of viewers with their live streaming API that can be set up in minutes. Given all this, we started digging into their docs. We were immediately intrigued by how dead simple their API looked, so we decided to give it a shot.

Mux provides a pretty generous pricing model at just $0.0013/min (Per minute of video duration streamed to a device), we expect our videos to be streamed for about 30–45 minutes max. So this pricing seemed fair to us. They also provide a $20 trial which gives plenty of time to tinker with and test.

The implementation

The first thing we did was from Mux’s dashboard created a new live streaming asset. Given this asset, you will be given everything needed to continue from there, including the live stream id, stream key, and RTMP URL to push the broadcasting.

Next, we needed a library that was able to publish to our RTMP link. There is a library called react-native-nodemediaclient. We were a little skeptical of this library but decided to give it a shot. We also found out its part of the Node-Media-Server, which is a pretty popular and active library that’s described as a Node.js implementation of RTMP/HTTP-FLV/WS-FLV/HLS/DASH Media Server. We had no issues installing and linking this library with native modules, which was a pretty good sign considering how sketchy linking can be in React Native. Adding their sample code(below) into our app, swapping out the outputUrl with our RTMP URL we got from our Mux dashboard, we were able to test this right away.

import { NodeCameraView } from 'react-native-nodemediaclient';



......



<NodeCameraView

style={styles.nodeCameraView}

ref={(vb) => { this.vb = vb }}

outputUrl = {" rtmp://live.mux.com/app/your-stream-key-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}

/> // Later on in your styles..

var styles = StyleSheet.create({

nodeCameraView : {

position: 'absolute',

top: 0,

left: 0,

bottom: 0,

right: 0,

},

...other styles here });

We wired up a button in the app that onClick accesses the NodeCameraView ref and runs with this.vb.start() and gave our view some style to take up the whole screen.

Be sure to add in all the checks for permissions necessary for iOS and Android otherwise you’ll run into some issues there at runtime.

Running the app

Mux provides a video player on their dashboard that shows when your stream is active and plays it for you live. After hitting publish in our app we immediately saw some things happening on the dashboard and eventually Mux’s video player started showing our live video from the app. It was that simple. Our video had about a 15–20 seconds stream delay which is pretty normal for the platform.

Viewing the stream in-app

Now that we know we can broadcast we gotta be able to see the broadcast live in our app. This library actually includes a video player as well, but we found that it simply did not work on iOS but did work on Android. That’s not good enough, so we looked at the most popular video library for React Native — react-native-video. Setting up this library was pretty straightforward following their readme.

Add the <Video/> component below into your app, keep in mind we are changing the source to our playback id found on Mux video dashboard:

import Video from 'react-native-video';





<Video

source={{uri: "https://stream.mux.com/your-playback-id.m3u8"}}

ref={(ref) => {

this.player = ref

}} // Store reference

onBuffer={this.onBuffer} // Callback when remote video is buffering

onError={this.videoError} // Callback when video cannot be loaded

style={styles.backgroundVideo} />



// Later on in your styles..

var styles = StyleSheet.create({

backgroundVideo: {

position: 'absolute',

top: 0,

left: 0,

bottom: 0,

right: 0,

},

});

Running this gave us the exact result we wanted when the live stream is running this video component will show it.

Wrapping up

That’s that, from here you can add whatever other features you’d like, including live viewer count or live commenting. We may add more parts to this article with additional features we are adding as we go but as of now its very bare bones. Be sure to check out Mux’s documentation to see what else you can do with their service as well. Things like manually starting/ending the live stream with an API call are useful and something we added to better serve the video to our viewers. It also helps with coordinating a loading/finished components for when the stream is starting and ending.

Thanks for reading, you can find an example of all this on Github here.