Заранее спасибо за ваше время и усилия!
В настоящее время я создаю приложение для обмена мгновенными сообщениями и включаю функцию потоковой передачи веб-камеры через 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];
Как мне перенаправить эти изображения указанному клиенту-получателю, и возможно ли это с моей реализацией в ее нынешнем виде?
Еще раз спасибо за ваше время!