Quindi, un piccolo problema. Ho un sacco di file multimediali salvati come stringhe base64 in mongo, alcuni sono immagini, alcuni sono video.Mostra video BASE64 con nodo/espresso
ho fatto un'API per ottenere i file multimediali:
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);
});
});
Ora, le immagini non hanno problemi. Caricano bene, sia direttamente dalla API, e quando chiamo l'API da un front-end (per esempio <img src="/api/media/23498423">
)
PROBLEMA
Se prelevo una video da un front-end, come la immagini - ma con un video-o object-tag:
<video src="/api/media/3424525" controls></video>
non c'è nessun problema, ma se carico il video in un browser direttamente dal API:
http://localhost:8080/api/media/3424525
server proc ess si blocca, nessun errore. Semplicemente si blocca. E non stiamo parlando di enormi file video: è un video da 1,5 MB.
Il tipo di supporto nell'intestazione per tutti i video con cui sto eseguendo il test è video/mp4
. Oh, e tanto per essere chiari: se faccio lo stesso con le immagini, tutto funziona perfettamente.
EDIT:
Va bene, così come suggerito da @idbehold e @zeeshan ho preso uno sguardo al GridFS e GridFS-stream, e per lo scopo della mia app, questo è certamente quello che avrei dovuto usare innanzitutto. Tuttavia, dopo aver implementato gridfs nella mia app, il problema persiste.
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);
});
});
Quando chiamo il file multimediale (sia esso immagine o video) da un front-end, all'interno di un tag HTML, tutto funziona bene. Ma se carico un video (di nuovo, video piccolissimi da 1.5mb a un massimo di 6mb di dimensione totale) direttamente nel browser, il processo del server si blocca. Per essere un po 'più chiaro: sto testando su Windows, e l'app del server (server.js) viene eseguita in console. La console e il processo in esecuzione è ciò che si blocca. Non riesco a caricare altre pagine/viste nell'app del nodo e non riesco nemmeno a interrompere/uccidere/arrestare l'app nodo o la console.
Per un file video da 1,5 MB ora avrai 3MB in memoria nel momento in cui chiami 'res.end (file)'. Dovresti trasmettere il video direttamente a 'res' senza buffering. Dovresti usare qualcosa come GridFS di Mongo e la sua API di streaming. Probabilmente dovrai aggiungere anche il supporto per le richieste dell'intervallo di byte. – idbehold
Non conoscevo la griglia, avrò un'occhiata, grazie. –
Sì, [l'API GridStore] (https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md) è ciò che vorrete usare. – idbehold