You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Xamarin.Android的CameraX多摄像头MP4录制开发咨询

Xamarin.Android CameraX 实现指南

以下是针对你需求的分步实现方案,同时解决你对cameraProviderFuture的困惑:

核心概念澄清:ProcessCameraProviderFuture

ProcessCameraProvider.GetInstance()返回的是异步初始化的ListenableFuture<ProcessCameraProvider>,不能直接在UI线程调用Get()(会阻塞界面),必须通过AddListener在初始化完成后执行后续操作。


1. 获取所有摄像头设备

当ProcessCameraProvider初始化完成后,调用GetAvailableCameraInfos()即可获取设备上所有摄像头的信息,包括镜头朝向、传感器参数等。

2. 摄像头启动与停止控制

CameraX通过生命周期绑定管理摄像头状态,绑定后会随Activity的onResume/onPause自动启停。若需手动控制,可通过Unbind()或UnbindAll()解除绑定,之后重新绑定即可重启。

3. 录制MP4格式文件

使用CameraX的VideoCapture用例,配置输出文件为MP4格式,调用StartRecording和StopRecording控制录制流程。

4. 无需额外界面

无需添加PreviewView,直接绑定VideoCapture用例即可实现无界面录制(部分旧设备可能要求预览,但主流设备支持无预览录制)。


完整代码实现

using Android.App;
using Android.Content.PM;
using Android.OS;
using AndroidX.Core.App;
using Android;
using AndroidX.Core.Content;
using Java.Util.Concurrent;
using AndroidX.Camera.Lifecycle;
using AndroidX.Camera.Core;
using AndroidX.Camera.Video;
using Java.IO;

namespace BadClaims
{
    [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
    public class MainActivity : MauiAppCompatActivity
    {
        private readonly string[] _requiredPermissions = new[] { Manifest.Permission.Camera, Manifest.Permission.RecordAudio, Manifest.Permission.WriteExternalStorage };
        private ProcessCameraProvider _cameraProvider;
        private Camera _camera;
        private VideoCapture _videoCapture;
        private readonly IExecutorService _cameraExecutor = Executors.NewSingleThreadExecutor();
        private Recording _activeRecording;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            
            if (AllPermissionsGranted())
            {
                InitializeCamera();
            }
            else
            {
                ActivityCompat.RequestPermissions(this, _requiredPermissions, 10);
            }
        }

        // 权限申请结果处理
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
        {
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == 10 && AllPermissionsGranted())
            {
                InitializeCamera();
            }
        }

        private bool AllPermissionsGranted()
        {
            return _requiredPermissions.All(permission => 
                ContextCompat.CheckSelfPermission(BaseContext, permission) == Permission.Granted);
        }

        // 初始化CameraX
        private void InitializeCamera()
        {
            var cameraProviderFuture = ProcessCameraProvider.GetInstance(BaseContext);
            
            // 添加监听,在Provider初始化完成后执行操作
            cameraProviderFuture.AddListener(new Runnable(() => 
            {
                _cameraProvider = cameraProviderFuture.Get();
                
                // 1. 获取所有摄像头设备信息
                var allCameras = _cameraProvider.GetAvailableCameraInfos();
                foreach (var cameraInfo in allCameras)
                {
                    var lensFacing = cameraInfo.LensFacing;
                    // 可记录摄像头朝向:CameraSelector.LensFacingFront / CameraSelector.LensFacingBack
                }

                // 配置VideoCapture用例
                ConfigureVideoCapture();
                
                // 绑定摄像头(启动)
                BindCameraUseCases();

            }), ContextCompat.GetMainExecutor(BaseContext));
        }

        // 配置视频录制参数
        private void ConfigureVideoCapture()
        {
            var videoCaptureBuilder = new VideoCapture.Builder();
            
            // 设置分辨率(可选)
            videoCaptureBuilder.SetTargetResolution(new Android.Util.Size(1280, 720));
            
            _videoCapture = videoCaptureBuilder.Build();
        }

        // 绑定摄像头用例(启动摄像头)
        private void BindCameraUseCases()
        {
            // 选择后置摄像头,若需前置可改为CameraSelector.LensFacingFront
            var cameraSelector = new CameraSelector.Builder()
                .RequireLensFacing(CameraSelector.LensFacingBack)
                .Build();

            try
            {
                // 先解绑所有已绑定的用例
                _cameraProvider.UnbindAll();
                
                // 绑定VideoCapture用例到Activity生命周期
                _camera = _cameraProvider.BindToLifecycle(this, cameraSelector, _videoCapture);
            }
            catch (System.Exception ex)
            {
                // 处理绑定失败异常
            }
        }

        // 开始录制MP4
        public void StartRecording()
        {
            if (_videoCapture == null) return;
            
            // 创建MP4输出文件(保存到公共视频目录)
            var outputFile = new File(
                Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMovies),
                $"recording_{System.DateTime.Now.Ticks}.mp4");

            var outputOptions = new OutputFileOptions.Builder(outputFile).Build();
            
            // 开始录制
            _activeRecording = _videoCapture.Output.Record(
                outputOptions,
                _cameraExecutor,
                new RecordingEventsListener());
        }

        // 停止录制
        public void StopRecording()
        {
            _activeRecording?.Stop();
            _activeRecording = null;
        }

        // 录制事件监听
        private class RecordingEventsListener : Java.Lang.Object, IRecordingEventListener
        {
            public void OnError(VideoCapture videoCapture, int errorCode, string message)
            {
                // 处理录制错误
            }

            public void OnFinalize(OutputFileResults outputFileResults)
            {
                // 录制完成,可处理输出文件
                var uri = outputFileResults.SavedUri;
            }
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();
            _cameraExecutor.Shutdown();
            _cameraProvider?.UnbindAll();
        }
    }
}

关键说明

  • 摄像头枚举:_cameraProvider.GetAvailableCameraInfos()返回所有可用摄像头,通过cameraInfo.LensFacing可区分前后置。
  • 启停控制:BindToLifecycle启动摄像头,UnbindAll停止;若需切换摄像头,重新绑定不同的CameraSelector即可。
  • MP4录制:OutputFileOptions指定MP4文件路径,Record方法启动录制,Stop方法停止。
  • 无界面录制:仅绑定VideoCapture用例,无需添加预览组件。

内容的提问来源于stack exchange,提问作者OBJECTSOCIAL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:05:37