Search code examples
mongoosegridfs-stream

How to read a video with gridfs-stream?


I'm using mongoose with gridfs-stream to store files, images, audios, and videos.

The problem is when I select another position/time in the video, is stopped, the same happens when I play any song.

Someone can help me?

This is my code:

exports.readById = function(req, res) {
    var id = req.modelName._id;

    gfs.findOne({
        _id: id
    }, function(err, file) {
        if (err) {
            return res.status(400).send({
                err: errorHandler.getErrorMessage(err)
            });
        }
        if (!file) {
            return res.status(404).send({
                err: 'No se encontró el registro especificado.'
            });
        }

        res.writeHead(200, {
            'Accept-Ranges': 'bytes',
            'Content-Length': file.length,
            'Content-Type': file.contentType
        });

        var readStream = gfs.createReadStream({
            _id: file._id
        });

        readStream.on('error', function(err) {
            if (err) {
                return res.status(400).send({
                    err: errorHandler.getErrorMessage(err)
                });
            }
        });

        readStream.pipe(res);
    });
};

Solution

  • Is necessary to use the range option, it allows us to select another position in the video and play it. In other words, making a request to the server so that the server responds with the data we need.

    Here is the complete code, I hope they serve someone.

    I found the example here.

    exports.readById = function(req, res) {
        var id = req.modelName._id;
    
        gfs.findOne({
            _id: id
        }, function(err, file) {
            if (err) {
                return res.status(400).send({
                    err: errorHandler.getErrorMessage(err)
                });
            }
            if (!file) {
                return res.status(404).send({
                    err: 'No se encontró el registro especificado.'
                });
            }
    
            if (req.headers['range']) {
                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) : file.length - 1;
                var chunksize = (end - start) + 1;
    
                res.writeHead(206, {
                    'Accept-Ranges': 'bytes',
                    'Content-Length': chunksize,
                    'Content-Range': 'bytes ' + start + '-' + end + '/' + file.length,
                    'Content-Type': file.contentType
                });
    
                gfs.createReadStream({
                    _id: file._id,
                    range: {
                        startPos: start,
                        endPos: end
                    }
                }).pipe(res);
            } else {
                res.header('Content-Length', file.length);
                res.header('Content-Type', file.contentType);
    
                gfs.createReadStream({
                    _id: file._id
                }).pipe(res);
            }
        });
    };