Android 录屏(录像)录制视频自定义输出视频分辨率,设置最合适尺寸;Android Mediacodec 录屏输出视频被缩小,Android 录屏全屏,录屏自定义尺寸,录屏录像黑边

      1.问题:

      首先我的应用场景Mediacodec ,使用了摄像头流与录屏流,中间会进行切换,然后录出来一个完整的视频,也就是从摄像到录屏再到摄像再录屏,需求比较。。。因为要录像又要录屏,所以不可能直接用手机屏幕的实际分辨率。所以从camera.getParameters()获取宽高并设置为输出的视频的分辨率。现象是很多手机上看录制好的视频录屏那块被缩小了,其实是因为有黑边造成的。因此问题其实是基于录屏的输出视频分辨率为核心的,其他录屏方案也大多适用。

     2.分析

     大多数手机获取的camera的分辨率与屏幕的分辨率不一致,重要的是长宽比不一样,比如说。相机获取了1920*1080的分辨率,而你的手机是2340*1080的分辨率,在录屏的时候输出视频,第一录屏要全屏录,也就是宽是2340,第二视频不会裁剪,所以你最后要输出1920*1080,他的宽自然要缩小,高度也就跟着等比缩小,然后上下会有黑边填充。也就是其实视频最后输出的是1920*1080,之所以看起来小了是上下填充了黑边。

       所以你要做的就是一个断点一个断点的去看相机支持的分辨率,然后一个一个去算比例,然后发现一些规律,然后换一部手机,然后再执行这一套操作,然后再换一步手机。。。

      好在这些我都替你做了。

     3.处理     

      查找camera支持的分辨率中最接近手机实际屏幕比例的值

其实是从手机支持的视频分辨率中找,不过因为也要用摄像头,视频支持的包括摄像头支持且比摄像头支持的多,所以要从摄像头支持的里找。即List<Camera.Size> prviewSizeList = myParameters.getSupportedPreviewSizes();不开摄像头的可以试着从List<Camera.Size> videoSizeList = myParameters.getSupportedVideoSizes();里找。下面是核心代码

public void initCamera() {
    getScreenSize();
    //注:摄像头相关的设置不写了,省的看混
    ............
    Camera.Parameters myParameters = myCamera.getParameters();
    //获取摄像头支持的分辨率
    List<Camera.Size> prviewSizeList = myParameters.getSupportedPreviewSizes();
    //获取手机支持的视频分辨率
    //List<Camera.Size> videoSizeList = myParameters.getSupportedVideoSizes();
    //获取最接近的分辨的索引
    int selectIndex = bestVideoSize(prviewSizeList);

    ............
    //设置相机预览尺寸
    //TODO 在你设置视频大小的地方也是用这里计算出来的值,以为我设置录制视频分辨率的地方不在,
//这,不过也是取得这里的值,所以就不写了                               
myParameters.setPreviewSize(prviewSizeList.get(selectIndex).width,prviewSizeList.get(selectIndex).height);

}

int mRealSizeWidth;//手机屏幕真实宽度
int mRealSizeHeight;//手机屏幕真实高度

 /**
   * 查找最接近屏幕宽高比的参数
   * @param cameraSizeList
   * @return
   */
public int bestVideoSize(List<Camera.Size> cameraSizeList) {
        if (cameraSizeList == null) {
            return -1;
        }
        //计算屏幕的实际分辨率的比值
        float realRatio = ((float) mRealSizeWidth / (float) mRealSizeHeight);
        int index = 0;//目标索引
        float outRatio = -1f;
        for (int i = 0; i < cameraSizeList.size(); i++) {
            if (cameraSizeList.get(i).height <= mRealSizeHeight) {//取的值高度不能高于屏
//幕真实高度
                float ratio = (float) (cameraSizeList.get(i).width) / (float) (cameraSizeList.get(i).height);
                if (outRatio == -1f) {
                    outRatio = Math.abs(ratio / realRatio - 1);
                    index = i;
                } else {
                    if (outRatio > Math.abs(ratio / realRatio - 1)) {
                        //取绝对值小的值,即选择与屏幕分辨率最接近的值
                        index = i;
                        outRatio = Math.abs(ratio / realRatio - 1);
                    }else if (outRatio == Math.abs(ratio / realRatio - 1)) {
                        //如果有两组长宽比完全一样的,选择height比较大,小的可能会视频模糊
                        if (cameraSizeList.get(i).height >= cameraSizeList.get(index).height) {
                            index = i;
                            outRatio = Math.abs(ratio / realRatio - 1);
                        }
                    }
                }

            }
        }
        return index;
    }


//计算屏幕真实分辨率
public void getScreenSize() {
        WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        Point outPoint = new Point();
        if (Build.VERSION.SDK_INT >= 19) {
            // 可能有虚拟按键的情况
            display.getRealSize(outPoint);
        } else {
            // 不可能有虚拟按键
            display.getSize(outPoint);
        }

        mRealSizeHeight = outPoint.y;
        mRealSizeWidth = outPoint.x;
    }

注意:我录的是横屏,所以我比较的都是高度height,如果是竖屏,最好是用宽度width。

      安卓手机的各种各样的分辨率问题不再多说了,没办法把所有的都测一遍,从我手里的一批手机测过后都是达到了比较完美的效果(除非你手机的相机有支持与屏幕比例一模一样的分辨率,否则几乎不会是完全的全屏,最终的效果也会因手机不同有些许差异),如果有不合适的,可以在bestVideoSize()方法里通过限制你要取值的height的高度范围这个方向考虑。

猜你喜欢

转载自blog.csdn.net/qq_37980878/article/details/109280306
今日推荐