Android开发 MediaPlayer将视频播放时尺寸适配完美

前言

    视频播放有一个较为蛋疼的问题,那就是尺寸适配.若是不作尺寸适配视频将会变形拉伸或者压缩.下面我就介绍我的实现的算法.算法

知足一边的算法

  知足一边?你多是疑问是什么意思.意思是就是始终将视频的高度或者宽度的其中一个铺满对应屏幕的高度或者宽度.而后在将另一个高或宽按比例求出合适的尺寸,其实这跟与摄像头的求出合适的分辨率预览思想是相似的.下面就是代码部分:ide

    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){ //判断视频的宽大于高,那么咱们就优先知足视频的宽度铺满屏幕的宽度,而后在按比例求出合适比例的高度
                Log.e(TAG, "changeVideoSize: 触发宽大于高" );
                if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
                    videoWidth = deviceWidth;
                    videoHeight = (int)(videoHeight/devicePercent);

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


                Log.e(TAG, "changeVideoSize: videoHeight="+videoHeight);

            }else {  //判断视频的高大于宽,那么咱们就优先知足视频的高度铺满屏幕的高度,而后在按比例求出合适比例的宽度
                if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {//竖屏
                    videoHeight = deviceHeight;
                    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);

        }

最后调用这个方法的地方优化

mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() { //尺寸变化回调
                @Override
                public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                    Log.e(TAG, "onVideoSizeChanged: 触发 width=" + width + "height=" + height);
                    changeVideoSize();

                }
            });

知足一边的算法优化竖屏

上面的算法,在视频高大于宽且屏幕是竖屏状况下,铺满高度,可是会计算宽度,可是计算后多多少少视频宽度与屏幕宽度不一致,可是其实已经很接近比例了.咱们能够接受视频的轻微拉伸,来知足视频铺满屏幕的状况,下面的算法就是作了这种优化spa

/**
     * 修改视频的大小,以用来适配屏幕
     */
    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){ //判断视频的宽大于高,那么咱们就优先知足视频的宽度铺满屏幕的宽度,而后在按比例求出合适比例的高度
            Log.e(TAG, "changeVideoSize: 触发宽大于高" );
            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;//求视频比例 注意是宽除高 与 上面的devicePercent 保持一致
                float differenceValue = Math.abs(videoPercent - devicePercent);//相减求绝对值
                L.e("devicePercent="+devicePercent);
                L.e("videoPercent="+videoPercent);
                L.e("differenceValue="+differenceValue);
                if (differenceValue < 0.3){ //若是小于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);

    }

 

求最正方形算法

其实这个算法不是个人,可是一开始看到的这个别人的算法的时候,忽然发现这算法跟我相机预览求正方形有殊途同归之妙(基本原理就是高宽比除宽高,或者宽高比除高宽,两个不一样的边相除或者相乘会获得近似正方形的尺寸).可是我的以为,并不合适在视频播放的时候使用,由于在横屏状况下会将视频变得很小.可是搬过来也是一个参考:code

public void changeVideoSize() {
        int videoWidth = mediaPlayer.getVideoWidth();
        int videoHeight = mediaPlayer.getVideoHeight();

        //根据视频尺寸去计算->视频能够在sufaceView中放大的最大倍数。
        float max;
        if (getResources().getConfiguration().orientation==ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            //竖屏模式下按视频宽度计算放大倍数值
            max = Math.max((float) videoWidth / (float) surfaceWidth,(float) videoHeight / (float) surfaceHeight);
        } else{
            //横屏模式下按视频高度计算放大倍数值
            max = Math.max(((float) videoWidth/(float) surfaceHeight),(float) videoHeight/(float) surfaceWidth);
        }
        
        //视频宽高分别/最大倍数值 计算出放大后的视频尺寸
        videoWidth = (int) Math.ceil((float) videoWidth / max);
        videoHeight = (int) Math.ceil((float) videoHeight / max);

        //没法直接设置视频尺寸,将计算出的视频尺寸设置到surfaceView 让视频自动填充。
        surfaceView.setLayoutParams(new RelativeLayout.LayoutParams(videoWidth, videoHeight));
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        changeVideoSize();
    }
相关文章
相关标签/搜索