增加佳明相机业务

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

@@ -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>