【发布时间】:2021-01-24 22:52:10
【问题描述】:
我正在尝试使用 Sockets 为我的宠物构建一个相机应用程序。我的应用程序可以运行,但速度极慢,FPS 低且分辨率低。我已经尽我所能,但它仍然非常滞后。有没有比 Socket 更有效的视频传输方式?像 YouTube 这样的东西就像一个魅力。他们是怎么做到的?
这是我的摄像头服务器代码
public static void main(String[] args) throws IOException {
cam = Webcam.getDefault();
//cam.setCustomViewSizes(new Dimension(1080, 2340));
cam.setViewSize(WebcamResolution.QVGA.getSize());
cam.open();
new Thread(() -> {
try {
camThread();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
ServerSocket server = new ServerSocket(8886);
while (true) {
Socket client = server.accept();
new Thread(() -> {
handleConnection(client);
}).start();
}
}
public static void compressThread(byte[] input) throws IOException {
img = Compressor.compress(input);
}
public static void camThread() throws IOException {
while (true) {
BufferedImage bufferedImage = cam.getImage();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", baos);
new Thread(() -> {
try {
compressThread(baos.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
public static void handleConnection(Socket client) {
try {
OutputStream os = client.getOutputStream();
InputStream is = client.getInputStream();
while (client.isConnected()) {
os.write(img);
os.flush();
while (is.available() == 0);
is.read();
}
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
try {
client.close();
}
catch (Exception e) {e.printStackTrace();}
}
}
还有我的应用客户端
while (client.isConnected) {
while (`is`.available() == 0);
val baos = ByteArrayOutputStream()
var bytePre = 11111
while (`is`.available() != 0) {
val data = `is`.read()
baos.write(data)
if (data == -39) if (bytePre == -1) break
bytePre = data
}
Thread {
val bytes = baos.toByteArray()
val bm = BitmapFactory.decodeByteArray(Compressor.decompress(bytes), 0, bytes.size)
runOnUiThread { video.setImageBitmap(bm) }
}.start()
val os = client.getOutputStream()
os.write(0)
os.flush()
}
runOnUiThread { Toast.makeText(this, "Verbindung wurde geschlossen", Toast.LENGTH_LONG).show() }
【问题讨论】:
-
Socket.isConnected()不会像您认为的那样做。特别是,它不会告诉您套接字是否当前“已连接”。此外,线程不会神奇地让一切变得更快。创建、运行和处置线程以在紧密循环中执行任务可能会涉及大量开销。考虑一个线程池或者可能是长寿命的线程。此代码似乎没有共享对象img的同步访问权限。camThread()可能会产生两个或多个同时运行 compressThread 的线程,每个线程都试图写入img。handleConnection()也访问img不安全。
标签: java android sockets camera video-streaming