1. 程式人生 > >Android使用MediaPlayer播放視訊

Android使用MediaPlayer播放視訊

這裡寫圖片描述

  • 目錄結構
    這裡寫圖片描述

  • 佈局檔案 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout android:id="@+id/root_rl" android:layout_width="match_parent" android:layout_height="400dp" android:background="#000000"> <SurfaceView android:id="@+id/surfaceView" android:layout_width
="match_parent" android:layout_height="400dp" />
<ImageView android:id="@+id/playOrPause" android:layout_width="60dp" android:layout_height="60dp" android:layout_centerInParent="true" android:src="@android:drawable/ic_media_play"
/>
<LinearLayout android:id="@+id/control_ll" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#55000000" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:orientation="horizontal" android:paddingBottom="5dp"> <ProgressBar android:id="@+id/pb_progress" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_start_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/pb_progress" android:text="00:00" android:textColor="#ffffff" /> <TextView android:id="@+id/tv_end_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@id/pb_progress" android:text="00:00" android:textColor="#ffffff" /> </RelativeLayout> </LinearLayout> </RelativeLayout> </merge>
  • 工具類 FormatTimeUtil.java
public class FormatTimeUtil {

    /**
     * 將毫秒轉換為00:00格式的字串
     *
     * @param time
     * @return
     */
    public static String formatLongToTimeStr(int time) {
        int minute = 0;
        int second = 0;
        String tmp;
        minute = time / 1000 / 60;
        tmp = String.valueOf(minute).length() == 2 ? minute + "" : "0" + minute + ":";
        second = time / 1000 % 60;
        tmp += String.valueOf(second).length() == 2 ? second + "" : "0" + second;
        return tmp;
    }
}
  • MainActivity.java
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, 
MediaPlayer.OnPreparedListener, 
MediaPlayer.OnCompletionListener, 
MediaPlayer.OnErrorListener, 
MediaPlayer.OnInfoListener, View.OnClickListener, 
MediaPlayer.OnSeekCompleteListener, 
MediaPlayer.OnVideoSizeChangedListener {

    private ImageView playOrPauseIv;
    private SurfaceView videoSuf;
    private MediaPlayer mPlayer;
    private ProgressBar mProgressBar;
    private String path;
    private RelativeLayout rootViewRl;
    private LinearLayout controlLl;
    private TextView startTime, endTime;

    private boolean isShow = false;

    public static final int UPDATE_TIME = 0x0001;
    public static final int HIDE_CONTROL = 0x0002;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATE_TIME:
                    updateTime();
                    mHandler.sendEmptyMessageDelayed(UPDATE_TIME, 500);
                    break;
                case HIDE_CONTROL:
                    hideControl();
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        initData();
        initSurfaceView();
        initPlayer();
        initEvent();

    }

    private void initData() {
        path = Environment.getExternalStorageDirectory().getPath() + "/478102.mp4";//這裡寫上你的視訊地址
    }

    private void initEvent() {
        playOrPauseIv.setOnClickListener(this);
        rootViewRl.setOnClickListener(this);
    }

    private void initSurfaceView() {
        videoSuf = (SurfaceView) findViewById(R.id.surfaceView);
        videoSuf.setZOrderOnTop(false);
        videoSuf.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        videoSuf.getHolder().addCallback(this);
    }

    private void initPlayer() {
        mPlayer = new MediaPlayer();
        mPlayer.setOnCompletionListener(this);
        mPlayer.setOnErrorListener(this);
        mPlayer.setOnInfoListener(this);
        mPlayer.setOnPreparedListener(this);
        mPlayer.setOnSeekCompleteListener(this);
        mPlayer.setOnVideoSizeChangedListener(this);
        try {
            mPlayer.setDataSource(path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initViews() {
        playOrPauseIv = (ImageView) findViewById(R.id.playOrPause);
        startTime = (TextView) findViewById(R.id.tv_start_time);
        endTime = (TextView) findViewById(R.id.tv_end_time);
        mProgressBar = (ProgressBar) findViewById(R.id.pb_progress);
        rootViewRl = (RelativeLayout) findViewById(R.id.root_rl);
        controlLl = (LinearLayout) findViewById(R.id.control_ll);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mPlayer.setDisplay(holder);
        mPlayer.prepareAsync();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        startTime.setText(FormatTimeUtil.formatLongToTimeStr(mp.getCurrentPosition()));
        endTime.setText(FormatTimeUtil.formatLongToTimeStr(mp.getDuration()));
        mProgressBar.setMax(mp.getDuration());
        mProgressBar.setProgress(mp.getCurrentPosition());
    }

    @Override
    public void onCompletion(MediaPlayer mp) {

    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        return false;
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        return false;
    }

    private void play() {
        if (mPlayer == null) {
            return;
        }
        Log.i("playPath", path);
        if (mPlayer.isPlaying()) {
            mPlayer.pause();
            mHandler.removeMessages(UPDATE_TIME);
            mHandler.removeMessages(HIDE_CONTROL);
            playOrPauseIv.setVisibility(View.VISIBLE);
            playOrPauseIv.setImageResource(android.R.drawable.ic_media_play);
        } else {
            mPlayer.start();
            mHandler.sendEmptyMessageDelayed(UPDATE_TIME, 500);
            mHandler.sendEmptyMessageDelayed(HIDE_CONTROL, 5000);
            playOrPauseIv.setVisibility(View.INVISIBLE);
            playOrPauseIv.setImageResource(android.R.drawable.ic_media_pause);
        }
    }

    @Override
    public void onSeekComplete(MediaPlayer mp) {
        //TODO
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.playOrPause:
                play();
                break;
            case R.id.root_rl:
                showControl();
                break;
        }
    }

    /**
     * 更新播放時間
     */
    private void updateTime() {
        startTime.setText(FormatTimeUtil.formatLongToTimeStr(mPlayer.getCurrentPosition()));
        mProgressBar.setProgress(mPlayer.getCurrentPosition());
    }

    /**
     * 隱藏進度條
     */
    private void hideControl() {
        isShow = false;
        mHandler.removeMessages(UPDATE_TIME);
        controlLl.animate().setDuration(300).translationY(controlLl.getHeight());
    }

    /**
     * 顯示進度條
     */
    private void showControl() {
        if (isShow) {
            play();
        }
        isShow = true;
        mHandler.removeMessages(HIDE_CONTROL);
        mHandler.sendEmptyMessage(UPDATE_TIME);
        mHandler.sendEmptyMessageDelayed(HIDE_CONTROL, 5000);
        controlLl.animate().setDuration(300).translationY(0);
    }
}
  • 清單檔案 AndroidMainifest.xml中宣告許可權
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  • 總結
    1. 在surfaceCreated方法中呼叫MediaPlayer的setDisPlay方法和prepareAsync方法。
    2. 使用Handler來延時傳送訊息來獲取MediaPlayer的currentPosition更新時間的顯示。
    3. 使用View.animte()屬性動畫來顯示和隱藏進度條。