Repository: over140/vlc-android-demo Branch: master Commit: 9adcbf8687bf Files: 27 Total size: 93.5 KB Directory structure: gitextract_zhjhf_95/ ├── .gitignore ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── nmbb/ │ │ └── vlc/ │ │ └── ApplicationTest.java │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ ├── com/ │ │ │ └── nmbb/ │ │ │ └── vlc/ │ │ │ ├── VLCApplication.java │ │ │ └── ui/ │ │ │ └── VlcVideoActivity.java │ │ └── org/ │ │ └── videolan/ │ │ ├── libvlc/ │ │ │ ├── AudioOutput.java │ │ │ ├── EventHandler.java │ │ │ ├── IVideoPlayer.java │ │ │ ├── LibVLC.java │ │ │ ├── LibVlcException.java │ │ │ ├── LibVlcUtil.java │ │ │ ├── Media.java │ │ │ ├── MediaList.java │ │ │ └── TrackInfo.java │ │ └── vlc/ │ │ └── util/ │ │ ├── Preferences.java │ │ └── VLCInstance.java │ └── res/ │ ├── layout/ │ │ └── activity_video_vlc.xml │ ├── values/ │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── values-w820dp/ │ └── dimens.xml ├── build.gradle ├── gradle.properties └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /.idea *.iml /gradle gradlew gradlew.bat proguard-rules.pro ================================================ FILE: README.md ================================================ vlc-android-demo ================ ================================================ FILE: app/.gitignore ================================================ /build ================================================ FILE: app/build.gradle ================================================ apply plugin: 'android' android { compileSdkVersion 19 buildToolsVersion "19.1.0" defaultConfig { applicationId "com.nmbb.vlc" minSdkVersion 9 targetSdkVersion 19 versionCode 1 versionName "1.0" } buildTypes { release { runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:19.1.0' } ================================================ FILE: app/src/androidTest/java/com/nmbb/vlc/ApplicationTest.java ================================================ package com.nmbb.vlc; import android.app.Application; import android.test.ApplicationTestCase; /** * Testing Fundamentals */ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/java/com/nmbb/vlc/VLCApplication.java ================================================ package com.nmbb.vlc; import android.app.Application; import android.content.Context; /** * Created by tangjun on 14-8-24. */ public class VLCApplication extends Application { private static VLCApplication sInstance; @Override public void onCreate() { super.onCreate(); sInstance = this; } public static Context getAppContext() { return sInstance; } } ================================================ FILE: app/src/main/java/com/nmbb/vlc/ui/VlcVideoActivity.java ================================================ package com.nmbb.vlc.ui; import android.app.Activity; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.media.AudioManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import com.nmbb.vlc.R; import org.videolan.libvlc.EventHandler; import org.videolan.libvlc.IVideoPlayer; import org.videolan.libvlc.LibVLC; import org.videolan.libvlc.LibVlcException; import org.videolan.vlc.util.VLCInstance; public class VlcVideoActivity extends Activity implements SurfaceHolder.Callback, IVideoPlayer { private final static String TAG = "[VlcVideoActivity]"; private SurfaceView mSurfaceView; private LibVLC mMediaPlayer; private SurfaceHolder mSurfaceHolder; private View mLoadingView; private int mVideoHeight; private int mVideoWidth; private int mVideoVisibleHeight; private int mVideoVisibleWidth; private int mSarNum; private int mSarDen; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_video_vlc); mSurfaceView = (SurfaceView) findViewById(R.id.video); mLoadingView = findViewById(R.id.video_loading); try { mMediaPlayer = VLCInstance.getLibVlcInstance(); } catch (LibVlcException e) { e.printStackTrace(); } mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setFormat(PixelFormat.RGBX_8888); mSurfaceHolder.addCallback(this); mMediaPlayer.eventVideoPlayerActivityCreated(true); EventHandler em = EventHandler.getInstance(); em.addHandler(mVlcHandler); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); mSurfaceView.setKeepScreenOn(true); // mMediaPlayer.setMediaList(); // mMediaPlayer.getMediaList().add(new Media(mMediaPlayer, "http://live.3gv.ifeng.com/zixun.m3u8"), false); // mMediaPlayer.playIndex(0); mMediaPlayer.playMRL("http://live.3gv.ifeng.com/zixun.m3u8"); } @Override public void onPause() { super.onPause(); if (mMediaPlayer != null) { mMediaPlayer.stop(); mSurfaceView.setKeepScreenOn(false); } } @Override protected void onDestroy() { super.onDestroy(); if (mMediaPlayer != null) { mMediaPlayer.eventVideoPlayerActivityCreated(false); EventHandler em = EventHandler.getInstance(); em.removeHandler(mVlcHandler); } } @Override public void onConfigurationChanged(Configuration newConfig) { setSurfaceSize(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight, mSarNum, mSarDen); super.onConfigurationChanged(newConfig); } @Override public void surfaceCreated(SurfaceHolder holder) { if (mMediaPlayer != null) { mSurfaceHolder = holder; mMediaPlayer.attachSurface(holder.getSurface(), this); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mSurfaceHolder = holder; if (mMediaPlayer != null) { mMediaPlayer.attachSurface(holder.getSurface(), this);//, width, height } if (width > 0) { mVideoHeight = height; mVideoWidth = width; } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mMediaPlayer != null) { mMediaPlayer.detachSurface(); } } @Override public void setSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den) { mVideoHeight = height; mVideoWidth = width; mVideoVisibleHeight = visible_height; mVideoVisibleWidth = visible_width; mSarNum = sar_num; mSarDen = sar_den; mHandler.removeMessages(HANDLER_SURFACE_SIZE); mHandler.sendEmptyMessage(HANDLER_SURFACE_SIZE); } private static final int HANDLER_BUFFER_START = 1; private static final int HANDLER_BUFFER_END = 2; private static final int HANDLER_SURFACE_SIZE = 3; private static final int SURFACE_BEST_FIT = 0; private static final int SURFACE_FIT_HORIZONTAL = 1; private static final int SURFACE_FIT_VERTICAL = 2; private static final int SURFACE_FILL = 3; private static final int SURFACE_16_9 = 4; private static final int SURFACE_4_3 = 5; private static final int SURFACE_ORIGINAL = 6; private int mCurrentSize = SURFACE_BEST_FIT; private Handler mVlcHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg == null || msg.getData() == null) return; switch (msg.getData().getInt("event")) { case EventHandler.MediaPlayerTimeChanged: break; case EventHandler.MediaPlayerPositionChanged: break; case EventHandler.MediaPlayerPlaying: mHandler.removeMessages(HANDLER_BUFFER_END); mHandler.sendEmptyMessage(HANDLER_BUFFER_END); break; case EventHandler.MediaPlayerBuffering: break; case EventHandler.MediaPlayerLengthChanged: break; case EventHandler.MediaPlayerEndReached: //播放完成 break; } } }; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case HANDLER_BUFFER_START: showLoading(); break; case HANDLER_BUFFER_END: hideLoading(); break; case HANDLER_SURFACE_SIZE: changeSurfaceSize(); break; } } }; private void showLoading() { mLoadingView.setVisibility(View.VISIBLE); } private void hideLoading() { mLoadingView.setVisibility(View.GONE); } private void changeSurfaceSize() { // get screen size int dw = getWindowManager().getDefaultDisplay().getWidth(); int dh = getWindowManager().getDefaultDisplay().getHeight(); // calculate aspect ratio double ar = (double) mVideoWidth / (double) mVideoHeight; // calculate display aspect ratio double dar = (double) dw / (double) dh; switch (mCurrentSize) { case SURFACE_BEST_FIT: if (dar < ar) dh = (int) (dw / ar); else dw = (int) (dh * ar); break; case SURFACE_FIT_HORIZONTAL: dh = (int) (dw / ar); break; case SURFACE_FIT_VERTICAL: dw = (int) (dh * ar); break; case SURFACE_FILL: break; case SURFACE_16_9: ar = 16.0 / 9.0; if (dar < ar) dh = (int) (dw / ar); else dw = (int) (dh * ar); break; case SURFACE_4_3: ar = 4.0 / 3.0; if (dar < ar) dh = (int) (dw / ar); else dw = (int) (dh * ar); break; case SURFACE_ORIGINAL: dh = mVideoHeight; dw = mVideoWidth; break; } mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight); ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams(); lp.width = dw; lp.height = dh; mSurfaceView.setLayoutParams(lp); mSurfaceView.invalidate(); } } ================================================ FILE: app/src/main/java/org/videolan/libvlc/AudioOutput.java ================================================ /***************************************************************************** * Aout.java ***************************************************************************** * Copyright © 2011-2012 VLC authors and VideoLAN * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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.libvlc; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; import android.util.Log; public class AudioOutput { /** * Java side of the audio output module for Android. * Uses an AudioTrack to play decoded audio buffers. * * TODO Use MODE_STATIC instead of MODE_STREAM with a MemoryFile (ashmem) */ public AudioOutput() { } private AudioTrack mAudioTrack; private static final String TAG = "LibVLC/aout"; public void init(int sampleRateInHz, int channels, int samples) { Log.d(TAG, sampleRateInHz + ", " + channels + ", " + samples + "=>" + channels * samples); int minBufferSize = AudioTrack.getMinBufferSize(sampleRateInHz, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT); mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRateInHz, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, Math.max(minBufferSize, channels * samples * 2), AudioTrack.MODE_STREAM); } public void release() { if (mAudioTrack != null) { mAudioTrack.release(); } mAudioTrack = null; } public void playBuffer(byte[] audioData, int bufferSize) { if (mAudioTrack.getState() == AudioTrack.STATE_UNINITIALIZED) return; if (mAudioTrack.write(audioData, 0, bufferSize) != bufferSize) { Log.w(TAG, "Could not write all the samples to the audio device"); } mAudioTrack.play(); } public void pause() { mAudioTrack.pause(); } } ================================================ FILE: app/src/main/java/org/videolan/libvlc/EventHandler.java ================================================ /***************************************************************************** * EventHandler.java ***************************************************************************** * Copyright © 2011-2014 VLC authors and VideoLAN * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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.libvlc; import android.os.Bundle; import android.os.Handler; import android.os.Message; import java.util.ArrayList; public class EventHandler { /* * Be sure to subscribe to events you need in the JNI too. */ //public static final int MediaMetaChanged = 0; //public static final int MediaSubItemAdded = 1; //public static final int MediaDurationChanged = 2; public static final int MediaParsedChanged = 3; //public static final int MediaFreed = 4; //public static final int MediaStateChanged = 5; //public static final int MediaPlayerMediaChanged = 0x100; //public static final int MediaPlayerNothingSpecial = 0x101; //public static final int MediaPlayerOpening = 0x102; public static final int MediaPlayerBuffering = 0x103; public static final int MediaPlayerPlaying = 0x104; public static final int MediaPlayerPaused = 0x105; public static final int MediaPlayerStopped = 0x106; //public static final int MediaPlayerForward = 0x107; //public static final int MediaPlayerBackward = 0x108; public static final int MediaPlayerEndReached = 0x109; public static final int MediaPlayerEncounteredError = 0x10a; public static final int MediaPlayerTimeChanged = 0x10b; public static final int MediaPlayerPositionChanged = 0x10c; //public static final int MediaPlayerSeekableChanged = 0x10d; //public static final int MediaPlayerPausableChanged = 0x10e; //public static final int MediaPlayerTitleChanged = 0x10f; //public static final int MediaPlayerSnapshotTaken = 0x110; public static final int MediaPlayerLengthChanged = 0x111; public static final int MediaPlayerVout = 0x112; //public static final int MediaListItemAdded = 0x200; //public static final int MediaListWillAddItem = 0x201; //public static final int MediaListItemDeleted = 0x202; //public static final int MediaListWillDeleteItem = 0x203; //public static final int MediaListViewItemAdded = 0x300; //public static final int MediaListViewWillAddItem = 0x301; //public static final int MediaListViewItemDeleted = 0x302; //public static final int MediaListViewWillDeleteItem = 0x303; //public static final int MediaListPlayerPlayed = 0x400; //public static final int MediaListPlayerNextItemSet = 0x401; //public static final int MediaListPlayerStopped = 0x402; //public static final int MediaDiscovererStarted = 0x500; //public static final int MediaDiscovererEnded = 0x501; //public static final int VlmMediaAdded = 0x600; //public static final int VlmMediaRemoved = 0x601; //public static final int VlmMediaChanged = 0x602; //public static final int VlmMediaInstanceStarted = 0x603; //public static final int VlmMediaInstanceStopped = 0x604; //public static final int VlmMediaInstanceStatusInit = 0x605; //public static final int VlmMediaInstanceStatusOpening = 0x606; //public static final int VlmMediaInstanceStatusPlaying = 0x607; //public static final int VlmMediaInstanceStatusPause = 0x608; //public static final int VlmMediaInstanceStatusEnd = 0x609; //public static final int VlmMediaInstanceStatusError = 0x60a; public static final int CustomMediaListExpanding = 0x2000; public static final int CustomMediaListExpandingEnd = 0x2001; public static final int CustomMediaListItemAdded = 0x2002; public static final int CustomMediaListItemDeleted = 0x2003; public static final int CustomMediaListItemMoved = 0x2004; public static final int HardwareAccelerationError = 0x3000; private ArrayList mEventHandler; private static EventHandler mInstance; EventHandler() { mEventHandler = new ArrayList(); } public static EventHandler getInstance() { if (mInstance == null) { mInstance = new EventHandler(); } return mInstance; } public void addHandler(Handler handler) { if (!mEventHandler.contains(handler)) mEventHandler.add(handler); } public void removeHandler(Handler handler) { mEventHandler.remove(handler); } /** This method is called by a native thread **/ public void callback(int event, Bundle b) { b.putInt("event", event); for (int i = 0; i < mEventHandler.size(); i++) { Message msg = Message.obtain(); msg.setData(b); mEventHandler.get(i).sendMessage(msg); } } } ================================================ FILE: app/src/main/java/org/videolan/libvlc/IVideoPlayer.java ================================================ /***************************************************************************** * IVideoPlayer.java ***************************************************************************** * Copyright © 2010-2013 VLC authors and VideoLAN * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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.libvlc; public interface IVideoPlayer { /** * This method is called by native vout to request a surface resize when frame size doesn't match surface size. * @param width Frame width * @param height Frame height * @param visible_width Visible frame width * @param visible_height Visible frame height * @param sar_num Surface aspect ratio numerator * @param sar_den Surface aspect ratio denominator */ void setSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den); } ================================================ FILE: app/src/main/java/org/videolan/libvlc/LibVLC.java ================================================ /***************************************************************************** * LibVLC.java ***************************************************************************** * Copyright © 2010-2013 VLC authors and VideoLAN * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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.libvlc; import android.content.Context; import android.os.Build; import android.util.Log; import android.view.Surface; import java.io.File; import java.util.ArrayList; import java.util.Map; public class LibVLC { private static final String TAG = "VLC/LibVLC"; public static final int AOUT_AUDIOTRACK_JAVA = 0; public static final int AOUT_AUDIOTRACK = 1; public static final int AOUT_OPENSLES = 2; public static final int VOUT_ANDROID_SURFACE = 0; public static final int VOUT_OPEGLES2 = 1; public static final int HW_ACCELERATION_AUTOMATIC = -1; public static final int HW_ACCELERATION_DISABLED = 0; public static final int HW_ACCELERATION_DECODING = 1; public static final int HW_ACCELERATION_FULL = 2; private static LibVLC sInstance; /** libVLC instance C pointer */ private long mLibVlcInstance = 0; // Read-only, reserved for JNI /** libvlc_media_player pointer and index */ private int mInternalMediaPlayerIndex = 0; // Read-only, reserved for JNI private long mInternalMediaPlayerInstance = 0; // Read-only, reserved for JNI private MediaList mMediaList; // Pointer to media list being followed private MediaList mPrimaryList; // Primary/default media list; see getPrimaryMediaList() /** Buffer for VLC messages */ private StringBuffer mDebugLogBuffer; private boolean mIsBufferingLog = false; private AudioOutput mAout; /** Keep screen bright */ //private WakeLock mWakeLock; /** Settings */ private int hardwareAcceleration = HW_ACCELERATION_AUTOMATIC; private String subtitlesEncoding = ""; private int aout = LibVlcUtil.isGingerbreadOrLater() ? AOUT_OPENSLES : AOUT_AUDIOTRACK_JAVA; private int vout = VOUT_ANDROID_SURFACE; private boolean timeStretching = false; private int deblocking = -1; private String chroma = ""; private boolean verboseMode = true; private float[] equalizer = null; private boolean frameSkip = false; private int networkCaching = 0; /** Path of application-specific cache */ private String mCachePath = ""; /** Native crash handler */ private OnNativeCrashListener mOnNativeCrashListener; /** Check in libVLC already initialized otherwise crash */ private boolean mIsInitialized = false; public native void attachSurface(Surface surface, IVideoPlayer player); public native void detachSurface(); public native void attachSubtitlesSurface(Surface surface); public native void detachSubtitlesSurface(); public native void eventVideoPlayerActivityCreated(boolean created); /* Load library before object instantiation */ static { try { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) System.loadLibrary("iomx-gingerbread"); else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2) System.loadLibrary("iomx-hc"); else System.loadLibrary("iomx-ics"); } catch (Throwable t) { // No need to warn if it isn't found, when we intentionally don't build these except for debug if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) Log.w(TAG, "Unable to load the iomx library: " + t); } try { System.loadLibrary("vlcjni"); } catch (UnsatisfiedLinkError ule) { Log.e(TAG, "Can't load vlcjni library: " + ule); /// FIXME Alert user System.exit(1); } catch (SecurityException se) { Log.e(TAG, "Encountered a security issue when loading vlcjni library: " + se); /// FIXME Alert user System.exit(1); } } /** * Singleton constructor of libVLC Without surface and vout to create the * thumbnail and get information e.g. on the MediaLibraryActivity * * @return libVLC instance * @throws org.videolan.libvlc.LibVlcException */ public static LibVLC getInstance() throws LibVlcException { synchronized (LibVLC.class) { if (sInstance == null) { /* First call */ sInstance = new LibVLC(); } } return sInstance; } /** * Return an existing instance of libVLC Call it when it is NOT important * that this fails * * @return libVLC instance OR null */ public static LibVLC getExistingInstance() { synchronized (LibVLC.class) { return sInstance; } } /** * Constructor * It is private because this class is a singleton. */ private LibVLC() { mAout = new AudioOutput(); } /** * Destructor: * It is bad practice to rely on them, so please don't forget to call * destroy() before exiting. */ @Override protected void finalize() { if (mLibVlcInstance != 0) { Log.d(TAG, "LibVLC is was destroyed yet before finalize()"); destroy(); } } /** * Get the media list that LibVLC is following right now. * * @return The media list object being followed */ public MediaList getMediaList() { return mMediaList; } /** * Set the media list for LibVLC to follow. * * @param mediaList The media list object to follow */ public void setMediaList(MediaList mediaList) { mMediaList = mediaList; } /** * Sets LibVLC to follow the default media list (see below) */ public void setMediaList() { mMediaList = mPrimaryList; } /** * Gets the primary media list, or the "currently playing" list. * Not to be confused with the media list pointer from above, which * refers the the MediaList object that libVLC is currently following. * This list is just one out of many lists that it can be pointed towards. * * This list will be used for lists of songs that are not user-defined. * For example: selecting a song from the Songs list, or from the list * displayed after selecting an album. * * It is loaded as the default list. * * @return The primary media list */ public MediaList getPrimaryMediaList() { return mPrimaryList; } /** * Give to LibVLC the surface to draw the video. * @param f the surface to draw */ public native void setSurface(Surface f); public static synchronized void restart(Context context) { if (sInstance != null) { try { sInstance.destroy(); sInstance.init(context); } catch (LibVlcException lve) { Log.e(TAG, "Unable to reinit libvlc: " + lve); } } } /** * those get/is* are called from native code to get settings values. */ public int getHardwareAcceleration() { return this.hardwareAcceleration; } public void setHardwareAcceleration(int hardwareAcceleration) { if (hardwareAcceleration < 0) { // Automatic mode: activate MediaCodec opaque direct rendering for 4.3 and above. if (LibVlcUtil.isJellyBeanMR2OrLater()) this.hardwareAcceleration = HW_ACCELERATION_FULL; else this.hardwareAcceleration = HW_ACCELERATION_DISABLED; } else this.hardwareAcceleration = hardwareAcceleration; } public String getSubtitlesEncoding() { return subtitlesEncoding; } public void setSubtitlesEncoding(String subtitlesEncoding) { this.subtitlesEncoding = subtitlesEncoding; } public int getAout() { return aout; } public void setAout(int aout) { if (aout < 0) this.aout = LibVlcUtil.isICSOrLater() ? AOUT_OPENSLES : AOUT_AUDIOTRACK_JAVA; else this.aout = aout; } public int getVout() { return vout; } public void setVout(int vout) { if (vout < 0) this.vout = VOUT_ANDROID_SURFACE; else this.vout = vout; } public boolean timeStretchingEnabled() { return timeStretching; } public void setTimeStretching(boolean timeStretching) { this.timeStretching = timeStretching; } public int getDeblocking() { int ret = deblocking; if(deblocking < 0) { /** * Set some reasonable deblocking defaults: * * Skip all (4) for armv6 and MIPS by default * Skip non-ref (1) for all armv7 more than 1.2 Ghz and more than 2 cores * Skip non-key (3) for all devices that don't meet anything above */ LibVlcUtil.MachineSpecs m = LibVlcUtil.getMachineSpecs(); if( (m.hasArmV6 && !(m.hasArmV7)) || m.hasMips ) ret = 4; else if(m.frequency >= 1200 && m.processors > 2) ret = 1; else if(m.bogoMIPS >= 1200 && m.processors > 2) { ret = 1; Log.d(TAG, "Used bogoMIPS due to lack of frequency info"); } else ret = 3; } else if(deblocking > 4) { // sanity check ret = 3; } return ret; } public void setDeblocking(int deblocking) { this.deblocking = deblocking; } public String getChroma() { return chroma; } public void setChroma(String chroma) { this.chroma = chroma.equals("YV12") && !LibVlcUtil.isGingerbreadOrLater() ? "" : chroma; } public boolean isVerboseMode() { return verboseMode; } public void setVerboseMode(boolean verboseMode) { this.verboseMode = verboseMode; } public float[] getEqualizer() { return equalizer; } public void setEqualizer(float[] equalizer) { this.equalizer = equalizer; applyEqualizer(); } private void applyEqualizer() { setNativeEqualizer(mInternalMediaPlayerInstance, this.equalizer); } private native int setNativeEqualizer(long mediaPlayer, float[] bands); public boolean frameSkipEnabled() { return frameSkip; } public void setFrameSkip(boolean frameskip) { this.frameSkip = frameskip; } public int getNetworkCaching() { return this.networkCaching; } public void setNetworkCaching(int networkcaching) { this.networkCaching = networkcaching; } /** * Initialize the libVLC class. * * This function must be called before using any libVLC functions. * * @throws org.videolan.libvlc.LibVlcException */ public void init(Context context) throws LibVlcException { Log.v(TAG, "Initializing LibVLC"); mDebugLogBuffer = new StringBuffer(); if (!mIsInitialized) { if(!LibVlcUtil.hasCompatibleCPU(context)) { Log.e(TAG, LibVlcUtil.getErrorMsg()); throw new LibVlcException(); } File cacheDir = context.getCacheDir(); mCachePath = (cacheDir != null) ? cacheDir.getAbsolutePath() : null; nativeInit(); mMediaList = mPrimaryList = new MediaList(this); setEventHandler(EventHandler.getInstance()); mIsInitialized = true; } } /** * Destroy this libVLC instance * @note You must call it before exiting */ public void destroy() { Log.v(TAG, "Destroying LibVLC instance"); nativeDestroy(); detachEventHandler(); mIsInitialized = false; } /** * Open the Java audio output. * This function is called by the native code */ public void initAout(int sampleRateInHz, int channels, int samples) { Log.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); } /** * Pause the Java audio output * This function is called by the native code */ public void pauseAout() { Log.d(TAG, "Pausing the java audio output"); mAout.pause(); } /** * Close the Java audio output * This function is called by the native code */ public void closeAout() { Log.d(TAG, "Closing the java audio output"); mAout.release(); } /** * Play a media from the media list (playlist) * * @param position The index of the media */ public void playIndex(int position) { String mrl = mMediaList.getMRL(position); if (mrl == null) return; String[] options = mMediaList.getMediaOptions(position); mInternalMediaPlayerIndex = position; playMRL(mLibVlcInstance, mrl, options); } /** * Play an MRL directly. * * @param mrl MRL of the media to play. */ public void playMRL(String mrl) { // index=-1 will return options from libvlc instance without relying on MediaList String[] options = mMediaList.getMediaOptions(-1); mInternalMediaPlayerIndex = 0; playMRL(mLibVlcInstance, mrl, options); } public TrackInfo[] readTracksInfo(String mrl) { return readTracksInfo(mLibVlcInstance, mrl); } /** * Get a media thumbnail. */ public byte[] getThumbnail(String mrl, int i_width, int i_height) { return getThumbnail(mLibVlcInstance, mrl, i_width, i_height); } /** * Return true if there is a video track in the file */ public boolean hasVideoTrack(String mrl) throws java.io.IOException { return hasVideoTrack(mLibVlcInstance, mrl); } /** * Sets the speed of playback (1 being normal speed, 2 being twice as fast) * * @param rate */ public native void setRate(float rate); /** * Get the current playback speed */ public native float getRate(); /** * Initialize the libvlc C library * @return a pointer to the libvlc instance */ private native void nativeInit() throws LibVlcException; /** * Close the libvlc C library * @note mLibVlcInstance should be 0 after a call to destroy() */ private native void nativeDestroy(); /** * Start buffering to the mDebugLogBuffer. */ public native void startDebugBuffer(); public native void stopDebugBuffer(); public String getBufferContent() { return mDebugLogBuffer.toString(); } public void clearBuffer() { mDebugLogBuffer.setLength(0); } public boolean isDebugBuffering() { return mIsBufferingLog; } /** * Play an mrl */ private native void playMRL(long instance, String mrl, String[] mediaOptions); /** * 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(); /** * Get player state. */ public native int getPlayerState(); /** * Gets volume as integer */ public native int getVolume(); /** * Sets volume as integer * @param volume: Volume level passed as integer */ public native int setVolume(int volume); /** * 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(); /** * Get the libVLC version * @return the libVLC version string */ public native String version(); /** * Get the libVLC compiler * @return the libVLC compiler string */ public native String compiler(); /** * Get the libVLC changeset * @return the libVLC changeset string */ public native String changeset(); /** * Get a media thumbnail. * @return a bytearray with the RGBA thumbnail data inside. */ private native byte[] getThumbnail(long instance, String mrl, int i_width, int i_height); /** * Return true if there is a video track in the file */ private native boolean hasVideoTrack(long instance, String mrl); private native TrackInfo[] readTracksInfo(long instance, String mrl); public native TrackInfo[] readTracksInfoInternal(); public native int getAudioTracksCount(); public native Map getAudioTrackDescription(); public native Map getStats(); public native int getAudioTrack(); public native int setAudioTrack(int index); public native int getVideoTracksCount(); public native int addSubtitleTrack(String path); public native Map getSpuTrackDescription(); public native int getSpuTrack(); public native int setSpuTrack(int index); public native int getSpuTracksCount(); public static native String nativeToURI(String path); public native static void sendMouseEvent( int action, int button, int x, int y); /** * Quickly converts path to URIs, which are mandatory in libVLC. * * @param path * The path to be converted. * @return A URI representation of path */ public static String PathToURI(String path) { if(path == null) { throw new NullPointerException("Cannot convert null path!"); } return LibVLC.nativeToURI(path); } public static native void nativeReadDirectory(String path, ArrayList res); public native static boolean nativeIsPathDirectory(String path); /** * Expand and continue playing the current media. * * @return the index of the media was expanded, and -1 if no media was expanded */ public int expandAndPlay() { int r = mMediaList.expandMedia(mInternalMediaPlayerIndex); if(r == 0) this.playIndex(mInternalMediaPlayerIndex); return r; } /** * Expand the current media. * @return the index of the media was expanded, and -1 if no media was expanded */ public int expand() { return mMediaList.expandMedia(mInternalMediaPlayerIndex); } private native void setEventHandler(EventHandler eventHandler); private native void detachEventHandler(); public native float[] getBands(); public native String[] getPresets(); public native float[] getPreset(int index); public static interface OnNativeCrashListener { public void onNativeCrash(); } public void setOnNativeCrashListener(OnNativeCrashListener l) { mOnNativeCrashListener = l; } private void onNativeCrash() { if (mOnNativeCrashListener != null) mOnNativeCrashListener.onNativeCrash(); } public String getCachePath() { return mCachePath; } public native int getTitle(); public native void setTitle(int title); public native int getChapterCountForTitle(int title); public native int getTitleCount(); } ================================================ FILE: app/src/main/java/org/videolan/libvlc/LibVlcException.java ================================================ /***************************************************************************** * LibVlcException.java ***************************************************************************** * Copyright © 2011-2012 VLC authors and VideoLAN * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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. *****************************************************************************/ /** * LibVlcException: exceptions thrown by the native LibVLC interface */ package org.videolan.libvlc; /** * @author jpeg * */ public class LibVlcException extends Exception { private static final long serialVersionUID = -1909522348226924189L; /** * Create an empty error */ public LibVlcException() { super(); } /** * @param detailMessage */ public LibVlcException(String detailMessage) { super(detailMessage); } /** * @param throwable */ public LibVlcException(Throwable throwable) { super(throwable); } /** * @param detailMessage * @param throwable */ public LibVlcException(String detailMessage, Throwable throwable) { super(detailMessage, throwable); } } ================================================ FILE: app/src/main/java/org/videolan/libvlc/LibVlcUtil.java ================================================ /***************************************************************************** * LibVlcUtil.java ***************************************************************************** * Copyright © 2011-2013 VLC authors and VideoLAN * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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.libvlc; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Locale; import android.content.Context; import android.net.Uri; import android.os.Build; import android.util.Log; public class LibVlcUtil { public final static String TAG = "VLC/LibVLC/Util"; public static boolean isFroyoOrLater() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO; } public static boolean isGingerbreadOrLater() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; } public static boolean isHoneycombOrLater() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; } public static boolean isICSOrLater() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH; } public static boolean isJellyBeanOrLater() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; } public static boolean isJellyBeanMR1OrLater() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; } public static boolean isJellyBeanMR2OrLater() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; } public static boolean isKitKatOrLater() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; } private static String errorMsg = null; private static boolean isCompatible = false; public static String getErrorMsg() { return errorMsg; } public static File URItoFile(String URI) { if(URI == null) return null; return new File(Uri.decode(URI).replace("file://","")); } public static String URItoFileName(String URI) { if(URI == null) return null; return URItoFile(URI).getName(); } public static boolean hasCompatibleCPU(Context context) { // If already checked return cached result if(errorMsg != null || isCompatible) return isCompatible; ElfData elf = readLib(context.getApplicationInfo().dataDir + "/lib/libvlcjni.so"); if(elf == null) { Log.e(TAG, "WARNING: Unable to read libvlcjni.so; cannot check device ABI!"); Log.e(TAG, "WARNING: Cannot guarantee correct ABI for this build (may crash)!"); return true; } String CPU_ABI = Build.CPU_ABI; String CPU_ABI2 = "none"; if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { // CPU_ABI2 since 2.2 try { CPU_ABI2 = (String)Build.class.getDeclaredField("CPU_ABI2").get(null); } catch (Exception e) { } } Log.i(TAG, "machine = " + (elf.e_machine == EM_ARM ? "arm" : elf.e_machine == EM_386 ? "x86" : "mips")); Log.i(TAG, "arch = " + elf.att_arch); Log.i(TAG, "fpu = " + elf.att_fpu); boolean hasNeon = false, hasFpu = false, hasArmV6 = false, hasArmV7 = false, hasMips = false, hasX86 = false; float bogoMIPS = -1; int processors = 0; if(CPU_ABI.equals("x86") || CPU_ABI2.equals("x86")) { hasX86 = true; } else if(CPU_ABI.equals("armeabi-v7a") || CPU_ABI2.equals("armeabi-v7a")) { hasArmV7 = true; hasArmV6 = true; /* Armv7 is backwards compatible to < v6 */ } else if(CPU_ABI.equals("armeabi") || CPU_ABI2.equals("armeabi")) { hasArmV6 = true; } try { FileReader fileReader = new FileReader("/proc/cpuinfo"); BufferedReader br = new BufferedReader(fileReader); String line; while((line = br.readLine()) != null) { if(!hasArmV7 && line.contains("ARMv7")) { hasArmV7 = true; hasArmV6 = true; /* Armv7 is backwards compatible to < v6 */ } if(!hasArmV7 && !hasArmV6 && line.contains("ARMv6")) hasArmV6 = true; // "clflush size" is a x86-specific cpuinfo tag. // (see kernel sources arch/x86/kernel/cpu/proc.c) if(line.contains("clflush size")) hasX86 = true; if(line.contains("GenuineIntel")) hasX86 = true; // "microsecond timers" is specific to MIPS. // see arch/mips/kernel/proc.c if(line.contains("microsecond timers")) hasMips = true; if(!hasNeon && line.contains("neon")) hasNeon = true; if(!hasFpu && line.contains("vfp")) hasFpu = true; if(line.startsWith("processor")) processors++; if(bogoMIPS < 0 && line.toLowerCase(Locale.ENGLISH).contains("bogomips")) { String[] bogo_parts = line.split(":"); try { bogoMIPS = Float.parseFloat(bogo_parts[1].trim()); } catch(NumberFormatException e) { bogoMIPS = -1; // invalid bogomips } } } fileReader.close(); } catch(IOException ex){ ex.printStackTrace(); errorMsg = "IOException whilst reading cpuinfo flags"; isCompatible = false; return false; } if(processors == 0) processors = 1; // possibly borked cpuinfo? // Enforce proper architecture to prevent problems if(elf.e_machine == EM_386 && !hasX86) { errorMsg = "x86 build on non-x86 device"; isCompatible = false; return false; } else if(elf.e_machine == EM_ARM && hasX86) { errorMsg = "ARM build on x86 device"; isCompatible = false; return false; } if(elf.e_machine == EM_MIPS && !hasMips) { errorMsg = "MIPS build on non-MIPS device"; isCompatible = false; return false; } else if(elf.e_machine == EM_ARM && hasMips) { errorMsg = "ARM build on MIPS device"; isCompatible = false; return false; } if(elf.e_machine == EM_ARM && elf.att_arch.startsWith("v7") && !hasArmV7) { errorMsg = "ARMv7 build on non-ARMv7 device"; isCompatible = false; return false; } if(elf.e_machine == EM_ARM) { if(elf.att_arch.startsWith("v6") && !hasArmV6) { errorMsg = "ARMv6 build on non-ARMv6 device"; isCompatible = false; return false; } else if(elf.att_fpu && !hasFpu) { errorMsg = "FPU-enabled build on non-FPU device"; isCompatible = false; return false; } } float frequency = -1; try { FileReader fileReader = new FileReader("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"); BufferedReader br = new BufferedReader(fileReader); String line = ""; try { line = br.readLine(); frequency = Float.parseFloat(line) / 1000.f; /* Convert to MHz */ } catch(NumberFormatException e) { Log.w(TAG, "Could not parse maximum CPU frequency!"); Log.w(TAG, "Failed to parse: " + line); } fileReader.close(); } catch(IOException ex) { Log.w(TAG, "Could not find maximum CPU frequency!"); } errorMsg = null; isCompatible = true; // Store into MachineSpecs machineSpecs = new MachineSpecs(); machineSpecs.hasArmV6 = hasArmV6; machineSpecs.hasArmV7 = hasArmV7; machineSpecs.hasFpu = hasFpu; machineSpecs.hasMips = hasMips; machineSpecs.hasNeon = hasNeon; machineSpecs.hasX86 = hasX86; machineSpecs.bogoMIPS = bogoMIPS; machineSpecs.processors = processors; machineSpecs.frequency = frequency; return true; } public static MachineSpecs getMachineSpecs() { return machineSpecs; } private static MachineSpecs machineSpecs = null; public static class MachineSpecs { public boolean hasNeon; public boolean hasFpu; public boolean hasArmV6; public boolean hasArmV7; public boolean hasMips; public boolean hasX86; public float bogoMIPS; public int processors; public float frequency; /* in MHz */ } private static final int EM_386 = 3; private static final int EM_MIPS = 8; private static final int EM_ARM = 40; private static final int ELF_HEADER_SIZE = 52; private static final int SECTION_HEADER_SIZE = 40; private static final int SHT_ARM_ATTRIBUTES = 0x70000003; private static class ElfData { ByteOrder order; int e_machine; int e_shoff; int e_shnum; int sh_offset; int sh_size; String att_arch; boolean att_fpu; } /** '*' prefix means it's unsupported */ private static String[] CPU_archs = {"*Pre-v4", "*v4", "*v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2", "v6K", "v7", "*v6-M", "*v6S-M", "*v7E-M", "*v8"}; private static ElfData readLib(String path) { File file = new File(path); if (!file.exists() || !file.canRead()) return null; RandomAccessFile in = null; try { in = new RandomAccessFile(file, "r"); ElfData elf = new ElfData(); if (!readHeader(in, elf)) return null; switch (elf.e_machine) { case EM_386: case EM_MIPS: return elf; case EM_ARM: in.close(); in = new RandomAccessFile(file, "r"); if (!readSection(in, elf)) return null; in.close(); in = new RandomAccessFile(file, "r"); if (!readArmAttributes(in, elf)) return null; break; default: return null; } return elf; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); } catch (IOException e) { } } return null; } private static boolean readHeader(RandomAccessFile in, ElfData elf) throws IOException { // http://www.sco.com/developers/gabi/1998-04-29/ch4.eheader.html byte[] bytes = new byte[ELF_HEADER_SIZE]; in.readFully(bytes); if (bytes[0] != 127 || bytes[1] != 'E' || bytes[2] != 'L' || bytes[3] != 'F' || bytes[4] != 1) { // ELFCLASS32, Only 32bit header is supported return false; } elf.order = bytes[5] == 1 ? ByteOrder.LITTLE_ENDIAN // ELFDATA2LSB : ByteOrder.BIG_ENDIAN; // ELFDATA2MSB // wrap bytes in a ByteBuffer to force endianess ByteBuffer buffer = ByteBuffer.wrap(bytes); buffer.order(elf.order); elf.e_machine = buffer.getShort(18); /* Architecture */ elf.e_shoff = buffer.getInt(32); /* Section header table file offset */ elf.e_shnum = buffer.getShort(48); /* Section header table entry count */ return true; } private static boolean readSection(RandomAccessFile in, ElfData elf) throws IOException { byte[] bytes = new byte[SECTION_HEADER_SIZE]; in.seek(elf.e_shoff); for (int i = 0; i < elf.e_shnum; ++i) { in.readFully(bytes); // wrap bytes in a ByteBuffer to force endianess ByteBuffer buffer = ByteBuffer.wrap(bytes); buffer.order(elf.order); int sh_type = buffer.getInt(4); /* Section type */ if (sh_type != SHT_ARM_ATTRIBUTES) continue; elf.sh_offset = buffer.getInt(16); /* Section file offset */ elf.sh_size = buffer.getInt(20); /* Section size in bytes */ return true; } return false; } private static boolean readArmAttributes(RandomAccessFile in, ElfData elf) throws IOException { byte[] bytes = new byte[elf.sh_size]; in.seek(elf.sh_offset); in.readFully(bytes); // wrap bytes in a ByteBuffer to force endianess ByteBuffer buffer = ByteBuffer.wrap(bytes); buffer.order(elf.order); //http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf //http://infocenter.arm.com/help/topic/com.arm.doc.ihi0045d/IHI0045D_ABI_addenda.pdf if (buffer.get() != 'A') // format-version return false; // sub-sections loop while (buffer.remaining() > 0) { int start_section = buffer.position(); int length = buffer.getInt(); String vendor = getString(buffer); if (vendor.equals("aeabi")) { // tags loop while (buffer.position() < start_section + length) { int start = buffer.position(); int tag = buffer.get(); int size = buffer.getInt(); // skip if not Tag_File, we don't care about others if (tag != 1) { buffer.position(start + size); continue; } // attributes loop while (buffer.position() < start + size) { tag = getUleb128(buffer); if (tag == 6) { // CPU_arch int arch = getUleb128(buffer); elf.att_arch = CPU_archs[arch]; } else if (tag == 27) { // ABI_HardFP_use getUleb128(buffer); elf.att_fpu = true; } else { // string for 4=CPU_raw_name / 5=CPU_name / 32=compatibility // string for >32 && odd tags // uleb128 for other tag %= 128; if (tag == 4 || tag == 5 || tag == 32 || (tag > 32 && (tag & 1) != 0)) getString(buffer); else getUleb128(buffer); } } } break; } } return true; } private static String getString(ByteBuffer buffer) { StringBuilder sb = new StringBuilder(buffer.limit()); while (buffer.remaining() > 0) { char c = (char) buffer.get(); if (c == 0) break; sb.append(c); } return sb.toString(); } private static int getUleb128(ByteBuffer buffer) { int ret = 0; int c; do { ret <<= 7; c = buffer.get(); ret |= c & 0x7f; } while((c & 0x80) > 0); return ret; } } ================================================ FILE: app/src/main/java/org/videolan/libvlc/Media.java ================================================ /***************************************************************************** * Media.java ***************************************************************************** * Copyright © 2011-2013 VLC authors and VideoLAN * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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.libvlc; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Locale; import android.graphics.Bitmap; import android.util.Log; public class Media implements Comparable { public final static String TAG = "VLC/LibVLC/Media"; public final static HashSet VIDEO_EXTENSIONS; public final static HashSet AUDIO_EXTENSIONS; public final static String EXTENSIONS_REGEX; public final static HashSet FOLDER_BLACKLIST; static { String[] video_extensions = { ".3g2", ".3gp", ".3gp2", ".3gpp", ".amv", ".asf", ".avi", ".divx", ".drc", ".dv", ".f4v", ".flv", ".gvi", ".gxf", ".ismv", ".iso", ".m1v", ".m2v", ".m2t", ".m2ts", ".m4v", ".mkv", ".mov", ".mp2", ".mp2v", ".mp4", ".mp4v", ".mpe", ".mpeg", ".mpeg1", ".mpeg2", ".mpeg4", ".mpg", ".mpv2", ".mts", ".mtv", ".mxf", ".mxg", ".nsv", ".nut", ".nuv", ".ogm", ".ogv", ".ogx", ".ps", ".rec", ".rm", ".rmvb", ".tod", ".ts", ".tts", ".vob", ".vro", ".webm", ".wm", ".wmv", ".wtv", ".xesc" }; String[] audio_extensions = { ".3ga", ".a52", ".aac", ".ac3", ".adt", ".adts", ".aif", ".aifc", ".aiff", ".amr", ".aob", ".ape", ".awb", ".caf", ".dts", ".flac", ".it", ".m4a", ".m4b", ".m4p", ".mid", ".mka", ".mlp", ".mod", ".mpa", ".mp1", ".mp2", ".mp3", ".mpc", ".mpga", ".oga", ".ogg", ".oma", ".opus", ".ra", ".ram", ".rmi", ".s3m", ".spx", ".tta", ".voc", ".vqf", ".w64", ".wav", ".wma", ".wv", ".xa", ".xm" }; String[] folder_blacklist = { "/alarms", "/notifications", "/ringtones", "/media/alarms", "/media/notifications", "/media/ringtones", "/media/audio/alarms", "/media/audio/notifications", "/media/audio/ringtones", "/Android/data/" }; VIDEO_EXTENSIONS = new HashSet(); for (String item : video_extensions) VIDEO_EXTENSIONS.add(item); AUDIO_EXTENSIONS = new HashSet(); for (String item : audio_extensions) AUDIO_EXTENSIONS.add(item); StringBuilder sb = new StringBuilder(115); sb.append(".+(\\.)((?i)("); sb.append(video_extensions[0].substring(1)); for(int i = 1; i < video_extensions.length; i++) { sb.append('|'); sb.append(video_extensions[i].substring(1)); } for(int i = 0; i < audio_extensions.length; i++) { sb.append('|'); sb.append(audio_extensions[i].substring(1)); } sb.append("))"); EXTENSIONS_REGEX = sb.toString(); FOLDER_BLACKLIST = new HashSet(); for (String item : folder_blacklist) FOLDER_BLACKLIST.add(android.os.Environment.getExternalStorageDirectory().getPath() + item); } public final static int TYPE_ALL = -1; public final static int TYPE_VIDEO = 0; public final static int TYPE_AUDIO = 1; public final static int TYPE_GROUP = 2; /** Metadata from libvlc_media */ protected String mTitle; private String mArtist; private String mGenre; private String mCopyright; private String mAlbum; private String mTrackNumber; private String mDescription; private String mRating; private String mDate; private String mSettings; private String mNowPlaying; private String mPublisher; private String mEncodedBy; private String mTrackID; private String mArtworkURL; private final String mLocation; private String mFilename; private long mTime = 0; private int mAudioTrack = -1; private int mSpuTrack = -2; private long mLength = 0; private int mType; private int mWidth = 0; private int mHeight = 0; private Bitmap mPicture; private boolean mIsPictureParsed; /** * Create a new Media * @param libVLC A pointer to the libVLC instance. Should not be NULL * @param URI The URI of the media. */ public Media(LibVLC libVLC, String URI) { if(libVLC == null) throw new NullPointerException("libVLC was null"); mLocation = URI; mType = TYPE_ALL; TrackInfo[] tracks = libVLC.readTracksInfo(mLocation); extractTrackInfo(tracks); } private void extractTrackInfo(TrackInfo[] tracks) { if (tracks == null) return; for (TrackInfo track : tracks) { if (track.Type == TrackInfo.TYPE_VIDEO) { mType = TYPE_VIDEO; mWidth = track.Width; mHeight = track.Height; } else if (mType == TYPE_ALL && track.Type == TrackInfo.TYPE_AUDIO){ mType = TYPE_AUDIO; } else if (track.Type == TrackInfo.TYPE_META) { mLength = track.Length; mTitle = track.Title; mArtist = getValueWrapper(track.Artist, UnknownStringType.Artist); mAlbum = getValueWrapper(track.Album, UnknownStringType.Album); mGenre = getValueWrapper(track.Genre, UnknownStringType.Genre); mArtworkURL = track.ArtworkURL; Log.d(TAG, "Title " + mTitle); Log.d(TAG, "Artist " + mArtist); Log.d(TAG, "Genre " + mGenre); Log.d(TAG, "Album " + mAlbum); } } /* No useful ES found */ if (mType == TYPE_ALL) { int dotIndex = mLocation.lastIndexOf("."); if (dotIndex != -1) { String fileExt = mLocation.substring(dotIndex).toLowerCase(Locale.ENGLISH); if( Media.VIDEO_EXTENSIONS.contains(fileExt) ) { mType = TYPE_VIDEO; } else if (Media.AUDIO_EXTENSIONS.contains(fileExt)) { mType = TYPE_AUDIO; } } } } public Media(String location, long time, long length, int type, Bitmap picture, String title, String artist, String genre, String album, int width, int height, String artworkURL, int audio, int spu) { mLocation = location; mFilename = null; mTime = time; mAudioTrack = audio; mSpuTrack = spu; mLength = length; mType = type; mPicture = picture; mWidth = width; mHeight = height; mTitle = title; mArtist = getValueWrapper(artist, UnknownStringType.Artist); mGenre = getValueWrapper(genre, UnknownStringType.Genre); mAlbum = getValueWrapper(album, UnknownStringType.Album); mArtworkURL = artworkURL; } private enum UnknownStringType { Artist , Genre, Album }; /** * Uses introspection to read VLC l10n databases, so that we can sever the * hard-coded dependency gracefully for 3rd party libvlc apps while still * maintaining good l10n in VLC for Android. * * @see org.videolan.vlc.util.Util#getValue(String, int) * * @param string The default string * @param type Alias for R.string.xxx * @return The default string if not empty or string from introspection */ private static String getValueWrapper(String string, UnknownStringType type) { if(string != null && string.length() > 0) return string; try { Class stringClass = Class.forName("org.videolan.vlc.R$string"); Class utilClass = Class.forName("org.videolan.vlc.Util"); Integer value; switch(type) { case Album: value = (Integer)stringClass.getField("unknown_album").get(null); break; case Genre: value = (Integer)stringClass.getField("unknown_genre").get(null); break; case Artist: default: value = (Integer)stringClass.getField("unknown_artist").get(null); break; } Method getValueMethod = utilClass.getDeclaredMethod("getValue", String.class, Integer.TYPE); // Util.getValue(string, R.string.xxx); return (String) getValueMethod.invoke(null, string, value); } catch (ClassNotFoundException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (NoSuchFieldException e) { } catch (NoSuchMethodException e) { } catch (InvocationTargetException e) { } // VLC for Android translations not available (custom app perhaps) // Use hardcoded English phrases. switch(type) { case Album: return "Unknown Album"; case Genre: return "Unknown Genre"; case Artist: default: return "Unknown Artist"; } } /** * Compare the filenames to sort items */ @Override public int compareTo(Media another) { return mTitle.toUpperCase(Locale.getDefault()).compareTo( another.getTitle().toUpperCase(Locale.getDefault())); } public String getLocation() { return mLocation; } public void updateMeta() { } public String getFileName() { if (mFilename == null) { mFilename = LibVlcUtil.URItoFileName(mLocation); } return mFilename; } public long getTime() { return mTime; } public void setTime(long time) { mTime = time; } public int getAudioTrack() { return mAudioTrack; } public void setAudioTrack(int track) { mAudioTrack = track; } public int getSpuTrack() { return mSpuTrack; } public void setSpuTrack(int track) { mSpuTrack = track; } public long getLength() { return mLength; } public int getType() { return mType; } public int getWidth() { return mWidth; } public int getHeight() { return mHeight; } /** * Returns the raw picture object. Likely to be NULL in VLC for Android * due to lazy-loading. * * Use {@link org.videolan.vlc.util.Bitmap#getPictureFromCache(org.videolan.libvlc.Media)} instead. * * @return The raw picture or NULL */ public Bitmap getPicture() { return mPicture; } /** * Sets the raw picture object. * * In VLC for Android, use {@link org.videolan.vlc.MediaDatabase#setPicture(org.videolan.libvlc.Media, android.graphics.Bitmap)} instead. * * @param p */ public void setPicture(Bitmap p) { mPicture = p; } public boolean isPictureParsed() { return mIsPictureParsed; } public void setPictureParsed(boolean isParsed) { mIsPictureParsed = isParsed; } public String getTitle() { if (mTitle != null && mType != TYPE_VIDEO) return mTitle; else { String fileName = getFileName(); if (fileName == null) return ""; int end = fileName.lastIndexOf("."); if (end <= 0) return fileName; return fileName.substring(0, end); } } public String getSubtitle() { return mType != TYPE_VIDEO ? mArtist + " - " + mAlbum : ""; } public String getArtist() { return mArtist; } public String getGenre() { if(getValueWrapper(null, UnknownStringType.Genre).equals(mGenre)) return mGenre; else if( mGenre.length() > 1)/* Make genres case insensitive via normalisation */ return Character.toUpperCase(mGenre.charAt(0)) + mGenre.substring(1).toLowerCase(Locale.getDefault()); else return mGenre; } public String getCopyright() { return mCopyright; } public String getAlbum() { return mAlbum; } public String getTrackNumber() { return mTrackNumber; } public String getDescription() { return mDescription; } public String getRating() { return mRating; } public String getDate() { return mDate; } public String getSettings() { return mSettings; } public String getNowPlaying() { return mNowPlaying; } public String getPublisher() { return mPublisher; } public String getEncodedBy() { return mEncodedBy; } public String getTrackID() { return mTrackID; } public String getArtworkURL() { return mArtworkURL; } } ================================================ FILE: app/src/main/java/org/videolan/libvlc/MediaList.java ================================================ /***************************************************************************** * MediaList.java ***************************************************************************** * Copyright © 2013 VLC authors and VideoLAN * Copyright © 2013 Edward Wang * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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.libvlc; import java.util.ArrayList; import android.os.Bundle; /** * Java/JNI wrapper for the libvlc_media_list_t structure. */ public class MediaList { private static final String TAG = "VLC/LibVLC/MediaList"; /* Since the libvlc_media_t is not created until the media plays, we have * to cache them here. */ private static class MediaHolder { Media m; boolean noVideo; // default false boolean noHardwareAcceleration; // default false public MediaHolder(Media media) { m = media; noVideo = false; noHardwareAcceleration = false; } public MediaHolder(Media m_, boolean noVideo_, boolean noHardwareAcceleration_) { m = m_; noVideo = noVideo_; noHardwareAcceleration = noHardwareAcceleration_; } } /* TODO: add locking */ private ArrayList mInternalList; private LibVLC mLibVLC; // Used to create new objects that require a libvlc instance private EventHandler mEventHandler; public MediaList(LibVLC libVLC) { mEventHandler = new EventHandler(); // used in init() below to fire events at the correct targets mInternalList = new ArrayList(); mLibVLC = libVLC; } /** * Adds a media URI to the media list. * * @param mrl * The MRL to add. Must be a location and not a path. * {@link LibVLC#PathToURI(String)} can be used to convert a path * to a MRL. */ public void add(String mrl) { add(new Media(mLibVLC, mrl)); } public void add(Media media) { add(media, false, false); } public void add(Media media, boolean noVideo) { add(media, noVideo, false); } public void add(Media media, boolean noVideo, boolean noHardwareAcceleration) { mInternalList.add(new MediaHolder(media, noVideo, noHardwareAcceleration)); signal_list_event(EventHandler.CustomMediaListItemAdded, mInternalList.size() - 1, media.getLocation()); } /** * Clear the media list. (remove all media) */ public void clear() { // Signal to observers of media being deleted. for(int i = 0; i < mInternalList.size(); i++) { signal_list_event(EventHandler.CustomMediaListItemDeleted, i, mInternalList.get(i).m.getLocation()); } mInternalList.clear(); } private boolean isValid(int position) { return position >= 0 && position < mInternalList.size(); } /** * This function checks the currently playing media for subitems at the given * position, and if any exist, it will expand them at the same position * and replace the current media. * * @param position The position to expand * @return -1 if no subitems were found, 0 if subitems were expanded */ public int expandMedia(int position) { ArrayList children = new ArrayList(); int ret = expandMedia(mLibVLC, position, children); if(ret == 0) { mEventHandler.callback(EventHandler.CustomMediaListExpanding, new Bundle()); this.remove(position); for(String mrl : children) { this.insert(position, mrl); } mEventHandler.callback(EventHandler.CustomMediaListExpandingEnd, new Bundle()); } return ret; } private native int expandMedia(LibVLC libvlc_instance, int position, ArrayList children); public void loadPlaylist(String mrl) { ArrayList items = new ArrayList(); loadPlaylist(mLibVLC, mrl, items); this.clear(); for(String item : items) { this.add(item); } } private native void loadPlaylist(LibVLC libvlc_instance, String mrl, ArrayList items); public void insert(int position, String mrl) { insert(position, new Media(mLibVLC, mrl)); } public void insert(int position, Media media) { mInternalList.add(position, new MediaHolder(media)); signal_list_event(EventHandler.CustomMediaListItemAdded, position, media.getLocation()); } /** * Move a media from one position to another * * @param startPosition start position * @param endPosition end position * @throws IndexOutOfBoundsException */ public void move(int startPosition, int endPosition) { if (!(isValid(startPosition) && endPosition >= 0 && endPosition <= mInternalList.size())) throw new IndexOutOfBoundsException("Indexes out of range"); MediaHolder toMove = mInternalList.get(startPosition); mInternalList.remove(startPosition); if (startPosition >= endPosition) mInternalList.add(endPosition, toMove); else mInternalList.add(endPosition - 1, toMove); Bundle b = new Bundle(); b.putInt("index_before", startPosition); b.putInt("index_after", endPosition); mEventHandler.callback(EventHandler.CustomMediaListItemMoved, b); } public void remove(int position) { if (!isValid(position)) return; String uri = mInternalList.get(position).m.getLocation(); mInternalList.remove(position); signal_list_event(EventHandler.CustomMediaListItemDeleted, position, uri); } public void remove(String location) { for (int i = 0; i < mInternalList.size(); ++i) { String uri = mInternalList.get(i).m.getLocation(); if (uri.equals(location)) { mInternalList.remove(i); signal_list_event(EventHandler.CustomMediaListItemDeleted, i, uri); i--; } } } public int size() { return mInternalList.size(); } public Media getMedia(int position) { if (!isValid(position)) return null; return mInternalList.get(position).m; } /** * @param position The index of the media in the list * @return null if not found */ public String getMRL(int position) { if (!isValid(position)) return null; return mInternalList.get(position).m.getLocation(); } public String[] getMediaOptions(int position) { boolean noHardwareAcceleration = mLibVLC.getHardwareAcceleration() == 0; boolean noVideo = false; if (isValid(position)) { if (!noHardwareAcceleration) noHardwareAcceleration = mInternalList.get(position).noHardwareAcceleration; noVideo = mInternalList.get(position).noVideo; } ArrayList options = new ArrayList(); if (!noHardwareAcceleration) { /* * Set higher caching values if using iomx decoding, since some omx * decoders have a very high latency, and if the preroll data isn't * enough to make the decoder output a frame, the playback timing gets * started too soon, and every decoded frame appears to be too late. * On Nexus One, the decoder latency seems to be 25 input packets * for 320x170 H.264, a few packets less on higher resolutions. * On Nexus S, the decoder latency seems to be about 7 packets. */ options.add(":file-caching=1500"); options.add(":network-caching=1500"); options.add(":codec=mediacodec,iomx,all"); } if (noVideo) options.add(":no-video"); return options.toArray(new String[options.size()]); } public EventHandler getEventHandler() { return mEventHandler; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("LibVLC Media List: {"); for(int i = 0; i < size(); i++) { sb.append(((Integer)i).toString()); sb.append(": "); sb.append(getMRL(i)); sb.append(", "); } sb.append("}"); return sb.toString(); } private void signal_list_event(int event, int position, String uri) { Bundle b = new Bundle(); b.putString("item_uri", uri); b.putInt("item_index", position); mEventHandler.callback(event, b); } } ================================================ FILE: app/src/main/java/org/videolan/libvlc/TrackInfo.java ================================================ /***************************************************************************** * TrackInfo.java ***************************************************************************** * Copyright © 2010-2013 VLC authors and VideoLAN * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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.libvlc; public class TrackInfo { public static final int TYPE_UNKNOWN = -1; public static final int TYPE_AUDIO = 0; public static final int TYPE_VIDEO = 1; public static final int TYPE_TEXT = 2; public static final int TYPE_META = 3; public int Type; public int Id; public String Codec; public String Language; public int Bitrate; /* Video */ public int Height; public int Width; public float Framerate; /* Audio */ public int Channels; public int Samplerate; /* MetaData */ public long Length; public String Title; public String Artist; public String Album; public String Genre; public String ArtworkURL; } ================================================ FILE: app/src/main/java/org/videolan/vlc/util/Preferences.java ================================================ /***************************************************************************** * Preferences.java ***************************************************************************** * Copyright © 2011-2014 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.util; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import org.json.JSONArray; import org.json.JSONException; public class Preferences { public final static String TAG = "VLC/Util/Preferences"; public static float[] getFloatArray(SharedPreferences pref, String key) { float[] array = null; String s = pref.getString(key, null); if (s != null) { try { JSONArray json = new JSONArray(s); array = new float[json.length()]; for (int i = 0; i < array.length; i++) array[i] = (float) json.getDouble(i); } catch (JSONException e) { e.printStackTrace(); } } return array; } public static void putFloatArray(Editor editor, String key, float[] array) { try { JSONArray json = new JSONArray(); for (float f : array) json.put(f); editor.putString("equalizer_values", json.toString()); } catch (JSONException e) { e.printStackTrace(); } } } ================================================ FILE: app/src/main/java/org/videolan/vlc/util/VLCInstance.java ================================================ /***************************************************************************** * VLCInstance.java ***************************************************************************** * Copyright © 2011-2014 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.util; import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; import com.nmbb.vlc.VLCApplication; import org.videolan.libvlc.LibVLC; import org.videolan.libvlc.LibVlcException; public class VLCInstance { public final static String TAG = "VLC/Util/VLCInstance"; /** A set of utility functions for the VLC application */ public static LibVLC getLibVlcInstance() throws LibVlcException { LibVLC instance = LibVLC.getExistingInstance(); if (instance == null) { //Thread.setDefaultUncaughtExceptionHandler(new VLCCrashHandler()); instance = LibVLC.getInstance(); final Context context = VLCApplication.getAppContext(); SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context); VLCInstance.updateLibVlcSettings(pref); instance.init(context); instance.setOnNativeCrashListener(new LibVLC.OnNativeCrashListener() { @Override public void onNativeCrash() { // Intent i = new Intent(context, NativeCrashActivity.class); // i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // i.putExtra("PID", android.os.Process.myPid()); // context.startActivity(i); // Logger.e("[VLCInstance]onNativeCrash..."); } }); } return instance; } public static void updateLibVlcSettings(SharedPreferences pref) { LibVLC instance = LibVLC.getExistingInstance(); if (instance == null) return; instance.setSubtitlesEncoding(pref.getString("subtitle_text_encoding", "")); instance.setTimeStretching(pref.getBoolean("enable_time_stretching_audio", false)); instance.setFrameSkip(pref.getBoolean("enable_frame_skip", false)); instance.setChroma(pref.getString("chroma_format", "")); instance.setVerboseMode(pref.getBoolean("enable_verbose_mode", true)); if (pref.getBoolean("equalizer_enabled", false)) instance.setEqualizer(Preferences.getFloatArray(pref, "equalizer_values")); int aout; try { aout = Integer.parseInt(pref.getString("aout", "-1")); } catch (NumberFormatException nfe) { aout = -1; } int vout; try { vout = Integer.parseInt(pref.getString("vout", "-1")); } catch (NumberFormatException nfe) { vout = -1; } int deblocking; try { deblocking = Integer.parseInt(pref.getString("deblocking", "-1")); } catch(NumberFormatException nfe) { deblocking = -1; } int hardwareAcceleration; try { hardwareAcceleration = Integer.parseInt(pref.getString("hardware_acceleration", "-1")); } catch(NumberFormatException nfe) { hardwareAcceleration = -1; } int networkCaching = pref.getInt("network_caching_value", 0); if(networkCaching > 60000) networkCaching = 60000; else if(networkCaching < 0) networkCaching = 0; instance.setAout(aout); instance.setVout(vout); instance.setDeblocking(deblocking); instance.setNetworkCaching(networkCaching); instance.setHardwareAcceleration(hardwareAcceleration); } } ================================================ FILE: app/src/main/res/layout/activity_video_vlc.xml ================================================ ================================================ FILE: app/src/main/res/values/dimens.xml ================================================ 16dp 16dp ================================================ FILE: app/src/main/res/values/strings.xml ================================================ VLC-Demo Hello world! Settings Loading... ================================================ FILE: app/src/main/res/values/styles.xml ================================================ ================================================ FILE: app/src/main/res/values-w820dp/dimens.xml ================================================ 64dp ================================================ FILE: build.gradle ================================================ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:0.12.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } ================================================ FILE: gradle.properties ================================================ # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Settings specified in this file will override any Gradle settings # configured through the IDE. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx10248m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true ================================================ FILE: settings.gradle ================================================ include ':app'