4

I'm trying to play a video using vlcj inside a JPanel but it doesn't work for me. The message exception I am getting is "java.lang.IllegalStateException: The video surface component must be displayable" which is the same problem as in Keep getting an Error "Component must be displayable".

The code of the JPanel which contains the canvas and the vlcj player is this:

import javax.swing.JPanel;

import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;

import java.awt.Canvas;
import java.awt.Color;

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 uk.co.caprica.vlcj.runtime.windows.WindowsCanvas;

public class MyJPanel extends JPanel {
private EmbeddedMediaPlayer player;
private WindowsCanvas canvas;

public MyJPanel() {
    canvas = new WindowsCanvas();
    add(canvas);
    revalidate();
    repaint();

    canvas.setVisible(true);

    MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
    player = mediaPlayerFactory.newEmbeddedMediaPlayer();

    CanvasVideoSurface videoSurface = mediaPlayerFactory.newVideoSurface(canvas);

    player.setVideoSurface(videoSurface);
    player.playMedia("v.avi");   // This sentence throws the exception.
}
}

MyJFrame extends JFrame and only contains the MyJPanel JPanel. I think it's not important at all.

import javax.swing.JFrame;

public class MyJFrame extends JFrame {
protected MyJPanel myJPanel;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                MyJFrame frame = new MyJFrame();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public MyJFrame() {
    myJPanel = new myJPanel();
    add(myJPanel);
}   
}

Thanks in advance.

Community
  • 1
  • 1
Jonás
  • 1,459
  • 4
  • 27
  • 43

1 Answers1

8

You're trying to play the media before the frame containing the canvas has been set to be visible. You'll need to put the playMedia() call in a separate method, and call it after the entire frame has been created and set as visible.

EDIT:

If you still want it to play straight off, just call the relevant method after you've created and made your frame visible:

MyJFrame frame = new MyJFrame();
frame.setVisible(true);
frame.startPlaying();

...obviously you'll need to define startPlaying() on MyJFrame, but then it should start playing straight off. you just need to set the frame visible first.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
  • You can't imagine how much I appreciate all your help. Really thanks. I've created a JButton to start the playing. Although, I would prefer autoplaying. What's the reason? I don't understand why it doesn't run. – Jonás May 16 '12 at 19:48
  • It works perfectly. Does the frame decide a different order to paint the components? – Jonás May 16 '12 at 20:04
  • @honnix It's nothing to do with painting order, it's simply that the underlying libvlc library requires the canvas is made visible on the screen before it will play a video on it (that's a simplification, but the idea is the same.) – Michael Berry May 16 '12 at 20:07
  • I have tried the same code and I have added `playMedia(url)` after `setVisible(true)` but when I execute my code, I get only the panel and no video is playing, whith no error in the console! see [my post](http://stackoverflow.com/questions/13440760/embedding-vlcj-in-jpanel) – Adil Nov 18 '12 at 15:50