From fe5d11d12fe2a7eb7d0582776f260415f1b2865b Mon Sep 17 00:00:00 2001 From: cristianoccazinsp <48869228+cristianoccazinsp@users.noreply.github.com> Date: Tue, 10 Dec 2019 11:02:45 -0300 Subject: [PATCH] feat(iOS): allow for audio session to be kept (#2636) * allow for audio session to be kept even after unmounts * readme typo --- docs/RNCamera.md | 8 +++++++- ios/RN/RNCamera.h | 1 + ios/RN/RNCamera.m | 15 +++++++++------ ios/RN/RNCameraManager.m | 5 +++++ src/RNCamera.js | 3 +++ types/index.d.ts | 2 ++ 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/docs/RNCamera.md b/docs/RNCamera.md index f2bfaf722..bf90ed4f6 100644 --- a/docs/RNCamera.md +++ b/docs/RNCamera.md @@ -230,6 +230,12 @@ Values: boolean `true` (default) | `false` Specifies if audio recording permissions should be requested. Make sure to follow README instructions for audio recording permissions [here](README.md). +### iOS `keepAudioSession` + +Values: boolean `true` | `false` (false) + +(iOS Only) When the camera is unmounted, it will release any audio session it acquired (if `captureAudio=true`) so other media can continue playing. However, this might not be always desirable (e.g., if video is played afterwards) and can be disabled by setting it to `true`. Setting this to `true`, means your app will not release the audio session. Note: other apps might still "steal" the audio session from your app. + ### `flashMode` Values: `RNCamera.Constants.FlashMode.off` (default), `RNCamera.Constants.FlashMode.on`, `RNCamera.Constants.FlashMode.auto` or `RNCamera.Constants.FlashMode.torch`. @@ -698,7 +704,7 @@ A rewritten version of `react-native-barcode-mask` using `Hooks` and `Reanimated - Customizable - Provide custom hook to "scan barcode within finder area" -Read more about it here [@nartc/react-native-barcode-mask](https://github.com/nartc/react-native-barcode-mask) +Read more about it here [@nartc/react-native-barcode-mask](https://github.com/nartc/react-native-barcode-mask) ## Testing diff --git a/ios/RN/RNCamera.h b/ios/RN/RNCamera.h index 8063b5079..de8e7cfa3 100644 --- a/ios/RN/RNCamera.h +++ b/ios/RN/RNCamera.h @@ -46,6 +46,7 @@ @property(nonatomic, assign) BOOL canDetectFaces; @property(nonatomic, assign) BOOL canDetectBarcodes; @property(nonatomic, assign) BOOL captureAudio; +@property(nonatomic, assign) BOOL keepAudioSession; @property(nonatomic, assign) CGRect rectOfInterest; @property(assign, nonatomic) AVVideoCodecType videoCodecType; @property(assign, nonatomic) diff --git a/ios/RN/RNCamera.m b/ios/RN/RNCamera.m index d984e7d14..59beaee2d 100644 --- a/ios/RN/RNCamera.m +++ b/ios/RN/RNCamera.m @@ -1342,19 +1342,22 @@ - (void)removeAudioCaptureSessionInput // Deactivate our audio session so other audio can resume // playing, if any. E.g., background music. - NSError *error = nil; + // unless told not to + if(!self.keepAudioSession){ + NSError *error = nil; - BOOL setInactive = [[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error]; + BOOL setInactive = [[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error]; - if (!setInactive) { - RCTLogWarn(@"Audio device could not set inactive: %s: %@", __func__, error); + if (!setInactive) { + RCTLogWarn(@"Audio device could not set inactive: %s: %@", __func__, error); + } } - + self.audioCaptureDeviceInput = nil; // inform that audio was interrupted if(audioRemoved && self.onAudioInterrupted){ - self.onAudioInterrupted(nil); + self.onAudioInterrupted(nil); } } } diff --git a/ios/RN/RNCameraManager.m b/ios/RN/RNCameraManager.m index a69637608..9b3796f16 100644 --- a/ios/RN/RNCameraManager.m +++ b/ios/RN/RNCameraManager.m @@ -305,6 +305,11 @@ + (NSDictionary *)barcodeDetectorConstants [view updateCaptureAudio]; } +RCT_CUSTOM_VIEW_PROPERTY(keepAudioSession, BOOL, RNCamera) +{ + [view setKeepAudioSession:[RCTConvert BOOL:json]]; +} + RCT_CUSTOM_VIEW_PROPERTY(rectOfInterest, CGRect, RNCamera) { [view setRectOfInterest: [RCTConvert CGRect:json]]; diff --git a/src/RNCamera.js b/src/RNCamera.js index 9b397913a..ace2be707 100644 --- a/src/RNCamera.js +++ b/src/RNCamera.js @@ -270,6 +270,7 @@ type PropsType = typeof View.props & { onFacesDetected?: ({ faces: Array }) => void, onTextRecognized?: ({ textBlocks: Array }) => void, captureAudio?: boolean, + keepAudioSession?: boolean, useCamera2Api?: boolean, playSoundOnCapture?: boolean, videoStabilizationMode?: number | string, @@ -417,6 +418,7 @@ export default class Camera extends React.Component { notAuthorizedView: PropTypes.element, pendingAuthorizationView: PropTypes.element, captureAudio: PropTypes.bool, + keepAudioSession: PropTypes.bool, useCamera2Api: PropTypes.bool, playSoundOnCapture: PropTypes.bool, videoStabilizationMode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), @@ -466,6 +468,7 @@ export default class Camera extends React.Component { ), captureAudio: true, + keepAudioSession: false, useCamera2Api: false, playSoundOnCapture: false, pictureSize: 'None', diff --git a/types/index.d.ts b/types/index.d.ts index b0210a7ff..c0f348a39 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -223,6 +223,8 @@ export interface RNCameraProps { // -- IOS ONLY PROPS defaultVideoQuality?: keyof VideoQuality; + /* if true, audio session will not be released on component unmount */ + keepAudioSession?: boolean; } interface Point {