react-native-audio-api 0.11.0-nightly-95f9c99-20251215 → 0.11.0-nightly-dd83923-20251216

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +382 -39
  2. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +45 -18
  3. package/android/src/main/cpp/audioapi/android/core/NativeAudioRecorder.hpp +9 -9
  4. package/android/src/main/cpp/audioapi/android/core/utils/AndroidFileWriterBackend.h +33 -0
  5. package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.cpp +170 -0
  6. package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.h +46 -0
  7. package/android/src/main/cpp/audioapi/android/core/utils/AudioDecoder.cpp +0 -1
  8. package/android/src/main/cpp/audioapi/android/core/utils/FileOptions.cpp +83 -0
  9. package/android/src/main/cpp/audioapi/android/core/utils/FileOptions.h +22 -0
  10. package/android/src/main/cpp/audioapi/android/core/utils/MiniaudioImplementation.cpp +8 -0
  11. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.cpp +493 -0
  12. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.h +70 -0
  13. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/ptrs.hpp +56 -0
  14. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/utils.cpp +114 -0
  15. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/utils.h +34 -0
  16. package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.cpp +296 -0
  17. package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.h +40 -0
  18. package/android/src/main/cpp/audioapi/android/system/NativeFileInfo.hpp +32 -0
  19. package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +2 -0
  20. package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +7 -3
  21. package/android/src/main/java/com/swmansion/audioapi/system/CentralizedForegroundService.kt +1 -0
  22. package/android/src/main/java/com/swmansion/audioapi/system/NativeFileInfo.kt +18 -0
  23. package/android/src/main/java/com/swmansion/audioapi/system/notification/PlaybackNotification.kt +1 -0
  24. package/android/src/main/java/com/swmansion/audioapi/system/notification/RecordingNotificationReceiver.kt +2 -0
  25. package/android/src/oldarch/NativeAudioAPIModuleSpec.java +100 -80
  26. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +3 -11
  27. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +145 -16
  28. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +21 -6
  29. package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +43 -60
  30. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +53 -33
  31. package/common/cpp/audioapi/core/sources/RecorderAdapterNode.cpp +42 -14
  32. package/common/cpp/audioapi/core/sources/RecorderAdapterNode.h +12 -9
  33. package/common/cpp/audioapi/core/utils/AudioFileWriter.cpp +41 -0
  34. package/common/cpp/audioapi/core/utils/AudioFileWriter.h +44 -0
  35. package/common/cpp/audioapi/core/utils/AudioRecorderCallback.cpp +101 -0
  36. package/common/cpp/audioapi/core/utils/AudioRecorderCallback.h +52 -0
  37. package/common/cpp/audioapi/utils/AudioFileProperties.cpp +92 -0
  38. package/common/cpp/audioapi/utils/AudioFileProperties.h +76 -0
  39. package/common/cpp/audioapi/utils/Result.hpp +323 -0
  40. package/common/cpp/audioapi/utils/UnitConversion.h +9 -0
  41. package/ios/audioapi/ios/AudioAPIModule.mm +9 -14
  42. package/ios/audioapi/ios/core/IOSAudioPlayer.h +1 -1
  43. package/ios/audioapi/ios/core/IOSAudioPlayer.mm +7 -6
  44. package/ios/audioapi/ios/core/IOSAudioRecorder.h +39 -13
  45. package/ios/audioapi/ios/core/IOSAudioRecorder.mm +302 -26
  46. package/ios/audioapi/ios/core/NativeAudioPlayer.m +7 -11
  47. package/ios/audioapi/ios/core/NativeAudioRecorder.h +8 -9
  48. package/ios/audioapi/ios/core/NativeAudioRecorder.m +70 -76
  49. package/ios/audioapi/ios/core/utils/AudioDecoder.mm +1 -0
  50. package/ios/audioapi/ios/core/utils/FileOptions.h +33 -0
  51. package/ios/audioapi/ios/core/utils/FileOptions.mm +195 -0
  52. package/ios/audioapi/ios/core/utils/IOSFileWriter.h +53 -0
  53. package/ios/audioapi/ios/core/utils/IOSFileWriter.mm +239 -0
  54. package/ios/audioapi/ios/core/utils/IOSRecorderCallback.h +47 -0
  55. package/ios/audioapi/ios/core/utils/IOSRecorderCallback.mm +185 -0
  56. package/ios/audioapi/ios/system/AudioEngine.h +21 -16
  57. package/ios/audioapi/ios/system/AudioEngine.mm +138 -130
  58. package/ios/audioapi/ios/system/AudioSessionManager.h +19 -9
  59. package/ios/audioapi/ios/system/AudioSessionManager.mm +250 -215
  60. package/ios/audioapi/ios/system/NotificationManager.mm +24 -42
  61. package/lib/commonjs/api.js +82 -109
  62. package/lib/commonjs/api.js.map +1 -1
  63. package/lib/commonjs/core/AudioRecorder.js +159 -13
  64. package/lib/commonjs/core/AudioRecorder.js.map +1 -1
  65. package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
  66. package/lib/commonjs/system/notification/PlaybackNotificationManager.js +17 -14
  67. package/lib/commonjs/system/notification/PlaybackNotificationManager.js.map +1 -1
  68. package/lib/commonjs/system/notification/RecordingNotificationManager.js +22 -19
  69. package/lib/commonjs/system/notification/RecordingNotificationManager.js.map +1 -1
  70. package/lib/commonjs/system/notification/SimpleNotificationManager.js +16 -13
  71. package/lib/commonjs/system/notification/SimpleNotificationManager.js.map +1 -1
  72. package/lib/commonjs/types.js +39 -0
  73. package/lib/commonjs/types.js.map +1 -1
  74. package/lib/commonjs/utils/filePresets.js +43 -0
  75. package/lib/commonjs/utils/filePresets.js.map +1 -0
  76. package/lib/commonjs/web-system/notification/PlaybackNotificationManager.js +6 -3
  77. package/lib/commonjs/web-system/notification/PlaybackNotificationManager.js.map +1 -1
  78. package/lib/commonjs/web-system/notification/RecordingNotificationManager.js +6 -3
  79. package/lib/commonjs/web-system/notification/RecordingNotificationManager.js.map +1 -1
  80. package/lib/module/api.js +5 -4
  81. package/lib/module/api.js.map +1 -1
  82. package/lib/module/core/AudioRecorder.js +159 -13
  83. package/lib/module/core/AudioRecorder.js.map +1 -1
  84. package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
  85. package/lib/module/system/notification/PlaybackNotificationManager.js +17 -14
  86. package/lib/module/system/notification/PlaybackNotificationManager.js.map +1 -1
  87. package/lib/module/system/notification/RecordingNotificationManager.js +22 -19
  88. package/lib/module/system/notification/RecordingNotificationManager.js.map +1 -1
  89. package/lib/module/system/notification/SimpleNotificationManager.js +16 -13
  90. package/lib/module/system/notification/SimpleNotificationManager.js.map +1 -1
  91. package/lib/module/types.js +38 -1
  92. package/lib/module/types.js.map +1 -1
  93. package/lib/module/utils/filePresets.js +39 -0
  94. package/lib/module/utils/filePresets.js.map +1 -0
  95. package/lib/module/web-system/notification/PlaybackNotificationManager.js +6 -3
  96. package/lib/module/web-system/notification/PlaybackNotificationManager.js.map +1 -1
  97. package/lib/module/web-system/notification/RecordingNotificationManager.js +6 -3
  98. package/lib/module/web-system/notification/RecordingNotificationManager.js.map +1 -1
  99. package/lib/typescript/api.d.ts +5 -4
  100. package/lib/typescript/api.d.ts.map +1 -1
  101. package/lib/typescript/core/AudioRecorder.d.ts +69 -7
  102. package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
  103. package/lib/typescript/events/types.d.ts +36 -2
  104. package/lib/typescript/events/types.d.ts.map +1 -1
  105. package/lib/typescript/interfaces.d.ts +24 -4
  106. package/lib/typescript/interfaces.d.ts.map +1 -1
  107. package/lib/typescript/specs/NativeAudioAPIModule.d.ts +1 -1
  108. package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
  109. package/lib/typescript/system/notification/PlaybackNotificationManager.d.ts +4 -3
  110. package/lib/typescript/system/notification/PlaybackNotificationManager.d.ts.map +1 -1
  111. package/lib/typescript/system/notification/RecordingNotificationManager.d.ts +4 -3
  112. package/lib/typescript/system/notification/RecordingNotificationManager.d.ts.map +1 -1
  113. package/lib/typescript/system/notification/SimpleNotificationManager.d.ts +3 -2
  114. package/lib/typescript/system/notification/SimpleNotificationManager.d.ts.map +1 -1
  115. package/lib/typescript/system/notification/types.d.ts.map +1 -1
  116. package/lib/typescript/types.d.ts +79 -3
  117. package/lib/typescript/types.d.ts.map +1 -1
  118. package/lib/typescript/utils/filePresets.d.ts +9 -0
  119. package/lib/typescript/utils/filePresets.d.ts.map +1 -0
  120. package/lib/typescript/web-system/notification/PlaybackNotificationManager.d.ts +4 -3
  121. package/lib/typescript/web-system/notification/PlaybackNotificationManager.d.ts.map +1 -1
  122. package/lib/typescript/web-system/notification/RecordingNotificationManager.d.ts +4 -3
  123. package/lib/typescript/web-system/notification/RecordingNotificationManager.d.ts.map +1 -1
  124. package/package.json +4 -4
  125. package/src/AudioAPIModule/globals.d.ts +1 -2
  126. package/src/api.ts +8 -29
  127. package/src/core/AudioRecorder.ts +195 -23
  128. package/src/events/types.ts +40 -2
  129. package/src/interfaces.ts +34 -5
  130. package/src/specs/NativeAudioAPIModule.ts +2 -2
  131. package/src/system/notification/PlaybackNotificationManager.ts +20 -16
  132. package/src/system/notification/RecordingNotificationManager.ts +26 -21
  133. package/src/system/notification/SimpleNotificationManager.ts +18 -13
  134. package/src/system/notification/types.ts +1 -0
  135. package/src/types.ts +89 -3
  136. package/src/utils/filePresets.ts +47 -0
  137. package/src/web-system/notification/PlaybackNotificationManager.ts +9 -5
  138. package/src/web-system/notification/RecordingNotificationManager.ts +9 -5
@@ -1,136 +1,110 @@
1
+ #import <AVFAudio/AVFAudio.h>
1
2
  #import <audioapi/ios/system/AudioSessionManager.h>
2
3
 
3
4
  @implementation AudioSessionManager
4
5
 
6
+ static AudioSessionManager *_sharedInstance = nil;
7
+
5
8
  - (instancetype)init
6
9
  {
7
10
  if (self = [super init]) {
8
11
  self.audioSession = [AVAudioSession sharedInstance];
9
12
 
10
- self.sessionCategory = AVAudioSessionCategoryPlayback;
11
- self.sessionMode = AVAudioSessionModeDefault;
12
- self.sessionOptions = 0;
13
- self.allowHapticsAndSystemSoundsDuringRecording = false;
14
- self.hasDirtySettings = true;
15
13
  self.isActive = false;
16
14
  self.shouldManageSession = true;
15
+
16
+ self.desiredCategory = AVAudioSessionCategoryPlayback;
17
+ self.desiredMode = AVAudioSessionModeDefault;
18
+ self.desiredOptions = 0;
19
+ self.allowHapticsAndSounds = false;
17
20
  }
18
21
 
22
+ _sharedInstance = self;
19
23
  return self;
20
24
  }
21
25
 
22
- - (void)cleanup
26
+ + (instancetype)sharedInstance
23
27
  {
24
- NSLog(@"[AudioSessionManager] cleanup");
28
+ return _sharedInstance;
29
+ }
25
30
 
31
+ - (void)cleanup
32
+ {
26
33
  self.audioSession = nil;
27
34
  }
28
35
 
29
- - (NSNumber *)getDevicePreferredSampleRate
36
+ - (bool)areDesiredOptionsSet
30
37
  {
31
- return [NSNumber numberWithFloat:[self.audioSession sampleRate]];
38
+ return (
39
+ self.audioSession.category == self.desiredCategory &&
40
+ self.audioSession.mode == self.desiredMode &&
41
+ self.audioSession.categoryOptions == self.desiredOptions &&
42
+ self.audioSession.allowHapticsAndSystemSoundsDuringRecording == self.allowHapticsAndSounds);
32
43
  }
33
44
 
34
- - (void)setAudioSessionOptions:(NSString *)category
35
- mode:(NSString *)mode
36
- options:(NSArray *)options
37
- allowHaptics:(BOOL)allowHaptics
45
+ - (bool)configureAudioSession
38
46
  {
39
- AVAudioSessionCategory sessionCategory = self.sessionCategory;
40
- AVAudioSessionMode sessionMode = self.sessionMode;
41
- AVAudioSessionCategoryOptions sessionOptions = 0;
42
- bool allowHapticsAndSystemSoundsDuringRecording = allowHaptics;
43
-
44
- if ([category isEqualToString:@"record"]) {
45
- sessionCategory = AVAudioSessionCategoryRecord;
46
- } else if ([category isEqualToString:@"ambient"]) {
47
- sessionCategory = AVAudioSessionCategoryAmbient;
48
- } else if ([category isEqualToString:@"playback"]) {
49
- sessionCategory = AVAudioSessionCategoryPlayback;
50
- } else if ([category isEqualToString:@"multiRoute"]) {
51
- sessionCategory = AVAudioSessionCategoryMultiRoute;
52
- } else if ([category isEqualToString:@"soloAmbient"]) {
53
- sessionCategory = AVAudioSessionCategorySoloAmbient;
54
- } else if ([category isEqualToString:@"playAndRecord"]) {
55
- sessionCategory = AVAudioSessionCategoryPlayAndRecord;
56
- }
47
+ NSError *error = nil;
57
48
 
58
- if ([mode isEqualToString:@"default"]) {
59
- sessionMode = AVAudioSessionModeDefault;
60
- } else if ([mode isEqualToString:@"gameChat"]) {
61
- sessionMode = AVAudioSessionModeGameChat;
62
- } else if ([mode isEqualToString:@"videoChat"]) {
63
- sessionMode = AVAudioSessionModeVideoChat;
64
- } else if ([mode isEqualToString:@"voiceChat"]) {
65
- sessionMode = AVAudioSessionModeVoiceChat;
66
- } else if ([mode isEqualToString:@"measurement"]) {
67
- sessionMode = AVAudioSessionModeMeasurement;
68
- } else if ([mode isEqualToString:@"voicePrompt"]) {
69
- sessionMode = AVAudioSessionModeVoicePrompt;
70
- } else if ([mode isEqualToString:@"spokenAudio"]) {
71
- sessionMode = AVAudioSessionModeSpokenAudio;
72
- } else if ([mode isEqualToString:@"moviePlayback"]) {
73
- sessionMode = AVAudioSessionModeMoviePlayback;
74
- } else if ([mode isEqualToString:@"videoRecording"]) {
75
- sessionMode = AVAudioSessionModeVideoRecording;
49
+ if (!self.shouldManageSession || [self areDesiredOptionsSet]) {
50
+ return true;
76
51
  }
77
52
 
78
- for (NSString *option in options) {
79
- if ([option isEqualToString:@"duckOthers"]) {
80
- sessionOptions |= AVAudioSessionCategoryOptionDuckOthers;
81
- }
82
-
83
- if ([option isEqualToString:@"allowAirPlay"]) {
84
- sessionOptions |= AVAudioSessionCategoryOptionAllowAirPlay;
85
- }
86
-
87
- if ([option isEqualToString:@"mixWithOthers"]) {
88
- sessionOptions |= AVAudioSessionCategoryOptionMixWithOthers;
89
- }
90
-
91
- if ([option isEqualToString:@"allowBluetooth"]) {
92
- sessionOptions |= AVAudioSessionCategoryOptionAllowBluetooth;
93
- }
94
-
95
- if ([option isEqualToString:@"defaultToSpeaker"]) {
96
- sessionOptions |= AVAudioSessionCategoryOptionDefaultToSpeaker;
97
- }
98
-
99
- if ([option isEqualToString:@"allowBluetoothA2DP"]) {
100
- sessionOptions |= AVAudioSessionCategoryOptionAllowBluetoothA2DP;
101
- }
102
-
103
- if ([option isEqualToString:@"overrideMutedMicrophoneInterruption"]) {
104
- sessionOptions |= AVAudioSessionCategoryOptionOverrideMutedMicrophoneInterruption;
105
- }
53
+ [self.audioSession setCategory:self.desiredCategory
54
+ mode:self.desiredMode
55
+ options:self.desiredOptions
56
+ error:&error];
106
57
 
107
- if ([option isEqualToString:@"interruptSpokenAudioAndMixWithOthers"]) {
108
- sessionOptions |= AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers;
109
- }
58
+ if (error != nil) {
59
+ NSLog(@"Error while configuring audio session: %@", [error debugDescription]);
60
+ return false;
61
+ } else {
62
+ NSLog(
63
+ @"[AudioSessionManager] Configured audio session: category=%@, mode=%@, options=%lu",
64
+ self.audioSession.category,
65
+ self.audioSession.mode,
66
+ (unsigned long)self.audioSession.categoryOptions);
110
67
  }
111
68
 
112
- if (self.sessionCategory != sessionCategory) {
113
- self.hasDirtySettings = true;
114
- self.sessionCategory = sessionCategory;
69
+ if (@available(iOS 13.0, *)) {
70
+ if (self.audioSession.allowHapticsAndSystemSoundsDuringRecording !=
71
+ self.allowHapticsAndSounds) {
72
+ [self.audioSession setAllowHapticsAndSystemSoundsDuringRecording:self.allowHapticsAndSounds
73
+ error:&error];
74
+
75
+ if (error != nil) {
76
+ NSLog(
77
+ @"Error while setting allowHapticsAndSystemSoundsDuringRecording: %@",
78
+ [error debugDescription]);
79
+ return false;
80
+ }
81
+ }
115
82
  }
116
83
 
117
- if (self.sessionMode != sessionMode) {
118
- self.hasDirtySettings = true;
119
- self.sessionMode = sessionMode;
120
- }
84
+ return true;
85
+ }
121
86
 
122
- if (self.sessionOptions != sessionOptions) {
123
- self.hasDirtySettings = true;
124
- self.sessionOptions = sessionOptions;
87
+ - (void)setAudioSessionOptions:(NSString *)categoryStr
88
+ mode:(NSString *)modeStr
89
+ options:(NSArray *)optionsArray
90
+ allowHaptics:(BOOL)allowHaptics
91
+ {
92
+ AVAudioSessionCategory category = [self categoryFromString:categoryStr];
93
+ AVAudioSessionMode mode = [self modeFromString:modeStr];
94
+ AVAudioSessionCategoryOptions options = [self optionsFromArray:optionsArray];
95
+ bool configChanged = false;
96
+
97
+ if (category != self.desiredCategory || mode != self.desiredMode ||
98
+ options != self.desiredOptions || allowHaptics != self.allowHapticsAndSounds) {
99
+ configChanged = true;
125
100
  }
126
101
 
127
- if (self.allowHapticsAndSystemSoundsDuringRecording !=
128
- allowHapticsAndSystemSoundsDuringRecording) {
129
- self.hasDirtySettings = true;
130
- self.allowHapticsAndSystemSoundsDuringRecording = allowHapticsAndSystemSoundsDuringRecording;
131
- }
102
+ self.desiredCategory = category;
103
+ self.desiredMode = mode;
104
+ self.desiredOptions = options;
105
+ self.allowHapticsAndSounds = allowHaptics;
132
106
 
133
- if (self.isActive) {
107
+ if (configChanged && self.isActive) {
134
108
  [self configureAudioSession];
135
109
  }
136
110
  }
@@ -140,17 +114,23 @@
140
114
  if (!self.shouldManageSession) {
141
115
  return true;
142
116
  }
143
- if (active == self.isActive) {
117
+
118
+ NSError *error = nil;
119
+ bool success = false;
120
+
121
+ if (self.isActive == active) {
144
122
  return true;
145
123
  }
146
124
 
147
125
  if (active) {
148
- [self configureAudioSession];
149
- }
126
+ success = [self configureAudioSession];
150
127
 
151
- NSError *error = nil;
128
+ if (!success) {
129
+ return false;
130
+ }
131
+ }
152
132
 
153
- bool success = [self.audioSession setActive:active error:&error];
133
+ success = [self.audioSession setActive:active error:&error];
154
134
 
155
135
  if (success) {
156
136
  self.isActive = active;
@@ -165,73 +145,27 @@
165
145
  return success;
166
146
  }
167
147
 
168
- - (bool)configureAudioSession
148
+ - (void)markInactive
169
149
  {
170
- if (!self.shouldManageSession) {
171
- NSLog(
172
- @"[AudioSessionManager] Skipping AVAudioSession configuration, shouldManageSession is false");
173
- return true;
174
- }
175
-
176
- if (![self hasDirtySettings]) {
177
- return true;
178
- }
179
-
180
- NSLog(
181
- @"[AudioSessionManager] configureAudioSession, category: %@, mode: %@, options: %lu, allowHaptics: %@",
182
- self.sessionCategory,
183
- self.sessionMode,
184
- (unsigned long)self.sessionOptions,
185
- self.allowHapticsAndSystemSoundsDuringRecording ? @"true" : @"false");
186
-
187
- NSError *error = nil;
188
-
189
- [self.audioSession setCategory:self.sessionCategory
190
- mode:self.sessionMode
191
- options:self.sessionOptions
192
- error:&error];
193
-
194
- if (error != nil) {
195
- NSLog(@"Error while configuring audio session: %@", [error debugDescription]);
196
- return false;
197
- }
198
-
199
- if (@available(iOS 13.0, *)) {
200
- [self.audioSession setAllowHapticsAndSystemSoundsDuringRecording:
201
- self.allowHapticsAndSystemSoundsDuringRecording
202
- error:&error];
203
-
204
- if (error != nil) {
205
- NSLog(
206
- @"Error while setting allowHapticsAndSystemSoundsDuringRecording: %@",
207
- [error debugDescription]);
208
- }
209
- }
210
-
211
- self.hasDirtySettings = false;
212
- return true;
150
+ // Mark as inactive no matter the state reported by AVAudioSession,
151
+ // this is used during interruptions to "force" going through configure&activate flow
152
+ // which is necessary after some of the interruptions (f.e. when the other app re-configures the hardware)
153
+ self.isActive = false;
213
154
  }
214
155
 
215
- - (bool)reconfigureAudioSession
156
+ - (void)disableSessionManagement
216
157
  {
217
- self.hasDirtySettings = true;
218
- if (self.isActive) {
219
- self.isActive = false;
220
- return [self setActive:true];
221
- }
222
- return true;
158
+ self.shouldManageSession = false;
223
159
  }
224
160
 
225
- - (void)markSettingsAsDirty
161
+ - (NSNumber *)getDevicePreferredSampleRate
226
162
  {
227
- self.hasDirtySettings = true;
228
- self.isActive = false;
163
+ return [NSNumber numberWithFloat:[self.audioSession sampleRate]];
229
164
  }
230
165
 
231
- - (void)disableSessionManagement
166
+ - (NSNumber *)getDevicePreferredInputChannelCount
232
167
  {
233
- self.shouldManageSession = false;
234
- self.hasDirtySettings = false;
168
+ return [NSNumber numberWithInteger:[self.audioSession inputNumberOfChannels]];
235
169
  }
236
170
 
237
171
  - (void)requestRecordingPermissions:(RCTPromiseResolveBlock)resolve
@@ -247,67 +181,72 @@
247
181
  nil);
248
182
  return;
249
183
  }
250
- if (@available(iOS 17, *)) {
251
- [AVAudioSession.sharedInstance requestRecordPermission:^(BOOL granted) {
252
- if (granted) {
253
- resolve(@"Granted");
254
- } else {
255
- resolve(@"Denied");
256
- }
184
+
185
+ resolve([self requestRecordingPermissions]);
186
+ }
187
+
188
+ - (NSString *)requestRecordingPermissions
189
+ {
190
+ id value = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSMicrophoneUsageDescription"];
191
+
192
+ if (value == nil) {
193
+ return @"Denied";
194
+ }
195
+
196
+ __block NSString *result = @"Denied";
197
+ dispatch_semaphore_t sem = dispatch_semaphore_create(0);
198
+
199
+ #if TARGET_OS_SIMULATOR
200
+ [self.audioSession requestRecordPermission:^(BOOL granted) {
201
+ result = granted ? @"Granted" : @"Denied";
202
+ dispatch_semaphore_signal(sem);
203
+ }];
204
+
205
+ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
206
+ return result;
207
+ #else
208
+ if (@available(iOS 17.0, *)) {
209
+ [AVAudioApplication requestRecordPermissionWithCompletionHandler:^(BOOL granted) {
210
+ result = granted ? @"Granted" : @"Denied";
211
+ dispatch_semaphore_signal(sem);
257
212
  }];
258
213
  } else {
259
214
  [self.audioSession requestRecordPermission:^(BOOL granted) {
260
- if (granted) {
261
- resolve(@"Granted");
262
- } else {
263
- resolve(@"Denied");
264
- }
215
+ result = granted ? @"Granted" : @"Denied";
216
+ dispatch_semaphore_signal(sem);
265
217
  }];
266
218
  }
219
+
220
+ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
221
+ return result;
222
+ #endif
267
223
  }
268
224
 
269
225
  - (void)checkRecordingPermissions:(RCTPromiseResolveBlock)resolve
270
226
  reject:(RCTPromiseRejectBlock)reject
271
227
  {
272
- if (@available(iOS 17, *)) {
273
- NSInteger res = [[AVAudioApplication sharedInstance] recordPermission];
274
- switch (res) {
275
- case AVAudioApplicationRecordPermissionUndetermined:
276
- resolve(@"Undetermined");
277
- break;
278
- case AVAudioApplicationRecordPermissionGranted:
279
- resolve(@"Granted");
280
- break;
281
- case AVAudioApplicationRecordPermissionDenied:
282
- resolve(@"Denied");
283
- break;
284
- default:
285
- resolve(@"Undetermined");
286
- break;
287
- }
288
- } else {
289
- NSInteger res = [self.audioSession recordPermission];
290
- switch (res) {
291
- case AVAudioSessionRecordPermissionUndetermined:
292
- resolve(@"Undetermined");
293
- break;
294
- case AVAudioSessionRecordPermissionGranted:
295
- resolve(@"Granted");
296
- break;
297
- case AVAudioSessionRecordPermissionDenied:
298
- resolve(@"Denied");
299
- break;
300
- default:
301
- resolve(@"Undetermined");
302
- break;
303
- }
304
- }
228
+ resolve([self checkRecordingPermissions]);
305
229
  }
306
230
 
307
231
  - (NSString *)checkRecordingPermissions
308
232
  {
233
+ #if TARGET_OS_SIMULATOR
234
+ NSInteger res = [self.audioSession recordPermission];
235
+
236
+ switch (res) {
237
+ case AVAudioSessionRecordPermissionUndetermined:
238
+ return @"Undetermined";
239
+ case AVAudioSessionRecordPermissionGranted:
240
+ return @"Granted";
241
+ case AVAudioSessionRecordPermissionDenied:
242
+ return @"Denied";
243
+ default:
244
+ return @"Undetermined";
245
+ }
246
+ #else
309
247
  if (@available(iOS 17, *)) {
310
248
  NSInteger res = [[AVAudioApplication sharedInstance] recordPermission];
249
+
311
250
  switch (res) {
312
251
  case AVAudioApplicationRecordPermissionUndetermined:
313
252
  return @"Undetermined";
@@ -318,19 +257,21 @@
318
257
  default:
319
258
  return @"Undetermined";
320
259
  }
321
- } else {
322
- NSInteger res = [self.audioSession recordPermission];
323
- switch (res) {
324
- case AVAudioSessionRecordPermissionUndetermined:
325
- return @"Undetermined";
326
- case AVAudioSessionRecordPermissionGranted:
327
- return @"Granted";
328
- case AVAudioSessionRecordPermissionDenied:
329
- return @"Denied";
330
- default:
331
- return @"Undetermined";
332
- }
333
260
  }
261
+
262
+ NSInteger res = [self.audioSession recordPermission];
263
+
264
+ switch (res) {
265
+ case AVAudioSessionRecordPermissionUndetermined:
266
+ return @"Undetermined";
267
+ case AVAudioSessionRecordPermissionGranted:
268
+ return @"Granted";
269
+ case AVAudioSessionRecordPermissionDenied:
270
+ return @"Denied";
271
+ default:
272
+ return @"Undetermined";
273
+ }
274
+ #endif
334
275
  }
335
276
 
336
277
  - (void)getDevicesInfo:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject
@@ -363,4 +304,98 @@
363
304
  return deviceList;
364
305
  }
365
306
 
307
+ - (AVAudioSessionCategory)categoryFromString:(NSString *)categorySTR
308
+ {
309
+ AVAudioSessionCategory category = 0;
310
+
311
+ if ([categorySTR isEqualToString:@"record"]) {
312
+ category = AVAudioSessionCategoryRecord;
313
+ } else if ([categorySTR isEqualToString:@"ambient"]) {
314
+ category = AVAudioSessionCategoryAmbient;
315
+ } else if ([categorySTR isEqualToString:@"playback"]) {
316
+ category = AVAudioSessionCategoryPlayback;
317
+ } else if ([categorySTR isEqualToString:@"multiRoute"]) {
318
+ category = AVAudioSessionCategoryMultiRoute;
319
+ } else if ([categorySTR isEqualToString:@"soloAmbient"]) {
320
+ category = AVAudioSessionCategorySoloAmbient;
321
+ } else if ([categorySTR isEqualToString:@"playAndRecord"]) {
322
+ category = AVAudioSessionCategoryPlayAndRecord;
323
+ }
324
+
325
+ return category;
326
+ }
327
+
328
+ - (AVAudioSessionMode)modeFromString:(NSString *)modeSTR
329
+ {
330
+ AVAudioSessionMode mode = 0;
331
+
332
+ if ([modeSTR isEqualToString:@"default"]) {
333
+ mode = AVAudioSessionModeDefault;
334
+ } else if ([modeSTR isEqualToString:@"gameChat"]) {
335
+ mode = AVAudioSessionModeGameChat;
336
+ } else if ([modeSTR isEqualToString:@"videoChat"]) {
337
+ mode = AVAudioSessionModeVideoChat;
338
+ } else if ([modeSTR isEqualToString:@"voiceChat"]) {
339
+ mode = AVAudioSessionModeVoiceChat;
340
+ } else if ([modeSTR isEqualToString:@"measurement"]) {
341
+ mode = AVAudioSessionModeMeasurement;
342
+ } else if ([modeSTR isEqualToString:@"voicePrompt"]) {
343
+ mode = AVAudioSessionModeVoicePrompt;
344
+ } else if ([modeSTR isEqualToString:@"spokenAudio"]) {
345
+ mode = AVAudioSessionModeSpokenAudio;
346
+ } else if ([modeSTR isEqualToString:@"moviePlayback"]) {
347
+ mode = AVAudioSessionModeMoviePlayback;
348
+ } else if ([modeSTR isEqualToString:@"videoRecording"]) {
349
+ mode = AVAudioSessionModeVideoRecording;
350
+ }
351
+
352
+ return mode;
353
+ }
354
+
355
+ - (AVAudioSessionCategoryOptions)optionsFromArray:(NSArray *)optionsArray
356
+ {
357
+ AVAudioSessionCategoryOptions options = 0;
358
+
359
+ for (NSString *option in optionsArray) {
360
+ if ([option isEqualToString:@"duckOthers"]) {
361
+ options |= AVAudioSessionCategoryOptionDuckOthers;
362
+ }
363
+
364
+ if ([option isEqualToString:@"allowAirPlay"]) {
365
+ options |= AVAudioSessionCategoryOptionAllowAirPlay;
366
+ }
367
+
368
+ if ([option isEqualToString:@"mixWithOthers"]) {
369
+ options |= AVAudioSessionCategoryOptionMixWithOthers;
370
+ }
371
+
372
+ if ([option isEqualToString:@"allowBluetooth"]) {
373
+ options |= AVAudioSessionCategoryOptionAllowBluetooth;
374
+ }
375
+
376
+ if ([option isEqualToString:@"defaultToSpeaker"]) {
377
+ options |= AVAudioSessionCategoryOptionDefaultToSpeaker;
378
+ }
379
+
380
+ if ([option isEqualToString:@"allowBluetoothA2DP"]) {
381
+ options |= AVAudioSessionCategoryOptionAllowBluetoothA2DP;
382
+ }
383
+
384
+ if ([option isEqualToString:@"overrideMutedMicrophoneInterruption"]) {
385
+ options |= AVAudioSessionCategoryOptionOverrideMutedMicrophoneInterruption;
386
+ }
387
+
388
+ if ([option isEqualToString:@"interruptSpokenAudioAndMixWithOthers"]) {
389
+ options |= AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers;
390
+ }
391
+ }
392
+
393
+ return options;
394
+ }
395
+
396
+ - (bool)isSessionActive
397
+ {
398
+ return self.isActive;
399
+ }
400
+
366
401
  @end