0

我正在我的 Android 手机上创建一个程序,将相机的输出发送到同一网络上的服务器。这是我的Java代码:

camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {

    public void onPreviewFrame(byte[] data, Camera cam) {

        try {
            socket = new Socket("XXX.XXX.XXX.XXX", 3000);
            out = socket.getOutputStream();
            out.write(data);
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        camera.addCallbackBuffer(data);
        }

服务器是 NodeJS 服务器:

time = 0

video_server.on 'connection', (socket) ->
    buffer = []
    socket.on 'data', (data) ->
            buffer.push data
    socket.on 'end', ->
            new_time = (new Date()).getTime()
            fps = Math.round(1000/(new_time - time)*100)/100
            console.log fps
            time = new_time

            stream = fs.createWriteStream 'image.jpg'
            stream.on 'close', ->
                    console.log 'Image saved.', fps
            stream.write data for data in buffer
            stream.end()

我的终端显示大约 1.5 fps (5 Mbps)。我对网络编程知之甚少,但我知道绝对应该有足够的带宽。每张图像为 640x480x1.5,速度为 18 fps,约为 63 Mbps。本地网络应该很容易处理这个问题,但是我在 Android 中的调试器给了我很多“连接被拒绝”的消息。

任何有助于解决我的不良网络做法的帮助都会很棒。(我稍后会进行图像压缩——但现在我需要优化这一步)。

4

2 回答 2

5

你已经设计了这个系统,使它必须做的工作比它应该做的要多很多倍。您需要为传输的每个帧建立和拆除连接。这不仅会扼杀您的吞吐量,还会耗尽您的资源。

使用合理的设计,传输帧所需的只是发送和接收帧数据。在您的设计中,对于每一帧,都必须建立一个 TCP 连接(3 个步骤),必须发送和接收帧数据,并且必须断开 TCP 连接。更糟糕的是,在连接关闭发生之前,接收器无法知道它已接收到所有帧数据。所以这不能隐藏在后台。

设计一个合理的协议,问题就会消失。

于 2012-08-23T02:30:12.907 回答
1

这真的有效吗?我看不到您绑定到服务器上端口 3000 的位置。

无论如何,如果这是一个视频流,您可能应该使用 UDP 而不是 TCP。在 UDP 中,可能会丢弃数据包,但对于视频流,这可能不会引起注意。由于交换的消息数量,UDP 通信所需的开销比 TCP 少得多。TCP 包含很多“确认”,以确保每条数据都到达目的地;UDP 不在乎,因此发送的数据包更少。根据我的经验,基于 UDP 的代码通常不如基于 TCP 的代码复杂。

_瑞安

于 2012-08-22T22:42:02.027 回答