基于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
相关产品推荐
相关产品推荐

