can't seek html5 video or audio in chrome

I found the reason why it's not working on this question:

HTML5 video will not loop

Our server doesn't understand partial content right now. As a result chrome is sending requests for content that doesn't get answered which in turn makes our video's and audio unseekable (and unloopable).


You must handle req.headers['range'] which Chrome will send to your streaming server.

Please refer to my codes below. It worked well on Chrome, Firefox, Edge and IE. I haven't test it on Safari but hopefully it also can work.

I used Sails/Nodejs backend and gridFS/mongodb database for storing Videos files as Chunks.

try {
        let foundMetaFile = await GridFS.findOne({id: fileId});

        if (!foundMetaFile) return res.status(400).json(Res.error(undefined, {message: `invalid ${fileId} file`}));

        let fileLength  = foundMetaFile['length'];
        let contentType = foundMetaFile['contentType'];
        // let chunkSize   = foundMetaFile['chunkSize'];
        if(req.headers['range']) {

            // Range request, partialle stream the file
            console.log('Range Reuqest');
            var parts = req.headers['range'].replace(/bytes=/, "").split("-");
            var partialStart = parts[0];
            var partialEnd = parts[1];

            var start = parseInt(partialStart, 10);
            var end = partialEnd ? parseInt(partialEnd, 10) : fileLength - 1;
            var chunkSize = (end - start) + 1;

            console.log('Range ', start, '-', end);

            res.writeHead(206, {
                'Content-Range': 'bytes ' + start + '-' + end + '/' + fileLength,
                'Accept-Ranges': 'bytes',
                'Content-Length': chunkSize,
                'Content-Type': contentType
            });
        }

        let { mongodbConnection } = global;
        let bucket = new GridFSBucket(mongodbConnection, { bucketName: 'fs' });

        return new Promise ((resolve, reject) => {
            let downloadStream  = bucket.openDownloadStream(fileId);
            downloadStream.on('error', (err) => {
                console.log("Received Error stream")
                res.end();
                reject(err);
            })

            downloadStream.on('end', () => {
                console.log("Received End stream");
                res.end();
                resolve(true);
            })
            console.log("start streaming");
            downloadStream.pipe(res);
        })

    } catch (error) {
        switch (error.name) {
            case 'UsageError':
                return res.status(400).json(Res.error(undefined, {message: 'invalid Input'}));
            case 'AdapterError':
                return res.status(400).json(Res.error(undefined, {message: 'adapter Error'}));
            default:
                return res.serverError(error);
        }