Package uk.co.caprica.vlcj.player

Source Code of uk.co.caprica.vlcj.player.MediaPlayerFactory

/*
* 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.player;

import java.awt.Canvas;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.binding.LibVlcFactory;
import uk.co.caprica.vlcj.binding.internal.libvlc_audio_output_device_t;
import uk.co.caprica.vlcj.binding.internal.libvlc_audio_output_t;
import uk.co.caprica.vlcj.binding.internal.libvlc_equalizer_t;
import uk.co.caprica.vlcj.binding.internal.libvlc_instance_t;
import uk.co.caprica.vlcj.binding.internal.libvlc_media_t;
import uk.co.caprica.vlcj.binding.internal.libvlc_module_description_t;
import uk.co.caprica.vlcj.log.NativeLog;
import uk.co.caprica.vlcj.logger.Logger;
import uk.co.caprica.vlcj.medialist.MediaList;
import uk.co.caprica.vlcj.player.direct.BufferFormatCallback;
import uk.co.caprica.vlcj.player.direct.DefaultDirectMediaPlayer;
import uk.co.caprica.vlcj.player.direct.DirectMediaPlayer;
import uk.co.caprica.vlcj.player.direct.RenderCallback;
import uk.co.caprica.vlcj.player.directaudio.AudioCallback;
import uk.co.caprica.vlcj.player.directaudio.DefaultDirectAudioPlayer;
import uk.co.caprica.vlcj.player.directaudio.DirectAudioPlayer;
import uk.co.caprica.vlcj.player.discoverer.MediaDiscoverer;
import uk.co.caprica.vlcj.player.embedded.DefaultEmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.FullScreenStrategy;
import uk.co.caprica.vlcj.player.embedded.videosurface.CanvasVideoSurface;
import uk.co.caprica.vlcj.player.embedded.videosurface.ComponentIdVideoSurface;
import uk.co.caprica.vlcj.player.embedded.videosurface.VideoSurfaceAdapter;
import uk.co.caprica.vlcj.player.embedded.videosurface.linux.LinuxVideoSurfaceAdapter;
import uk.co.caprica.vlcj.player.embedded.videosurface.mac.MacVideoSurfaceAdapter;
import uk.co.caprica.vlcj.player.embedded.videosurface.windows.WindowsVideoSurfaceAdapter;
import uk.co.caprica.vlcj.player.headless.DefaultHeadlessMediaPlayer;
import uk.co.caprica.vlcj.player.headless.HeadlessMediaPlayer;
import uk.co.caprica.vlcj.player.list.DefaultMediaListPlayer;
import uk.co.caprica.vlcj.player.list.MediaListPlayer;
import uk.co.caprica.vlcj.player.manager.DefaultMediaManager;
import uk.co.caprica.vlcj.player.manager.MediaManager;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import uk.co.caprica.vlcj.version.LibVlcVersion;
import uk.co.caprica.vlcj.version.Version;

/**
* Factory for media player instances.
* <p>
* The factory initialises a single libvlc instance and uses that to create media player instances.
* <p>
* If required, you can create multiple factory instances each with their own libvlc options.
* <p>
* You should release the factory when your application terminates to properly clean up native
* resources.
* <p>
* The factory also provides access to the native libvlc Logger and other resources such as the list
* of audio outputs, and the list of available audio and video filters.
* <p>
* Usage:
*
* <pre>
*   // Set some options for libvlc
*   String[] libvlcArgs = {...add options here...};
*
*   // Create a factory instance (once), you can keep a reference to this
*   MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory(libvlcArgs);
*
*   // Create a full-screen strategy
*   FullScreenStrategy fullScreenStrategy = new DefaultFullScreenStrategy(mainFrame);
*
*   // Create a media player instance
*   EmbeddedMediaPlayer mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer(fullScreenStrategy);
*
*   // Do some interesting things with the media player, like setting a video surface...
*
*   ...
*
*   // Release the media player
*   mediaPlayer.release();
*
*   // Release the factory
*   factory.release();
* </pre>
*
* You <em>must</em> make sure you keep a hard reference to the media player (and possibly other)
* objects created by this factory. If you allow a media player object to go out of scope, then
* unpredictable behaviour will occur (such as events no longer seeming to fire) even though the
* video playback continues (since that happens via native code). You may also likely suffer fatal
* JVM crashes.
* <p>
* It is always a better strategy to reuse media player instances, rather than repeatedly creating
* and destroying instances.
*/
public class MediaPlayerFactory {

    /**
     * Workaround for running under Java7 on Linux.
     * <p>
     * Without this (unless other client configuration changes have already been made) an
     * unsatisfied link error will likely be thrown by the JVM when an attempt is made to play
     * video in an embedded media player.
     */
    static {
        // Only apply for Linux, but not for a headless environment...
        if(RuntimeUtil.isNix() && !GraphicsEnvironment.isHeadless()) {
            // Only apply if the run-time version is Java 1.7.0 or later...
            Version actualJavaVersion = new Version(System.getProperty("java.version"));
            if(actualJavaVersion.atLeast(new Version("1.7.0"))) {
                Logger.debug("Trying workaround for Java7 on Linux");
                Toolkit.getDefaultToolkit();
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        try {
                            Logger.debug("Attempting to load jawt...");
                            System.loadLibrary("jawt");
                            Logger.debug("...loaded jawt");
                        }
                        catch(UnsatisfiedLinkError e) {
                            Logger.debug("Failed to load jawt", e);
                        }
                        return null;
                    }
                });
                Logger.debug("Java7 on Linux workaround complete.");
            }
        }
    }

    /**
     * Help text if libvlc failed to load and initialise.
     */
    private static final String PLUGIN_PATH_HELP =
        "Failed to initialise libvlc.\n\n" +
        "This is most often caused either by an invalid vlc option being passed when creating a MediaPlayerFactory or by libvlc being unable to locate the required plugins.\n\n" +
        "If libvlc is unable to locate the required plugins the instructions below may help:\n\n" +
        "In the text below <libvlc-path> represents the name of the directory containing \"{0}\" and \"{1}\" and <plugins-path> represents the name of the directory containing the vlc plugins...\n\n" +
        "For libvlc to function correctly the vlc plugins must be available, there are a number of different ways to achieve this:\n" +
        " 1. Make sure the plugins are installed in the \"<libvlc-path>/{2}\" directory, this should be the case with a normal vlc installation.\n" +
        " 2. Set the VLC_PLUGIN_PATH operating system environment variable to point to \"<plugins-path>\".\n\n" +
        "More information may be available in the log, specify -Dvlcj.log=DEBUG on the command-line when starting your application.\n\n";

    /**
     * Native library interface.
     */
    protected final LibVlc libvlc;

    /**
     * Native library instance.
     */
    protected final libvlc_instance_t instance;

    /**
     * Flag if the native equalizer is available or not.
     * <p>
     * Requires libvlc 2.2.0 or later.
     * <p>
     * This flag will be removed eventually when 2.1.0 and earlier are no longer supported.
     */
    private final boolean equalizerAvailable;

    /**
     * Cached equalizer band frequencies.
     */
    private final List<Float> equalizerBandFrequencies;

    /**
     * Cached equalizer preset names.
     */
    private final List<String> equalizerPresetNames;

    /**
     * True when the factory has been released.
     */
    private boolean released;

    /**
     * Create a new media player factory.
     * <p>
     * If you want to enable logging or synchronisation of the native library interface you must use
     * {@link #MediaPlayerFactory(LibVlc)} and {@link LibVlcFactory}.
     * <p>
     * This factory constructor will enforce a minimum required native library version check - if a
     * suitable native library version is not found a RuntimeException will be thrown.
     * <p>
     * If you do not want to enforce this version check, use one of the other constructors that
     * accepts a LibVlc instance that you obtain from the {@link LibVlcFactory}.
     */
    public MediaPlayerFactory() {
        this(new String[] {});
    }

    /**
     * Create a new media player factory.
     * <p>
     * If you want to enable logging or synchronisation of the native library interface you must use
     * {@link #MediaPlayerFactory(LibVlc)} and {@link LibVlcFactory}.
     * <p>
     * This factory constructor will enforce a minimum required native library version check - if a
     * suitable native library version is not found, a RuntimeException will be thrown.
     * <p>
     * If you do not want to enforce this version check, use one of the other constructors that
     * accepts a LibVlc instance that you obtain from the {@link LibVlcFactory}.
     * <p>
     * Most initialisation arguments may be gleaned by invoking <code>"vlc -H"</code>.
     *
     * @param libvlcArgs initialisation arguments to pass to libvlc
     */
    public MediaPlayerFactory(String... libvlcArgs) {
        this(LibVlcFactory.factory().atLeast("2.1.0").create(), libvlcArgs);
    }

    /**
     * Create a new media player factory.
     * <p>
     * Use {@link LibVlcFactory} to get a reference to the native library.
     *
     * @param libvlc interface to the native library
     */
    public MediaPlayerFactory(LibVlc libvlc) {
        this(libvlc, new String[] {});
    }

    /**
     * Create a new media player factory.
     * <p>
     * Use {@link LibVlcFactory} to get a reference to the native library.
     *
     * @param libvlc interface to the native library
     * @param libvlcArgs initialisation arguments to pass to libvlc
     */
    public MediaPlayerFactory(LibVlc libvlc, String... libvlcArgs) {
        Logger.debug("MediaPlayerFactory(libvlc={},libvlcArgs={})", libvlc, Arrays.toString(libvlcArgs));
        // JNA will look for the libvlc shared library here (and also libvlccore)...
        Logger.debug("jna.library.path={}", System.getProperty("jna.library.path"));
        // Convenience
        if(libvlcArgs == null) {
            libvlcArgs = new String[0];
        }
        // Ordinarily libvlc will look for it's plugins in a directory named "vlc/plugins" relative
        // to the directory where libvlccore is loaded from, this can be overridden by explicitly
        // specifying the "VLC_PLUGIN_PATH" system property (although this should not be necessary)
        String vlcPluginPath = System.getProperty("VLC_PLUGIN_PATH");
        Logger.debug("VLC_PLUGIN_PATH={}", vlcPluginPath);
        this.libvlc = libvlc;
        this.instance = libvlc.libvlc_new(libvlcArgs.length, libvlcArgs);
        Logger.debug("instance={}", instance);
        if(instance == null) {
            Logger.error("Failed to initialise libvlc");
            String msg = MessageFormat.format(PLUGIN_PATH_HELP, new Object[] {RuntimeUtil.getLibVlcName(), RuntimeUtil.getLibVlcCoreName(), RuntimeUtil.getPluginsDirectoryName()});
            throw new RuntimeException(msg);
        }
        // Cache the equalizer static data
        equalizerAvailable = LibVlcVersion.getVersion().atLeast(new Version("2.2.0"));
        Logger.debug("equalizerAvailable={}", equalizerAvailable);
        if(equalizerAvailable) {
            equalizerBandFrequencies = createEqualizerBandFrequencies();
            equalizerPresetNames = createEqualizerPresetNames();
        }
        else {
            equalizerBandFrequencies = null;
            equalizerPresetNames = null;
        }
    }

    /**
     * Create a new media player factory.
     * <p>
     * This is simply an alternate constructor for convenience, see
     * {@link #MediaPlayerFactory(String...)}.
     *
     * @param libvlcArgs initialisation arguments to pass to libvlc, may be empty but must not be <code>null</code>
     */
    public MediaPlayerFactory(List<String> libvlcArgs) {
        this(libvlcArgs.toArray(new String[libvlcArgs.size()]));
    }

    /**
     * Create a new media player factory.
     * <p>
     * Use {@link LibVlcFactory} to get a reference to the native library.
     * <p>
     * This is simply an alternate constructor for convenience, see
     * {@link #MediaPlayerFactory(LibVlc, String...)}.
     *
     * @param libvlc interface to the native library
     * @param libvlcArgs initialisation arguments to pass to libvlc, may be empty but must not be <code>null</code>
     */
    public MediaPlayerFactory(LibVlc libvlc, List<String> libvlcArgs) {
        this(libvlc, libvlcArgs.toArray(new String[libvlcArgs.size()]));
    }

    /**
     * Release the native resources associated with this factory.
     */
    public void release() {
        Logger.debug("release()");
        if(!released) {
            if(instance != null) {
                libvlc.libvlc_release(instance);
            }
            released = true;
        }
    }

    // === Factory Configuration ================================================

    /**
     * Set the application name.
     *
     * @param userAgent application name
     */
    public void setUserAgent(String userAgent) {
        Logger.debug("setUserAgent(userAgent={})", userAgent);
        setUserAgent(userAgent, null);
    }

    /**
     * Set the application name.
     *
     * @param userAgent application name
     * @param httpUserAgent application name for HTTP
     */
    public void setUserAgent(String userAgent, String httpUserAgent) {
        Logger.debug("setUserAgent(userAgent={},httpUserAgent={})", userAgent, httpUserAgent);
        libvlc.libvlc_set_user_agent(instance, userAgent, userAgent);
    }

    /**
     * Set the application identification information.
     *
     * @param id application id, e.g. com.somecompany.myapp
     * @param version application version
     * @param icon path to application icon
     *
     * @since libvlc 2.1.0
     */
    public void setApplicationId(String id, String version, String icon) {
        Logger.debug("setApplicationId(id=" + id + ",version=" + version + ",icon=" + icon + ")");
        libvlc.libvlc_set_app_id(instance, id, version, icon);
    }

    /**
     * Get the available audio outputs.
     * <p>
     * Each audio output has zero or more audio devices, each device having it's own unique
     * identifier that can be used on a media player to set the select the required output device.
     *
     * @return collection of audio outputs
     */
    public List<AudioOutput> getAudioOutputs() {
        Logger.debug("getAudioOutputs()");
        List<AudioOutput> result = new ArrayList<AudioOutput>();
        libvlc_audio_output_t audioOutputs = libvlc.libvlc_audio_output_list_get(instance);
        if(audioOutputs != null) {
            // Must prevent automatic synchronisation on the native structure, otherwise a
            // fatal JVM crash will occur when the native release call is made - not quite
            // sure why this is needed here
            audioOutputs.setAutoSynch(false);
            libvlc_audio_output_t audioOutput = audioOutputs;
            while(audioOutput != null) {
                // The native strings must be copied here, but not freed (they are freed natively
                // in the subsequent release call
                String name = NativeString.copyNativeString(libvlc, audioOutput.psz_name);
                String description = NativeString.copyNativeString(libvlc, audioOutput.psz_description);
                result.add(new AudioOutput(name, description, getAudioOutputDevices(name)));
                audioOutput = audioOutput.p_next;
            }
            libvlc.libvlc_audio_output_list_release(audioOutputs);
        }
        return result;
    }

    /**
     * Get the devices associated with an audio output.
     *
     * @param outputName output
     * @return collection of audio output devices
     */
    private List<AudioDevice> getAudioOutputDevices(String outputName) {
        Logger.debug("getAudioOutputDevices(outputName={})", outputName);
        List<AudioDevice> result = new ArrayList<AudioDevice>();
        libvlc_audio_output_device_t audioDevices = libvlc.libvlc_audio_output_device_list_get(instance, outputName);
        if (audioDevices != null) {
            // Must prevent automatic synchronisation on the native structure, otherwise a
            // fatal JVM crash will occur when the native release call is made - not quite
            // sure why this is needed here
            audioDevices.setAutoSynch(false);
            libvlc_audio_output_device_t audioDevice = audioDevices;
            while(audioDevice != null) {
                // The native strings must be copied here, but not freed (they are freed natively
                // in the subsequent release call)
                String device = NativeString.copyNativeString(libvlc, audioDevice.psz_device);
                String description = NativeString.copyNativeString(libvlc, audioDevice.psz_description);
                result.add(new AudioDevice(device, description));
                audioDevice = audioDevice.p_next;
            }
            libvlc.libvlc_audio_output_device_list_release(audioDevices);
        }
        return result;
    }

    /**
     * Get the available audio filters.
     *
     * @return collection of audio filter descriptions
     *
     * @since libvlc 2.0.0
     */
    public List<ModuleDescription> getAudioFilters() {
        Logger.debug("getAudioFilters()");
        libvlc_module_description_t moduleDescriptions = libvlc.libvlc_audio_filter_list_get(instance);
        // Without disabling auto synch on this JNA structure a fatal crash will
        // intermittently occur when the release call is made - this is the only
        // time (filters) in all of the vlcj bindings that this is required and I
        // do not understand why it is needed only in this case
        moduleDescriptions.setAutoSynch(false);
        List<ModuleDescription> result = getModuleDescriptions(moduleDescriptions);
        libvlc.libvlc_module_description_list_release(moduleDescriptions);
        return result;
    }

    /**
     * Get the available video filters.
     *
     * @return collection of video filter descriptions
     *
     * @since libvlc 2.0.0
     */
    public List<ModuleDescription> getVideoFilters() {
        Logger.debug("getVideoFilters()");
        libvlc_module_description_t moduleDescriptions = libvlc.libvlc_video_filter_list_get(instance);
        // Without disabling auto synch on this JNA structure a fatal crash will
        // intermittently occur when the release call is made - this is the only
        // time (filters) in all of the vlcj bindings that this is required and I
        // do not understand why it is needed only in this case
        moduleDescriptions.setAutoSynch(false);
        List<ModuleDescription> result = getModuleDescriptions(moduleDescriptions);
        libvlc.libvlc_module_description_list_release(moduleDescriptions);
        return result;
    }

    /**
     * Convert a collection of native module description structures.
     *
     * @param moduleDescriptions module descriptions
     * @return collection of module descriptions
     */
    private List<ModuleDescription> getModuleDescriptions(libvlc_module_description_t moduleDescriptions) {
        List<ModuleDescription> result = new ArrayList<ModuleDescription>();
        libvlc_module_description_t moduleDescription = moduleDescriptions;
        while(moduleDescription != null) {
            result.add(new ModuleDescription(moduleDescription.psz_name, moduleDescription.psz_shortname, moduleDescription.psz_longname, moduleDescription.psz_help));
            moduleDescription = moduleDescription.p_next;
        }
        return result;
    }

    // === Equalizer ============================================================

    /**
     * Is the audio equalizer available?
     *
     * This will be removed when libvlc 2.1.x is no longer supported.
     *
     * @return <code>true</code> if the equalizer is available; <code>false</code> otherwise
     */
    public final boolean isEqualizerAvailable() {
        return equalizerAvailable;
    }

    /**
     * Create the available equalizer band frequency values.
     *
     * @return list of equalizer band frequencies
     */
    private List<Float> createEqualizerBandFrequencies() {
        Logger.debug("createEqualizerBandFrequencies()");
        int numBands = libvlc.libvlc_audio_equalizer_get_band_count();
        Logger.debug("numBands={}", numBands);
        List<Float> result = new ArrayList<Float>(numBands);
        for(int i = 0; i < numBands; i++) {
            result.add(libvlc.libvlc_audio_equalizer_get_band_frequency(i));
        }
        Logger.debug("result={}", result);
        return Collections.unmodifiableList(result);
    }

    /**
     * Create the available equalizer preset names.
     *
     * @return list of equalizer preset names
     */
    private List<String> createEqualizerPresetNames() {
        Logger.debug("createEqualizerPresetNames()");
        int numPresets = libvlc.libvlc_audio_equalizer_get_preset_count();
        Logger.debug("numPresets={}", numPresets);
        List<String> result = new ArrayList<String>(numPresets);
        for(int i = 0; i < numPresets; i++) {
            result.add(libvlc.libvlc_audio_equalizer_get_preset_name(i));
        }
        Logger.debug("result={}", result);
        return Collections.unmodifiableList(result);
    }

    /**
     * Get the list of distinct equalizer band frequencies.
     *
     * @return list of frequencies (Hz)
     * @since libvlc 2.2.0
     */
    public final List<Float> getEqualizerBandFrequencies() {
        Logger.debug("getEqualizerBandFrequencies()");
        checkEqualizer();
        return equalizerBandFrequencies;
    }

    /**
     * Get the list of names of available equalizer presets.
     *
     * @return list of preset names
     * @since libvlc 2.2.0
     */
    public final List<String> getEqualizerPresetNames() {
        Logger.debug("getEqualizerPresetNames()");
        checkEqualizer();
        return equalizerPresetNames;
    }

    /**
     * Create a new audio equalizer.
     *
     * @return equalizer
     * @since libvlc 2.2.0
     */
    public final Equalizer newEqualizer() {
        Logger.debug("newEqualizer()");
        checkEqualizer();
        return new Equalizer(libvlc);
    }

    /**
     * Create a new audio equalizer from a named preset.
     *
     * @param presetName name of the preset
     * @return equalizer
     * @since libvlc 2.2.0
     */
    public final Equalizer newEqualizer(String presetName) {
        Logger.debug("newEqualizer(presetName={})", presetName);
        checkEqualizer();
        int index = equalizerPresetNames.indexOf(presetName);
        if(index != -1) {
            libvlc_equalizer_t presetEqualizer = libvlc.libvlc_audio_equalizer_new_from_preset(index);
            if(presetEqualizer != null) {
                Equalizer equalizer = new Equalizer(libvlc);
                equalizer.setPreamp(libvlc.libvlc_audio_equalizer_get_preamp(presetEqualizer));
                for(int i = 0; i < libvlc.libvlc_audio_equalizer_get_band_count(); i++) {
                    equalizer.setAmp(i, libvlc.libvlc_audio_equalizer_get_amp_at_index(presetEqualizer, i));
                }
                libvlc.libvlc_audio_equalizer_release(presetEqualizer);
                return equalizer;
            }
            else {
                return null;
            }
        }
        else {
            throw new IllegalArgumentException("No such preset named '" + presetName + "'");
        }
    }

    /**
     * Get all of the available preset equalizer instances.
     * <p>
     * This will return new equalizer instances (i.e. they are not cached or shared), so
     * applications are free to change the values in the returned equalizer instances if
     * so desired.
     *
     * @return map of preset name to equalizer instance, sorted by name
     * @since libvlc 2.2.0
     */
    public final Map<String, Equalizer> getAllPresetEqualizers() {
        Logger.debug("getAllPresetEqualizers()");
        checkEqualizer();
        Map<String, Equalizer> result = new TreeMap<String, Equalizer>();
        for(String presetName : equalizerPresetNames) {
            result.put(presetName, newEqualizer(presetName));
        }
        Logger.trace("result={}", result);
        return result;
    }

    /**
     * Check whether or not the audio equalizer is available.
     *
     * @throws UnsupportedOperationException if the equalizer is not available
     */
    private void checkEqualizer() {
        if(!equalizerAvailable) {
            throw new UnsupportedOperationException("Equalizer is not available, you need libvlc 2.2.0 or later");
        }
    }

    // === Media Player =========================================================

    /**
     * Create a new embedded media player.
     * <p>
     * Full-screen will not be available, to enable full-screen support see
     * {@link #newEmbeddedMediaPlayer(FullScreenStrategy)}, or use an alternate mechanism to
     * manually set full-screen if needed.
     *
     * @return media player instance
     */
    public EmbeddedMediaPlayer newEmbeddedMediaPlayer() {
        Logger.debug("newEmbeddedMediaPlayer()");
        return newEmbeddedMediaPlayer(null);
    }

    /**
     * Create a new embedded media player.
     *
     * @param fullScreenStrategy full screen implementation, may be <code>null</code>
     * @return media player instance
     */
    public EmbeddedMediaPlayer newEmbeddedMediaPlayer(FullScreenStrategy fullScreenStrategy) {
        Logger.debug("newEmbeddedMediaPlayer(fullScreenStrategy={})", fullScreenStrategy);
        return new DefaultEmbeddedMediaPlayer(libvlc, instance, fullScreenStrategy);
    }

    /**
     * Create a new direct video rendering media player.
     *
     * @param bufferFormatCallback callback to set the desired buffer format
     * @param renderCallback callback to receive the video frame data
     * @return media player instance
     */
    public DirectMediaPlayer newDirectMediaPlayer(BufferFormatCallback bufferFormatCallback, RenderCallback renderCallback) {
        Logger.debug("newDirectMediaPlayer(formatCallback={},renderCallback={})", bufferFormatCallback, renderCallback);
        return new DefaultDirectMediaPlayer(libvlc, instance, bufferFormatCallback, renderCallback);
    }

    /**
     * Create a new direct audio media player.
     *
     * @param format decoded audio format
     * @param rate decoded audio sample rate
     * @param channels decoded audio channels
     * @param audioCallback callback
     * @return media player instance
     */
    public DirectAudioPlayer newDirectAudioPlayer(String format, int rate, int channels, AudioCallback audioCallback) {
        Logger.debug("newDirectAudioPlayer(format={},rate={},channels={},audioCallback={}", format, rate, channels, audioCallback);
        return new DefaultDirectAudioPlayer(libvlc, instance, format, rate, channels, audioCallback);
    }

    /**
     * Create a new headless media player.
     * <p>
     * The head-less player is intended for audio media players or streaming server media players
     * and may spawn a native video player window unless you set proper media options when playing
     * media.
     *
     * @return media player instance
     */
    public HeadlessMediaPlayer newHeadlessMediaPlayer() {
        Logger.debug("newHeadlessMediaPlayer()");
        return new DefaultHeadlessMediaPlayer(libvlc, instance);
    }

    /**
     * Create a new play-list media player.
     *
     * @return media player instance
     */
    public MediaListPlayer newMediaListPlayer() {
        Logger.debug("newMediaListPlayer()");
        return new DefaultMediaListPlayer(libvlc, instance);
    }

    // === Video Surface ========================================================

    /**
     * Create a new video surface for a Canvas.
     *
     * @param canvas canvas
     * @return video surface
     */
    public CanvasVideoSurface newVideoSurface(Canvas canvas) {
        Logger.debug("newVideoSurface(canvas={})", canvas);
        VideoSurfaceAdapter videoSurfaceAdapter;
        if(RuntimeUtil.isNix()) {
            videoSurfaceAdapter = new LinuxVideoSurfaceAdapter();
        }
        else if(RuntimeUtil.isWindows()) {
            videoSurfaceAdapter = new WindowsVideoSurfaceAdapter();
        }
        else if(RuntimeUtil.isMac()) {
            videoSurfaceAdapter = new MacVideoSurfaceAdapter();
        }
        else {
            throw new RuntimeException("Unable to create a media player - failed to detect a supported operating system");
        }
        CanvasVideoSurface videoSurface = new CanvasVideoSurface(canvas, videoSurfaceAdapter);
        Logger.debug("videoSurface={}", videoSurface);
        return videoSurface;
    }

    /**
     * Create a new video surface for a native component id.
     *
     * @param componentId native component id
     * @return video surface
     */
    public ComponentIdVideoSurface newVideoSurface(long componentId) {
        Logger.debug("newVideoSurface(componentId={})", componentId);
        VideoSurfaceAdapter videoSurfaceAdapter;
        if(RuntimeUtil.isNix()) {
            videoSurfaceAdapter = new LinuxVideoSurfaceAdapter();
        }
        else if(RuntimeUtil.isWindows()) {
            videoSurfaceAdapter = new WindowsVideoSurfaceAdapter();
        }
        else if(RuntimeUtil.isMac()) {
            videoSurfaceAdapter = new MacVideoSurfaceAdapter();
        }
        else {
            throw new RuntimeException("Unable to create a media player - failed to detect a supported operating system");
        }
        ComponentIdVideoSurface videoSurface = new ComponentIdVideoSurface(componentId, videoSurfaceAdapter);
        Logger.debug("videoSurface={}", videoSurface);
        return videoSurface;
    }

    // === Media List ===========================================================

    /**
     * Create a new media list for a play-list media player.
     *
     * @return media list instance
     */
    public MediaList newMediaList() {
        Logger.debug("newMediaList()");
        return new MediaList(libvlc, instance);
    }

    // === Meta Data ============================================================

    /**
     * Get local media meta data.
     * <p>
     * Note that requesting meta data may cause one or more HTTP connections to
     * be made to external web-sites to attempt download of album art.
     * <p>
     * This method should <strong>not</strong> be invoked for non-local MRL's
     * like streaming network addresses.
     *
     * @param mediaPath path to the local media
     * @param parse <code>true</code> if the media should be parsed immediately</code>; otherwise <code>false</code>
     * @return media meta data, or <code>null</code> if the media could not be located
     */
    public MediaMeta getMediaMeta(String mediaPath, boolean parse) {
        Logger.debug("getMediaMeta(mediaPath={},parse={})", mediaPath, parse);
        libvlc_media_t media = libvlc.libvlc_media_new_path(instance, mediaPath);
        Logger.debug("media={}", media);
        if(media != null) {
            if(parse) {
                Logger.debug("Parsing media...");
                libvlc.libvlc_media_parse(media);
                Logger.debug("Media parsed.");
            }
            MediaMeta mediaMeta = new DefaultMediaMeta(libvlc, media);
            // Release this native reference, the media meta instance retains its own native reference
            libvlc.libvlc_media_release(media);
            return mediaMeta;
        }
        else {
            return null;
        }
    }

    // === Log ==================================================================

    /**
     * Create a new native log component.
     * <p>
     * <strong>The native log requires vlc 2.1.0 or later.</strong>
     *
     * @return native log component, or <code>null</code> if the native log is not available
     */
    public NativeLog newLog() {
        Logger.debug("newLog()");
        if(LibVlcVersion.getVersion().atLeast(LibVlcVersion.LIBVLC_210)) {
            return new NativeLog(libvlc, instance);
        }
        else {
            Logger.warn("Native log not available on this platform, needs libvlc 2.1.0 or later");
            return null;
        }
    }

    // === Media Discoverer =====================================================

    /**
     * Create a new native media service discoverer.
     * <p>
     * Not all media discoveres are supported on all platforms.
     *
     * @param name name of the required service discoverer, e.g. "audio", "video".
     * @return native media discoverer component
     */
    public MediaDiscoverer newMediaDiscoverer(String name) {
        Logger.debug("newMediaDiscoverer(name={})", name);
        return new MediaDiscoverer(libvlc, instance, name);
    }

    /**
     * Create a new native audio media service discoverer.
     * <p>
     * This method is simply a convenient wrapper around {@link #newMediaDiscoverer(String)}.
     *
     * @return native media discoverer component
     */
    public MediaDiscoverer newAudioMediaDiscoverer() {
        Logger.debug("newAudioMediaDiscoverer()");
        return newMediaDiscoverer("audio");
    }

    /**
     * Create a new native video media service discoverer.
     * <p>
     * This should return for example video capture devices currently attached to
     * the system.
     * <p>
     * This method is simply a convenient wrapper around {@link #newMediaDiscoverer(String)}.
     * <p>
     * The video discoverer may not be available on all platforms.
     *
     * @return native media discoverer component
     */
    public MediaDiscoverer newVideoMediaDiscoverer() {
        Logger.debug("newVideoMediaDiscoverer()");
        return newMediaDiscoverer("video");
    }

    // === Clock ================================================================

    /**
     * Get the time as defined by LibVLC.
     * <p>
     * The time is not meaningful in the sense of what time is it, rather it is a monotonic clock
     * with an arbitrary starting value.
     *
     * @return current clock time value, in microseconds
     */
    public long clock() {
        Logger.trace("clock()");
        return libvlc.libvlc_clock();
    }

    // === Media Manager ========================================================

    /**
     * Create a new media manager.
     *
     * @return media manager instance
     */
    public MediaManager newMediaManager() {
        Logger.trace("newMediaManager()");
        return new DefaultMediaManager(libvlc, instance);
    }

    // === Build Information ====================================================

    /**
     * Get the libvlc version.
     *
     * @return native library version
     */
    public String version() {
        Logger.debug("version()");
        return libvlc.libvlc_get_version();
    }

    /**
     * Get the compiler used to build libvlc.
     *
     * @return compiler
     */
    public String compiler() {
        Logger.debug("compiler()");
        return libvlc.libvlc_get_compiler();
    }

    /**
     * Get the source code change-set id used to build libvlc.
     *
     * @return change-set
     */
    public String changeset() {
        Logger.debug("changeset()");
        return libvlc.libvlc_get_changeset();
    }
}
TOP

Related Classes of uk.co.caprica.vlcj.player.MediaPlayerFactory

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.