React Native: Streaming Agora Cloud-Recording HLS Videos from an S3 Bucket
Tags: reactnative, javascript, tutorial, mobile
Published: 2021-10-11 10:03:34

In a [previous blog](https://www.agora.io/en/blog/cloud-recording-for-react-native-video-chat-using-agora/) post, we looked at how to add Agora cloud recording to a video chat application for storing the recordings in an Amazon S3 bucket. Here, we’ll go over how to fetch and playback the recorded videos in a React Native application.

We’ve updated the [app](https://github.com/EkaanshArora/Agora-RN-Record-Playback) and the [back end](https://github.com/EkaanshArora/Agora-Cloud-Recording-Example) from the last blog post to bring everything together. If you just want the demo, you can deploy the back end and build the app from the links provided.

## Prerequisites
- An Agora developer account (see How to Get Started)
- An Amazon AWS account
- A Heroku account or another service to deploy the back end
- Understanding of React Native

## Agora Setup
1. **Create a project**: Once you have an Agora account, click the Project Management tab in the console. Click the Create button. Enter a name for your project. Select Secured Mode while creating the project.
2. **Enable cloud recording**: Click the View usage button and select the option to enable cloud recording.
3. **Get app credentials**: Copy the App ID and the App Certificate from the same page to a text file. We’ll use these later.
4. **Get customer credentials**: Visit the RESTful API page and click the Add Secret button. Copy the Customer ID and the Customer Secret to a text file.

## AWS Setup
Once you’ve created an AWS account, we need to create an Amazon S3 bucket to store our video recordings and an IAM user to access our bucket. If you have already completed this setup, you can skip this section.
1. Go to your [AWS IAM Console](https://console.aws.amazon.com/iam/home#/users) and create a user. Add the AmazonS3FullAccess policy with Programmatic Access. Copy your AWS Access Key and Secret Key to the text file.
2. Create an Amazon [S3 bucket](https://s3.console.aws.amazon.com/s3/home):
![aws screenshot](https://miro.medium.com/1*2LAlWLeGZNd7QGibCKFEbA.png)
Choose a name for your bucket and copy it to a text file. We’ll use this text file later. Allow public access to stream media from your bucket by deselecting the block all public access check box. Click the Create Bucket button.

> Note: With the URL for your recording, anyone on the internet can view it. We’ll discuss how to make the recording secure at the end of the post.

We’ll also need the region number for the selected AWS region. Go to this [table](https://docs.agora.io/en/cloud-recording/cloud_recording_api_rest?platform=RESTful#a-namestorageconfigacloud-storage-configuration), click the Amazon S3 tab, and note your region number. For example, if you’re using the US_EAST_1 region, your bucket number is 0.

3. Add the bucket policy.
To make files accessible by all users, we’ll add a bucket policy. Go to the Permissions tab in your newly created bucket and add this policy:
```
{
    "Version": "2012-10-17",
    "Id": "Policy1620917655085",
    "Statement": [
        {
            "Sid": "Stmt1620917653925",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::agora-rec123/*"
        }
    ]
}
```
## Deploying Our Back End
Before deploying our back end, we need the following variables. (It’s time to use our text file.) We’ll be using the Heroku one-click deploy to make it super simple to get our back end up and running. You can use any other service as well.

> Note: We’ve updated the back end, so if you’re using the back end from the previous post, you should update it now.

```
APP_ID=
APP_CERTIFICATE=
RECORDING_VENDOR=
RECORDING_REGION=
BUCKET_NAME=
BUCKET_ACCESS_KEY=
BUCKET_ACCESS_SECRET=
CUSTOMER_ID=
CUSTOMER_CERTIFICATE=
```
> Note: RECORDING_VENDOR=1 for AWS. Click this link for more information.

1. Create an account on Heroku if you haven’t done so already.
2. Click this link to use the Heroku one-click deploy.
3. Enter your variables and click the Deploy App button at the bottom of the page.
4. Wait a few minutes. Once the deployment is complete, save your back-end URL in a text file, which we’ll use in the app.

## Building Our App
We’ll start from the app we developed in the last post, which lets you take part in group video calls and record them. I’ve refactored the app to move all the video call and recording components to `./components/Call.tsx`. We’ll start with a new file: `./components/PlayRecording.tsx`
{% gist https://gist.github.com/EkaanshArora/bb2a3bafe97bc8b3ca910d00456bfec4 %}
We’ll use the Video component from react-native-video for HLS playback. We take in the back-end URL, App ID, and channel name as props to our PlayRecording component. We define an interface for our state. tracks will contain an array of URLs for each m3u8 file. currentTrack is the index of the URL we’re playing. statusMsg holds a string to display the current status of the video player.
{% gist https://gist.github.com/EkaanshArora/211e70b4a924d2d32bc1dadd8b3f9a40 %}
We define our component and our initial state. In the `componentDidMount` we perform a GET request to the `/api/get/recordingUrls/<ChannelName>` route of our back-end server. We get the response JSON and update the `tracks` state array.
{% gist https://gist.github.com/EkaanshArora/4fb8eca83a59146a3f4b03aaf26c6ebd %}
In our render method, we’re returning a list of tracks wrapped in `TouchableOpacity` using a `ScrollView`. When a track is selected, we update the `currentTrack` state with the track index.
{% gist https://gist.github.com/EkaanshArora/29ba1cd623c4e696a56391179c142de9 %}
We use the `Video` component with the source set as the URL we want to play (`currentTrack` index of our `tracks` array). We have event handlers to update our `statusMsg`. We also display the `statusMsg` in a `Text` component.

## Putting it back together
{% gist https://gist.github.com/EkaanshArora/e0799ace0bb540d5f19a95d9d27562d4 %}
We use the `PlayRecording` component in our `App.tsx` along with the Call component to put everything back together.

> **Security Consideration**: As we discussed, with our current configuration all the recordings stored on the S3 bucket are public so that the React Native client can access them. Before we use the app in production, it’s important to set access control for our videos. Once we get our users authenticated, we can issue them access to the files, while keeping the files private for everyone else. You can find more information [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) and [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-overview.html).

## Conclusion

You can find more information about cloud recording [here](https://docs.agora.io/en/cloud-recording/landing-page?platform=RESTful). If you’re starting out with the Agora SDKs, take a look at the [Agora Video Call Quickstart Guide](https://docs.agora.io/en/Video/landing-page?platform=React%20Native) and this [blog post](https://www.agora.io/en/blog/how-to-build-a-react-native-video-calling-app-using-agora/).

And I invite you to join the [Agora Developer Slack community](https://www.agora.io/en/join-slack/). Feel free to ask any React Native questions in the `#react-native-help-me` channel and cloud recording questions in the `#cloud-recording-help-me` channel.