Skip to content

Instantly share code, notes, and snippets.

@psi-4ward
Created October 22, 2013 11:28
Show Gist options
  • Star 42 You must be signed in to star a gist
  • Fork 16 You must be signed in to fork a gist
  • Save psi-4ward/7099001 to your computer and use it in GitHub Desktop.
Save psi-4ward/7099001 to your computer and use it in GitHub Desktop.
NodeJS MongoDB-GridFS Video range stream example Lets your browser seek/jump wihin the video-playback.
var app = require('express')();
var GridStore = require('mongodb').GridStore;
var ObjectID = require('mongodb').ObjectID;
var MongoClient = require('mongodb').MongoClient;
var Server = require('mongodb').Server;
var dbConnection;
MongoClient.connect("mongodb://localhost:27017/ersatz?auto_reconnect", {journal: true}, function(err, db) {
dbConnection = db;
app.listen(3000);
});
function StreamGridFile(req, res, GridFile) {
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) : GridFile.length -1;
var chunksize = (end-start)+1;
console.log('Range ',start,'-',end);
res.writeHead(206, {
'Content-Range': 'bytes ' + start + '-' + end + '/' + GridFile.length,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': GridFile.contentType
});
// Set filepointer
GridFile.seek(start, function() {
// get GridFile stream
var stream = GridFile.stream(true);
// write to response
stream.on('data', function(buff) {
// count data to abort streaming if range-end is reached
// perhaps theres a better way?
start += buff.length;
if(start >= end) {
// enough data send, abort
GridFile.close();
res.end();
} else {
res.write(buff);
}
});
});
} else {
// stream back whole file
console.log('No Range Request');
res.header('Content-Type', GridFile.contentType);
res.header('Content-Length', GridFile.length);
var stream = GridFile.stream(true);
stream.pipe(res);
}
}
app.get('/', function(req, res) {
console.log('GET request');
new GridStore(dbConnection, new ObjectID("526652540d9e077978000230"), null, 'r').open(function(err, GridFile) {
if(!GridFile) {
res.send(404,'Not Found');
return;
}
StreamGridFile(req, res, GridFile)
});
});
@derMani
Copy link

derMani commented Jul 22, 2015

Hey, I've just found your example here! Great work and thanks, but with the same example, I get a net::ERR_CONTENT_LENGTH_MISMATCH error.

Does the chunksize in the code here relate to to the chunksize in my GridFS?

@derMani
Copy link

derMani commented Jul 22, 2015

Your Code works well with IE11, FF and Chrome, but for some reasons Safari refuses to play my BigBuckBunny video (MOV/H.264) delivered through GridFS

@derMani
Copy link

derMani commented Jul 22, 2015

For some reason, I can not edit / delete previous posts (sorry for spamming):

With a little change, your example works fine in Safari:

https://gist.github.com/derMani/218bd18cc926d85a57a1

@mkoryak
Copy link

mkoryak commented Sep 29, 2015

to steam only a part of the file do fs.createReadStream('sample.txt', {start: 90, end: 99});

ah, but i have no idea if GridStream has support for that...

@zishon89us
Copy link

Streaming videos directly to/from GridFS using gridfs-stream either with mongodb-native db instance or mongoose.

Clone node-cheat direct_upload_gridfs, run node app followed by npm install express mongodb gridfs-stream.

@codiac82
Copy link

codiac82 commented May 6, 2016

Specific not work "start" FILE FOR VIDEO
I have 70 gigabytes of video and I'll extract a fragment of a size of 10 megabytes
Example:

  1. fs.createReadStream('sample.txt', {start: 50 000 000, end: 60 000 000})
    2.res.writeHead(206, {
    'Content-disposition': 'filename=streamxx.mp4',
    'Accept-Ranges': 'bytes',
    'Content-Type': "video/mp4",
    'Content-Range': 'bytes ' + start + '-' + end + '/' + GridFile.length,//GridFile.length, // start = 50 000 000
    'Content-Length': chunksize
    });
  2. GridFile.seek(start, function () { // start = 50 000 000
    or Other

These examples can extract part of the video file, but can not play in this part of the HTML5 Video tag . I tried FFMPEG and its superstructure but still can not play. As this fragmetn play or what or how to modify it ??

@samsonayalew
Copy link

This is a grate help for me on my projects. Thanks you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment