依次播放vlcj的4k视频,中间没有黑框

时间:2019-02-04 13:38:14

标签: java transition buffering kiosk vlcj

最近几天,我一直在尝试使用java vlcj库播放多个4k视频,彼此之间没有黑色(缓冲?)帧。

我的想法是,将JLabel放在EmbeddedVideoPlayer的画布上。当我单击下一个视频的按钮时,我将暂停正在进行的视频->在那一刻制作该帧的图像->在JLabel上绘制该图像->使JLabel可见。当下一个视频真正开始播放时,我将再次使JLabel不可见。理想情况下,用户永远不必看黑框。

public class FullscreenPlayer {
    public final EmbeddedMediaPlayerComponent mediaPlayerComponent;
    public final EmbeddedMediaPlayer mediaPlayer;
    public JFrame frame;

    public JLabel overlayLabel;

    boolean posChanged = false;
    String fhdVideoPath;

public FullscreenPlayer(int screen) {
    System.setProperty("sun.awt.noerasebackground", "true");

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gs = ge.getScreenDevices();
    Rectangle bounds = gs[screen].getDefaultConfiguration().getBounds();

    final String[] VLC_ARGS = { "--intf", "dummy", /* no interface */
            /*"--vout", "dummy",  we don't want video (output) */
            "--no-audio", /* we don't want audio (decoding) */
            "--no-snapshot-preview", /* no blending in dummy vout */
    };


    MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory(VLC_ARGS);

    Canvas videoCanvas = new Canvas();
    videoCanvas.setBounds(0, 0, bounds.width, bounds.height);
    videoCanvas.setIgnoreRepaint(true);

    overlayLabel = new JLabel();
    overlayLabel.setBounds(0, 0, bounds.width, bounds.height);
     overlayLabel.setBackground(Color.black);
    overlayLabel.setVisible(true);
    overlayLabel.setIgnoreRepaint(true);

    Panel p = new Panel();

    p.setLayout(null);
    p.setBackground(Color.black);
    p.setIgnoreRepaint(true);

    p.add(overlayLabel);
    p.add(videoCanvas);

    frame = new JFrame();

    mediaPlayerComponent = new EmbeddedMediaPlayerComponent() {
        private static final long serialVersionUID = 1L;

        @Override
        protected FullScreenStrategy onGetFullScreenStrategy() {
            return new Win32FullScreenStrategy(frame);
        }
    };

    // mediaPlayer = mediaPlayerComponent.getMediaPlayer();
    mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();

    mediaPlayer.setVideoSurface(mediaPlayerFactory.newVideoSurface(videoCanvas));

    mediaPlayer.addMediaPlayerEventListener(new MediaPlayerEventAdapter() {

        @Override
        public void positionChanged(MediaPlayer mediaPlayer, float newPosition) {
            super.positionChanged(mediaPlayer, newPosition);

            if (!posChanged) {
                System.out.println("Position changed!");
                posChanged = true;
                overlayLabel.setVisible(false);
            }
        }
    });

    // frame.add(videoCanvas);
    frame.setLayout(new BorderLayout());
    frame.add(p, BorderLayout.CENTER);
    frame.setSize(bounds.width, bounds.height);
    frame.setLocation(bounds.x, bounds.y);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBackground(Color.black);
    frame.setVisible(true);
    frame.setLocationRelativeTo(null);
    frame.setIgnoreRepaint(true);
    frame.addWindowListener(new WindowAdapter() {
        @Override
        public void windowClosing(WindowEvent e) {
            mediaPlayer.release();
            mediaPlayerFactory.release();
            System.exit(0);
        }
    });

    frame.addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            switch (e.getKeyChar()) {
            case 'q':
                overlayLabel.setVisible(!overlayLabel.isVisible());
                break;
            case 'w':
                BufferedImage img = mediaPlayer.getSnapshot();
                overlayTest(img);
                break;
            }
        }
    });

    mediaPlayer.setFullScreenStrategy(new Win32FullScreenStrategy(frame));
    mediaPlayer.setFullScreen(true);
}

public void start(String uhdPath, String fhdPath) {
    fhdVideoPath = fhdPath;
    mediaPlayer.pause();

    try {
        BufferedImage img = mediaPlayer.getSnapshot();

        if (mediaPlayer.getTime() > 0 || mediaPlayer.getTime() != -1) {
            overlayTest(img);
        }
        PresentationStarter.fhdInstance.mediaPlayer.pause();
        mediaPlayer.playMedia(uhdPath);
        posChanged = false;
    } catch (Exception e) {
        e.printStackTrace();
    }

}

public void overlayTest(BufferedImage image) {
    double i_h = image.getHeight(null);
    double i_w = image.getWidth(null);
    double c_w = frame.getWidth();

    int imgHeight = (int) (i_h / (i_w / c_w));
    int imgWidth = (int) c_w;

    BufferedImage resizedImage = PresentationStarter.resize(image, imgWidth, imgHeight);
    ImageIcon imgIcon = new ImageIcon(resizedImage);

    overlayLabel.setIcon(imgIcon);
    overlayLabel.setVisible(true);

    // The repaint happens after this point.
}

}

播放视频时,我看不到任何vlcj调试消息。仅当我关闭应用程序时。但这可能是因为我没有正确进行垃圾收集。

感谢您提供的任何帮助。

亲切的问候

0 个答案:

没有答案