所以,有点奇怪的问题。我有一堆媒体文件在mongo中保存为base64字符串,有些是图像,有些是视频。
我制作了一个用于获取媒体文件的API:
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);
});
});
现在,图像没有问题。它们可以直接从API加载,也可以从前端调用API(例如 <img src="/api/media/23498423">
)
问题
如果我从前端获取视频,如图像 - 但使用视频或对象标记:
<video src="/api/media/3424525" controls></video>
没问题,但如果我直接从API加载视频:
http://localhost:8080/api/media/3424525
服务器进程崩溃,没有错误。它只是冻结了。我们不是在谈论巨大的视频文件 - 它是一个1.5MB的视频。
我正在测试的所有视频的标题中的媒体类型是 video/mp4
。哦,只是要清楚:如果我对图像做同样的事情,一切都很完美。
编辑:
好的,正如@idbehold和@zeeshan建议的那样,我看了一下gridfs和gridfs-stream,为了我的应用程序的目的,这肯定是我应该首先使用的。但是,在我的应用程序中实现gridfs后,问题仍然存在。
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);
});
});
当我从前端,HTML标签中调用媒体文件(无论是图像还是视频)时,一切正常。但是,如果我直接在浏览器中加载视频(再次,从1.5mb到最大6mb的小视频),服务器进程会冻结。更清楚一点:我在Windows上测试,服务器应用程序(server.js)在控制台中运行。控制台和正在运行的进程是冻结的。我无法在节点应用程序中加载任何更多的页面/视图,我甚至无法停止/终止/关闭节点应用程序或控制台。