Итак, бит нечетной проблемы. У меня есть куча медиа файлов, сохраненных в виде строк base64 в mongo, некоторые из них - изображения, а некоторые - видео.
Я создал 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 из front-end (например <img src="/api/media/23498423">
)
ПРОБЛЕМА
Если я получаю видео с интерфейсного интерфейса, например изображения, но с видео- или объектным тегом:
<video src="/api/media/3424525" controls></video>
нет проблем, но если я загружу видео в браузере непосредственно из API:
http://localhost:8080/api/media/3424525
происходит сбой сервера, никаких ошибок. Он просто замерзает. И мы не говорим о огромных видеофайлах - это 1,5 МБ видео.
Тип мультимедиа в заголовке для всех видео, которые я тестирую, составляет video/mp4
. О, и просто чтобы быть ясным: если я делаю то же самое с изображениями, все работает отлично.
EDIT:
Хорошо, так, как это было предложено @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);
});
});
Когда я вызываю мультимедийный файл (будь то изображение или видео) из front-end, в теге HTML все работает отлично. Но если я загружу видео (опять же, небольшие видеоролики размером от 1,5 до 6 макс.) Прямо в браузере, серверный процесс зависает. Быть немного более ясным: я тестирую на окнах, а серверное приложение (server.js) запускается в консоли. Консоль и выполняемый ею процесс замерзают. Я не могу загрузить больше страниц/представлений в приложение node, и я не могу даже остановить/убить/выключить приложение node или консоль.