Skip to content

Commit

Permalink
fix(rn-camera) prevent camera-flickering on ios by introducing new pr…
Browse files Browse the repository at this point in the history
…operty defaultVideoQuality (react-native-camera#1886)

* Adding defaultVideoQuality property for iOS

* Remove quality in Readme

* Restore preset when cleanup the camera

* Validate isRecording to stopRecording

* Update the quality only if has changed.

* Fix AVCaptureSessionPreset type
  • Loading branch information
listicos authored and n1ru4l committed Oct 29, 2018
1 parent 2932f5a commit 09828cd
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 5 deletions.
27 changes: 27 additions & 0 deletions docs/RNCamera.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,33 @@ The video stabilization mode used for a video recording. The possible values are

You can read more about each stabilization type here: https://developer.apple.com/documentation/avfoundation/avcapturevideostabilizationmode

### `iOS` `defaultVideoQuality`

This option specifies the quality of the video to be taken. The possible values are:

- `RNCamera.Constants.VideoQuality.2160p`.
- `ios` Specifies capture settings suitable for 2160p (also called UHD or 4K) quality (3840x2160 pixel) video output.
- `android` Quality level corresponding to the 2160p (3840x2160) resolution. (Android Lollipop and above only!).
- `RNCamera.Constants.VideoQuality.1080p`.
- `ios` Specifies capture settings suitable for 1080p quality (1920x1080 pixel) video output.
- `android` Quality level corresponding to the 1080p (1920 x 1080) resolution.
- `RNCamera.Constants.VideoQuality.720p`.
- `ios` Specifies capture settings suitable for 720p quality (1280x720 pixel) video output.
- `android` Quality level corresponding to the 720p (1280 x 720) resolution.
- `RNCamera.Constants.VideoQuality.480p`.
- `ios` Specifies capture settings suitable for VGA quality (640x480 pixel) video output.
- `android` Quality level corresponding to the 480p (720 x 480) resolution.
- `RNCamera.Constants.VideoQuality.4:3`.
- `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.
- `RNCamera.Constants.VideoQuality.288p`.
- `ios` Specifies capture settings suitable for CIF quality (352x288 pixel) video output.
- `android` Not supported.

If nothing is passed the device's highest camera quality will be used as default.
Note: This solve the flicker video recording issue for iOS


### Native Event callbacks props

#### `onCameraReady`
Expand Down
1 change: 1 addition & 0 deletions ios/RN/RNCamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
@property (nonatomic, assign) BOOL canReadText;
@property(assign, nonatomic) AVVideoCodecType videoCodecType;
@property (assign, nonatomic) AVCaptureVideoStabilizationMode videoStabilizationMode;
@property(assign, nonatomic) NSInteger defaultVideoQuality;

- (id)initWithBridge:(RCTBridge *)bridge;
- (void)updateType;
Expand Down
19 changes: 14 additions & 5 deletions ios/RN/RNCamera.m
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,10 @@ - (void)record:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve r
}

if (options[@"quality"]) {
[self updateSessionPreset:[RNCameraUtils captureSessionPresetForVideoResolution:(RNCameraVideoResolution)[options[@"quality"] integerValue]]];
AVCaptureSessionPreset newQuality = [RNCameraUtils captureSessionPresetForVideoResolution:(RNCameraVideoResolution)[options[@"quality"] integerValue]];
if (self.session.sessionPreset != newQuality) {
[self updateSessionPreset:newQuality];
}
}

[self updateSessionAudioIsMuted:!!options[@"mute"]];
Expand Down Expand Up @@ -565,7 +568,11 @@ - (void)record:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve r

- (void)stopRecording
{
[self.movieFileOutput stopRecording];
if ([self.movieFileOutput isRecording]) {
[self.movieFileOutput stopRecording];
} else {
RCTLogWarn(@"Video is not recording.");
}
}

- (void)resumePreview
Expand Down Expand Up @@ -593,7 +600,8 @@ - (void)startSession
return;
}

self.session.sessionPreset = AVCaptureSessionPresetPhoto;
AVCaptureSessionPreset preset = [RNCameraUtils captureSessionPresetForVideoResolution:[self defaultVideoQuality]];
self.session.sessionPreset = preset == AVCaptureSessionPresetHigh ? AVCaptureSessionPresetPhoto: preset;

AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
if ([self.session canAddOutput:stillImageOutput]) {
Expand Down Expand Up @@ -949,8 +957,9 @@ - (void)cleanupCamera {
[self setupOrDisableTextDetector];
}

if (self.session.sessionPreset != AVCaptureSessionPresetPhoto) {
[self updateSessionPreset:AVCaptureSessionPresetPhoto];
AVCaptureSessionPreset preset = [RNCameraUtils captureSessionPresetForVideoResolution:[self defaultVideoQuality]];
if (self.session.sessionPreset != preset) {
[self updateSessionPreset: preset == AVCaptureSessionPresetHigh ? AVCaptureSessionPresetPhoto: preset];
}
}

Expand Down
5 changes: 5 additions & 0 deletions ios/RN/RNCameraManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ + (NSDictionary *)faceDetectorConstants
[view setupOrDisableTextDetector];
}

RCT_CUSTOM_VIEW_PROPERTY(defaultVideoQuality, NSInteger, RNCamera)
{
[view setDefaultVideoQuality:(NSInteger) [RCTConvert NSInteger:json]];
}

RCT_REMAP_METHOD(takePicture,
options:(NSDictionary *)options
reactTag:(nonnull NSNumber *)reactTag
Expand Down
1 change: 1 addition & 0 deletions src/RNCamera.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export default class Camera extends React.Component<PropsType, StateType> {
videoStabilizationMode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
pictureSize: PropTypes.string,
mirrorVideo: PropTypes.bool,
defaultVideoQuality: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};

static defaultProps: Object = {
Expand Down

0 comments on commit 09828cd

Please sign in to comment.