如何实现无需手动点击录制按钮自动启动视频录制并定时停止
实现自动启动并定时停止的视频录制
使用MediaStore.ACTION_VIDEO_CAPTURE无法实现自动录制,因为该Intent会启动系统自带的相机应用,你无法通过代码控制其界面操作(比如自动点击录制/保存按钮)。要实现自动录制,你需要使用自定义相机录制逻辑,推荐使用Jetpack CameraX库,它兼容性好且易于实现。
解决方案步骤
1. 添加CameraX依赖
在模块级build.gradle文件中添加CameraX相关依赖:
dependencies { def camerax_version = "1.3.0" implementation "androidx.camera:camera-core:$camerax_version" implementation "androidx.camera:camera-camera2:$camerax_version" implementation "androidx.camera:camera-view:$camerax_version" }
2. 更新布局文件
在activity_main.xml中添加PreviewView用于显示相机预览:
<androidx.camera.view.PreviewView android:id="@+id/previewView" android:layout_width="match_parent" android:layout_height="match_parent"/> <Button android:id="@+id/record_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始录制" android:layout_gravity="bottom|center_horizontal" android:layout_marginBottom="32dp"/>
3. 修改MainActivity实现自动录制逻辑
替换原有代码为以下实现:
import androidx.appcompat.app.AppCompatActivity; import androidx.camera.core.CameraSelector; import androidx.camera.core.Preview; import androidx.camera.lifecycle.ProcessCameraProvider; import androidx.camera.video.MediaStoreOutputOptions; import androidx.camera.video.Quality; import androidx.camera.video.QualitySelector; import androidx.camera.video.Recorder; import androidx.camera.video.Recording; import androidx.camera.video.VideoCapture; import androidx.camera.video.VideoRecordEvent; import androidx.camera.view.PreviewView; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.lifecycle.LifecycleOwner; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.widget.Button; import android.widget.Toast; import com.google.common.util.concurrent.ListenableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MainActivity extends AppCompatActivity { private static final int PERMISSION_REQUEST_CODE = 100; private static final int RECORD_DURATION_MS = 5000; // 录制时长5秒 private PreviewView previewView; private Button recordBtn; private VideoCapture<Recorder> videoCapture; private Recording currentRecording; private ExecutorService cameraExecutor; private Handler handler = new Handler(Looper.getMainLooper()); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); previewView = findViewById(R.id.previewView); recordBtn = findViewById(R.id.record_button); cameraExecutor = Executors.newSingleThreadExecutor(); // 检查权限 if (allPermissionsGranted()) { startCamera(); } else { ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CODE ); } recordBtn.setOnClickListener(v -> { if (currentRecording == null) { startRecording(); } }); } private void startCamera() { ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this); cameraProviderFuture.addListener(() -> { try { ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); // 设置预览用例 Preview preview = new Preview.Builder().build(); preview.setSurfaceProvider(previewView.getSurfaceProvider()); // 设置视频录制用例 Recorder recorder = new Recorder.Builder() .setQualitySelector(QualitySelector.from(Quality.HIGHEST)) .build(); videoCapture = VideoCapture.withOutput(recorder); // 绑定相机用例到生命周期 CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA; cameraProvider.unbindAll(); cameraProvider.bindToLifecycle( (LifecycleOwner) this, cameraSelector, preview, videoCapture ); } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); } }, ContextCompat.getMainExecutor(this)); } private void startRecording() { if (videoCapture == null) return; recordBtn.setEnabled(false); recordBtn.setText("录制中..."); // 设置视频输出路径(保存到系统媒体库) MediaStoreOutputOptions outputOptions = new MediaStoreOutputOptions.Builder( getContentResolver(), android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI ).build(); // 开始录制 currentRecording = videoCapture.getOutput() .prepareRecording(this, outputOptions) .start(ContextCompat.getMainExecutor(this), recordEvent -> { switch (recordEvent.getEventType()) { case VideoRecordEvent.EVENT_START: // 定时停止录制 handler.postDelayed(() -> { if (currentRecording != null) { currentRecording.stop(); } }, RECORD_DURATION_MS); break; case VideoRecordEvent.EVENT_FINALIZE: if (!recordEvent.hasError()) { String msg = "视频已保存: " + recordEvent.getOutputResults().getOutputUri(); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } else { currentRecording.close(); currentRecording = null; Toast.makeText(this, "录制失败: " + recordEvent.getError(), Toast.LENGTH_SHORT).show(); } recordBtn.setEnabled(true); recordBtn.setText("开始录制"); break; } }); } private boolean allPermissionsGranted() { return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_REQUEST_CODE) { if (allPermissionsGranted()) { startCamera(); } else { Toast.makeText(this, "需要相机和录音权限才能录制视频", Toast.LENGTH_SHORT).show(); finish(); } } } @Override protected void onDestroy() { super.onDestroy(); cameraExecutor.shutdown(); handler.removeCallbacksAndMessages(null); } }
关键说明
- 权限处理: 需要申请
CAMERA和RECORD_AUDIO权限,这是录制视频的必要权限。 - 自动启停: 通过
Handler.postDelayed在指定时长后调用Recording.stop()实现自动停止。 - 视频保存: 使用
MediaStoreOutputOptions将视频保存到系统媒体库,无需额外存储权限(Android 10+)。 - CameraX优势: 自动适配不同设备,简化相机操作逻辑,无需处理复杂的相机兼容性问题。
替代方案
如果无法使用CameraX,也可以使用Camera2 API实现自定义录制,但Camera2的代码复杂度更高,需要处理更多设备兼容性细节。
内容的提问来源于stack exchange,提问作者Adnan Siddique
相关产品推荐
相关产品推荐

