繁体   English   中英

如何连续接收 UDP 网络摄像头流?

[英]How to receive UDP Webcam stream continuously?

服务器

try {
        DatagramSocket socket = new DatagramSocket(4242);
    
    
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        WebcamPanel panel = new WebcamPanel();

        JFrame window = new JFrame("Test webcam panel");
        window.add(panel);
        window.setSize(500, 500);
        window.setResizable(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
        
        while(true){
            socket.receive(packet);
            System.out.println("received");
            byte[] buff = packet.getData();
            ByteArrayInputStream bain = new ByteArrayInputStream(buff);
            panel.DrawImage(ImageIO.read(bain));
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

客户

try{
        DatagramSocket socket = new DatagramSocket();
        InetAddress address = InetAddress.getByName("localhost");
        
        Webcam webcam = Webcam.getDefault();
        webcam.setViewSize(WebcamResolution.VGA.getSize());
        
        WebcamPanel panel = new WebcamPanel(webcam);
        panel.setFPSDisplayed(true);
        panel.setDisplayDebugInfo(true);
        panel.setImageSizeDisplayed(true);
        panel.setMirrored(true);

        JFrame window = new JFrame("Test webcam panel");
        window.add(panel);
        window.setResizable(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.pack();
        window.setVisible(true);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        while(true){
            ImageIO.write(webcam.getImage(),"jpg", baos);
            baos.flush();
            byte[] image_buffer = baos.toByteArray();
            System.out.println(image_buffer.length);
            DatagramPacket packet = new DatagramPacket(image_buffer, image_buffer.length, address, 4242);
            socket.send(packet);
            
        }
        
    }catch(Exception e){
        e.toString();
    }

控制台->客户端:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
20884
41796
62687
83582

控制台->服务器:

received
received
received

服务器无法接收完整的数据。 它接收到三个数据并停止。 我不明白为什么服务器停止了。 客户端中的 Webcampanel 正在检查网络摄像头。 它运行良好,但无法发送图像。 如何连续接收全部数据? 请找出问题。

你声明一个1024 bytes的包

byte[] buffer = new byte[1024];

在您的服务器中,您正在读取每个包并将其视为一个整体图像:

byte[] buff = packet.getData(); // This is not a whole image yet
ByteArrayInputStream bain = new ByteArrayInputStream(buff);
panel.DrawImage(ImageIO.read(bain));

例如,第一个图像的长度为20884 ,因此重建图像至少需要20884/1024 + 1包。

如果您检查服务器日志,我认为当图像未完全构建并用于绘制到窗格时,您会看到某种运行时异常。

为了接收整个包并重建图像,您需要知道如何在服务器上检测文件结尾。

但从技术上讲,UDP 协议是不可靠的,您可能会丢失一些包裹,您收到的包裹顺序与发送时的顺序不同。 所以用UDP很难做到这一点。

我建议使用 TCP 进行文件传输。 可靠,包裹订单有保障。

改变这个

ByteArrayOutputStream baos = new ByteArrayOutputStream();

    while(true){
        ImageIO.write(webcam.getImage(),"jpg", baos);
        baos.flush();
        byte[] image_buffer = baos.toByteArray();
        // ...
   }

对此:

    while(true){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(webcam.getImage(),"jpg", baos);
        baos.flush();
        byte[] image_buffer = baos.toByteArray();
        // ....
    }

这对我有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM