react-native-audio-api 0.6.0-rc.4 → 0.6.0
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.
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +35 -2
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +4 -0
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +31 -17
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +1 -3
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +56 -2
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +0 -12
- package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +35 -12
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +30 -29
- package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +20 -22
- package/android/src/main/java/com/swmansion/audioapi/system/MediaReceiver.kt +19 -9
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +30 -11
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +53 -26
- package/android/src/main/java/com/swmansion/audioapi/system/VolumeChangeListener.kt +10 -5
- package/android/src/oldarch/NativeAudioAPIModuleSpec.java +39 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +20 -14
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +2 -3
- package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h +24 -11
- package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +1 -0
- package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +10 -89
- package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +3 -24
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +2 -2
- package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +2 -3
- package/common/cpp/audioapi/core/AudioContext.cpp +4 -1
- package/common/cpp/audioapi/core/AudioContext.h +1 -1
- package/common/cpp/audioapi/core/AudioNode.cpp +31 -2
- package/common/cpp/audioapi/core/AudioNode.h +7 -1
- package/common/cpp/audioapi/core/AudioParam.cpp +84 -2
- package/common/cpp/audioapi/core/AudioParam.h +14 -1
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +7 -1
- package/common/cpp/audioapi/core/BaseAudioContext.h +7 -1
- package/common/cpp/audioapi/core/OfflineAudioContext.cpp +3 -2
- package/common/cpp/audioapi/core/OfflineAudioContext.h +1 -1
- package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +19 -56
- package/common/cpp/audioapi/core/analysis/AnalyserNode.h +3 -2
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +28 -26
- package/common/cpp/audioapi/core/effects/GainNode.cpp +9 -9
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +5 -2
- package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +56 -0
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +13 -13
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +14 -10
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +1 -1
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +7 -6
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +5 -3
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +15 -10
- package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +35 -1
- package/common/cpp/audioapi/core/utils/AudioNodeManager.h +15 -1
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +108 -0
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +62 -0
- package/common/cpp/audioapi/events/AudioEventHandlerRegistryHostObject.h +48 -0
- package/common/cpp/audioapi/jsi/JsiPromise.cpp +3 -4
- package/common/cpp/audioapi/utils/AudioArray.h +1 -1
- package/common/cpp/audioapi/utils/CircularAudioArray.cpp +94 -0
- package/common/cpp/audioapi/utils/CircularAudioArray.h +26 -0
- package/ios/audioapi/ios/AudioAPIModule.h +13 -0
- package/ios/audioapi/ios/AudioAPIModule.mm +115 -6
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +3 -10
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +15 -52
- package/ios/audioapi/ios/core/NativeAudioPlayer.m +2 -0
- package/ios/audioapi/ios/core/NativeAudioRecorder.m +7 -3
- package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.h +7 -0
- package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.mm +12 -0
- package/ios/audioapi/ios/system/AudioEngine.h +5 -0
- package/ios/audioapi/ios/system/AudioEngine.mm +7 -15
- package/ios/audioapi/ios/system/AudioSessionManager.h +3 -1
- package/ios/audioapi/ios/system/AudioSessionManager.mm +36 -17
- package/ios/audioapi/ios/system/LockScreenManager.h +3 -3
- package/ios/audioapi/ios/system/LockScreenManager.mm +36 -48
- package/ios/audioapi/ios/system/NotificationManager.h +3 -3
- package/ios/audioapi/ios/system/NotificationManager.mm +21 -29
- package/lib/commonjs/api.js +4 -4
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/AudioBufferSourceNode.js +2 -2
- package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/commonjs/core/AudioNode.js +8 -2
- package/lib/commonjs/core/AudioNode.js.map +1 -1
- package/lib/commonjs/core/AudioParam.js +2 -1
- package/lib/commonjs/core/AudioParam.js.map +1 -1
- package/lib/commonjs/core/AudioRecorder.js +11 -28
- package/lib/commonjs/core/AudioRecorder.js.map +1 -1
- package/lib/commonjs/core/AudioScheduledSourceNode.js +4 -1
- package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/commonjs/core/BiquadFilterNode.js +4 -4
- package/lib/commonjs/core/BiquadFilterNode.js.map +1 -1
- package/lib/commonjs/core/GainNode.js +1 -1
- package/lib/commonjs/core/GainNode.js.map +1 -1
- package/lib/commonjs/core/OscillatorNode.js +2 -2
- package/lib/commonjs/core/OscillatorNode.js.map +1 -1
- package/lib/commonjs/core/StereoPannerNode.js +1 -1
- package/lib/commonjs/core/StereoPannerNode.js.map +1 -1
- package/lib/commonjs/events/AudioEventEmitter.js +22 -0
- package/lib/commonjs/events/AudioEventEmitter.js.map +1 -0
- package/lib/commonjs/events/AudioEventSubscription.js +20 -0
- package/lib/commonjs/events/AudioEventSubscription.js.map +1 -0
- package/lib/commonjs/events/index.js +21 -0
- package/lib/commonjs/events/index.js.map +1 -0
- package/lib/commonjs/events/types.js +6 -0
- package/lib/commonjs/events/types.js.map +1 -0
- package/lib/commonjs/hooks/useSytemVolume.js +1 -1
- package/lib/commonjs/hooks/useSytemVolume.js.map +1 -1
- package/lib/commonjs/specs/NativeAudioAPIModule.js +3 -3
- package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/commonjs/specs/index.js +2 -16
- package/lib/commonjs/specs/index.js.map +1 -1
- package/lib/commonjs/system/AudioManager.js +26 -26
- package/lib/commonjs/system/AudioManager.js.map +1 -1
- package/lib/module/api.js +2 -2
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +2 -2
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioNode.js +7 -2
- package/lib/module/core/AudioNode.js.map +1 -1
- package/lib/module/core/AudioParam.js +2 -1
- package/lib/module/core/AudioParam.js.map +1 -1
- package/lib/module/core/AudioRecorder.js +11 -28
- package/lib/module/core/AudioRecorder.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +4 -1
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/core/BiquadFilterNode.js +4 -4
- package/lib/module/core/BiquadFilterNode.js.map +1 -1
- package/lib/module/core/GainNode.js +1 -1
- package/lib/module/core/GainNode.js.map +1 -1
- package/lib/module/core/OscillatorNode.js +2 -2
- package/lib/module/core/OscillatorNode.js.map +1 -1
- package/lib/module/core/StereoPannerNode.js +1 -1
- package/lib/module/core/StereoPannerNode.js.map +1 -1
- package/lib/module/events/AudioEventEmitter.js +16 -0
- package/lib/module/events/AudioEventEmitter.js.map +1 -0
- package/lib/module/events/AudioEventSubscription.js +15 -0
- package/lib/module/events/AudioEventSubscription.js.map +1 -0
- package/lib/module/events/index.js +6 -0
- package/lib/module/events/index.js.map +1 -0
- package/lib/module/events/types.js +4 -0
- package/lib/module/events/types.js.map +1 -0
- package/lib/module/hooks/useSytemVolume.js +1 -1
- package/lib/module/hooks/useSytemVolume.js.map +1 -1
- package/lib/module/specs/NativeAudioAPIModule.js +3 -2
- package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/module/specs/index.js +2 -3
- package/lib/module/specs/index.js.map +1 -1
- package/lib/module/system/AudioManager.js +27 -27
- package/lib/module/system/AudioManager.js.map +1 -1
- package/lib/typescript/api.d.ts +2 -1
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/AudioNode.d.ts +2 -1
- package/lib/typescript/core/AudioNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioParam.d.ts +4 -2
- package/lib/typescript/core/AudioParam.d.ts.map +1 -1
- package/lib/typescript/core/AudioRecorder.d.ts +4 -14
- package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +3 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/events/AudioEventEmitter.d.ts +10 -0
- package/lib/typescript/events/AudioEventEmitter.d.ts.map +1 -0
- package/lib/typescript/events/AudioEventSubscription.d.ts +11 -0
- package/lib/typescript/events/AudioEventSubscription.d.ts.map +1 -0
- package/lib/typescript/events/index.d.ts +4 -0
- package/lib/typescript/events/index.d.ts.map +1 -0
- package/lib/typescript/events/types.d.ts +50 -0
- package/lib/typescript/events/types.d.ts.map +1 -0
- package/lib/typescript/hooks/useSytemVolume.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +10 -10
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts +15 -3
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
- package/lib/typescript/specs/index.d.ts +2 -3
- package/lib/typescript/specs/index.d.ts.map +1 -1
- package/lib/typescript/system/AudioManager.d.ts +8 -4
- package/lib/typescript/system/AudioManager.d.ts.map +1 -1
- package/lib/typescript/system/types.d.ts +1 -34
- package/lib/typescript/system/types.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +0 -1
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/api.ts +6 -3
- package/src/core/AudioBufferSourceNode.ts +2 -2
- package/src/core/AudioNode.ts +8 -3
- package/src/core/AudioParam.ts +5 -2
- package/src/core/AudioRecorder.ts +22 -62
- package/src/core/AudioScheduledSourceNode.ts +13 -2
- package/src/core/BiquadFilterNode.ts +4 -4
- package/src/core/GainNode.ts +1 -1
- package/src/core/OscillatorNode.ts +2 -2
- package/src/core/StereoPannerNode.ts +1 -1
- package/src/events/AudioEventEmitter.ts +29 -0
- package/src/events/AudioEventSubscription.ts +26 -0
- package/src/events/index.ts +4 -0
- package/src/events/types.ts +64 -0
- package/src/hooks/useSytemVolume.ts +2 -1
- package/src/interfaces.ts +19 -20
- package/src/specs/NativeAudioAPIModule.ts +23 -2
- package/src/specs/index.ts +2 -4
- package/src/system/AudioManager.ts +39 -38
- package/src/system/types.ts +1 -41
- package/src/types.ts +0 -8
- package/android/src/main/java/com/swmansion/audioapi/AudioManagerModule.kt +0 -64
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionEventEmitter.kt +0 -88
- package/android/src/oldarch/NativeAudioManagerModuleSpec.java +0 -99
- package/ios/audioapi/ios/AudioManagerModule.h +0 -18
- package/ios/audioapi/ios/AudioManagerModule.mm +0 -93
- package/lib/commonjs/specs/NativeAudioManagerModule.js +0 -36
- package/lib/commonjs/specs/NativeAudioManagerModule.js.map +0 -1
- package/lib/module/specs/NativeAudioManagerModule.js +0 -33
- package/lib/module/specs/NativeAudioManagerModule.js.map +0 -1
- package/lib/typescript/specs/NativeAudioManagerModule.d.ts +0 -15
- package/lib/typescript/specs/NativeAudioManagerModule.d.ts.map +0 -1
- package/src/specs/NativeAudioManagerModule.ts +0 -45
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AudioEventName, AudioEventCallback } from './types';
|
|
2
|
+
import AudioEventSubscription from './AudioEventSubscription';
|
|
3
|
+
import { IAudioEventEmitter } from '../interfaces';
|
|
4
|
+
|
|
5
|
+
export default class AudioEventEmitter {
|
|
6
|
+
private readonly audioEventEmitter: IAudioEventEmitter;
|
|
7
|
+
|
|
8
|
+
constructor(audioEventEmitter: IAudioEventEmitter) {
|
|
9
|
+
this.audioEventEmitter = audioEventEmitter;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
addAudioEventListener<Name extends AudioEventName>(
|
|
13
|
+
name: Name,
|
|
14
|
+
callback: AudioEventCallback<Name>
|
|
15
|
+
): AudioEventSubscription {
|
|
16
|
+
const subscriptionId = this.audioEventEmitter.addAudioEventListener(
|
|
17
|
+
name,
|
|
18
|
+
callback
|
|
19
|
+
);
|
|
20
|
+
return new AudioEventSubscription(subscriptionId, name, this);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
removeAudioEventListener<Name extends AudioEventName>(
|
|
24
|
+
name: Name,
|
|
25
|
+
subscriptionId: string
|
|
26
|
+
): void {
|
|
27
|
+
this.audioEventEmitter.removeAudioEventListener(name, subscriptionId);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AudioEventName } from './types';
|
|
2
|
+
import { AudioEventEmitter } from './';
|
|
3
|
+
|
|
4
|
+
export default class AudioEventSubscription {
|
|
5
|
+
private readonly audioEventEmitter: AudioEventEmitter;
|
|
6
|
+
private readonly eventName: AudioEventName;
|
|
7
|
+
/** @internal */
|
|
8
|
+
public readonly subscriptionId: string;
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
subscriptionId: string,
|
|
12
|
+
eventName: AudioEventName,
|
|
13
|
+
audioEventEmitter: AudioEventEmitter
|
|
14
|
+
) {
|
|
15
|
+
this.subscriptionId = subscriptionId;
|
|
16
|
+
this.eventName = eventName;
|
|
17
|
+
this.audioEventEmitter = audioEventEmitter;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public remove(): void {
|
|
21
|
+
this.audioEventEmitter.removeAudioEventListener(
|
|
22
|
+
this.eventName,
|
|
23
|
+
this.subscriptionId
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import AudioBuffer from '../core/AudioBuffer';
|
|
2
|
+
|
|
3
|
+
interface EventEmptyType {}
|
|
4
|
+
|
|
5
|
+
export interface EventTypeWithValue {
|
|
6
|
+
value: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface OnInterruptionEventType {
|
|
10
|
+
type: 'ended' | 'began';
|
|
11
|
+
shouldResume: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface OnRouteChangeEventType {
|
|
15
|
+
reason: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface SystemEvents {
|
|
19
|
+
remotePlay: EventEmptyType;
|
|
20
|
+
remotePause: EventEmptyType;
|
|
21
|
+
remoteStop: EventEmptyType;
|
|
22
|
+
remoteTogglePlayPause: EventEmptyType;
|
|
23
|
+
remoteChangePlaybackRate: EventTypeWithValue;
|
|
24
|
+
remoteNextTrack: EventEmptyType;
|
|
25
|
+
remotePreviousTrack: EventEmptyType;
|
|
26
|
+
remoteSkipForward: EventEmptyType;
|
|
27
|
+
remoteSkipBackward: EventEmptyType;
|
|
28
|
+
remoteSeekForward: EventTypeWithValue;
|
|
29
|
+
remoteSeekBackward: EventTypeWithValue;
|
|
30
|
+
remoteChangePlaybackPosition: EventTypeWithValue;
|
|
31
|
+
volumeChange: EventTypeWithValue;
|
|
32
|
+
interruption: OnInterruptionEventType;
|
|
33
|
+
routeChange: OnRouteChangeEventType;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface OnAudioReadyEventType {
|
|
37
|
+
buffer: AudioBuffer;
|
|
38
|
+
numFrames: number;
|
|
39
|
+
when: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface AudioAPIEvents {
|
|
43
|
+
ended: EventTypeWithValue;
|
|
44
|
+
audioReady: OnAudioReadyEventType;
|
|
45
|
+
audioError: EventEmptyType; // to change
|
|
46
|
+
systemStateChanged: EventEmptyType; // to change
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type AudioEvents = SystemEvents & AudioAPIEvents;
|
|
50
|
+
|
|
51
|
+
export type SystemEventName = keyof SystemEvents;
|
|
52
|
+
export type SystemEventCallback<Name extends SystemEventName> = (
|
|
53
|
+
event: SystemEvents[Name]
|
|
54
|
+
) => void;
|
|
55
|
+
|
|
56
|
+
export type AudioAPIEventName = keyof AudioAPIEvents;
|
|
57
|
+
export type AudioAPIEventCallback<Name extends AudioAPIEventName> = (
|
|
58
|
+
event: AudioAPIEvents[Name]
|
|
59
|
+
) => void;
|
|
60
|
+
|
|
61
|
+
export type AudioEventName = keyof AudioEvents;
|
|
62
|
+
export type AudioEventCallback<Name extends AudioEventName> = (
|
|
63
|
+
event: AudioEvents[Name]
|
|
64
|
+
) => void;
|
|
@@ -6,11 +6,12 @@ export default function useSystemVolume() {
|
|
|
6
6
|
|
|
7
7
|
useEffect(() => {
|
|
8
8
|
AudioManager.observeVolumeChanges(true);
|
|
9
|
-
const listener = AudioManager.
|
|
9
|
+
const listener = AudioManager.enableSystemEvent('volumeChange', (e) => {
|
|
10
10
|
setVolume(parseFloat(e.value.toFixed(2)));
|
|
11
11
|
});
|
|
12
12
|
return () => {
|
|
13
13
|
listener?.remove();
|
|
14
|
+
|
|
14
15
|
AudioManager.observeVolumeChanges(false);
|
|
15
16
|
};
|
|
16
17
|
}, []);
|
package/src/interfaces.ts
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
OscillatorType,
|
|
5
5
|
BiquadFilterType,
|
|
6
6
|
ChannelCountMode,
|
|
7
|
-
AudioRecorderStatus,
|
|
8
7
|
ChannelInterpretation,
|
|
9
8
|
} from './types';
|
|
9
|
+
import { AudioEventName, AudioEventCallback } from './events/types';
|
|
10
10
|
|
|
11
11
|
export interface IBaseAudioContext {
|
|
12
12
|
readonly destination: IAudioDestinationNode;
|
|
@@ -54,8 +54,8 @@ export interface IAudioNode {
|
|
|
54
54
|
readonly channelCountMode: ChannelCountMode;
|
|
55
55
|
readonly channelInterpretation: ChannelInterpretation;
|
|
56
56
|
|
|
57
|
-
connect: (
|
|
58
|
-
disconnect: (
|
|
57
|
+
connect: (destination: IAudioNode | IAudioParam) => void;
|
|
58
|
+
disconnect: (destination?: IAudioNode | IAudioParam) => void;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
export interface IGainNode extends IAudioNode {
|
|
@@ -85,7 +85,9 @@ export interface IAudioDestinationNode extends IAudioNode {}
|
|
|
85
85
|
export interface IAudioScheduledSourceNode extends IAudioNode {
|
|
86
86
|
start(when?: number): void;
|
|
87
87
|
stop: (when: number) => void;
|
|
88
|
-
|
|
88
|
+
|
|
89
|
+
// passing subscriptionId(uint_64 in cpp, string in js) to the cpp
|
|
90
|
+
onended: string;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
export interface IOscillatorNode extends IAudioScheduledSourceNode {
|
|
@@ -165,24 +167,21 @@ export interface IAnalyserNode extends IAudioNode {
|
|
|
165
167
|
getByteTimeDomainData: (array: Uint8Array) => void;
|
|
166
168
|
}
|
|
167
169
|
|
|
168
|
-
export type IAudioReadyCallback = (
|
|
169
|
-
buffer: IAudioBuffer,
|
|
170
|
-
numFrames: number,
|
|
171
|
-
when: number
|
|
172
|
-
) => void;
|
|
173
|
-
|
|
174
|
-
export type IErrorCallback = (error: Error) => void;
|
|
175
|
-
|
|
176
|
-
export type IStatusChangeCallback = (
|
|
177
|
-
status: AudioRecorderStatus,
|
|
178
|
-
previousStatus: AudioRecorderStatus
|
|
179
|
-
) => void;
|
|
180
|
-
|
|
181
170
|
export interface IAudioRecorder {
|
|
182
171
|
start: () => void;
|
|
183
172
|
stop: () => void;
|
|
184
173
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
174
|
+
// passing subscriptionId(uint_64 in cpp, string in js) to the cpp
|
|
175
|
+
onAudioReady: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface IAudioEventEmitter {
|
|
179
|
+
addAudioEventListener<Name extends AudioEventName>(
|
|
180
|
+
name: Name,
|
|
181
|
+
callback: AudioEventCallback<Name>
|
|
182
|
+
): string;
|
|
183
|
+
removeAudioEventListener<Name extends AudioEventName>(
|
|
184
|
+
name: Name,
|
|
185
|
+
subscriptionId: string
|
|
186
|
+
): void;
|
|
188
187
|
}
|
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
3
|
+
import type { TurboModule } from 'react-native';
|
|
4
|
+
import { PermissionStatus } from '../system/types';
|
|
2
5
|
|
|
3
6
|
interface Spec extends TurboModule {
|
|
4
7
|
install(): boolean;
|
|
8
|
+
|
|
9
|
+
setLockScreenInfo(info: {
|
|
10
|
+
[key: string]: string | boolean | number | undefined;
|
|
11
|
+
}): void;
|
|
12
|
+
resetLockScreenInfo(): void;
|
|
13
|
+
enableRemoteCommand(name: string, enabled: boolean): void;
|
|
14
|
+
setAudioSessionOptions(
|
|
15
|
+
category: string,
|
|
16
|
+
mode: string,
|
|
17
|
+
options: Array<string>
|
|
18
|
+
): void;
|
|
19
|
+
getDevicePreferredSampleRate(): number;
|
|
20
|
+
observeAudioInterruptions(enabled: boolean): void;
|
|
21
|
+
observeVolumeChanges(enabled: boolean): void;
|
|
22
|
+
requestRecordingPermissions(): Promise<PermissionStatus>;
|
|
23
|
+
checkRecordingPermissions(): Promise<PermissionStatus>;
|
|
5
24
|
}
|
|
6
25
|
|
|
7
|
-
|
|
26
|
+
const NativeAudioAPIModule = TurboModuleRegistry.get<Spec>('AudioAPIModule');
|
|
27
|
+
|
|
28
|
+
export { NativeAudioAPIModule };
|
package/src/specs/index.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
import { NativeAudioAPIModule } from './NativeAudioAPIModule';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
import { AudioManagerModule, eventEmitter } from './NativeAudioManagerModule';
|
|
5
|
-
|
|
6
|
-
export { NativeAudioAPIModule, AudioManagerModule, eventEmitter };
|
|
4
|
+
export { NativeAudioAPIModule };
|
|
@@ -1,24 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { SessionOptions, LockScreenInfo, PermissionStatus } from './types';
|
|
2
|
+
import { SystemEventName, SystemEventCallback } from '../events/types';
|
|
3
|
+
import { NativeAudioAPIModule } from '../specs';
|
|
4
|
+
import { AudioEventEmitter, AudioEventSubscription } from '../events';
|
|
5
|
+
|
|
6
|
+
if (global.AudioEventEmitter == null) {
|
|
7
|
+
if (!NativeAudioAPIModule) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`Failed to install react-native-audio-api: The native module could not be found.`
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
NativeAudioAPIModule.install();
|
|
14
|
+
}
|
|
10
15
|
|
|
11
16
|
class AudioManager {
|
|
17
|
+
private readonly audioEventEmitter: AudioEventEmitter;
|
|
18
|
+
constructor() {
|
|
19
|
+
this.audioEventEmitter = new AudioEventEmitter(global.AudioEventEmitter);
|
|
20
|
+
}
|
|
21
|
+
|
|
12
22
|
setLockScreenInfo(info: LockScreenInfo) {
|
|
13
|
-
|
|
23
|
+
NativeAudioAPIModule!.setLockScreenInfo(info);
|
|
14
24
|
}
|
|
15
25
|
|
|
16
26
|
resetLockScreenInfo() {
|
|
17
|
-
|
|
27
|
+
NativeAudioAPIModule!.resetLockScreenInfo();
|
|
18
28
|
}
|
|
19
29
|
|
|
20
30
|
setAudioSessionOptions(options: SessionOptions) {
|
|
21
|
-
|
|
31
|
+
NativeAudioAPIModule!.setAudioSessionOptions(
|
|
22
32
|
options.iosCategory ?? '',
|
|
23
33
|
options.iosMode ?? '',
|
|
24
34
|
options.iosOptions ?? []
|
|
@@ -26,46 +36,37 @@ class AudioManager {
|
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
getDevicePreferredSampleRate(): number {
|
|
29
|
-
return
|
|
39
|
+
return NativeAudioAPIModule!.getDevicePreferredSampleRate();
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
observeAudioInterruptions(enabled: boolean) {
|
|
33
|
-
|
|
43
|
+
NativeAudioAPIModule!.observeAudioInterruptions(enabled);
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
observeVolumeChanges(enabled: boolean) {
|
|
37
|
-
|
|
47
|
+
NativeAudioAPIModule!.observeVolumeChanges(enabled);
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
AudioManagerModule.enableRemoteCommand(name, true);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
enableRemoteEvent<Name extends RemoteEventName>(
|
|
50
|
+
enableSystemEvent<Name extends SystemEventName>(
|
|
45
51
|
name: Name,
|
|
46
|
-
callback?:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
callback?: SystemEventCallback<Name>,
|
|
53
|
+
enabled = true
|
|
54
|
+
): AudioEventSubscription | null {
|
|
55
|
+
NativeAudioAPIModule!.enableRemoteCommand(name, enabled);
|
|
56
|
+
|
|
57
|
+
if (!enabled || !callback) {
|
|
50
58
|
return null;
|
|
51
59
|
}
|
|
52
|
-
switch (name) {
|
|
53
|
-
case 'interruption':
|
|
54
|
-
subscription = eventEmitter.addListener('onInterruption', callback);
|
|
55
|
-
break;
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
break;
|
|
61
|
+
return this.audioEventEmitter.addAudioEventListener(name, callback);
|
|
62
|
+
}
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
async requestRecordingPermissions(): Promise<PermissionStatus> {
|
|
65
|
+
return NativeAudioAPIModule!.requestRecordingPermissions();
|
|
66
|
+
}
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
return subscription;
|
|
68
|
+
async checkRecordingPermissions(): Promise<PermissionStatus> {
|
|
69
|
+
return NativeAudioAPIModule!.checkRecordingPermissions();
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
package/src/system/types.ts
CHANGED
|
@@ -51,44 +51,4 @@ export interface LockScreenInfo extends BaseLockScreenInfo {
|
|
|
51
51
|
elapsedTime?: number;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
interface RemoteControlEventType {
|
|
57
|
-
value: number;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
interface OnInterruptionEventType {
|
|
61
|
-
type: 'ended' | 'began';
|
|
62
|
-
shouldResume: boolean;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
interface OnRouteChangeEventType {
|
|
66
|
-
reason: string;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
interface RemoteCommands {
|
|
70
|
-
play: RemoteEmptyType;
|
|
71
|
-
pause: RemoteEmptyType;
|
|
72
|
-
stop: RemoteEmptyType;
|
|
73
|
-
togglePlayPause: RemoteEmptyType;
|
|
74
|
-
changePlaybackRate: RemoteEmptyType;
|
|
75
|
-
nextTrack: RemoteEmptyType;
|
|
76
|
-
previousTrack: RemoteEmptyType;
|
|
77
|
-
skipForward: RemoteEmptyType;
|
|
78
|
-
skipBackward: RemoteEmptyType;
|
|
79
|
-
seekForward: RemoteEmptyType;
|
|
80
|
-
seekBackward: RemoteEmptyType;
|
|
81
|
-
changePlaybackPosition: RemoteEmptyType;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
interface RemoteEvents {
|
|
85
|
-
volumeChange: RemoteControlEventType;
|
|
86
|
-
interruption: OnInterruptionEventType;
|
|
87
|
-
routeChange: OnRouteChangeEventType;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export type RemoteCommandName = keyof RemoteCommands;
|
|
91
|
-
export type RemoteEventName = keyof RemoteEvents;
|
|
92
|
-
export type RemoteEventCallback<Name extends RemoteEventName> = (
|
|
93
|
-
event: RemoteEvents[Name]
|
|
94
|
-
) => void;
|
|
54
|
+
export type PermissionStatus = 'Undetermined' | 'Denied' | 'Granted';
|
package/src/types.ts
CHANGED
|
@@ -45,11 +45,3 @@ export type WindowType = 'blackman' | 'hann';
|
|
|
45
45
|
export interface AudioBufferSourceNodeOptions {
|
|
46
46
|
pitchCorrection: boolean;
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
export type AudioRecorderStatus =
|
|
50
|
-
| 'idle'
|
|
51
|
-
| 'initializing'
|
|
52
|
-
| 'ready'
|
|
53
|
-
| 'running'
|
|
54
|
-
| 'stopping'
|
|
55
|
-
| 'error';
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
package com.swmansion.audioapi
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
-
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
5
|
-
import com.facebook.react.bridge.ReactMethod
|
|
6
|
-
import com.facebook.react.bridge.ReadableArray
|
|
7
|
-
import com.facebook.react.bridge.ReadableMap
|
|
8
|
-
import com.swmansion.audioapi.system.MediaSessionManager
|
|
9
|
-
|
|
10
|
-
class AudioManagerModule(
|
|
11
|
-
reactContext: ReactApplicationContext,
|
|
12
|
-
) : ReactContextBaseJavaModule(reactContext) {
|
|
13
|
-
companion object {
|
|
14
|
-
const val NAME = "AudioManagerModule"
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
init {
|
|
18
|
-
try {
|
|
19
|
-
System.loadLibrary("react-native-audio-api")
|
|
20
|
-
} catch (exception: UnsatisfiedLinkError) {
|
|
21
|
-
throw RuntimeException("Could not load native module AudioAPIModule", exception)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
MediaSessionManager.initialize(reactContext)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
28
|
-
fun setLockScreenInfo(info: ReadableMap?) {
|
|
29
|
-
MediaSessionManager.setLockScreenInfo(info)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
33
|
-
fun resetLockScreenInfo() {
|
|
34
|
-
MediaSessionManager.resetLockScreenInfo()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
38
|
-
fun enableRemoteCommand(
|
|
39
|
-
name: String,
|
|
40
|
-
enabled: Boolean,
|
|
41
|
-
) {
|
|
42
|
-
MediaSessionManager.enableRemoteCommand(name, enabled)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
46
|
-
fun setAudioSessionOptions(
|
|
47
|
-
category: String?,
|
|
48
|
-
mode: String?,
|
|
49
|
-
options: ReadableArray?,
|
|
50
|
-
) {
|
|
51
|
-
// Nothing to do here
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
55
|
-
fun getDevicePreferredSampleRate(): Double = MediaSessionManager.getDevicePreferredSampleRate()
|
|
56
|
-
|
|
57
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
58
|
-
fun observeAudioInterruptions(enable: Boolean) = MediaSessionManager.observeAudioInterruptions(enable)
|
|
59
|
-
|
|
60
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
61
|
-
fun observeVolumeChanges(enable: Boolean) = MediaSessionManager.observeVolumeChanges(enable)
|
|
62
|
-
|
|
63
|
-
override fun getName(): String = NAME
|
|
64
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
package com.swmansion.audioapi.system
|
|
2
|
-
|
|
3
|
-
import android.content.Intent
|
|
4
|
-
import android.os.Build
|
|
5
|
-
import androidx.core.app.NotificationManagerCompat
|
|
6
|
-
import com.facebook.react.bridge.Arguments
|
|
7
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
9
|
-
|
|
10
|
-
class MediaSessionEventEmitter(
|
|
11
|
-
val reactContext: ReactApplicationContext,
|
|
12
|
-
val notificationId: Int,
|
|
13
|
-
) {
|
|
14
|
-
fun sendEvent(
|
|
15
|
-
name: String,
|
|
16
|
-
values: Map<String, Any>?,
|
|
17
|
-
) {
|
|
18
|
-
val data = Arguments.createMap()
|
|
19
|
-
|
|
20
|
-
if (values != null) {
|
|
21
|
-
for (value in values) {
|
|
22
|
-
when (value.value) {
|
|
23
|
-
is Double, is Float -> {
|
|
24
|
-
data.putDouble(value.key, value.value as Double)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
is Boolean -> {
|
|
28
|
-
data.putBoolean(value.key, value.value as Boolean)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
is Int -> {
|
|
32
|
-
data.putInt(value.key, value.value as Int)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
reactContext
|
|
39
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
40
|
-
.emit(name, data)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
fun onPlay() {
|
|
44
|
-
sendEvent("onRemotePlay", null)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
fun onPause() {
|
|
48
|
-
sendEvent("onRemotePause", null)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
fun onStop() {
|
|
52
|
-
stopForegroundService()
|
|
53
|
-
sendEvent("onRemoteStop", null)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
fun onSkipToNext() {
|
|
57
|
-
sendEvent("onRemoteNextTrack", null)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
fun onSkipToPrevious() {
|
|
61
|
-
sendEvent("onRemotePreviousTrack", null)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
fun onFastForward() {
|
|
65
|
-
sendEvent("onRemoteSkipForward", null)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
fun onRewind() {
|
|
69
|
-
sendEvent("onRemoteSkipBackward", null)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
fun onInterruption(values: Map<String, Any>) {
|
|
73
|
-
sendEvent("onInterruption", values)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
fun onVolumeChange(values: Map<String, Number>) {
|
|
77
|
-
sendEvent("onVolumeChange", values)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
private fun stopForegroundService() {
|
|
81
|
-
NotificationManagerCompat.from(reactContext).cancel(notificationId)
|
|
82
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
83
|
-
val myIntent =
|
|
84
|
-
Intent(reactContext, MediaNotificationManager.NotificationService::class.java)
|
|
85
|
-
reactContext.stopService(myIntent)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
4
|
-
*
|
|
5
|
-
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
6
|
-
* once the code is regenerated.
|
|
7
|
-
*
|
|
8
|
-
* @generated by codegen project: GenerateModuleJavaSpec.js
|
|
9
|
-
*
|
|
10
|
-
* @nolint
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
package com.swmansion.audioapi;
|
|
14
|
-
|
|
15
|
-
import com.facebook.proguard.annotations.DoNotStrip;
|
|
16
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
17
|
-
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
18
|
-
import com.facebook.react.bridge.ReactMethod;
|
|
19
|
-
import com.facebook.react.bridge.ReadableArray;
|
|
20
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
21
|
-
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
|
22
|
-
import javax.annotation.Nonnull;
|
|
23
|
-
|
|
24
|
-
public abstract class NativeAudioManagerModuleSpec extends ReactContextBaseJavaModule implements TurboModule {
|
|
25
|
-
public static final String NAME = "AudioManagerModule";
|
|
26
|
-
|
|
27
|
-
public NativeAudioManagerModuleSpec(ReactApplicationContext reactContext) {
|
|
28
|
-
super(reactContext);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@Override
|
|
32
|
-
public @Nonnull String getName() {
|
|
33
|
-
return NAME;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
protected final void emitOnRemotePlay() {
|
|
37
|
-
mEventEmitterCallback.invoke("onRemotePlay");
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
protected final void emitOnRemotePause() {
|
|
41
|
-
mEventEmitterCallback.invoke("onRemotePause");
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
protected final void emitOnStop() {
|
|
45
|
-
mEventEmitterCallback.invoke("onStop");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
protected final void emitOnTogglePlayPause() {
|
|
49
|
-
mEventEmitterCallback.invoke("onTogglePlayPause");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
protected final void emitOnChangePlaybackRate(double value) {
|
|
53
|
-
mEventEmitterCallback.invoke("onChangePlaybackRate", value);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
protected final void emitOnNextTrack() {
|
|
57
|
-
mEventEmitterCallback.invoke("onNextTrack");
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
protected final void emitOnPreviousTrack() {
|
|
61
|
-
mEventEmitterCallback.invoke("onPreviousTrack");
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
protected final void emitOnSkipForward(double value) {
|
|
65
|
-
mEventEmitterCallback.invoke("onSkipForward", value);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
protected final void emitOnSkipBackward(double value) {
|
|
69
|
-
mEventEmitterCallback.invoke("onSkipBackward", value);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
protected final void emitOnSeekForward() {
|
|
73
|
-
mEventEmitterCallback.invoke("onSeekForward");
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
protected final void emitOnSeekBackward() {
|
|
77
|
-
mEventEmitterCallback.invoke("onSeekBackward");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
protected final void emitOnChangePlaybackPosition(double value) {
|
|
81
|
-
mEventEmitterCallback.invoke("onChangePlaybackPosition", value);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
@ReactMethod
|
|
85
|
-
@DoNotStrip
|
|
86
|
-
public abstract void setLockScreenInfo(ReadableMap info);
|
|
87
|
-
|
|
88
|
-
@ReactMethod
|
|
89
|
-
@DoNotStrip
|
|
90
|
-
public abstract void resetLockScreenInfo();
|
|
91
|
-
|
|
92
|
-
@ReactMethod
|
|
93
|
-
@DoNotStrip
|
|
94
|
-
public abstract void setSessionOptions(String category, String mode, ReadableArray options);
|
|
95
|
-
|
|
96
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
97
|
-
@DoNotStrip
|
|
98
|
-
public abstract double getDevicePreferredSampleRate();
|
|
99
|
-
}
|