diff --git a/packages/audiodocs/docs/system/audio-manager.mdx b/packages/audiodocs/docs/system/audio-manager.mdx index c5dd35be8..4f86c84ee 100644 --- a/packages/audiodocs/docs/system/audio-manager.mdx +++ b/packages/audiodocs/docs/system/audio-manager.mdx @@ -102,7 +102,16 @@ Resets all of the lock screen data. | :---: | :---: | :---- | | enabled | `boolean` | It is used to set/unset [AVAudioSession](https://developer.apple.com/documentation/avfaudio/avaudiosession?language=objc#Activating-the-audio-configuration) activity | -#### Returns promise of `boolean` type, which is resolved to `true` if invokation ended with success, `false` otherwise. +#### Returns promise of `boolean` type, which is resolved to `true` if invokation ended with success, `false` otherwise.' + +### `disableSessionManagement` + +#### Returns `undefined`. + +Disables all internal default [AVAudioSession](https://developer.apple.com/documentation/avfaudio/avaudiosession) configurations and management done by the `react-native-audio-api` package. After calling this method, user is responsible for managing audio session entirely on their own. +Typical use-case for this method is when user wants to fully control audio session outside of `react-native-audio-api` package, +commonly when using another audio library along `react-native-audio-api`. The method has to be called before `AudioContext` is created, for example in app initialization code. +Any later call to `setAudioSessionOptions` or `setAudioSessionActivity` will re-enable internal audio session management. ### `getDevicePreferredSampleRate` diff --git a/packages/react-native-audio-api/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt b/packages/react-native-audio-api/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt index 73d8adf0c..453d77d55 100644 --- a/packages/react-native-audio-api/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +++ b/packages/react-native-audio-api/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt @@ -110,6 +110,10 @@ class AudioAPIModule( // noting to do here } + override fun disableSessionManagement() { + // nothing to do here + } + override fun setLockScreenInfo(info: ReadableMap?) { MediaSessionManager.setLockScreenInfo(info) } diff --git a/packages/react-native-audio-api/android/src/oldarch/NativeAudioAPIModuleSpec.java b/packages/react-native-audio-api/android/src/oldarch/NativeAudioAPIModuleSpec.java index d7b5ed4d0..3e0840996 100644 --- a/packages/react-native-audio-api/android/src/oldarch/NativeAudioAPIModuleSpec.java +++ b/packages/react-native-audio-api/android/src/oldarch/NativeAudioAPIModuleSpec.java @@ -50,6 +50,10 @@ public NativeAudioAPIModuleSpec(ReactApplicationContext reactContext) { @DoNotStrip public abstract void setAudioSessionOptions(String category, String mode, ReadableArray options, boolean allowHaptics); + @ReactMethod + @DoNotStrip + public abstract void disableSessionManagement(); + @ReactMethod @DoNotStrip public abstract void setLockScreenInfo(ReadableMap info); diff --git a/packages/react-native-audio-api/ios/audioapi/ios/AudioAPIModule.mm b/packages/react-native-audio-api/ios/audioapi/ios/AudioAPIModule.mm index 1974d8171..baecd10f2 100644 --- a/packages/react-native-audio-api/ios/audioapi/ios/AudioAPIModule.mm +++ b/packages/react-native-audio-api/ios/audioapi/ios/AudioAPIModule.mm @@ -118,6 +118,9 @@ - (void)invalidate setAudioSessionActivity : (BOOL)enabled resolve : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock) reject) { + if (!self.audioSessionManager.shouldManageSession) { + [self.audioSessionManager setShouldManageSession:true]; + } if ([self.audioSessionManager setActive:enabled]) { resolve(@"true"); return; @@ -130,6 +133,9 @@ - (void)invalidate setAudioSessionOptions : (NSString *)category mode : (NSString *)mode options : (NSArray *) options allowHaptics : (BOOL)allowHaptics) { + if (!self.audioSessionManager.shouldManageSession) { + [self.audioSessionManager setShouldManageSession:true]; + } [self.audioSessionManager setAudioSessionOptions:category mode:mode options:options allowHaptics:allowHaptics]; } @@ -182,6 +188,11 @@ - (void)invalidate [self.audioSessionManager getDevicesInfo:resolve reject:reject]; } +RCT_EXPORT_METHOD(disableSessionManagement) +{ + [self.audioSessionManager disableSessionManagement]; +} + #ifdef RCT_NEW_ARCH_ENABLED - (std::shared_ptr)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params diff --git a/packages/react-native-audio-api/ios/audioapi/ios/system/AudioSessionManager.h b/packages/react-native-audio-api/ios/audioapi/ios/system/AudioSessionManager.h index c62c541fc..19474ad11 100644 --- a/packages/react-native-audio-api/ios/audioapi/ios/system/AudioSessionManager.h +++ b/packages/react-native-audio-api/ios/audioapi/ios/system/AudioSessionManager.h @@ -14,6 +14,7 @@ @property (nonatomic, assign) AVAudioSessionCategory sessionCategory; @property (nonatomic, assign) AVAudioSessionCategoryOptions sessionOptions; @property (nonatomic, assign) bool allowHapticsAndSystemSoundsDuringRecording; +@property (nonatomic, assign) bool shouldManageSession; - (instancetype)init; - (void)cleanup; @@ -27,6 +28,7 @@ options:(NSArray *)options allowHaptics:(BOOL)allowHaptics; - (bool)setActive:(bool)active; +- (void)disableSessionManagement; - (void)requestRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject; - (void)checkRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject; diff --git a/packages/react-native-audio-api/ios/audioapi/ios/system/AudioSessionManager.mm b/packages/react-native-audio-api/ios/audioapi/ios/system/AudioSessionManager.mm index 01e713f4f..5c22a1725 100644 --- a/packages/react-native-audio-api/ios/audioapi/ios/system/AudioSessionManager.mm +++ b/packages/react-native-audio-api/ios/audioapi/ios/system/AudioSessionManager.mm @@ -13,6 +13,7 @@ - (instancetype)init self.allowHapticsAndSystemSoundsDuringRecording = false; self.hasDirtySettings = true; self.isActive = false; + self.shouldManageSession = true; } return self; @@ -135,6 +136,9 @@ - (void)setAudioSessionOptions:(NSString *)category - (bool)setActive:(bool)active { + if (!self.shouldManageSession) { + return true; + } if (active == self.isActive) { return true; } @@ -162,6 +166,11 @@ - (bool)setActive:(bool)active - (bool)configureAudioSession { + if (!self.shouldManageSession) { + NSLog(@"[AudioSessionManager] Skipping AVAudioSession configuration, shouldManageSession is false"); + return true; + } + if (![self hasDirtySettings]) { return true; } @@ -211,6 +220,12 @@ - (void)markSettingsAsDirty self.isActive = false; } +- (void)disableSessionManagement +{ + self.shouldManageSession = false; + self.hasDirtySettings = false; +} + - (void)requestRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject { id value = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSMicrophoneUsageDescription"]; diff --git a/packages/react-native-audio-api/src/specs/NativeAudioAPIModule.ts b/packages/react-native-audio-api/src/specs/NativeAudioAPIModule.ts index 6bab1ba39..21fa17a88 100644 --- a/packages/react-native-audio-api/src/specs/NativeAudioAPIModule.ts +++ b/packages/react-native-audio-api/src/specs/NativeAudioAPIModule.ts @@ -15,6 +15,7 @@ interface Spec extends TurboModule { options: Array, allowHaptics: boolean ): void; + disableSessionManagement(): void; // Lock Screen Info setLockScreenInfo(info: { diff --git a/packages/react-native-audio-api/src/system/AudioManager.ts b/packages/react-native-audio-api/src/system/AudioManager.ts index 70a116ee4..46a2a2b9f 100644 --- a/packages/react-native-audio-api/src/system/AudioManager.ts +++ b/packages/react-native-audio-api/src/system/AudioManager.ts @@ -45,6 +45,10 @@ class AudioManager { ); } + disableSessionManagement() { + NativeAudioAPIModule!.disableSessionManagement(); + } + setLockScreenInfo(info: LockScreenInfo) { NativeAudioAPIModule!.setLockScreenInfo(info); }