avatarArtem Diashkin

Summary

This article provides a comprehensive guide on implementing video streaming and segmentation using Node.js and React.js, including setting up a React application with a video player and creating an Express.js server to handle video streaming in chunks and segmented video (m3u8).

Abstract

The article delves into the process of streaming video content over the web using Node.js and React.js technologies. It covers the creation of a React.js front-end application that interacts with a Node.js server to stream video in different manners: as a continuous stream and as segmented video using the m3u8 format. The author guides the reader through setting up the project structure, implementing back-end functionalities with Express.js, and using libraries such as fluent-ffmpeg for video segmentation. The article also touches on deploying the application on platforms like Netlify and provides access to a GitHub repository with the complete code example.

Opinions

  • The author emphasizes the practicality of using Node.js for video streaming, showcasing both Express.js and native Node.js streaming capabilities.
  • There is a clear preference for using fluent-ffmpeg to abstract the complexity of ffmpeg command-line tools for video segmentation.
  • The article suggests that developers can benefit from using the provided project template and GitHub repository to expedite their development process.
  • The author values the ease of use of the vime-js player for React applications and recommends it for handling video playback.
  • There is an opinion that deploying such applications on services like Netlify can be straightforward, even for beginners.
  • The author encourages readers to explore their other articles for additional learning and development resources.

Node.js. Video streaming, and segmentation in Examples

In this article we will take a look at how we can send a video as a stream (in chunks), and as a segmented video (m3u8). Additionaly we will create a React.js app with “vime-js” (not vimeo) player.

What we will be implementing

This is how our React.js page will look like fetching data from our Node.js server:

Prerequisites

Project structure:

If you are using WebStorm as your development IDE you can use this template file:

Just download the archive and copy it into the folder (for Mac users)

/Users/{userName}/Library/Application Support/JetBrains/WebStorm{version}/projectTemplates

After that, you can create a new project from that template (don't repeat yourself 🙂):

A new project will be created from that template

Don’t worry, you will not have to create this project from scratch → I will leave a link to the github repo:

If you just want to check the project without downloading it and running locally you can press “dot” . at the github page → VS Code IDEA will open:

Github page IDEA (gif)

Express.js data send

At first, we will be working on back-end implementation. We will use a video file to be work with from the Unreal Engine5 demo:

At first, we will place that file into the /server/assets folder:

Next, we will create an Express.js route (.sendFile) that will send this file by GET request /video-file :

After the server start, you can open a browser at localhost:3001/video-file page (no React, for now at least) and see how it works:

stream log image

If user will forward a video…

… video data will be loaded in chunks (take a closer look at status 206 Partial Content), just like we will do it next:

This approach is uses the Express.js framework, but how it can be done using Node.js only. Let’s take a look next.

Streaming video file

Here we will implement the same thing but only using Node.js. Create a new GET /video-chunk route:

getFileSizeAndResolvedPath and getChunkProps functions in utils.ts file:

If you will open localhost:3001/video-chunk page → result will be the same

Video segmentation

And this is the most interesting part. In this section, we will create segments of our video → m3u8 list with .ts files.

⚠️ NOTE: You can create video segments of your video using many desktop tools available, but here I what to show you how to do that using Node.js.

We will use fluent-ffmpreg library:

This library abstracts the complex command-line usage of ffmpeg into a fluent, easy to use node.js module.

Instal those packages into the /server project:

yarn add fluent-ffmpeg @ffmpeg-installer/ffmpeg hls-server

… and types (if you use typescript):

yarn add @types/fluent-ffmpeg -D

Next, copy-paste code into the src/generate.mjs file.

👉 You can check more about those command lines we copy-pasted here:

Next, run node generate.mjs command:

It will generate ts segments with m3u8 from Unreal Engine 5 video file:

👉 m3u8 file is basically a list of video segment file names and timecodes:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:13
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:13.213200,
segments/file000.ts
#EXTINF:8.341667,
segments/file001.ts
#EXTINF:0.834167,
segments/file002.ts
#EXTINF:8.341667,
segments/file003.ts
...
#EXTINF:8.341667,
segments/file151.ts
#EXTINF:8.174833,
segments/file152.ts
#EXT-X-ENDLIST

Next, we will create two simple routes:

  • /segment-list → will return a m3u8 list
  • /segments/:segment → will return a file002.ts (as example) from assets/segments folder

React application

At first, add vime player to your dependencies:

yarn add @vime/react

Next, update App.ts file with this code:

Basically, we have three Players:

  • Chunks and File players requesting a video file from a server in a “simple” way → fetch video file by a link;
  • Segments players work a bit differently → it fetches m3u8 list with the segment file names and timecodes at first and then file by one at a specific time

⚠️ NOTE: You can check my other article, if want to know how to deploy this app on Netlify:

Github repository link:

If you liked this story you can check “List of all my stories” as well. Happy coding!

Nodejs
React
Development
JavaScript
Typescript
Recommended from ReadMedium