Java WebCam Streaming через TCP Socket, перенаправляя последовательности изображений клиент-получатель - PullRequest
0 голосов
/ 06 мая 2018

Заранее спасибо за ваше время и усилия! В настоящее время я создаю приложение для обмена мгновенными сообщениями и включаю функцию потоковой передачи веб-камеры через API веб-камеры Sarxos от Github. Реализация моего приложения состоит в том, что другой поток в операционной системе компьютера, на котором запущено приложение сервера, открывается всякий раз, когда клиент принимается, а клиенты хранятся в базе данных MySql. Я еще не изучил мультиплексирование ввода-вывода, поэтому пока придерживаюсь этой реализации.

Что касается потоковой передачи с веб-камеры, я могу отправлять изображения из клиентского приложения в серверное приложение, а серверное приложение получает последовательность изображений и воспроизводит видео очень хорошо и без задержек.

Однако моя проблема в том, чтобы перенаправить эти последовательности изображений (видео) с сервера на указанный клиент, для которого клиент, инициирующий поток, желает начать видеочат.

Я перепробовал слишком много реализаций для перечисления, но вот мой текущий код:

ЗАЯВКА КЛИЕНТА:

    Thread t1 = new Thread() {
        @Override
        public void run() {
            while (true) {
                BufferedImage frame = webCam.getImage();
                int frameWidth = frame.getWidth();
                int frameHeight = frame.getHeight();

                try {
                    videoOutputStream.writeInt(frameWidth);
                    videoOutputStream.writeInt(frameHeight);

                    int[] pixelData = new int[frameWidth * frameHeight];
                    frame.getRGB(0, 0, frameWidth, frameHeight, pixelData, 0, frameWidth);
                    for (int i = 0; i < pixelData.length; i++) {
                        videoOutputStream.writeInt(pixelData[i]);
                    }
                     Thread.sleep(20);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };
    t1.start();

ПРИМЕНЕНИЕ СЕРВЕРА:

      BufferedImage frame; 

        while (true) {

    //Client who is SENDING images via webcam is using the "videoInputStream" object 
    //Client who is RECEIVING these images is using the "recipientVideoOutputStream" object 

DataOutputStream recipientVideoOutputStream = c.getVideoOutputStream(); 
                int frameWidth = videoInputStream.readInt(); 
                int frameHeight = videoInputStream.readInt();

                frame = new BufferedImage(frameWidth, frameHeight, BufferedImage.TYPE_INT_RGB);

                recipientVideoOutputStream.writeInt(frameWidth);
                recipientVideoOutputStream.writeInt(frameHeight);

                int[] pixelData = new int[frameWidth * frameHeight];
                for (int i = 0; i < pixelData.length; i++) {
                    pixelData[i] = videoInputStream.readInt();
                }

                for (int i = 0; i < pixelData.length; i++) {
                    recipientVideoOutputStream.writeInt(pixelData[i]); //This is where we write/re-direct the images as bytes to the receiving client
                }
            }

И, теперь, код для клиентского приложения, когда оно ПОЛУЧАЕТ видеопоток, который был отправлен клиент-сервер, и сервер теперь перенаправляет изображения указанному клиентскому получателю:

            Thread t1 = new Thread() {
                @Override
                public void run() {
                    int frameWidth;
                    int frameHeight;
                    int[] pixelData;
                    BufferedImage frame;
                    Image imagefx;

                    while (true) {

                        try {
                            frameWidth = videoInputStream.readInt();
                            frameHeight = videoInputStream.readInt();
                            pixelData = new int[frameWidth * frameHeight];

                            for (int i = 0; i < pixelData.length; i++) {
                                pixelData[i] = videoInputStream.readInt();
                                System.out.println("CLIENT READING PIXEL DATA " + pixelData[i]);
                            }

                            frame = new BufferedImage(frameWidth, frameHeight, BufferedImage.TYPE_INT_RGB);
                            frame.setRGB(0, 0, frameWidth, frameHeight, pixelData, 0, frameWidth);

                            imagefx = SwingFXUtils.toFXImage(frame, null);
                            System.out.println("CLIENT GOT IMAGE " + imagefx);
                            videoStreamStage.updateImage(imagefx); //Sets the image for the client's stage showing the streamed video, this is within a Platform.runLater()
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };

В настоящее время клиент-получатель видит около 1 кадра перед сбоем с NegativeArraySizeException, иногда рядом с исключением кучи памяти. Я могу передать изображения, отрисовывающие видео с клиент-сервера, без проблем, но перенаправление видеопотока другому клиенту съело все мои выходные и, к сожалению, безуспешно.

(РЕДАКТИРОВАТЬ): NegativeArraySizeException генерируется при выполнении следующей строки в клиентском приложении (клиент, который получает потоковые изображения):

pixelData = new int[frameWidth * frameHeight];

Как мне перенаправить эти изображения указанному клиенту-получателю, и возможно ли это с моей реализацией в ее нынешнем виде?

Еще раз спасибо за ваше время!

...