Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

197
LINES

< > BotCompany Repo | #1033822 // JavaCPP ffpmeg Screen Capture Demo [OK on Linux x64]

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Uses 16081K of libraries. Click here for Pure Java version (6169L/34K).

1  
!7
2  
3  
// from https://github.com/vzhn/ffmpeg-java-samples/blob/master/src/main/java/GrabScreen.java
4  
5  
// Sadly this is not faster than java.awt.Robot
6  
7  
lib 1400544 // javacpp ffmpeg examples for linux x64
8  
9  
import org.apache.commons.cli.CommandLine;
10  
import org.apache.commons.cli.DefaultParser;
11  
import org.apache.commons.cli.Option;
12  
import org.apache.commons.cli.Options;
13  
import org.apache.commons.cli.HelpFormatter;
14  
import org.apache.commons.cli.ParseException;
15  
import org.bytedeco.javacpp.*;
16  
17  
import javax.swing.*;
18  
import java.awt.*;
19  
import java.awt.image.BufferedImage;
20  
import java.awt.image.DataBufferByte;
21  
22  
import static java.lang.String.format;
23  
import static org.bytedeco.javacpp.avcodec.av_packet_unref;
24  
import static org.bytedeco.javacpp.avdevice.avdevice_register_all;
25  
import static org.bytedeco.javacpp.avformat.*;
26  
import static org.bytedeco.javacpp.avutil.*;
27  
import static org.bytedeco.javacpp.swscale.sws_freeContext;
28  
import static org.bytedeco.javacpp.swscale.sws_getContext;
29  
30  
p { GrabScreen.main(args); }
31  
32  
sclass GrabScreen {
33  
    /** upper left corner coordinates */
34  
    private static final String DEFAULT_X = "0";
35  
    private static final String DEFAULT_Y = "0";
36  
37  
    /** screen fragment dimensions */
38  
    private static final String DEFAULT_WIDTH = "640";
39  
    private static final String DEFAULT_HEIGHT = "480";
40  
41  
    private int width;
42  
    private int height;
43  
    private int x;
44  
    private int y;
45  
    private String display;
46  
47  
    private AVInputFormat x11grab;
48  
    private AVFormatContext x11GrabDevice;
49  
    private avcodec.AVPacket pkt;
50  
    private BufferedImage bufferedImage;
51  
    private AVFrame rgbFrame;
52  
    private swscale.SwsContext swsContext;
53  
    private IntPointer bgr0Linesize;
54  
55  
    private GrabScreen() {}
56  
    
57  
    new FunctionTimings timings;
58  
59  
    public static void main(String... argv) throws ParseException {
60  
        av_log_set_level(AV_LOG_VERBOSE);
61  
62  
        Options options = new Options();
63  
        options.addOption("help", false, "show help and exit");
64  
        options.addOption("width", true, "width");
65  
        options.addOption("height", true, "height");
66  
        options.addOption("x", true, "x");
67  
        options.addOption("y", true, "y");
68  
        options.addOption("display", true, "display");
69  
70  
        CommandLine cmd = new DefaultParser().parse(options, argv);
71  
        if (cmd.hasOption("help")) {
72  
            HelpFormatter helpFormatter = new HelpFormatter();
73  
            helpFormatter.printHelp("EncodeAndMuxH264 [options]", options);
74  
        } else {
75  
            System.out.println("options:");
76  
            GrabScreen instance = new GrabScreen();
77  
            instance.width = Integer.parseInt(getOption(cmd,"width", DEFAULT_WIDTH));
78  
            instance.height = Integer.parseInt(getOption(cmd,"height", DEFAULT_HEIGHT));
79  
            instance.x = Integer.parseInt(getOption(cmd,"x", DEFAULT_X));
80  
            instance.y = Integer.parseInt(getOption(cmd,"y", DEFAULT_Y));
81  
            instance.display = getOption(cmd, "display", System.getenv("DISPLAY"));
82  
83  
            instance.start();
84  
        }
85  
86  
        GrabScreen instance = new GrabScreen();
87  
        instance.start();
88  
    }
89  
90  
    private static String getOption(CommandLine cmd, String key, String defaultValue) {
91  
        String v = cmd.getOptionValue(key, defaultValue);
92  
        System.out.println("\t" + key + " = \"" + v + "\"");
93  
        return v;
94  
    }
95  
96  
    private void setupX11GrabDevice() {
97  
        avdevice_register_all();
98  
        x11grab = av_find_input_format("x11grab");
99  
        if (x11grab == null) {
100  
            throw new RuntimeException("x11grab not found");
101  
        }
102  
        x11GrabDevice = avformat_alloc_context();
103  
        if (x11GrabDevice == null) {
104  
            throw new RuntimeException("x11grab device not found");
105  
        }
106  
107  
        String url = format("%s.0+%d,%d", display, x, y);
108  
        AVDictionary options = new AVDictionary();
109  
        av_dict_set(options, "video_size", format("%dx%d", width, height), 0);
110  
        if(avformat_open_input(x11GrabDevice, url, x11grab, options) != 0) {
111  
            throw new RuntimeException("Couldn't open input stream.\n");
112  
        }
113  
        av_dict_free(options);
114  
115  
        av_dump_format(x11GrabDevice, 0, url, 0);
116  
        if (x11GrabDevice.nb_streams() == 0) {
117  
            throw new RuntimeException("Stream not found!");
118  
        }
119  
        int pixFormat = x11GrabDevice.streams(0).codecpar().format();
120  
        if (pixFormat != AV_PIX_FMT_BGR0) {
121  
            throw new RuntimeException("unsupported pixel format: " + pixFormat);
122  
        }
123  
        pkt = new avcodec.AVPacket();
124  
    }
125  
126  
    private void start() {
127  
        doEvery(1.0, r { print(timings.render()); });
128  
      
129  
        setupX11GrabDevice();
130  
        allocRGB24Frame();
131  
        allocSWSContext();
132  
133  
        JFrame frame = setupJFrame();
134  
        PointerPointer<Pointer> pktDataPointer = new PointerPointer<>(1);
135  
        while (frame.isShowing()) {
136  
          timings.time("Grab image", r {
137  
            timings.time("av_read_frame", -> av_read_frame(x11GrabDevice, pkt));
138  
            timings.time("pktDataPointer.put", -> pktDataPointer.put(pkt.data()));
139  
140  
            timings.time("sws_scale", -> swscale.sws_scale(
141  
                swsContext, pktDataPointer, bgr0Linesize, 0,
142  
                rgbFrame.height(), rgbFrame.data(), rgbFrame.linesize()
143  
            ));
144  
145  
            DataBufferByte buffer = cast bufferedImage.getRaster().getDataBuffer();
146  
            timings.time("rgbFrame get data", -> {
147  
              rgbFrame.data(0).get(buffer.getData());
148  
              av_packet_unref(pkt);
149  
            });
150  
          });
151  
152  
          frame.repaint();
153  
        }
154  
        pktDataPointer.deallocate();
155  
156  
        av_frame_free(rgbFrame);
157  
        avformat_close_input(x11GrabDevice);
158  
        sws_freeContext(swsContext);
159  
160  
        frame.dispose();
161  
        System.exit(0);
162  
    }
163  
164  
    private JFrame setupJFrame() {
165  
        this.bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
166  
        JFrame frame = new JFrame() {
167  
            @Override
168  
            public void paint(Graphics g) {
169  
                g.drawImage(bufferedImage, 0, 0, null);
170  
            }
171  
        };
172  
        frame.setTitle("grab screen");
173  
        frame.setSize(width, height);
174  
        frame.setVisible(true);
175  
        return frame;
176  
    }
177  
178  
    private void allocRGB24Frame() {
179  
        rgbFrame = av_frame_alloc();
180  
        rgbFrame.format(AV_PIX_FMT_BGR24);
181  
        rgbFrame.width(width);
182  
        rgbFrame.height(height);
183  
        int ret = av_frame_get_buffer(rgbFrame, 32);
184  
        if (ret < 0) {
185  
            throw new RuntimeException("Could not allocate the video frame data");
186  
        }
187  
    }
188  
189  
    private void allocSWSContext() {
190  
        bgr0Linesize = new IntPointer(1);
191  
        bgr0Linesize.put(4 * width);
192  
        swsContext =
193  
            sws_getContext(width, height, AV_PIX_FMT_BGR0,
194  
            width, height, rgbFrame.format(), 0,
195  
                null, null, (DoublePointer) null);
196  
    }
197  
}

Author comment

Began life as a copy of #1033821

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033822
Snippet name: JavaCPP ffpmeg Screen Capture Demo [OK on Linux x64]
Eternal ID of this version: #1033822/10
Text MD5: 2311740cd598cd5071e5b2e5693fc895
Transpilation MD5: 40e0234f9cc94d0350829f7ce33b1eba
Author: stefan
Category: javax / gazelle v
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-01-06 19:13:04
Source code size: 7089 bytes / 197 lines
Pitched / IR pitched: No / No
Views / Downloads: 111 / 668
Version history: 9 change(s)
Referenced in: [show references]