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();
    }
相關文章
相關標籤/搜索