私の悪い英語を読んで、申し訳ありません。TCPウェブカメラのストリーミング
私はOpenCVでウェブカメラストリーミングに取り組んでいます。 私の最終的な目標はSkypeのようなアプリケーションを作ることです。 私は最初に基本的な1:1 TCPモデルを試しています。
TCP 1:1モデルについて
接続後、クライアントはリアルタイムWebカメラフレームを送信し、サーバーは受信してjpanelに表示します。
これまで画像を受信してjpanelに表示しました。
私は連続したフレームを受信しようとしています。
最初は、サーバーサイドソケットは、クライアントからの入力が完了するまで待機するように見えました。つまり、リアルタイムフレームが連続して送信されるため停止しませんでした。
私は止められないのを待つことから脱出するためにフレームを送る前にすべてのフレームサイズを送った。
しかし、うまくいきません。クライアントはフレームを送信し続けますが、サーバーはそれをうまく受信しません。
例えば、クライアントは約25Kバイトサイズのフレームを送信する場合、サーバは読み取り専用1あたり1〜3バイトを受信しても、バッファサイズは512
あるClientThread.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);
}
}
}
ServerThread.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();
}
}
}
なぜクライアントにBUFSIZEを送信するサーバ? –
@SteveSmithバッファのサイズが同じであれば、データの送受信量は同じになると思いました。 – Bana