Hey I've been on the search for quite a while now for a simple video API. I want to stream Videos on a simple page and implement them into my html. Any suggestions how I can make this work ?
1 Answers
We can use HTTP range requests
and the streaming APIs of the fs
module in Node.js to create video streaming APIs.
HTTP range requests allow sending only a portion of an HTTP message from a server to a client. Partial requests are useful for large media or downloading files with pause and resume functions, for example.
We will be using the http
module to create a simple server in Node.js and the promisify
utility to convert the callbacks to promises from the fs module
.
With Range Requests, we can control the amount of data we want to send to the client. In the below example, we simply look for the range headers, if they are present, we can parse the starting and ending bytes from the range header
and we will only send that part of the file.
We will create a read stream of the file and pipe it to the res
(http.ServerResponse
is a writable stream).
const { createServer } = require('http');
const path = require('path');
const { promisify } = require('util');
const { stat, createReadStream } = require('fs');
const fileInfo = promisify(stat);
const filename = './streams/test-video.mp4';
createServer( async (req, res) => {
const { size } = await fileInfo(filename);
const fileExtension = path.extname(filename).replace('.', '');
const { range } = req.headers;
if (range) {
let [start, end] = range.replace(/bytes=/, '').split('-')
start = parseInt(start, 10); // starting bytes
// end = end ? parseInt(end, 10) : size - 1 // end of file unless specified
end = Math.min(start + 5000, size - 1); // 5000 bytes starting from start byte or end of file, whichever is smaller
res.writeHead(206, { // HTTP 206 - Because it is Partial Content
'Content-Range': `bytes ${start}-${end}/${size}`,
'Accept-Ranges': 'bytes',
'Content-Length': (end - start) + 1,// denotes the number of bytes requested and not the entire file size
'Content-Type': `video/${fileExtension}`,
});
createReadStream(filename, { start, end }).pipe(res);
} else {
res.writeHead(200, {
'Content-Type': `video/${fileExtension}`,
'Content-Length': size,
});
createReadStream(filename).pipe(res);
}
}).listen(3000, () => {
console.log('Server listening on port 3000');
})

- 11
- 3