expo-audio 0.2.0 → 0.2.2

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 (40) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/audio/AudioPlayer.kt +5 -2
  4. package/android/src/main/java/expo/modules/audio/AudioRecorder.kt +9 -15
  5. package/android/src/main/java/expo/modules/audio/AudioRecords.kt +4 -4
  6. package/app.plugin.js +1 -0
  7. package/build/Audio.types.d.ts +10 -12
  8. package/build/Audio.types.d.ts.map +1 -1
  9. package/build/Audio.types.js.map +1 -1
  10. package/build/AudioModule.types.d.ts +8 -8
  11. package/build/AudioModule.types.d.ts.map +1 -1
  12. package/build/AudioModule.types.js.map +1 -1
  13. package/build/AudioModule.web.d.ts.map +1 -1
  14. package/build/AudioModule.web.js +4 -3
  15. package/build/AudioModule.web.js.map +1 -1
  16. package/build/ExpoAudio.d.ts +3 -0
  17. package/build/ExpoAudio.d.ts.map +1 -1
  18. package/build/ExpoAudio.js +7 -5
  19. package/build/ExpoAudio.js.map +1 -1
  20. package/build/ExpoAudio.web.d.ts.map +1 -1
  21. package/build/ExpoAudio.web.js +4 -3
  22. package/build/ExpoAudio.web.js.map +1 -1
  23. package/build/utils/options.js +6 -6
  24. package/build/utils/options.js.map +1 -1
  25. package/ios/AudioModule.swift +18 -15
  26. package/ios/AudioPlayer.swift +18 -14
  27. package/ios/AudioRecorder.swift +57 -11
  28. package/ios/AudioRecords.swift +2 -2
  29. package/ios/AudioUtils.swift +2 -2
  30. package/package.json +2 -2
  31. package/plugin/build/withAudio.d.ts +5 -0
  32. package/plugin/build/withAudio.js +17 -0
  33. package/plugin/src/withAudio.ts +26 -0
  34. package/plugin/tsconfig.json +9 -0
  35. package/src/Audio.types.ts +10 -12
  36. package/src/AudioModule.types.ts +8 -8
  37. package/src/AudioModule.web.ts +4 -3
  38. package/src/ExpoAudio.ts +8 -6
  39. package/src/ExpoAudio.web.ts +4 -3
  40. package/src/utils/options.ts +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoAudio.web.d.ts","sourceRoot":"","sources":["../src/ExpoAudio.web.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,SAAS,EACT,WAAW,EACX,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AAIjD,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;IAAE,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,QAUlF;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,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AACnD,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"ExpoAudio.web.d.ts","sourceRoot":"","sources":["../src/ExpoAudio.web.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,SAAS,EACT,WAAW,EACX,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,aAAa,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;IAAE,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,QAUlF;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,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AACnD,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC"}
@@ -2,6 +2,7 @@ import { useEvent } from 'expo';
2
2
  import { useEffect, useState, useMemo } from 'react';
3
3
  import { AudioPlayer, AudioRecorder } from './AudioModule.types';
4
4
  import * as AudioModule from './AudioModule.web';
5
+ import { AUDIO_SAMPLE_UPDATE, PLAYBACK_STATUS_UPDATE, RECORDING_STATUS_UPDATE } from './ExpoAudio';
5
6
  import { createRecordingOptions } from './utils/options';
6
7
  import { resolveSource } from './utils/resolveSource';
7
8
  export function useAudioPlayer(source = null, updateInterval = 500) {
@@ -14,12 +15,12 @@ export function useAudioPlayer(source = null, updateInterval = 500) {
14
15
  }
15
16
  export function useAudioPlayerStatus(player) {
16
17
  const currentStatus = useMemo(() => player.currentStatus, [player.id]);
17
- return useEvent(player, 'onPlaybackStatusUpdate', currentStatus);
18
+ return useEvent(player, PLAYBACK_STATUS_UPDATE, currentStatus);
18
19
  }
19
20
  export function useAudioSampleListener(player, listener) {
20
21
  player.setAudioSamplingEnabled(true);
21
22
  useEffect(() => {
22
- const subscription = player.addListener('onAudioSampleUpdate', listener);
23
+ const subscription = player.addListener(AUDIO_SAMPLE_UPDATE, listener);
23
24
  return () => {
24
25
  player.setAudioSamplingEnabled(false);
25
26
  subscription.remove();
@@ -32,7 +33,7 @@ export function useAudioRecorder(options, statusListener) {
32
33
  return new AudioModule.AudioRecorderWeb(platformOptions);
33
34
  }, [JSON.stringify(platformOptions)]);
34
35
  useEffect(() => {
35
- const subscription = recorder.addListener('onRecordingStatusUpdate', (status) => {
36
+ const subscription = recorder.addListener(RECORDING_STATUS_UPDATE, (status) => {
36
37
  statusListener?.(status);
37
38
  });
38
39
  return () => {
@@ -1 +1 @@
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 { useEffect, useState, useMemo } from 'react';\n\nimport {\n AudioMode,\n AudioSource,\n AudioStatus,\n RecorderState,\n RecordingOptions,\n RecordingStatus,\n} from './Audio.types';\nimport { AudioPlayer, AudioRecorder } from './AudioModule.types';\nimport * as AudioModule from './AudioModule.web';\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, 'onPlaybackStatusUpdate', currentStatus);\n}\n\nexport function useAudioSampleListener(\n player: AudioModule.AudioPlayerWeb,\n listener: (data: { channels: { frames: number[] }[]; timestamp: number }) => void\n) {\n player.setAudioSamplingEnabled(true);\n useEffect(() => {\n const subscription = player.addListener('onAudioSampleUpdate', 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('onRecordingStatusUpdate', (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 { AudioModule, AudioPlayer, AudioRecorder };\nexport * from './Audio.types';\nexport * from './RecordingConstants';\n"]}
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 { useEffect, useState, useMemo } from 'react';\n\nimport {\n AudioMode,\n AudioSource,\n AudioStatus,\n RecorderState,\n RecordingOptions,\n RecordingStatus,\n} from './Audio.types';\nimport { AudioPlayer, AudioRecorder } 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: { channels: { frames: number[] }[]; timestamp: number }) => 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 { AudioModule, AudioPlayer, AudioRecorder };\nexport * from './Audio.types';\nexport * from './RecordingConstants';\n"]}
@@ -1,23 +1,23 @@
1
1
  import { Platform } from 'expo-modules-core';
2
2
  export function createRecordingOptions(options) {
3
- let newOptions = {
3
+ let commonOptions = {
4
4
  extension: options.extension,
5
5
  sampleRate: options.sampleRate,
6
6
  numberOfChannels: options.numberOfChannels,
7
7
  bitRate: options.bitRate,
8
8
  };
9
9
  if (Platform.OS === 'ios') {
10
- newOptions = {
11
- ...newOptions,
10
+ commonOptions = {
11
+ ...commonOptions,
12
12
  ...options.ios,
13
13
  };
14
14
  }
15
15
  else if (Platform.OS === 'android') {
16
- newOptions = {
17
- ...newOptions,
16
+ commonOptions = {
17
+ ...commonOptions,
18
18
  ...options.android,
19
19
  };
20
20
  }
21
- return newOptions;
21
+ return commonOptions;
22
22
  }
23
23
  //# sourceMappingURL=options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/utils/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,MAAM,UAAU,sBAAsB,CAAC,OAAyB;IAC9D,IAAI,UAAU,GAAG;QACf,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,UAAU,GAAG;YACX,GAAG,UAAU;YACb,GAAG,OAAO,CAAC,GAAG;SACf,CAAC;KACH;SAAM,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE;QACpC,UAAU,GAAG;YACX,GAAG,UAAU;YACb,GAAG,OAAO,CAAC,OAAO;SACnB,CAAC;KACH;IACD,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import { Platform } from 'expo-modules-core';\n\nimport { RecordingOptions } from '../Audio.types';\n\nexport function createRecordingOptions(options: RecordingOptions) {\n let newOptions = {\n extension: options.extension,\n sampleRate: options.sampleRate,\n numberOfChannels: options.numberOfChannels,\n bitRate: options.bitRate,\n };\n\n if (Platform.OS === 'ios') {\n newOptions = {\n ...newOptions,\n ...options.ios,\n };\n } else if (Platform.OS === 'android') {\n newOptions = {\n ...newOptions,\n ...options.android,\n };\n }\n return newOptions;\n}\n"]}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/utils/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,MAAM,UAAU,sBAAsB,CAAC,OAAyB;IAC9D,IAAI,aAAa,GAAG;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,aAAa,GAAG;YACd,GAAG,aAAa;YAChB,GAAG,OAAO,CAAC,GAAG;SACf,CAAC;KACH;SAAM,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE;QACpC,aAAa,GAAG;YACd,GAAG,aAAa;YAChB,GAAG,OAAO,CAAC,OAAO;SACnB,CAAC;KACH;IACD,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import { Platform } from 'expo-modules-core';\n\nimport { RecordingOptions } from '../Audio.types';\n\nexport function createRecordingOptions(options: RecordingOptions) {\n let commonOptions = {\n extension: options.extension,\n sampleRate: options.sampleRate,\n numberOfChannels: options.numberOfChannels,\n bitRate: options.bitRate,\n };\n\n if (Platform.OS === 'ios') {\n commonOptions = {\n ...commonOptions,\n ...options.ios,\n };\n } else if (Platform.OS === 'android') {\n commonOptions = {\n ...commonOptions,\n ...options.android,\n };\n }\n return commonOptions;\n}\n"]}
@@ -165,10 +165,8 @@ public class AudioModule: Module {
165
165
  // swiftlint:disable:next closure_body_length
166
166
  Class(AudioRecorder.self) {
167
167
  Constructor { (options: RecordingOptions) -> AudioRecorder in
168
- guard let cachesDir = appContext?.fileSystem?.cachesDirectory, let directory = URL(string: cachesDir) else {
169
- throw Exceptions.AppContextLost()
170
- }
171
- let avRecorder = AudioUtils.createRecorder(directory: directory, with: options)
168
+ let recordingDir = try recordingDirectory()
169
+ let avRecorder = AudioUtils.createRecorder(directory: recordingDir, with: options)
172
170
  let recorder = AudioRecorder(avRecorder)
173
171
  AudioComponentRegistry.shared.add(recorder)
174
172
 
@@ -191,26 +189,23 @@ public class AudioModule: Module {
191
189
  recorder.uri
192
190
  }
193
191
 
192
+ AsyncFunction("prepareToRecordAsync") { (recorder, options: RecordingOptions?) in
193
+ recorder.prepare(options: options)
194
+ }
195
+
194
196
  Function("record") { (recorder: AudioRecorder) -> [String: Any] in
195
197
  try checkPermissions()
196
- recorder.ref.record()
197
- recorder.startTimestamp = Int(recorder.deviceCurrentTime)
198
- return recorder.getRecordingStatus()
198
+ return recorder.startRecording()
199
199
  }
200
200
 
201
201
  Function("pause") { recorder in
202
202
  try checkPermissions()
203
- recorder.ref.pause()
204
- let current = recorder.deviceCurrentTime
205
- recorder.previousRecordingDuration += (current - recorder.startTimestamp)
206
- recorder.startTimestamp = 0
203
+ recorder.pauseRecording()
207
204
  }
208
205
 
209
- Function("stop") { recorder in
206
+ AsyncFunction("stop") { recorder in
210
207
  try checkPermissions()
211
- recorder.ref.stop()
212
- recorder.startTimestamp = 0
213
- recorder.previousRecordingDuration = 0
208
+ recorder.stopRecording()
214
209
  }
215
210
 
216
211
  Function("getStatus") { recorder -> [String: Any] in
@@ -241,6 +236,13 @@ public class AudioModule: Module {
241
236
  }
242
237
  }
243
238
 
239
+ private func recordingDirectory() throws -> URL {
240
+ guard let cachesDir = appContext?.fileSystem?.cachesDirectory, let directory = URL(string: cachesDir) else {
241
+ throw Exceptions.AppContextLost()
242
+ }
243
+ return directory
244
+ }
245
+
244
246
  private func setIsAudioActive(_ isActive: Bool) throws {
245
247
  if !isActive {
246
248
  for player in AudioComponentRegistry.shared.players.values {
@@ -265,6 +267,7 @@ public class AudioModule: Module {
265
267
  AudioComponentRegistry.shared.recorders.values.forEach { recorder in
266
268
  if recorder.isRecording {
267
269
  recorder.ref.stop()
270
+ recorder.allowsRecording = false
268
271
  }
269
272
  }
270
273
  }
@@ -1,8 +1,10 @@
1
1
  import ExpoModulesCore
2
2
  import Combine
3
3
 
4
- private let playbackStatus = "onPlaybackStatusUpdate"
5
- private let audioSample = "onAudioSampleUpdate"
4
+ private enum AudioConstants {
5
+ static let playbackStatus = "playbackStatusUpdate"
6
+ static let audioSample = "audioSampleUpdate"
7
+ }
6
8
 
7
9
  public class AudioPlayer: SharedRef<AVPlayer> {
8
10
  let id = UUID().uuidString
@@ -21,6 +23,10 @@ public class AudioPlayer: SharedRef<AVPlayer> {
21
23
  private var samplingEnabled = false
22
24
  private var tapInstalled = false
23
25
 
26
+ private var duration: Double {
27
+ (ref.currentItem?.duration.seconds ?? 0.0) * 1000
28
+ }
29
+
24
30
  init(_ ref: AVPlayer, interval: Double) {
25
31
  self.interval = interval
26
32
  super.init(ref)
@@ -56,8 +62,7 @@ public class AudioPlayer: SharedRef<AVPlayer> {
56
62
  }
57
63
 
58
64
  func currentStatus() -> [String: Any] {
59
- let time = ref.currentItem?.duration
60
- let duration = ref.status == .readyToPlay ? (time?.seconds ?? 0.0) : 0.0
65
+ let duration = ref.status == .readyToPlay ? duration : 0.0
61
66
  return [
62
67
  "id": id,
63
68
  "currentTime": (ref.currentItem?.currentTime().seconds ?? 0) * 1000,
@@ -65,7 +70,7 @@ public class AudioPlayer: SharedRef<AVPlayer> {
65
70
  "timeControlStatus": timeControlStatusString(status: ref.timeControlStatus),
66
71
  "reasonForWaitingToPlay": reasonForWaitingToPlayString(status: ref.reasonForWaitingToPlay),
67
72
  "mute": ref.isMuted,
68
- "duration": duration * 1000,
73
+ "duration": duration,
69
74
  "playing": ref.timeControlStatus == .playing,
70
75
  "loop": isLooping,
71
76
  "isLoaded": ref.currentItem?.status == .readyToPlay,
@@ -76,11 +81,11 @@ public class AudioPlayer: SharedRef<AVPlayer> {
76
81
  }
77
82
 
78
83
  func updateStatus(with dict: [String: Any]) {
79
- var body = currentStatus()
80
- body.merge(dict) { _, new in
84
+ var arguments = currentStatus()
85
+ arguments.merge(dict) { _, new in
81
86
  new
82
87
  }
83
- self.emit(event: playbackStatus, arguments: body)
88
+ self.emit(event: AudioConstants.playbackStatus, arguments: arguments)
84
89
  }
85
90
 
86
91
  private func setupPublisher() {
@@ -99,9 +104,7 @@ public class AudioPlayer: SharedRef<AVPlayer> {
99
104
  }
100
105
 
101
106
  private func playerIsBuffering() -> Bool {
102
- let isPlaying = ref.timeControlStatus == .playing
103
-
104
- if isPlaying {
107
+ if ref.timeControlStatus == .playing {
105
108
  return false
106
109
  }
107
110
 
@@ -137,7 +140,7 @@ public class AudioPlayer: SharedRef<AVPlayer> {
137
140
  return ["frames": channelData]
138
141
  }
139
142
 
140
- self.emit(event: audioSample, arguments: [
143
+ self.emit(event: AudioConstants.audioSample, arguments: [
141
144
  "channels": channels,
142
145
  "timestamp": timestamp
143
146
  ])
@@ -165,7 +168,8 @@ public class AudioPlayer: SharedRef<AVPlayer> {
165
168
  self.ref.play()
166
169
  } else {
167
170
  self.updateStatus(with: [
168
- "isPlaying": false
171
+ "isPlaying": false,
172
+ "currentTime": self.duration
169
173
  ])
170
174
  }
171
175
  }
@@ -176,7 +180,7 @@ public class AudioPlayer: SharedRef<AVPlayer> {
176
180
  let interval = CMTime(seconds: updateInterval, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
177
181
  timeToken = ref.addPeriodicTimeObserver(forInterval: interval, queue: nil) { time in
178
182
  self.updateStatus(with: [
179
- "currentPosition": time.seconds * 1000
183
+ "currentTime": time.seconds * 1000
180
184
  ])
181
185
  }
182
186
  }
@@ -1,25 +1,28 @@
1
1
  import ExpoModulesCore
2
2
 
3
- private let recordingStatus = "onRecordingStatusUpdate"
3
+ private let recordingStatus = "recordingStatusUpdate"
4
4
 
5
5
  class AudioRecorder: SharedRef<AVAudioRecorder>, RecordingResultHandler {
6
6
  let id = UUID().uuidString
7
7
  private lazy var recordingDelegate = {
8
8
  RecordingDelegate(resultHandler: self)
9
9
  }()
10
- var startTimestamp = 0
11
- var previousRecordingDuration = 0
10
+ private var startTimestamp = 0
11
+ private var previousRecordingDuration = 0
12
+ private var isPrepared = false
13
+ private lazy var recordingSession = AVAudioSession.sharedInstance()
14
+ var allowsRecording = true
12
15
 
13
- override init(_ pointer: AVAudioRecorder) {
14
- super.init(pointer)
15
- pointer.delegate = recordingDelegate
16
+ override init(_ ref: AVAudioRecorder) {
17
+ super.init(ref)
18
+ ref.delegate = recordingDelegate
16
19
 
17
20
  do {
18
- try AVAudioSession.sharedInstance().setCategory(.playAndRecord)
21
+ try recordingSession.setCategory(.playAndRecord, mode: .default)
22
+ try recordingSession.setActive(true)
19
23
  } catch {
20
- print("Failed to set recording category")
24
+ log.info("Failed to update the recording session")
21
25
  }
22
- ref.prepareToRecord()
23
26
  }
24
27
 
25
28
  var isRecording: Bool {
@@ -38,12 +41,48 @@ class AudioRecorder: SharedRef<AVAudioRecorder>, RecordingResultHandler {
38
41
  ref.url.absoluteString
39
42
  }
40
43
 
44
+ private var currentDuration: Int {
45
+ deviceCurrentTime - startTimestamp
46
+ }
47
+
48
+ func prepare(options: RecordingOptions?) {
49
+ if let options {
50
+ ref = AudioUtils.createRecorder(directory: recordingDirectory, with: options)
51
+ ref.delegate = recordingDelegate
52
+ }
53
+ ref.prepareToRecord()
54
+ isPrepared = true
55
+ }
56
+
57
+ func startRecording() -> [String: Any] {
58
+ if !allowsRecording {
59
+ log.info("Recording is currently disabled")
60
+ return [:]
61
+ }
62
+ ref.record()
63
+ startTimestamp = Int(deviceCurrentTime)
64
+ return getRecordingStatus()
65
+ }
66
+
67
+ func stopRecording() {
68
+ ref.stop()
69
+ startTimestamp = 0
70
+ previousRecordingDuration = 0
71
+ isPrepared = false
72
+ }
73
+
74
+ func pauseRecording() {
75
+ ref.pause()
76
+ previousRecordingDuration += currentDuration
77
+ startTimestamp = 0
78
+ }
79
+
41
80
  func getRecordingStatus() -> [String: Any] {
42
- let currentDuration = isRecording ? (deviceCurrentTime - startTimestamp) : 0
81
+ let currentDuration = isRecording ? currentDuration : 0
43
82
  let duration = previousRecordingDuration + Int(currentDuration)
44
83
 
45
84
  var result: [String: Any] = [
46
- "canRecord": true,
85
+ "canRecord": isPrepared,
47
86
  "isRecording": isRecording,
48
87
  "durationMillis": duration,
49
88
  "mediaServicesDidReset": false,
@@ -79,6 +118,13 @@ class AudioRecorder: SharedRef<AVAudioRecorder>, RecordingResultHandler {
79
118
  ])
80
119
  }
81
120
 
121
+ private var recordingDirectory: URL? {
122
+ guard let cachesDir = appContext?.fileSystem?.cachesDirectory, let directory = URL(string: cachesDir) else {
123
+ return nil
124
+ }
125
+ return directory
126
+ }
127
+
82
128
  override func sharedObjectWillRelease() {
83
129
  AudioComponentRegistry.shared.remove(self)
84
130
  ref.stop()
@@ -32,11 +32,11 @@ enum PitchCorrectionQuality: String, Enumerable {
32
32
 
33
33
  struct RecordingOptions: Record {
34
34
  @Field var `extension`: String
35
- @Field var outputFormat: String?
36
- @Field var audioQuality: Int
37
35
  @Field var sampleRate: Double
38
36
  @Field var numberOfChannels: Double
39
37
  @Field var bitRate: Double
38
+ @Field var outputFormat: String?
39
+ @Field var audioQuality: Int
40
40
  @Field var bitRateStrategy: BitRateStrategy?
41
41
  @Field var bitDepthHint: Double?
42
42
  @Field var linearPCMBitDepth: Double?
@@ -73,7 +73,7 @@ struct AudioUtils {
73
73
  if let directory {
74
74
  let fileUrl = createRecordingUrl(from: directory, with: options)
75
75
  do {
76
- return try AVAudioRecorder(url: fileUrl, settings: AudioUtils.setRecordingOptions(options))
76
+ return try AVAudioRecorder(url: fileUrl, settings: AudioUtils.createRecordingOptions(options))
77
77
  } catch {
78
78
  return AVAudioRecorder()
79
79
  }
@@ -90,7 +90,7 @@ struct AudioUtils {
90
90
  return AVPlayer()
91
91
  }
92
92
 
93
- static func setRecordingOptions(_ options: RecordingOptions) -> [String: Any] {
93
+ static func createRecordingOptions(_ options: RecordingOptions) -> [String: Any] {
94
94
  let strategy = options.bitRateStrategy?.toAVBitRateStrategy() ?? AVAudioBitRateStrategy_Variable
95
95
 
96
96
  var settings = [String: Any]()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-audio",
3
3
  "title": "Expo Audio",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
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": "7c7d2362fff23bec26cd145ed34edd9c403551bd"
43
+ "gitHead": "2e4f18d41da033c5ced0a4a045d91cf5250016b7"
44
44
  }
@@ -0,0 +1,5 @@
1
+ import { ConfigPlugin } from 'expo/config-plugins';
2
+ declare const _default: ConfigPlugin<void | {
3
+ microphonePermission?: string | false | undefined;
4
+ }>;
5
+ export default _default;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_plugins_1 = require("expo/config-plugins");
4
+ const pkg = require('expo-audio/package.json');
5
+ const MICROPHONE_USAGE = 'Allow $(PRODUCT_NAME) to access your microphone';
6
+ const withAudio = (config, { microphonePermission } = {}) => {
7
+ config_plugins_1.IOSConfig.Permissions.createPermissionsPlugin({
8
+ NSMicrophoneUsageDescription: MICROPHONE_USAGE,
9
+ })(config, {
10
+ NSMicrophoneUsageDescription: microphonePermission,
11
+ });
12
+ return config_plugins_1.AndroidConfig.Permissions.withPermissions(config, [
13
+ microphonePermission !== false && 'android.permission.RECORD_AUDIO',
14
+ 'android.permission.MODIFY_AUDIO_SETTINGS',
15
+ ].filter(Boolean));
16
+ };
17
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withAudio, pkg.name, pkg.version);
@@ -0,0 +1,26 @@
1
+ import { AndroidConfig, ConfigPlugin, IOSConfig, createRunOncePlugin } from 'expo/config-plugins';
2
+
3
+ const pkg = require('expo-audio/package.json');
4
+
5
+ const MICROPHONE_USAGE = 'Allow $(PRODUCT_NAME) to access your microphone';
6
+
7
+ const withAudio: ConfigPlugin<{ microphonePermission?: string | false } | void> = (
8
+ config,
9
+ { microphonePermission } = {}
10
+ ) => {
11
+ IOSConfig.Permissions.createPermissionsPlugin({
12
+ NSMicrophoneUsageDescription: MICROPHONE_USAGE,
13
+ })(config, {
14
+ NSMicrophoneUsageDescription: microphonePermission,
15
+ });
16
+
17
+ return AndroidConfig.Permissions.withPermissions(
18
+ config,
19
+ [
20
+ microphonePermission !== false && 'android.permission.RECORD_AUDIO',
21
+ 'android.permission.MODIFY_AUDIO_SETTINGS',
22
+ ].filter(Boolean) as string[]
23
+ );
24
+ };
25
+
26
+ export default createRunOncePlugin(withAudio, pkg.name, pkg.version);
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "expo-module-scripts/tsconfig.plugin",
3
+ "compilerOptions": {
4
+ "outDir": "build",
5
+ "rootDir": "src"
6
+ },
7
+ "include": ["./src"],
8
+ "exclude": ["**/__mocks__/*", "**/__tests__/*"]
9
+ }
@@ -118,25 +118,25 @@ export type RecordingOptions = {
118
118
  /**
119
119
  * The desired file extension.
120
120
  *
121
- * @example `'.caf'`
121
+ * @example .caf
122
122
  */
123
123
  extension: string;
124
124
  /**
125
125
  * The desired sample rate.
126
126
  *
127
- * @example `44100`
127
+ * @example 44100
128
128
  */
129
129
  sampleRate: number;
130
130
  /**
131
131
  * The desired number of channels.
132
132
  *
133
- * @example `1`, `2`
133
+ * @example 2
134
134
  */
135
135
  numberOfChannels: number;
136
136
  /**
137
137
  * The desired bit rate.
138
138
  *
139
- * @example `128000`
139
+ * @example 128000
140
140
  */
141
141
  bitRate: number;
142
142
  /**
@@ -162,13 +162,13 @@ export type RecordingOptionsIos = {
162
162
  /**
163
163
  * The desired file extension.
164
164
  *
165
- * @example `'.caf'`
165
+ * @example .caf
166
166
  */
167
167
  extension?: string;
168
168
  /**
169
169
  * The desired sample rate.
170
170
  *
171
- * @example `44100`
171
+ * @example 44100
172
172
  */
173
173
  sampleRate?: number;
174
174
  /**
@@ -186,15 +186,13 @@ export type RecordingOptionsIos = {
186
186
  /**
187
187
  * The desired bit depth hint.
188
188
  *
189
- * @example
190
- * `16`
189
+ * @example 16
191
190
  */
192
191
  bitDepthHint?: number;
193
192
  /**
194
193
  * The desired PCM bit depth.
195
194
  *
196
- * @example
197
- * `16`
195
+ * @example 16
198
196
  */
199
197
  linearPCMBitDepth?: number;
200
198
  /**
@@ -211,13 +209,13 @@ export type RecordingOptionsAndroid = {
211
209
  /**
212
210
  * The desired file extension.
213
211
  *
214
- * @example `'.caf'`
212
+ * @example .caf
215
213
  */
216
214
  extension?: string;
217
215
  /**
218
216
  * The desired sample rate.
219
217
  *
220
- * @example `44100`
218
+ * @example 44100
221
219
  */
222
220
  sampleRate?: number;
223
221
  /**
@@ -76,7 +76,7 @@ export declare class AudioPlayer extends SharedObject<AudioEvents> {
76
76
  currentTime: number;
77
77
 
78
78
  /**
79
- * The total duration of the audio, in seconds.
79
+ * The total duration of the audio in seconds.
80
80
  */
81
81
  duration: number;
82
82
 
@@ -102,7 +102,7 @@ export declare class AudioPlayer extends SharedObject<AudioEvents> {
102
102
  currentStatus: AudioStatus;
103
103
 
104
104
  /**
105
- * Resumes the player.
105
+ * Start playing audio.
106
106
  */
107
107
  play(): void;
108
108
 
@@ -122,7 +122,7 @@ export declare class AudioPlayer extends SharedObject<AudioEvents> {
122
122
  * @param rate The playback rate of the audio.
123
123
  * @param pitchCorrectionQuality The quality of the pitch correction.
124
124
  */
125
- setPlaybackRate(second: number, pitchCorrectionQuality?: PitchCorrectionQuality): void;
125
+ setPlaybackRate(rate: number, pitchCorrectionQuality?: PitchCorrectionQuality): void;
126
126
 
127
127
  /**
128
128
  *
@@ -142,8 +142,8 @@ type AudioSample = {
142
142
  };
143
143
 
144
144
  export type AudioEvents = {
145
- onPlaybackStatusUpdate(status: AudioStatus): void;
146
- onAudioSampleUpdate(data: AudioSample): void;
145
+ playbackStatusUpdate(status: AudioStatus): void;
146
+ audioSampleUpdate(data: AudioSample): void;
147
147
  };
148
148
 
149
149
  export declare class AudioRecorder extends SharedObject<RecordingEvents> {
@@ -205,7 +205,7 @@ export declare class AudioRecorder extends SharedObject<RecordingEvents> {
205
205
  * @param inputUid The uid of a `RecordingInput`.
206
206
  * @return A `Promise` that is resolved if successful or rejected if not.
207
207
  */
208
- setInput(input: string): void;
208
+ setInput(inputUid: string): void;
209
209
 
210
210
  /**
211
211
  * Status of the current recording.
@@ -221,7 +221,7 @@ export declare class AudioRecorder extends SharedObject<RecordingEvents> {
221
221
  /**
222
222
  * Prepares the recording for recording.
223
223
  */
224
- prepareToRecordAsync(options?: RecordingOptions): Promise<void>;
224
+ prepareToRecordAsync(options?: Partial<RecordingOptions>): Promise<void>;
225
225
 
226
226
  /**
227
227
  * Stops the recording once the specified time has elapsed.
@@ -231,5 +231,5 @@ export declare class AudioRecorder extends SharedObject<RecordingEvents> {
231
231
  }
232
232
 
233
233
  export type RecordingEvents = {
234
- onRecordingStatusUpdate: (status: RecordingStatus) => void;
234
+ recordingStatusUpdate: (status: RecordingStatus) => void;
235
235
  };
@@ -10,6 +10,7 @@ import {
10
10
  RecordingOptions,
11
11
  } from './Audio.types';
12
12
  import { AudioPlayer, AudioEvents, RecordingEvents, AudioRecorder } from './AudioModule.types';
13
+ import { PLAYBACK_STATUS_UPDATE, RECORDING_STATUS_UPDATE } from './ExpoAudio';
13
14
  import { RecordingPresets } from './RecordingConstants';
14
15
 
15
16
  const nextId = (() => {
@@ -207,12 +208,12 @@ export class AudioPlayerWeb
207
208
  const media = new Audio(newSource);
208
209
 
209
210
  media.ontimeupdate = () => {
210
- this.emit('onPlaybackStatusUpdate', getStatusFromMedia(media, this.id));
211
+ this.emit(PLAYBACK_STATUS_UPDATE, getStatusFromMedia(media, this.id));
211
212
  };
212
213
 
213
214
  media.onloadeddata = () => {
214
215
  this.loaded = true;
215
- this.emit('onPlaybackStatusUpdate', {
216
+ this.emit(PLAYBACK_STATUS_UPDATE, {
216
217
  ...getStatusFromMedia(media, this.id),
217
218
  isLoaded: this.loaded,
218
219
  });
@@ -338,7 +339,7 @@ export class AudioRecorderWeb
338
339
 
339
340
  this.uri = url;
340
341
 
341
- this.emit('onRecordingStatusUpdate', {
342
+ this.emit(RECORDING_STATUS_UPDATE, {
342
343
  id: this.id,
343
344
  isFinished: true,
344
345
  hasError: false,