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

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

注意事项

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

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

相关推荐
H.莓飛4 分钟前
【C++】类与对象(末):static、友元与拷贝优化
linux·开发语言·c++·visual studio
青春逝如流水12 分钟前
Java 线程在内存模型(JMM)与 JVM 实现:规范与落地的多元路径
java·开发语言·jvm·多线程·ai文章
小弥儿14 分钟前
PPT Master:用 AI 把PDF/Word一键转成可编辑 PPT
学习·开源·github
wangbing11252 小时前
springboot应用关闭时触发动作
java·spring boot·后端
weixin_460443565 小时前
2026年新修订《网络安全法》实施:Java私有化考试系统如何做好SBOM、漏洞治理与安全升级?
java·开发语言·在线考试系统·企业培训考试系统·宏远培训考试系统·国企培训考试系统·国产化培训系统
海鸥-w8 小时前
什么是AOP
java
EasyGBS8 小时前
摄像头还在线,画面已经不能用了?国标GB28181视频平台EasyGBS视频质量诊断怎么用
服务器·安全·音视频
2601_955662468 小时前
情感解说视频如何提升感染力?配音细节很关键
人工智能·音视频·语音识别·视频
Cc.Y8 小时前
Java零基础入门:可变字符串与包装类:StringBuilder、StringBuffer 与 通讯录管理系统实战
java·开发语言·python
paopaokaka_luck8 小时前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis