抓取屏幕数据推送到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();