package com.media;
import java.io.IOException;
import java.lang.ref.WeakReference;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.view.Surface;
import android.view.SurfaceHolder;
public class NativePlayer extends MediaPlayer
{
private static final int MEDIA_NOP = 0; // interface test message
private static final int MEDIA_PREPARED = 1;
private static final int MEDIA_PLAYBACK_COMPLETE = 2;
private static final int MEDIA_BUFFERING_UPDATE = 3;
private static final int MEDIA_SEEK_COMPLETE = 4;
private static final int MEDIA_SET_VIDEO_SIZE = 5;
private static final int MEDIA_ERROR = 100;
private static final int MEDIA_INFO = 200;
private static final int MEDIA_LOADING_PER = 400;
private final static String TAG = "NativePlayer";
private int mNativeContext;
private int mNativeData = 0;
private Surface mSurface;
private AudioTrack mTrack;
private SurfaceHolder mSurfaceHolder;
private static Rect mRect = null;
private EventHandler mEventHandler;
private PowerManager.WakeLock mWakeLock = null;
private boolean mScreenOnWhilePlaying;
private boolean mStayAwake;
private static Bitmap mBitmap;
private boolean mLocalLogable = true;
static{
try {
NativeLib loadLib = new NativeLib();
} catch (Exception e) {
e.printStackTrace();
}
}
public NativePlayer() {
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else {
mEventHandler = null;
}
native_init();
native_setup(new WeakReference<NativePlayer>(this));
setLocalLogable(mLocalLogable);
}
public static void initAudioTrack(Object mediaplayer_ref, int sampleRateInHz, int channelConfig) throws IOException
{
NativePlayer mp = (NativePlayer)((WeakReference<?>)mediaplayer_ref).get();
if (mp == null) {
return;
}
int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, AudioFormat.ENCODING_PCM_16BIT);
mp.mTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRateInHz, channelConfig, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes, AudioTrack.MODE_STREAM);
mp.mTrack.play();
}
public static void writeAudioTrack(Object mediaplayer_ref, byte[] audioData, int size) throws IOException
{
NativePlayer mp = (NativePlayer)((WeakReference<?>)mediaplayer_ref).get();
if (mp == null) {
return;
}
mp.mTrack.write(audioData, 0, size);
}
public static void releaseAudioTrack(Object mediaplayer_ref) throws IOException
{
NativePlayer mp = (NativePlayer)((WeakReference<?>)mediaplayer_ref).get();
if (mp == null) {
return;
}
if(mp.mTrack!=null)
{
mp.mTrack.stop();
mp.mTrack.release();
mp.mTrack = null;
}
}
private native void _setAudioTrack(AudioTrack track) throws IOException;
public static void JavaDraw(Object mediaplayer_ref) throws IOException
{
NativePlayer mp = (NativePlayer)((WeakReference<?>)mediaplayer_ref).get();
if (mp == null) {
return;
}
Canvas canvas = mp.mSurfaceHolder.lockCanvas(mRect);
if (canvas == null){
return;
}
_nativeDraw(mBitmap);
canvas.drawBitmap(mBitmap, 0, 0, null);
mp.mSurfaceHolder.unlockCanvasAndPost(canvas);
}
private static native void _nativeDraw(Bitmap canvas);
private static void postEventFromNative(Object mediaplayer_ref, int what, int arg1, int arg2, Object obj) {
NativePlayer mp = (NativePlayer)((WeakReference<?>)mediaplayer_ref).get();
if (mp == null) {
return;
}
if (mp.mEventHandler != null) {
Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);
mp.mEventHandler.sendMessage(m);
}
}
public void setDisplay(SurfaceHolder sh) {
mSurfaceHolder = sh;
if (sh != null) {
mSurface = sh.getSurface();
} else {
mSurface = null;
}
updateSurfaceScreenOn();
// _setVideoSurface(mSurface);
}
public void start() throws IllegalStateException {
stayAwake(true);
_start();
}
public void stop() throws IllegalStateException {
stayAwake(false);
_stop();
}
public void pause() throws IllegalStateException {
stayAwake(false);
_pause();
}
public void prepareAsync() throws IllegalStateException{
try {
prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setDataSource(Context context, Uri uri){
try {
setDataSource(uri.toString());
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private native void setLocalLogable(boolean logable);
private native void _setVideoSurface(Surface surface) throws IOException;
public native void setDataSource(String path) throws IOException, IllegalArgumentException, IllegalStateException;
public native void prepare() throws IOException, IllegalStateException;
private native void _start() throws IllegalStateException;
private native void _stop() throws IllegalStateException;
private native void _pause() throws IllegalStateException;
public native int getVideoWidth();
public native int getVideoHeight();
public native boolean isPlaying();
public native void seekTo(int msec) throws IllegalStateException;
public native int getCurrentPosition();
public native int getDuration();
private native void _release();
private native void _reset();
private native int native_suspend_resume(boolean isSuspend);
public native void setAudioStreamType(int streamtype);
private static native final void native_init() throws RuntimeException;
private native final void native_setup(Object mediaplayer_this);
private native final void native_finalize();
public void release() {
stayAwake(false);
updateSurfaceScreenOn();
mOnPreparedListener = null;
mOnBufferingUpdateListener = null;
mOnCompletionListener = null;
mOnSeekCompleteListener = null;
mOnErrorListener = null;
mOnInfoListener = null;
mOnVideoSizeChangedListener = null;
_release();
if (mSurfaceHolder != null){
Canvas tmpCanvas = mSurfaceHolder.lockCanvas(mRect);
if (tmpCanvas != null){
tmpCanvas.drawColor(Color.BLACK);
mSurfaceHolder.unlockCanvasAndPost(tmpCanvas);
}
}
}
public void reset() {
stayAwake(false);
_reset();
mEventHandler.removeCallbacksAndMessages(null);
}
public boolean suspend() {
if (native_suspend_resume(true) < 0) {
return false;
}
stayAwake(false);
mEventHandler.removeCallbacksAndMessages(null);
return true;
}
public boolean resume() {
if (native_suspend_resume(false) < 0) {
return false;
}
if (isPlaying()) {
stayAwake(true);
}
return true;
}
public void setWakeMode(Context context, int mode) {
boolean washeld = false;
if (mWakeLock != null) {
if (mWakeLock.isHeld()) {
washeld = true;
mWakeLock.release();
}
mWakeLock = null;
}
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(mode|PowerManager.ON_AFTER_RELEASE, MediaPlayer.class.getName());
mWakeLock.setReferenceCounted(false);
if (washeld) {
mWakeLock.acquire();
}
}
public void setScreenOnWhilePlaying(boolean screenOn) {
if (mScreenOnWhilePlaying != screenOn) {
mScreenOnWhilePlaying = screenOn;
updateSurfaceScreenOn();
}
}
private void stayAwake(boolean awake) {
if (mWakeLock != null) {
if (awake && !mWakeLock.isHeld()) {
mWakeLock.acquire();
} else if (!awake && mWakeLock.isHeld()) {
mWakeLock.release();
}
}
mStayAwake = awake;
updateSurfaceScreenOn();
}
private void updateSurfaceScreenOn() {
if (mSurfaceHolder != null) {
mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
}
}
private OnVideoSizeChangedListener mOnVideoSizeChangedListener;
public void setOnVideoSizeChangedListener(
OnVideoSizeChangedListener mSizeChangedListener) {
mOnVideoSizeChangedListener = mSizeChangedListener;
}
private OnSeekCompleteListener mOnSeekCompleteListener;
public void setOnSeekCompleteListener(OnSeekCompleteListener listener)
{
mOnSeekCompleteListener = listener;
}
private OnPreparedListener mOnPreparedListener;
public void setOnPreparedListener(OnPreparedListener listener)
{
mOnPreparedListener = listener;
}
private OnBufferingUpdateListener mOnBufferingUpdateListener;
public void setOnBufferingUpdateListener(OnBufferingUpdateListener listener)
{
mOnBufferingUpdateListener = listener;
}
private OnCompletionListener mOnCompletionListener;
public void setOnCompletionListener(OnCompletionListener listener)
{
mOnCompletionListener = listener;
}
private OnErrorListener mOnErrorListener;
public void setOnErrorListener(OnErrorListener listener)
{
mOnErrorListener = listener;
}
private OnInfoListener mOnInfoListener;
public void setOnInfoListener(OnInfoListener listener)
{
mOnInfoListener = listener;
}
public interface OnLoadingPerListener
{
void onLoadingPer(MediaPlayer mp, int per);
}
private OnLoadingPerListener mOnLoadingPerListener;
public void setOnLoadingPerListener(OnLoadingPerListener listener)
{
mOnLoadingPerListener = listener;
}
private class EventHandler extends Handler
{
private NativePlayer mMediaPlayer;
public EventHandler(NativePlayer nativePlayer, Looper looper) {
super(looper);
mMediaPlayer = nativePlayer;
}
@Override
public void handleMessage(Message msg) {
if (mMediaPlayer.mNativeContext == 0) {
return;
}
switch(msg.what) {
case MEDIA_PREPARED:
if (mOnPreparedListener != null)
mOnPreparedListener.onPrepared(mMediaPlayer);
return;
case MEDIA_PLAYBACK_COMPLETE:
if (mOnCompletionListener != null)
mOnCompletionListener.onCompletion(mMediaPlayer);
stayAwake(false);
return;
case MEDIA_BUFFERING_UPDATE:
if (mOnBufferingUpdateListener != null){
mOnBufferingUpdateListener.onBufferingUpdate(mMediaPlayer, msg.arg1);
}
return;
case MEDIA_SEEK_COMPLETE:
if (mOnSeekCompleteListener != null)
mOnSeekCompleteListener.onSeekComplete(mMediaPlayer);
return;
case MEDIA_SET_VIDEO_SIZE:
if (mOnVideoSizeChangedListener != null){
if (null == mRect){
mRect = new Rect();
mRect.set(0, 0, msg.arg1, msg.arg2);
}
mBitmap = Bitmap.createBitmap(msg.arg1, msg.arg2, Bitmap.Config.RGB_565);
mOnVideoSizeChangedListener.onVideoSizeChanged(mMediaPlayer, msg.arg1, msg.arg2);
}
return;
case MEDIA_ERROR:
boolean error_was_handled = false;
if (mOnErrorListener != null) {
error_was_handled = mOnErrorListener.onError(mMediaPlayer, msg.arg1, msg.arg2);
}
if (mOnCompletionListener != null && !error_was_handled) {
mOnCompletionListener.onCompletion(mMediaPlayer);
}
stayAwake(false);
return;
case MEDIA_INFO:
if (mOnInfoListener != null) {
mOnInfoListener.onInfo(mMediaPlayer, msg.arg1, msg.arg2);
}
return;
case MEDIA_LOADING_PER:
if (mOnLoadingPerListener != null) {
mOnLoadingPerListener.onLoadingPer(mMediaPlayer, msg.arg1);
}
case MEDIA_NOP:
break;
default:
return;
}
}
}
}