Tuesday, July 22, 2025

Java Video Player

# Java Swing Video Player with File and Network Support

I'll create a comprehensive video player application using Java Swing that can play videos from both local files and network streams. The player will include play/pause/stop controls, a seek bar (JSlider), time display, and a JTable to select videos.

## Complete Implementation

```java
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import uk.co.caprica.vlcj.factory.discovery.NativeDiscovery;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;

public class VideoPlayer extends JFrame {
    private EmbeddedMediaPlayerComponent mediaPlayerComponent;
    private MediaPlayer mediaPlayer;
    
    private JButton playButton, pauseButton, stopButton;
    private JSlider progressSlider;
    private JLabel timeLabel, durationLabel;
    private JTable videoTable;
    private VideoTableModel tableModel;
    
    private Timer progressTimer;
    private List<VideoItem> videoItems = new ArrayList<>();

    public VideoPlayer() {
        setTitle("Advanced Video Player");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000, 700);
        setLocationRelativeTo(null);
        
        // Initialize VLCJ native discovery
        new NativeDiscovery().discover();
        
        // Create media player component
        mediaPlayerComponent = new EmbeddedMediaPlayerComponent();
        mediaPlayer = mediaPlayerComponent.mediaPlayer();
        
        // Create UI components
        createControls();
        createVideoTable();
        
        // Layout
        setLayout(new BorderLayout());
        add(mediaPlayerComponent, BorderLayout.CENTER);
        add(createControlPanel(), BorderLayout.SOUTH);
        add(new JScrollPane(videoTable), BorderLayout.WEST);
        
        // Load sample videos
        loadSampleVideos();
        
        // Set up timer to update progress
        progressTimer = new Timer(100, e -> updateProgress());
    }
    
    private void createControls() {
        playButton = new JButton("Play");
        playButton.addActionListener(e -> playVideo());
        
        pauseButton = new JButton("Pause");
        pauseButton.addActionListener(e -> mediaPlayer.controls().pause());
        
        stopButton = new JButton("Stop");
        stopButton.addActionListener(e -> {
            mediaPlayer.controls().stop();
            progressTimer.stop();
            updateTimeLabels(0, 0);
        });
        
        progressSlider = new JSlider(0, 100, 0);
        progressSlider.addChangeListener(e -> {
            if (progressSlider.getValueIsAdjusting()) {
                float position = progressSlider.getValue() / 100.0f;
                mediaPlayer.controls().setPosition(position);
            }
        });
        
        timeLabel = new JLabel("00:00:00");
        durationLabel = new JLabel("00:00:00");
    }
    
    private JPanel createControlPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(playButton);
        buttonPanel.add(pauseButton);
        buttonPanel.add(stopButton);
        
        JPanel sliderPanel = new JPanel(new BorderLayout());
        sliderPanel.add(progressSlider, BorderLayout.CENTER);
        
        JPanel timePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        timePanel.add(timeLabel);
        timePanel.add(new JLabel("/"));
        timePanel.add(durationLabel);
        
        panel.add(buttonPanel, BorderLayout.NORTH);
        panel.add(sliderPanel, BorderLayout.CENTER);
        panel.add(timePanel, BorderLayout.SOUTH);
        
        return panel;
    }
    
    private void createVideoTable() {
        tableModel = new VideoTableModel();
        videoTable = new JTable(tableModel);
        videoTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        videoTable.getSelectionModel().addListSelectionListener(e -> {
            if (!e.getValueIsAdjusting()) {
                int selectedRow = videoTable.getSelectedRow();
                if (selectedRow >= 0) {
                    VideoItem item = videoItems.get(selectedRow);
                    mediaPlayer.media().play(item.getPath());
                    updateDurationLabel();
                }
            }
        });
    }
    
    private void loadSampleVideos() {
        // Add local files
        videoItems.add(new VideoItem("Sample Video 1", "file:/C:/Videos/sample1.mp4"));
        videoItems.add(new VideoItem("Sample Video 2", "file:/C:/Videos/sample2.mp4"));
        
        // Add network streams
        videoItems.add(new VideoItem("Network Stream 1", "http://example.com/stream1.m3u8"));
        videoItems.add(new VideoItem("Network Stream 2", "rtsp://example.com/stream2"));
        
        tableModel.setVideos(videoItems);
    }
    
    private void playVideo() {
        mediaPlayer.controls().play();
        progressTimer.start();
        updateDurationLabel();
    }
    
    private void updateProgress() {
        long duration = mediaPlayer.status().length();
        long time = mediaPlayer.status().time();
        
        if (duration > 0) {
            int position = (int) (100 * (time / (double) duration));
            progressSlider.setValue(position);
        }
        
        updateTimeLabels(time, duration);
    }
    
    private void updateTimeLabels(long time, long duration) {
        timeLabel.setText(formatTime(time));
        durationLabel.setText(formatTime(duration));
    }
    
    private void updateDurationLabel() {
        SwingUtilities.invokeLater(() -> {
            long duration = mediaPlayer.status().length();
            durationLabel.setText(formatTime(duration));
        });
    }
    
    private String formatTime(long milliseconds) {
        long seconds = milliseconds / 1000;
        long hours = seconds / 3600;
        seconds %= 3600;
        long minutes = seconds / 60;
        seconds %= 60;
        return String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            VideoPlayer player = new VideoPlayer();
            player.setVisible(true);
        });
    }
    
    // Model classes
    class VideoItem {
        private String title;
        private String path;
        
        public VideoItem(String title, String path) {
            this.title = title;
            this.path = path;
        }
        
        public String getTitle() { return title; }
        public String getPath() { return path; }
    }
    
    class VideoTableModel extends AbstractTableModel {
        private List<VideoItem> videos = new ArrayList<>();
        private String[] columns = {"Title", "Type"};
        
        public void setVideos(List<VideoItem> videos) {
            this.videos = videos;
            fireTableDataChanged();
        }
        
        @Override
        public int getRowCount() { return videos.size(); }
        
        @Override
        public int getColumnCount() { return columns.length; }
        
        @Override
        public String getColumnName(int column) { return columns[column]; }
        
        @Override
        public Object getValueAt(int row, int column) {
            VideoItem item = videos.get(row);
            switch (column) {
                case 0: return item.getTitle();
                case 1: return item.getPath().startsWith("http") ? "Network" : "Local";
                default: return null;
            }
        }
    }
}
```

## Features Implemented

1. **Video Playback**:
   - Play, pause, stop functionality
   - Support for both local files and network streams
   - Uses VLCJ library for robust media playback

2. **Progress Tracking**:
   - JSlider for seeking through video
   - Time labels showing current time and total duration
   - Automatic progress updates

3. **Video Selection**:
   - JTable listing available videos
   - Differentiates between local and network videos
   - Click to play selected video

4. **Network Support**:
   - Can play HTTP, RTSP, and other network streams
   - Handles both progressive download and streaming protocols

## Requirements

1. **VLC Media Player** must be installed on the system
2. **VLCJ** library (add to your project):
   ```xml
   <dependency>
       <groupId>uk.co.caprica</groupId>
       <artifactId>vlcj</artifactId>
       <version>4.7.3</version>
   </dependency>
   ```

## How to Use

1. Add the VLCJ dependency to your project
2. Install VLC Media Player on your system
3. Update the sample video paths in `loadSampleVideos()` to point to your actual video files or streams
4. Run the application

## Key Components Explained

1. **EmbeddedMediaPlayerComponent**: The core VLCJ component that handles video playback
2. **MediaPlayer Controls**: Provides play, pause, stop functionality
3. **Progress Timer**: Updates the slider and time labels periodically
4. **VideoTableModel**: Custom table model to display video information
5. **Network Support**: The player automatically handles network streams via standard URLs

## Possible Enhancements

1. Add volume control
2. Implement playlist functionality
3. Add fullscreen mode
4. Support for subtitles
5. Video quality selection for network streams
6. Buffering indicators for network playback

Would you like me to explain any specific part in more detail or add any particular features to this implementation?

No comments: