How to stream RTSP to React using ExpressJS
Tags: react, express, ffmpeg, axios
Published: 2021-03-05 12:16:22

Hi, I'm back. I will be showing you how to stream RTSP video input to your React frontend.

RTSP video is generally from your ip camera but it is a type of video format. I struggled with doing this whole project but I have come up with a stable enough project to help you out, if you need any. Also, I'd say the solutions on the web are really all over the place. 

I definitely struggled because I didn't know the first thing about RTSP and streaming video. 

I'll be using these frameworks/technologies:
- React
- Express JS
- [hls-server](https://www.npmjs.com/package/hls-server)
- [fluent-ffmpeg](https://www.npmjs.com/package/fluent-ffmpeg)
- [@ffmpeg-installer/ffmpeg](https://www.npmjs.com/package/@ffmpeg-installer/ffmpeg)
- [axios](https://www.npmjs.com/package/axios)
- [react-hls-player](https://www.npmjs.com/package/react-hls-player)


You can find the full source code [here](https://github.com/muhdmirzamz/hls-stream). I will go over the basics of the code.

We are going to:
- use axios to send a GET request to the backend
- use ffmpeg to convert RTSP to files (`.m3u8` and `.ts` files)
- pipe/insert those files into a HLS(Http Live Streaming) server
- send a response back to the frontend once the `.m3u8` file has been created
- show the video player using a state variable
- actually play the video

### Use ffmpeg to convert RTSP to files (`.m3u8` and `.ts` files)
![Screenshot 2021-03-05 at 7.50.48 PM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3urn5ttgddfquruxtw04.png)
 

The RTSP video format consists of 2 files. The `.m3u8` file and the `.ts` files.

![Screenshot 2021-03-05 at 7.20.15 PM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nmgrdl9ajeyb1so72pr6.png)
 

The `.m3u8` file is like a directory of where the `.ts` files are. So the video player needs the `.m3u8` file to actually ask for the rest of the `.ts` files. 

The .ts files are segments of the video that has been cut. You can specify the length of each segment using ffmpeg.

This is what the `.m3u8` file looks like.

![Screenshot 2021-03-05 at 8.13.10 PM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lolqf90irj9ik24rs9sx.png)
 

Since both files are needed, our backend does accommodate for these two files, meaning two GET request paths.

### Pipe/insert those files into a HLS(Http Live Streaming) server

This is where HLS(HTTP Live Streaming) comes in.

As you can see, there are 2 routes. `getManifestStream` and `getSegmentStream`.

`getManifestStream` serves the `.m3u8` file while `getSegmentStream` serves `.ts` files.

![Screenshot 2021-03-05 at 7.52.56 PM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7wvjxmzoxm105qxeit5.png)

This code checks to see if the files(`.m3u8`, `.ts`) are actually created and makes sure that they are ready to be served/streamed to the frontend.

### Send a response back to the frontend 


To check if the `.m3u8` file has actually been created, I did a check.

```fs.access("videos/output.m3u8", fs.constants.F_OK, (err) =>  {}```

This is made in the `.on('progress')` block of the `ffmpeg` function which allows you to check on the progress of the file conversion.

If the file has indeed been created, do a `res.sendStatus(200) `.

### Show the video player using a state variable

In the frontend, we are at the `response` block of the `axios.get("")` function where we will set the state variable to `true` and ask React to re-render the video player into the DOM.

![Screenshot 2021-03-05 at 8.02.09 PM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4h0yw1g6gphrrtzioxqe.png)

### Actually play the video

![Screenshot 2021-03-05 at 8.04.24 PM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqdvn4txtctx1kqjduaz.png)

The video will play automatically once the `.m3u8` file has been loaded. However, as you can see, I set the `muted` property as such because for some reason (as seen on Stackoverflow), Chrome needed it to be set for the video to play automatically.

Again, it can be overwhelming, so you can find the full source code [here](https://github.com/muhdmirzamz/hls-stream).