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

Posted aqi00

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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开发笔记的完整目录

以上是关于Android开发笔记(一百八十二)使用CameraX录像的主要内容,如果未能解决你的问题,请参考以下文章

Android开发笔记(一百八十八)工作管理器WorkManager

Android开发笔记(一百八十八)工作管理器WorkManager

Android开发笔记(一百八十八)工作管理器WorkManager

Android开发笔记(一百八十一)使用CameraX拍照

Android开发笔记(一百八十一)使用CameraX拍照

Android开发笔记(一百八十一)使用CameraX拍照