2012-12-26 66 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浏览器支持)。