Thursday, March 31, 2016

Show BASE64 video with node/express

Leave a Comment

So, bit of an odd problem. I have a bunch of media files saved as base64 strings in mongo, some are images, some are videos.

I made an API for getting the media files:

app.get('/api/media/:media_id', function (req, res) {     media.findById(req.params.media_id)         .exec(function (err, media) {             if (err) {                 res.send(err);             }              var file = new Buffer(media.file, 'base64');             res.writeHead(200, {'Content-Type': media.type, 'Content-Transfer-Encoding': 'BASE64', 'Content-Length': file.length});             res.end(file);         }); }); 

Now, images have no problems. They load just fine, both directly from the API, and when I call the API from a front-end (for example <img src="/api/media/23498423">)

THE PROBLEM

If I fetch a video from a front-end, like the images - but with a video- or object-tag:

<video src="/api/media/3424525" controls></video> 

there's no problem, but if I load the video in a browser directly from the API:

http://localhost:8080/api/media/3424525 

the server process crashes, no errors. It simply just freezes up. And we're not talking about huge video files - it's a 1.5MB video.

The media type in the header for all the videos I'm testing with is video/mp4. Oh, and just to be clear: if I do the same with images, everything works perfectly.

EDIT:

Okay, so as suggested by @idbehold and @zeeshan I took a look at gridfs and gridfs-stream, and for the purpose of my app, this certainly is what I should have used in the first place. However, after implementing gridfs in my app, the problem still persists.

app.get('/api/media/:media_id', function (req, res) {     gfs.findOne({ _id: req.params.media_id }, function (err, file) {         if (err) {             return res.status(400).send(err);         }         if (!file) {             return res.status(404).send('');         }          res.set('Content-Type', file.contentType);         res.set('Content-Disposition', 'inline; filename="' + file.filename + '"');          var readstream = gfs.createReadStream({             _id: file._id         });          readstream.on("error", function (err) {             console.log("Got an error while processing stream: ", err.message);             res.end();         });          readstream.pipe(res);     }); }); 

When I call the media file (be it image or video) from a front-end, within a HTML tag, everything works out fine. But if I load a video (again, smallish videos from 1.5mb to max 6mb total size) directly in the browser, the server process freezes. To be a bit more clear: I am testing on windows, and the server app (server.js) is run in console. The console and the process it is running is what freezes. I cannot load any more pages/views in the node app, and I cannot even stop/kill/shutdown the node app or the console.

3 Answers

Answers 1

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

var mongo = require('mongodb'),     Grid = require('gridfs-stream'),     db = new mongo.Db('yourDatabaseName', new mongo.Server("127.0.0.1", 27017)),     gfs = Grid(db, mongo);  //store app.post('/video', function (req, res) {     req.pipe(gfs.createWriteStream({         filename: 'file_name_here'     }));     res.send("Success!"); });  //get app.get('/video/:vid', function (req, res) {     gfs.createReadStream({         _id: req.params.vid // or provide filename: 'file_name_here'     }).pipe(res); }); 

for complete files and running project:

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

Answers 2

Truly an odd problem...
I could be way off, but it's worth a shot:

One of the differences when opening a url directly from the browser is that the browser will also try to fetch http://localhost:8080/favicon.ico (while trying to find the tab icon). Maybe the problem is not related to your video code, but rather to some other route, trying to handle the /favicon.ico request?

Have you tried using wget or curl?

Answers 3

I don't know the answer, maybe this is could be dumb suggest, but what is the browser are you using? Maybe something from Microsoft causes the problem...

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment