在Android开发中实现静默拍视频

在 Android 中自动拍摄视频通常可以通过 MediaRecorderCameraX 实现。以下是使用 CameraX 的方式来实现自动拍摄视频的详细代码,因为 CameraX 相对简单且适合大多数设备。

实现步骤

  1. 配置 CameraX 和 VideoCapture。
  2. 开始并自动停止录制视频。
  3. 保存视频文件。

准备工作

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 :通过 CameraXVideoCapture 功能进行视频录制,使用 Recorder 来配置视频质量。
  • 自动开始和停止录制 :代码中 startRecording() 方法会自动开始录制,并设置了一个 postDelayed() 方法,在 10 秒后自动停止录制。可以根据需要更改时间。
  • 文件保存 :视频文件保存在 getExternalFilesDir() 目录下,文件名包含时间戳以避免重复。

注意事项

  1. 权限:确保在实际运行时已授予相机和麦克风权限。
  2. 保存路径 :视频保存路径为 getExternalFilesDir(),这是一个沙盒目录,不需要额外的文件读写权限。

这样,您就可以通过 CameraX 在 Android 应用中实现自动拍摄视频。

相关推荐
异常君几秒前
线程池隐患解析:为何阿里巴巴拒绝 Executors
java·后端·代码规范
Java技术小馆6 分钟前
SpringBoot中暗藏的设计模式
java·面试·架构
xiguolangzi7 分钟前
《springBoot3 中使用redis》
java
꧁坚持很酷꧂9 分钟前
配置Ubuntu18.04中的Qt Creator为中文(图文详解)
开发语言·qt·ubuntu
李菠菜14 分钟前
非SpringBoot环境下Jedis集群操作Redis实战指南
java·redis
hepherd14 分钟前
Flutter 环境搭建 (Android)
android·flutter·visual studio code
不当菜虚困26 分钟前
JAVA设计模式——(四)门面模式
java·开发语言·设计模式
ruyingcai66666626 分钟前
用python进行OCR识别
开发语言·python·ocr
m0Java门徒34 分钟前
面向对象编程核心:封装、继承、多态与 static 关键字深度解析
java·运维·开发语言·intellij-idea·idea
liuweidong080236 分钟前
【Pandas】pandas DataFrame radd
开发语言·python·pandas