增加佳明相机业务

This commit is contained in:
qiji4215
2023-04-19 15:41:33 +08:00
parent fdb62780ee
commit 3876ab9f38
142 changed files with 8433 additions and 67 deletions

View File

@@ -10,41 +10,17 @@ ext.vtmVersion = "0.18.0"
ext.realm_version = '10.10.1'
ext.appcompatVersion = "1.3.0"
ext.materialVersion = "1.5.0"
ext.kotlin_version = '1.7.0'
ext.kotlin_version = '1.8.0'
android {
compileSdk 30
defaultConfig {
minSdk 23
targetSdk 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
// 指定room.schemaLocation生成的文件路径
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
@@ -55,8 +31,7 @@ android {
dependencies {
compileOnly fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
api files('libs/BaiduLBS_AndroidSDK_Lib.aar')
api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation "androidx.appcompat:appcompat:$appcompatVersion"
implementation "com.google.android.material:material:$materialVersion"
testImplementation 'junit:junit:4.13.2'

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -14,8 +14,7 @@
android:value="IxQi4mZGTlfv6Z9M2GRdqn4KKRbOATUU" />
<application
android:allowBackup="true"
android:networkSecurityConfig="@xml/network_security_config"
>
android:networkSecurityConfig="@xml/network_security_config">
</application>
</manifest>

View File

@@ -4,7 +4,6 @@ import com.google.protobuf.Descriptors;
import com.google.protobuf.GeneratedMessageV3;
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Resultdata;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateXYM;
import org.locationtech.jts.geom.CoordinateXYZM;

View File

@@ -16,48 +16,43 @@ import com.navinfo.collect.library.sensor.ISensor.enmConnectionStatus;
public interface CameraEventListener extends SensorEventListener{
/**
*拍照成功
*
*
* @return
*/
public void OnSnapPictureResponse(HostBean hostBean, Bitmap bitmap, String picName, int tag);
/** 错误 */
public void requestError(HostBean hostBean, VolleyError e, CameraGarminVirbXE.enmCommandType commandType, int tag);
/**
* 开始自动拍照回调
*/
public void OnStartRecordResponse(HostBean hostBean, int tag);
/**
* 停止自动拍照回调
*/
public void OnStopRecordResponse(HostBean hostBean, int tag);
/**
* 停止自动拍照回调
*/
public void OnStatusResponse(HostBean hostBean, int tag);
/**
* 局域网搜索相机完成回调
* @param tag
* @param scanIpList
*/
public void OnSearchResponse(int tag,ArrayList<HostBean> scanIpList);
/**
* 状态发生改变时候回调
* @param connectStatus
*/
public void OnConnectStatusChanged(HostBean hostBean, enmConnectionStatus connectStatus, int tag);
/**
* 返回设备id
* @param devicesId
*/
public void OnGetDeviceInfo(HostBean hostBean, String devicesId, int tag);
/**
* 返回是否有gps信息
* @param status
@@ -97,4 +92,11 @@ public interface CameraEventListener extends SensorEventListener{
*
*/
public void OnGetMediaList(HostBean hostBean, String json, int tag);
/**
* 返回设备id
* @param devicesId
*/
public void OnGetDeviceInfo(HostBean hostBean,String devicesId,int tag);
}

View File

@@ -0,0 +1,60 @@
package com.navinfo.collect.library.sensor;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE;
import com.navinfo.collect.library.garminvirbxe.SensorParams;
import com.navinfo.collect.library.sensor.ISensor.enmSensorModel;
import com.navinfo.collect.library.sensor.ISensor.enmSensorType;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class SensorManager {
private static volatile SensorManager mInstance;
private Context mContext;
private long diffTime = 0;
Handler mainHandler = new Handler(Looper.getMainLooper());
public static SensorManager getInstance() {
if (mInstance == null) {
synchronized (SensorManager.class) {
if (mInstance == null) {
mInstance = new SensorManager();
}
}
}
return mInstance;
}
public void init(Context context) {
mContext = context;
diffTime = context.getSharedPreferences("nowTime", Context.MODE_PRIVATE).getLong("THE_DIFFERENCE_VALUE", 0);
}
public static ISensor CreateSensor(Context mContext, enmSensorType type, enmSensorModel model) {
ISensor pSensorInstance = null;
if (type == enmSensorType.SENSOR_CAMEAR) { // Garmin 相机
if (model == enmSensorModel.CAMERA_GARMIN_VIRB_XE) {
pSensorInstance = new CameraGarminVirbXE(mContext);
} else {
pSensorInstance = new Camera(mContext);
}
}
return pSensorInstance;
}
public void setDiffTime(long diffValue) {
this.diffTime = diffValue;
}
}

View File

@@ -0,0 +1,100 @@
/*****************************************************************************
* VLCApplication.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 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 com.navinfo.collect.library.system;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import android.util.Log;
import java.util.Locale;
public class VLCApplication extends Application {
public final static String TAG = "VLC/VLCApplication";
private static VLCApplication instance;
public final static String SLEEP_INTENT = "org.videolan.vlc.SleepIntent";
@Override
public void onCreate() {
super.onCreate();
// Are we using advanced debugging - locale?
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
String p = pref.getString("set_locale", "");
if (p != null && !p.equals("")) {
Locale locale;
// workaround due to region code
if(p.equals("zh-TW")) {
locale = Locale.TRADITIONAL_CHINESE;
} else if(p.startsWith("zh")) {
locale = Locale.CHINA;
} else if(p.equals("pt-BR")) {
locale = new Locale("pt", "BR");
} else if(p.equals("bn-IN") || p.startsWith("bn")) {
locale = new Locale("bn", "IN");
} else {
/**
* Avoid a crash of
* java.lang.AssertionError: couldn't initialize LocaleData for locale
* if the user enters nonsensical region codes.
*/
if(p.contains("-"))
p = p.substring(0, p.indexOf('-'));
locale = new Locale(p);
}
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
}
instance = this;
}
/**
* Called when the overall system is running low on memory
*/
@Override
public void onLowMemory() {
super.onLowMemory();
Log.w(TAG, "System is running low on memory");
}
/**
* @return the main context of the Application
*/
public static Context getAppContext()
{
return instance;
}
/**
* @return the main resources from the Application
*/
public static Resources getAppResources()
{
if(instance == null) return null;
return instance.getResources();
}
}

View File

@@ -0,0 +1,74 @@
/*****************************************************************************
* 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 Aout {
/**
* 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 Aout() {
}
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();
}
}

View File

@@ -0,0 +1,123 @@
/*****************************************************************************
* EventHandler.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.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;
private ArrayList<Handler> mEventHandler;
private static EventHandler mInstance;
EventHandler() {
mEventHandler = new ArrayList<Handler>();
}
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);
}
}
}

View File

@@ -0,0 +1,34 @@
/*****************************************************************************
* 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);
}

View File

@@ -0,0 +1,653 @@
/*****************************************************************************
* 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.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;
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 Aout mAout;
/** Keep screen bright */
//private WakeLock mWakeLock;
/** Settings */
private boolean iomx = false;
private String subtitlesEncoding = "";
private int aout = LibVlcUtil.isGingerbreadOrLater() ? AOUT_OPENSLES : AOUT_AUDIOTRACK_JAVA;
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;
/** Check in libVLC already initialized otherwise crash */
private boolean mIsInitialized = false;
public native void attachSurface(Surface surface, IVideoPlayer player, int width, int height);
public native void detachSurface();
/* 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) {
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 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 Aout();
}
/**
* Destructor:
* It is bad practice to rely on them, so please don't forget to call
* destroy() before exiting.
*/
@Override
public 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 boolean useIOMX() {
return iomx;
}
public void setIomx(boolean iomx) {
this.iomx = iomx;
}
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.isGingerbreadOrLater() ? AOUT_OPENSLES : AOUT_AUDIOTRACK_JAVA;
else
this.aout = aout;
}
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.bogoMIPS > 1200 && m.processors > 2)
ret = 1;
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
*/
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();
}
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();
}
public int readMedia(String mrl) {
return readMedia(mLibVlcInstance, mrl, false);
}
/**
* Read a media.
*/
public int readMedia(String mrl, boolean novideo) {
Log.v(TAG, "Reading " + mrl);
return readMedia(mLibVlcInstance, mrl, novideo);
}
/**
* Play a media from the media list (playlist)
*
* @param position The index of the media
*/
public void playIndex(int position) {
playIndex(mLibVlcInstance, position);
}
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;
}
/**
* Read a media
* @param instance: the instance of libVLC
* @param mrl: the media mrl
* @param novideo: don't enable video decoding for this media
* @return the position in the playlist
*/
private native int readMedia(long instance, String mrl, boolean novideo);
/**
* Play an index in the native media list (playlist)
*/
private native void playIndex(long instance, int position);
/**
* 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();
/**
* Play the previous media (if any) in the media list
*/
public native void previous();
/**
* Play the next media (if any) in the media list
*/
public native void next();
/**
* 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[] readTracksInfoPosition(MediaList mediaList, int position);
public native int getAudioTracksCount();
public native Map<Integer,String> getAudioTrackDescription();
public native int getAudioTrack();
public native int setAudioTrack(int index);
public native int getVideoTracksCount();
public native int addSubtitleTrack(String path);
public native Map<Integer,String> getSpuTrackDescription();
public native int getSpuTrack();
public native int setSpuTrack(int index);
public native int getSpuTracksCount();
public static native String nativeToURI(String 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<String> res);
public native static boolean nativeIsPathDirectory(String path);
/**
* Get the list of existing items in the media list (playlist)
*/
public native void getMediaListItems(ArrayList<String> arl);
/**
* 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;
}
private native void setEventHandler(EventHandler eventHandler);
private native void detachEventHandler();
public native float[] getBands();
public native String[] getPresets();
public native float[] getPreset(int index);
}

View File

@@ -0,0 +1,62 @@
/*****************************************************************************
* 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);
}
}

View File

@@ -0,0 +1,421 @@
/*****************************************************************************
* 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 android.content.Context;
import android.os.Build;
import android.util.Log;
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;
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;
}
private static String errorMsg = null;
private static boolean isCompatible = false;
public static String getErrorMsg() {
return errorMsg;
}
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")) {
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;
// "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;
}
}
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;
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;
}
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;
}
}

View File

@@ -0,0 +1,124 @@
/*****************************************************************************
* 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;
/**
* Java/JNI wrapper for the libvlc_media_list_t structure.
*/
public class MediaList {
private static final String TAG = "VLC/LibVLC/MediaList";
private long mMediaListInstance = 0; // Read-only, reserved for JNI
private long mEventHanderGlobalRef = 0; // Read-only, reserved for JNI
private LibVLC mLibVLC; // Used to create new objects that require a libvlc instance
private boolean destroyed = false;
private EventHandler mEventHandler;
public MediaList(LibVLC libVLC) {
mEventHandler = new EventHandler(); // used in init() below to fire events at the correct targets
mMediaListInstance = init(libVLC);
mLibVLC = libVLC;
}
private native long init(LibVLC libvlc_instance);
@Override
public void finalize() {
if(!destroyed) destroy();
}
/**
* Releases the media list.
*
* The object should be considered released after this and must not be used.
*/
public void destroy() {
nativeDestroy();
mMediaListInstance = 0;
mEventHanderGlobalRef = 0;
mLibVLC = null;
destroyed = true;
}
private native void nativeDestroy();
public void add(String mrl) {
add(mLibVLC, mrl, false, false);
}
public void add(String mrl, boolean noVideo) {
add(mLibVLC, mrl, noVideo, false);
}
private native void add(LibVLC libvlc_instance, String mrl, boolean noVideo, boolean noOmx);
/**
* Clear the media list. (remove all media)
*/
public native void clear();
/**
* 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) {
return expandMedia(mLibVLC, position);
}
private native int expandMedia(LibVLC libvlc_instance, int position);
public void loadPlaylist(String mrl) {
loadPlaylist(mLibVLC, mrl);
}
private native void loadPlaylist(LibVLC libvlc_instance, String mrl);
public void insert(int position, String mrl) {
insert(mLibVLC, position, mrl);
}
private native void insert(LibVLC libvlc_instance, int position, String mrl);
public native void remove(int position);
public native int size();
/**
* @param position The index of the media in the list
* @return null if not found
*/
public native String getMRL(int position);
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();
}
}

View File

@@ -0,0 +1,52 @@
/*****************************************************************************
* 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;
/* 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;
}

View File

@@ -0,0 +1,183 @@
package org.videolan.vlc;
/** Murmur hash 2.0.
*
* The murmur hash is a relative fast hash function from
* http://murmurhash.googlepages.com/ for platforms with efficient
* multiplication.
*
* This is a re-implementation of the original C code plus some
* additional features.
*
* Public domain.
*
* @author Viliam Holub
* @version 1.0.2
*
*/
public final class MurmurHash {
/** Generates 32 bit hash from byte array of the given length and
* seed.
*
* @param data byte array to hash
* @param length length of the array to hash
* @param seed initial seed value
* @return 32 bit hash of the given array
*/
public static int hash32(final byte[] data, int length, int seed) {
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.
final int m = 0x5bd1e995;
final int r = 24;
// Initialize the hash to a random value
int h = seed ^ length;
int length4 = length / 4;
for (int i = 0; i < length4; i++) {
final int i4 = i * 4;
int k = (data[i4 + 0] & 0xff) + ((data[i4 + 1] & 0xff) << 8)
+ ((data[i4 + 2] & 0xff) << 16) + ((data[i4 + 3] & 0xff) << 24);
k *= m;
k ^= k >>> r;
k *= m;
h *= m;
h ^= k;
}
// Handle the last few bytes of the input array
switch (length % 4) {
case 3:
h ^= (data[(length & ~3) + 2] & 0xff) << 16;
case 2:
h ^= (data[(length & ~3) + 1] & 0xff) << 8;
case 1:
h ^= (data[length & ~3] & 0xff);
h *= m;
}
h ^= h >>> 13;
h *= m;
h ^= h >>> 15;
return h;
}
/** Generates 32 bit hash from byte array with default seed value.
*
* @param data byte array to hash
* @param length length of the array to hash
* @return 32 bit hash of the given array
*/
public static int hash32(final byte[] data, int length) {
return hash32(data, length, 0x9747b28c);
}
/** Generates 32 bit hash from a string.
*
* @param text string to hash
* @return 32 bit hash of the given string
*/
public static int hash32(final String text) {
final byte[] bytes = text.getBytes();
return hash32(bytes, bytes.length);
}
/** Generates 32 bit hash from a substring.
*
* @param text string to hash
* @param from starting index
* @param length length of the substring to hash
* @return 32 bit hash of the given string
*/
public static int hash32(final String text, int from, int length) {
return hash32(text.substring(from, from + length));
}
/** Generates 64 bit hash from byte array of the given length and seed.
*
* @param data byte array to hash
* @param length length of the array to hash
* @param seed initial seed value
* @return 64 bit hash of the given array
*/
public static long hash64(final byte[] data, int length, int seed) {
final long m = 0xc6a4a7935bd1e995L;
final int r = 47;
long h = (seed & 0xffffffffl) ^ (length * m);
int length8 = length / 8;
for (int i = 0; i < length8; i++) {
final int i8 = i * 8;
long k = ((long) data[i8 + 0] & 0xff) + (((long) data[i8 + 1] & 0xff) << 8)
+ (((long) data[i8 + 2] & 0xff) << 16) + (((long) data[i8 + 3] & 0xff) << 24)
+ (((long) data[i8 + 4] & 0xff) << 32) + (((long) data[i8 + 5] & 0xff) << 40)
+ (((long) data[i8 + 6] & 0xff) << 48) + (((long) data[i8 + 7] & 0xff) << 56);
k *= m;
k ^= k >>> r;
k *= m;
h ^= k;
h *= m;
}
switch (length % 8) {
case 7:
h ^= (long) (data[(length & ~7) + 6] & 0xff) << 48;
case 6:
h ^= (long) (data[(length & ~7) + 5] & 0xff) << 40;
case 5:
h ^= (long) (data[(length & ~7) + 4] & 0xff) << 32;
case 4:
h ^= (long) (data[(length & ~7) + 3] & 0xff) << 24;
case 3:
h ^= (long) (data[(length & ~7) + 2] & 0xff) << 16;
case 2:
h ^= (long) (data[(length & ~7) + 1] & 0xff) << 8;
case 1:
h ^= (long) (data[length & ~7] & 0xff);
h *= m;
}
;
h ^= h >>> r;
h *= m;
h ^= h >>> r;
return h;
}
/** Generates 64 bit hash from byte array with default seed value.
*
* @param data byte array to hash
* @param length length of the array to hash
* @return 64 bit hash of the given string
*/
public static long hash64(final byte[] data, int length) {
return hash64(data, length, 0xe17a1465);
}
/** Generates 64 bit hash from a string.
*
* @param text string to hash
* @return 64 bit hash of the given string
*/
public static long hash64(final String text) {
final byte[] bytes = text.getBytes();
return hash64(bytes, bytes.length);
}
/** Generates 64 bit hash from a substring.
*
* @param text string to hash
* @param from starting index
* @param length length of the substring to hash
* @return 64 bit hash of the given array
*/
public static long hash64(final String text, int from, int length) {
return hash64(text.substring(from, from + length));
}
}

View File

@@ -0,0 +1,44 @@
/*****************************************************************************
* PhoneStateReceiver.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 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 android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import org.videolan.libvlc.LibVLC;
public class PhoneStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING) ||
state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
LibVLC libVLC = LibVLC.getExistingInstance();
if (libVLC != null && libVLC.isPlaying())
libVLC.pause();
}
}
}

View File

@@ -0,0 +1,26 @@
/*****************************************************************************
* RepeatType.java
*****************************************************************************
* Copyright © 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;
public enum RepeatType {
None,
Once,
All
}

View File

@@ -0,0 +1,546 @@
/*****************************************************************************
* Util.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 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 android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.WindowManager;
import android.widget.Toast;
import com.navinfo.collect.library.system.VLCApplication;
import org.json.JSONArray;
import org.json.JSONException;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.LibVlcException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.StringTokenizer;
public class Util {
public final static String TAG = "VLC/Util";
private final static boolean hasNavBar;
private Context context;
private static volatile Util mInstance;
/** A set of utility functions for the VLC application */
static {
HashSet<String> devicesWithoutNavBar = new HashSet<String>();
devicesWithoutNavBar.add("HTC One V");
devicesWithoutNavBar.add("HTC One S");
devicesWithoutNavBar.add("HTC One X");
devicesWithoutNavBar.add("HTC One XL");
hasNavBar = isICSOrLater() && !devicesWithoutNavBar.contains(android.os.Build.MODEL);
}
public static Util getInstance() {
if (mInstance == null) {
synchronized (Util.class) {
if (mInstance == null) {
mInstance = new Util();
}
}
}
return mInstance;
}
public void init(Context con){
this.context = con;
// Are we using advanced debugging - locale?
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(con);
String p = pref.getString("set_locale", "");
if (p != null && !p.equals("")) {
Locale locale;
// workaround due to region code
if(p.equals("zh-TW")) {
locale = Locale.TRADITIONAL_CHINESE;
} else if(p.startsWith("zh")) {
locale = Locale.CHINA;
} else if(p.equals("pt-BR")) {
locale = new Locale("pt", "BR");
} else if(p.equals("bn-IN") || p.startsWith("bn")) {
locale = new Locale("bn", "IN");
} else {
/**
* Avoid a crash of
* java.lang.AssertionError: couldn't initialize LocaleData for locale
* if the user enters nonsensical region codes.
*/
if(p.contains("-"))
p = p.substring(0, p.indexOf('-'));
locale = new Locale(p);
}
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
con.getResources().updateConfiguration(config,
con.getResources().getDisplayMetrics());
}
}
public LibVLC getLibVlcInstance() throws LibVlcException {
LibVLC instance = LibVLC.getExistingInstance();
if (instance == null) {
Thread.setDefaultUncaughtExceptionHandler(new VlcCrashHandler());
instance = LibVLC.getInstance();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
updateLibVlcSettings(pref);
instance.init(context);
}
return instance;
}
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();
}
}
public static void updateLibVlcSettings(SharedPreferences pref) {
LibVLC instance = LibVLC.getExistingInstance();
if (instance == null)
return;
instance.setIomx(pref.getBoolean("enable_iomx", false));
instance.setSubtitlesEncoding(pref.getString("subtitles_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(getFloatArray(pref, "equalizer_values"));
int aout;
try {
aout = Integer.parseInt(pref.getString("aout", "-1"));
}
catch (NumberFormatException nfe) {
aout = -1;
}
int deblocking;
try {
deblocking = Integer.parseInt(pref.getString("deblocking", "-1"));
}
catch(NumberFormatException nfe) {
deblocking = -1;
}
int networkCaching = pref.getInt("network_caching_value", 0);
if(networkCaching > 60000)
networkCaching = 60000;
else if(networkCaching < 0)
networkCaching = 0;
instance.setAout(aout);
instance.setDeblocking(deblocking);
instance.setNetworkCaching(networkCaching);
}
/** Print an on-screen message to alert the user */
public static void toaster(Context context, int stringId, int duration) {
Toast.makeText(context, stringId, duration).show();
}
public static void toaster(Context context, int stringId) {
toaster(context, stringId, Toast.LENGTH_SHORT);
}
public static File URItoFile(String URI) {
return new File(Uri.decode(URI).replace("file://",""));
}
public static String URItoFileName(String URI) {
return URItoFile(URI).getName();
}
public static String stripTrailingSlash(String s) {
if( s.endsWith("/") && s.length() > 1 )
return s.substring(0, s.length() - 1);
return s;
}
public static String readAsset(String assetName, String defaultS) {
try {
InputStream is = VLCApplication.getAppResources().getAssets().open(assetName);
BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF8"));
StringBuilder sb = new StringBuilder();
String line = r.readLine();
if(line != null) {
sb.append(line);
line = r.readLine();
while(line != null) {
sb.append('\n');
sb.append(line);
line = r.readLine();
}
}
return sb.toString();
} catch (IOException e) {
return defaultS;
}
}
/**
* Convert time to a string
* @param millis e.g.time/length from file
* @return formated string (hh:)mm:ss
*/
public static String millisToString(long millis)
{
return millisToString(millis, false);
}
/**
* Convert time to a string
* @param millis e.g.time/length from file
* @return formated string "[hh]h[mm]min" / "[mm]min[s]s"
*/
public static String millisToText(long millis)
{
return millisToString(millis, true);
}
private static String millisToString(long millis, boolean text) {
boolean negative = millis < 0;
millis = Math.abs(millis);
millis /= 1000;
int sec = (int) (millis % 60);
millis /= 60;
int min = (int) (millis % 60);
millis /= 60;
int hours = (int) millis;
String time;
DecimalFormat format = (DecimalFormat)NumberFormat.getInstance(Locale.US);
format.applyPattern("00");
if (text) {
if (millis > 0)
time = (negative ? "-" : "") + hours + "h" + format.format(min) + "min";
else if (min > 0)
time = (negative ? "-" : "") + min + "min";
else
time = (negative ? "-" : "") + sec + "s";
}
else {
if (millis > 0)
time = (negative ? "-" : "") + hours + ":" + format.format(min) + ":" + format.format(sec);
else
time = (negative ? "-" : "") + min + ":" + format.format(sec);
}
return time;
}
public static Bitmap scaleDownBitmap(Context context, Bitmap bitmap, int width) {
/*
* This method can lead to OutOfMemoryError!
* If the source size is more than twice the target size use
* the optimized version available in AudioUtil::readCoverBitmap
*/
if (bitmap != null) {
final float densityMultiplier = context.getResources().getDisplayMetrics().density;
int w = (int) (width * densityMultiplier);
int h = (int) (w * bitmap.getHeight() / ((double) bitmap.getWidth()));
bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
}
return bitmap;
}
public static Bitmap cropBorders(Bitmap bitmap, int width, int height)
{
int top = 0;
for (int i = 0; i < height / 2; i++) {
int pixel1 = bitmap.getPixel(width / 2, i);
int pixel2 = bitmap.getPixel(width / 2, height - i - 1);
if ((pixel1 == 0 || pixel1 == -16777216) &&
(pixel2 == 0 || pixel2 == -16777216)) {
top = i;
} else {
break;
}
}
int left = 0;
for (int i = 0; i < width / 2; i++) {
int pixel1 = bitmap.getPixel(i, height / 2);
int pixel2 = bitmap.getPixel(width - i - 1, height / 2);
if ((pixel1 == 0 || pixel1 == -16777216) &&
(pixel2 == 0 || pixel2 == -16777216)) {
left = i;
} else {
break;
}
}
if (left >= width / 2 - 10 || top >= height / 2 - 10)
return bitmap;
// Cut off the transparency on the borders
return Bitmap.createBitmap(bitmap, left, top,
(width - (2 * left)), (height - (2 * top)));
}
public static String getValue(String string, int defaultId)
{
return (string != null && string.length() > 0) ?
string : VLCApplication.getAppContext().getString(defaultId);
}
public static int convertPxToDp(int px) {
WindowManager wm = (WindowManager)VLCApplication.getAppContext().
getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
float logicalDensity = metrics.density;
int dp = Math.round(px / logicalDensity);
return dp;
}
public static int convertDpToPx(int dp) {
return Math.round(
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
VLCApplication.getAppResources().getDisplayMetrics())
);
}
public static boolean isFroyoOrLater()
{
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.FROYO;
}
public static boolean isGingerbreadOrLater()
{
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD;
}
public static boolean isHoneycombOrLater()
{
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB;
}
public static boolean isICSOrLater()
{
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}
public static boolean isJellyBeanOrLater()
{
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN;
}
public static boolean hasExternalStorage() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
public static boolean hasNavBar()
{
return hasNavBar;
}
/** hasCombBar test if device has Combined Bar : only for tablet with Honeycomb or ICS */
public static boolean hasCombBar() {
return (!isPhone()
&& ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) &&
(android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.JELLY_BEAN)));
}
public static boolean isPhone(){
TelephonyManager manager = (TelephonyManager)VLCApplication.getAppContext().getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
return false;
}else{
return true;
}
}
public static String[] getStorageDirectories()
{
String[] dirs = null;
BufferedReader bufReader = null;
try {
bufReader = new BufferedReader(new FileReader("/proc/mounts"));
ArrayList<String> list = new ArrayList<String>();
list.add(Environment.getExternalStorageDirectory().getPath());
String line;
while((line = bufReader.readLine()) != null) {
if(line.contains("vfat") || line.contains("exfat") ||
line.contains("/mnt") || line.contains("/Removable")) {
StringTokenizer tokens = new StringTokenizer(line, " ");
String s = tokens.nextToken();
s = tokens.nextToken(); // Take the second token, i.e. mount point
if (list.contains(s))
continue;
if (line.contains("/dev/block/vold")) {
if (!line.startsWith("tmpfs") &&
!line.startsWith("/dev/mapper") &&
!s.startsWith("/mnt/secure") &&
!s.startsWith("/mnt/shell") &&
!s.startsWith("/mnt/asec") &&
!s.startsWith("/mnt/obb")
) {
list.add(s);
}
}
}
}
dirs = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
dirs[i] = list.get(i);
}
}
catch (FileNotFoundException e) {}
catch (IOException e) {}
finally {
if (bufReader != null) {
try {
bufReader.close();
}
catch (IOException e) {}
}
}
return dirs;
}
public static String[] getCustomDirectories() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(VLCApplication.getAppContext());
final String custom_paths = preferences.getString("custom_paths", "");
if(custom_paths.equals(""))
return new String[0];
else
return custom_paths.split(":");
}
public static String[] getMediaDirectories() {
ArrayList<String> list = new ArrayList<String>();
list.addAll(Arrays.asList(Util.getStorageDirectories()));
list.addAll(Arrays.asList(Util.getCustomDirectories()));
return list.toArray(new String[list.size()]);
}
public static void addCustomDirectory(String path) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(VLCApplication.getAppContext());
ArrayList<String> dirs = new ArrayList<String>(
Arrays.asList(getCustomDirectories()));
dirs.add(path);
StringBuilder builder = new StringBuilder();
builder.append(dirs.remove(0));
for(String s : dirs) {
builder.append(":");
builder.append(s);
}
Editor editor = preferences.edit();
editor.putString("custom_paths", builder.toString());
editor.commit();
}
public static void removeCustomDirectory(String path) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(VLCApplication.getAppContext());
if(!preferences.getString("custom_paths", "").contains(path))
return;
ArrayList<String> dirs = new ArrayList<String>(
Arrays.asList(preferences.getString("custom_paths", "").split(
":")));
dirs.remove(path);
String custom_path;
if(dirs.size() > 0) {
StringBuilder builder = new StringBuilder();
builder.append(dirs.remove(0));
for(String s : dirs) {
builder.append(":");
builder.append(s);
}
custom_path = builder.toString();
} else { // don't do unneeded extra work
custom_path = "";
}
Editor editor = preferences.edit();
editor.putString("custom_paths", custom_path);
editor.commit();
}
/**
* Get the formatted current playback speed in the form of 1.00x
*/
public static String formatRateString(float rate) {
return String.format(Locale.US, "%.2fx", rate);
}
/**
* equals() with two strings where either could be null
*/
public static boolean nullEquals(String s1, String s2) {
return (s1 == null ? s2 == null : s1.equals(s2));
}
}

View File

@@ -0,0 +1,125 @@
/*****************************************************************************
* VlcCrashHandler.java
*****************************************************************************
* Copyright © 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 android.os.Environment;
import android.text.format.DateFormat;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
public class VlcCrashHandler implements UncaughtExceptionHandler {
private static final String TAG = "VLC/VlcCrashHandler";
private UncaughtExceptionHandler defaultUEH;
public VlcCrashHandler() {
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
// Inject some info about android version and the device, since google can't provide them in the developer console
StackTraceElement[] trace = ex.getStackTrace();
StackTraceElement[] trace2 = new StackTraceElement[trace.length+3];
System.arraycopy(trace, 0, trace2, 0, trace.length);
trace2[trace.length+0] = new StackTraceElement("Android", "MODEL", android.os.Build.MODEL, -1);
trace2[trace.length+1] = new StackTraceElement("Android", "VERSION", android.os.Build.VERSION.RELEASE, -1);
trace2[trace.length+2] = new StackTraceElement("Android", "FINGERPRINT", android.os.Build.FINGERPRINT, -1);
ex.setStackTrace(trace2);
ex.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
Log.e(TAG, stacktrace);
// Save the log on SD card if available
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String sdcardPath = Environment.getExternalStorageDirectory().getPath();
writeLog(stacktrace, sdcardPath + "/vlc_crash");
writeLogcat(sdcardPath + "/vlc_logcat");
}
defaultUEH.uncaughtException(thread, ex);
}
private void writeLog(String log, String name) {
CharSequence timestamp = DateFormat.format("yyyyMMdd_kkmmss", System.currentTimeMillis());
String filename = name + "_" + timestamp + ".log";
try {
FileOutputStream stream = new FileOutputStream(filename);
OutputStreamWriter output = new OutputStreamWriter(stream);
BufferedWriter bw = new BufferedWriter(output);
bw.write(log);
bw.newLine();
bw.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void writeLogcat(String name) {
CharSequence timestamp = DateFormat.format("yyyyMMdd_kkmmss", System.currentTimeMillis());
String filename = name + "_" + timestamp + ".log";
String[] args = { "logcat", "-v", "time", "-d" };
try {
Process process = Runtime.getRuntime().exec(args);
InputStreamReader input = new InputStreamReader(
process.getInputStream());
OutputStreamWriter output = new OutputStreamWriter(
new FileOutputStream(filename));
BufferedReader br = new BufferedReader(input);
BufferedWriter bw = new BufferedWriter(output);
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
}
bw.close();
output.close();
br.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,39 @@
/*****************************************************************************
* VlcRunnable.java
*****************************************************************************
* Copyright © 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;
public abstract class VlcRunnable implements Runnable {
private final Object user;
public VlcRunnable() {
this.user = null;
}
public VlcRunnable(Object o) {
this.user = o;
}
public abstract void run(Object o);
@Override
public void run() {
run(user);
}
}

View File

@@ -0,0 +1,37 @@
/*****************************************************************************
* WeakHandler.java
*****************************************************************************
* Copyright © 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 android.os.Handler;
import java.lang.ref.WeakReference;
public abstract class WeakHandler<T> extends Handler {
private WeakReference<T> mOwner;
public WeakHandler(T owner) {
mOwner = new WeakReference<T>(owner);
}
public T getOwner() {
return mOwner.get();
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:topLeftRadius="3dp" android:topRightRadius="3dp" android:bottomLeftRadius="3dp" android:bottomRightRadius="3dp"></corners>
<padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp"/>
<solid android:color="#AA535353"></solid>
</shape>

View File

@@ -9,6 +9,7 @@
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="transparent">#00FFFFFF</color>
<color name="background_light">#ffffffff</color>
<color name="draw_line_blue1_color" comment="线数据样式">#028FFF</color>
<color name="draw_line_blue2_color" comment="线数据样式">#4E55AF</color>
<color name="draw_line_red_color" comment="线数据样式">#FFF6565D</color>