Package uk.co.caprica.vlcj.test.multi

Source Code of uk.co.caprica.vlcj.test.multi.TestMultiPlayer

/*
* This file is part of VLCJ.
*
* VLCJ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VLCJ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VLCJ.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2009, 2010, 2011, 2012, 2013, 2014 Caprica Software Limited.
*/

package uk.co.caprica.vlcj.test.multi;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.DefaultFullScreenStrategy;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.FullScreenStrategy;
import uk.co.caprica.vlcj.test.VlcjTest;

/**
* Example multi-instance player.
* <p>
* This approach to multi-instance players is not really recommended due to potential
* concurrency/re-entrancy problems with the long list of native libraries that vlc uses. The more
* player instances you have in one application, the more likely you are to see fatal crashes in
* those native libraries.
* <p>
* One of the biggest culprits is Fontconfig: version 2.10.91+ is supposed to be thread-safe so one
* of the most common causes of multi-player crash bugs should be gone when compiled with that
* particular version. However, other native libraries may still cause problems.
* <p>
* Also, a current limitation of vlc is that all in-process media players will share the same audio
* controls - there is no independent audio control available.
* <p>
* Out of process media players are reliable, but a lot more difficult and intricate to implement.
*/
public class TestMultiPlayer extends VlcjTest {

    private final String[] medias = {
        "/home/videos/1.flv",
        "/home/videos/2.flv",
        "/home/videos/3.flv",
        "/home/videos/4.flv",
        // Your MRL's go here
    };

    private final int rows = 1;
    private final int cols = 4;

    private final Frame mainFrame;

    private final List<PlayerInstance> players = new ArrayList<PlayerInstance>();

    private final MediaPlayerFactory factory;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestMultiPlayer().start();
            }
        });
    }

    public TestMultiPlayer() {
        JPanel contentPane = new JPanel();
        contentPane.setBackground(Color.black);
        contentPane.setLayout(new GridLayout(rows, cols, 16, 16));
        contentPane.setBorder(new EmptyBorder(16, 16, 16, 16));

        mainFrame = new Frame("VLCJ Test Multi Player");
        mainFrame.setIconImage(new ImageIcon(getClass().getResource("/icons/vlcj-logo.png")).getImage());
        mainFrame.setLayout(new BorderLayout());
        mainFrame.setBackground(Color.black);
        mainFrame.add(contentPane, BorderLayout.CENTER);
        mainFrame.setBounds(100, 100, 1600, 300);
        mainFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent evt) {
                for(PlayerInstance pi : players) {
                    pi.mediaPlayer().release();
                }
                factory.release();
                System.exit(0);
            }
        });

        mainFrame.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                for(int i = 0; i < players.size(); i ++ ) {
                    players.get(i).mediaPlayer().pause();
                }
            }
        });

        factory = new MediaPlayerFactory();

        FullScreenStrategy fullScreenStrategy = new DefaultFullScreenStrategy(mainFrame);

        for(int i = 0; i < medias.length; i ++ ) {
            EmbeddedMediaPlayer player = factory.newEmbeddedMediaPlayer(fullScreenStrategy);
            PlayerInstance playerInstance = new PlayerInstance(player);
            players.add(playerInstance);

            JPanel playerPanel = new JPanel();
            playerPanel.setLayout(new BorderLayout());
            playerPanel.setBorder(new LineBorder(Color.white, 2));
            playerPanel.add(playerInstance.videoSurface());

            contentPane.add(playerPanel);
        }

        mainFrame.setVisible(true);
    }

    private void start() {
        Executors.newSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < medias.length; i ++ ) {
                    players.get(i).mediaPlayer().setVideoSurface(factory.newVideoSurface(players.get(i).videoSurface()));
                    players.get(i).mediaPlayer().prepareMedia(medias[i]);
                }

                // There is a race condition somewhere when invoking libvlc_media_player_play()
                // multiple times in quick succession that causes a hard-failure and a fatal
                // VM crash.
                //
                // This is _not_ about _concurrently_ calling play multiple times, but the
                // native play function call must be off-loading something to a separate
                // thread and returning - then a subsequent call to play somehow interferes
                // with that or fails because of that.
                //
                // When libvlc_media_player_play() is called, the video playback is kicked
                // off asynchronously - so the API call will return before the video has
                // started playing. If we invoke play and then wait (making this effectively
                // a synchronous call) for the player to start playing, there is less chance
                // for the hard VM crash to occur - but it still might
                for(int i = 0; i < medias.length; i ++ ) {
                    EmbeddedMediaPlayer mediaPlayer = players.get(i).mediaPlayer();
                    mediaPlayer.start();
                }
            }
        });
    }
}
TOP

Related Classes of uk.co.caprica.vlcj.test.multi.TestMultiPlayer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.