Welcome folks today in this blog post we will be implemting video streaming
in webpage using fetch
api in javascript using node.js and express. All the full source code of the application is shown below.
Get Started
In order to get started you need to make a new node.js
project using the below command
npm init -y
And now you need to make an index.js
file and copy paste the following code
index.js
1 2 3 4 5 6 7 8 9 10 11 12 |
const fs = require('fs'); const path = require('path'); const express = require('express'); const app = express(); app.get('/',(req,res) => { res.sendFile(__dirname + "/index.html") }) app.listen(3000, () => { console.log('Server started on port 3000'); }); |
As you can see we are importing the required modules at the top and then we are showing the index.html
file when the user goes to the /
route
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<!DOCTYPE html> <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>Document</title> </head> <body> <video id="my-video" controls></video> </body> <script> const videoElement = document.getElementById('my-video'); const url = '/video'; fetch(url) .then(response => { if (response.status === 206) { // Streaming response received response.body.pipeTo(new WritableStream({ write(chunk) { // Append received data to the media element buffer videoElement.buffered.end(0); videoElement.srcObject = new MediaStream([chunk]); } })); } else { // Non-streaming response received response.blob().then(blob => { videoElement.src = URL.createObjectURL(blob); }); } }) .catch(error => { console.error(error); }); </script> </html> |
As you can see we have the video
tag inside the html and then inside the javascript we are making the fetch
api call to the backend api route which is called /video
here we are getting the response
from the server and then we are showing the video inside the video
tag. Now we need to make this backend
api request as shown below
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
const fs = require('fs'); const path = require('path'); const express = require('express'); const app = express(); app.get('/',(req,res) => { res.sendFile(__dirname + "/index.html") }) app.get('/video', (req, res) => { const filePath = path.join(__dirname, 'video.mp4'); const stat = fs.statSync(filePath); const fileSize = stat.size; const range = req.headers.range; if (range) { const parts = range.replace(/bytes=/, '').split('-'); const start = parseInt(parts[0], 10); const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1; const chunksize = (end - start) + 1; const file = fs.createReadStream(filePath, {start, end}); const head = { 'Content-Range': `bytes ${start}-${end}/${fileSize}`, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/mp4', }; res.writeHead(206, head); file.pipe(res); } else { const head = { 'Content-Length': fileSize, 'Content-Type': 'video/mp4', }; res.writeHead(200, head); fs.createReadStream(filePath).pipe(res); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); |
As you can see we are passing the stream
of data of the video file which is stored inside the local
file path and then we are reading all the data using the createReadStream()
method chunk by chunk and then passing it to the client using the pipe()
method.
node index.js