gpt4 book ai didi

java - java中的TCP网络摄像头流

转载 作者:可可西里 更新时间:2023-11-01 02:53:47 26 4
gpt4 key购买 nike

感谢阅读,提前为我的英语不好道歉。

我正在使用 OpenCV 进行网络摄像头流式处理。我的最终目标是制作类似 Skype 的应用程序。所以我首先尝试基本的 1:1 TCP 模型。

关于TCP 1:1模型,
连接后,客户端发送其实时网络摄像头帧,服务器接收并在其 jpanel 上显示。

到目前为止,我确实收到了一张图片并在 jpanel 上显示了它。
我正在尝试接收连续的帧。
起初,问题是服务器端套接字似乎在等待客户端输入完成,即它永远不会停止,因为实时帧是连续发送的。
所以我在发送帧之前发送了每个帧大小,以逃避无法停止的等待。
但效果不佳。客户端不断发送帧,但服务器接收不到。
例如,如果客户端发送大约 25k 字节大小的帧,服务器每次读取仅接收 1 到 3 个字节,即使缓冲区大小为 512。

客户端线程.java

package client;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.imageio.ImageIO;

import video.VideoCap;

public class ClientThread extends Thread
{

String serverIp;
int serverPort;
Socket socket;
VideoCap videoCap;

public ClientThread(Socket socket, String serverIp, int serverPort, VideoCap videoCap)
{
this.socket = socket;
this.serverIp = serverIp;
this.serverPort = serverPort;
this.videoCap = videoCap;
}

public void run()
{
while (ClientUI.calling)
{
try
{
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);

// receive
int bufSize = dis.readInt();
while (ClientUI.calling)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(videoCap.getOneFrame(), "jpg", baos);
InputStream inputImage = new ByteArrayInputStream(baos.toByteArray());

// frame size
dos.writeInt(baos.size());
out(inputImage, baos, bufSize);
Thread.sleep(5000);
}

}
catch (IOException | InterruptedException e)
{
e.printStackTrace();
}
}
}

void out(InputStream in, OutputStream out, int bufSize)
{
long size = 0;
try
{
byte[] buf = new byte[bufSize];
int n;
while ((n = in.read(buf)) > 0)
{
out.write(buf, 0, n);
size += n;
System.out.println("size: " + size);
}
}
catch (IOException e)
{
e.printStackTrace();
}

finally
{
System.out.println(getClass().getName() + " :: out >>> sent size: " + size);
}
}
}

服务器线程.java

package server;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ServerThread extends Thread
{
ServerSocket serverSocket;
Socket socket;
JPanel panel;
byte[] buf;

public ServerThread(ServerSocket serverSocket, JPanel panel, int bufSize)
{
this.serverSocket = serverSocket;
this.panel = panel;
buf = new byte[bufSize];
}

public void run()
{
try
{
System.out.println("waiting for client");
socket = serverSocket.accept();
System.out.println("client accepted");
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.writeInt(buf.length);

while (ServerUI.calling)
{
int frameSize = dis.readInt();
ByteArrayOutputStream outImage = new ByteArrayOutputStream();
long size = 0;
int n;

while (frameSize >= size)
{
n = dis.read(buf);
if (n == -1)
break;
outImage.write(buf, 0, n);
size += n;
System.out.println(n);

}

InputStream inputImage = new ByteArrayInputStream(outImage.toByteArray());
BufferedImage bufferedImage = ImageIO.read(inputImage);
panel.getGraphics().drawImage(bufferedImage, 0, 0, null);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}

}

最佳答案

我将 DataOutput/InputStream 更改为 ObjectOutput/InputStream。我不确定为什么不顺利,但我想这是因为序列化问题。但是 byte 不需要序列化,所以我不太清楚。

我将提供无论如何工作的代码。因为AudioServer我分成了两个Thread所以前面的代码和下面的代码有很大的不同。

VideoServerThread.java

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class VideoServerThread extends Thread
{
private ServerSocket serverSocket;
int videoServerPort;
private Socket socket;
private JPanel panel;
private boolean calling;

public VideoServerThread(ServerSocket serverSocket, int videoServerPort, JPanel panel, boolean calling)
{
this.serverSocket = serverSocket;
this.videoServerPort = videoServerPort;
this.panel = panel;
this.calling = calling;
}

@Override
public void run()
{
System.out.println("Video Server opened!");
try
{
serverSocket = new ServerSocket(videoServerPort);
socket = serverSocket.accept();
InputStream in = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(in);
BufferedImage bufferedImage;
InputStream inputImage;
Frame f;
while (calling)
{
f = (Frame) ois.readObject();
inputImage = new ByteArrayInputStream(f.bytes);
bufferedImage = ImageIO.read(inputImage);
panel.getGraphics().drawImage(bufferedImage, 0, 0, panel.getWidth(), panel.getHeight(), null);
panel.getGraphics().drawImage(bufferedImage, 0, 0, null);
bufferedImage.flush();
inputImage.close();
f = null;
}

}

catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}

class Frame implements Serializable
{
public byte[] bytes;
public Frame(byte[] bytes)
{
this.bytes = bytes;
}

public int size()
{
return bytes.length;
}
}
}

VideoClientThread.java

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.imageio.ImageIO;
import common.Frame;
import video.VideoCap;

public class VideoClientThread extends Thread
{
private final String formatType = "jpg";
private VideoCap videoCap;
private Socket socket;
private String ip;
private int port;
private boolean calling;

public VideoClientThread(VideoCap videoCap, Socket socket, String ip, int port, boolean calling)
{
this.videoCap = videoCap;
this.socket = socket;
this.ip = ip;
this.port = port;
this.calling = calling;
}

public void run()
{
try
{
socket = new Socket(ip, port);
socket.setSoTimeout(5000);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
Frame f;
BufferedImage bufferedImage;
while (calling)
{
ByteArrayOutputStream fbaos = new ByteArrayOutputStream();
bufferedImage = videoCap.getOneFrame();
ImageIO.write(bufferedImage, formatType, fbaos);
f = new Frame(fbaos.toByteArray());
oos.writeObject(f);
oos.flush();
bufferedImage.flush();
// Thread.sleep(33);
}
}
catch (IOException e)
{
e.printStackTrace();
}
// catch (InterruptedException e)
// {
// e.printStackTrace();
// }
}
}

关于java - java中的TCP网络摄像头流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43276792/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com