/***************************************************************************** * LibVLC.java ***************************************************************************** * Copyright © 2010-2012 VLC authors and VideoLAN * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ package org.videolan.vlc; import java.util.ArrayList; import org.videolan.vlc.LibVlcException; import tv.danmaku.pragma.Pragma; import tv.danmaku.android.util.CollectionHelper; import tv.danmaku.android.util.DebugLog; //import tv.danmaku.bili.pluginapk.PluginApkManager; import android.content.Context; import android.view.Surface; public class LibVLC { private static final String TAG = "VLC/LibVLC"; private static final String[] sDefaultParameters = new String[] { "-I", "dummy", "--no-osd", "--no-plugins-cache", "--no-drop-late-frames", "--no-video-title-show", "--no-stats", "--avcodec-fast", "--avcodec-threads=0", "--http-hosts-reject-range", "v.youku.com,f.youku.com", "--ts-seek-percent" }; private static boolean mLibIomxLoaded = false; private static boolean mLibVlcLoaded = false; private static LibVLC sInstance; /** libVLC instance C pointer */ private long mLibVlcInstance = 0; // Read-only, reserved for JNI /** libvlc_media_list_player pointer */ private long mMediaListPlayerInstance = 0; // Read-only, reserved for JNI private long mInternalMediaPlayerInstance = 0; // Read-only, reserved for // JNI /** libvlc_media_list_t pointer */ private long mMediaListInstance = 0; // Read-only, reserved for JNI private Aout mAout; /** Keep screen bright */ // private WakeLock mWakeLock; /** Check in libVLC already initialized otherwise crash */ private boolean mIsInitialized = false; public native void attachSurface(Surface surface, Object parentView, int width, int height); public native void detachSurface(); /* Load library before object instantiation */ private static void loadLib(Context context, LibVlcLibraryLoader libLoader) throws LibVlcException { synchronized (LibVLC.class) { if (!mLibIomxLoaded) { try { libLoader.loadVlcLibIomx(context); } catch (Throwable t) { DebugLog.w(TAG, "Unable to load the iomx library: " + t); System.exit(1); } } if (mLibVlcLoaded) return; try { DebugLog.d(TAG, "loading vlcjni"); libLoader.loadLibVlc(context); DebugLog.d(TAG, "vlcjni loaded: "); mLibVlcLoaded = true; } catch (UnsatisfiedLinkError ule) { DebugLog.e(TAG, "Can't load vlcjni library: " + ule); // / FIXME: Alert user System.exit(1); } catch (SecurityException se) { DebugLog.e(TAG, "Encountered a security issue when loading vlcjni library: " + se); // / FIXME: Alert user System.exit(1); } } } /** * Singleton constructor Without surface and vout to create the thumbnail * and get information e.g. on the MediaLibraryAcitvity * * @return * @throws LibVlcException */ public static LibVLC getInstance(Context context, LibVlcLibraryLoader libLoader) throws LibVlcException { synchronized (LibVLC.class) { if (sInstance == null) { /* First call */ loadLib(context, libLoader); sInstance = new LibVLC(); ArrayList<String> params = new ArrayList<String>(); CollectionHelper.Append(params, sDefaultParameters); DebugLog.v(TAG, "libvlc arguments:"); for (String par : params) { DebugLog.v(TAG, " " + par); } sInstance.initEx(params.toArray(new String[params.size()])); } return sInstance; } } static LibVLC getExistingInstance() { synchronized (LibVLC.class) { return sInstance; } } public static void destroyExistingInstance() { synchronized (LibVLC.class) { if (sInstance != null) { sInstance.destroy(); sInstance = null; } } } /** * Constructor It is private because this class is a singleton. */ private LibVLC() { mAout = new Aout(); } /** * Destructor: It is bad practice to rely on them, so please don't forget to * call destroy() before exiting. */ public void finalize() { if (mLibVlcInstance != 0) { DebugLog.d(TAG, "LibVLC is was destroyed yet before finalize()"); destroy(); } } /** * Give to LibVLC the surface to draw the video. * * @param f * the surface to draw */ public native void setSurface(Surface f); /** * Initialize the libVLC class */ private void initEx(String[] params) throws LibVlcException { DebugLog.v(TAG, "Initializing LibVLC"); if (!mIsInitialized) { nativeInitEx(Pragma.DEBUG, params); setEventManager(EventManager.getIntance()); mIsInitialized = true; } } /** * Destroy this libVLC instance * * @note You must call it before exiting */ public void destroy() { DebugLog.v(TAG, "Destroying LibVLC instance"); nativeDestroy(); detachEventManager(); mIsInitialized = false; } /** * Open the Java audio output. This function is called by the native code */ public void initAout(int sampleRateInHz, int channels, int samples) { DebugLog.d(TAG, "Opening the java audio output"); mAout.init(sampleRateInHz, channels, samples); } /** * Play an audio buffer taken from the native code This function is called * by the native code */ public void playAudio(byte[] audioData, int bufferSize) { mAout.playBuffer(audioData, bufferSize); } /** * Close the Java audio output This function is called by the native code */ public void closeAout() { DebugLog.d(TAG, "Closing the java audio output"); mAout.release(); } /** * Read a media. */ public void readMediaEx(String mrl, String[] options) { DebugLog.v(TAG, "Reading " + mrl); DebugLog.v(TAG, "libvlcplayer options:"); for (String opt : options) { DebugLog.v(TAG, " " + opt); } readMediaEx(mLibVlcInstance, mrl, options); } /** * Change the verbosity of libvlc * * @param verbose * : true for increased verbosity */ public native void changeVerbosity(boolean verbose); /** * Initialize the libvlc C library * * @return a pointer to the libvlc instance */ private native void nativeInitEx(boolean verbose, String[] params) throws LibVlcException; /** * Close the libvlc C library * * @note mLibVlcInstance should be 0 after a call to destroy() */ private native void nativeDestroy(); /** * Read a media * * @param instance * : the instance of libVLC * @param mrl * : the media mrl */ private native void readMediaEx(long instance, String mrl, String[] options); /** * Return true if there is currently a running media player. */ public native boolean hasMediaPlayer(); /** * Returns true if any media is playing */ public native boolean isPlaying(); /** * Returns true if any media is seekable */ public native boolean isSeekable(); /** * Plays any loaded media */ public native void play(); /** * Pauses any playing media */ public native void pause(); /** * Stops any playing media */ public native void stop(); /** * Gets the current movie time (in ms). * * @return the movie time (in ms), or -1 if there is no media. */ public native long getTime(); /** * Sets the movie time (in ms), if any media is being played. * * @param time * : Time in ms. * @return the movie time (in ms), or -1 if there is no media. */ public native long setTime(long time); /** * Gets the movie position. * * @return the movie position, or -1 for any error. */ public native float getPosition(); /** * Sets the movie position. * * @param pos * : movie position. */ public native void setPosition(float pos); /** * Gets current movie's length in ms. * * @return the movie length (in ms), or -1 if there is no media. */ public native long getLength(); private native void setEventManager(EventManager eventManager); private native void detachEventManager(); }