TUICameraManager.m 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Created by Tencent on 2023/06/09.
  2. // Copyright © 2023 Tencent. All rights reserved.
  3. #import "TUICameraManager.h"
  4. @implementation TUICameraManager
  5. #pragma mark - - Switch Camera
  6. - (AVCaptureDeviceInput *)switchCamera:(AVCaptureSession *)session old:(AVCaptureDeviceInput *)oldinput new:(AVCaptureDeviceInput *)newinput {
  7. [session beginConfiguration];
  8. [session removeInput:oldinput];
  9. if ([session canAddInput:newinput]) {
  10. [session addInput:newinput];
  11. [session commitConfiguration];
  12. return newinput;
  13. } else {
  14. [session addInput:oldinput];
  15. [session commitConfiguration];
  16. return oldinput;
  17. }
  18. }
  19. #pragma mark - - Zoom
  20. - (id)zoom:(AVCaptureDevice *)device factor:(CGFloat)factor {
  21. if (device.activeFormat.videoMaxZoomFactor > factor && factor >= 1.0) {
  22. NSError *error;
  23. if ([device lockForConfiguration:&error]) {
  24. [device rampToVideoZoomFactor:factor withRate:4.0];
  25. [device unlockForConfiguration];
  26. }
  27. return error;
  28. }
  29. return [self error:@"Unsupported zoom factor" code:2000];
  30. }
  31. #pragma mark - - Focus
  32. - (id)focus:(AVCaptureDevice *)device point:(CGPoint)point {
  33. BOOL supported = [device isFocusPointOfInterestSupported] && [device isFocusModeSupported:AVCaptureFocusModeAutoFocus];
  34. if (supported) {
  35. NSError *error;
  36. if ([device lockForConfiguration:&error]) {
  37. device.focusPointOfInterest = point;
  38. device.focusMode = AVCaptureFocusModeAutoFocus;
  39. [device unlockForConfiguration];
  40. }
  41. return error;
  42. }
  43. return [self error:@"Device does not support focus" code:2001];
  44. }
  45. #pragma mark - - Expose
  46. static const NSString *CameraAdjustingExposureContext;
  47. - (id)expose:(AVCaptureDevice *)device point:(CGPoint)point {
  48. BOOL supported = [device isExposurePointOfInterestSupported] && [device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure];
  49. if (supported) {
  50. NSError *error;
  51. if ([device lockForConfiguration:&error]) {
  52. device.exposurePointOfInterest = point;
  53. device.exposureMode = AVCaptureExposureModeContinuousAutoExposure;
  54. if ([device isExposureModeSupported:AVCaptureExposureModeLocked]) {
  55. [device addObserver:self forKeyPath:@"adjustingExposure" options:NSKeyValueObservingOptionNew context:&CameraAdjustingExposureContext];
  56. }
  57. [device unlockForConfiguration];
  58. }
  59. return error;
  60. }
  61. return [self error:@"Device does not support exposure" code:2002];
  62. }
  63. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
  64. if (context == &CameraAdjustingExposureContext) {
  65. AVCaptureDevice *device = (AVCaptureDevice *)object;
  66. if (!device.isAdjustingExposure && [device isExposureModeSupported:AVCaptureExposureModeLocked]) {
  67. [object removeObserver:self forKeyPath:@"adjustingExposure" context:&CameraAdjustingExposureContext];
  68. dispatch_async(dispatch_get_main_queue(), ^{
  69. NSError *error;
  70. if ([device lockForConfiguration:&error]) {
  71. device.exposureMode = AVCaptureExposureModeLocked;
  72. [device unlockForConfiguration];
  73. } else {
  74. NSLog(@"%@", error);
  75. }
  76. });
  77. }
  78. } else {
  79. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  80. }
  81. }
  82. #pragma mark - - Auto focus, exposure
  83. - (id)resetFocusAndExposure:(AVCaptureDevice *)device {
  84. AVCaptureFocusMode focusMode = AVCaptureFocusModeContinuousAutoFocus;
  85. AVCaptureExposureMode exposureMode = AVCaptureExposureModeContinuousAutoExposure;
  86. BOOL canResetFocus = [device isFocusPointOfInterestSupported] && [device isFocusModeSupported:focusMode];
  87. BOOL canResetExposure = [device isExposurePointOfInterestSupported] && [device isExposureModeSupported:exposureMode];
  88. CGPoint centerPoint = CGPointMake(0.5f, 0.5f);
  89. NSError *error;
  90. if ([device lockForConfiguration:&error]) {
  91. if (canResetFocus) {
  92. device.focusMode = focusMode;
  93. device.focusPointOfInterest = centerPoint;
  94. }
  95. if (canResetExposure) {
  96. device.exposureMode = exposureMode;
  97. device.exposurePointOfInterest = centerPoint;
  98. }
  99. [device unlockForConfiguration];
  100. }
  101. return error;
  102. }
  103. #pragma mark - - Flash
  104. - (AVCaptureFlashMode)flashMode:(AVCaptureDevice *)device {
  105. return [device flashMode];
  106. }
  107. - (id)changeFlash:(AVCaptureDevice *)device mode:(AVCaptureFlashMode)mode {
  108. if (![device hasFlash]) {
  109. return [self error:@"Flash is not supported" code:2003];
  110. }
  111. if ([self torchMode:device] == AVCaptureTorchModeOn) {
  112. [self setTorch:device model:AVCaptureTorchModeOff];
  113. }
  114. return [self setFlash:device mode:mode];
  115. }
  116. - (id)setFlash:(AVCaptureDevice *)device mode:(AVCaptureFlashMode)mode {
  117. if ([device isFlashModeSupported:mode]) {
  118. NSError *error;
  119. if ([device lockForConfiguration:&error]) {
  120. device.flashMode = mode;
  121. [device unlockForConfiguration];
  122. }
  123. return error;
  124. }
  125. return [self error:@"Flash is not supported" code:2003];
  126. }
  127. #pragma mark - - Flashlight
  128. - (AVCaptureTorchMode)torchMode:(AVCaptureDevice *)device {
  129. return [device torchMode];
  130. }
  131. - (id)changeTorch:(AVCaptureDevice *)device model:(AVCaptureTorchMode)mode {
  132. if (![device hasTorch]) {
  133. return [self error:@"Flashlight not supported" code:2004];
  134. }
  135. if ([self flashMode:device] == AVCaptureFlashModeOn) {
  136. [self setFlash:device mode:AVCaptureFlashModeOff];
  137. }
  138. return [self setTorch:device model:mode];
  139. }
  140. - (id)setTorch:(AVCaptureDevice *)device model:(AVCaptureTorchMode)mode {
  141. if ([device isTorchModeSupported:mode]) {
  142. NSError *error;
  143. if ([device lockForConfiguration:&error]) {
  144. device.torchMode = mode;
  145. [device unlockForConfiguration];
  146. }
  147. return error;
  148. }
  149. return [self error:@"Flashlight not supported" code:2004];
  150. }
  151. #pragma mark -
  152. - (NSError *)error:(NSString *)text code:(NSInteger)code {
  153. NSDictionary *desc = @{NSLocalizedDescriptionKey : text};
  154. NSError *error = [NSError errorWithDomain:@"com.tui.camera" code:code userInfo:desc];
  155. return error;
  156. }
  157. @end