首页 > 解决方案 > UDP 网络摄像头流式传输 (JAVA)

问题描述

服务器

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 正在检查网络摄像头。它运行良好,但无法发送图像。如何连续接收全部数据?请找出问题。

标签: javaudpwebcam

解决方案


你声明一个包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 进行文件传输。可靠,包裹订单有保障。


推荐阅读