mirror of
https://github.com/status-im/react-native-camera.git
synced 2025-02-24 09:48:17 +00:00
186 lines
6.1 KiB
Objective-C
186 lines
6.1 KiB
Objective-C
#import "RCTCameraManager.h"
|
|
#import "RCTCamera.h"
|
|
#import "RCTBridge.h"
|
|
#import "RCTUtils.h"
|
|
#import <AVFoundation/AVFoundation.h>
|
|
|
|
@implementation RCTCameraManager
|
|
|
|
+ (id)sharedManager {
|
|
static RCTCameraManager *sharedCameraManager = nil;
|
|
@synchronized(self) {
|
|
if (sharedCameraManager == nil)
|
|
sharedCameraManager = [[self alloc] init];
|
|
}
|
|
return sharedCameraManager;
|
|
}
|
|
|
|
@synthesize bridge = _bridge;
|
|
|
|
- (UIView *)view
|
|
{
|
|
[self setCurrentCamera:[[RCTCamera alloc] init]];
|
|
return _currentCamera;
|
|
}
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(aspect, NSString);
|
|
RCT_EXPORT_VIEW_PROPERTY(camera, NSInteger);
|
|
RCT_EXPORT_VIEW_PROPERTY(orientation, NSInteger);
|
|
|
|
- (NSDictionary *)constantsToExport
|
|
{
|
|
return @{
|
|
@"aspects": @{
|
|
@"Stretch": AVLayerVideoGravityResize,
|
|
@"Fit": AVLayerVideoGravityResizeAspect,
|
|
@"Fill": AVLayerVideoGravityResizeAspectFill
|
|
},
|
|
@"cameras": @{
|
|
@"Front": @(AVCaptureDevicePositionFront),
|
|
@"Back": @(AVCaptureDevicePositionBack)
|
|
},
|
|
@"orientations": @{
|
|
@"LandscapeLeft": @(AVCaptureVideoOrientationLandscapeLeft),
|
|
@"LandscapeRight": @(AVCaptureVideoOrientationLandscapeRight),
|
|
@"Portrait": @(AVCaptureVideoOrientationPortrait),
|
|
@"PortraitUpsideDown": @(AVCaptureVideoOrientationPortraitUpsideDown)
|
|
}
|
|
};
|
|
}
|
|
|
|
- (id)init {
|
|
if ((self = [super init])) {
|
|
[self setSession:[[AVCaptureSession alloc] init]];
|
|
[_session setSessionPreset:AVCaptureSessionPresetHigh];
|
|
|
|
NSError *error = nil;
|
|
|
|
AVCaptureDevice *captureDevice = [self deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionBack];
|
|
|
|
_captureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
|
|
|
|
|
|
if (error)
|
|
{
|
|
NSLog(@"%@", error);
|
|
}
|
|
|
|
if ([_session canAddInput:_captureDeviceInput])
|
|
{
|
|
[_session addInput:_captureDeviceInput];
|
|
|
|
[[(AVCaptureVideoPreviewLayer *)_currentCamera.viewfinder.layer connection] setVideoOrientation:AVCaptureVideoOrientationPortrait];
|
|
[(AVCaptureVideoPreviewLayer *)_currentCamera.viewfinder.layer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
|
|
}
|
|
|
|
AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
|
|
if ([_session canAddOutput:stillImageOutput])
|
|
{
|
|
[_stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}];
|
|
[_session addOutput:stillImageOutput];
|
|
[self setStillImageOutput:stillImageOutput];
|
|
}
|
|
|
|
[_session startRunning];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)checkDeviceAuthorizationStatus:(RCTResponseSenderBlock) callback {
|
|
RCT_EXPORT();
|
|
NSString *mediaType = AVMediaTypeVideo;
|
|
|
|
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
|
|
callback(@[[NSNull null], @(granted)]);
|
|
}];
|
|
}
|
|
|
|
- (void)setAspect:(NSString *)aspect
|
|
{
|
|
[(AVCaptureVideoPreviewLayer *)_currentCamera.viewfinder.layer setVideoGravity:aspect];
|
|
}
|
|
|
|
|
|
- (void)setCamera:(NSInteger)camera
|
|
{
|
|
// AVCaptureDevice *currentVideoDevice = [_captureDeviceInput device];
|
|
AVCaptureDevicePosition position = (AVCaptureDevicePosition)camera;
|
|
AVCaptureDevice *videoDevice = [self deviceWithMediaType:AVMediaTypeVideo preferringPosition:(AVCaptureDevicePosition)position];
|
|
|
|
NSError *error = nil;
|
|
AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
|
|
|
|
if (error)
|
|
{
|
|
NSLog(@"%@", error);
|
|
}
|
|
|
|
[[self session] beginConfiguration];
|
|
|
|
[[self session] removeInput:[self captureDeviceInput]];
|
|
|
|
|
|
if ([[self session] canAddInput:videoDeviceInput])
|
|
{
|
|
// [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:currentVideoDevice];
|
|
//
|
|
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:videoDevice];
|
|
//
|
|
[[self session] addInput:videoDeviceInput];
|
|
[self setCaptureDeviceInput:videoDeviceInput];
|
|
}
|
|
else
|
|
{
|
|
[[self session] addInput:_captureDeviceInput];
|
|
}
|
|
|
|
[[self session] commitConfiguration];
|
|
}
|
|
|
|
- (void)setOrientation:(NSInteger)orientation
|
|
{
|
|
[[(AVCaptureVideoPreviewLayer *)_currentCamera.viewfinder.layer connection] setVideoOrientation:orientation];
|
|
}
|
|
|
|
- (void)takePicture:(RCTResponseSenderBlock) callback {
|
|
RCT_EXPORT();
|
|
// Update the orientation on the still image output video connection before capturing.
|
|
[[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)_currentCamera.viewfinder.layer connection] videoOrientation]];
|
|
|
|
// Flash set to Auto for Still Capture
|
|
// [AVCamViewController setFlashMode:AVCaptureFlashModeAuto forDevice:[[self videoDeviceInput] device]];
|
|
|
|
// Capture a still image.
|
|
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
|
|
|
|
if (imageDataSampleBuffer)
|
|
{
|
|
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
|
|
NSString *imageBase64 = [imageData base64EncodedStringWithOptions:0];
|
|
callback(@[[NSNull null], imageBase64]);
|
|
}
|
|
else {
|
|
callback(@[RCTMakeError(error.description, nil, nil)]);
|
|
}
|
|
}];
|
|
}
|
|
|
|
- (AVCaptureDevice *)deviceWithMediaType:(NSString *)mediaType preferringPosition:(AVCaptureDevicePosition)position
|
|
{
|
|
NSArray *devices = [AVCaptureDevice devicesWithMediaType:mediaType];
|
|
AVCaptureDevice *captureDevice = [devices firstObject];
|
|
|
|
for (AVCaptureDevice *device in devices)
|
|
{
|
|
if ([device position] == position)
|
|
{
|
|
captureDevice = device;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return captureDevice;
|
|
}
|
|
|
|
@end
|