Mornor
Mornor

Reputation: 3803

Display VLCJ player in Canvas

I try to put a VLCJ player inside a canvas. I have already read many subjects about it, but I still can't achieved what I would like to do.

Here is the code I use :

public class RaspberryControler extends JFrame 
{

    /*Have to declare it in order to use vlcj*/
    private EmbeddedMediaPlayerComponent mediaPlayerComponent;
    private EmbeddedMediaPlayer mediaPlayer;

    public RaspberryControler(String host){
       this.host = host;
       controler = new Controler(this);  
       initComponents();
    }

    private void initComponents(){      
      setBasicParameters();
      createMainPanel();
      createControlPanel(); 
      createWebcamPanel(); 
      mainPanel.add(webcamPanel); 
      mainPanel.add(controlPanel); 
      setListeners();       

      /*Set the last parameters of the frame*/
      this.revalidate();
      this.repaint();
      this.setDefaultCloseOperation(EXIT_ON_CLOSE);
      this.setLocationRelativeTo(null);     
   }

   private void createMainPanel(){

       mainPanel = new JPanel();

       /*Set the Layout*/
       mainPanel.setLayout(new FlowLayout());
       mainPanel.setVisible(true);

       /*Set the parameters*/ 
       this.getContentPane().add(mainPanel);
   }

    private void createWebcamPanel(){       
      /*Get the VLC Libraries*/
    NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:/VLC/VideoLAN/VLC");
    Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);

    /*Create components*/
    liveStream = new JLabel("Live Stream"); 
    mediaPlayerComponent = new EmbeddedMediaPlayerComponent(); 

    /*Set parameters of the components*/
    liveStream.setPreferredSize(new Dimension(200, 30));
    liveStream.setHorizontalAlignment(SwingConstants.CENTER);

    /*Set the layout*/
    webcamPanel = new JPanel();
    webcamPanel.setLayout(new BorderLayout()); 
    webcamPanel.setPreferredSize(new Dimension(550, 480));
    webcamPanel.setBorder(BorderFactory.createLineBorder(Color.RED));

    /*Place the components*/
    webcamPanel.setVisible(true);
    webcamPanel.add(liveStream, BorderLayout.NORTH);        
    webcamPanel.add(mediaPlayerComponent, BorderLayout.CENTER);

    this.setVisible(true); 

    try{
        mediaPlayerComponent.getMediaPlayer().playMedia("http://127.0.0.1:8989/movie");
    }catch(IllegalStateException e){
        System.out.println(e.toString());
    }
}

Then, of course, the WebcamPanel is added to the current JFrame.

What did I do wrong ?

This is the output : The video surface component must be displayable Thanks to those who will respond !

Ps : Here are the subject I checked : - https://github.com/caprica/vlcj/issues/29 - Failed to play video by vlcj in java

Upvotes: 1

Views: 1470

Answers (1)

caprica
caprica

Reputation: 4146

You don't actually say precisely what is not working.

On the face of it, it looks like you are missing a layout constraint.

Probably this:

webcamPanel.add(canvas);

Should be this:

webcamPanel.add(canvas, BorderLayout.CENTER);

Otherwise you are adding your Canvas with a null layout constraint.

The "video component must be displayable" error is because you can not play a video until the user interface is displayable - VLC does not have a valid window handle for the Canvas until you either pack() the frame, or make it visible. In short, before you play the video you should do frame.setVisible(true).

In relation to threading, the usual Swing threading rules apply - i.e. you must ensure that changes to UI components are invoked on the Event Dispatch Thread (EDT). Normally you don't need worry about this, like when you respond to a Swing event listener. You only need to worry about this if you have a background thread (not the Swing EDT) that initiates the creation or manipulation of Swing components. If you need to do this, you use invokeLater on the SwingUtilities class. I don't think this is needed in your case, but without more code it's hard to say.

A slightly off-topic but related comment: with modern versions of vlcj, there are much easier ways to do this, e.g. by using EmbeddedMediaPlayerComponent it takes care of the media player, the video surface and the associated Canvas for you. You just add the component to your layout and you're done.

Upvotes: 1

Related Questions