0

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 Answers1

0

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');
})