在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 应用中实现自动拍摄视频。

相关推荐
赏金术士6 分钟前
Retrofit + Kotlin 协程(Android 实战教程)
android·kotlin·retrofit
噢,我明白了8 分钟前
表单的完整 CRUD 练习【极简个人记账本】(含前端后端链接mySQL)
java·前端·数据库·mysql
通往曙光的路上15 分钟前
mysql1
java
Tigshop开源商城5 小时前
『物流设置+SEO优化』Tigshop开源商城系统 JAVA v5.8.26 版本更新!
java·开源商城系统·tigshop
坚果派·白晓明6 小时前
【鸿蒙PC三方库移植适配框架解读系列】第八篇:扩展lycium框架使其满足rust三方库适配
c语言·开发语言·华为·rust·harmonyos·鸿蒙
花间相见6 小时前
【PaddleOCR教程01】PP-OCRv5 全面指南:从模型架构到实战部署
开发语言·r语言
Purple Coder7 小时前
BMS学习经验
学习
小短腿的代码世界7 小时前
Qt 股票订单撮合引擎:高频交易系统的核心心脏
开发语言·数据库·qt·系统架构·交互
Tigshop开源商城7 小时前
『订单税率+收货地址校验国家字段』功能上新|跨境运营更高效,Tigshop开源商城系统 JAVA v5.8.23 版本更新
java·开源商城系统·tigshop
REDcker7 小时前
C++变量存储与ELF段布局详解 从const全局到rodata与nm_readelf验证实践
java·c++·面试