Search code examples
javaswingvlcj

Update video to show in desktop application


I have a desktop application using vclj and swing. I have a frame (JFrame component) that contains a video created using vclj (instance of VideoPanel). The problem is that I need to update the video to show in this jframe in runtime. When I try to do it I don't get that it works. Instead, the component of video vclj appears in black color without showing any video.

Code of video component:

public class VideoPanel extends JPanel {

    private EmbeddedMediaPlayerComponent mymediaPlayer;
    private EmbeddedMediaPlayer mediaPlayer;

    private Canvas canvas;

   public VideoPanel() {

       setLayout(new BorderLayout(10, 10)); 

       Canvas canvas_1 = new Canvas();
       add(canvas_1, BorderLayout.CENTER);

       NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcPath);
       Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);

       MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
       CanvasVideoSurface videoSurface = mediaPlayerFactory.newVideoSurface(canvas_1);
       mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
       mediaPlayer.setVideoSurface(videoSurface);

   }

   public void startPlayer() {
       mediaPlayer.playMedia(mediaPath);    
   }

}

Code called each time that I try to update the video shown in the jframe:

// Remove last video shown
getContentPane().removeAll();

// Create new video vclj        
video = new VideoPanel();

// add video to jframe
add(video, BorderLayout.CENTER);

setVisible(true);

// Update hierarchy of components and repaint
revalidate();
repaint();

// Start the player
video.startPlayer();

// Update hierarchy of components and repaint
revalidate();
repaint();

setVisible(true);

pack();

As you can see, I call to revalidate and repaint methods before and after starting player for content is updated in the jframe.

BTW, When I pressed the close button of the window that has the video, it shows a frame of the video.

Thanks in advance!!


Solution

  • i made a simple small example working example with hard coded MediaPaths, replace this through your mediaPath Variable:

    VideoFrame.java

    package de.professional_webworkx.vlcj;
    
    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class VideoFrame extends JFrame {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        private VideoPanel videoPanel;
    
        public VideoFrame() {
            initializeGUI();
        }
    
        private void initializeGUI() {
    
            JPanel buttonPanel = createButtonPanel();
    
            this.setTitle("MyVideoApp");
            this.setSize(1024, 768);
            this.setLayout(new BorderLayout());
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            videoPanel = new VideoPanel("/home/ottp/Videos/Test.ogv");
            this.getContentPane().add(buttonPanel, BorderLayout.NORTH);
            this.getContentPane().add(videoPanel, BorderLayout.CENTER);
            this.setVisible(true);
            videoPanel.startPlayer();
        }
    
        private JPanel createButtonPanel() {
    
            JPanel buttonPanel  = new JPanel(new GridLayout(1, 2));
            JButton nextVideo   = new JButton("Next Video");
            nextVideo.addActionListener(new ActionListener() {
    
                public void actionPerformed(ActionEvent e) {
                    updateVideoPanel();
                }
    
    
            });
            buttonPanel.add(nextVideo);
            JButton prevVideo   = new JButton("Prev Video");
            buttonPanel.add(prevVideo);
            return buttonPanel;
        }
    
        private void updateVideoPanel() {
            this.remove(videoPanel);
            videoPanel = new VideoPanel("/home/ottp/Videos/Example.ogv");
            this.getContentPane().add(videoPanel, BorderLayout.CENTER);
            videoPanel.startPlayer();
            revalidate();
        }
    
    }
    

    VideoPanel.java

    package de.professional_webworkx.vlcj;
    
    import java.awt.BorderLayout;
    import java.awt.Canvas;
    
    import javax.swing.JPanel;
    
    import uk.co.caprica.vlcj.binding.LibVlc;
    import uk.co.caprica.vlcj.player.MediaPlayerFactory;
    import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
    import uk.co.caprica.vlcj.player.embedded.videosurface.CanvasVideoSurface;
    import uk.co.caprica.vlcj.runtime.RuntimeUtil;
    
    import com.sun.jna.Native;
    
    public class VideoPanel extends JPanel {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        private EmbeddedMediaPlayer mediaPlayer;
        private Canvas _canvas;
        private String mediaPath;
    
        public VideoPanel(final String mediaPath) {
    
            this.mediaPath  = mediaPath;
            setLayout(new BorderLayout(10, 10));
            _canvas = new Canvas();
            add(_canvas, BorderLayout.CENTER);
    
            Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
            MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
            CanvasVideoSurface videoSurface = mediaPlayerFactory.newVideoSurface(_canvas);
            mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
            mediaPlayer.setVideoSurface(videoSurface);
        }
    
        public void startPlayer() {
                    mediaPlayer.playMedia(mediaPath);
        }
    
    
    }
    

    App.java

    package de.professional_webworkx.vlcj;
    
    import javax.swing.SwingUtilities;
    
    import uk.co.caprica.vlcj.binding.LibVlc;
    import uk.co.caprica.vlcj.component.EmbeddedMediaListPlayerComponent;
    import uk.co.caprica.vlcj.runtime.RuntimeUtil;
    
    import com.sun.jna.Native;
    
    /**
     * Hello world!
     *
     */
    public class App 
    {
        private static EmbeddedMediaListPlayerComponent component;
        public static void main( String[] args )
        {
            Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
            SwingUtilities.invokeLater(new Runnable() {
    
                public void run() {
                    new App();
    
                }
            });
        }
    
        private App() {
            new VideoFrame();
        }
    }
    

    It is a maven project, i added vlcj as a maven dependency to my pom.xml, so i had not to add the searchpath. And also the click on the Next Video Button is handled, so update your Videocontent within the updateVideoPanel() Method, there you can have a List or an Array with all your Videos you would like to show. Hope this helps..