使用camera2和mediacodec API录制和保存视频的步骤如下:
<uses-permission android:name="android.permission.CAMERA" />
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
String[] cameraIds = cameraManager.getCameraIdList();
String cameraId = cameraIds[0]; // 选择第一个相机设备
cameraManager.openCamera(cameraId, cameraStateCallback, null);
CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// 相机已打开,可以进行下一步操作
cameraDevice = camera;
createCaptureSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
// 相机断开连接
camera.close();
cameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
// 相机打开错误
camera.close();
cameraDevice = null;
}
};
private void createCaptureSession() {
List<Surface> surfaces = new ArrayList<>();
surfaces.add(previewSurface); // 预览的Surface
surfaces.add(encoderSurface); // 编码的Surface
cameraDevice.createCaptureSession(surfaces, captureSessionStateCallback, null);
}
CameraCaptureSession.StateCallback captureSessionStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
// 会话已创建,可以进行预览
cameraCaptureSession = session;
createPreviewRequest();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
// 会话创建失败
}
};
private void createPreviewRequest() {
try {
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(previewSurface);
cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
MediaCodec encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, width, height);
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iFrameInterval);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Surface encoderSurface = encoder.createInputSurface();
builder.addTarget(encoderSurface);
encoder.start();
cameraCaptureSession.setRepeatingRequest(builder.build(), new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
// 获取预览数据
Image image = result.get(CaptureResult.STATISTICS_PREVIEW_DATA);
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
// 将数据传递给编码器
int inputBufferIndex = encoder.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = encoder.getInputBuffer(inputBufferIndex);
inputBuffer.clear();
inputBuffer.put(buffer);
encoder.queueInputBuffer(inputBufferIndex, 0, buffer.limit(), 0, 0);
}
image.close();
}
}, null);
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = encoder.getOutputBuffer(outputBufferIndex);
// 将编码后的数据保存到文件
saveToFile(outputBuffer, bufferInfo);
encoder.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);
}
encoder.stop();
encoder.release();
cameraCaptureSession.close();
cameraDevice.close();
以上是使用camera2和mediacodec API录制和保存视频的基本步骤。具体实现中还需要处理异常、设置视频的分辨率、码率等参数,以及添加适当的错误处理和释放资源的代码。
领取专属 10元无门槛券
手把手带您无忧上云