123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- using Android;
- using Android.App;
- using Android.Content;
- using Android.Content.PM;
- using Android.Hardware.Camera2;
- using Android.OS;
- using Android.Util;
- using Android.Views;
- using Java.Lang;
- using Java.Util;
- using Java.Util.Concurrent;
- using System;
- using System.Collections.Generic;
- using Vinno.vCloud.FIS.CrossPlatform.Common;
- using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo;
- using Exception = System.Exception;
- namespace Vinno.vCloud.FIS.CrossPlatform.Android.LiveVideo
- {
- public class CameraHelperV2
- {
- private readonly Context _mContext;
- private CameraManager _cameraManager;
- private PackageManager _packageManager;
- private string _mCameraId;
- private bool _isFront;
- private CameraDevice _mCameraDevice;
- private CameraStateCallBack _cameraStateCallBack;
- private CameraCaptureSessionCallback _cameraCaptureSessionCallback;
- private Handler _mBackgroundHandler;
- private HandlerThread _mBackgroundThread;
- private CaptureRequest.Builder _mCaptureRequestBuilder;
- private CaptureRequest _mCaptureRequest;
- private CameraCaptureSession _mCameraCaptureSession;
- private readonly Semaphore _mCameraOpenCloseLock = new Semaphore(1);//以防止在关闭相机之前应用程序退出
- private CameraReaderHelperV2 _cameraReader;
- public event EventHandler<ImageFrameData> ImageFrameReceived;
- private int _cameraWidth;
- private int _cameraHeight;
- private int _fps;
- public CameraHelperV2(int cameraWidth, int cameraHeight, string cameraId = null, int fps = 15)
- {
- _mContext = Application.Context;
- _packageManager = _mContext.PackageManager;
- _cameraHeight = cameraHeight;
- _cameraWidth = cameraWidth;
- _fps = fps;
- _cameraManager = (CameraManager)_mContext.GetSystemService(Context.CameraService);
- _mCameraId = cameraId;
- }
- public void ChangeCameraId(string cameraId)
- {
- if (_mCameraId != cameraId)
- {
- _mCameraId = cameraId;
- CloseCamera();
- OpenCamera();
- }
- }
- public void Start()
- {
- try
- {
- if (string.IsNullOrEmpty(_mCameraId))
- {
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"Camera Helper Init Error : Id is null");
- return;
- }
- else
- {
- CrossPlatformHelper.Instance.LogWriter?.WriteLineInfo($"Camera HelperV2 Init, Id is {_mCameraId}");
- }
- var cameraCharacteristics = _cameraManager.GetCameraCharacteristics(_mCameraId);
- var isFacing = cameraCharacteristics.Get(CameraCharacteristics.LensFacing);
- if (isFacing != null && isFacing == Integer.ValueOf((int)LensFacing.Back))
- {
- _isFront = false;
- }
- else
- {
- _isFront = true;
- }
- _cameraStateCallBack = new CameraStateCallBack();
- _cameraStateCallBack.CameraDeviceChanged += OnCameraDeviceChanged;
- _cameraCaptureSessionCallback = new CameraCaptureSessionCallback();
- _cameraCaptureSessionCallback.SessionConfigured += OnConfigured;
- StartBackgroundThread();
- _cameraReader = new CameraReaderHelperV2(_mBackgroundHandler, _fps);
- _cameraReader.ImageFrameReceived += OnImageFrameReceived;
- _cameraReader.InitImageReader(_cameraWidth, _cameraHeight);
- SetupCamera();
- }
- catch (Exception ex)
- {
- _mCameraOpenCloseLock.Release();
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"Camera Helper Init Error : {ex}");
- }
- }
- ~CameraHelperV2()
- {
- if (_cameraReader != null)
- {
- _cameraReader.ImageFrameReceived -= ImageFrameReceived;
- _cameraReader.Close();
- }
- if (_cameraStateCallBack != null)
- {
- _cameraStateCallBack.CameraDeviceChanged -= OnCameraDeviceChanged;
- }
- if (_cameraCaptureSessionCallback != null)
- {
- _cameraCaptureSessionCallback.SessionConfigured -= OnConfigured;
- }
- }
- private void OnImageFrameReceived(object sender, ImageFrameData e)
- {
- ImageFrameReceived?.Invoke(this, e);
- }
- private void OnConfigured(object sender, CameraCaptureSession session)
- {
- try
- {
- //创建捕获请求
- _mCaptureRequest = _mCaptureRequestBuilder.Build();
- _mCameraCaptureSession = session;
- //设置反复捕获数据的请求,这样预览界面就会一直有数据显示
- _mCameraCaptureSession.SetRepeatingRequest(_mCaptureRequest, null, _mBackgroundHandler);
- }
- catch (Exception exception)
- {
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"OnConfigured error:{exception}");
- }
- }
- private void StartBackgroundThread()
- {
- _mBackgroundThread = new HandlerThread("CameraBackground");
- _mBackgroundThread.Start();
- _mBackgroundHandler = new Handler(_mBackgroundThread.Looper);
- }
- private void StopBackgroundThread()
- {
- try
- {
- if (_mBackgroundThread != null)
- {
- _mBackgroundThread.QuitSafely();
- _mBackgroundThread.Join();
- _mBackgroundThread = null;
- }
- _mBackgroundHandler = null;
- }
- catch (InterruptedException e)
- {
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"Stop Background thread error:{e}");
- }
- }
- private void OnCameraDeviceChanged(object sender, CameraDevice cameraDevice)
- {
- _mCameraOpenCloseLock.Release();
- _mCameraDevice = cameraDevice;
- if (cameraDevice != null)
- {
- StartPreview();
- }
- }
- private void StartPreview()
- {
- try
- {
- ////创建CaptureRequestBuilder,TEMPLATE_PREVIEW比表示预览请求
- _mCaptureRequestBuilder = _mCameraDevice.CreateCaptureRequest(CameraTemplate.Preview);
- ////设置Surface作为预览数据的显示界面
- var surface = _cameraReader.GetInputSurface();
- _mCaptureRequestBuilder.AddTarget(surface);
- // Here, we create a CameraCaptureSession for camera preview.
- List<Surface> surfaces = new List<Surface>
- {
- surface
- };
- /*创建相机捕获会话,
- 第一个参数是捕获数据的输出Surface列表,
- 第二个参数是CameraCaptureSession的状态回调接口,当它创建好后会回调onConfigured方法,
- 第三个参数用来确定Callback在哪个线程执行,为null的话就在当前线程执行*/
- _mCameraDevice.CreateCaptureSession(surfaces, _cameraCaptureSessionCallback, _mBackgroundHandler);
- }
- catch (Exception e)
- {
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"StartPreview error:{e}");
- }
- }
- private void OpenCamera()
- {
- try
- {
- if (_packageManager.CheckPermission(Manifest.Permission.Camera, _mContext.PackageName) != Permission.Granted)
- {
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"Open Camera Error:The Camera Permission Denied.");
- return;
- }
- if (!_mCameraOpenCloseLock.TryAcquire(2500, TimeUnit.Milliseconds))
- {
- throw new RuntimeException("Time out waiting to lock camera opening.");
- }
- _cameraManager.OpenCamera(_mCameraId, _cameraStateCallBack, _mBackgroundHandler);
- }
- catch (CameraAccessException e)
- {
- _mCameraOpenCloseLock.Release();
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"Open Camera Error:{e}");
- }
- }
- private void CloseCamera()
- {
- try
- {
- _mCameraOpenCloseLock.Acquire();
- if (_mCameraCaptureSession != null)
- {
- _mCameraCaptureSession.Close();
- _mCameraCaptureSession = null;
- }
- if (_mCameraDevice != null)
- {
- _mCameraDevice.Close();
- _mCameraDevice = null;
- }
- }
- catch (Exception e)
- {
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"Close Camera Error:{e}");
- }
- finally
- {
- _mCameraOpenCloseLock.Release();
- }
- }
- private Size GetOptimalSize(Size[] sizeMap, int width, int height)
- {
- List<Size> sizeList = new List<Size>();
- foreach (Size option in sizeMap)
- {
- if (width > height)
- {
- if (option.Width > width && option.Height > height)
- {
- sizeList.Add(option);
- }
- }
- else
- {
- if (option.Width > height && option.Height > width)
- {
- sizeList.Add(option);
- }
- }
- }
- if (sizeList.Count > 0)
- {
- return (Size)Collections.Min(sizeList, new CompareSizesByArea());
- }
- return sizeMap[0];
- }
- private void SetupCamera()
- {
- try
- {
- OpenCamera();
- }
- catch (Exception e)
- {
- _mCameraOpenCloseLock.Release();
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"SetupCamera error:{e}");
- }
- }
- public void SwitchCamera()
- {
- _mCameraId = _mCameraId.Equals("0") ? "1" : "0";
- CloseCamera();
- OpenCamera();
- }
- public void Stop()
- {
- CloseCamera();
- StopBackgroundThread();
- }
- }
- }
|