react-native-audio-api 0.11.1 → 0.11.3

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 (113) hide show
  1. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +8 -5
  2. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +1 -1
  3. package/android/src/main/cpp/audioapi/android/core/utils/AndroidFileWriterBackend.h +1 -1
  4. package/android/src/main/cpp/audioapi/android/core/utils/FileOptions.cpp +7 -3
  5. package/android/src/main/cpp/audioapi/android/core/utils/FileOptions.h +1 -1
  6. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.cpp +4 -2
  7. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.h +1 -1
  8. package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.cpp +5 -4
  9. package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.h +2 -2
  10. package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +9 -0
  11. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +2 -0
  12. package/android/src/oldarch/NativeAudioAPIModuleSpec.java +4 -0
  13. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +3 -1
  14. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +1 -1
  15. package/common/cpp/audioapi/core/sources/StreamerNode.h +6 -0
  16. package/common/cpp/audioapi/jsi/JsiUtils.cpp +21 -0
  17. package/common/cpp/audioapi/jsi/JsiUtils.h +17 -0
  18. package/ios/audioapi/ios/AudioAPIModule.mm +9 -0
  19. package/ios/audioapi/ios/core/IOSAudioRecorder.h +1 -1
  20. package/ios/audioapi/ios/core/IOSAudioRecorder.mm +5 -4
  21. package/ios/audioapi/ios/core/utils/FileOptions.h +3 -1
  22. package/ios/audioapi/ios/core/utils/FileOptions.mm +9 -3
  23. package/ios/audioapi/ios/core/utils/IOSFileWriter.h +2 -1
  24. package/ios/audioapi/ios/core/utils/IOSFileWriter.mm +5 -2
  25. package/ios/audioapi/ios/system/AudioEngine.mm +3 -1
  26. package/ios/audioapi/ios/system/AudioSessionManager.h +3 -0
  27. package/ios/audioapi/ios/system/AudioSessionManager.mm +38 -2
  28. package/lib/commonjs/api.js +8 -8
  29. package/lib/commonjs/api.js.map +1 -1
  30. package/lib/commonjs/core/AudioDecoder.js +2 -2
  31. package/lib/commonjs/core/AudioDecoder.js.map +1 -1
  32. package/lib/commonjs/core/AudioRecorder.js +4 -4
  33. package/lib/commonjs/core/AudioRecorder.js.map +1 -1
  34. package/lib/commonjs/hooks/index.js +21 -0
  35. package/lib/commonjs/hooks/index.js.map +1 -0
  36. package/lib/commonjs/hooks/useAudioInput.js +70 -0
  37. package/lib/commonjs/hooks/useAudioInput.js.map +1 -0
  38. package/lib/commonjs/hooks/useSystemVolume.js +4 -5
  39. package/lib/commonjs/hooks/useSystemVolume.js.map +1 -1
  40. package/lib/commonjs/index.js +11 -0
  41. package/lib/commonjs/index.js.map +1 -1
  42. package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
  43. package/lib/commonjs/specs/NativeAudioAPIModule.web.js +1 -0
  44. package/lib/commonjs/specs/NativeAudioAPIModule.web.js.map +1 -1
  45. package/lib/commonjs/system/AudioManager.js +3 -0
  46. package/lib/commonjs/system/AudioManager.js.map +1 -1
  47. package/lib/commonjs/web-system/AudioManager.js +1 -0
  48. package/lib/commonjs/web-system/AudioManager.js.map +1 -1
  49. package/lib/module/api.js +2 -3
  50. package/lib/module/api.js.map +1 -1
  51. package/lib/module/core/AudioDecoder.js +2 -2
  52. package/lib/module/core/AudioDecoder.js.map +1 -1
  53. package/lib/module/core/AudioRecorder.js +4 -5
  54. package/lib/module/core/AudioRecorder.js.map +1 -1
  55. package/lib/module/hooks/index.js +5 -0
  56. package/lib/module/hooks/index.js.map +1 -0
  57. package/lib/module/hooks/useAudioInput.js +66 -0
  58. package/lib/module/hooks/useAudioInput.js.map +1 -0
  59. package/lib/module/hooks/useSystemVolume.js +1 -1
  60. package/lib/module/hooks/useSystemVolume.js.map +1 -1
  61. package/lib/module/index.js +5 -0
  62. package/lib/module/index.js.map +1 -1
  63. package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
  64. package/lib/module/specs/NativeAudioAPIModule.web.js +1 -0
  65. package/lib/module/specs/NativeAudioAPIModule.web.js.map +1 -1
  66. package/lib/module/system/AudioManager.js +3 -0
  67. package/lib/module/system/AudioManager.js.map +1 -1
  68. package/lib/module/web-system/AudioManager.js +1 -0
  69. package/lib/module/web-system/AudioManager.js.map +1 -1
  70. package/lib/typescript/api.d.ts +2 -3
  71. package/lib/typescript/api.d.ts.map +1 -1
  72. package/lib/typescript/core/AudioDecoder.d.ts.map +1 -1
  73. package/lib/typescript/core/AudioRecorder.d.ts +2 -2
  74. package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
  75. package/lib/typescript/events/types.d.ts +6 -4
  76. package/lib/typescript/events/types.d.ts.map +1 -1
  77. package/lib/typescript/hooks/index.d.ts +3 -0
  78. package/lib/typescript/hooks/index.d.ts.map +1 -0
  79. package/lib/typescript/hooks/useAudioInput.d.ts +28 -0
  80. package/lib/typescript/hooks/useAudioInput.d.ts.map +1 -0
  81. package/lib/typescript/hooks/useSystemVolume.d.ts.map +1 -1
  82. package/lib/typescript/index.d.ts +1 -0
  83. package/lib/typescript/index.d.ts.map +1 -1
  84. package/lib/typescript/interfaces.d.ts +1 -1
  85. package/lib/typescript/interfaces.d.ts.map +1 -1
  86. package/lib/typescript/specs/NativeAudioAPIModule.d.ts +2 -1
  87. package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
  88. package/lib/typescript/specs/NativeAudioAPIModule.web.d.ts +1 -0
  89. package/lib/typescript/specs/NativeAudioAPIModule.web.d.ts.map +1 -1
  90. package/lib/typescript/system/AudioManager.d.ts +1 -0
  91. package/lib/typescript/system/AudioManager.d.ts.map +1 -1
  92. package/lib/typescript/system/types.d.ts +3 -1
  93. package/lib/typescript/system/types.d.ts.map +1 -1
  94. package/lib/typescript/types.d.ts +3 -0
  95. package/lib/typescript/types.d.ts.map +1 -1
  96. package/lib/typescript/web-system/AudioManager.d.ts +1 -0
  97. package/lib/typescript/web-system/AudioManager.d.ts.map +1 -1
  98. package/package.json +1 -1
  99. package/src/api.ts +5 -4
  100. package/src/core/AudioDecoder.ts +2 -2
  101. package/src/core/AudioRecorder.ts +5 -4
  102. package/src/events/types.ts +16 -12
  103. package/src/hooks/index.ts +2 -0
  104. package/src/hooks/useAudioInput.ts +93 -0
  105. package/src/hooks/useSystemVolume.ts +3 -2
  106. package/src/index.ts +5 -0
  107. package/src/interfaces.ts +1 -1
  108. package/src/specs/NativeAudioAPIModule.ts +2 -1
  109. package/src/specs/NativeAudioAPIModule.web.ts +2 -0
  110. package/src/system/AudioManager.ts +4 -0
  111. package/src/system/types.ts +3 -1
  112. package/src/types.ts +4 -0
  113. package/src/web-system/AudioManager.ts +1 -0
@@ -0,0 +1,93 @@
1
+ import { useCallback, useEffect, useMemo, useState } from 'react';
2
+
3
+ import { AudioManager } from '../api';
4
+ import { OnRouteChangeEventType, RouteChangeReason } from '../events/types';
5
+ import {
6
+ AudioDeviceInfo,
7
+ AudioDeviceList,
8
+ AudioDevicesInfo,
9
+ } from '../system/types';
10
+
11
+ const meaningfulReasons: RouteChangeReason[] = [
12
+ 'NewDeviceAvailable',
13
+ 'OldDeviceUnavailable',
14
+ // e.g. system picks a different device as current one is not suitable for the new configuration
15
+ 'CategoryChange',
16
+ 'ConfigurationChange',
17
+ ];
18
+
19
+ /**
20
+ * A hook that provides basic information and selection capabilities for audio
21
+ * input devices on the system. (iOS only currently). The hook will
22
+ * automatically listen for configuration changes and updates its state. If you
23
+ * need more granular control, consider using the AudioManager API directly.
24
+ *
25
+ * @returns An object containing audio input information and selection
26
+ * capabilities
27
+ */
28
+ export default function useAudioInput() {
29
+ const [availableInputs, setAvailableInputs] = useState<AudioDeviceList>([]);
30
+ const [currentInput, setCurrentInput] = useState<string | null>(null);
31
+
32
+ const onSelectInput = useCallback(async (device: AudioDeviceInfo) => {
33
+ const success = await AudioManager.setInputDevice(device.id);
34
+
35
+ if (success) {
36
+ setCurrentInput(device.id);
37
+ }
38
+
39
+ const devicesInfo: AudioDevicesInfo = await AudioManager.getDevicesInfo();
40
+ setAvailableInputs(devicesInfo.availableInputs);
41
+ }, []);
42
+
43
+ useEffect(() => {
44
+ async function fetchAvailableInputs() {
45
+ const audioDevices = await AudioManager.getDevicesInfo();
46
+ const currentDeviceId = audioDevices.currentInputs.length
47
+ ? audioDevices.currentInputs[0].id
48
+ : null;
49
+
50
+ setAvailableInputs(audioDevices.availableInputs);
51
+ setCurrentInput(currentDeviceId);
52
+ }
53
+
54
+ async function handleRouteChange(event: OnRouteChangeEventType) {
55
+ if (!meaningfulReasons.includes(event.reason)) {
56
+ return;
57
+ }
58
+
59
+ await fetchAvailableInputs();
60
+ }
61
+
62
+ const sub = AudioManager.addSystemEventListener(
63
+ 'routeChange',
64
+ handleRouteChange
65
+ );
66
+
67
+ fetchAvailableInputs();
68
+ return () => {
69
+ sub?.remove();
70
+ };
71
+ }, []);
72
+
73
+ return useMemo(
74
+ () => ({
75
+ /**
76
+ * The list of available audio input devices under current device
77
+ * configuration.
78
+ */
79
+ availableInputs,
80
+ /**
81
+ * The currently selected audio input device, or null if none is yet
82
+ * decided by the system.
83
+ */
84
+ currentInput: availableInputs.find((d) => d.id === currentInput) || null,
85
+ /**
86
+ * Selects the given device as the current input. Returns true if
87
+ * successful, throws otherwise.
88
+ */
89
+ onSelectInput,
90
+ }),
91
+ [availableInputs, currentInput, onSelectInput]
92
+ );
93
+ }
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
- import AudioManager from '../system/AudioManager';
2
+
3
+ import { AudioManager } from '../api';
3
4
 
4
5
  export default function useSystemVolume() {
5
6
  const [volume, setVolume] = useState(0);
@@ -12,9 +13,9 @@ export default function useSystemVolume() {
12
13
  setVolume(parseFloat(e.value.toFixed(2)));
13
14
  }
14
15
  );
16
+
15
17
  return () => {
16
18
  listener?.remove();
17
-
18
19
  AudioManager.observeVolumeChanges(false);
19
20
  };
20
21
  }, []);
package/src/index.ts CHANGED
@@ -1 +1,6 @@
1
1
  export * from './api';
2
+
3
+ // Note: hooks are (and always should!) rely only on imports from './api'
4
+ // to be able to use them both in RN and Web environments.
5
+ // Thus they can/have to be exported here.
6
+ export * from './hooks';
package/src/interfaces.ts CHANGED
@@ -304,7 +304,7 @@ export interface IAudioRecorderCallbackOptions
304
304
 
305
305
  export interface IAudioRecorder {
306
306
  // default recorder methods
307
- start: () => Result<{ path: string }>;
307
+ start: (fileNameOverride?: string) => Result<{ path: string }>;
308
308
  stop: () => Result<FileInfo>;
309
309
  isRecording: () => boolean;
310
310
  isPaused: () => boolean;
@@ -34,6 +34,7 @@ interface Spec extends TurboModule {
34
34
 
35
35
  // Audio devices
36
36
  getDevicesInfo(): Promise<AudioDevicesInfo>;
37
+ setInputDevice(deviceId: string): Promise<boolean>;
37
38
 
38
39
  // Notification system
39
40
  showNotification(
@@ -45,6 +46,6 @@ interface Spec extends TurboModule {
45
46
  isNotificationActive(key: string): Promise<boolean>;
46
47
  }
47
48
 
48
- const NativeAudioAPIModule = TurboModuleRegistry.get<Spec>('AudioAPIModule');
49
+ const NativeAudioAPIModule = TurboModuleRegistry.get<Spec>('AudioAPIModule')!;
49
50
 
50
51
  export { NativeAudioAPIModule };
@@ -35,6 +35,7 @@ interface Spec extends TurboModule {
35
35
 
36
36
  // Audio devices
37
37
  getDevicesInfo(): Promise<AudioDevicesInfo>;
38
+ setInputDevice(deviceId: string): Promise<boolean>;
38
39
 
39
40
  // New notification system
40
41
  showNotification(
@@ -74,6 +75,7 @@ const NativeAudioAPIModule: Spec = {
74
75
  currentInputs: [],
75
76
  currentOutputs: [],
76
77
  }),
78
+ setInputDevice: mockAsync(true),
77
79
  showNotification: mockAsync({ success: true }),
78
80
  hideNotification: mockAsync({ success: true }),
79
81
  isNotificationActive: mockAsync(false),
@@ -94,6 +94,10 @@ class AudioManager implements IAudioManager {
94
94
  async getDevicesInfo(): Promise<AudioDevicesInfo> {
95
95
  return NativeAudioAPIModule.getDevicesInfo();
96
96
  }
97
+
98
+ async setInputDevice(deviceId: string): Promise<boolean> {
99
+ return NativeAudioAPIModule.setInputDevice(deviceId);
100
+ }
97
101
  }
98
102
 
99
103
  export default new AudioManager();
@@ -24,8 +24,8 @@ export type IOSOption =
24
24
  | 'duckOthers'
25
25
  | 'allowAirPlay'
26
26
  | 'mixWithOthers'
27
- | 'allowBluetooth'
28
27
  | 'defaultToSpeaker'
28
+ | 'allowBluetoothHFP'
29
29
  | 'allowBluetoothA2DP'
30
30
  | 'overrideMutedMicrophoneInterruption'
31
31
  | 'interruptSpokenAudioAndMixWithOthers';
@@ -40,6 +40,7 @@ export interface SessionOptions {
40
40
  export type PermissionStatus = 'Undetermined' | 'Denied' | 'Granted';
41
41
 
42
42
  export interface AudioDeviceInfo {
43
+ id: string;
43
44
  name: string;
44
45
  category: string;
45
46
  }
@@ -70,4 +71,5 @@ export interface IAudioManager {
70
71
  requestNotificationPermissions(): Promise<PermissionStatus>;
71
72
  checkNotificationPermissions(): Promise<PermissionStatus>;
72
73
  getDevicesInfo(): Promise<AudioDevicesInfo>;
74
+ setInputDevice(deviceId: string): Promise<boolean>;
73
75
  }
package/src/types.ts CHANGED
@@ -151,3 +151,7 @@ export interface IIRFilterNodeOptions {
151
151
  }
152
152
 
153
153
  export type DecodeDataInput = number | string | ArrayBuffer;
154
+
155
+ export interface AudioRecorderStartOptions {
156
+ fileNameOverride?: string;
157
+ }
@@ -22,6 +22,7 @@ class AudioManager implements IAudioManager {
22
22
  checkRecordingPermissions = mockAsync('Granted' as PermissionStatus);
23
23
  requestNotificationPermissions = mockAsync('Granted' as PermissionStatus);
24
24
  checkNotificationPermissions = mockAsync('Granted' as PermissionStatus);
25
+ setInputDevice = mockAsync(true);
25
26
  getDevicesInfo = mockAsync({
26
27
  availableInputs: [],
27
28
  availableOutputs: [],