Android开发笔记(一百八十二)使用CameraX录像

通过CameraX实现录像功能的话,初始化相机的步骤与拍照时大同小异,区别在于增加了对视频捕捉器VideoCapture的处理。需要修改的代码主要有三个地方,分别说明如下。
第一个地方是在AndroidManifest.xml里补充声明录音权限,完整的权限声明配置如下所示:

<!-- 相机 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 录音 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 存储卡读写 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

第二个地方是在重置相机的resetCamera方法中,构建完图像捕捉器对象,还要构建视频捕捉器对象,并设置视频的宽高比例、视频帧率、比特率(视频每秒录制的比特数)、旋转角度等录制参数。视频捕捉器的构建代码示例如下:

if (mCameraMode == MODE_RECORD) { // 录像
    // 构建一个视频捕捉器
    mVideoCapture = new VideoCapture.Builder()
            .setTargetAspectRatio(mAspectRatio) // 设置宽高比例
            .setVideoFrameRate(60) // 设置视频帧率
            .setBitRate(3 * 1024 * 1024) // 设置比特率
            .setTargetRotation(rotation) // 设置旋转角度
            .setAudioRecordSource(MediaRecorder.AudioSource.MIC)
            .build();
}

第三个地方是在绑定摄像头的bindCamera方法中,对于录像操作来说,需要把视频捕捉器绑定到相机提供器的生命周期,而非绑定图像捕捉器。绑定视频捕捉器的代码片段示例如下:

if (captureMode == MODE_RECORD) { // 录像
    // 把相机选择器、预览视图、视频捕捉器绑定到相机提供器的生命周期
    Camera camera = mCameraProvider.bindToLifecycle(
            mOwner, mCameraSelector, mPreview, mVideoCapture);
}

初始化相机之后,即可调用视频捕捉器的startRecording方法开始录像,或者调用stopRecording方法停止录像。录像代码示例如下:

private String mVideoPath; // 视频保存路径
private int MAX_RECORD_TIME = 15; // 最大录制时长,默认15秒
// 获取视频的保存路径
public String getVideoPath() {
    return mVideoPath;
}

// 开始录像
public void startRecord(int max_record_time) {
    MAX_RECORD_TIME = max_record_time;
    bindCamera(MODE_RECORD); // 绑定摄像头
    mVideoPath = String.format("%s/%s.mp4", mMediaDir, DateUtil.getNowDateTime());
    VideoCapture.Metadata metadata = new VideoCapture.Metadata();
    // 构建视频捕捉器的输出选项
    VideoCapture.OutputFileOptions options = new VideoCapture.OutputFileOptions.Builder(new File(mVideoPath))
            .setMetadata(metadata).build();
    // 开始录像动作
    mVideoCapture.startRecording(options, mExecutorService, new VideoCapture.OnVideoSavedCallback() {
        @Override
        public void onVideoSaved(VideoCapture.OutputFileResults outputFileResults) {
            mHandler.post(() -> bindCamera(MODE_PHOTO));
            mStopListener.onStop("录制完成的视频路径为"+mVideoPath);
        }

        @Override
        public void onError(int videoCaptureError, String message, Throwable cause) {
            mHandler.post(() -> bindCamera(MODE_PHOTO));
            mStopListener.onStop("录制失败,错误信息为:"+cause.getMessage());
        }
    });
    // 限定时长到达之后自动停止录像
    mHandler.postDelayed(() -> stopRecord(), MAX_RECORD_TIME*1000);
}

// 停止录像
public void stopRecord() {
    mVideoCapture.stopRecording(); // 视频捕捉器停止录像
}

当然,录像功能也要先在布局文件中添加CameraXView节点。为了方便观察当前已录制的时长,还可以在布局文件中添加计时器节点Chronometer。接着给Java代码补充CameraXView对象的初始化以及录像动作,其中关键代码示例如下:

private CameraXView cxv_preview; // 声明一个增强相机视图对象
private Chronometer chr_cost; // 声明一个计时器对象
private ImageView iv_record; // 声明一个图像视图对象
private boolean isRecording = false; // 是否正在录像

// 初始化相机
private void initCamera() {
    // 打开增强相机,并指定停止录像监听器
    cxv_preview.openCamera(this, CameraXView.MODE_RECORD, (result) -> {
        runOnUiThread(() -> {
            chr_cost.setVisibility(View.GONE);
            chr_cost.stop(); // 停止计时
            iv_record.setImageResource(R.drawable.record_start);
            iv_record.setEnabled(true);
            isRecording = false;
            Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
        });
    });
}

// 处理录像动作
private void dealRecord() {
    if (!isRecording) {
        iv_record.setImageResource(R.drawable.record_stop);
        cxv_preview.startRecord(15); // 开始录像
        chr_cost.setVisibility(View.VISIBLE);
        chr_cost.setBase(SystemClock.elapsedRealtime()); // 设置计时器的基准时间
        chr_cost.start(); // 开始计时
        isRecording = !isRecording;
    } else {
        iv_record.setEnabled(false);
        cxv_preview.stopRecord(); // 停止录像
    }
}

运行测试App,打开录像界面的初始效果如下图所示,此时除了预览画面外,界面下方还展示录制按钮。

 点击录制按钮开始录像,正在录像的界面如下图所示,此时录制按钮换成了暂停图标,其上方也跳动着已录制时长的数字。


点此查看Android开发笔记的完整目录

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值