2016-03-22 52 views
11

所以,有點奇怪的問題。我有一堆媒體文件保存爲mongo中的base64字符串,其中一些是圖像,一些是視頻。顯示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-或對象標籤:

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

有沒有問題,但如果我在瀏覽器中直接從API加載視頻:

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

服務器PROC ess崩潰,沒有錯誤。它只是凍結了。我們並不是在談論大量的視頻文件 - 它是一個1.5MB的視頻。

我正在測試的所有視頻的標頭中的媒體類型爲video/mp4。哦,只是要清楚:如果我對圖像做同樣的事情,一切都完美無缺。

編輯:

好了,所以通過@idbehold的建議和@zeeshan我看了看GridFS的和GridFS的流,併爲我的應用程序的目的,這肯定是我應該用首先。但是,在我的應用程序中實現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

對於一個1.5MB的視頻文件,你現在有3MB的內存在你調用'res.end(file)'的時候。您應該直接將視頻直接傳輸到「res」,無需緩衝。您應該使用Mongo的GridFS及其流媒體API。您可能還必須添加對字節範圍請求的支持。 – idbehold

+0

我不知道網格,我會看看,謝謝。 –

+0

是的,[GridStore API](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md)是你想要使用的。 – idbehold

回答

7

視頻流至/從使用GridFS的gridfs-stream或者與mongodb的天然分貝實例貓鼬

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

4

真是一個奇怪的問題...
我可能是遙遠,但它是值得一試:直接從瀏覽器中打開一個URL時

其中一個不同是,瀏覽器也會嘗試獲取http://localhost:8080/favicon.ico(嘗試查找標籤圖標時)。也許問題與您的視頻代碼無關,而是與其他路線有關,試圖處理/favicon.ico請求?

您是否嘗試過使用wgetcurl

+0

這值得研究。好決定。 –

+0

我做了一些廣泛的測試,在應用程序進程崩潰的任何情況下都沒有提取favicon.ico的任何問題 - 雖然這是一個很好的建議,所以爲+1 :) –

2

我不知道答案,也許這是一個愚蠢的建議,但你使用的是什麼瀏覽器?也許從微軟的東西導致這個問題...

+0

我測試在Chrome,Firefox,Firefox的開發,opera,ie9 + 10,以及相同的結果,也在android chrome上 –