@symbiote-native/audio 0.1.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.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/build/angular/index.d.ts +1 -0
  4. package/build/angular/index.js +4 -0
  5. package/build/core/audio-module.d.ts +26 -0
  6. package/build/core/audio-module.js +64 -0
  7. package/build/core/audio-player.d.ts +13 -0
  8. package/build/core/audio-player.js +31 -0
  9. package/build/core/audio-playlist.d.ts +8 -0
  10. package/build/core/audio-playlist.js +14 -0
  11. package/build/core/audio-recorder.d.ts +5 -0
  12. package/build/core/audio-recorder.js +40 -0
  13. package/build/core/audio-stream.d.ts +13 -0
  14. package/build/core/audio-stream.js +16 -0
  15. package/build/core/index.d.ts +9 -0
  16. package/build/core/index.js +8 -0
  17. package/build/core/native-module.d.ts +134 -0
  18. package/build/core/native-module.js +2 -0
  19. package/build/core/recording-presets.d.ts +50 -0
  20. package/build/core/recording-presets.js +94 -0
  21. package/build/core/resolve-source.d.ts +10 -0
  22. package/build/core/resolve-source.js +31 -0
  23. package/build/core/types.d.ts +218 -0
  24. package/build/core/types.js +8 -0
  25. package/build-ngc/angular/index.d.ts +1 -0
  26. package/build-ngc/angular/index.js +5 -0
  27. package/build-ngc/angular/index.js.map +1 -0
  28. package/build-ngc/core/audio-module.d.ts +26 -0
  29. package/build-ngc/core/audio-module.js +65 -0
  30. package/build-ngc/core/audio-module.js.map +1 -0
  31. package/build-ngc/core/audio-player.d.ts +13 -0
  32. package/build-ngc/core/audio-player.js +32 -0
  33. package/build-ngc/core/audio-player.js.map +1 -0
  34. package/build-ngc/core/audio-playlist.d.ts +8 -0
  35. package/build-ngc/core/audio-playlist.js +15 -0
  36. package/build-ngc/core/audio-playlist.js.map +1 -0
  37. package/build-ngc/core/audio-recorder.d.ts +5 -0
  38. package/build-ngc/core/audio-recorder.js +41 -0
  39. package/build-ngc/core/audio-recorder.js.map +1 -0
  40. package/build-ngc/core/audio-stream.d.ts +13 -0
  41. package/build-ngc/core/audio-stream.js +17 -0
  42. package/build-ngc/core/audio-stream.js.map +1 -0
  43. package/build-ngc/core/index.d.ts +9 -0
  44. package/build-ngc/core/index.js +9 -0
  45. package/build-ngc/core/index.js.map +1 -0
  46. package/build-ngc/core/native-module.d.ts +134 -0
  47. package/build-ngc/core/native-module.js +3 -0
  48. package/build-ngc/core/native-module.js.map +1 -0
  49. package/build-ngc/core/recording-presets.d.ts +50 -0
  50. package/build-ngc/core/recording-presets.js +95 -0
  51. package/build-ngc/core/recording-presets.js.map +1 -0
  52. package/build-ngc/core/resolve-source.d.ts +10 -0
  53. package/build-ngc/core/resolve-source.js +32 -0
  54. package/build-ngc/core/resolve-source.js.map +1 -0
  55. package/build-ngc/core/types.d.ts +218 -0
  56. package/build-ngc/core/types.js +9 -0
  57. package/build-ngc/core/types.js.map +1 -0
  58. package/native-link.json +47 -0
  59. package/package.json +150 -0
  60. package/src/angular/index.ts +4 -0
  61. package/src/core/audio-module.ts +82 -0
  62. package/src/core/audio-player.ts +53 -0
  63. package/src/core/audio-playlist.ts +20 -0
  64. package/src/core/audio-recorder.ts +46 -0
  65. package/src/core/audio-stream.ts +22 -0
  66. package/src/core/index.ts +62 -0
  67. package/src/core/native-module.ts +181 -0
  68. package/src/core/recording-presets.ts +99 -0
  69. package/src/core/resolve-source.ts +41 -0
  70. package/src/core/types.ts +282 -0
@@ -0,0 +1,134 @@
1
+ import { SharedObject } from 'expo-modules-core';
2
+ import type { PermissionResponse } from 'expo-modules-core';
3
+ import type { IAudioMetadata, IAudioMode, IAudioPlaylistLoopMode, IAudioSample, IAudioSource, IAudioStatus, IAudioLockScreenOptions, IAudioPlaylistStatus, IPitchCorrectionQuality, IRecorderState, IRecordingInput, IRecordingOptions, IRecordingStartOptions, IRecordingStatus } from './types';
4
+ export type NativeAudioPlayerEvents = {
5
+ playbackStatusUpdate(status: IAudioStatus): void;
6
+ audioSampleUpdate(data: IAudioSample): void;
7
+ };
8
+ export declare class NativeAudioPlayer extends SharedObject<NativeAudioPlayerEvents> {
9
+ constructor(source: IAudioSource, updateInterval: number, keepAudioSessionActive: boolean, preferredForwardBufferDuration: number);
10
+ id: string;
11
+ playing: boolean;
12
+ muted: boolean;
13
+ loop: boolean;
14
+ paused: boolean;
15
+ isLoaded: boolean;
16
+ isAudioSamplingSupported: boolean;
17
+ isBuffering: boolean;
18
+ currentTime: number;
19
+ duration: number;
20
+ volume: number;
21
+ playbackRate: number;
22
+ shouldCorrectPitch: boolean;
23
+ currentStatus: IAudioStatus;
24
+ play(): void;
25
+ pause(): void;
26
+ replace(source: IAudioSource): void;
27
+ seekTo(seconds: number, toleranceMillisBefore?: number, toleranceMillisAfter?: number): Promise<void>;
28
+ setPlaybackRate(rate: number, pitchCorrectionQuality?: IPitchCorrectionQuality): void;
29
+ setAudioSamplingEnabled(enabled: boolean): void;
30
+ setActiveForLockScreen(active: boolean, metadata?: IAudioMetadata, options?: IAudioLockScreenOptions): void;
31
+ updateLockScreenMetadata(metadata: IAudioMetadata): void;
32
+ clearLockScreenControls(): void;
33
+ remove(): void;
34
+ }
35
+ export type NativeAudioRecorderEvents = {
36
+ recordingStatusUpdate: (status: IRecordingStatus) => void;
37
+ };
38
+ export declare class NativeAudioRecorder extends SharedObject<NativeAudioRecorderEvents> {
39
+ constructor(options: Partial<IRecordingOptions>);
40
+ id: string;
41
+ currentTime: number;
42
+ isRecording: boolean;
43
+ uri: string | null;
44
+ record(options?: IRecordingStartOptions): void;
45
+ stop(): Promise<void>;
46
+ pause(): void;
47
+ getAvailableInputs(): IRecordingInput[];
48
+ getCurrentInput(): Promise<IRecordingInput>;
49
+ setInput(inputUid: string): void;
50
+ getStatus(): IRecorderState;
51
+ /** @deprecated Use `record({ atTime: seconds })` instead. */
52
+ startRecordingAtTime(seconds: number): void;
53
+ prepareToRecordAsync(options?: Partial<IRecordingOptions>): Promise<void>;
54
+ /** @deprecated Use `record({ forDuration: seconds })` instead. */
55
+ recordForDuration(seconds: number): void;
56
+ }
57
+ export type NativeAudioPlaylistEvents = {
58
+ playlistStatusUpdate(status: IAudioPlaylistStatus): void;
59
+ trackChanged(data: {
60
+ previousIndex: number;
61
+ currentIndex: number;
62
+ }): void;
63
+ };
64
+ export declare class NativeAudioPlaylist extends SharedObject<NativeAudioPlaylistEvents> {
65
+ constructor(sources: IAudioSource[], updateInterval: number, loop: IAudioPlaylistLoopMode);
66
+ id: string;
67
+ readonly currentIndex: number;
68
+ readonly trackCount: number;
69
+ readonly sources: {
70
+ uri?: string;
71
+ name?: string;
72
+ }[];
73
+ playing: boolean;
74
+ muted: boolean;
75
+ isLoaded: boolean;
76
+ isBuffering: boolean;
77
+ currentTime: number;
78
+ duration: number;
79
+ volume: number;
80
+ playbackRate: number;
81
+ loop: IAudioPlaylistLoopMode;
82
+ currentStatus: IAudioPlaylistStatus;
83
+ play(): void;
84
+ pause(): void;
85
+ next(): void;
86
+ previous(): void;
87
+ skipTo(index: number): void;
88
+ seekTo(seconds: number): Promise<void>;
89
+ add(source: IAudioSource): void;
90
+ insert(source: IAudioSource, index: number): void;
91
+ remove(index: number): void;
92
+ clear(): void;
93
+ destroy(): void;
94
+ }
95
+ export type NativeAudioStreamEvents = {
96
+ audioStreamBuffer(buffer: {
97
+ data: ArrayBuffer;
98
+ sampleRate: number;
99
+ channels: number;
100
+ timestamp: number;
101
+ }): void;
102
+ audioStreamStatus(status: {
103
+ isStreaming: boolean;
104
+ }): void;
105
+ };
106
+ export declare class NativeAudioStream extends SharedObject<NativeAudioStreamEvents> {
107
+ constructor(options: {
108
+ sampleRate: number;
109
+ channels: number;
110
+ encoding: string;
111
+ });
112
+ id: string;
113
+ readonly sampleRate: number;
114
+ readonly channels: number;
115
+ readonly isStreaming: boolean;
116
+ start(): Promise<void>;
117
+ stop(): void;
118
+ }
119
+ export type INativeAudioModule = {
120
+ readonly AudioPlayer: typeof NativeAudioPlayer;
121
+ readonly AudioRecorder: typeof NativeAudioRecorder;
122
+ readonly AudioPlaylist: typeof NativeAudioPlaylist;
123
+ readonly AudioStream: typeof NativeAudioStream;
124
+ setIsAudioActiveAsync(active: boolean): Promise<void>;
125
+ setAudioModeAsync(mode: Partial<IAudioMode>): Promise<void>;
126
+ requestRecordingPermissionsAsync(): Promise<PermissionResponse>;
127
+ requestNotificationPermissionsAsync(): Promise<PermissionResponse>;
128
+ getRecordingPermissionsAsync(): Promise<PermissionResponse>;
129
+ preload(source: IAudioSource, preferredForwardBufferDuration: number): Promise<void>;
130
+ clearPreloadedSource(source: IAudioSource): Promise<void>;
131
+ clearAllPreloadedSources(): Promise<void>;
132
+ getPreloadedSources(): Promise<string[]>;
133
+ };
134
+ export declare const expoAudio: INativeAudioModule;
@@ -0,0 +1,2 @@
1
+ import { requireNativeModule, SharedObject } from 'expo-modules-core';
2
+ export const expoAudio = requireNativeModule('ExpoAudio');
@@ -0,0 +1,50 @@
1
+ import type { IRecordingOptions } from './types';
2
+ /** @platform ios */
3
+ export declare enum IOSOutputFormat {
4
+ LINEARPCM = "lpcm",
5
+ AC3 = "ac-3",
6
+ '60958AC3' = "cac3",
7
+ APPLEIMA4 = "ima4",
8
+ MPEG4AAC = "aac ",
9
+ MPEG4CELP = "celp",
10
+ MPEG4HVXC = "hvxc",
11
+ MPEG4TWINVQ = "twvq",
12
+ MACE3 = "MAC3",
13
+ MACE6 = "MAC6",
14
+ ULAW = "ulaw",
15
+ ALAW = "alaw",
16
+ QDESIGN = "QDMC",
17
+ QDESIGN2 = "QDM2",
18
+ QUALCOMM = "Qclp",
19
+ MPEGLAYER1 = ".mp1",
20
+ MPEGLAYER2 = ".mp2",
21
+ MPEGLAYER3 = ".mp3",
22
+ APPLELOSSLESS = "alac",
23
+ MPEG4AAC_HE = "aach",
24
+ MPEG4AAC_LD = "aacl",
25
+ MPEG4AAC_ELD = "aace",
26
+ MPEG4AAC_ELD_SBR = "aacf",
27
+ MPEG4AAC_ELD_V2 = "aacg",
28
+ MPEG4AAC_HE_V2 = "aacp",
29
+ MPEG4AAC_SPATIAL = "aacs",
30
+ AMR = "samr",
31
+ AMR_WB = "sawb",
32
+ AUDIBLE = "AUDB",
33
+ ILBC = "ilbc",
34
+ DVIINTELIMA = 1836253201,
35
+ MICROSOFTGSM = 1836253233,
36
+ AES3 = "aes3",
37
+ ENHANCEDAC3 = "ec-3"
38
+ }
39
+ export declare enum AudioQuality {
40
+ MIN = 0,
41
+ LOW = 32,
42
+ MEDIUM = 64,
43
+ HIGH = 96,
44
+ MAX = 127
45
+ }
46
+ /** The two preset `IRecordingOptions` bundles expo-audio ships. */
47
+ export declare const RecordingPresets: {
48
+ readonly HIGH_QUALITY: IRecordingOptions;
49
+ readonly LOW_QUALITY: IRecordingOptions;
50
+ };
@@ -0,0 +1,94 @@
1
+ /** @platform ios */
2
+ export var IOSOutputFormat;
3
+ (function (IOSOutputFormat) {
4
+ IOSOutputFormat["LINEARPCM"] = "lpcm";
5
+ IOSOutputFormat["AC3"] = "ac-3";
6
+ IOSOutputFormat["60958AC3"] = "cac3";
7
+ IOSOutputFormat["APPLEIMA4"] = "ima4";
8
+ IOSOutputFormat["MPEG4AAC"] = "aac ";
9
+ IOSOutputFormat["MPEG4CELP"] = "celp";
10
+ IOSOutputFormat["MPEG4HVXC"] = "hvxc";
11
+ IOSOutputFormat["MPEG4TWINVQ"] = "twvq";
12
+ IOSOutputFormat["MACE3"] = "MAC3";
13
+ IOSOutputFormat["MACE6"] = "MAC6";
14
+ IOSOutputFormat["ULAW"] = "ulaw";
15
+ IOSOutputFormat["ALAW"] = "alaw";
16
+ IOSOutputFormat["QDESIGN"] = "QDMC";
17
+ IOSOutputFormat["QDESIGN2"] = "QDM2";
18
+ IOSOutputFormat["QUALCOMM"] = "Qclp";
19
+ IOSOutputFormat["MPEGLAYER1"] = ".mp1";
20
+ IOSOutputFormat["MPEGLAYER2"] = ".mp2";
21
+ IOSOutputFormat["MPEGLAYER3"] = ".mp3";
22
+ IOSOutputFormat["APPLELOSSLESS"] = "alac";
23
+ IOSOutputFormat["MPEG4AAC_HE"] = "aach";
24
+ IOSOutputFormat["MPEG4AAC_LD"] = "aacl";
25
+ IOSOutputFormat["MPEG4AAC_ELD"] = "aace";
26
+ IOSOutputFormat["MPEG4AAC_ELD_SBR"] = "aacf";
27
+ IOSOutputFormat["MPEG4AAC_ELD_V2"] = "aacg";
28
+ IOSOutputFormat["MPEG4AAC_HE_V2"] = "aacp";
29
+ IOSOutputFormat["MPEG4AAC_SPATIAL"] = "aacs";
30
+ IOSOutputFormat["AMR"] = "samr";
31
+ IOSOutputFormat["AMR_WB"] = "sawb";
32
+ IOSOutputFormat["AUDIBLE"] = "AUDB";
33
+ IOSOutputFormat["ILBC"] = "ilbc";
34
+ IOSOutputFormat[IOSOutputFormat["DVIINTELIMA"] = 1836253201] = "DVIINTELIMA";
35
+ IOSOutputFormat[IOSOutputFormat["MICROSOFTGSM"] = 1836253233] = "MICROSOFTGSM";
36
+ IOSOutputFormat["AES3"] = "aes3";
37
+ IOSOutputFormat["ENHANCEDAC3"] = "ec-3";
38
+ })(IOSOutputFormat || (IOSOutputFormat = {}));
39
+ export var AudioQuality;
40
+ (function (AudioQuality) {
41
+ AudioQuality[AudioQuality["MIN"] = 0] = "MIN";
42
+ AudioQuality[AudioQuality["LOW"] = 32] = "LOW";
43
+ AudioQuality[AudioQuality["MEDIUM"] = 64] = "MEDIUM";
44
+ AudioQuality[AudioQuality["HIGH"] = 96] = "HIGH";
45
+ AudioQuality[AudioQuality["MAX"] = 127] = "MAX";
46
+ })(AudioQuality || (AudioQuality = {}));
47
+ const HIGH_QUALITY = {
48
+ extension: '.m4a',
49
+ sampleRate: 44100,
50
+ numberOfChannels: 2,
51
+ bitRate: 128000,
52
+ android: {
53
+ outputFormat: 'mpeg4',
54
+ audioEncoder: 'aac',
55
+ },
56
+ ios: {
57
+ outputFormat: IOSOutputFormat.MPEG4AAC,
58
+ audioQuality: AudioQuality.MAX,
59
+ linearPCMBitDepth: 16,
60
+ linearPCMIsBigEndian: false,
61
+ linearPCMIsFloat: false,
62
+ },
63
+ web: {
64
+ mimeType: 'audio/webm',
65
+ bitsPerSecond: 128000,
66
+ },
67
+ };
68
+ const LOW_QUALITY = {
69
+ extension: '.m4a',
70
+ sampleRate: 44100,
71
+ numberOfChannels: 2,
72
+ bitRate: 64000,
73
+ android: {
74
+ extension: '.3gp',
75
+ outputFormat: '3gp',
76
+ audioEncoder: 'amr_nb',
77
+ },
78
+ ios: {
79
+ audioQuality: AudioQuality.MIN,
80
+ outputFormat: IOSOutputFormat.MPEG4AAC,
81
+ linearPCMBitDepth: 16,
82
+ linearPCMIsBigEndian: false,
83
+ linearPCMIsFloat: false,
84
+ },
85
+ web: {
86
+ mimeType: 'audio/webm',
87
+ bitsPerSecond: 128000,
88
+ },
89
+ };
90
+ /** The two preset `IRecordingOptions` bundles expo-audio ships. */
91
+ export const RecordingPresets = {
92
+ HIGH_QUALITY,
93
+ LOW_QUALITY,
94
+ };
@@ -0,0 +1,10 @@
1
+ import type { IAudioSource } from './types';
2
+ /**
3
+ * Normalizes a source into the shape the native player accepts. A `number` (a `require()`'d
4
+ * local asset) resolves via `@symbiote-native/engine`'s `resolveAssetSource` seam — RN's own
5
+ * generic asset-registry lookup, wired by `bootstrapHost`. An actual `expo-asset` `Asset`
6
+ * instance is still not ported, see `types.ts`'s header comment on `IAudioSource`. A plain
7
+ * string is treated as a URI, matching upstream.
8
+ */
9
+ export declare function resolveSource(source?: IAudioSource): IAudioSource | null;
10
+ export declare function resolveSources(sources: IAudioSource[]): NonNullable<IAudioSource>[];
@@ -0,0 +1,31 @@
1
+ import { resolveAssetSource } from '@symbiote-native/engine';
2
+ // resolveAssetSource returns `unknown` by design (the seam serves every require()'d-asset
3
+ // consumer, not just this package) — narrow it instead of casting.
4
+ function isAudioSourceObject(value) {
5
+ return typeof value === 'object' && value !== null;
6
+ }
7
+ /**
8
+ * Normalizes a source into the shape the native player accepts. A `number` (a `require()`'d
9
+ * local asset) resolves via `@symbiote-native/engine`'s `resolveAssetSource` seam — RN's own
10
+ * generic asset-registry lookup, wired by `bootstrapHost`. An actual `expo-asset` `Asset`
11
+ * instance is still not ported, see `types.ts`'s header comment on `IAudioSource`. A plain
12
+ * string is treated as a URI, matching upstream.
13
+ */
14
+ export function resolveSource(source) {
15
+ if (source == null) {
16
+ return null;
17
+ }
18
+ if (typeof source === 'number') {
19
+ const resolved = resolveAssetSource(source);
20
+ return isAudioSourceObject(resolved) ? resolved : null;
21
+ }
22
+ if (typeof source === 'string') {
23
+ return { uri: source };
24
+ }
25
+ return source;
26
+ }
27
+ export function resolveSources(sources) {
28
+ return sources
29
+ .map(source => resolveSource(source))
30
+ .filter((source) => source != null);
31
+ }
@@ -0,0 +1,218 @@
1
+ import type { AudioQuality, IOSOutputFormat } from './recording-presets';
2
+ /** Audio source information returned from native when reading sources from a queue. */
3
+ export type IAudioSourceInfo = {
4
+ uri?: string;
5
+ name?: string;
6
+ };
7
+ /**
8
+ * A URI string, an object describing a remote/local (by URI) audio source, or the numeric asset
9
+ * id `require('./song.mp3')` produces — resolved via `resolveSource`/`resolveSources`.
10
+ */
11
+ export type IAudioSource = string | number | null | {
12
+ uri?: string;
13
+ headers?: Record<string, string>;
14
+ name?: string;
15
+ };
16
+ export type IAudioPlayerOptions = {
17
+ /** How often (in milliseconds) to emit playback status updates. @default 500 */
18
+ updateInterval?: number;
19
+ /** @platform web */
20
+ crossOrigin?: 'anonymous' | 'use-credentials';
21
+ /**
22
+ * If `true`, the audio session is not deactivated when this player pauses or finishes.
23
+ * @platform ios
24
+ * @default false
25
+ */
26
+ keepAudioSessionActive?: boolean;
27
+ /**
28
+ * Seconds to buffer ahead of the current playback position.
29
+ * @platform ios
30
+ * @platform android
31
+ * @default 0
32
+ */
33
+ preferredForwardBufferDuration?: number;
34
+ };
35
+ export type IPreloadOptions = {
36
+ /** @default 10 */
37
+ preferredForwardBufferDuration?: number;
38
+ };
39
+ export type IRecordingInput = {
40
+ name: string;
41
+ type: string;
42
+ uid: string;
43
+ };
44
+ export type IPitchCorrectionQuality = 'low' | 'medium' | 'high';
45
+ export type IAudioStatus = {
46
+ id: string;
47
+ currentTime: number;
48
+ playbackState: string;
49
+ timeControlStatus: string;
50
+ reasonForWaitingToPlay: string;
51
+ mute: boolean;
52
+ duration: number;
53
+ playing: boolean;
54
+ loop: boolean;
55
+ didJustFinish: boolean;
56
+ isBuffering: boolean;
57
+ isLoaded: boolean;
58
+ playbackRate: number;
59
+ shouldCorrectPitch: boolean;
60
+ /** @platform ios */
61
+ mediaServicesDidReset?: boolean;
62
+ isLive: boolean;
63
+ currentOffsetFromLive: number | null;
64
+ error: string | null;
65
+ };
66
+ export type IRecordingStatus = {
67
+ id: string;
68
+ isFinished: boolean;
69
+ hasError: boolean;
70
+ error: string | null;
71
+ url: string | null;
72
+ /** @platform ios */
73
+ mediaServicesDidReset?: boolean;
74
+ };
75
+ export type IRecorderState = {
76
+ canRecord: boolean;
77
+ isRecording: boolean;
78
+ durationMillis: number;
79
+ mediaServicesDidReset: boolean;
80
+ metering?: number;
81
+ url: string | null;
82
+ };
83
+ /** @platform android */
84
+ export type IAndroidOutputFormat = 'default' | '3gp' | 'mpeg4' | 'amrnb' | 'amrwb' | 'aac_adts' | 'mpeg2ts' | 'webm';
85
+ /** @platform android */
86
+ export type IAndroidAudioEncoder = 'default' | 'amr_nb' | 'amr_wb' | 'aac' | 'he_aac' | 'aac_eld';
87
+ export type IRecordingStartOptions = {
88
+ /** @platform ios @platform android @platform web */
89
+ forDuration?: number;
90
+ /** @platform ios */
91
+ atTime?: number;
92
+ };
93
+ /** @platform android @platform ios */
94
+ export type IRecordingDirectory = 'cache' | 'document';
95
+ export type IRecordingOptionsWeb = {
96
+ mimeType?: string;
97
+ bitsPerSecond?: number;
98
+ };
99
+ /** @platform ios */
100
+ export type IRecordingOptionsIos = {
101
+ extension?: string;
102
+ sampleRate?: number;
103
+ outputFormat?: string | IOSOutputFormat | number;
104
+ audioQuality: AudioQuality | number;
105
+ bitRateStrategy?: number;
106
+ bitDepthHint?: number;
107
+ linearPCMBitDepth?: number;
108
+ linearPCMIsBigEndian?: boolean;
109
+ linearPCMIsFloat?: boolean;
110
+ };
111
+ /** @platform android */
112
+ export type IRecordingSource = 'camcorder' | 'default' | 'mic' | 'remote_submix' | 'unprocessed' | 'voice_communication' | 'voice_performance' | 'voice_recognition';
113
+ /** @platform android */
114
+ export type IRecordingOptionsAndroid = {
115
+ extension?: string;
116
+ sampleRate?: number;
117
+ outputFormat: IAndroidOutputFormat;
118
+ audioEncoder: IAndroidAudioEncoder;
119
+ maxFileSize?: number;
120
+ audioSource?: IRecordingSource;
121
+ };
122
+ export type IRecordingOptions = {
123
+ /** @default 'cache' */
124
+ directory?: IRecordingDirectory;
125
+ isMeteringEnabled?: boolean;
126
+ extension: string;
127
+ sampleRate: number;
128
+ numberOfChannels: number;
129
+ bitRate: number;
130
+ android: IRecordingOptionsAndroid;
131
+ ios: IRecordingOptionsIos;
132
+ web: IRecordingOptionsWeb;
133
+ };
134
+ export type IAudioMode = {
135
+ /** @default true */
136
+ playsInSilentMode: boolean;
137
+ /** @default 'mixWithOthers' */
138
+ interruptionMode: IInterruptionMode;
139
+ /** @default false @platform ios */
140
+ allowsRecording: boolean;
141
+ /** @default false */
142
+ shouldPlayInBackground: boolean;
143
+ /** @default false */
144
+ shouldRouteThroughEarpiece: boolean;
145
+ /** @default false @platform ios @platform android */
146
+ allowsBackgroundRecording?: boolean;
147
+ };
148
+ export type IInterruptionMode = 'mixWithOthers' | 'doNotMix' | 'duckOthers';
149
+ export type IAudioMetadata = {
150
+ title?: string;
151
+ artist?: string;
152
+ albumTitle?: string;
153
+ artworkUrl?: string;
154
+ };
155
+ export type IAudioPlaylistLoopMode = 'none' | 'single' | 'all';
156
+ export type IAudioPlaylistOptions = {
157
+ /** @default [] */
158
+ sources?: IAudioSource[];
159
+ /** @default 500 */
160
+ updateInterval?: number;
161
+ /** @default 'none' */
162
+ loop?: IAudioPlaylistLoopMode;
163
+ /** @platform web */
164
+ crossOrigin?: 'anonymous' | 'use-credentials';
165
+ };
166
+ export type IAudioPlaylistStatus = {
167
+ id: string;
168
+ currentIndex: number;
169
+ trackCount: number;
170
+ currentTime: number;
171
+ duration: number;
172
+ playing: boolean;
173
+ isBuffering: boolean;
174
+ isLoaded: boolean;
175
+ playbackRate: number;
176
+ muted: boolean;
177
+ volume: number;
178
+ loop: IAudioPlaylistLoopMode;
179
+ didJustFinish: boolean;
180
+ };
181
+ /** From AudioConstants.ts — which lock-screen controls to show while a player is active. */
182
+ export type IAudioLockScreenOptions = {
183
+ showSeekForward?: boolean;
184
+ showSeekBackward?: boolean;
185
+ isLiveStream?: boolean;
186
+ };
187
+ export type IAudioSample = {
188
+ channels: {
189
+ frames: number[];
190
+ }[];
191
+ timestamp: number;
192
+ };
193
+ export type IAudioStreamEncoding = 'float32' | 'int16';
194
+ export type IAudioStreamOptions = {
195
+ /** @default 48000 */
196
+ sampleRate?: number;
197
+ /** @default 1 */
198
+ channels?: number;
199
+ /** @default 'float32' */
200
+ encoding?: IAudioStreamEncoding;
201
+ };
202
+ export type IAudioStreamBuffer = {
203
+ data: ArrayBuffer;
204
+ sampleRate: number;
205
+ channels: number;
206
+ timestamp: number;
207
+ };
208
+ export type IAudioStreamStatus = {
209
+ isStreaming: boolean;
210
+ };
211
+ /** From AudioEventKeys.ts — event names the `SharedObject` classes' `addListener` accepts. */
212
+ export declare const PLAYBACK_STATUS_UPDATE = "playbackStatusUpdate";
213
+ export declare const AUDIO_SAMPLE_UPDATE = "audioSampleUpdate";
214
+ export declare const RECORDING_STATUS_UPDATE = "recordingStatusUpdate";
215
+ export declare const PLAYLIST_STATUS_UPDATE = "playlistStatusUpdate";
216
+ export declare const TRACK_CHANGED = "trackChanged";
217
+ export declare const AUDIO_STREAM_BUFFER = "audioStreamBuffer";
218
+ export declare const AUDIO_STREAM_STATUS = "audioStreamStatus";
@@ -0,0 +1,8 @@
1
+ /** From AudioEventKeys.ts — event names the `SharedObject` classes' `addListener` accepts. */
2
+ export const PLAYBACK_STATUS_UPDATE = 'playbackStatusUpdate';
3
+ export const AUDIO_SAMPLE_UPDATE = 'audioSampleUpdate';
4
+ export const RECORDING_STATUS_UPDATE = 'recordingStatusUpdate';
5
+ export const PLAYLIST_STATUS_UPDATE = 'playlistStatusUpdate';
6
+ export const TRACK_CHANGED = 'trackChanged';
7
+ export const AUDIO_STREAM_BUFFER = 'audioStreamBuffer';
8
+ export const AUDIO_STREAM_STATUS = 'audioStreamStatus';
@@ -0,0 +1 @@
1
+ export * from '../core';
@@ -0,0 +1,5 @@
1
+ // @symbiote-native/audio/angular: the Angular entry over the framework-agnostic core. Same
2
+ // reasoning as the React/Vue entries — every export here is a plain class/function with no
3
+ // framework-specific lifecycle to wrap, so this is a plain re-export.
4
+ export * from '../core';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,2FAA2F;AAC3F,sEAAsE;AACtE,cAAc,SAAS,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { type PermissionResponse } from 'expo-modules-core';
2
+ import type { IAudioMode, IAudioSource, IPreloadOptions } from './types';
3
+ /** Enables or disables the audio subsystem globally — pauses all playback when set to `false`. */
4
+ export declare function setIsAudioActiveAsync(active: boolean): Promise<void>;
5
+ /** Configures the global audio session — background playback, mixing, interruption handling. */
6
+ export declare function setAudioModeAsync(mode: Partial<IAudioMode>): Promise<void>;
7
+ /** Requests microphone-access permission required for recording. */
8
+ export declare function requestRecordingPermissionsAsync(): Promise<PermissionResponse>;
9
+ /**
10
+ * Requests permission to post notifications on Android, needed for lock-screen/notification-shade
11
+ * playback controls. @platform android — throws on every other platform.
12
+ */
13
+ export declare function requestNotificationPermissionsAsync(): Promise<PermissionResponse>;
14
+ /** Checks the current recording-permission status without prompting. */
15
+ export declare function getRecordingPermissionsAsync(): Promise<PermissionResponse>;
16
+ /**
17
+ * Preloads an audio source for near-instant playback later — call at module scope, before any
18
+ * player is created from the same source.
19
+ */
20
+ export declare function preload(source: IAudioSource, options?: IPreloadOptions): Promise<void>;
21
+ /** Releases a specific preloaded source (must match what was passed to `preload`). */
22
+ export declare function clearPreloadedSource(source: IAudioSource): Promise<void>;
23
+ /** Releases every preloaded source. */
24
+ export declare function clearAllPreloadedSources(): Promise<void>;
25
+ /** URIs of every source currently in the preload cache. */
26
+ export declare function getPreloadedSources(): Promise<string[]>;
@@ -0,0 +1,65 @@
1
+ import { Platform } from 'expo-modules-core';
2
+ import { expoAudio } from './native-module';
3
+ import { resolveSource } from './resolve-source';
4
+ /** Enables or disables the audio subsystem globally — pauses all playback when set to `false`. */
5
+ export async function setIsAudioActiveAsync(active) {
6
+ return expoAudio.setIsAudioActiveAsync(active);
7
+ }
8
+ /** Configures the global audio session — background playback, mixing, interruption handling. */
9
+ export async function setAudioModeAsync(mode) {
10
+ const audioMode = Platform.OS === 'ios'
11
+ ? mode
12
+ : {
13
+ shouldPlayInBackground: mode.shouldPlayInBackground,
14
+ shouldRouteThroughEarpiece: mode.shouldRouteThroughEarpiece,
15
+ interruptionMode: mode.interruptionMode,
16
+ allowsBackgroundRecording: mode.allowsBackgroundRecording,
17
+ playsInSilentMode: mode.playsInSilentMode,
18
+ };
19
+ return expoAudio.setAudioModeAsync(audioMode);
20
+ }
21
+ /** Requests microphone-access permission required for recording. */
22
+ export async function requestRecordingPermissionsAsync() {
23
+ return expoAudio.requestRecordingPermissionsAsync();
24
+ }
25
+ /**
26
+ * Requests permission to post notifications on Android, needed for lock-screen/notification-shade
27
+ * playback controls. @platform android — throws on every other platform.
28
+ */
29
+ export async function requestNotificationPermissionsAsync() {
30
+ if (Platform.OS !== 'android') {
31
+ throw new Error('expo-audio: `requestNotificationPermissionsAsync` is only available on Android.');
32
+ }
33
+ return expoAudio.requestNotificationPermissionsAsync();
34
+ }
35
+ /** Checks the current recording-permission status without prompting. */
36
+ export async function getRecordingPermissionsAsync() {
37
+ return expoAudio.getRecordingPermissionsAsync();
38
+ }
39
+ /**
40
+ * Preloads an audio source for near-instant playback later — call at module scope, before any
41
+ * player is created from the same source.
42
+ */
43
+ export async function preload(source, options = {}) {
44
+ const resolved = resolveSource(source);
45
+ if (!resolved)
46
+ return;
47
+ const { preferredForwardBufferDuration = 10 } = options;
48
+ return expoAudio.preload(resolved, preferredForwardBufferDuration);
49
+ }
50
+ /** Releases a specific preloaded source (must match what was passed to `preload`). */
51
+ export async function clearPreloadedSource(source) {
52
+ const resolved = resolveSource(source);
53
+ if (!resolved)
54
+ return;
55
+ return expoAudio.clearPreloadedSource(resolved);
56
+ }
57
+ /** Releases every preloaded source. */
58
+ export async function clearAllPreloadedSources() {
59
+ return expoAudio.clearAllPreloadedSources();
60
+ }
61
+ /** URIs of every source currently in the preload cache. */
62
+ export async function getPreloadedSources() {
63
+ return expoAudio.getPreloadedSources();
64
+ }
65
+ //# sourceMappingURL=audio-module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-module.js","sourceRoot":"","sources":["../../src/core/audio-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA2B,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,kGAAkG;AAClG,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAAe;IACzD,OAAO,SAAS,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC;AAED,gGAAgG;AAChG,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAyB;IAEzB,MAAM,SAAS,GACb,QAAQ,CAAC,EAAE,KAAK,KAAK;QACnB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC;YACE,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;YACnD,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;YAC3D,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,yBAAyB,EAAE,IAAI,CAAC,yBAAyB;YACzD,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;SAC1C,CAAC;IACR,OAAO,SAAS,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;AAChD,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,gCAAgC;IACpD,OAAO,SAAS,CAAC,gCAAgC,EAAE,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mCAAmC;IACvD,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC,mCAAmC,EAAE,CAAC;AACzD,CAAC;AAED,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,4BAA4B;IAChD,OAAO,SAAS,CAAC,4BAA4B,EAAE,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAoB,EACpB,UAA2B,EAAE;IAE7B,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,MAAM,EAAE,8BAA8B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IACxD,OAAO,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,8BAA8B,CAAC,CAAC;AACrE,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAoB;IAEpB,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,OAAO,SAAS,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED,uCAAuC;AACvC,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,OAAO,SAAS,CAAC,wBAAwB,EAAE,CAAC;AAC9C,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,OAAO,SAAS,CAAC,mBAAmB,EAAE,CAAC;AACzC,CAAC"}