抓取屏幕数据推送到Socket客户端(Windows版)
这期是群里的一个粉丝的的作业,粉丝提供的初版本的代码,功能没有写完整。我们进行了一个简单的修改。实现了 抓取屏幕数据通过SocketServer推送到ServerClient客户端 这样的一个功能。
实现想法
1.抓取器抓取到屏幕数据。 2.将帧数据转换成输入流。 3.推送到Socket客户端 4.Socket客户端接受到数据并输出。
引入javacv版本
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.4-1.5.6</version>
</dependency>
核心方法
ServerSocket代码
public class Socket_Server {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(10001);
System.out.println("服务器启动");
Socket client = ss.accept();
System.out.println("服务器链接成功");
OutputStream os = client.getOutputStream();
//启动线程
ScreenThread screenThread = new ScreenThread(os);
screenThread.start();
new CountDownLatch(1).await();
} catch (Exception e) {
e.printStackTrace();
class ScreenThread extends Thread {
//数据的输出流
private OutputStream os;
//构造函数 单位秒
public ScreenThread(OutputStream os) {
this.os = os;
// 输出流,视频最终会输出到此
private ByteArrayOutputStream bos = new ByteArrayOutputStream();
//开始启动线程
public void run() {
try {
//使用gdi方式获取windows桌面画面
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("desktop");
grabber.setFormat("gdigrab");// 基于gdigrab的输入格式
grabber.setOption("framerate", "25");// 帧率设置25帧每秒
//grabber.setOption("draw_mouse", "1");//显示鼠标
grabber.setImageWidth(300);
grabber.setImageHeight(600);
try {
grabber.start();//开始采集屏幕画面
} catch (FrameGrabber.Exception e) {
e.printStackTrace();
FFmpegLogCallback.set();
Frame frame;
for (;(frame = grabber.grabImage())!=null;) {
try {
BufferedImage bufferedImage = FrameToBufferedImage(frame);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", stream);
os.write(stream.toByteArray());
} catch (FrameRecorder.Exception e) {
e.printStackTrace();
grabber.close();//close包含stop和release方法
} catch (Exception e) {
e.printStackTrace();
* 转图片数据
* @param frame
* @return
public static BufferedImage FrameToBufferedImage(Frame frame) {
//创建BufferedImage对象
Java2DFrameConverter converter = new Java2DFrameConverter();
return converter.getBufferedImage(frame);
}
ServerClient代码
**
* @author 原代码 zy 修改者 dzp
* @date 2021/12/17-14:07
public class Socket_Client {
public static void main(String[] args) {
try {
String input = JOptionPane.showInputDialog("服务器IP", "127.0.0.1:10001");
String host = input.substring(0, input.indexOf(":"));
String post = input.substring(input.indexOf(":") + 1);
Socket client = new Socket(host, Integer.parseInt(post));
CanvasFrame canvas = new CanvasFrame("服务器画面");// 新建一个窗口
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas.setAlwaysOnTop(true);
while (true) {
//输入流
InputStream dis = client.getInputStream();
canvas.showImage( ImageIO.read(dis));
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();