Record and Upload Videos with React Native

Daniel Schmidt
React Native Training
4 min readJul 10, 2018

In one of my last blog posts, Samuel Omole asked me if I could do an article about uploading content with React Native. For me the most interesting content to upload are videos, they are fun to watch. Also, they open up cool opportunities to do super cool stuff like streaming, so there might be a part two on this post if you are interested. 🤔

Building a server

As this post is about React Native, so I will just put some links here for you to read thoroughly how you can build a Node.js backend for this project.

Express File Uploads with Express + Multer by Jecelyn Yeen explains in detail how you can build a Node.js backend to upload files and serve them.

If you want to go one step further you can also read Video stream with Node.js by Diogo Spínola, which goes into detail about downloading the video as a stream.

If you don’t want to go into building a server, make sure you have installed docker and run docker run -p 3000:3000 danielmschmidt/react-native-video-upload-demo-backend, in the command line. This will start our video server on port 3000 and we are ready to go.

Starting the recording

Now let’s come to the interesting part, React Native. Before we can upload a video, we need to create one, so let’s take a look at react-native-camera maintained by the React Native community. It gives you an easy interface to interact with the camera of your phone with React Native. You can mount a component that displays what your camera records and you can use the reference to trigger actions like taking a picture or recording a video. And this is what we are going to do, so let’s take a look at the code:

We want to have different display states:

  1. No video being recorded
  2. Video recording in progress
  3. Video recording was done & upload in progress

I decided to encode them with two boolean flags: recording and processing. Let’s start with the render method for these states:

As you can see we decide based on the current state which button we want to show. As you can see we also set the reference of the camera for later use. Last but not least there are a couple of default values and here we go. Besides the state handling this is what you need to get a usage like this:

Recording a video is super easy with react-native-video, you simply need to use the reference we have stored. Please note that the startRecording function will not finish because the await only finishes after stopRecording was called.

Uploading the Video

Having a video on your phone is cool, but having it on a server is even cooler. For this, we need to put the data into a FormData object and upload it via fetch.

Watching the videos

Last but not least I would like to show you the easiest way I have found to display videos. I could not get libraries like react-native-video running with my backend, but we web works fine, so I choose the easy and pragmatic route.

I just fetch all the videos my backend stores and add links to them on the watch page. This will not stay like this forever, but I have the feeling it is a good first start to get a sense of it.

What’s Next?

What I have shown you so far seems pretty standard, but it opens up a lot of cool opportunities. If you compare the features we have (roughly) with YouTube we basically have video recording and uploading as well as watching them. While this is a good start I want to try myself on the bigger challenge:

I would like to build the live feature, specifically, I want people to be able to subscribe to my live stream while I am recording it and see almost the same as my camera sees. For this I would need to modify or patch react-native-camera to emit the path to the video right after it starts recording, I need to watch changes on this file and upload them right away to a server using a connection that stays open. Sounds like a great challenge, I am excited.

If you like to see the second part, please comment here and let me know. It will surely motivate me to do my best to deliver 💪

--

--