expo-audio 0.2.2 → 0.2.4
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/CHANGELOG.md +14 -0
- package/android/build.gradle +3 -2
- package/android/src/main/java/expo/modules/audio/AudioModule.kt +35 -20
- package/android/src/main/java/expo/modules/audio/AudioPlayer.kt +51 -25
- package/build/Audio.types.d.ts +1 -1
- package/build/Audio.types.js.map +1 -1
- package/build/AudioModule.d.ts +5 -2
- package/build/AudioModule.d.ts.map +1 -1
- package/build/AudioModule.js +3 -0
- package/build/AudioModule.js.map +1 -1
- package/build/AudioModule.types.d.ts +15 -9
- package/build/AudioModule.types.d.ts.map +1 -1
- package/build/AudioModule.types.js.map +1 -1
- package/build/AudioModule.web.d.ts +1 -0
- package/build/AudioModule.web.d.ts.map +1 -1
- package/build/AudioModule.web.js +4 -0
- package/build/AudioModule.web.js.map +1 -1
- package/build/ExpoAudio.d.ts +6 -10
- package/build/ExpoAudio.d.ts.map +1 -1
- package/build/ExpoAudio.js +7 -4
- package/build/ExpoAudio.js.map +1 -1
- package/build/ExpoAudio.web.d.ts +6 -10
- package/build/ExpoAudio.web.d.ts.map +1 -1
- package/build/ExpoAudio.web.js +7 -4
- package/build/ExpoAudio.web.js.map +1 -1
- package/build/RecordingConstants.d.ts +17 -25
- package/build/RecordingConstants.d.ts.map +1 -1
- package/build/RecordingConstants.js +17 -25
- package/build/RecordingConstants.js.map +1 -1
- package/build/index.d.ts +4 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -0
- package/build/index.js.map +1 -1
- package/ios/AudioModule.swift +6 -2
- package/ios/AudioPlayer.swift +3 -0
- package/ios/AudioUtils.swift +9 -1
- package/package.json +2 -2
- package/src/Audio.types.ts +1 -1
- package/src/AudioModule.ts +6 -2
- package/src/AudioModule.types.ts +15 -7
- package/src/AudioModule.web.ts +5 -0
- package/src/ExpoAudio.ts +12 -9
- package/src/ExpoAudio.web.ts +12 -5
- package/src/RecordingConstants.ts +17 -25
- package/src/index.ts +6 -0
package/build/ExpoAudio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAudio.js","sourceRoot":"","sources":["../src/ExpoAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,
|
|
1
|
+
{"version":3,"file":"ExpoAudio.js","sourceRoot":"","sources":["../src/ExpoAudio.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEvent } from 'expo';\nimport { PermissionResponse, useReleasingSharedObject } from 'expo-modules-core';\nimport { useEffect, useState, useMemo } from 'react';\n\nimport {\n AudioMode,\n AudioSource,\n AudioStatus,\n RecorderState,\n RecordingOptions,\n RecordingStatus,\n} from './Audio.types';\nimport AudioModule from './AudioModule';\nimport { AudioPlayer, AudioRecorder, AudioSample } from './AudioModule.types';\nimport { createRecordingOptions } from './utils/options';\nimport { resolveSource } from './utils/resolveSource';\n\nexport const PLAYBACK_STATUS_UPDATE = 'playbackStatusUpdate';\nexport const AUDIO_SAMPLE_UPDATE = 'audioSampleUpdate';\nexport const RECORDING_STATUS_UPDATE = 'recordingStatusUpdate';\n\nexport function useAudioPlayer(\n source: AudioSource | string | number | null = null,\n updateInterval: number = 500\n): AudioPlayer {\n const parsedSource = resolveSource(source);\n return useReleasingSharedObject(\n () => new AudioModule.AudioPlayer(parsedSource, updateInterval),\n [JSON.stringify(parsedSource)]\n );\n}\n\nexport function useAudioPlayerStatus(player: AudioPlayer): AudioStatus {\n const currentStatus = useMemo(() => player.currentStatus, [player.id]);\n return useEvent(player, PLAYBACK_STATUS_UPDATE, currentStatus);\n}\n\nexport function useAudioSampleListener(player: AudioPlayer, listener: (data: AudioSample) => void) {\n player.setAudioSamplingEnabled(true);\n useEffect(() => {\n if (!player.isAudioSamplingSupported) {\n return;\n }\n const subscription = player.addListener(AUDIO_SAMPLE_UPDATE, listener);\n return () => {\n subscription.remove();\n };\n }, [player.id]);\n}\n\nexport function useAudioRecorder(\n options: RecordingOptions,\n statusListener?: (status: RecordingStatus) => void\n): AudioRecorder {\n const platformOptions = createRecordingOptions(options);\n const recorder = useReleasingSharedObject(() => {\n return new AudioModule.AudioRecorder(platformOptions);\n }, [JSON.stringify(platformOptions)]);\n\n useEffect(() => {\n const subscription = recorder.addListener(RECORDING_STATUS_UPDATE, (status) => {\n statusListener?.(status);\n });\n return () => subscription.remove();\n }, [recorder.id]);\n\n return recorder;\n}\n\nexport function useAudioRecorderState(recorder: AudioRecorder, interval: number = 500) {\n const [state, setState] = useState<RecorderState>(recorder.getStatus());\n\n useEffect(() => {\n const int = setInterval(() => {\n setState(recorder.getStatus());\n }, interval);\n\n return () => clearInterval(int);\n }, [recorder.id]);\n\n return state;\n}\n\nexport async function setIsAudioActiveAsync(active: boolean): Promise<void> {\n return await AudioModule.setIsAudioActiveAsync(active);\n}\n\nexport async function setAudioModeAsync(mode: Partial<AudioMode>): Promise<void> {\n return await AudioModule.setAudioModeAsync(mode);\n}\n\nexport async function requestRecordingPermissionsAsync(): Promise<PermissionResponse> {\n return await AudioModule.requestRecordingPermissionsAsync();\n}\n\nexport async function getRecordingPermissionsAsync(): Promise<PermissionResponse> {\n return await AudioModule.getRecordingPermissionsAsync();\n}\n\nexport { AudioModule };\n"]}
|
package/build/ExpoAudio.web.d.ts
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
|
+
import { PermissionResponse } from 'expo-modules-core';
|
|
1
2
|
import { AudioMode, AudioSource, AudioStatus, RecorderState, RecordingOptions, RecordingStatus } from './Audio.types';
|
|
2
|
-
import {
|
|
3
|
+
import { AudioRecorder, AudioSample } from './AudioModule.types';
|
|
3
4
|
import * as AudioModule from './AudioModule.web';
|
|
4
5
|
export declare function useAudioPlayer(source?: AudioSource | string | number | null, updateInterval?: number): AudioModule.AudioPlayerWeb;
|
|
5
6
|
export declare function useAudioPlayerStatus(player: AudioModule.AudioPlayerWeb): AudioStatus;
|
|
6
|
-
export declare function useAudioSampleListener(player: AudioModule.AudioPlayerWeb, listener: (data:
|
|
7
|
-
channels: {
|
|
8
|
-
frames: number[];
|
|
9
|
-
}[];
|
|
10
|
-
timestamp: number;
|
|
11
|
-
}) => void): void;
|
|
7
|
+
export declare function useAudioSampleListener(player: AudioModule.AudioPlayerWeb, listener: (data: AudioSample) => void): void;
|
|
12
8
|
export declare function useAudioRecorder(options: RecordingOptions, statusListener?: (status: RecordingStatus) => void): AudioModule.AudioRecorderWeb;
|
|
13
9
|
export declare function useAudioRecorderState(recorder: AudioRecorder, interval?: number): RecorderState;
|
|
14
10
|
export declare function setIsAudioActiveAsync(active: boolean): Promise<void>;
|
|
15
11
|
export declare function setAudioModeAsync(mode: AudioMode): Promise<void>;
|
|
16
|
-
export
|
|
17
|
-
export
|
|
18
|
-
export
|
|
12
|
+
export declare function requestRecordingPermissionsAsync(): Promise<PermissionResponse>;
|
|
13
|
+
export declare function getRecordingPermissionsAsync(): Promise<PermissionResponse>;
|
|
14
|
+
export { AudioModule };
|
|
19
15
|
//# sourceMappingURL=ExpoAudio.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAudio.web.d.ts","sourceRoot":"","sources":["../src/ExpoAudio.web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExpoAudio.web.d.ts","sourceRoot":"","sources":["../src/ExpoAudio.web.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EACL,SAAS,EACT,WAAW,EACX,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AAKjD,wBAAgB,cAAc,CAC5B,MAAM,GAAE,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,IAAW,EACnD,cAAc,GAAE,MAAY,GAC3B,WAAW,CAAC,cAAc,CAY5B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,CAAC,cAAc,GAAG,WAAW,CAGpF;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,WAAW,CAAC,cAAc,EAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,QAUtC;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EACzB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GACjD,WAAW,CAAC,gBAAgB,CAiB9B;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,GAAE,MAAY,iBAYpF;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAEpF;AAED,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAEhF;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
package/build/ExpoAudio.web.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useEvent } from 'expo';
|
|
2
2
|
import { useEffect, useState, useMemo } from 'react';
|
|
3
|
-
import { AudioPlayer, AudioRecorder } from './AudioModule.types';
|
|
4
3
|
import * as AudioModule from './AudioModule.web';
|
|
5
4
|
import { AUDIO_SAMPLE_UPDATE, PLAYBACK_STATUS_UPDATE, RECORDING_STATUS_UPDATE } from './ExpoAudio';
|
|
6
5
|
import { createRecordingOptions } from './utils/options';
|
|
@@ -59,7 +58,11 @@ export async function setIsAudioActiveAsync(active) {
|
|
|
59
58
|
export async function setAudioModeAsync(mode) {
|
|
60
59
|
return await AudioModule.setAudioModeAsync(mode);
|
|
61
60
|
}
|
|
62
|
-
export
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
export async function requestRecordingPermissionsAsync() {
|
|
62
|
+
return await AudioModule.requestRecordingPermissionsAsync();
|
|
63
|
+
}
|
|
64
|
+
export async function getRecordingPermissionsAsync() {
|
|
65
|
+
return await AudioModule.getRecordingPermissionsAsync();
|
|
66
|
+
}
|
|
67
|
+
export { AudioModule };
|
|
65
68
|
//# sourceMappingURL=ExpoAudio.web.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAudio.web.js","sourceRoot":"","sources":["../src/ExpoAudio.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpoAudio.web.js","sourceRoot":"","sources":["../src/ExpoAudio.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEvent } from 'expo';\nimport { PermissionResponse } from 'expo-modules-core';\nimport { useEffect, useState, useMemo } from 'react';\n\nimport {\n AudioMode,\n AudioSource,\n AudioStatus,\n RecorderState,\n RecordingOptions,\n RecordingStatus,\n} from './Audio.types';\nimport { AudioRecorder, AudioSample } from './AudioModule.types';\nimport * as AudioModule from './AudioModule.web';\nimport { AUDIO_SAMPLE_UPDATE, PLAYBACK_STATUS_UPDATE, RECORDING_STATUS_UPDATE } from './ExpoAudio';\nimport { createRecordingOptions } from './utils/options';\nimport { resolveSource } from './utils/resolveSource';\n\nexport function useAudioPlayer(\n source: AudioSource | string | number | null = null,\n updateInterval: number = 500\n): AudioModule.AudioPlayerWeb {\n const parsedSource = resolveSource(source);\n const player = useMemo(\n () => new AudioModule.AudioPlayerWeb(parsedSource, updateInterval),\n [JSON.stringify(parsedSource)]\n );\n\n useEffect(() => {\n return () => player.remove();\n }, []);\n\n return player;\n}\n\nexport function useAudioPlayerStatus(player: AudioModule.AudioPlayerWeb): AudioStatus {\n const currentStatus = useMemo(() => player.currentStatus, [player.id]);\n return useEvent(player, PLAYBACK_STATUS_UPDATE, currentStatus);\n}\n\nexport function useAudioSampleListener(\n player: AudioModule.AudioPlayerWeb,\n listener: (data: AudioSample) => void\n) {\n player.setAudioSamplingEnabled(true);\n useEffect(() => {\n const subscription = player.addListener(AUDIO_SAMPLE_UPDATE, listener);\n return () => {\n player.setAudioSamplingEnabled(false);\n subscription.remove();\n };\n }, [player.id]);\n}\n\nexport function useAudioRecorder(\n options: RecordingOptions,\n statusListener?: (status: RecordingStatus) => void\n): AudioModule.AudioRecorderWeb {\n const platformOptions = createRecordingOptions(options);\n const recorder = useMemo(() => {\n return new AudioModule.AudioRecorderWeb(platformOptions);\n }, [JSON.stringify(platformOptions)]);\n\n useEffect(() => {\n const subscription = recorder.addListener(RECORDING_STATUS_UPDATE, (status) => {\n statusListener?.(status);\n });\n return () => {\n recorder.clearTimeouts();\n subscription.remove();\n };\n }, [recorder.id]);\n\n return recorder;\n}\n\nexport function useAudioRecorderState(recorder: AudioRecorder, interval: number = 500) {\n const [state, setState] = useState<RecorderState>(recorder.getStatus());\n\n useEffect(() => {\n const id = setInterval(() => {\n setState(recorder.getStatus());\n }, interval);\n\n return () => clearInterval(id);\n }, [recorder.id]);\n\n return state;\n}\n\nexport async function setIsAudioActiveAsync(active: boolean): Promise<void> {\n return await AudioModule.setIsAudioActiveAsync(active);\n}\n\nexport async function setAudioModeAsync(mode: AudioMode): Promise<void> {\n return await AudioModule.setAudioModeAsync(mode);\n}\n\nexport async function requestRecordingPermissionsAsync(): Promise<PermissionResponse> {\n return await AudioModule.requestRecordingPermissionsAsync();\n}\n\nexport async function getRecordingPermissionsAsync(): Promise<PermissionResponse> {\n return await AudioModule.getRecordingPermissionsAsync();\n}\n\nexport { AudioModule };\n"]}
|
|
@@ -4,23 +4,18 @@ import { type RecordingOptions } from './Audio.types';
|
|
|
4
4
|
*
|
|
5
5
|
* # `HIGH_QUALITY`
|
|
6
6
|
* ```ts
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* RecordingPresets.HIGH_QUALITY = {
|
|
8
|
+
* extension: '.m4a',
|
|
9
|
+
* sampleRate: 44100,
|
|
10
|
+
* numberOfChannels: 2,
|
|
11
|
+
* bitRate: 128000,
|
|
9
12
|
* android: {
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* audioEncoder: AndroidAudioEncoder.AAC,
|
|
13
|
-
* sampleRate: 44100,
|
|
14
|
-
* numberOfChannels: 2,
|
|
15
|
-
* bitRate: 128000,
|
|
13
|
+
* outputFormat: 'mpeg4',
|
|
14
|
+
* audioEncoder: 'aac',
|
|
16
15
|
* },
|
|
17
16
|
* ios: {
|
|
18
|
-
* extension: '.m4a',
|
|
19
17
|
* outputFormat: IOSOutputFormat.MPEG4AAC,
|
|
20
|
-
* audioQuality:
|
|
21
|
-
* sampleRate: 44100,
|
|
22
|
-
* numberOfChannels: 2,
|
|
23
|
-
* bitRate: 128000,
|
|
18
|
+
* audioQuality: AudioQuality.MAX,
|
|
24
19
|
* linearPCMBitDepth: 16,
|
|
25
20
|
* linearPCMIsBigEndian: false,
|
|
26
21
|
* linearPCMIsFloat: false,
|
|
@@ -34,22 +29,19 @@ import { type RecordingOptions } from './Audio.types';
|
|
|
34
29
|
*
|
|
35
30
|
* # `LOW_QUALITY`
|
|
36
31
|
* ```ts
|
|
37
|
-
*
|
|
38
|
-
*
|
|
32
|
+
* RecordingPresets.LOW_QUALITY = {
|
|
33
|
+
* extension: '.m4a',
|
|
34
|
+
* sampleRate: 44100,
|
|
35
|
+
* numberOfChannels: 2,
|
|
36
|
+
* bitRate: 64000,
|
|
39
37
|
* android: {
|
|
40
38
|
* extension: '.3gp',
|
|
41
|
-
* outputFormat:
|
|
42
|
-
* audioEncoder:
|
|
43
|
-
* sampleRate: 44100,
|
|
44
|
-
* numberOfChannels: 2,
|
|
45
|
-
* bitRate: 128000,
|
|
39
|
+
* outputFormat: '3gp',
|
|
40
|
+
* audioEncoder: 'amr_nb',
|
|
46
41
|
* },
|
|
47
42
|
* ios: {
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* sampleRate: 44100,
|
|
51
|
-
* numberOfChannels: 2,
|
|
52
|
-
* bitRate: 128000,
|
|
43
|
+
* audioQuality: AudioQuality.MIN,
|
|
44
|
+
* outputFormat: IOSOutputFormat.MPEG4AAC,
|
|
53
45
|
* linearPCMBitDepth: 16,
|
|
54
46
|
* linearPCMIsBigEndian: false,
|
|
55
47
|
* linearPCMIsFloat: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordingConstants.d.ts","sourceRoot":"","sources":["../src/RecordingConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AA+CrF
|
|
1
|
+
{"version":3,"file":"RecordingConstants.d.ts","sourceRoot":"","sources":["../src/RecordingConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AA+CrF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAG7D,CAAC"}
|
|
@@ -47,23 +47,18 @@ const LOW_QUALITY = {
|
|
|
47
47
|
*
|
|
48
48
|
* # `HIGH_QUALITY`
|
|
49
49
|
* ```ts
|
|
50
|
-
*
|
|
51
|
-
*
|
|
50
|
+
* RecordingPresets.HIGH_QUALITY = {
|
|
51
|
+
* extension: '.m4a',
|
|
52
|
+
* sampleRate: 44100,
|
|
53
|
+
* numberOfChannels: 2,
|
|
54
|
+
* bitRate: 128000,
|
|
52
55
|
* android: {
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* audioEncoder: AndroidAudioEncoder.AAC,
|
|
56
|
-
* sampleRate: 44100,
|
|
57
|
-
* numberOfChannels: 2,
|
|
58
|
-
* bitRate: 128000,
|
|
56
|
+
* outputFormat: 'mpeg4',
|
|
57
|
+
* audioEncoder: 'aac',
|
|
59
58
|
* },
|
|
60
59
|
* ios: {
|
|
61
|
-
* extension: '.m4a',
|
|
62
60
|
* outputFormat: IOSOutputFormat.MPEG4AAC,
|
|
63
|
-
* audioQuality:
|
|
64
|
-
* sampleRate: 44100,
|
|
65
|
-
* numberOfChannels: 2,
|
|
66
|
-
* bitRate: 128000,
|
|
61
|
+
* audioQuality: AudioQuality.MAX,
|
|
67
62
|
* linearPCMBitDepth: 16,
|
|
68
63
|
* linearPCMIsBigEndian: false,
|
|
69
64
|
* linearPCMIsFloat: false,
|
|
@@ -77,22 +72,19 @@ const LOW_QUALITY = {
|
|
|
77
72
|
*
|
|
78
73
|
* # `LOW_QUALITY`
|
|
79
74
|
* ```ts
|
|
80
|
-
*
|
|
81
|
-
*
|
|
75
|
+
* RecordingPresets.LOW_QUALITY = {
|
|
76
|
+
* extension: '.m4a',
|
|
77
|
+
* sampleRate: 44100,
|
|
78
|
+
* numberOfChannels: 2,
|
|
79
|
+
* bitRate: 64000,
|
|
82
80
|
* android: {
|
|
83
81
|
* extension: '.3gp',
|
|
84
|
-
* outputFormat:
|
|
85
|
-
* audioEncoder:
|
|
86
|
-
* sampleRate: 44100,
|
|
87
|
-
* numberOfChannels: 2,
|
|
88
|
-
* bitRate: 128000,
|
|
82
|
+
* outputFormat: '3gp',
|
|
83
|
+
* audioEncoder: 'amr_nb',
|
|
89
84
|
* },
|
|
90
85
|
* ios: {
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* sampleRate: 44100,
|
|
94
|
-
* numberOfChannels: 2,
|
|
95
|
-
* bitRate: 128000,
|
|
86
|
+
* audioQuality: AudioQuality.MIN,
|
|
87
|
+
* outputFormat: IOSOutputFormat.MPEG4AAC,
|
|
96
88
|
* linearPCMBitDepth: 16,
|
|
97
89
|
* linearPCMIsBigEndian: false,
|
|
98
90
|
* linearPCMIsFloat: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordingConstants.js","sourceRoot":"","sources":["../src/RecordingConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAyB,YAAY,EAAE,MAAM,eAAe,CAAC;AAErF,MAAM,YAAY,GAAqB;IACrC,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM;IACf,OAAO,EAAE;QACP,YAAY,EAAE,OAAO;QACrB,YAAY,EAAE,KAAK;KACpB;IACD,GAAG,EAAE;QACH,YAAY,EAAE,eAAe,CAAC,QAAQ;QACtC,YAAY,EAAE,YAAY,CAAC,GAAG;QAC9B,iBAAiB,EAAE,EAAE;QACrB,oBAAoB,EAAE,KAAK;QAC3B,gBAAgB,EAAE,KAAK;KACxB;IACD,GAAG,EAAE;QACH,QAAQ,EAAE,YAAY;QACtB,aAAa,EAAE,MAAM;KACtB;CACF,CAAC;AAEF,MAAM,WAAW,GAAqB;IACpC,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,CAAC;IACnB,OAAO,EAAE,KAAK;IACd,OAAO,EAAE;QACP,SAAS,EAAE,MAAM;QACjB,YAAY,EAAE,KAAK;QACnB,YAAY,EAAE,QAAQ;KACvB;IACD,GAAG,EAAE;QACH,YAAY,EAAE,YAAY,CAAC,GAAG;QAC9B,YAAY,EAAE,eAAe,CAAC,QAAQ;QACtC,iBAAiB,EAAE,EAAE;QACrB,oBAAoB,EAAE,KAAK;QAC3B,gBAAgB,EAAE,KAAK;KACxB;IACD,GAAG,EAAE;QACH,QAAQ,EAAE,YAAY;QACtB,aAAa,EAAE,MAAM;KACtB;CACF,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"RecordingConstants.js","sourceRoot":"","sources":["../src/RecordingConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAyB,YAAY,EAAE,MAAM,eAAe,CAAC;AAErF,MAAM,YAAY,GAAqB;IACrC,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM;IACf,OAAO,EAAE;QACP,YAAY,EAAE,OAAO;QACrB,YAAY,EAAE,KAAK;KACpB;IACD,GAAG,EAAE;QACH,YAAY,EAAE,eAAe,CAAC,QAAQ;QACtC,YAAY,EAAE,YAAY,CAAC,GAAG;QAC9B,iBAAiB,EAAE,EAAE;QACrB,oBAAoB,EAAE,KAAK;QAC3B,gBAAgB,EAAE,KAAK;KACxB;IACD,GAAG,EAAE;QACH,QAAQ,EAAE,YAAY;QACtB,aAAa,EAAE,MAAM;KACtB;CACF,CAAC;AAEF,MAAM,WAAW,GAAqB;IACpC,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,CAAC;IACnB,OAAO,EAAE,KAAK;IACd,OAAO,EAAE;QACP,SAAS,EAAE,MAAM;QACjB,YAAY,EAAE,KAAK;QACnB,YAAY,EAAE,QAAQ;KACvB;IACD,GAAG,EAAE;QACH,YAAY,EAAE,YAAY,CAAC,GAAG;QAC9B,YAAY,EAAE,eAAe,CAAC,QAAQ;QACtC,iBAAiB,EAAE,EAAE;QACrB,oBAAoB,EAAE,KAAK;QAC3B,gBAAgB,EAAE,KAAK;KACxB;IACD,GAAG,EAAE;QACH,QAAQ,EAAE,YAAY;QACtB,aAAa,EAAE,MAAM;KACtB;CACF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAqC;IAChE,YAAY;IACZ,WAAW;CACZ,CAAC","sourcesContent":["import { IOSOutputFormat, type RecordingOptions, AudioQuality } from './Audio.types';\n\nconst HIGH_QUALITY: RecordingOptions = {\n extension: '.m4a',\n sampleRate: 44100,\n numberOfChannels: 2,\n bitRate: 128000,\n android: {\n outputFormat: 'mpeg4',\n audioEncoder: 'aac',\n },\n ios: {\n outputFormat: IOSOutputFormat.MPEG4AAC,\n audioQuality: AudioQuality.MAX,\n linearPCMBitDepth: 16,\n linearPCMIsBigEndian: false,\n linearPCMIsFloat: false,\n },\n web: {\n mimeType: 'audio/webm',\n bitsPerSecond: 128000,\n },\n};\n\nconst LOW_QUALITY: RecordingOptions = {\n extension: '.m4a',\n sampleRate: 44100,\n numberOfChannels: 2,\n bitRate: 64000,\n android: {\n extension: '.3gp',\n outputFormat: '3gp',\n audioEncoder: 'amr_nb',\n },\n ios: {\n audioQuality: AudioQuality.MIN,\n outputFormat: IOSOutputFormat.MPEG4AAC,\n linearPCMBitDepth: 16,\n linearPCMIsBigEndian: false,\n linearPCMIsFloat: false,\n },\n web: {\n mimeType: 'audio/webm',\n bitsPerSecond: 128000,\n },\n};\n\n/**\n * Constant which contains definitions of the two preset examples of `RecordingOptions`, as implemented in the Audio SDK.\n *\n * # `HIGH_QUALITY`\n * ```ts\n * RecordingPresets.HIGH_QUALITY = {\n * extension: '.m4a',\n * sampleRate: 44100,\n * numberOfChannels: 2,\n * bitRate: 128000,\n * android: {\n * outputFormat: 'mpeg4',\n * audioEncoder: 'aac',\n * },\n * ios: {\n * outputFormat: IOSOutputFormat.MPEG4AAC,\n * audioQuality: AudioQuality.MAX,\n * linearPCMBitDepth: 16,\n * linearPCMIsBigEndian: false,\n * linearPCMIsFloat: false,\n * },\n * web: {\n * mimeType: 'audio/webm',\n * bitsPerSecond: 128000,\n * },\n * };\n * ```\n *\n * # `LOW_QUALITY`\n * ```ts\n * RecordingPresets.LOW_QUALITY = {\n * extension: '.m4a',\n * sampleRate: 44100,\n * numberOfChannels: 2,\n * bitRate: 64000,\n * android: {\n * extension: '.3gp',\n * outputFormat: '3gp',\n * audioEncoder: 'amr_nb',\n * },\n * ios: {\n * audioQuality: AudioQuality.MIN,\n * outputFormat: IOSOutputFormat.MPEG4AAC,\n * linearPCMBitDepth: 16,\n * linearPCMIsBigEndian: false,\n * linearPCMIsFloat: false,\n * },\n * web: {\n * mimeType: 'audio/webm',\n * bitsPerSecond: 128000,\n * },\n * };\n * ```\n */\nexport const RecordingPresets: Record<string, RecordingOptions> = {\n HIGH_QUALITY,\n LOW_QUALITY,\n};\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
+
export { PermissionResponse, PermissionExpiration, PermissionStatus } from 'expo-modules-core';
|
|
1
2
|
export * from './ExpoAudio';
|
|
3
|
+
export * from './Audio.types';
|
|
4
|
+
export * from './AudioModule.types';
|
|
5
|
+
export * from './RecordingConstants';
|
|
2
6
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE/F,cAAc,aAAa,CAAC;AAE5B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
|
package/build/index.js
CHANGED
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC","sourcesContent":["export * from './ExpoAudio';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE/F,cAAc,aAAa,CAAC;AAE5B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC","sourcesContent":["export { PermissionResponse, PermissionExpiration, PermissionStatus } from 'expo-modules-core';\n\nexport * from './ExpoAudio';\n\nexport * from './Audio.types';\nexport * from './AudioModule.types';\nexport * from './RecordingConstants';\n"]}
|
package/ios/AudioModule.swift
CHANGED
|
@@ -46,7 +46,7 @@ public class AudioModule: Module {
|
|
|
46
46
|
// swiftlint:disable:next closure_body_length
|
|
47
47
|
Class(AudioPlayer.self) {
|
|
48
48
|
Constructor { (source: AudioSource?, updateInterval: Double) -> AudioPlayer in
|
|
49
|
-
let avPlayer = AudioUtils.createAVPlayer(
|
|
49
|
+
let avPlayer = AudioUtils.createAVPlayer(from: source)
|
|
50
50
|
let player = AudioPlayer(avPlayer, interval: updateInterval)
|
|
51
51
|
AudioComponentRegistry.shared.add(player)
|
|
52
52
|
return player
|
|
@@ -107,7 +107,7 @@ public class AudioModule: Module {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
Property("paused") { player in
|
|
110
|
-
|
|
110
|
+
player.isPaused
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
Property("volume") { player in
|
|
@@ -140,6 +140,10 @@ public class AudioModule: Module {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
Function("replace") { (player, source: AudioSource) in
|
|
144
|
+
player.ref.replaceCurrentItem(with: AudioUtils.createAVPlayerItem(from: source))
|
|
145
|
+
}
|
|
146
|
+
|
|
143
147
|
Function("pause") { player in
|
|
144
148
|
player.ref.pause()
|
|
145
149
|
}
|
package/ios/AudioPlayer.swift
CHANGED
|
@@ -13,6 +13,9 @@ public class AudioPlayer: SharedRef<AVPlayer> {
|
|
|
13
13
|
var pitchCorrectionQuality: AVAudioTimePitchAlgorithm = .varispeed
|
|
14
14
|
var currentRate: Float = 0.0
|
|
15
15
|
let interval: Double
|
|
16
|
+
var isPaused: Bool {
|
|
17
|
+
ref.rate != 0.0
|
|
18
|
+
}
|
|
16
19
|
|
|
17
20
|
// MARK: Observers
|
|
18
21
|
private var timeToken: Any?
|
package/ios/AudioUtils.swift
CHANGED
|
@@ -81,7 +81,7 @@ struct AudioUtils {
|
|
|
81
81
|
return AVAudioRecorder()
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
static func createAVPlayer(source: AudioSource?) -> AVPlayer {
|
|
84
|
+
static func createAVPlayer(from source: AudioSource?) -> AVPlayer {
|
|
85
85
|
if let source, let url = source.uri {
|
|
86
86
|
let asset = AVURLAsset(url: url, options: source.headers)
|
|
87
87
|
let item = AVPlayerItem(asset: asset)
|
|
@@ -90,6 +90,14 @@ struct AudioUtils {
|
|
|
90
90
|
return AVPlayer()
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
static func createAVPlayerItem(from source: AudioSource?) -> AVPlayerItem? {
|
|
94
|
+
guard let source, let url = source.uri else {
|
|
95
|
+
return nil
|
|
96
|
+
}
|
|
97
|
+
let asset = AVURLAsset(url: url, options: source.headers)
|
|
98
|
+
return AVPlayerItem(asset: asset)
|
|
99
|
+
}
|
|
100
|
+
|
|
93
101
|
static func createRecordingOptions(_ options: RecordingOptions) -> [String: Any] {
|
|
94
102
|
let strategy = options.bitRateStrategy?.toAVBitRateStrategy() ?? AVAudioBitRateStrategy_Variable
|
|
95
103
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-audio",
|
|
3
3
|
"title": "Expo Audio",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.4",
|
|
5
5
|
"description": "A cross-platform audio library for React Native and Expo apps.",
|
|
6
6
|
"main": "build/index.js",
|
|
7
7
|
"types": "build/index.d.ts",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"react": "*",
|
|
41
41
|
"react-native": "*"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "128718d43bac2eaed764b3551469b95400f2363e"
|
|
44
44
|
}
|
package/src/Audio.types.ts
CHANGED
|
@@ -176,7 +176,7 @@ export type RecordingOptionsIos = {
|
|
|
176
176
|
*/
|
|
177
177
|
outputFormat?: string | IOSOutputFormat | number;
|
|
178
178
|
/**
|
|
179
|
-
* The desired audio quality. See the [`
|
|
179
|
+
* The desired audio quality. See the [`AudioQuality`](#audioquality) enum for all valid values.
|
|
180
180
|
*/
|
|
181
181
|
audioQuality: AudioQuality | number;
|
|
182
182
|
/**
|
package/src/AudioModule.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { requireNativeModule } from 'expo-modules-core';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { NativeAudioModule } from './AudioModule.types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @hidden
|
|
7
|
+
*/
|
|
8
|
+
export default requireNativeModule<NativeAudioModule>('ExpoAudio');
|
package/src/AudioModule.types.ts
CHANGED
|
@@ -11,18 +11,19 @@ import {
|
|
|
11
11
|
RecordingStatus,
|
|
12
12
|
} from './Audio.types';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @hidden
|
|
16
|
+
*/
|
|
17
|
+
export declare class NativeAudioModule {
|
|
15
18
|
setIsAudioActiveAsync(active: boolean): Promise<void>;
|
|
16
19
|
setAudioModeAsync(category: Partial<AudioMode>): Promise<void>;
|
|
17
|
-
requestRecordingPermissionsAsync(): Promise<
|
|
18
|
-
getRecordingPermissionsAsync(): Promise<
|
|
20
|
+
requestRecordingPermissionsAsync(): Promise<PermissionResponse>;
|
|
21
|
+
getRecordingPermissionsAsync(): Promise<PermissionResponse>;
|
|
19
22
|
|
|
20
23
|
readonly AudioPlayer: typeof AudioPlayer;
|
|
21
24
|
readonly AudioRecorder: typeof AudioRecorder;
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
export type RecordingPermissionResponse = PermissionResponse;
|
|
25
|
-
|
|
26
27
|
export declare class AudioPlayer extends SharedObject<AudioEvents> {
|
|
27
28
|
/**
|
|
28
29
|
* Initializes a new audio player instance with the given source.
|
|
@@ -111,6 +112,11 @@ export declare class AudioPlayer extends SharedObject<AudioEvents> {
|
|
|
111
112
|
*/
|
|
112
113
|
pause(): void;
|
|
113
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Replaces the current audio source with a new one.
|
|
117
|
+
*/
|
|
118
|
+
replace(source: AudioSource): void;
|
|
119
|
+
|
|
114
120
|
/**
|
|
115
121
|
* Seeks the playback by the given number of seconds.
|
|
116
122
|
* @param seconds The number of seconds to seek by.
|
|
@@ -136,11 +142,13 @@ export declare class AudioPlayer extends SharedObject<AudioEvents> {
|
|
|
136
142
|
remove(): void;
|
|
137
143
|
}
|
|
138
144
|
|
|
139
|
-
type AudioSample = {
|
|
140
|
-
channels:
|
|
145
|
+
export type AudioSample = {
|
|
146
|
+
channels: AudioSampleChannel[];
|
|
141
147
|
timestamp: number;
|
|
142
148
|
};
|
|
143
149
|
|
|
150
|
+
export type AudioSampleChannel = { frames: number[] };
|
|
151
|
+
|
|
144
152
|
export type AudioEvents = {
|
|
145
153
|
playbackStatusUpdate(status: AudioStatus): void;
|
|
146
154
|
audioSampleUpdate(data: AudioSample): void;
|
package/src/AudioModule.web.ts
CHANGED
|
@@ -181,6 +181,11 @@ export class AudioPlayerWeb
|
|
|
181
181
|
this.isPlaying = false;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
replace(source: AudioSource): void {
|
|
185
|
+
this.src = source;
|
|
186
|
+
this.media = this._createMediaElement();
|
|
187
|
+
}
|
|
188
|
+
|
|
184
189
|
async seekTo(seconds: number): Promise<void> {
|
|
185
190
|
this.media.currentTime = seconds / 1000;
|
|
186
191
|
}
|
package/src/ExpoAudio.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEvent } from 'expo';
|
|
2
|
-
import { useReleasingSharedObject } from 'expo-modules-core';
|
|
2
|
+
import { PermissionResponse, useReleasingSharedObject } from 'expo-modules-core';
|
|
3
3
|
import { useEffect, useState, useMemo } from 'react';
|
|
4
4
|
|
|
5
5
|
import {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
RecordingStatus,
|
|
12
12
|
} from './Audio.types';
|
|
13
13
|
import AudioModule from './AudioModule';
|
|
14
|
-
import { AudioPlayer, AudioRecorder } from './AudioModule.types';
|
|
14
|
+
import { AudioPlayer, AudioRecorder, AudioSample } from './AudioModule.types';
|
|
15
15
|
import { createRecordingOptions } from './utils/options';
|
|
16
16
|
import { resolveSource } from './utils/resolveSource';
|
|
17
17
|
|
|
@@ -35,10 +35,7 @@ export function useAudioPlayerStatus(player: AudioPlayer): AudioStatus {
|
|
|
35
35
|
return useEvent(player, PLAYBACK_STATUS_UPDATE, currentStatus);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
export function useAudioSampleListener(
|
|
39
|
-
player: AudioPlayer,
|
|
40
|
-
listener: (data: { channels: { frames: number[] }[]; timestamp: number }) => void
|
|
41
|
-
) {
|
|
38
|
+
export function useAudioSampleListener(player: AudioPlayer, listener: (data: AudioSample) => void) {
|
|
42
39
|
player.setAudioSamplingEnabled(true);
|
|
43
40
|
useEffect(() => {
|
|
44
41
|
if (!player.isAudioSamplingSupported) {
|
|
@@ -92,6 +89,12 @@ export async function setAudioModeAsync(mode: Partial<AudioMode>): Promise<void>
|
|
|
92
89
|
return await AudioModule.setAudioModeAsync(mode);
|
|
93
90
|
}
|
|
94
91
|
|
|
95
|
-
export
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
export async function requestRecordingPermissionsAsync(): Promise<PermissionResponse> {
|
|
93
|
+
return await AudioModule.requestRecordingPermissionsAsync();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export async function getRecordingPermissionsAsync(): Promise<PermissionResponse> {
|
|
97
|
+
return await AudioModule.getRecordingPermissionsAsync();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export { AudioModule };
|
package/src/ExpoAudio.web.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEvent } from 'expo';
|
|
2
|
+
import { PermissionResponse } from 'expo-modules-core';
|
|
2
3
|
import { useEffect, useState, useMemo } from 'react';
|
|
3
4
|
|
|
4
5
|
import {
|
|
@@ -9,7 +10,7 @@ import {
|
|
|
9
10
|
RecordingOptions,
|
|
10
11
|
RecordingStatus,
|
|
11
12
|
} from './Audio.types';
|
|
12
|
-
import {
|
|
13
|
+
import { AudioRecorder, AudioSample } from './AudioModule.types';
|
|
13
14
|
import * as AudioModule from './AudioModule.web';
|
|
14
15
|
import { AUDIO_SAMPLE_UPDATE, PLAYBACK_STATUS_UPDATE, RECORDING_STATUS_UPDATE } from './ExpoAudio';
|
|
15
16
|
import { createRecordingOptions } from './utils/options';
|
|
@@ -39,7 +40,7 @@ export function useAudioPlayerStatus(player: AudioModule.AudioPlayerWeb): AudioS
|
|
|
39
40
|
|
|
40
41
|
export function useAudioSampleListener(
|
|
41
42
|
player: AudioModule.AudioPlayerWeb,
|
|
42
|
-
listener: (data:
|
|
43
|
+
listener: (data: AudioSample) => void
|
|
43
44
|
) {
|
|
44
45
|
player.setAudioSamplingEnabled(true);
|
|
45
46
|
useEffect(() => {
|
|
@@ -95,6 +96,12 @@ export async function setAudioModeAsync(mode: AudioMode): Promise<void> {
|
|
|
95
96
|
return await AudioModule.setAudioModeAsync(mode);
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
export
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
export async function requestRecordingPermissionsAsync(): Promise<PermissionResponse> {
|
|
100
|
+
return await AudioModule.requestRecordingPermissionsAsync();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function getRecordingPermissionsAsync(): Promise<PermissionResponse> {
|
|
104
|
+
return await AudioModule.getRecordingPermissionsAsync();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export { AudioModule };
|
|
@@ -50,23 +50,18 @@ const LOW_QUALITY: RecordingOptions = {
|
|
|
50
50
|
*
|
|
51
51
|
* # `HIGH_QUALITY`
|
|
52
52
|
* ```ts
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* RecordingPresets.HIGH_QUALITY = {
|
|
54
|
+
* extension: '.m4a',
|
|
55
|
+
* sampleRate: 44100,
|
|
56
|
+
* numberOfChannels: 2,
|
|
57
|
+
* bitRate: 128000,
|
|
55
58
|
* android: {
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* audioEncoder: AndroidAudioEncoder.AAC,
|
|
59
|
-
* sampleRate: 44100,
|
|
60
|
-
* numberOfChannels: 2,
|
|
61
|
-
* bitRate: 128000,
|
|
59
|
+
* outputFormat: 'mpeg4',
|
|
60
|
+
* audioEncoder: 'aac',
|
|
62
61
|
* },
|
|
63
62
|
* ios: {
|
|
64
|
-
* extension: '.m4a',
|
|
65
63
|
* outputFormat: IOSOutputFormat.MPEG4AAC,
|
|
66
|
-
* audioQuality:
|
|
67
|
-
* sampleRate: 44100,
|
|
68
|
-
* numberOfChannels: 2,
|
|
69
|
-
* bitRate: 128000,
|
|
64
|
+
* audioQuality: AudioQuality.MAX,
|
|
70
65
|
* linearPCMBitDepth: 16,
|
|
71
66
|
* linearPCMIsBigEndian: false,
|
|
72
67
|
* linearPCMIsFloat: false,
|
|
@@ -80,22 +75,19 @@ const LOW_QUALITY: RecordingOptions = {
|
|
|
80
75
|
*
|
|
81
76
|
* # `LOW_QUALITY`
|
|
82
77
|
* ```ts
|
|
83
|
-
*
|
|
84
|
-
*
|
|
78
|
+
* RecordingPresets.LOW_QUALITY = {
|
|
79
|
+
* extension: '.m4a',
|
|
80
|
+
* sampleRate: 44100,
|
|
81
|
+
* numberOfChannels: 2,
|
|
82
|
+
* bitRate: 64000,
|
|
85
83
|
* android: {
|
|
86
84
|
* extension: '.3gp',
|
|
87
|
-
* outputFormat:
|
|
88
|
-
* audioEncoder:
|
|
89
|
-
* sampleRate: 44100,
|
|
90
|
-
* numberOfChannels: 2,
|
|
91
|
-
* bitRate: 128000,
|
|
85
|
+
* outputFormat: '3gp',
|
|
86
|
+
* audioEncoder: 'amr_nb',
|
|
92
87
|
* },
|
|
93
88
|
* ios: {
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* sampleRate: 44100,
|
|
97
|
-
* numberOfChannels: 2,
|
|
98
|
-
* bitRate: 128000,
|
|
89
|
+
* audioQuality: AudioQuality.MIN,
|
|
90
|
+
* outputFormat: IOSOutputFormat.MPEG4AAC,
|
|
99
91
|
* linearPCMBitDepth: 16,
|
|
100
92
|
* linearPCMIsBigEndian: false,
|
|
101
93
|
* linearPCMIsFloat: false,
|
package/src/index.ts
CHANGED