在 Android 中自动拍摄视频通常可以通过 MediaRecorder
或 CameraX
实现。以下是使用 CameraX
的方式来实现自动拍摄视频的详细代码,因为 CameraX
相对简单且适合大多数设备。
实现步骤
- 配置 CameraX 和 VideoCapture。
- 开始并自动停止录制视频。
- 保存视频文件。
准备工作
在 build.gradle
中添加依赖:
dependencies {
def camerax_version = "1.2.0"
implementation "androidx.camera:camera-core:$camerax_version"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-video:$camerax_version"
}
自动录制视频的 Java 代码
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.video.FileOutputOptions;
import androidx.camera.video.PendingRecording;
import androidx.camera.video.Quality;
import androidx.camera.video.Recorder;
import androidx.camera.video.VideoCapture;
import androidx.camera.video.VideoRecordEvent;
import androidx.camera.video.VideoRecording;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.File;
import java.util.concurrent.ExecutionException;
public class VideoCaptureActivity extends AppCompatActivity {
private static final int REQUEST_CODE_PERMISSIONS = 10;
private static final String[] REQUIRED_PERMISSIONS = {Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
private VideoCapture<Recorder> videoCapture;
private VideoRecording videoRecording;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 检查权限
if (allPermissionsGranted()) {
startCamera(); // 启动相机
} else {
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS);
}
}
// 检查权限是否被授予
private boolean allPermissionsGranted() {
for (String permission : REQUIRED_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
// 请求权限结果的处理
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (allPermissionsGranted()) {
startCamera();
} else {
Toast.makeText(this, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show();
finish();
}
}
}
// 启动CameraX
private void startCamera() {
ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
bindVideoCapture(cameraProvider);
} catch (ExecutionException | InterruptedException e) {
Log.e("VideoCaptureActivity", "Error starting camera", e);
}
}, ContextCompat.getMainExecutor(this));
}
// 绑定视频捕获功能
@OptIn(markerClass = androidx.camera.video.ExperimentalVideo.class)
private void bindVideoCapture(@NonNull ProcessCameraProvider cameraProvider) {
// 配置 Recorder 和 VideoCapture
Recorder recorder = new Recorder.Builder()
.setQualitySelector(QualitySelector.from(Quality.HD))
.build();
videoCapture = VideoCapture.withOutput(recorder);
CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;
try {
// 取消之前的绑定并重新绑定
cameraProvider.unbindAll();
cameraProvider.bindToLifecycle(this, cameraSelector, videoCapture);
startRecording(); // 自动开始录制视频
} catch (Exception e) {
Log.e("VideoCaptureActivity", "Error binding video capture", e);
}
}
// 开始录制视频
private void startRecording() {
File outputDir = getExternalFilesDir(null); // 获取文件保存路径
File videoFile = new File(outputDir, "video_capture_" + System.currentTimeMillis() + ".mp4");
// 设置文件输出选项
FileOutputOptions fileOutputOptions = new FileOutputOptions.Builder(videoFile).build();
// 创建录制会话
PendingRecording pendingRecording = videoCapture.getOutput().prepareRecording(this, fileOutputOptions);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
pendingRecording.withAudioEnabled(); // 启用音频录制
}
// 开始录制
videoRecording = pendingRecording.start(ContextCompat.getMainExecutor(this), videoRecordEvent -> {
if (videoRecordEvent instanceof VideoRecordEvent.Start) {
Log.d("VideoCaptureActivity", "Recording started");
} else if (videoRecordEvent instanceof VideoRecordEvent.Finalize) {
// 录制完成后处理
VideoRecordEvent.Finalize finalizeEvent = (VideoRecordEvent.Finalize) videoRecordEvent;
if (!finalizeEvent.hasError()) {
Log.d("VideoCaptureActivity", "Video saved successfully: " + videoFile.getAbsolutePath());
Toast.makeText(this, "Video saved: " + videoFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
} else {
Log.e("VideoCaptureActivity", "Error saving video: " + finalizeEvent.getError());
}
}
});
// 可选:指定录制时间限制,例如 10 秒后自动停止
findViewById(R.id.stopRecordingButton).postDelayed(this::stopRecording, 10000); // 10 秒后停止录制
}
// 停止录制视频
private void stopRecording() {
if (videoRecording != null) {
videoRecording.stop();
videoRecording = null;
Log.d("VideoCaptureActivity", "Recording stopped");
}
}
}
代码说明
- 权限检查:代码会检查是否授予了摄像头和音频录制权限。
-
绑定 CameraX:通过
CameraX
的VideoCapture
功能进行视频录制,使用Recorder
来配置视频质量。 -
自动开始和停止录制:代码中
startRecording()
方法会自动开始录制,并设置了一个postDelayed()
方法,在 10 秒后自动停止录制。可以根据需要更改时间。 -
文件保存:视频文件保存在
getExternalFilesDir()
目录下,文件名包含时间戳以避免重复。
注意事项
- 权限:确保在实际运行时已授予相机和麦克风权限。
-
保存路径:视频保存路径为
getExternalFilesDir()
,这是一个沙盒目录,不需要额外的文件读写权限。
这样,您就可以通过 CameraX
在 Android 应用中实现自动拍摄视频。