# Java Swing Desktop Screen Recorder with Network Streaming
I'll help you create a Java Swing application that can:
1. Display the desktop screen in real-time
2. Record the desktop screen with pause/resume functionality
3. Save the recording to a file
4. Stream the video over a network
Here's a complete implementation:
```java
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.atomic.AtomicBoolean;
public class DesktopRecorder extends JFrame {
private Robot robot;
private Rectangle screenRect;
private AtomicBoolean recording = new AtomicBoolean(false);
private AtomicBoolean paused = new AtomicBoolean(false);
private JLabel screenLabel;
private File outputFile;
private ServerSocket serverSocket;
private boolean streaming = false;
public DesktopRecorder() {
try {
robot = new Robot();
screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
setTitle("Desktop Recorder");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
screenLabel = new JLabel();
add(screenLabel, BorderLayout.CENTER);
JPanel controlPanel = new JPanel();
JButton startBtn = new JButton("Start Recording");
JButton pauseBtn = new JButton("Pause");
JButton stopBtn = new JButton("Stop");
JButton streamBtn = new JButton("Start Streaming");
startBtn.addActionListener(e -> startRecording());
pauseBtn.addActionListener(e -> togglePause());
stopBtn.addActionListener(e -> stopRecording());
streamBtn.addActionListener(e -> toggleStreaming());
controlPanel.add(startBtn);
controlPanel.add(pauseBtn);
controlPanel.add(stopBtn);
controlPanel.add(streamBtn);
add(controlPanel, BorderLayout.SOUTH);
pack();
setSize(800, 600);
setLocationRelativeTo(null);
// Start screen capture thread
new Thread(this::captureScreen).start();
} catch (AWTException e) {
e.printStackTrace();
}
}
private void captureScreen() {
while (true) {
try {
BufferedImage screenImage = robot.createScreenCapture(screenRect);
ImageIcon icon = new ImageIcon(screenImage.getScaledInstance(
screenLabel.getWidth(), screenLabel.getHeight(), Image.SCALE_SMOOTH));
screenLabel.setIcon(icon);
if (recording.get() && !paused.get()) {
// Save frame to video file (simplified - in real app use proper video encoding)
saveFrame(screenImage);
// Stream frame if streaming is enabled
if (streaming) {
streamFrame(screenImage);
}
}
Thread.sleep(1000 / 30); // ~30 FPS
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void saveFrame(BufferedImage image) {
if (outputFile == null) {
outputFile = new File("recording_" + System.currentTimeMillis() + ".avi");
}
// In a real application, you would use proper video encoding (like Xuggler or JavaCV)
// This is a simplified placeholder
try (FileOutputStream fos = new FileOutputStream(outputFile, true)) {
// Just saving raw bytes - not a proper video format
byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
fos.write(pixels);
} catch (IOException e) {
e.printStackTrace();
}
}
private void streamFrame(BufferedImage image) {
try {
if (serverSocket == null) {
serverSocket = new ServerSocket(5555);
new Thread(this::handleStreamConnections).start();
}
// Convert image to bytes (simplified)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
byte[] imageBytes = baos.toByteArray();
// Broadcast to all connected clients
for (Socket client : ClientHandler.clients) {
try {
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
dos.writeInt(imageBytes.length);
dos.write(imageBytes);
dos.flush();
} catch (IOException e) {
// Client disconnected
ClientHandler.clients.remove(client);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void handleStreamConnections() {
try {
while (streaming) {
Socket client = serverSocket.accept();
ClientHandler.clients.add(client);
System.out.println("New client connected: " + client.getInetAddress());
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void startRecording() {
recording.set(true);
paused.set(false);
JOptionPane.showMessageDialog(this, "Recording started!");
}
private void togglePause() {
paused.set(!paused.get());
JOptionPane.showMessageDialog(this, paused.get() ? "Recording paused" : "Recording resumed");
}
private void stopRecording() {
recording.set(false);
paused.set(false);
JOptionPane.showMessageDialog(this, "Recording stopped! Saved to: " + outputFile.getAbsolutePath());
outputFile = null;
}
private void toggleStreaming() {
streaming = !streaming;
if (streaming) {
JOptionPane.showMessageDialog(this, "Streaming started on port 5555");
} else {
JOptionPane.showMessageDialog(this, "Streaming stopped");
try {
if (serverSocket != null) {
serverSocket.close();
serverSocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new DesktopRecorder().setVisible(true);
});
}
static class ClientHandler {
static java.util.List<Socket> clients = new java.util.ArrayList<>();
}
}
```
## Important Notes About This Implementation:
1. **Video Encoding**: This example doesn't include proper video encoding. In a real application, you would use a library like:
- Xuggler
- JavaCV (OpenCV wrapper)
- JCodec
2. **Performance**: Screen recording is resource-intensive. The current implementation captures at ~30 FPS but may need optimization for different systems.
3. **Network Streaming**: The streaming implementation is basic. For a production app, consider:
- Using proper video compression
- Implementing a protocol like RTMP
- Adding authentication
4. **Pause Functionality**: The pause button stops frames from being saved/streamed but continues screen capture.
## To Improve This Application:
1. Add proper video encoding using a library like JavaCV:
```java
// Example with JavaCV
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("output.mp4", screenWidth, screenHeight);
recorder.setFormat("mp4");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.start();
```
2. Add file chooser dialog to select output location:
```java
JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
outputFile = fileChooser.getSelectedFile();
}
```
3. Add quality settings (resolution, FPS, compression)
Would you like me to explain any specific part in more detail or enhance any particular functionality?
No comments:
Post a Comment