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 | } |
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: | 224 / 946 |
Version history: | 9 change(s) |
Referenced in: | [show references] |