2012-12-26 96 views
5

在linux上使用Motion,每個網絡攝像頭都在其自己的端口上作爲流提供服務。 我現在想要使用Node.js提供所有在同一端口上的流。通過Node.js代理管理MJPEG流

  • 編輯:此解決方案現在工作。我需要得到從原來的MJPEG流的邊界線(這是「BoundaryString」在我的運動配置)
 

app.get('/motion', function(req, res) { 

    var boundary = "BoundaryString"; 

    var options = { 
    // host to forward to 
    host: '192.168.1.2', 
    // port to forward to 
    port: 8302, 
    // path to forward to 
    path: '/', 
    // request method 
    method: 'GET', 
    // headers to send 
    headers: req.headers 
    }; 

    var creq = http.request(options, function(cres) { 

     res.setHeader('Content-Type', 'multipart/x-mixed-replace;boundary="' + boundary + '"'); 
     res.setHeader('Connection', 'close'); 
     res.setHeader('Pragma', 'no-cache'); 
     res.setHeader('Cache-Control', 'no-cache, private'); 
     res.setHeader('Expires', 0); 
     res.setHeader('Max-Age', 0); 

    // wait for data 
    cres.on('data', function(chunk){ 
     res.write(chunk); 
    }); 

    cres.on('close', function(){ 
     // closed, let's end client request as well 
     res.writeHead(cres.statusCode); 
     res.end(); 
    }); 

    }).on('error', function(e) { 
    // we got an error, return 500 error to client and log error 
    console.log(e.message); 
    res.writeHead(500); 
    res.end(); 
    }); 

    creq.end(); 

}); 
 

我認爲這在192.168.1.2:8302 MJPEG編碼流提供了AS /運動,但事實並非如此。 也許因爲它永遠不會結束,而這個代理例子並不是真正的流式例子嗎?

+0

你可以看看使用nginx代替。 – david

+2

它需要成爲一個節點解決方案 – skerit

回答

1

通過HTTP流式傳輸不是問題。我經常使用Node來做這件事。我認爲你遇到的問題是你沒有發送一個內容類型頭到客戶端。實際上,您無需發送任何響應標題即可寫入數據。

一定要正確的內容類型頭返回給客戶端發出請求,發送任何實際內容數據之前。

您可能需要handle multipart responses,如果節點的HTTP客戶端還沒有爲你做。

另外,我建議使用Wireshark調試這個,所以你可以看到什麼是被髮送和接收。這將有助於您快速縮小這類問題的範圍。

我也應該注意到,有些客戶有塊編碼,這是什麼,如果你不指定內容長度的節點會發送一個問題(你不能因爲它是不確定的)。如果您需要禁用分塊編碼,請參閱我的答案:https://stackoverflow.com/a/11589937/362536基本上,您只需要禁用它:response.useChunkedEncodingByDefault = false;。除非你需要,否則不要這樣做!並確保發送一個Connection: close在您的標題中!

+0

塊事件是mjpeg流的問題。我看到一個普通的JPEG流始終作爲一個整體部分。所以我應該等待整個幀,然後才發送給客戶端。 – skerit

+1

啊,找到它了!在我的響應頭文件中,我需要設置原始mjpeg流中使用的多部分邊界(在運動中,它總是與「BoundaryString」相同)。這樣我就可以將塊轉發,而無需向它自己添加任何數據。 – skerit

0

你需要做的是要求MJPEG流時,有必要就在一個線程和響應每個客戶端與MJPEG或JPEG(如果你需要IE瀏覽器支持)。