Android开发 MediaPlayer播放本地视频完善的demo(只是代码记录)

xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_layout"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:keepScreenOn="true"
    android:background="@color/colorBlack1"
    tools:context=".work.share.VideoPlayActivity">

    <SurfaceView
        android:id="@+id/video_play_surfaceview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintVertical_bias="0.5"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

    <ImageView
        android:id="@+id/start_and_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_sex_male"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="10dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/vedio_current_time"
        app:layout_constraintBottom_toBottomOf="parent" />

    <TextView
        android:id="@+id/vedio_current_time"
        android:text="当前时间"
        android:textColor="@color/fontWhite"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        app:layout_constraintTop_toTopOf="@id/start_and_stop"
        app:layout_constraintBottom_toBottomOf="@id/start_and_stop"
        app:layout_constraintLeft_toRightOf="@id/start_and_stop"
        app:layout_constraintRight_toLeftOf="@id/vedio_seek"/>

   <SeekBar
       android:id="@+id/vedio_seek"
       android:layout_width="0dp"
       android:layout_height="0dp"
       android:maxHeight="3dp"
       android:minHeight="3dp"
       android:progressDrawable="@drawable/vedio_seekbar_bg"
       app:layout_constraintTop_toTopOf="@id/start_and_stop"
       app:layout_constraintBottom_toBottomOf="@id/start_and_stop"
       app:layout_constraintLeft_toRightOf="@id/vedio_current_time"
       app:layout_constraintRight_toRightOf="@id/vedio_total_time"/>

    <TextView
        android:id="@+id/vedio_total_time"
        android:textColor="@color/fontWhite"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        app:layout_constraintTop_toTopOf="@id/start_and_stop"
        app:layout_constraintBottom_toBottomOf="@id/start_and_stop"
        app:layout_constraintLeft_toRightOf="@id/vedio_seek"
        app:layout_constraintRight_toRightOf="parent"/>

    <ImageView
        android:id="@+id/back"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/title_height"
        android:paddingLeft="20dp"
        android:src="@mipmap/ic_back_white"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>

    <TextView
        android:id="@+id/vedio_settings"
        android:textColor="@color/fontWhite"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:visibility="gone"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

代码

/**
 *@content:视频播放activity
 *@time:2019-6-13

 */

public class VideoPlayActivity extends BaseActivity implements View.OnClickListener {
    private static final String TAG = VideoPlayActivity.class.getSimpleName();
    private ConstraintLayout mRootLayout;
    private SurfaceView mVideoPlaySurfaceview;
    private ImageView mStartAndStop, mBack;
    private MediaPlayer mMediaPlayer;
    private SeekBar mVedioSeek;
    private TextView mVedioCurrentTimeTextView, mVedioTotalTimeTextView, mVedioSettings;
    private String mPath;
    private boolean isInitFinish = false;
    private SurfaceHolder mSurfaceHolder;
    private Handler mHandler;
    private final int GET_VIDEO_PLAY_TIME_KEY = 0x01;
    private final int GONS_VIEW_KEY = 0x02;
    private static int mCurrentPlayTime = 0; //因为切换横竖屏后,activity其实是重新创建的,所以需要用静态变量保存当前播放时间
    private int mTotalPlayTime = 0;
    SimpleDateFormat mTimeFormat = new SimpleDateFormat("mm:ss");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
        initVedioSeekListener();
        initHandler();
        mHandler.sendEmptyMessageDelayed(GONS_VIEW_KEY,8*1000);
        File file = new File(getExternalCacheDir(), "demo.mp4");
        mPath = file.getAbsolutePath();
        initMediaPalyer();
        initSurfaceviewStateListener();

    }

    @Override
    protected void onPause() {
        super.onPause();
        pausePlay();
    }

    @Override
    protected void onResume() {
        super.onResume();
        startPlay();
    }

    @Override
    public int getLayout() {
        return R.layout.activity_video_play;
    }

    @Override
    public void initView() {
        mRootLayout = findViewById(R.id.root_layout);
        mVideoPlaySurfaceview = findViewById(R.id.video_play_surfaceview);
        mStartAndStop = findViewById(R.id.start_and_stop);
        mVedioCurrentTimeTextView = findViewById(R.id.vedio_current_time);
        mVedioTotalTimeTextView = findViewById(R.id.vedio_total_time);
        mVedioSeek = findViewById(R.id.vedio_seek);
        mVedioSettings = findViewById(R.id.vedio_settings);
        mBack = findViewById(R.id.back);
        mStartAndStop.setOnClickListener(this);
        mBack.setOnClickListener(this);
        mRootLayout.setOnClickListener(this);


    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_and_stop:
                if (mMediaPlayer.isPlaying()) {
                    pausePlay();
                    mStartAndStop.setImageResource(R.mipmap.ic_sex_male);
                } else {
                    startPlay();
                    mStartAndStop.setImageResource(R.mipmap.ic_sex_female);
                }
                break;
            case R.id.back:
                finish();
                break;
            case R.id.root_layout:
                mStartAndStop.setVisibility(View.VISIBLE);
                mVedioSettings.setVisibility(View.VISIBLE);
                mVedioTotalTimeTextView.setVisibility(View.VISIBLE);
                mVedioCurrentTimeTextView.setVisibility(View.VISIBLE);
                mBack.setVisibility(View.VISIBLE);
                mVedioSeek.setVisibility(View.VISIBLE);
                mHandler.sendEmptyMessageDelayed(GONS_VIEW_KEY,8*1000);
                break;
            default:
                break;
        }

    }

    private void initHandler(){
        mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what){
                    case GET_VIDEO_PLAY_TIME_KEY:
                        if (mMediaPlayer != null){
                            mCurrentPlayTime = mMediaPlayer.getCurrentPosition();
                            L.e("每秒mCurrentPlayTime="+mCurrentPlayTime);
                            mVedioSeek.setProgress(mCurrentPlayTime/1000);
                            mVedioCurrentTimeTextView.setText(mTimeFormat.format(mCurrentPlayTime));

                        }
                        mHandler.sendEmptyMessageDelayed(GET_VIDEO_PLAY_TIME_KEY,1000);
                        break;
                    case GONS_VIEW_KEY:
                        mStartAndStop.setVisibility(View.GONE);
                        mVedioSettings.setVisibility(View.GONE);
                        mVedioTotalTimeTextView.setVisibility(View.GONE);
                        mVedioCurrentTimeTextView.setVisibility(View.GONE);
                        mBack.setVisibility(View.GONE);
                        mVedioSeek.setVisibility(View.GONE);
                        break;
                    default:
                        break;

                }
            }
        };
    }

    private void initVedioSeekListener(){
        mVedioSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mMediaPlayer.seekTo(seekBar.getProgress()*1000);
                mCurrentPlayTime = mMediaPlayer.getCurrentPosition();
                mVedioCurrentTimeTextView.setText(mTimeFormat.format(mCurrentPlayTime));

            }
        });
    }


    private void initSurfaceviewStateListener() {
        mSurfaceHolder = mVideoPlaySurfaceview.getHolder();
        mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                mMediaPlayer.setDisplay(holder);//给mMediaPlayer添加预览的SurfaceHolder
                setPlayVideo(mPath);//添加播放视频的路径
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.e(TAG, "surfaceChanged触发: width=" + width + "height" + height);

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
    }

    private void initMediaPalyer() {
        mMediaPlayer = new MediaPlayer();

    }

    private void setPlayVideo(String path) {
        try {
            mMediaPlayer.setDataSource(path);//
            mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);//缩放模式
            mMediaPlayer.setLooping(true);//设置循环播放
            mMediaPlayer.prepareAsync();//异步准备
//            mMediaPlayer.prepare();//同步准备,因为是同步在一些性能较差的设备上会导致UI卡顿
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { //准备完成回调
                @Override
                public void onPrepared(MediaPlayer mp) {
                    isInitFinish = true;
                    mMediaPlayer.start();
                    mHandler.sendEmptyMessage(GET_VIDEO_PLAY_TIME_KEY);
                    mTotalPlayTime = mMediaPlayer.getDuration();
                    if (mTotalPlayTime == -1){
                        Toast.makeText(VideoPlayActivity.this, "视频文件时间异常", Toast.LENGTH_SHORT).show();
                        finish();
                    }
                    mVedioSeek.setMax(mTotalPlayTime/1000);
                    mVedioTotalTimeTextView.setText(formatTime(mTotalPlayTime));
                }
            });
            mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() { //尺寸变化回调
                @Override
                public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                    changeVideoSize();
                    L.e("mCurrentPlayTime="+mCurrentPlayTime);
                    seekTo(mCurrentPlayTime);

                }
            });
            mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    L.e("视频播放错误,错误原因what="+what+"extra="+extra);
                    return false;
                }
            });
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {

                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 修改视频的大小,以用来适配屏幕
     */
    public void changeVideoSize() {
        int videoWidth = mMediaPlayer.getVideoWidth();
        int videoHeight = mMediaPlayer.getVideoHeight();
        int deviceWidth = getResources().getDisplayMetrics().widthPixels;
        int deviceHeight = getResources().getDisplayMetrics().heightPixels;
        Log.e(TAG, "changeVideoSize: deviceHeight="+deviceHeight+"deviceWidth="+deviceWidth);
        float devicePercent = 0;
        //下面进行求屏幕比例,因为横竖屏会改变屏幕宽度值,所以为了保持更小的值除更大的值.
        if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { //竖屏
            devicePercent = (float) deviceWidth / (float) deviceHeight; //竖屏状态下宽度小与高度,求比
        }else { //横屏
            devicePercent = (float) deviceHeight / (float) deviceWidth; //横屏状态下高度小与宽度,求比

        }

        if (videoWidth > videoHeight){
            if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
                videoWidth = deviceWidth;
                videoHeight = (int)(videoHeight/devicePercent);

            }else {
                videoWidth = deviceWidth;
                videoHeight = (int)(deviceWidth*devicePercent);
            }

        }else {
            if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {//竖屏

                videoHeight = deviceHeight;
                float videoPercent = (float) videoWidth / (float) videoHeight;
                float differenceValue = Math.abs(videoPercent - devicePercent);
                if (differenceValue < 0.3){
                    videoWidth = deviceWidth;
                }else {
                    videoWidth = (int)(videoWidth/devicePercent);
                }


            }else { //横屏
                videoHeight = deviceHeight;
                videoWidth = (int)(deviceHeight*devicePercent);

            }

        }

        ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mVideoPlaySurfaceview.getLayoutParams();
        layoutParams.width = videoWidth;
        layoutParams.height = videoHeight;
        layoutParams.verticalBias = 0.5f;
        layoutParams.horizontalBias = 0.5f;
        mVideoPlaySurfaceview.setLayoutParams(layoutParams);

    }


    private void startPlay(){
        if (!mMediaPlayer.isPlaying()){
            mMediaPlayer.start();
        }
    }

    private void stopPlay(){
        if (mMediaPlayer.isPlaying()){
            mMediaPlayer.stop();
        }
    }

    private void pausePlay(){
        if (mMediaPlayer.isPlaying()){
            mMediaPlayer.pause();
        }
    }

    private void seekTo(int time){
        mMediaPlayer.seekTo(time);
    }

    private String formatTime(long time){
        return mTimeFormat.format(time);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mMediaPlayer != null){
            if (mMediaPlayer.isPlaying()){
                mMediaPlayer.stop();
            }
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

}
原文地址:https://www.cnblogs.com/guanxinjing/p/11024195.html