【问题标题】:Java Stream Video EfficientJava 流视频高效
【发布时间】:2021-01-24 22:52:10
【问题描述】:

我正在尝试使用 Sockets 为我的宠物构建一个相机应用程序。我的应用程序可以运行,但速度极慢,FPS 低且分辨率低。我已经尽我所能,但它仍然非常滞后。有没有比 Socket 更有效的视频传输方式?像 YouTube 这样的东西就像一个魅力。他们是怎么做到的?

这是我的摄像头服务器代码

public static void main(String[] args) throws IOException {
    cam = Webcam.getDefault();

    //cam.setCustomViewSizes(new Dimension(1080, 2340));
    cam.setViewSize(WebcamResolution.QVGA.getSize());


    cam.open();

    new Thread(() -> {
        try {
            camThread();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }).start();

    ServerSocket server = new ServerSocket(8886);

    while (true) {
        Socket client = server.accept();

        new Thread(() -> {
            handleConnection(client);
        }).start();
    }
}

public static void compressThread(byte[] input) throws IOException {

    img = Compressor.compress(input);

}

public static void camThread() throws IOException {
    while (true) {
        BufferedImage bufferedImage = cam.getImage();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "jpg", baos);

        new Thread(() -> {
            try {
                compressThread(baos.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

public static void handleConnection(Socket client) {
    try {
        OutputStream os = client.getOutputStream();
        InputStream is = client.getInputStream();

        while (client.isConnected()) {

            os.write(img);
            os.flush();

            while (is.available() == 0);
            is.read();

        }
    } catch (IOException ioe) {
        System.out.println(ioe.getMessage());
        try {
            client.close();
        }
        catch (Exception e) {e.printStackTrace();}

    }
}

还有我的应用客户端

while (client.isConnected) {
        while (`is`.available() == 0);

        val baos = ByteArrayOutputStream()

        var bytePre = 11111
        while (`is`.available() != 0) {
            val data = `is`.read()
            baos.write(data)
            if (data == -39) if (bytePre == -1) break
            bytePre = data
        }


        Thread {
            val bytes = baos.toByteArray()

            val bm = BitmapFactory.decodeByteArray(Compressor.decompress(bytes), 0, bytes.size)

            runOnUiThread { video.setImageBitmap(bm) }
        }.start()

        val os = client.getOutputStream()
        os.write(0)
        os.flush()



    }

    runOnUiThread { Toast.makeText(this, "Verbindung wurde geschlossen", Toast.LENGTH_LONG).show() }

【问题讨论】:

  • Socket.isConnected() 不会像您认为的那样做。特别是,它不会告诉您套接字是否当前“已连接”。此外,线程不会神奇地让一切变得更快。创建、运行和处置线程以在紧密循环中执行任务可能会涉及大量开销。考虑一个线程池或者可能是长寿命的线程。此代码似乎没有共享对象img 的同步访问权限。 camThread() 可能会产生两个或多个同时运行 compressThread 的线程,每个线程都试图写入imghandleConnection() 也访问 img 不安全。

标签: java android sockets camera video-streaming


【解决方案1】:

您不应该按字节阅读,我认为等待传入字节的繁忙循环可以使用 Thread.sleep(10) 来减少 CPU 的压力。

尝试在您的read() 中使用is.available() 的结果。

请在此处查看此答案以了解您可以使用的实现:

How to read all of Inputstream in Server Socket JAVA

【讨论】:

    猜你喜欢
    • 2012-08-23
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    相关资源
    最近更新 更多