java - 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 正在检查网络摄像头。它运行良好,但无法发送图像。如何连续接收全部数据?请找出问题。
解决方案
你声明一个包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 进行文件传输。可靠,包裹订单有保障。
推荐阅读
- c++ - 模棱两可的函数模板
- javascript - 函数仅在按钮单击中调用一次。希望每次单击按钮都执行该功能
- c++ - 为什么我的 Rcpp 代码比 glmnet 慢得多?
- mysql - 如何加快 Rails 中的 find_or_initialize?
- python - 如何在 Python 中关闭类的另一个函数内的文件?
- javascript - Redux-saga 不能在 Promise 中使用生成器函数?
- ruby-on-rails - 如何从 Visual Studio Code 运行和调试 Ruby on Rails?
- python - Django查询 - 在过滤器中结合两种不同的情况
- c++ - VlcQt 中对函数的未定义引用(安装后)
- python - 按索引访问熊猫系列时出错