2016-03-22 21 views
11

Yani, tuhaf bir sorun. Mongo'da base64 dizeleri olarak kaydedilmiş bir dizi medya dosyası var, bazıları görüntü, bazıları video. Düğüm/express ile BASE64 videosunu göster

Ortam dosyalarını almak için bir API yaptı:
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); 
     }); 
}); 

Şimdi, görüntüler sorunumuz yok. Onlar API sadece ince, hem doğrudan yükleyin ve ben bir ön ucundan API çağırdığınızda

SORUN

(örneğin <img src="/api/media/23498423"> için) ben gibi, bir ön uç bir video algetir görüntüler - ama video- veya nesne etiketi ile: hiçbir sorun, ama

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

ben API doğrudan bir tarayıcıda videoyu yüklerseniz:

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

sunucu proc ess çöküyor, hata yok. Sadece donuyor. Ve büyük video dosyaları hakkında konuşmuyoruz - bu bir 1,5MB video.

Şu anda test ettiğim tüm videolar için başlıktaki ortam türü video/mp4. Oh, ve sadece açıklığa kavuşmak gerekirse: eğer görüntüleri aynen yaparsam, her şey mükemmel çalışır.

DÜZENLEME

: bu kesinlikle kullandığım olması gereken ben gridfs ve gridfs-stream bir göz attım ve benim app amacıyla @idbehold önerdiği şekilde ve @zeeshan,

tamamdır ilk sırada. Ancak, uygulamamdaki gridfleri uyguladıktan sonra sorun hala devam ediyor.

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); 
    }); 
}); 

Ben medya dosyasını çağırır

HTML etiketi içinde, her şey güzel çalışır, bir ön-ucundan (o resim veya video olun). Ancak doğrudan tarayıcıya bir video yüklerseniz (yine 1,5mb'den maksimum 6mb'ye kadar küçük boyutlu videolar), sunucu işlemi donuyor. Biraz daha açık olmak gerekirse: Windows üzerinde test yapıyorum ve sunucu uygulaması (server.js) konsolda çalıştırılıyor. Konsol ve çalıştırdığı işlem donuyor. Düğüm uygulamasında daha fazla sayfa/görüntü yükleyemiyorum ve düğüm uygulamasını veya konsolu durdurup/kes/kapatamıyorum.

+0

Bir 1,5MB video dosyası için artık “res.end (dosya)” adını verdiğinizde 3MB belleğe sahip olacaksınız. Videoyu, arabelleğe alınmadan doğrudan "res" olarak yayınlamalısınız. Mongo GridFS ve akış API'sı gibi bir şey kullanmalısınız. Büyük olasılıkla bayt aralığı istekleri için de destek eklemeniz gerekecek. – idbehold

+0

Izgaraları bilmiyordum, bir bakacağım, teşekkürler. –

+0

Evet, [GridStore API] (https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md) kullanmak isteyeceğiniz şeydir. – idbehold

cevap

7

Canlı video doğrudan/kullanarak GridFS gelen gridfs-stream ya mongodb-yerli db örneğiyle veya firavunfaresi. tam dosya ve çalışan proje için

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); 
}); 

:

Klon direct_upload_gridfs düğüm-hile, npm install express mongodb gridfs-stream ardından node app çalıştırın. Gerçekten garip bir sorun

4

...
Ben yolu kapalı olabilir, ama denemeye değer: farkların

Bir doğrudan tarayıcıdan bir url açma tarayıcı da almaya çalışacağız olmasıdır http://localhost:8080/favicon.ico (sekme simgesini bulmaya çalışırken).Belki de sorun video kodunuzla ilgili değil, başka bir rotaya, /favicon.ico isteğini ele almaya çalışıyor?

wget veya curl kullanmayı denediniz mi?

+0

Bu incelemeye değer. İyi arama. –

+0

Bazı kapsamlı testler yaptım ve uygulama sürecinin çöktüğü örneklerin hiçbirinde favicon.ico getirilmesiyle ilgili herhangi bir sorun yaşanmadı - bu iyi bir öneriydi, bu yüzden +1 bunun için :) –

2

Cevabı bilmiyorum, belki bu aptal bir öneridir, ancak kullandığınız tarayıcı nedir? Belki de Microsoft'tan gelen bir sorun, sorun çıkarır ...

+0

Ben krom, firefox, firefox dev'de test ediyorum opera, ie9 + 10, ve aynı sonuca sahip kenar, ayrıca android krom –