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开发笔记(一百八十二)使用CameraX录像的主要内容,如果未能解决你的问题,请参考以下文章
Android开发笔记(一百八十八)工作管理器WorkManager
Android开发笔记(一百八十八)工作管理器WorkManager