【Android RTMP】Android Camera 视频数据采集预览 ( 视频采集相关概念 | 摄像头预览参数设置 | 摄像头预览数据回调接口 )

2023-03-27 21:16:02 浏览数 (1)

文章目录

  • 一、 Android 端数据采集涉及到的相关概念
  • 二、 Camera 预览图像尺寸设置
  • 三、 获取摄像头采集的数据格式

一、 Android 端数据采集涉及到的相关概念


1 . 图像采集显示组件 : 布局文件中添加 SurfaceView , 用于在该 SurfaceView 组件中预览 Camera 采集的图像数据 ;

2 . Android 摄像头常量 : Android 中使用特定的常量指定使用哪个摄像头 ;

① 指定后摄像头 : 使用 Camera.CameraInfo.CAMERA_FACING_BACK 常量 , 指定后摄像头 ;

② 指定前摄像头 : 使用 Camera.CameraInfo.CAMERA_FACING_FRONT 常量 , 指定前摄像头 ;

3 . 码率 与 帧率 :

① 码率 : 单位时间内 , 传输的视频数据的位数 , 单位是 BPS ;

② 码率与视频质量 : 码率与视频编码后的数据量成正比 , 码率越高 , 允许的数据量大小越高 , 视频越清晰 , 数据量随之变大 ;

③ 码率极限值 : 码率不是越大越好 , 码率有一个极限值 , 固定的宽高的视频码率有一个最大值 , 高于该最大值 , 没有任何意义 , 不能提升视频质量 ;

④ 帧率 : FPS , 界面刷新频率 , 单位 赫兹 Hz , 每秒刷新的画面次数 ;

二、 Camera 预览图像尺寸设置


Camera 采集图像数据时 , 会通过指定的回调函数返回图像数据 , 这些图像数据称为预览数据 , 图像肯定有对应的尺寸 , 这些尺寸是 Camera 启动时设置的 , 称为预览尺寸 PreviewSize ;

1 . Camera 预览图像尺寸设置 :

① 用户设置测图像预览尺寸 : 用户设置 Camera 参数时 , 会设置一个 Camera 摄像头预览图像宽高参数 , 这个值用户可以随意设置 ;

② 系统预置的 Camera 预览尺寸 : 但是实际上 , Android 系统中的 Camera 摄像头的尺寸参数必须从几个预置的预览尺寸中选择 , 这些预览尺寸是厂家设定好的 , 用户无法设置 Camera 的语言尺寸 ;

厂家为该 Camera 预置了若干个预览尺寸 , 需要选择一个用户设置的尺寸与系统预置尺寸差距最小的那个 , 才能更好的实现用户意图 ;

2 . 预览尺寸选择方法 :

① 用户设置像素总数 : 用户设置的宽高像素值相乘, 就是用户设置像素总数 ;

② 系统支持像素总数 : 屏幕支持的 宽 高 像素值相乘, 就是系统支持的某个宽高的像素总数 ;

③ 选择尺寸 : 找出一个系统预置的预览尺寸的 系统支持像素总数 , 该数值与 用户设置像素总数 最接近即可 , 该预览尺寸就是要设置给 Camera 的预览尺寸 ;

3 . 代码示例 : 根据用户设置的尺寸 , 选择最接近的 Camera 支持的预览尺寸值 ;

代码语言:javascript复制
    /**
     * 用户设置的高度
     */
    private int mHeight;

    /**
     * 用户设置的宽度
     */
    private int mWidth;

    /**
     * 设置 Camera 摄像头的参数
     * 宽度, 高度
     *
     * 摄像头支持的宽高值是固定的, 不能人为的随意设置
     * 手机给出一组支持的宽高值, 可以选择其中的某一个进行设置
     *
     * 用户虽然设置了一个宽高值, 这个宽高值肯定不能直接设置给 Camera 摄像头
     * 需要对比 Camera 支持的一组宽高值, 哪一个与用户设置的最接近
     * 这个最相似的宽高值就是我们要设置的值
     *
     * 对比方法 : 对比像素总数
     * 用户设置像素总数 : 用户设置的 宽 高 像素值相乘, 就是用户设置像素总数
     * 系统支持像素总数 : 屏幕支持的 宽 高 像素值相乘, 就是系统支持的某个宽高的像素总数
     *
     * 找出上述 用户设置像素总数 和 系统支持像素总数 最接近的的那个 系统支持像素总数
     *      对应的 屏幕支持的 宽 高 值
     *
     * @param parameters
     */
    private void setPreviewSize(Camera.Parameters parameters) {
        // 1. 获取摄像头参数中的预览图像大小参数
        List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();


        // 2. 下面开始遍历获取与用户设置的宽高值最接近的, Camera 支持的宽高值


        // 获取系统 Camera 摄像头支持的最低的摄像头
        //      Camera.Size 中有宽度和高度参数
        Camera.Size currentSupportSize = supportedPreviewSizes.get(0);
        // 对比第 0 个系统支持的像素总数 与 用户设置的像素总数 差值
        //      之后会逐个对比, 每个系统支持的像素总数 与 用户设置像素总数 差值
        //      选择差值最小的那个像素值
        int minDeltaOfPixels = 
        	Math.abs(currentSupportSize.height * currentSupportSize.width - mWidth * mHeight);
        // 对比完成之后, 删除像素值
        //supportedPreviewSizes.remove(0);

        // 遍历系统支持的宽高像素集合, 如果
        Iterator<Camera.Size> iterator = supportedPreviewSizes.iterator();
        while (iterator.hasNext()) {
            // 当前遍历的的系统支持的像素宽高
            Camera.Size tmpSupportSize = iterator.next();
            // 计算当前的设备支持宽高与用户设置的宽高的像素点个数差值
            int tmpDeltaOfPixels = 
            	Math.abs(tmpSupportSize.height * tmpSupportSize.width - mWidth * mHeight);

            // 如果当前的差分值 小于 当前最小像素差分值, 那么使用当前的数据替代
            if (tmpDeltaOfPixels < minDeltaOfPixels) {
                minDeltaOfPixels = tmpDeltaOfPixels;
                currentSupportSize = tmpSupportSize;
            }
        }

        // 3. 选择出了最合适的 Camera 支持的宽高值
        mWidth = currentSupportSize.width;
        mHeight = currentSupportSize.height;

        // 4. 为 Camera 设置最合适的像素值
        parameters.setPreviewSize(mWidth, mHeight);
    }

三、 获取摄像头采集的数据格式


1 . 设置数据预览回调接口 :

① 设置方法 : Android 中的摄像头 Camera 通过调用 setPreviewCallbackWithBuffer 函数 , 传递一个回调接口对象 ;

② 调用的 setPreviewCallbackWithBuffer 方法原型 :

代码语言:javascript复制
public final void setPreviewCallbackWithBuffer(PreviewCallback cb)

③ 传递的接口参数 :

代码语言:javascript复制
public interface PreviewCallback{
	void onPreviewFrame(byte[] data, Camera camera);
}

2 . PreviewCallback 回调接口的作用 : PreviewCallback 接口中定义了 onPreviewFrame 方法 , 该方法中的 byte[] data 参数就是摄像头采集的数据 ;

3 . 采集到的图像数据 : 这是摄像头采集的图像数据 , Android 中的 Camera 摄像头采集数据成功后 , 就会回调该 PreviewCallback 接口中的 onPreviewFrame 方法 , 可以让用户获取并使用这些图像数据 ;

这是数据的格式是 NV21 格式的 ;

代码语言:javascript复制
    // 设置 Camera 预览数据回调接口
	mCameraHelper.setPreviewCallback(this);

	// ....

    /**
     * Camera 摄像头采集数据完毕, 通过回调接口传回数据
     * 数据格式是 nv21 格式的
     * @param data
     * @param camera
     */
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        // 处理该获取的 Camera 采集的 data 数据, nv21 格式图片
    }

0 人点赞