Воспроизведение 4k видео с vlcj один за другим без черных рамок между ними - PullRequest
0 голосов
/ 04 февраля 2019

Последние несколько дней я пытался воспроизвести несколько видео 4k с библиотекой java vlcj, друг за другом без черных (буферных?) Кадров между ними.

Моя идея заключалась в том, что япоместите 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 при воспроизведении видео.Только когда я закрываю приложение.Но это может быть потому, что я не собираю мусор должным образом.

Я благодарен за любую помощь.

С уважением

...