Published on December 8, 2020 (about 4 years ago)

Live streaming with React Native

Erik Peña
By Erik Peña5 min readEngineering

LinkHead's up!

While the information in this post still has a ton of great details, the react-native-nodemediaclient project has sadly been deprecated.

LinkSo...

You've decided to introduce mobile live streaming to your React Native app. This is wonderful and if you are using Mux this is especially great because getting set up and running is extremely easy.

One of the nice things about React Native is the community supported libraries. There's virtually a library for everything. However, when selecting a library to enable live streaming, you'll need to ensure that the library streams over RTMP, which is the industry standard protocol.

For the purposes of this post, I decided to demonstrate live streaming with Mux using the react-native-nodemediaclient as the broadcasting client. In reality, this could be replaced with whatever library you select that is capable of streaming RTMP from within React Native.

Okay, big picture time. We more or less know what technologies we're going with. To summarize with a high level diagram (I love making these), here is the general idea of what's involved to enable live streaming—

With the preface out of the way, let's talk about how to create a new live stream within Mux. Within Mux Dashboard, create a new Live Stream and acquire the Playback ID (not to be confused with the Live Stream ID) as well as the Stream Key. That's it! You, at this point, have all the information you need to start streaming to Mux.

On the live stream details page, you'll also notice there are two RTMP URL options values. Use the RTMPS url wherever possible as it is more secure. If the broadcast client is not capable of working over RTMPS, then Mux does also provide an unsecured RTMP url, but I would advise against that as much as possible.

When constructing your stream URL, you will combine the RMTP URL with your Stream Key. So if you had a Stream Key of 5b2a4a75-86c2-177c-72a2-45ab2b5e2583 your stream URL will look like—

rtmps://global-live.mux.com:443/app/5b2a4a75-86c2-177c-72a2-45ab2b5e2583

LinkOkay, let's get our nerd on 🧑‍💻

In the following code snippet, the key takeaway is how the stream URL is used with whichever broadcast client you choose. Again, I went with react-native-nodemediaclient, but you could insert whichever library suits your needs.

For the sake of brevity, I hardcoded video, audio and camera configurations that react-native-nodemediaclient uses. This would be something you'll want to adapt to your product for a better streaming experience.

javascript
import React from 'react; import { Dimensions, View } from "react-native"; import { NodeCameraView } from "react-native-nodemediaclient"; const { width, height } = Dimensions.get("window"); const config = { cameraConfig: { cameraId: 1, cameraFrontMirror: false }, videoConfig: { preset: 4, bitrate: 2000000, profile: 2, fps: 30, videoFrontMirror: true, }, audioConfig: { bitrate: 128000, profile: 1, samplerate: 44100, } }; const BroadcastScreen = () => { const cameraViewRef = React.useRef(null); const streamKey = '5b2a4a75-86c2-177c-72a2-45ab2b5e2583'; const url = `rtmps://global-live.mux.com:443/app/${streamKey}`; return ( <View style={{flex: 1}}> <NodeCameraView style={{width, height}} ref={cameraViewRef} outputUrl={url} camera={config.cameraConfig} audio={config.audioConfig} video={config.videoConfig} autopreview={true} /> </View> ); }; export default BroadcastScreen;

At this stage, your broadcast client is configured and ready to start streaming. Most libraries make use of React refs to give access to imperative function handles (e.g. cameraViewRef.current.start(), cameraViewRef.current.stop(), etc). These functions can then be called when content creators are interacting with the app.

All that's really left is to implement a UI that allows the user to start and stop a live stream Well... that's the minimum we need to do in order to live stream with Mux.

LinkHold on though, this is important...

When starting the stream, it is crucial to remember that what the content creator sees on their screen is directly from their camera and doesn't translate to what their end users are necessarily are seeing on the playback side.

Remember, there are various factors that go into the quality of a stream from a device and if they are streaming from a mobile phone, chances are they are doing so over a cellular network. For this reason, being on a cellular network means that the available upload bandwidth will be limited and means that you'll need to be economical with your video quality.

LinkDemo time!

To help understand what to approximate expectations, I went through a series of recordings at various bitrates and presets. The following are side-by-side comparisons that demonstrates what the screen is showing the content creator (left) and what the end user sees (right).

Link360 x 640 at 1,000 kbps

I did this video while in my office. I decided to have a little more fun with the next videos and actually get out into the world for more real-world field examples.

Link540 x 960 at 2,000 kbps

Alki Beach, West Seattle. December is not really the time to come out here. But hey, it's the only real beach we got.

Link720 x 1280 at 3,000 kbps

Welcome to Pike's Place Market. You know, where they throw fish and the home of the nasty Gum Wall. I'm really not even sure why I decided to come here 😂

Link1080 x 1920 at 5,000 kbps

This is the MoPOP (Museum of Pop Culture). Architecturally beautiful and a lot of cool things inside (I couldn't get in). Special guest at the end of the video if you stay tuned.

The above demos are using static bitrates for streaming. In general, you'd want to enable variable bitrates based on the broadcasting device's connection speed. If this is available in the broadcasting client, you will definitely want to take advantage of it.

I hope this post was helpful and informative in your journey of learning how to live stream with React Native!

Written By

Erik Peña

Big time techie with a disposition for digital media. Affinity for Italian food and dad jokes.

Leave your wallet where it is

No credit card required to get started.