系统:windows 64位 (推荐windows 10 X64 20H2)
内存:4G或以上
CPU:双核或以上
显卡:GT1030或以上级别
显示器分辨率:1080P或以上,系统画面缩放最好调整为100%
文章内所有官方无法下载或下载困难的资源合集(永久有效):
提取码:8888
下载后解压到合适的目录,我选择的是D:jdk-17.0.1,然后加上环境变量
下载后解压到合适的目录,我选择的是D:javafx-sdk-17.0.1
下载后解压到合适的位置,我选择的是D:Program Filesapache-maven-3.8.4,打开根目录中的conf文件夹,找到setting.xml,编辑它
我把本地仓库设置为D盘的repo文件夹
用阿里的仓库
慢的同学可以用这个镜像,速度不错,解压到合适位置,我选择的是D:Program Fileseclipse
解压好后先不急打开eclipse,先打开eclipse目录,找到eclipse.ini文件,编辑它(允许eclipse访问jdk中的类)
直接下载,我把它放到了D盘根目录,然后运行cmd
选择你解压的eclipse路径,点击安装就可以了
打开首选项,修改好字符集
配置maven,就可以了
不停的下一步直到安装完成就可以了(可选)
这是个好东西,好像是一个叫Felix Roske的大佬写的(具体我也不知道),可惜多年没更新,目前官方最新版是2.1.7(未发版,发版的是2.1.6),只支持JDK1.8。我找到源码重新用JAVA17编译后,分析问题,魔改了下(后面我会说具体改了哪几个地方),就能用了。
提取码:8888
下载后到maven根目录的bin文件夹下,以管理员运行cmd,添加到本地maven仓库
这是个可选的UI拖拽控件。
提取码:8888
下载后opencv-4.5.5.jar到maven根目录的bin文件夹下,以管理员运行cmd,添加到本地maven仓库(这边就不截图了,参考上面的图)
将opencv_java455.dll到jdk根目录的bin文件夹下
提取码:8888
下载好后,把文件夹解压到eclipse的工作空间
如果项目出现红色感叹号,按如下方式操作:
按照此法导入(一个服务端,一个客户端),至此所有需要下载的东西都下完了。
i) 打包服务端、客户端
把打包后的文件到合适的地方,我把它放到了D: emote
客户端也按照上面的方法打包,然后到同一个目录
ii) 生成JRE17、javaFX17运行环境
以管理员身份运行cmd,输入如下命令:
会发现D: emote下生成了指定模块的JRE
把opencv_java455.dll到jre17根目录的bin目录下
把javafx-sdk-17.0.1文件夹也进来
进入javafx-sdk-17.0.1的bin目录中,把jfxwebkit.dll文件删除,没用到这个包,太占地方了
iii) 编写启动脚本
新建一个run_server.bat的文件,编辑它,输入如下内容,保存
再新建一个run_client.bat的文件,编辑它,输入如下内容,保存
双击run_server.bat,启动服务端,看到如下界面,说明启动成功
把快速编辑模式关闭,防止界面输出时阻塞程序
双击run_client.bat,启动客户端,同样的办法,关闭快速编辑模式,你也可以右键时直接设置默认值,默认开启cmd时关闭快速编辑模式(很重要)
点左上角的开启,剩下的就不说了
因为我客户端和服务端使用了不同的电脑,所以画面是正常的,你们服务端和客户端在一台电脑运行时,看到的画面应该是这样的:
注意:任务栏上有客户端右键退出按钮,直接关闭窗口默认隐藏到任务栏
找到服务端启动类,点击运行配置
如下启动参数(让程序启动时能够访问jdk的类,也可以把这部分直接配置在eclipse目录中的eclipse.ini文件中)
同理,找到客户端的启动类,如下参数(添加javaFX 运行时需要的模块)
注意:这里的--module-path,我配置的javaFX sdk是在D盘根目录,具体根据自己的实际情况调整。
修改服务端的端口,默认是8080,也可以自己自定义。如果修改了,就按照之前的方式重新打包,替换原来的RemoteServer-0.0.1-SNAPSHOT.jar文件
修改服务端的内网IP和端口。修改后,就按照之前的方式重新打包,替换原来的RemoteClient-0.0.1-SNAPSHOT.jar文件
修改好重新打包,替换完成以后的目录。现在服务端和客户端都依赖同一个环境运行,我们需要进行分离(其中jre17是服务端和客户端都需要的,javafx-sdk-17.0.1只有客户端需要)
创建2个文件夹remote_server和remote_client
按照如下方式把文件剪切、过去
现在服务端和客户端运行环境就分开了
把服务端进行简单打包(至于封装成安装包,不属于本文重点,就不讲了),服务端打包后只有43MB,并不大,把它到被控电脑(因为已经包含jre了,不需要安装jdk和其他环境),解压到任意目录,运行其中的run_server.bat
然后运行控制端的客户端run_client.bat,就可以了
首先被控电脑的端口需要映射到外网端口,然后配置跟局域网中的方法一样,客户端连接的IP需要换成外网IP和映射的外网端口即可(也可以在路由器开启DMZ主机(有安全隐患),并且路由WAN口地址属于三大运营商的外网IP,如果分配的是运营商虚拟内网IP,电信可以打客服电话要求修改,其他运营商据我所知不行)。
注意:外网控制需要配置好权限管理,推荐使用JWT。代码不修改直接在外网运行,没有任何安全保障。
3.0.1 获取屏幕图像(根据不同的屏幕分辨率和电脑性能,效率在20-40ms之间)
为啥要这样? 你不会直接调用Robot类的createScreenCapture方法获取图片吧?让我们看下源码,源码的操作很秀,简单来说是先获取像素数组,再把他转成图片,但是我这里其实只需要获取像素数组,再转成png二进制的数据就可以了,你给我转图片来回倒腾,性能直接爆炸。源码如下:(用这个方法来回倒腾,性能最少浪费100ms以上,并且CPU占用率也会报警),我其实只需要源码中的pixels = peer.getRGBPixels(screenRect);这一行代码就够了。
问:为啥不用DXGI,效率比JAVA源码这个还要高啊(DXGI效率大约在3-8ms)
答:我在资料夹中提供了DXGI的JAVA调用封装,并且放了一个简单的word文档,感兴趣自己看,需要win8以上电脑才能用。
提取码:8888
看看源码都干了什么:
获取到了像素数组后,需要转为二进制数据,下面是高效率的方法(2-5ms):
将二进制的bmp格式图片数据转为png格式二进制数据,下面是通过openCV进行的高效率转换方法(20-35ms):
帧间压缩(这和真正的帧间压缩差了十万八千里,我也想不到别的名称,姑且这么叫吧)——直接把2个图片的二进制数据进行比较,把不变的标记为-127,如果本身这个像素位置就是-127,那就改为-126(肉眼看不出来),每次只需要传输变化的图片(5-15ms),不需要每次都传原图。调用openCV,使用png压缩后,每帧的体积很小
把从服务端接收的二进制png格式数据转为二进制bmp格式数据(20-35ms)
帧还原(与上一帧比较,将改变的像素位置替换)(5-15ms)
将二进制像素数据转为int[]型,下面是高效率的方法(2-5ms):
将像素数组设置到javaFX的页面元素,通过WritableImage对象获得PixelWriter,执行setPixels方法直接绘制像素,下面是高效率方法(1-2ms)
客户端接收到服务端数据后,需要解码一段时间,这时候不能让服务端干等着,解码需要运行于单独的线程,效率比较高
配置一下线程池
把数据计算这块单独放一个线程
控制线程队列数量,保证画面实时性
主要动了这个类:AbstractJavaFxApplicationSupport,修改了springboot初始化顺序,原来是先初始化javaFX应用程序,再初始化springboot启动,调整为相反顺序。
添加一个spirng上下文
springboot启动后,将这个对象赋值给AbstractJavaFxApplicationSupport
修改javaFX初始化方法
展示欢迎屏幕时增加一个加载抽象方法
整个客户端启动类代码修改后变为,这样改造,用到JAVA20应该都没问题
有几个同学给我发微信说不会用DXGI插件,囧囧囧,好吧,我打包了一个DXGI获取屏幕的版本,测试下来可将CPU占用降低到10%以下,服务端编码效率提升45%。提升不错,就是本来几乎原汁原味的JAVA已经慢慢变味了(下一步不会让我搞rtmp流吧,😅)
老地方自己下载:
通过指针获取屏幕像素数组,其他地方不变,DXGI的C++代码就不介绍了:
本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕,E-mail:xinmeigg88@163.com
本文链接:http://zleialh.tongchengxian.cn/news/6812.html
有话要说...