building Node.js video streaming in 5 minutes
hi folks, in this blog we will build a Node.js video streaming application in like 10 minutes.
hi folks, in this blog we will build a Node.js video streaming application in like 10 minutes.
prerequisite
- install Node.js on your computer
what is streaming
Streams are collections of data — just like arrays or strings. The difference is that streams might not be available all at once, and they don’t have to fit in memory. This makes streams really powerful when working with large amounts of data, or data that’s coming from an external source one chunk at a time.
setup [ 1 ] - Getting started
1 - create a folder and name it video-streaming
2 - initialize npm in your project npm init -y
3 - install these packages
dependencies.
#### npm install express
development dependencies.
npm install -D nodemon
add this script to your package.json
file.
"start": "nodemon index.js"
setup [2] - setup Node.js server
1 - create an index.js
file in your project root.
2 - add this code below
const express = require("express");
const app = express(); // setup express application
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log("SERVER STARTED AT PORT: " + PORT);
});
this code starts web server using express
framework and listening to port: 3000
.
setup [3] - serving html page
now we want to serve an HTML page with a video element to the Frontend.
1 - create a public
folder in your project root.
2 - create the index.html
file in the created folder (public
) and add this HTML code.
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home | Video Streaming</title>
</head>
<body>
<video
controls
src="/video"
id="video-stream"
poster="/poster.jpeg"
width="700"
>
</video>
</body>
</html>
controls
: Specifies that video controls should be displayed (such as a play/pause button etc).src
: Specifies the URL of the video file.poster
: Specifies an image to be shown while the video is downloading, or until the user hits the play button.
serving html file
we need to send the html page to the users. add this code below in index.js
file.
app.get("/", (req, res) => {
try {
res.sendFile(__dirname + "/public/index.html");
} catch (err) {
res.status(500).send("internal server error occurred")
}
});
what that code does, is listen to get the request in the base URL of the application, when it gets the response will be sent file by using sendFile
and the first parameter is an HTML file path.
note: __dirname
is the root path of the current directory.
Serving Poster Image - setup [4]
the poster is image will be shown until the video is downloaded or the user clicks the video. note: you need to any image you want in the public directory that you make. see the code below
app.get("/:file_name", (req, res) => {
try {
res.sendFile(__dirname + req.params.file_name);
} catch (err) {
res.status(500).send("internal server error occurred");
}
});
Streaming video - setup[5] and Final
import required node.js modules
when streaming the video we need to import two Node.js build-in library in the top of file.
const fs = require("fs");
const path = require("path");
fs
: file system module allows you to work with the file system on your computer. To include the File System module.
path
: allows you to interact with file paths easily. The path module has many useful properties and methods to access and manipulate paths in the file system.
setup video API function
add this code before Serving Poster Image function, because nodejs will go throw the express middlewares and if the requested url is /video
it will be match the Serving Poster Image middlewaree not the video middleware.
note : you need to add random video in public file.
app.get("/video", (req, res) => {
// indicates the part of a document that the server should return
// on this measure in bytes for example: range = 0-6 bytes.
const range = req.headers.range;
if (!range) res.status(400).send("Range must be provided");
const videoPath = path.join(__dirname, "public", "video.mp4");
// extract video size by using statSyn()
const videoSize = fs.statSync(videoPath).size;
// 10 powered by 6 equal 1000000bytes = 1mb
const chunkSize = 10 ** 6;
// calculating video where to start and where to end.
const start = Number(range.replace(/\D/g, ""));
const end = Math.min(start + chunkSize, videoSize - 1);
const contentLength = end - start + 1;
// setup video headers
const headers = {
"Content-Range": `bytes ${start}-${end}/${videoSize}`,
"Accept-Ranges": "bytes",
"Content-Length": contentLength,
"Content-Type": "video/mp4",
};
res.writeHead(206, headers);
// creating readStream (stdin).
const videoStream = fs.createReadStream(videoPath, { start, end });
// create live stream pipe line
videoStream.pipe(res);
});
and then run npm run start
. to see your work.
what is pipe() in streaming
Streams make for quite a handy abstraction, and there's a lot you can do with them - as an example, stream.pipe()
, the method used to take a readable stream and connect it to a writeable stream. the writable stream is the user we request him the data buffers.
project source code: github.com/alguerocode/video-streaming
- social media:
=> follow me in twitter: alguerocode
=> follow me in github: alguerocode
See My projects, don't forget to add a star is really help me grow.
thank you for reading.