Pergunta

How to add JLabel with a transparent background on top of vlcj MediaPlayer?

I put source below, but it is not working as it should, because JLabel doesn't have transparent background set.

import com.sun.jna.NativeLibrary;
import javax.swing.*;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;

class VideoExample extends JFrame {

    private EmbeddedMediaPlayerComponent mediaPlayerComponent;

    public VideoExample(String path) {
        super("Простой видео плеер");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(640, 480);

        //Create JLayeredPane 
        JLayeredPane mainLayer = new JLayeredPane();
        mainLayer.setSize(640,480);

        //Create MediaPlayer on background
        mediaPlayerComponent = new EmbeddedMediaPlayerComponent();
        mediaPlayerComponent.setLocation(0, 0);
        mediaPlayerComponent.setSize(mainLayer.getSize());

        //Create MediaPlayer on foreground
        JLabel label = new JLabel("LABEL", JLabel.CENTER);
        label.setBounds(100, 100, 200, 100);
        label.setOpaque(false);

        mainLayer.add(mediaPlayerComponent, JLayeredPane.DEFAULT_LAYER); //add mediaPlayer in DEFAULT_LAYER
        mainLayer.add(label, JLayeredPane.PALETTE_LAYER); //add label in PALETTE_LAYER
        add(mainLayer); // add JLayeredPane in JFrame 

        setVisible(true);
        mediaPlayerComponent.getMediaPlayer().playMedia(path);
    }

    public static void main(String[] args) {
        NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), System.getProperty("user.dir") + "/lib/vlc64");
        final String mrl = "D:\\Candlelight_QT.mov";
        new VideoExample(mrl);
    }
}

This is the result:

The result http://vitamin.vipdesign.com.ua/1n7tJ.jpg

Foi útil?

Solução

MadProgrammer is right. VLCJ attaches a native video surface to a java.awt.Canvas. You can supply your own Canvas with overridden paint(..) method but that won't help. This is what happens internally on Linux in LinuxVideoSurfaceAdapter:

    public void attach(LibVlc libvlc, MediaPlayer mediaPlayer, long componentId) {
        Logger.debug("attach(componentId={})", componentId);
        libvlc.libvlc_media_player_set_xwindow(mediaPlayer.mediaPlayerInstance(), (int)componentId);
    }

The native java.awt.Canvas X11 window is used as a target for VLC output.

My best bet is to use the overlay mechanism like madprogrammer mentioned. Basically you'll need to supply a Window or JWindow by subclassing EmbeddedMediaPlayerComponent. As transparency is quite platform dependent you'll want to check if the desired type of transparency/transluncency is supported by your target environment (careful: complex graphics configurations might have different capabilities for each screen device!):

final boolean perPixelTranslucencySupported = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().isWindowTranslucencySupported(WindowTranslucency.PERPIXEL_TRANSLUCENT);

Create a subclass of EmbeddedMediaPlayerComponent:

  mediaPlayerComponent = new EmbeddedMediaPlayerComponent() {

            @Override
            protected Window onGetOverlay() {
                final JWindow transparentWindow = new JWindow();

                // Set basic window opacity if required - the window system must support WindowTranslucency (i.e. PERPIXEL_TRANSLUCENT)!
                transparentWindow.setOpacity(0.8f);
                // White with transparent alpha channel - WindowTranslucency is required for translucency.
                transparentWindow.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));

                final JLabel superImposedLightweigtLabel = new JLabel("Hello, VLC.", JLabel.CENTER);
                superImposedLightweigtLabel.setOpaque(false);

                transparentWindow.getContentPane().add(superImposedLightweigtLabel);
                return transparentWindow;
            }
        ...
      }

After making the main JFrame visible, enable the overlay:

mediaPlayerComponent.getMediaPlayer().enableOverlay(true);

I couldn't verify the results as I am working in a virtual machine without transparency features right now so my actual JWindow overlay is NOT transparent for obvious reasons. Please let us know if it works as desired and if there are any other pitfalls.

Outras dicas

You need to take the time to read the vlcj wiki...

You can not simply add a lightweight transparent JComponent on top of the heavyweight video surface Canvas component - it will not work.

Check out Overlaying Graphics for more details

It would appear that you're creating a Color with an alpha value (meaning it is transparent):

new Color(0, 200, 0, 50)

Try just using

new Color(0, 200, 0)

(unless I've missed the point of the question)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top