• 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;
            }
        }
    
    }
  • 相关阅读:
    G. Reducing Delivery Cost 思维+最短路
    Bounding Wall 线段树 + 思维 ccpc 2020 秦皇岛 B
    Java代理模式
    Java开发 使用反射判断一个类的是否继承指定接口类
    Java开发 AES加解密工具类——兼容Android9.0
    Java byte转换工具类
    注册LiveData或者MutableLiveData的观察者导致的内存泄露问题
    Android开发 NavOptions记录
    关于MySQL的命名规范
    Locust学习笔记(5)
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/11024195.html
Copyright © 2020-2023  润新知