Skip to content
This repository has been archived by the owner on Jun 16, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1339 from n1ru4l/ios-codec-option
Browse files Browse the repository at this point in the history
feat(rn-camera): add codec option for ios
  • Loading branch information
n1ru4l committed Mar 13, 2018
2 parents f109430 + 2b9d8db commit 3daea5d
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 4 deletions.
11 changes: 9 additions & 2 deletions docs/RNCamera.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,13 @@ The promise will be fulfilled with an object with some of the following properti
- `ios` Specifies capture settings suitable for VGA quality (640x480 pixel) video output. (Same as RNCamera.Constants.VideoQuality.480p).
- `android` Quality level corresponding to the 480p (720 x 480) resolution but with video frame width set to 640.

If nothing is passed the device's highest camera quality will be used as default.

If nothing is passed the device's highest camera quality will be used as default.
- `iOS` `codec`. This option specifies the codec of the output video. Setting the codec is only supported on `iOS >= 10`. The possible values are:
- `RNCamera.Constants.VideoCodec['H264']`
- `RNCamera.Constants.VideoCodec['JPEG']`
- `RNCamera.Constants.VideoCodec['HVEC']` (`iOS >= 11`)
- `RNCamera.Constants.VideoCodec['AppleProRes422']` (`iOS >= 11`)
- `RNCamera.Constants.VideoCodec['AppleProRes4444']` (`iOS >= 11`)
- `maxDuration` (float greater than 0). Specifies the maximum duration of the video to be recorded in seconds. If nothing is specified, no time limit will be used.

- `maxFileSize` (int greater than 0). Specifies the maximum file size, in bytes, of the video to be recorded. For 1mb, for example, use 1*1024*1024. If nothing is specified, no size limit will be used.
Expand All @@ -296,6 +301,8 @@ The promise will be fulfilled with an object with some of the following properti

- `uri`: returns the path to the video saved on your app's cache directory.

- `iOS` `codec`: the codec of the recorded video. One of `RNCamera.Constants.VideoCodec`

#### `stopRecording: void`

Should be called after recordAsync() to make the promise be fulfilled and get the video uri.
Expand Down
1 change: 1 addition & 0 deletions ios/RN/RNCamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@property (assign, nonatomic) float focusDepth;
@property (assign, nonatomic) NSInteger whiteBalance;
@property (nonatomic, assign, getter=isReadingBarCodes) BOOL barCodeReading;
@property(assign, nonatomic) AVVideoCodecType videoCodecType;

- (id)initWithBridge:(RCTBridge *)bridge;
- (void)updateType;
Expand Down
24 changes: 22 additions & 2 deletions ios/RN/RNCamera.m
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,21 @@ - (void)record:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve r

AVCaptureConnection *connection = [self.movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
[connection setVideoOrientation:[RNCameraUtils videoOrientationForInterfaceOrientation:[[UIApplication sharedApplication] statusBarOrientation]]];


if (options[@"codec"]) {
AVVideoCodecType videoCodecType = options[@"codec"];
if (@available(iOS 10, *)) {
if ([self.movieFileOutput.availableVideoCodecTypes containsObject:videoCodecType]) {
[self.movieFileOutput setOutputSettings:@{AVVideoCodecKey:videoCodecType} forConnection:connection];
self.videoCodecType = videoCodecType;
} else {
RCTLogWarn(@"%s: Video Codec '%@' is not supported on this device.", __func__, videoCodecType);
}
} else {
RCTLogWarn(@"%s: Setting videoCodec is only supported above iOS version 10.", __func__);
}
}

dispatch_async(self.sessionQueue, ^{
NSString *path = [RNFileSystem generatePathInDirectory:[[RNFileSystem cacheDirectoryPath] stringByAppendingString:@"Camera"] withExtension:@".mov"];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:path];
Expand Down Expand Up @@ -714,12 +728,18 @@ - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToO
}
}
if (success && self.videoRecordedResolve != nil) {
self.videoRecordedResolve(@{ @"uri": outputFileURL.absoluteString });
AVVideoCodecType videoCodec = self.videoCodecType;
if (videoCodec == nil) {
videoCodec = [self.movieFileOutput.availableVideoCodecTypes firstObject];
}

self.videoRecordedResolve(@{ @"uri": outputFileURL.absoluteString, @"codec":videoCodec });
} else if (self.videoRecordedReject != nil) {
self.videoRecordedReject(@"E_RECORDING_FAILED", @"An error occurred while recording a video.", error);
}
self.videoRecordedResolve = nil;
self.videoRecordedReject = nil;
self.videoCodecType = nil;

[self cleanupMovieFileCapture];
// If face detection has been running prior to recording to file
Expand Down
1 change: 1 addition & 0 deletions ios/RN/RNCameraManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ typedef NS_ENUM(NSInteger, RNCameraVideoResolution) {
@interface RNCameraManager : RCTViewManager <RCTBridgeModule>

+ (NSDictionary *)validBarCodeTypes;
+ (NSDictionary *)validCodecTypes;

@end

19 changes: 19 additions & 0 deletions ios/RN/RNCameraManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ - (NSDictionary *)constantsToExport
@"480p": @(RNCameraVideo4x3),
@"4:3": @(RNCameraVideo4x3),
},
@"VideoCodec": [[self class] validCodecTypes],
@"BarCodeType" : [[self class] validBarCodeTypes],
@"FaceDetection" : [[self class] faceDetectorConstants]
};
Expand All @@ -65,6 +66,24 @@ - (NSDictionary *)constantsToExport
return @[@"onCameraReady", @"onMountError", @"onBarCodeRead", @"onFacesDetected"];
}

+ (NSDictionary *)validCodecTypes
{
if (@available(iOS 11, *)) {
return @{
@"H264": AVVideoCodecTypeH264,
@"HVEC": AVVideoCodecTypeHEVC,
@"JPEG": AVVideoCodecTypeJPEG,
@"AppleProRes422": AVVideoCodecTypeAppleProRes422,
@"AppleProRes4444": AVVideoCodecTypeAppleProRes4444
};
} else {
return @{
@"H264": AVVideoCodecH264,
@"JPEG": AVVideoCodecJPEG
};
}
}

+ (NSDictionary *)validBarCodeTypes
{
return @{
Expand Down
2 changes: 2 additions & 0 deletions src/RNCamera.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type RecordingOptions = {
maxDuration?: number,
maxFileSize?: number,
quality?: number | string,
codec?: string,
mute?: boolean,
};

Expand Down Expand Up @@ -96,6 +97,7 @@ export default class Camera extends React.Component<PropsType> {
AutoFocus: CameraManager.AutoFocus,
WhiteBalance: CameraManager.WhiteBalance,
VideoQuality: CameraManager.VideoQuality,
VideoCodec: CameraManager.VideoCodec,
BarCodeType: CameraManager.BarCodeType,
FaceDetection: CameraManager.FaceDetection,
};
Expand Down

0 comments on commit 3daea5d

Please sign in to comment.