Mis*_*ith 6 java screenshot video-capture video-encoding
我在远程管理玩具项目中工作.现在,我可以使用Robot该类捕获屏幕截图并控制鼠标.截图是BufferedImage实例.
首先,我的要求: - 只有服务器和客户端. - 性能很重要,因为客户端可能是Android应用程序.
我想过打开两个套接字连接,一个用于鼠标和系统命令,另一个用于视频输入.
如何将屏幕截图转换为视频流?我应该将它们转换为已知的视频格式,还是可以发送一系列序列化图像?
压缩是另一个问题.根据我的初步测试,以全分辨率发送屏幕捕获将导致低帧速率.我认为我需要至少24 fps来感知运动,所以我要同时缩小和压缩.我可以转换BufferedImages为jpg文件,然后设置压缩率,但我不想将文件存储在磁盘上,它们应该只存在于RAM中.另一种可能性是将实例(表示未压缩的屏幕截图)序列化为GZipOutputStream.这是正确的方法是什么?
总结一下:
OutputStream?提前致谢.
更新:我的测试,客户端和服务器在同一台机器上
- 全屏幕序列化BufferedImages(只有维度,类型和int []),没有压缩:1.9 fps.
通过GZip流的完整屏幕图像:2.6 fps.
-Downscaled图像(640宽度)和GZip流:6.56 fps.
- 全屏幕图像和RLE编码:4.14 fps.
-Downscaled图像和RLE编码:7.29 fps.
如果它只是屏幕捕获,我不会使用视频压缩方案压缩它们,很可能你不想要有损压缩(小文本中的模糊细节等是最常见的缺陷).为了获得可行的"远程桌面"感觉,请记住先前发送的屏幕截图并仅发送差异以进入下一个.如果帧之间没有(或很少)改变,这是非常有效的.然而,在诸如播放视频,游戏或在文档中滚动很多的某些情况下,它将无法正常工作.
压缩两个BufferedImage之间的差异可以使用或多或少的复杂方法来完成,一个非常简单但相当有效的方法是简单地从另一个中减去一个图像(在它们相同的地方产生零)并用简单的RLE压缩结果(运行长度编码).
降低颜色精度可用于进一步减少数据量(取决于用例,您可以省略每个颜色通道的最低有效N位,因为如果将颜色从24位减少到15位,大多数GUI应用程序看起来差别不大位).
// server start
sendScreenMetaToClient(); // width, height, how many grid squares
...
// server loop ImageBuffer[] prevScrnGrid while(isRunning) {
ImageBuffer scrn = captureScreen();
ImageBuffer[] scrnGrid = screenToGrid(scrn);
for(int i = 0; i < scrnGrid.length; i++) {
if(isSameImage(scrnGrid[i], prevScrnGrid[i]) == false) {
prevScrnGrid[i] = scrnGrid[i];
sendGridSquareToClient(i, scrnGrid[i]); // send the client a message saying it will get grid square (i) then send the bytes for grid square (i)
}
} }
Run Code Online (Sandbox Code Playgroud)
不发送序列化的java对象只是发送图像数据.
ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();
ImageIO.write( bufferedImage, "jpg", imgBytes );
imgBytes.flush();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2050 次 |
| 最近记录: |