8

在 linux 上使用 Motion,每个网络摄像头都在其自己的端口上作为流提供。我现在想使用 Node.js 在同一个端口上提供这些流。

  • 编辑:这个解决方案现在有效。我需要从原始 mjpeg 流中获取边界字符串(在我的 Motion 配置中是“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 流作为 /motion 提供,但事实并非如此。也许是因为它永远不会结束,而这个代理示例并不是真正的流式示例?

4

2 回答 2

2

通过 HTTP 流式传输不是问题。我经常用 Node 来做这件事。我认为您遇到的问题是您没有向客户端发送内容类型标头。实际上,您无需发送任何响应标头即可直接写入数据。

在发送任何实际内容数据之前,请务必将正确的内容类型标头发送回发出请求的客户端。

如果 Node 的 HTTP 客户端还没有为您处理,您可能需要处理多部分响应。

另外,我建议使用 Wireshark 进行调试,这样您就可以准确地看到发送和接收的内容。这将帮助您快速缩小此类问题的范围。

我还应该注意,一些客户端在分块编码方面存在问题,如果你不指定内容长度(你不能因为它是不确定的),这就是 Node 将发送的内容。如果您需要禁用分块编码,请在此处查看我的答案: https ://stackoverflow.com/a/11589937/362536 基本上,您只需要禁用它: response.useChunkedEncodingByDefault = false;。除非你需要,否则不要这样做!并确保Connection: close在您的标题中发送一个!

于 2012-12-26T04:07:44.563 回答
0

您需要做的是在需要时仅在一个线程中请求 mjpeg 流,并使用 mjpeg 或 jpeg 响应每个客户端(如果您需要 IE 支持)。

于 2014-01-03T09:34:00.390 回答