所以,有点奇怪的问题。我有一堆媒体文件在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)在控制台中运行。控制台和它正在运行的进程是冻结的。我无法在节点应用程序中加载任何更多的页面/视图,我甚至无法停止/终止/关闭节点应用程序或控制台。
答案 0 :(得分:7)
使用{em> mongodb-native db instance 或 mongoose 使用gridfs-stream直接将数据流式传输到GridFS或从GridFS流式传输。
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);
});
表示完整文件和正在运行的项目:
克隆节点作弊direct_upload_gridfs,运行node app
后跟npm install express mongodb gridfs-stream
。
答案 1 :(得分:4)
真的是一个奇怪的问题...... 我可能会离开,但它值得一试:
直接从浏览器打开网址时的一个不同之处是,浏览器还会尝试获取http://localhost:8080/favicon.ico
(尝试查找标签图标时)。也许问题与您的视频代码无关,而是与其他路线有关,试图处理/favicon.ico
请求?
您是否尝试过使用wget
或curl
?
答案 2 :(得分:2)
我不知道答案,也许这是一个愚蠢的建议,但你使用的是什么浏览器?也许微软的某些东西导致了这个问题......