android mediaplayer 自定义 mediacontroller

来源:互联网 发布:长春java培训哪家好 编辑:程序博客网 时间:2024/05/31 15:19
  以前做的一个项目,与流媒体相关的,那时学了好多相关知识,还写了一个自定义的 MediaPlayer Controller。现在稍微有点时间,简单整理一下,顺便分享出来。你要做的只是实现 Controller.ControlOper,并把 Controller 设置为你的 MediaPlayer 的控制器即可。注意那个mPlayer.setDataSource()里面那个 url,是个开放的 rtsp 测试地址,可能会失效哦,如果失效的话,会看到“黑屏”,出现这种情况的话,请自己换个别的测试地址哦。
  另外,在 onDestory() 里面要记得释放相关资源哦!
 @Override protected void onDestroy() {  super.onDestroy();  releaseMediaPlayer(); } private void releaseMediaPlayer() {   mController.removeHandlerCallback();  if (mPlayer != null) {      mPlayer.stop();      mPlayer.release();  } } public void removeHandlerCallback() {    if(mHandler != null) {      mHandler.removeCallbacksAndMessages(null);      mHandler = null;    } }

一、MediaplayerController

  MediaplayerController(以下简称 Controller)是一个用于 MediaPlayer 的 view 类。该 view 上有通用的控件,如播放/暂停,前进/后退等。你需要做的只是实现 Controller.ControlOper 接口,并把该控制器设置为你的 MediaPlayer 的控制器即可。控制器的 view 都抽出来了,你可以根据需要进行修改,做出漂亮的控制器来了。
public class Controller extends FrameLayout {    private static final String LOG_TAG = Controller.class.getName();        private static final int    FADE_OUT = 1;    private static final int    DEFTIMEOUT = 3000;    private static final int    SHOW_PROGRESS = 2;        private ImageButton         mBtnPause;    private ImageButton         mBtnFfwd;    private ImageButton         mBtnRew;    private ImageButton         mBtnNext;    private ImageButton         mBtnPrev;    private ImageButton         mBtnFullscreen;    private Handler             mHandler = new MsgHandler(this);        private ControlOper  mPlayerCtrl;    private Context             mContext;    private ViewGroup           mAnchorVGroup;    private View                mRootView;    private ProgressBar         mProgress;    private TextView            mEndTime, mCurTime;    private boolean             mIsShowing;    private boolean             mIsDragging;        private boolean             mUseFastForward;    private boolean             mFromXml;    private boolean             mIsListenersSet;    private View.OnClickListener mNextListener, mPrevListener;    StringBuilder               mStrBuilder;    Formatter                   mFormatter;        public Controller(Context context) {        this(context, true);    }    public Controller(Context context, AttributeSet attrs) {        super(context, attrs);                mRootView = null;        mContext = context;        mUseFastForward = true;        mFromXml = true;    }    public Controller(Context context, boolean useFastForward) {        super(context);        mContext = context;        mUseFastForward = useFastForward;    }        public void removeHandlerCallback() {    if(mHandler != null) {    mHandler.removeCallbacksAndMessages(null);    mHandler = null;    }    }    @Override    public void onFinishInflate() {        if (mRootView != null) {            initCtrlView(mRootView);        }    }        public void setMediaPlayer(ControlOper player) {        mPlayerCtrl = player;        updatePausePlay();        updateFullScreen();    }    public void setAnchorView(ViewGroup view) {            mAnchorVGroup = view;        FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(                ViewGroup.LayoutParams.MATCH_PARENT,                ViewGroup.LayoutParams.MATCH_PARENT        );        removeAllViews();                View v = createCtrlView();        addView(v, frameParams);    }    protected View createCtrlView() {           LayoutInflater inflate = (LayoutInflater) mContext        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);                mRootView = inflate.inflate(R.layout.controller, null);        initCtrlView(mRootView);        return mRootView;    }    private void initCtrlView(View v) {            mBtnPause = (ImageButton) v.findViewById(R.id.pause);        if (mBtnPause != null) {            mBtnPause.requestFocus();            mBtnPause.setOnClickListener(mPauseListener);        }                mBtnFullscreen = (ImageButton) v.findViewById(R.id.fullscreen);        if (mBtnFullscreen != null) {            mBtnFullscreen.requestFocus();            mBtnFullscreen.setOnClickListener(mFullscreenListener);        }        mBtnFfwd = (ImageButton) v.findViewById(R.id.ffwd);        if (mBtnFfwd != null) {            mBtnFfwd.setOnClickListener(mFfwdListener);            if (!mFromXml) {                mBtnFfwd.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);            }        }        mBtnRew = (ImageButton) v.findViewById(R.id.rew);        if (mBtnRew != null) {            mBtnRew.setOnClickListener(mRewListener);            if (!mFromXml) {                mBtnRew.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);            }        }        // By default these are hidden. They will be enabled when setPrevNextListeners() is called         mBtnNext = (ImageButton) v.findViewById(R.id.next);        if (mBtnNext != null && !mFromXml && !mIsListenersSet) {            mBtnNext.setVisibility(View.GONE);        }                mBtnPrev = (ImageButton) v.findViewById(R.id.prev);        if (mBtnPrev != null && !mFromXml && !mIsListenersSet) {            mBtnPrev.setVisibility(View.GONE);        }        mProgress = (ProgressBar) v.findViewById(R.id.mediacontroller_progress);        if (mProgress != null) {            if (mProgress instanceof SeekBar) {                SeekBar seeker = (SeekBar) mProgress;                seeker.setOnSeekBarChangeListener(mSeekListener);            }            mProgress.setMax(1000);        }        mEndTime = (TextView) v.findViewById(R.id.time);        mCurTime = (TextView) v.findViewById(R.id.time_current);        mStrBuilder = new StringBuilder();        mFormatter = new Formatter(mStrBuilder, Locale.getDefault());        installPrevNextListeners();    }    /**     * Show the controller on screen. It will go away automatically after     * 3 seconds of inactivity.     */    public void show() {        show(DEFTIMEOUT);    }    /**     * Disable pause or seek buttons if the stream cannot be paused or seeked.     * This requires the control interface to be a MediaPlayerControlExt     */    private void disableUnsupportedButtons() {        if (mPlayerCtrl == null) {            return;        }                try {            if (mBtnPause != null && !mPlayerCtrl.canPause()) {                mBtnPause.setEnabled(false);            }            if (mBtnRew != null && !mPlayerCtrl.canSeekBackward()) {                mBtnRew.setEnabled(false);            }            if (mBtnFfwd != null && !mPlayerCtrl.canSeekForward()) {                mBtnFfwd.setEnabled(false);            }        } catch (IncompatibleClassChangeError ex) {                }    }        public void show(int timeout) {        if (!mIsShowing && mAnchorVGroup != null) {            setProgress();            if (mBtnPause != null) {                mBtnPause.requestFocus();            }            disableUnsupportedButtons();            FrameLayout.LayoutParams tlp = new FrameLayout.LayoutParams(                ViewGroup.LayoutParams.MATCH_PARENT,                ViewGroup.LayoutParams.WRAP_CONTENT,                Gravity.BOTTOM            );                        mAnchorVGroup.addView(this, tlp);            mIsShowing = true;        }        updatePausePlay();        updateFullScreen();                        mHandler.sendEmptyMessage(SHOW_PROGRESS);        Message msg = mHandler.obtainMessage(FADE_OUT);        if (timeout != 0) {            mHandler.removeMessages(FADE_OUT);            mHandler.sendMessageDelayed(msg, timeout);        }    }        public boolean isShowing() {        return mIsShowing;    }    /**     * Remove the controller from the screen.     */    public void hide() {        if (mAnchorVGroup == null) {            return;        }        try {            mAnchorVGroup.removeView(this);            if(mHandler != null) {            mHandler.removeMessages(SHOW_PROGRESS);            }        } catch (IllegalArgumentException ex) {            Log.w("MediaController", "already removed");        }        mIsShowing = false;    }    private String stringForTime(int timeMs) {        int totalSeconds = timeMs / 1000;        int seconds = totalSeconds % 60;        int minutes = (totalSeconds / 60) % 60;        int hours   = totalSeconds / 3600;        mStrBuilder.setLength(0);        if (hours > 0) {            return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();        } else {            return mFormatter.format("%02d:%02d", minutes, seconds).toString();        }    }    private int setProgress() {        if (mPlayerCtrl == null || mIsDragging) {            return 0;        }                int position = mPlayerCtrl.getCurPosition();        int duration = mPlayerCtrl.getDuration();        if (mProgress != null) {            if (duration > 0) {                // use long to avoid overflow                long pos = 1000L * position / duration;                mProgress.setProgress( (int) pos);            }            int percent = mPlayerCtrl.getBufPercent();            mProgress.setSecondaryProgress(percent * 10);        }        if (mEndTime != null)            mEndTime.setText(stringForTime(duration));        if (mCurTime != null)            mCurTime.setText(stringForTime(position));        return position;    }    @Override    public boolean onTouchEvent(MotionEvent event) {        show(DEFTIMEOUT);        return true;    }    @Override    public boolean onTrackballEvent(MotionEvent ev) {        show(DEFTIMEOUT);        return false;    }    @Override    public boolean dispatchKeyEvent(KeyEvent event) {        if (mPlayerCtrl == null) {            return true;        }                int keyCode = event.getKeyCode();        final boolean uniqueDown = event.getRepeatCount() == 0                && event.getAction() == KeyEvent.ACTION_DOWN;        if (keyCode ==  KeyEvent.KEYCODE_HEADSETHOOK                || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE                || keyCode == KeyEvent.KEYCODE_SPACE) {            if (uniqueDown) {                doPauseResume();                show(DEFTIMEOUT);                if (mBtnPause != null) {                    mBtnPause.requestFocus();                }            }            return true;        } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {            if (uniqueDown && !mPlayerCtrl.isPlaying()) {                mPlayerCtrl.start();                updatePausePlay();                show(DEFTIMEOUT);            }            return true;        } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP                || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {            if (uniqueDown && mPlayerCtrl.isPlaying()) {                mPlayerCtrl.pause();                updatePausePlay();                show(DEFTIMEOUT);            }            return true;        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN                || keyCode == KeyEvent.KEYCODE_VOLUME_UP                || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {            // don't show the controls for volume adjustment            return super.dispatchKeyEvent(event);        } else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {            if (uniqueDown) {                hide();            }            return true;        }        show(DEFTIMEOUT);        return super.dispatchKeyEvent(event);    }    private View.OnClickListener mPauseListener = new View.OnClickListener() {        public void onClick(View v) {            doPauseResume();            show(DEFTIMEOUT);        }    };    private View.OnClickListener mFullscreenListener = new View.OnClickListener() {        public void onClick(View v) {            doToggleFullscreen();            show(DEFTIMEOUT);        }    };    public void updatePausePlay() {        if (mRootView == null || mBtnPause == null || mPlayerCtrl == null) {            return;        }        if (mPlayerCtrl.isPlaying()) {            mBtnPause.setImageResource(R.drawable.pause);        } else {            mBtnPause.setImageResource(R.drawable.play);        }    }    public void updateFullScreen() {        if (mRootView == null || mBtnFullscreen == null || mPlayerCtrl == null) {            return;        }                if (mPlayerCtrl.isFullScreen()) {            mBtnFullscreen.setImageResource(R.drawable.nscale);        }        else {            mBtnFullscreen.setImageResource(R.drawable.scale);        }    }    private void doPauseResume() {        if (mPlayerCtrl == null) {            return;        }                if (mPlayerCtrl.isPlaying()) {            mPlayerCtrl.pause();        } else {            mPlayerCtrl.start();        }        updatePausePlay();    }    private void doToggleFullscreen() {        if (mPlayerCtrl == null) {            return;        }        Log.i(LOG_TAG, "doToggleFullscreen");        mPlayerCtrl.fullScreen();    }    private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {        public void onStartTrackingTouch(SeekBar bar) {            show(3600000);            mIsDragging = true;            mHandler.removeMessages(SHOW_PROGRESS);        }        public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {            if (mPlayerCtrl == null) {                return;            }                        if (!fromuser) {                // We're not interested in programmatically generated changes to                // the progress bar's position.                return;            }            long duration = mPlayerCtrl.getDuration();            long newposition = (duration * progress) / 1000L;            mPlayerCtrl.seekTo( (int) newposition);            if (mCurTime != null)                mCurTime.setText(stringForTime( (int) newposition));        }        public void onStopTrackingTouch(SeekBar bar) {            mIsDragging = false;            setProgress();            updatePausePlay();            show(DEFTIMEOUT);                        mHandler.sendEmptyMessage(SHOW_PROGRESS);        }    };    @Override    public void setEnabled(boolean enabled) {        if (mBtnPause != null) {            mBtnPause.setEnabled(enabled);        }        if (mBtnFfwd != null) {            mBtnFfwd.setEnabled(enabled);        }        if (mBtnRew != null) {            mBtnRew.setEnabled(enabled);        }        if (mBtnNext != null) {            mBtnNext.setEnabled(enabled && mNextListener != null);        }        if (mBtnPrev != null) {            mBtnPrev.setEnabled(enabled && mPrevListener != null);        }        if (mProgress != null) {            mProgress.setEnabled(enabled);        }        disableUnsupportedButtons();        super.setEnabled(enabled);    }    @SuppressLint("NewApi")@Override    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {        super.onInitializeAccessibilityEvent(event);        event.setClassName(Controller.class.getName());    }    @SuppressLint("NewApi")@Override    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {        super.onInitializeAccessibilityNodeInfo(info);        info.setClassName(Controller.class.getName());    }    private View.OnClickListener mRewListener = new View.OnClickListener() {        public void onClick(View v) {            if (mPlayerCtrl == null) {                return;            }                        int pos = mPlayerCtrl.getCurPosition();            pos -= 5000; // milliseconds            mPlayerCtrl.seekTo(pos);            setProgress();            show(DEFTIMEOUT);        }    };    private View.OnClickListener mFfwdListener = new View.OnClickListener() {        public void onClick(View v) {            if (mPlayerCtrl == null) {                return;            }                        int pos = mPlayerCtrl.getCurPosition();            pos += 15000; // milliseconds            mPlayerCtrl.seekTo(pos);            setProgress();            show(DEFTIMEOUT);        }    };    private void installPrevNextListeners() {        if (mBtnNext != null) {            mBtnNext.setOnClickListener(mNextListener);            mBtnNext.setEnabled(mNextListener != null);        }        if (mBtnPrev != null) {            mBtnPrev.setOnClickListener(mPrevListener);            mBtnPrev.setEnabled(mPrevListener != null);        }    }    public void setPrevNextListeners(View.OnClickListener next, View.OnClickListener prev) {        mNextListener = next;        mPrevListener = prev;        mIsListenersSet = true;        if (mRootView != null) {            installPrevNextListeners();                        if (mBtnNext != null && !mFromXml) {                mBtnNext.setVisibility(View.VISIBLE);            }            if (mBtnPrev != null && !mFromXml) {                mBtnPrev.setVisibility(View.VISIBLE);            }        }    }        public interface ControlOper {        void    start();        void    pause();        int     getDuration();        int     getCurPosition();        void    seekTo(int pos);        boolean isPlaying();        int     getBufPercent();        boolean canPause();        boolean canSeekBackward();        boolean canSeekForward();        boolean isFullScreen();        void    fullScreen();    }        private static class MsgHandler extends Handler {            private final WeakReference<Controller> mView;         MsgHandler(Controller view) {            mView = new WeakReference<Controller>(view);        }                @Override        public void handleMessage(Message msg) {                    Controller view = mView.get();            if (view == null || view.mPlayerCtrl == null) {                return;            }                        int pos;            switch (msg.what) {                            case FADE_OUT: {                    view.hide();                    break;                }                                case SHOW_PROGRESS: {                                if(view.mPlayerCtrl.isPlaying()) {                pos = view.setProgress();                } else {                return;                }                                        if (!view.mIsDragging && view.mIsShowing                    && view.mPlayerCtrl.isPlaying()) {                                            msg = obtainMessage(SHOW_PROGRESS);                        sendMessageDelayed(msg, 1000 - (pos % 1000));                    }                    break;                }            }        }    }}

二、MainActivity
package mediaplayer;import java.io.IOException;import com.demo.player.R;import android.app.Activity;import android.media.AudioManager;import android.media.MediaPlayer;import android.net.Uri;import android.os.Bundle;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.widget.FrameLayout;import android.widget.Toast;public class Player extends Activity {MediaPlayer mPlayer;SurfaceView mSurfaceView;Controller mController;SurfaceHolder.Callback mCallback;MediaPlayer.OnPreparedListener mPreparedListener;Controller.ControlOper mPlayerControl;private long mExitTime = 0;@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_player);initListeners();mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);SurfaceHolder surfaceHolder = mSurfaceView.getHolder();surfaceHolder.addCallback(mCallback);mPlayer = new MediaPlayer(); mController = new Controller(this); try { mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mPlayer.setDataSource(this, Uri.parse("rtsp://184.72.239.149"+ "/vod/mp4:BigBuckBunny_115k.mov"));mPlayer.setOnPreparedListener(mPreparedListener);mPlayer.prepareAsync();} catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }} private void releaseMediaPlayer() {mController.removeHandlerCallback();    if (mPlayer != null) {    mPlayer.stop();    mPlayer.release();    }}@Overridepublic boolean onTouchEvent(MotionEvent event) {super.onTouchEvent(event);mController.show(); return false;}@Overrideprotected void onDestroy() {super.onDestroy();releaseMediaPlayer();}@Overrideprotected void onPause() {   super.onPause();   mPlayer.pause();}    @Override    public void onBackPressed() {        if ((System.currentTimeMillis() - mExitTime) > 1500) {            Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();            mExitTime = System.currentTimeMillis();        } else {            finish();        }        return;    }private void initListeners() {mCallback = new SurfaceHolder.Callback() {public void surfaceCreated(SurfaceHolder holder) {mPlayer.setDisplay(holder);}public void surfaceChanged(SurfaceHolder holder, int format,int width, int height) {}public void surfaceDestroyed(SurfaceHolder holder) {}};mPreparedListener = new MediaPlayer.OnPreparedListener() {public void onPrepared(MediaPlayer mp) {mController.setMediaPlayer(mPlayerControl);mController.setAnchorView((FrameLayout)findViewById(R.id.surfacecontainer));mPlayer.start();}};mPlayerControl = new Controller.ControlOper() {public void start() {mPlayer.start();}public void pause() {mPlayer.pause();}public int getDuration() {return mPlayer.getDuration();}public int getCurPosition() {return mPlayer.getCurrentPosition();}public void seekTo(int pos) {mPlayer.seekTo(pos);}public boolean isPlaying() {return mPlayer.isPlaying();}public int getBufPercent() {return 0;}public boolean canPause() {return true;}public boolean canSeekBackward() {return true;}public boolean canSeekForward() {return true;}public boolean isFullScreen() {return false;}public void fullScreen() {}};}}

四、controller.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:background="#CC000000"   android:orientation="vertical">     <LinearLayout       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:gravity="center"       android:paddingTop="4dip"       android:orientation="horizontal">         <ImageButton android:id="@+id/prev"           style="@android:style/MediaButton.Previous"           android:contentDescription="@string/description" />               <ImageButton android:id="@+id/rew"           style="@android:style/MediaButton.Rew"           android:contentDescription="@string/description" />               <ImageButton android:id="@+id/pause"           style="@android:style/MediaButton.Play"           android:contentDescription="@string/description" />               <ImageButton android:id="@+id/ffwd"           style="@android:style/MediaButton.Ffwd"           android:contentDescription="@string/description" />               <ImageButton android:id="@+id/next"           style="@android:style/MediaButton.Next"           android:contentDescription="@string/description" />     </LinearLayout>     <LinearLayout       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:orientation="horizontal">         <TextView android:id="@+id/time_current"           android:textSize="14sp"           android:textStyle="bold"           android:paddingTop="4dip"           android:paddingLeft="4dip"           android:layout_gravity="center_horizontal"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:paddingRight="4dip" />         <SeekBar           android:id="@+id/mediacontroller_progress"           style="?android:attr/progressBarStyleHorizontal"           android:layout_width="0dip"           android:layout_weight="1"           android:layout_height="21dip" />         <TextView android:id="@+id/time"           android:textSize="14sp"           android:textStyle="bold"           android:paddingTop="4dip"           android:paddingRight="4dip"           android:layout_gravity="center_horizontal"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:paddingLeft="4dip" />               <ImageButton android:id="@+id/fullscreen"           android:layout_marginTop="-7dp"           android:paddingTop="4dip"           android:paddingBottom="4dip"           android:paddingLeft="10dip"           android:paddingRight="4dip"           android:layout_gravity="top"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:background="@android:color/transparent"           android:contentDescription="@string/description" />           </LinearLayout> </LinearLayout>

五、activity_player.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"     android:layout_height="match_parent"     android:background="@android:color/black"     android:gravity="center_horizontal|center_vertical"     android:orientation="vertical" >     <FrameLayout         android:id="@+id/surfacecontainer"         android:layout_width="match_parent"         android:layout_height="wrap_content" >         <SurfaceView android:id="@+id/surfaceview"             android:layout_width="wrap_content"             android:layout_height="wrap_content" />         </FrameLayout></LinearLayout>



0 0
原创粉丝点击