expo-audio 1.1.0 → 1.1.1

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 (57) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/audio/AudioModule.kt +9 -4
  4. package/android/src/main/java/expo/modules/audio/AudioRecords.kt +2 -1
  5. package/build/Audio.types.d.ts +18 -13
  6. package/build/Audio.types.d.ts.map +1 -1
  7. package/build/Audio.types.js.map +1 -1
  8. package/build/ExpoAudio.d.ts +1 -2
  9. package/build/ExpoAudio.d.ts.map +1 -1
  10. package/build/ExpoAudio.js +2 -3
  11. package/build/ExpoAudio.js.map +1 -1
  12. package/expo-module.config.json +1 -1
  13. package/local-maven-repo/expo/modules/audio/expo.modules.audio/{1.1.0/expo.modules.audio-1.1.0-sources.jar → 1.1.1/expo.modules.audio-1.1.1-sources.jar} +0 -0
  14. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1-sources.jar.md5 +1 -0
  15. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1-sources.jar.sha1 +1 -0
  16. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1-sources.jar.sha256 +1 -0
  17. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1-sources.jar.sha512 +1 -0
  18. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.aar +0 -0
  19. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.aar.md5 +1 -0
  20. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.aar.sha1 +1 -0
  21. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.aar.sha256 +1 -0
  22. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.aar.sha512 +1 -0
  23. package/local-maven-repo/expo/modules/audio/expo.modules.audio/{1.1.0/expo.modules.audio-1.1.0.module → 1.1.1/expo.modules.audio-1.1.1.module} +22 -22
  24. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.module.md5 +1 -0
  25. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.module.sha1 +1 -0
  26. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.module.sha256 +1 -0
  27. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.module.sha512 +1 -0
  28. package/local-maven-repo/expo/modules/audio/expo.modules.audio/{1.1.0/expo.modules.audio-1.1.0.pom → 1.1.1/expo.modules.audio-1.1.1.pom} +1 -1
  29. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.pom.md5 +1 -0
  30. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.pom.sha1 +1 -0
  31. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.pom.sha256 +1 -0
  32. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.1/expo.modules.audio-1.1.1.pom.sha512 +1 -0
  33. package/local-maven-repo/expo/modules/audio/expo.modules.audio/maven-metadata.xml +4 -4
  34. package/local-maven-repo/expo/modules/audio/expo.modules.audio/maven-metadata.xml.md5 +1 -1
  35. package/local-maven-repo/expo/modules/audio/expo.modules.audio/maven-metadata.xml.sha1 +1 -1
  36. package/local-maven-repo/expo/modules/audio/expo.modules.audio/maven-metadata.xml.sha256 +1 -1
  37. package/local-maven-repo/expo/modules/audio/expo.modules.audio/maven-metadata.xml.sha512 +1 -1
  38. package/package.json +2 -2
  39. package/src/Audio.types.ts +18 -13
  40. package/src/ExpoAudio.ts +2 -3
  41. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0-sources.jar.md5 +0 -1
  42. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0-sources.jar.sha1 +0 -1
  43. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0-sources.jar.sha256 +0 -1
  44. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0-sources.jar.sha512 +0 -1
  45. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.aar +0 -0
  46. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.aar.md5 +0 -1
  47. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.aar.sha1 +0 -1
  48. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.aar.sha256 +0 -1
  49. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.aar.sha512 +0 -1
  50. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.module.md5 +0 -1
  51. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.module.sha1 +0 -1
  52. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.module.sha256 +0 -1
  53. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.module.sha512 +0 -1
  54. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.pom.md5 +0 -1
  55. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.pom.sha1 +0 -1
  56. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.pom.sha256 +0 -1
  57. package/local-maven-repo/expo/modules/audio/expo.modules.audio/1.1.0/expo.modules.audio-1.1.0.pom.sha512 +0 -1
package/CHANGELOG.md CHANGED
@@ -10,12 +10,17 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 1.1.1 — 2025-12-17
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
13
17
  ## 1.1.0 — 2025-12-11
14
18
 
15
19
  ### 🎉 New features
16
20
 
17
21
  - [iOS/Android] Add showSeekForward and showSeekBackward options to AudioLockScreenOptions to control visibility of seek buttons on lock screen. ([#40124](https://github.com/expo/expo/pull/40124) by [@chrfalch](https://github.com/chrfalch))
18
22
  - [iOS/Android] Add support background recording. ([#41134](https://github.com/expo/expo/pull/41134) by [@alanjhughes](https://github.com/alanjhughes))
23
+ - [Android] Support `mixWithOthers` interruption mode. ([#41670](https://github.com/expo/expo/pull/41670) by [@alanjhughes](https://github.com/alanjhughes))
19
24
 
20
25
  ### 🐛 Bug fixes
21
26
 
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'expo.modules.audio'
7
- version = '1.1.0'
7
+ version = '1.1.1'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.audio"
11
11
  defaultConfig {
12
12
  versionCode 1
13
- versionName "1.1.0"
13
+ versionName "1.1.1"
14
14
  }
15
15
 
16
16
  compileOptions {
@@ -116,18 +116,18 @@ class AudioModule : Module() {
116
116
  }
117
117
 
118
118
  private fun requestAudioFocus() {
119
- if (focusAcquired || !audioEnabled) {
119
+ if (focusAcquired || !audioEnabled || interruptionMode == InterruptionMode.MIX_WITH_OTHERS) {
120
120
  return
121
121
  }
122
122
 
123
123
  val result = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
124
124
  val requestType = interruptionMode?.let {
125
125
  if (it == InterruptionMode.DO_NOT_MIX) {
126
- AudioManager.AUDIOFOCUS_GAIN
126
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
127
127
  } else {
128
128
  AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
129
129
  }
130
- } ?: AudioManager.AUDIOFOCUS_GAIN
130
+ } ?: AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
131
131
  audioFocusRequest = AudioFocusRequest.Builder(requestType).run {
132
132
  setAudioAttributes(
133
133
  AudioAttributes.Builder()
@@ -143,7 +143,12 @@ class AudioModule : Module() {
143
143
  }
144
144
  } else {
145
145
  @Suppress("DEPRECATION")
146
- audioManager.requestAudioFocus(audioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)
146
+ val requestType = if (interruptionMode == InterruptionMode.DO_NOT_MIX) {
147
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
148
+ } else {
149
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
150
+ }
151
+ audioManager.requestAudioFocus(audioFocusChangeListener, AudioManager.STREAM_MUSIC, requestType)
147
152
  }
148
153
 
149
154
  if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
@@ -99,7 +99,8 @@ class AudioLockScreenOptions(
99
99
 
100
100
  enum class InterruptionMode(val value: String) : Enumerable {
101
101
  DO_NOT_MIX("doNotMix"),
102
- DUCK_OTHERS("duckOthers")
102
+ DUCK_OTHERS("duckOthers"),
103
+ MIX_WITH_OTHERS("mixWithOthers")
103
104
  }
104
105
 
105
106
  class RecordOptions(
@@ -425,17 +425,22 @@ export type AudioMode = {
425
425
  */
426
426
  playsInSilentMode: boolean;
427
427
  /**
428
- * Determines how the audio session interacts with other sessions.
428
+ * Determines how the audio session interacts with other audio sessions.
429
429
  *
430
- * @platform ios
430
+ * - `'doNotMix'`: Requests exclusive audio focus. Other apps will pause their audio.
431
+ * - `'duckOthers'`: Requests audio focus with ducking. Other apps lower their volume but continue playing.
432
+ * - `'mixWithOthers'`: Audio plays alongside other apps without interrupting them.
433
+ * On Android, this means no audio focus is requested. Best suited for sound effects,
434
+ * UI feedback, or short audio clips.
431
435
  */
432
436
  interruptionMode: InterruptionMode;
433
437
  /**
434
438
  * Determines how the audio session interacts with other sessions on Android.
435
439
  *
436
440
  * @platform android
441
+ * @deprecated Use `interruptionMode` instead, which now works on both platforms.
437
442
  */
438
- interruptionModeAndroid: InterruptionModeAndroid;
443
+ interruptionModeAndroid?: InterruptionModeAndroid;
439
444
  /**
440
445
  * Whether the audio session allows recording.
441
446
  *
@@ -463,23 +468,23 @@ export type AudioMode = {
463
468
  allowsBackgroundRecording?: boolean;
464
469
  };
465
470
  /**
466
- * Audio interruption behavior modes for iOS.
471
+ * Audio interruption behavior modes.
467
472
  *
468
- * Controls how your app's audio interacts with other apps' audio when interruptions occur.
469
- * This affects what happens when phone calls, notifications, or other apps play audio.
473
+ * Controls how your app's audio interacts with other apps' audio.
470
474
  *
471
475
  * @platform ios
476
+ * - `'doNotMix'`: Requests exclusive audio focus. Other apps will pause their audio.
477
+ * - `'duckOthers'`: Requests audio focus with ducking. Other apps lower their volume but continue playing.
478
+ * - `'mixWithOthers'`: Audio plays alongside other apps without interrupting them.
479
+ * On Android, this means no audio focus is requested - best suited for sound effects,
480
+ * UI feedback, or short audio clips. Note that on Android your app won't receive
481
+ * audio focus loss callbacks (for example, during phone calls) when using this mode.
472
482
  */
473
483
  export type InterruptionMode = 'mixWithOthers' | 'doNotMix' | 'duckOthers';
474
484
  /**
475
- * Audio interruption behavior modes for Android.
476
- *
477
- * Controls how your app's audio interacts with other apps' audio on Android.
478
- * Note that Android doesn't support 'mixWithOthers' mode; audio focus is more strictly managed.
479
- *
480
- * @platform android
485
+ * @deprecated Use `InterruptionMode` instead, which now works on both platforms.
481
486
  */
482
- export type InterruptionModeAndroid = 'doNotMix' | 'duckOthers';
487
+ export type InterruptionModeAndroid = InterruptionMode;
483
488
  /**
484
489
  * Recording source for android.
485
490
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Audio.types.d.ts","sourceRoot":"","sources":["../src/Audio.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Audio.types.d.ts","sourceRoot":"","sources":["../src/Audio.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Audio.types.js","sourceRoot":"","sources":["../src/Audio.types.ts"],"names":[],"mappings":"","sourcesContent":["import { AudioQuality, IOSOutputFormat } from './RecordingConstants';\n\n// @docsMissing\nexport type AudioSource =\n | string\n | number\n | null\n | {\n /**\n * A string representing the resource identifier for the audio,\n * which could be an HTTPS address, a local file path, or the name of a static audio file resource.\n */\n uri?: string;\n /**\n * The asset ID of a local audio asset, acquired with the `require` function.\n * This property is exclusive with the `uri` property. When both are present, the `assetId` will be ignored.\n */\n assetId?: number;\n /**\n * An object representing the HTTP headers to send along with the request for a remote audio source.\n * On web requires the `Access-Control-Allow-Origin` header returned by the server to include the current domain.\n */\n headers?: Record<string, string>;\n };\n\n/**\n * Options for configuring audio player behavior.\n */\nexport type AudioPlayerOptions = {\n /**\n * How often (in milliseconds) to emit playback status updates. Defaults to 500ms.\n *\n * @example\n * ```tsx\n * import { useAudioPlayer } from 'expo-audio';\n *\n * export default function App() {\n * const player = useAudioPlayer(source);\n *\n * // High-frequency updates for smooth progress bars\n * const player = useAudioPlayer(source, { updateInterval: 100 });\n *\n * // Standard updates (default behavior)\n * const player = useAudioPlayer(source, { updateInterval: 500 });\n *\n * // Low-frequency updates for better performance\n * const player = useAudioPlayer(source, { updateInterval: 1000 });\n * }\n * ```\n *\n * @default 500ms\n *\n * @platform ios\n * @platform android\n * @platform web\n */\n updateInterval?: number;\n /**\n * If set to `true`, the system will attempt to download the resource to the device before loading.\n * This value defaults to `false`.\n *\n * Works with:\n * - Local assets from `require('path/to/file')`\n * - Remote HTTP/HTTPS URLs\n * - Asset objects\n *\n * When enabled, this ensures the audio file is fully downloaded before playback begins.\n * This can improve playback performance and reduce buffering, especially for users\n * managing multiple audio players simultaneously.\n *\n * On Android and iOS, this will download the audio file to the device's tmp directory before playback begins.\n * The system will purge the file at its discretion.\n *\n * On web, this will download the audio file to the user's device memory and make it available for the user to play.\n * The system will usually purge the file from memory after a reload or on memory pressure.\n * On web, CORS restrictions apply to the blob url, so you need to make sure the server returns the `Access-Control-Allow-Origin` header.\n *\n * @platform ios\n * @platform web\n * @platform android\n */\n downloadFirst?: boolean;\n /**\n * Determines the [cross origin policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/crossorigin) used by the underlying native view on web.\n * If `undefined` (default), does not use CORS at all. If set to `'anonymous'`, the audio will be loaded with CORS enabled.\n * Note that some audio may not play if CORS is enabled, depending on the CDN settings.\n * If you encounter issues, consider adjusting the `crossOrigin` property.\n *\n *\n * @platform web\n * @default undefined\n */\n crossOrigin?: 'anonymous' | 'use-credentials';\n /**\n * If set to `true`, the audio session will not be deactivated when this player pauses or finishes playback.\n * This prevents interrupting other audio sources (like videos) when the audio ends.\n *\n * Useful for sound effects that should not interfere with ongoing video playback or other audio.\n * The audio session for this player will not be deactivated automatically when the player finishes playback.\n *\n * > **Note:** If needed, you can manually deactivate the audio session using `setIsAudioActiveAsync(false)`.\n *\n * @platform ios\n * @default false\n */\n keepAudioSessionActive?: boolean;\n};\n\n/**\n * @deprecated Use `AudioPlayerOptions` instead.\n * Options for audio loading behavior.\n */\nexport type AudioLoadOptions = AudioPlayerOptions;\n\n/**\n * Represents an available audio input device for recording.\n *\n * This type describes audio input sources like built-in microphones, external microphones,\n * or other audio input devices that can be used for recording. Each input has an identifying\n * information that can be used to select the preferred recording source.\n */\nexport type RecordingInput = {\n /** Human-readable name of the audio input device. */\n name: string;\n /** Type or category of the input device (for example, 'Built-in Microphone', 'External Microphone'). */\n type: string;\n /** Unique identifier for the input device, used to select the input ('Built-in Microphone', 'External Microphone') for recording. */\n uid: string;\n};\n\n/**\n * Pitch correction quality settings for audio playback rate changes.\n *\n * When changing playback rate, pitch correction can be applied to maintain the original pitch.\n * Different quality levels offer trade-offs between processing power and audio quality.\n *\n * @platform ios\n */\nexport type PitchCorrectionQuality = 'low' | 'medium' | 'high';\n\n/**\n * Comprehensive status information for an `AudioPlayer`.\n *\n * This object contains all the current state information about audio playback,\n * including playback position, duration, loading state, and playback settings.\n * Used by `useAudioPlayerStatus()` to provide real-time status updates.\n */\nexport type AudioStatus = {\n /** Unique identifier for the player instance. */\n id: number;\n /** Current playback position in seconds. */\n currentTime: number;\n /** String representation of the player's internal playback state. */\n playbackState: string;\n /** String representation of the player's time control status (playing/paused/waiting). */\n timeControlStatus: string;\n /** Reason why the player is waiting to play (if applicable). */\n reasonForWaitingToPlay: string;\n /** Whether the player is currently muted. */\n mute: boolean;\n /** Total duration of the audio in seconds, or 0 if not yet determined. */\n duration: number;\n /** Whether the audio is currently playing. */\n playing: boolean;\n /** Whether the audio is set to loop when it reaches the end. */\n loop: boolean;\n /** Whether the audio just finished playing. */\n didJustFinish: boolean;\n /** Whether the player is currently buffering data. */\n isBuffering: boolean;\n /** Whether the audio has finished loading and is ready to play. */\n isLoaded: boolean;\n /** Current playback rate (1.0 = normal speed). */\n playbackRate: number;\n /**\n * Whether pitch correction is enabled for rate changes.\n * @default true\n */\n shouldCorrectPitch: boolean;\n};\n\n/**\n * Status information for recording operations from the event system.\n *\n * This type represents the status data emitted by `recordingStatusUpdate` events.\n * It contains high-level information about the recording session and any errors.\n * Used internally by the event system. Most users should use `useAudioRecorderState()` instead.\n */\nexport type RecordingStatus = {\n /** Unique identifier for the recording session. */\n id: number;\n /** Whether the recording has finished (stopped). */\n isFinished: boolean;\n /** Whether an error occurred during recording. */\n hasError: boolean;\n /** Error message if an error occurred, `null` otherwise. */\n error: string | null;\n /** File URL of the completed recording, if available. */\n url: string | null;\n};\n\n/**\n * Current state information for an `AudioRecorder`.\n *\n * This object contains detailed information about the recorder's current state,\n * including recording status, duration, and technical details. This is what you get\n * when calling `recorder.getStatus()` or using `useAudioRecorderState()`.\n */\nexport type RecorderState = {\n /** Whether the recorder is ready and able to record. */\n canRecord: boolean;\n /** Whether recording is currently in progress. */\n isRecording: boolean;\n /** Duration of the current recording in milliseconds. */\n durationMillis: number;\n /** Whether the media services have been reset (typically indicates a system interruption). */\n mediaServicesDidReset: boolean;\n /** Current audio level/volume being recorded (if metering is enabled). */\n metering?: number;\n /** File URL where the recording will be saved, if available. */\n url: string | null;\n};\n\n/**\n * Audio output format options for Android recording.\n *\n * Specifies the container format for recorded audio files on Android.\n * Different formats have different compatibility and compression characteristics.\n *\n * @platform android\n */\nexport type AndroidOutputFormat =\n | 'default'\n | '3gp'\n | 'mpeg4'\n | 'amrnb'\n | 'amrwb'\n | 'aac_adts'\n | 'mpeg2ts'\n | 'webm';\n\n/**\n * Audio encoder options for Android recording.\n *\n * Specifies the audio codec used to encode recorded audio on Android.\n * Different encoders offer different quality, compression, and compatibility trade-offs.\n *\n * @platform android\n */\nexport type AndroidAudioEncoder = 'default' | 'amr_nb' | 'amr_wb' | 'aac' | 'he_aac' | 'aac_eld';\n\n/**\n * Bit rate strategies for audio encoding.\n *\n * Determines how the encoder manages bit rate during recording, affecting\n * file size consistency and quality characteristics.\n */\nexport type BitRateStrategy = 'constant' | 'longTermAverage' | 'variableConstrained' | 'variable';\n\n/**\n * Options for controlling how audio recording is started.\n */\nexport type RecordingStartOptions = {\n /**\n * The duration in seconds after which recording should automatically stop.\n * If not provided, recording continues until manually stopped.\n *\n * @platform ios\n * @platform android\n * @platform web\n */\n forDuration?: number;\n /**\n * The time in seconds to wait before starting the recording.\n * If not provided, recording starts immediately.\n *\n * **Platform behavior:**\n * - Android: Ignored, recording starts immediately\n * - iOS: Uses native AVAudioRecorder.record(atTime:) for precise timing.\n * - Web: Ignored, recording starts immediately\n *\n * > **warning** On iOS, the recording process starts immediately (you'll see status updates),\n * but actual audio capture begins after the specified delay. This is not a countdown, since\n * the recorder is active but silent during the delay period.\n *\n * @platform ios\n */\n atTime?: number;\n};\n\nexport type RecordingOptions = {\n /**\n * A boolean that determines whether audio level information will be part of the status object under the \"metering\" key.\n */\n isMeteringEnabled?: boolean;\n /**\n * The desired file extension.\n *\n * @example .caf\n */\n extension: string;\n /**\n * The desired sample rate.\n *\n * @example 44100\n */\n sampleRate: number;\n /**\n * The desired number of channels.\n *\n * @example 2\n */\n numberOfChannels: number;\n /**\n * The desired bit rate.\n *\n * @example 128000\n */\n bitRate: number;\n /**\n * Recording options for the Android platform.\n * @platform android\n */\n android: RecordingOptionsAndroid;\n /**\n * Recording options for the iOS platform.\n * @platform ios\n */\n ios: RecordingOptionsIos;\n /**\n * Recording options for the Web platform.\n * @platform web\n */\n web: RecordingOptionsWeb;\n};\n\n/**\n * Recording options for the web.\n *\n * Web recording uses the `MediaRecorder` API, which has different capabilities\n * compared to native platforms. These options map directly to `MediaRecorder` settings.\n *\n * @platform web\n */\nexport type RecordingOptionsWeb = {\n /** MIME type for the recording (for example, 'audio/webm', 'audio/mp4'). */\n mimeType?: string;\n /** Target bits per second for the recording. */\n bitsPerSecond?: number;\n};\n\n/**\n * Recording configuration options specific to iOS.\n *\n * iOS recording uses `AVAudioRecorder` with extensive format and quality options.\n * These settings provide fine-grained control over the recording characteristics.\n *\n * @platform ios\n */\nexport type RecordingOptionsIos = {\n /**\n * The desired file extension.\n *\n * @example .caf\n */\n extension?: string;\n /**\n * The desired sample rate.\n *\n * @example 44100\n */\n sampleRate?: number;\n /**\n * The desired file format. See the [`IOSOutputFormat`](#iosoutputformat) enum for all valid values.\n */\n outputFormat?: string | IOSOutputFormat | number;\n /**\n * The desired audio quality. See the [`AudioQuality`](#audioquality) enum for all valid values.\n */\n audioQuality: AudioQuality | number;\n /**\n * The desired bit rate strategy. See the next section for an enumeration of all valid values of `bitRateStrategy`.\n */\n bitRateStrategy?: number;\n /**\n * The desired bit depth hint.\n *\n * @example 16\n */\n bitDepthHint?: number;\n /**\n * The desired PCM bit depth.\n *\n * @example 16\n */\n linearPCMBitDepth?: number;\n /**\n * A boolean describing if the PCM data should be formatted in big endian.\n */\n linearPCMIsBigEndian?: boolean;\n /**\n * A boolean describing if the PCM data should be encoded in floating point or integral values.\n */\n linearPCMIsFloat?: boolean;\n};\n\n/**\n * Recording configuration options specific to Android.\n *\n * Android recording uses `MediaRecorder` with options for format, encoder, and file constraints.\n * These settings control the output format and quality characteristics.\n *\n * @platform android\n */\nexport type RecordingOptionsAndroid = {\n /**\n * The desired file extension.\n *\n * @example .caf\n */\n extension?: string;\n /**\n * The desired sample rate.\n *\n * @example 44100\n */\n sampleRate?: number;\n /**\n * The desired file format. See the [`AndroidOutputFormat`](#androidoutputformat) type for all valid values.\n */\n outputFormat: AndroidOutputFormat;\n /**\n * The desired audio encoder. See the [`AndroidAudioEncoder`](#androidaudioencoder) type for all valid values.\n */\n audioEncoder: AndroidAudioEncoder;\n /**\n * The desired maximum file size in bytes, after which the recording will stop (but `stopAndUnloadAsync()` must still\n * be called after this point).\n *\n * @example\n * `65536`\n */\n maxFileSize?: number;\n /**\n * The desired audio Source. See the [`RecordingSource`](#recordingsource) type for all valid values.\n */\n audioSource?: RecordingSource;\n};\n\nexport type AudioMode = {\n /**\n * Determines if audio playback is allowed when the device is in silent mode.\n *\n * @platform ios\n */\n playsInSilentMode: boolean;\n /**\n * Determines how the audio session interacts with other sessions.\n *\n * @platform ios\n */\n interruptionMode: InterruptionMode;\n /**\n * Determines how the audio session interacts with other sessions on Android.\n *\n * @platform android\n */\n interruptionModeAndroid: InterruptionModeAndroid;\n /**\n * Whether the audio session allows recording.\n *\n * @default false\n * @platform ios\n */\n allowsRecording: boolean;\n /**\n * Whether the audio session stays active when the app moves to the background.\n * @default false\n */\n shouldPlayInBackground: boolean;\n /**\n * Whether the audio should route through the earpiece.\n * @platform android\n */\n shouldRouteThroughEarpiece: boolean;\n /**\n * Whether audio recording should continue when the app moves to the background.\n *\n * @default false\n * @platform ios\n * @platform android\n */\n allowsBackgroundRecording?: boolean;\n};\n\n/**\n * Audio interruption behavior modes for iOS.\n *\n * Controls how your app's audio interacts with other apps' audio when interruptions occur.\n * This affects what happens when phone calls, notifications, or other apps play audio.\n *\n * @platform ios\n */\nexport type InterruptionMode = 'mixWithOthers' | 'doNotMix' | 'duckOthers';\n\n/**\n * Audio interruption behavior modes for Android.\n *\n * Controls how your app's audio interacts with other apps' audio on Android.\n * Note that Android doesn't support 'mixWithOthers' mode; audio focus is more strictly managed.\n *\n * @platform android\n */\nexport type InterruptionModeAndroid = 'doNotMix' | 'duckOthers';\n\n/**\n * Recording source for android.\n *\n * An audio source defines both a default physical source of audio signal, and a recording configuration.\n *\n * - `camcorder`: Microphone audio source tuned for video recording, with the same orientation as the camera if available.\n * - `default`: The default audio source.\n * - `mic`: Microphone audio source.\n * - `unprocessed`: Microphone audio source tuned for unprocessed (raw) sound if available, behaves like `default` otherwise.\n * - `voice_communication`: Microphone audio source tuned for voice communications such as VoIP. It will for instance take advantage of echo cancellation or automatic gain control if available.\n * - `voice_performance`: Source for capturing audio meant to be processed in real time and played back for live performance (e.g karaoke). The capture path will minimize latency and coupling with playback path.\n * - `voice_recognition`: Microphone audio source tuned for voice recognition.\n *\n * @see https://developer.android.com/reference/android/media/MediaRecorder.AudioSource\n * @platform android\n */\nexport type RecordingSource =\n | 'camcorder'\n | 'default'\n | 'mic'\n | 'remote_submix'\n | 'unprocessed'\n | 'voice_communication'\n | 'voice_performance'\n | 'voice_recognition';\n\n// @docsMissing\nexport type AudioMetadata = {\n title?: string;\n artist?: string;\n albumTitle?: string;\n artworkUrl?: string;\n};\n"]}
1
+ {"version":3,"file":"Audio.types.js","sourceRoot":"","sources":["../src/Audio.types.ts"],"names":[],"mappings":"","sourcesContent":["import { AudioQuality, IOSOutputFormat } from './RecordingConstants';\n\n// @docsMissing\nexport type AudioSource =\n | string\n | number\n | null\n | {\n /**\n * A string representing the resource identifier for the audio,\n * which could be an HTTPS address, a local file path, or the name of a static audio file resource.\n */\n uri?: string;\n /**\n * The asset ID of a local audio asset, acquired with the `require` function.\n * This property is exclusive with the `uri` property. When both are present, the `assetId` will be ignored.\n */\n assetId?: number;\n /**\n * An object representing the HTTP headers to send along with the request for a remote audio source.\n * On web requires the `Access-Control-Allow-Origin` header returned by the server to include the current domain.\n */\n headers?: Record<string, string>;\n };\n\n/**\n * Options for configuring audio player behavior.\n */\nexport type AudioPlayerOptions = {\n /**\n * How often (in milliseconds) to emit playback status updates. Defaults to 500ms.\n *\n * @example\n * ```tsx\n * import { useAudioPlayer } from 'expo-audio';\n *\n * export default function App() {\n * const player = useAudioPlayer(source);\n *\n * // High-frequency updates for smooth progress bars\n * const player = useAudioPlayer(source, { updateInterval: 100 });\n *\n * // Standard updates (default behavior)\n * const player = useAudioPlayer(source, { updateInterval: 500 });\n *\n * // Low-frequency updates for better performance\n * const player = useAudioPlayer(source, { updateInterval: 1000 });\n * }\n * ```\n *\n * @default 500ms\n *\n * @platform ios\n * @platform android\n * @platform web\n */\n updateInterval?: number;\n /**\n * If set to `true`, the system will attempt to download the resource to the device before loading.\n * This value defaults to `false`.\n *\n * Works with:\n * - Local assets from `require('path/to/file')`\n * - Remote HTTP/HTTPS URLs\n * - Asset objects\n *\n * When enabled, this ensures the audio file is fully downloaded before playback begins.\n * This can improve playback performance and reduce buffering, especially for users\n * managing multiple audio players simultaneously.\n *\n * On Android and iOS, this will download the audio file to the device's tmp directory before playback begins.\n * The system will purge the file at its discretion.\n *\n * On web, this will download the audio file to the user's device memory and make it available for the user to play.\n * The system will usually purge the file from memory after a reload or on memory pressure.\n * On web, CORS restrictions apply to the blob url, so you need to make sure the server returns the `Access-Control-Allow-Origin` header.\n *\n * @platform ios\n * @platform web\n * @platform android\n */\n downloadFirst?: boolean;\n /**\n * Determines the [cross origin policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/crossorigin) used by the underlying native view on web.\n * If `undefined` (default), does not use CORS at all. If set to `'anonymous'`, the audio will be loaded with CORS enabled.\n * Note that some audio may not play if CORS is enabled, depending on the CDN settings.\n * If you encounter issues, consider adjusting the `crossOrigin` property.\n *\n *\n * @platform web\n * @default undefined\n */\n crossOrigin?: 'anonymous' | 'use-credentials';\n /**\n * If set to `true`, the audio session will not be deactivated when this player pauses or finishes playback.\n * This prevents interrupting other audio sources (like videos) when the audio ends.\n *\n * Useful for sound effects that should not interfere with ongoing video playback or other audio.\n * The audio session for this player will not be deactivated automatically when the player finishes playback.\n *\n * > **Note:** If needed, you can manually deactivate the audio session using `setIsAudioActiveAsync(false)`.\n *\n * @platform ios\n * @default false\n */\n keepAudioSessionActive?: boolean;\n};\n\n/**\n * @deprecated Use `AudioPlayerOptions` instead.\n * Options for audio loading behavior.\n */\nexport type AudioLoadOptions = AudioPlayerOptions;\n\n/**\n * Represents an available audio input device for recording.\n *\n * This type describes audio input sources like built-in microphones, external microphones,\n * or other audio input devices that can be used for recording. Each input has an identifying\n * information that can be used to select the preferred recording source.\n */\nexport type RecordingInput = {\n /** Human-readable name of the audio input device. */\n name: string;\n /** Type or category of the input device (for example, 'Built-in Microphone', 'External Microphone'). */\n type: string;\n /** Unique identifier for the input device, used to select the input ('Built-in Microphone', 'External Microphone') for recording. */\n uid: string;\n};\n\n/**\n * Pitch correction quality settings for audio playback rate changes.\n *\n * When changing playback rate, pitch correction can be applied to maintain the original pitch.\n * Different quality levels offer trade-offs between processing power and audio quality.\n *\n * @platform ios\n */\nexport type PitchCorrectionQuality = 'low' | 'medium' | 'high';\n\n/**\n * Comprehensive status information for an `AudioPlayer`.\n *\n * This object contains all the current state information about audio playback,\n * including playback position, duration, loading state, and playback settings.\n * Used by `useAudioPlayerStatus()` to provide real-time status updates.\n */\nexport type AudioStatus = {\n /** Unique identifier for the player instance. */\n id: number;\n /** Current playback position in seconds. */\n currentTime: number;\n /** String representation of the player's internal playback state. */\n playbackState: string;\n /** String representation of the player's time control status (playing/paused/waiting). */\n timeControlStatus: string;\n /** Reason why the player is waiting to play (if applicable). */\n reasonForWaitingToPlay: string;\n /** Whether the player is currently muted. */\n mute: boolean;\n /** Total duration of the audio in seconds, or 0 if not yet determined. */\n duration: number;\n /** Whether the audio is currently playing. */\n playing: boolean;\n /** Whether the audio is set to loop when it reaches the end. */\n loop: boolean;\n /** Whether the audio just finished playing. */\n didJustFinish: boolean;\n /** Whether the player is currently buffering data. */\n isBuffering: boolean;\n /** Whether the audio has finished loading and is ready to play. */\n isLoaded: boolean;\n /** Current playback rate (1.0 = normal speed). */\n playbackRate: number;\n /**\n * Whether pitch correction is enabled for rate changes.\n * @default true\n */\n shouldCorrectPitch: boolean;\n};\n\n/**\n * Status information for recording operations from the event system.\n *\n * This type represents the status data emitted by `recordingStatusUpdate` events.\n * It contains high-level information about the recording session and any errors.\n * Used internally by the event system. Most users should use `useAudioRecorderState()` instead.\n */\nexport type RecordingStatus = {\n /** Unique identifier for the recording session. */\n id: number;\n /** Whether the recording has finished (stopped). */\n isFinished: boolean;\n /** Whether an error occurred during recording. */\n hasError: boolean;\n /** Error message if an error occurred, `null` otherwise. */\n error: string | null;\n /** File URL of the completed recording, if available. */\n url: string | null;\n};\n\n/**\n * Current state information for an `AudioRecorder`.\n *\n * This object contains detailed information about the recorder's current state,\n * including recording status, duration, and technical details. This is what you get\n * when calling `recorder.getStatus()` or using `useAudioRecorderState()`.\n */\nexport type RecorderState = {\n /** Whether the recorder is ready and able to record. */\n canRecord: boolean;\n /** Whether recording is currently in progress. */\n isRecording: boolean;\n /** Duration of the current recording in milliseconds. */\n durationMillis: number;\n /** Whether the media services have been reset (typically indicates a system interruption). */\n mediaServicesDidReset: boolean;\n /** Current audio level/volume being recorded (if metering is enabled). */\n metering?: number;\n /** File URL where the recording will be saved, if available. */\n url: string | null;\n};\n\n/**\n * Audio output format options for Android recording.\n *\n * Specifies the container format for recorded audio files on Android.\n * Different formats have different compatibility and compression characteristics.\n *\n * @platform android\n */\nexport type AndroidOutputFormat =\n | 'default'\n | '3gp'\n | 'mpeg4'\n | 'amrnb'\n | 'amrwb'\n | 'aac_adts'\n | 'mpeg2ts'\n | 'webm';\n\n/**\n * Audio encoder options for Android recording.\n *\n * Specifies the audio codec used to encode recorded audio on Android.\n * Different encoders offer different quality, compression, and compatibility trade-offs.\n *\n * @platform android\n */\nexport type AndroidAudioEncoder = 'default' | 'amr_nb' | 'amr_wb' | 'aac' | 'he_aac' | 'aac_eld';\n\n/**\n * Bit rate strategies for audio encoding.\n *\n * Determines how the encoder manages bit rate during recording, affecting\n * file size consistency and quality characteristics.\n */\nexport type BitRateStrategy = 'constant' | 'longTermAverage' | 'variableConstrained' | 'variable';\n\n/**\n * Options for controlling how audio recording is started.\n */\nexport type RecordingStartOptions = {\n /**\n * The duration in seconds after which recording should automatically stop.\n * If not provided, recording continues until manually stopped.\n *\n * @platform ios\n * @platform android\n * @platform web\n */\n forDuration?: number;\n /**\n * The time in seconds to wait before starting the recording.\n * If not provided, recording starts immediately.\n *\n * **Platform behavior:**\n * - Android: Ignored, recording starts immediately\n * - iOS: Uses native AVAudioRecorder.record(atTime:) for precise timing.\n * - Web: Ignored, recording starts immediately\n *\n * > **warning** On iOS, the recording process starts immediately (you'll see status updates),\n * but actual audio capture begins after the specified delay. This is not a countdown, since\n * the recorder is active but silent during the delay period.\n *\n * @platform ios\n */\n atTime?: number;\n};\n\nexport type RecordingOptions = {\n /**\n * A boolean that determines whether audio level information will be part of the status object under the \"metering\" key.\n */\n isMeteringEnabled?: boolean;\n /**\n * The desired file extension.\n *\n * @example .caf\n */\n extension: string;\n /**\n * The desired sample rate.\n *\n * @example 44100\n */\n sampleRate: number;\n /**\n * The desired number of channels.\n *\n * @example 2\n */\n numberOfChannels: number;\n /**\n * The desired bit rate.\n *\n * @example 128000\n */\n bitRate: number;\n /**\n * Recording options for the Android platform.\n * @platform android\n */\n android: RecordingOptionsAndroid;\n /**\n * Recording options for the iOS platform.\n * @platform ios\n */\n ios: RecordingOptionsIos;\n /**\n * Recording options for the Web platform.\n * @platform web\n */\n web: RecordingOptionsWeb;\n};\n\n/**\n * Recording options for the web.\n *\n * Web recording uses the `MediaRecorder` API, which has different capabilities\n * compared to native platforms. These options map directly to `MediaRecorder` settings.\n *\n * @platform web\n */\nexport type RecordingOptionsWeb = {\n /** MIME type for the recording (for example, 'audio/webm', 'audio/mp4'). */\n mimeType?: string;\n /** Target bits per second for the recording. */\n bitsPerSecond?: number;\n};\n\n/**\n * Recording configuration options specific to iOS.\n *\n * iOS recording uses `AVAudioRecorder` with extensive format and quality options.\n * These settings provide fine-grained control over the recording characteristics.\n *\n * @platform ios\n */\nexport type RecordingOptionsIos = {\n /**\n * The desired file extension.\n *\n * @example .caf\n */\n extension?: string;\n /**\n * The desired sample rate.\n *\n * @example 44100\n */\n sampleRate?: number;\n /**\n * The desired file format. See the [`IOSOutputFormat`](#iosoutputformat) enum for all valid values.\n */\n outputFormat?: string | IOSOutputFormat | number;\n /**\n * The desired audio quality. See the [`AudioQuality`](#audioquality) enum for all valid values.\n */\n audioQuality: AudioQuality | number;\n /**\n * The desired bit rate strategy. See the next section for an enumeration of all valid values of `bitRateStrategy`.\n */\n bitRateStrategy?: number;\n /**\n * The desired bit depth hint.\n *\n * @example 16\n */\n bitDepthHint?: number;\n /**\n * The desired PCM bit depth.\n *\n * @example 16\n */\n linearPCMBitDepth?: number;\n /**\n * A boolean describing if the PCM data should be formatted in big endian.\n */\n linearPCMIsBigEndian?: boolean;\n /**\n * A boolean describing if the PCM data should be encoded in floating point or integral values.\n */\n linearPCMIsFloat?: boolean;\n};\n\n/**\n * Recording configuration options specific to Android.\n *\n * Android recording uses `MediaRecorder` with options for format, encoder, and file constraints.\n * These settings control the output format and quality characteristics.\n *\n * @platform android\n */\nexport type RecordingOptionsAndroid = {\n /**\n * The desired file extension.\n *\n * @example .caf\n */\n extension?: string;\n /**\n * The desired sample rate.\n *\n * @example 44100\n */\n sampleRate?: number;\n /**\n * The desired file format. See the [`AndroidOutputFormat`](#androidoutputformat) type for all valid values.\n */\n outputFormat: AndroidOutputFormat;\n /**\n * The desired audio encoder. See the [`AndroidAudioEncoder`](#androidaudioencoder) type for all valid values.\n */\n audioEncoder: AndroidAudioEncoder;\n /**\n * The desired maximum file size in bytes, after which the recording will stop (but `stopAndUnloadAsync()` must still\n * be called after this point).\n *\n * @example\n * `65536`\n */\n maxFileSize?: number;\n /**\n * The desired audio Source. See the [`RecordingSource`](#recordingsource) type for all valid values.\n */\n audioSource?: RecordingSource;\n};\n\nexport type AudioMode = {\n /**\n * Determines if audio playback is allowed when the device is in silent mode.\n *\n * @platform ios\n */\n playsInSilentMode: boolean;\n /**\n * Determines how the audio session interacts with other audio sessions.\n *\n * - `'doNotMix'`: Requests exclusive audio focus. Other apps will pause their audio.\n * - `'duckOthers'`: Requests audio focus with ducking. Other apps lower their volume but continue playing.\n * - `'mixWithOthers'`: Audio plays alongside other apps without interrupting them.\n * On Android, this means no audio focus is requested. Best suited for sound effects,\n * UI feedback, or short audio clips.\n */\n interruptionMode: InterruptionMode;\n /**\n * Determines how the audio session interacts with other sessions on Android.\n *\n * @platform android\n * @deprecated Use `interruptionMode` instead, which now works on both platforms.\n */\n interruptionModeAndroid?: InterruptionModeAndroid;\n /**\n * Whether the audio session allows recording.\n *\n * @default false\n * @platform ios\n */\n allowsRecording: boolean;\n /**\n * Whether the audio session stays active when the app moves to the background.\n * @default false\n */\n shouldPlayInBackground: boolean;\n /**\n * Whether the audio should route through the earpiece.\n * @platform android\n */\n shouldRouteThroughEarpiece: boolean;\n /**\n * Whether audio recording should continue when the app moves to the background.\n *\n * @default false\n * @platform ios\n * @platform android\n */\n allowsBackgroundRecording?: boolean;\n};\n\n/**\n * Audio interruption behavior modes.\n *\n * Controls how your app's audio interacts with other apps' audio.\n *\n * @platform ios\n * - `'doNotMix'`: Requests exclusive audio focus. Other apps will pause their audio.\n * - `'duckOthers'`: Requests audio focus with ducking. Other apps lower their volume but continue playing.\n * - `'mixWithOthers'`: Audio plays alongside other apps without interrupting them.\n * On Android, this means no audio focus is requested - best suited for sound effects,\n * UI feedback, or short audio clips. Note that on Android your app won't receive\n * audio focus loss callbacks (for example, during phone calls) when using this mode.\n */\nexport type InterruptionMode = 'mixWithOthers' | 'doNotMix' | 'duckOthers';\n\n/**\n * @deprecated Use `InterruptionMode` instead, which now works on both platforms.\n */\nexport type InterruptionModeAndroid = InterruptionMode;\n\n/**\n * Recording source for android.\n *\n * An audio source defines both a default physical source of audio signal, and a recording configuration.\n *\n * - `camcorder`: Microphone audio source tuned for video recording, with the same orientation as the camera if available.\n * - `default`: The default audio source.\n * - `mic`: Microphone audio source.\n * - `unprocessed`: Microphone audio source tuned for unprocessed (raw) sound if available, behaves like `default` otherwise.\n * - `voice_communication`: Microphone audio source tuned for voice communications such as VoIP. It will for instance take advantage of echo cancellation or automatic gain control if available.\n * - `voice_performance`: Source for capturing audio meant to be processed in real time and played back for live performance (e.g karaoke). The capture path will minimize latency and coupling with playback path.\n * - `voice_recognition`: Microphone audio source tuned for voice recognition.\n *\n * @see https://developer.android.com/reference/android/media/MediaRecorder.AudioSource\n * @platform android\n */\nexport type RecordingSource =\n | 'camcorder'\n | 'default'\n | 'mic'\n | 'remote_submix'\n | 'unprocessed'\n | 'voice_communication'\n | 'voice_performance'\n | 'voice_recognition';\n\n// @docsMissing\nexport type AudioMetadata = {\n title?: string;\n artist?: string;\n albumTitle?: string;\n artworkUrl?: string;\n};\n"]}
@@ -218,11 +218,10 @@ export declare function setIsAudioActiveAsync(active: boolean): Promise<void>;
218
218
  * ```tsx
219
219
  * import { setAudioModeAsync } from 'expo-audio';
220
220
  *
221
- * // Configure audio for background playback
221
+ * // Configure audio for background playback with mixing
222
222
  * await setAudioModeAsync({
223
223
  * playsInSilentMode: true,
224
224
  * shouldPlayInBackground: true,
225
- * interruptionModeAndroid: 'duckOthers',
226
225
  * interruptionMode: 'mixWithOthers'
227
226
  * });
228
227
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoAudio.d.ts","sourceRoot":"","sources":["../src/ExpoAudio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAA4B,MAAM,mBAAmB,CAAC;AAIjF,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,WAAW,EACX,WAAW,EAEX,aAAa,EACb,gBAAgB,EAEhB,eAAe,EAChB,MAAM,eAAe,CAAC;AAMvB,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAoC9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,cAAc,CAC5B,MAAM,GAAE,WAAkB,EAC1B,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAkDb;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAGrE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,QAShG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EACzB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GACjD,aAAa,CAcf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,GAAE,MAAY,iBAgCpF;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,IAAW,EACnD,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAsBb;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAEpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAEhF;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"ExpoAudio.d.ts","sourceRoot":"","sources":["../src/ExpoAudio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAA4B,MAAM,mBAAmB,CAAC;AAIjF,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,WAAW,EACX,WAAW,EAEX,aAAa,EACb,gBAAgB,EAEhB,eAAe,EAChB,MAAM,eAAe,CAAC;AAMvB,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAoC9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,cAAc,CAC5B,MAAM,GAAE,WAAkB,EAC1B,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAkDb;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAGrE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,QAShG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EACzB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GACjD,aAAa,CAcf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,GAAE,MAAY,iBAgCpF;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,IAAW,EACnD,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAsBb;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAEpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAEhF;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -355,11 +355,10 @@ export async function setIsAudioActiveAsync(active) {
355
355
  * ```tsx
356
356
  * import { setAudioModeAsync } from 'expo-audio';
357
357
  *
358
- * // Configure audio for background playback
358
+ * // Configure audio for background playback with mixing
359
359
  * await setAudioModeAsync({
360
360
  * playsInSilentMode: true,
361
361
  * shouldPlayInBackground: true,
362
- * interruptionModeAndroid: 'duckOthers',
363
362
  * interruptionMode: 'mixWithOthers'
364
363
  * });
365
364
  *
@@ -376,7 +375,7 @@ export async function setAudioModeAsync(mode) {
376
375
  : {
377
376
  shouldPlayInBackground: mode.shouldPlayInBackground,
378
377
  shouldRouteThroughEarpiece: mode.shouldRouteThroughEarpiece,
379
- interruptionMode: mode.interruptionModeAndroid,
378
+ interruptionMode: mode.interruptionMode ?? mode.interruptionModeAndroid,
380
379
  allowsBackgroundRecording: mode.allowsBackgroundRecording,
381
380
  };
382
381
  return await AudioModule.setAudioModeAsync(audioMode);
@@ -1 +1 @@
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';\nimport { Platform } from 'react-native';\n\nimport {\n AudioMode,\n AudioPlayerOptions,\n AudioSource,\n AudioStatus,\n PitchCorrectionQuality,\n RecorderState,\n RecordingOptions,\n RecordingStartOptions,\n RecordingStatus,\n} from './Audio.types';\nimport {\n AUDIO_SAMPLE_UPDATE,\n PLAYBACK_STATUS_UPDATE,\n RECORDING_STATUS_UPDATE,\n} from './AudioEventKeys';\nimport AudioModule from './AudioModule';\nimport { AudioPlayer, AudioRecorder, AudioSample } from './AudioModule.types';\nimport { createRecordingOptions } from './utils/options';\nimport { resolveSource, resolveSourceWithDownload } from './utils/resolveSource';\n\n// TODO: Temporary solution until we develop a way of overriding prototypes that won't break the lazy loading of the module.\nconst replace = AudioModule.AudioPlayer.prototype.replace;\nAudioModule.AudioPlayer.prototype.replace = function (source: AudioSource) {\n return replace.call(this, resolveSource(source));\n};\n\nconst setPlaybackRate = AudioModule.AudioPlayer.prototype.setPlaybackRate;\nAudioModule.AudioPlayer.prototype.setPlaybackRate = function (\n rate: number,\n pitchCorrectionQuality?: PitchCorrectionQuality\n) {\n if (Platform.OS === 'android') {\n return setPlaybackRate.call(this, rate);\n } else {\n return setPlaybackRate.call(this, rate, pitchCorrectionQuality);\n }\n};\n\n// Audio recording prototypes should not be shimmed on tvOS, where they do not exist\nif (!Platform.isTV || Platform.OS !== 'ios') {\n const prepareToRecordAsync = AudioModule.AudioRecorder.prototype.prepareToRecordAsync;\n AudioModule.AudioRecorder.prototype.prepareToRecordAsync = function (options?: RecordingOptions) {\n const processedOptions = options ? createRecordingOptions(options) : undefined;\n return prepareToRecordAsync.call(this, processedOptions);\n };\n\n const record = AudioModule.AudioRecorder.prototype.record;\n AudioModule.AudioRecorder.prototype.record = function (options?: RecordingStartOptions) {\n return record.call(this, options);\n };\n}\n\n/**\n * Creates an `AudioPlayer` instance that automatically releases when the component unmounts.\n *\n * This hook manages the player's lifecycle and ensures it's properly disposed when no longer needed.\n * The player will start loading the audio source immediately upon creation.\n *\n * @param source The audio source to load. Can be a local asset via `require()`, a remote URL, or null for no initial source.\n * @param options Audio player configuration options.\n * @returns An `AudioPlayer` instance that's automatically managed by the component lifecycle.\n *\n * @example\n * ```tsx\n * import { useAudioPlayer } from 'expo-audio';\n *\n * function MyComponent() {\n * const player = useAudioPlayer(require('./sound.mp3'));\n *\n * return (\n * <Button title=\"Play\" onPress={() => player.play()} />\n * );\n * }\n * ```\n *\n * @example Using downloadFirst\n * ```tsx\n * import { useAudioPlayer } from 'expo-audio';\n *\n * function MyComponent() {\n * const player = useAudioPlayer('https://example.com/audio.mp3', {\n * updateInterval: 1000,\n * downloadFirst: true,\n * });\n *\n * return (\n * <Button title=\"Play\" onPress={() => player.play()} />\n * );\n * }\n * ```\n */\nexport function useAudioPlayer(\n source: AudioSource = null,\n options: AudioPlayerOptions = {}\n): AudioPlayer {\n const { updateInterval = 500, downloadFirst = false, keepAudioSessionActive = false } = options;\n\n // If downloadFirst is true, we don't need to resolve the source, because it will be resolved in the useEffect below.\n // If downloadFirst is false, we resolve the source here.\n // we call .replace() in the useEffect below to replace the source with the downloaded one.\n const initialSource = useMemo(() => {\n return downloadFirst ? null : resolveSource(source);\n }, [JSON.stringify(source), downloadFirst]);\n\n const player = useReleasingSharedObject(\n () => new AudioModule.AudioPlayer(initialSource, updateInterval, keepAudioSessionActive),\n [JSON.stringify(initialSource), updateInterval, keepAudioSessionActive]\n );\n\n // Handle async source resolution for downloadFirst\n useEffect(() => {\n if (!downloadFirst || source === null) {\n return;\n }\n\n let isCancelled = false;\n\n // We resolve the source with expo-asset and replace the player's source with the downloaded one.\n async function resolveAndReplaceSource() {\n try {\n const resolved = await resolveSourceWithDownload(source);\n\n if (\n !isCancelled &&\n resolved &&\n JSON.stringify(resolved) !== JSON.stringify(initialSource)\n ) {\n player.replace(resolved);\n }\n } catch (error) {\n if (!isCancelled) {\n console.warn('expo-audio: Failed to download source, using original:', error);\n }\n }\n }\n\n resolveAndReplaceSource();\n\n return () => {\n isCancelled = true;\n };\n }, [player, JSON.stringify(source), downloadFirst]);\n\n return player;\n}\n\n/**\n * Hook that provides real-time playback status updates for an `AudioPlayer`.\n *\n * This hook automatically subscribes to playback status changes and returns the current status.\n * The status includes information about playback state, current time, duration, loading state, and more.\n *\n * @param player The `AudioPlayer` instance to monitor.\n * @returns The current `AudioStatus` object containing playback information.\n *\n * @example\n * ```tsx\n * import { useAudioPlayer, useAudioPlayerStatus } from 'expo-audio';\n *\n * function PlayerComponent() {\n * const player = useAudioPlayer(require('./sound.mp3'));\n * const status = useAudioPlayerStatus(player);\n *\n * return (\n * <View>\n * <Text>Playing: {status.playing ? 'Yes' : 'No'}</Text>\n * <Text>Current Time: {status.currentTime}s</Text>\n * <Text>Duration: {status.duration}s</Text>\n * </View>\n * );\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\n/**\n * Hook that sets up audio sampling for an `AudioPlayer` and calls a listener with audio data.\n *\n * This hook enables audio sampling on the player (if supported) and subscribes to audio sample updates.\n * Audio sampling provides real-time access to audio waveform data for visualization or analysis.\n *\n * > **Note:** Audio sampling requires `RECORD_AUDIO` permission on Android and is not supported on all platforms.\n *\n * @param player The `AudioPlayer` instance to sample audio from.\n * @param listener Function called with each audio sample containing waveform data.\n *\n * @example\n * ```tsx\n * import { useEffect } from 'react';\n * import { useAudioPlayer, useAudioSampleListener, requestRecordingPermissionsAsync } from 'expo-audio';\n *\n * function AudioVisualizerComponent() {\n * const player = useAudioPlayer(require('./music.mp3'));\n *\n * // if required on Android, request recording permissions\n * useEffect(() => {\n * async function requestPermission() {\n * const { granted } = await requestRecordingPermissionsAsync();\n * if (granted) {\n * console.log(\"Permission granted\");\n * }\n * }\n *\n * requestPermission();\n * }, []);\n *\n * useAudioSampleListener(player, (sample) => {\n * // Use sample.channels array for audio visualization\n * console.log('Audio sample:', sample.channels[0].frames);\n * });\n *\n * return <AudioWaveform player={player} />;\n * }\n * ```\n */\nexport function useAudioSampleListener(player: AudioPlayer, listener: (data: AudioSample) => void) {\n useEffect(() => {\n if (!player.isAudioSamplingSupported) {\n return;\n }\n player.setAudioSamplingEnabled(true);\n const subscription = player.addListener(AUDIO_SAMPLE_UPDATE, listener);\n return () => subscription.remove();\n }, [player.id]);\n}\n\n/**\n * Hook that creates an `AudioRecorder` instance for recording audio.\n *\n * This hook manages the recorder's lifecycle and ensures it's properly disposed when no longer needed.\n * The recorder is automatically prepared with the provided options and can be used to record audio.\n *\n * @param options Recording configuration options including format, quality, sample rate, etc.\n * @param statusListener Optional callback function that receives recording status updates.\n * @returns An `AudioRecorder` instance that's automatically managed by the component lifecycle.\n *\n * @example\n * ```tsx\n * import { useAudioRecorder, RecordingPresets } from 'expo-audio';\n *\n * function RecorderComponent() {\n * const recorder = useAudioRecorder(\n * RecordingPresets.HIGH_QUALITY,\n * (status) => console.log('Recording status:', status)\n * );\n *\n * const startRecording = async () => {\n * await recorder.prepareToRecordAsync();\n * recorder.record();\n * };\n *\n * return (\n * <Button title=\"Start Recording\" onPress={startRecording} />\n * );\n * }\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\n/**\n * Hook that provides real-time recording state updates for an `AudioRecorder`.\n *\n * This hook polls the recorder's status at regular intervals and returns the current recording state.\n * Use this when you need to monitor the recording status without setting up a status listener.\n *\n * @param recorder The `AudioRecorder` instance to monitor.\n * @param interval How often (in milliseconds) to poll the recorder's status. Defaults to 500ms.\n * @returns The current `RecorderState` containing recording information.\n *\n * @example\n * ```tsx\n * import { useAudioRecorder, useAudioRecorderState, RecordingPresets } from 'expo-audio';\n *\n * function RecorderStatusComponent() {\n * const recorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);\n * const state = useAudioRecorderState(recorder);\n *\n * return (\n * <View>\n * <Text>Recording: {state.isRecording ? 'Yes' : 'No'}</Text>\n * <Text>Duration: {Math.round(state.durationMillis / 1000)}s</Text>\n * <Text>Can Record: {state.canRecord ? 'Yes' : 'No'}</Text>\n * </View>\n * );\n * }\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 const newState = recorder.getStatus();\n\n setState((prevState) => {\n const meteringChanged =\n (prevState.metering === undefined) !== (newState.metering === undefined) ||\n (prevState.metering !== undefined &&\n newState.metering !== undefined &&\n Math.abs(prevState.metering - newState.metering) > 0.1);\n\n if (\n prevState.canRecord !== newState.canRecord ||\n prevState.isRecording !== newState.isRecording ||\n prevState.mediaServicesDidReset !== newState.mediaServicesDidReset ||\n prevState.url !== newState.url ||\n Math.abs(prevState.durationMillis - newState.durationMillis) > 50 ||\n meteringChanged\n ) {\n return newState;\n }\n return prevState;\n });\n }, interval);\n\n return () => clearInterval(int);\n }, [recorder.id]);\n\n return state;\n}\n\n/**\n * Creates an instance of an `AudioPlayer` that doesn't release automatically.\n *\n * > **info** For most use cases you should use the [`useAudioPlayer`](#useaudioplayersource-options) hook instead.\n * > See the [Using the `AudioPlayer` directly](#using-the-audioplayer-directly) section for more details.\n * @param source The audio source to load.\n * @param options Audio player configuration options.\n */\nexport function createAudioPlayer(\n source: AudioSource | string | number | null = null,\n options: AudioPlayerOptions = {}\n): AudioPlayer {\n const { updateInterval = 500, downloadFirst = false, keepAudioSessionActive = false } = options;\n const initialSource = downloadFirst ? null : resolveSource(source);\n const player = new AudioModule.AudioPlayer(initialSource, updateInterval, keepAudioSessionActive);\n\n if (downloadFirst && source) {\n resolveSourceWithDownload(source)\n .then((resolved) => {\n if (resolved) {\n player.replace(resolved);\n }\n })\n .catch((error) => {\n console.warn('expo-audio: Failed to download source, using fallback:', error);\n const fallback = resolveSource(source);\n if (fallback) {\n player.replace(fallback);\n }\n });\n }\n\n return player;\n}\n\n/**\n * Enables or disables the audio subsystem globally.\n *\n * When set to `false`, this will pause all audio playback and prevent new audio from playing.\n * This is useful for implementing app-wide audio controls or responding to system events.\n *\n * @param active Whether audio should be active (`true`) or disabled (`false`).\n * @returns A Promise that resolves when the audio state has been updated.\n *\n * @example\n * ```tsx\n * import { setIsAudioActiveAsync } from 'expo-audio';\n *\n * // Disable all audio when app goes to background\n * const handleAppStateChange = async (nextAppState) => {\n * if (nextAppState === 'background') {\n * await setIsAudioActiveAsync(false);\n * } else if (nextAppState === 'active') {\n * await setIsAudioActiveAsync(true);\n * }\n * };\n * ```\n */\nexport async function setIsAudioActiveAsync(active: boolean): Promise<void> {\n return await AudioModule.setIsAudioActiveAsync(active);\n}\n\n/**\n * Configures the global audio behavior and session settings.\n *\n * This function allows you to control how your app's audio interacts with other apps,\n * background playback behavior, audio routing, and interruption handling.\n *\n * @param mode Partial audio mode configuration object. Only specified properties will be updated.\n * @returns A Promise that resolves when the audio mode has been applied.\n *\n * @example\n * ```tsx\n * import { setAudioModeAsync } from 'expo-audio';\n *\n * // Configure audio for background playback\n * await setAudioModeAsync({\n * playsInSilentMode: true,\n * shouldPlayInBackground: true,\n * interruptionModeAndroid: 'duckOthers',\n * interruptionMode: 'mixWithOthers'\n * });\n *\n * // Configure audio for recording\n * await setAudioModeAsync({\n * allowsRecording: true,\n * playsInSilentMode: true\n * });\n * ```\n */\nexport async function setAudioModeAsync(mode: Partial<AudioMode>): Promise<void> {\n const audioMode: Partial<AudioMode> =\n Platform.OS === 'ios'\n ? mode\n : {\n shouldPlayInBackground: mode.shouldPlayInBackground,\n shouldRouteThroughEarpiece: mode.shouldRouteThroughEarpiece,\n interruptionMode: mode.interruptionModeAndroid,\n allowsBackgroundRecording: mode.allowsBackgroundRecording,\n };\n return await AudioModule.setAudioModeAsync(audioMode);\n}\n\n/**\n * Requests permission to record audio from the microphone.\n *\n * This function prompts the user for microphone access permission, which is required\n * for audio recording functionality. On iOS, this will show the system permission dialog.\n * On Android, this requests the `RECORD_AUDIO` permission.\n *\n * @returns A Promise that resolves to a `PermissionResponse` object containing the permission status.\n *\n * @example\n * ```tsx\n * import { requestRecordingPermissionsAsync } from 'expo-audio';\n *\n * const checkPermissions = async () => {\n * const { status, granted } = await requestRecordingPermissionsAsync();\n *\n * if (granted) {\n * console.log('Recording permission granted');\n * } else {\n * console.log('Recording permission denied:', status);\n * }\n * };\n * ```\n */\nexport async function requestRecordingPermissionsAsync(): Promise<PermissionResponse> {\n return await AudioModule.requestRecordingPermissionsAsync();\n}\n\n/**\n * Checks the current status of recording permissions without requesting them.\n *\n * This function returns the current permission status for microphone access\n * without triggering a permission request dialog. Use this to check permissions\n * before deciding whether to call `requestRecordingPermissionsAsync()`.\n *\n * @returns A Promise that resolves to a `PermissionResponse` object containing the current permission status.\n *\n * @example\n * ```tsx\n * import { getRecordingPermissionsAsync, requestRecordingPermissionsAsync } from 'expo-audio';\n *\n * const ensureRecordingPermissions = async () => {\n * const { status } = await getRecordingPermissionsAsync();\n *\n * if (status !== 'granted') {\n * // Permission not granted, request it\n * const { granted } = await requestRecordingPermissionsAsync();\n * return granted;\n * }\n *\n * return true; // Already granted\n * };\n * ```\n */\nexport async function getRecordingPermissionsAsync(): Promise<PermissionResponse> {\n return await AudioModule.getRecordingPermissionsAsync();\n}\n\nexport { AudioModule };\n"]}
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';\nimport { Platform } from 'react-native';\n\nimport {\n AudioMode,\n AudioPlayerOptions,\n AudioSource,\n AudioStatus,\n PitchCorrectionQuality,\n RecorderState,\n RecordingOptions,\n RecordingStartOptions,\n RecordingStatus,\n} from './Audio.types';\nimport {\n AUDIO_SAMPLE_UPDATE,\n PLAYBACK_STATUS_UPDATE,\n RECORDING_STATUS_UPDATE,\n} from './AudioEventKeys';\nimport AudioModule from './AudioModule';\nimport { AudioPlayer, AudioRecorder, AudioSample } from './AudioModule.types';\nimport { createRecordingOptions } from './utils/options';\nimport { resolveSource, resolveSourceWithDownload } from './utils/resolveSource';\n\n// TODO: Temporary solution until we develop a way of overriding prototypes that won't break the lazy loading of the module.\nconst replace = AudioModule.AudioPlayer.prototype.replace;\nAudioModule.AudioPlayer.prototype.replace = function (source: AudioSource) {\n return replace.call(this, resolveSource(source));\n};\n\nconst setPlaybackRate = AudioModule.AudioPlayer.prototype.setPlaybackRate;\nAudioModule.AudioPlayer.prototype.setPlaybackRate = function (\n rate: number,\n pitchCorrectionQuality?: PitchCorrectionQuality\n) {\n if (Platform.OS === 'android') {\n return setPlaybackRate.call(this, rate);\n } else {\n return setPlaybackRate.call(this, rate, pitchCorrectionQuality);\n }\n};\n\n// Audio recording prototypes should not be shimmed on tvOS, where they do not exist\nif (!Platform.isTV || Platform.OS !== 'ios') {\n const prepareToRecordAsync = AudioModule.AudioRecorder.prototype.prepareToRecordAsync;\n AudioModule.AudioRecorder.prototype.prepareToRecordAsync = function (options?: RecordingOptions) {\n const processedOptions = options ? createRecordingOptions(options) : undefined;\n return prepareToRecordAsync.call(this, processedOptions);\n };\n\n const record = AudioModule.AudioRecorder.prototype.record;\n AudioModule.AudioRecorder.prototype.record = function (options?: RecordingStartOptions) {\n return record.call(this, options);\n };\n}\n\n/**\n * Creates an `AudioPlayer` instance that automatically releases when the component unmounts.\n *\n * This hook manages the player's lifecycle and ensures it's properly disposed when no longer needed.\n * The player will start loading the audio source immediately upon creation.\n *\n * @param source The audio source to load. Can be a local asset via `require()`, a remote URL, or null for no initial source.\n * @param options Audio player configuration options.\n * @returns An `AudioPlayer` instance that's automatically managed by the component lifecycle.\n *\n * @example\n * ```tsx\n * import { useAudioPlayer } from 'expo-audio';\n *\n * function MyComponent() {\n * const player = useAudioPlayer(require('./sound.mp3'));\n *\n * return (\n * <Button title=\"Play\" onPress={() => player.play()} />\n * );\n * }\n * ```\n *\n * @example Using downloadFirst\n * ```tsx\n * import { useAudioPlayer } from 'expo-audio';\n *\n * function MyComponent() {\n * const player = useAudioPlayer('https://example.com/audio.mp3', {\n * updateInterval: 1000,\n * downloadFirst: true,\n * });\n *\n * return (\n * <Button title=\"Play\" onPress={() => player.play()} />\n * );\n * }\n * ```\n */\nexport function useAudioPlayer(\n source: AudioSource = null,\n options: AudioPlayerOptions = {}\n): AudioPlayer {\n const { updateInterval = 500, downloadFirst = false, keepAudioSessionActive = false } = options;\n\n // If downloadFirst is true, we don't need to resolve the source, because it will be resolved in the useEffect below.\n // If downloadFirst is false, we resolve the source here.\n // we call .replace() in the useEffect below to replace the source with the downloaded one.\n const initialSource = useMemo(() => {\n return downloadFirst ? null : resolveSource(source);\n }, [JSON.stringify(source), downloadFirst]);\n\n const player = useReleasingSharedObject(\n () => new AudioModule.AudioPlayer(initialSource, updateInterval, keepAudioSessionActive),\n [JSON.stringify(initialSource), updateInterval, keepAudioSessionActive]\n );\n\n // Handle async source resolution for downloadFirst\n useEffect(() => {\n if (!downloadFirst || source === null) {\n return;\n }\n\n let isCancelled = false;\n\n // We resolve the source with expo-asset and replace the player's source with the downloaded one.\n async function resolveAndReplaceSource() {\n try {\n const resolved = await resolveSourceWithDownload(source);\n\n if (\n !isCancelled &&\n resolved &&\n JSON.stringify(resolved) !== JSON.stringify(initialSource)\n ) {\n player.replace(resolved);\n }\n } catch (error) {\n if (!isCancelled) {\n console.warn('expo-audio: Failed to download source, using original:', error);\n }\n }\n }\n\n resolveAndReplaceSource();\n\n return () => {\n isCancelled = true;\n };\n }, [player, JSON.stringify(source), downloadFirst]);\n\n return player;\n}\n\n/**\n * Hook that provides real-time playback status updates for an `AudioPlayer`.\n *\n * This hook automatically subscribes to playback status changes and returns the current status.\n * The status includes information about playback state, current time, duration, loading state, and more.\n *\n * @param player The `AudioPlayer` instance to monitor.\n * @returns The current `AudioStatus` object containing playback information.\n *\n * @example\n * ```tsx\n * import { useAudioPlayer, useAudioPlayerStatus } from 'expo-audio';\n *\n * function PlayerComponent() {\n * const player = useAudioPlayer(require('./sound.mp3'));\n * const status = useAudioPlayerStatus(player);\n *\n * return (\n * <View>\n * <Text>Playing: {status.playing ? 'Yes' : 'No'}</Text>\n * <Text>Current Time: {status.currentTime}s</Text>\n * <Text>Duration: {status.duration}s</Text>\n * </View>\n * );\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\n/**\n * Hook that sets up audio sampling for an `AudioPlayer` and calls a listener with audio data.\n *\n * This hook enables audio sampling on the player (if supported) and subscribes to audio sample updates.\n * Audio sampling provides real-time access to audio waveform data for visualization or analysis.\n *\n * > **Note:** Audio sampling requires `RECORD_AUDIO` permission on Android and is not supported on all platforms.\n *\n * @param player The `AudioPlayer` instance to sample audio from.\n * @param listener Function called with each audio sample containing waveform data.\n *\n * @example\n * ```tsx\n * import { useEffect } from 'react';\n * import { useAudioPlayer, useAudioSampleListener, requestRecordingPermissionsAsync } from 'expo-audio';\n *\n * function AudioVisualizerComponent() {\n * const player = useAudioPlayer(require('./music.mp3'));\n *\n * // if required on Android, request recording permissions\n * useEffect(() => {\n * async function requestPermission() {\n * const { granted } = await requestRecordingPermissionsAsync();\n * if (granted) {\n * console.log(\"Permission granted\");\n * }\n * }\n *\n * requestPermission();\n * }, []);\n *\n * useAudioSampleListener(player, (sample) => {\n * // Use sample.channels array for audio visualization\n * console.log('Audio sample:', sample.channels[0].frames);\n * });\n *\n * return <AudioWaveform player={player} />;\n * }\n * ```\n */\nexport function useAudioSampleListener(player: AudioPlayer, listener: (data: AudioSample) => void) {\n useEffect(() => {\n if (!player.isAudioSamplingSupported) {\n return;\n }\n player.setAudioSamplingEnabled(true);\n const subscription = player.addListener(AUDIO_SAMPLE_UPDATE, listener);\n return () => subscription.remove();\n }, [player.id]);\n}\n\n/**\n * Hook that creates an `AudioRecorder` instance for recording audio.\n *\n * This hook manages the recorder's lifecycle and ensures it's properly disposed when no longer needed.\n * The recorder is automatically prepared with the provided options and can be used to record audio.\n *\n * @param options Recording configuration options including format, quality, sample rate, etc.\n * @param statusListener Optional callback function that receives recording status updates.\n * @returns An `AudioRecorder` instance that's automatically managed by the component lifecycle.\n *\n * @example\n * ```tsx\n * import { useAudioRecorder, RecordingPresets } from 'expo-audio';\n *\n * function RecorderComponent() {\n * const recorder = useAudioRecorder(\n * RecordingPresets.HIGH_QUALITY,\n * (status) => console.log('Recording status:', status)\n * );\n *\n * const startRecording = async () => {\n * await recorder.prepareToRecordAsync();\n * recorder.record();\n * };\n *\n * return (\n * <Button title=\"Start Recording\" onPress={startRecording} />\n * );\n * }\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\n/**\n * Hook that provides real-time recording state updates for an `AudioRecorder`.\n *\n * This hook polls the recorder's status at regular intervals and returns the current recording state.\n * Use this when you need to monitor the recording status without setting up a status listener.\n *\n * @param recorder The `AudioRecorder` instance to monitor.\n * @param interval How often (in milliseconds) to poll the recorder's status. Defaults to 500ms.\n * @returns The current `RecorderState` containing recording information.\n *\n * @example\n * ```tsx\n * import { useAudioRecorder, useAudioRecorderState, RecordingPresets } from 'expo-audio';\n *\n * function RecorderStatusComponent() {\n * const recorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);\n * const state = useAudioRecorderState(recorder);\n *\n * return (\n * <View>\n * <Text>Recording: {state.isRecording ? 'Yes' : 'No'}</Text>\n * <Text>Duration: {Math.round(state.durationMillis / 1000)}s</Text>\n * <Text>Can Record: {state.canRecord ? 'Yes' : 'No'}</Text>\n * </View>\n * );\n * }\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 const newState = recorder.getStatus();\n\n setState((prevState) => {\n const meteringChanged =\n (prevState.metering === undefined) !== (newState.metering === undefined) ||\n (prevState.metering !== undefined &&\n newState.metering !== undefined &&\n Math.abs(prevState.metering - newState.metering) > 0.1);\n\n if (\n prevState.canRecord !== newState.canRecord ||\n prevState.isRecording !== newState.isRecording ||\n prevState.mediaServicesDidReset !== newState.mediaServicesDidReset ||\n prevState.url !== newState.url ||\n Math.abs(prevState.durationMillis - newState.durationMillis) > 50 ||\n meteringChanged\n ) {\n return newState;\n }\n return prevState;\n });\n }, interval);\n\n return () => clearInterval(int);\n }, [recorder.id]);\n\n return state;\n}\n\n/**\n * Creates an instance of an `AudioPlayer` that doesn't release automatically.\n *\n * > **info** For most use cases you should use the [`useAudioPlayer`](#useaudioplayersource-options) hook instead.\n * > See the [Using the `AudioPlayer` directly](#using-the-audioplayer-directly) section for more details.\n * @param source The audio source to load.\n * @param options Audio player configuration options.\n */\nexport function createAudioPlayer(\n source: AudioSource | string | number | null = null,\n options: AudioPlayerOptions = {}\n): AudioPlayer {\n const { updateInterval = 500, downloadFirst = false, keepAudioSessionActive = false } = options;\n const initialSource = downloadFirst ? null : resolveSource(source);\n const player = new AudioModule.AudioPlayer(initialSource, updateInterval, keepAudioSessionActive);\n\n if (downloadFirst && source) {\n resolveSourceWithDownload(source)\n .then((resolved) => {\n if (resolved) {\n player.replace(resolved);\n }\n })\n .catch((error) => {\n console.warn('expo-audio: Failed to download source, using fallback:', error);\n const fallback = resolveSource(source);\n if (fallback) {\n player.replace(fallback);\n }\n });\n }\n\n return player;\n}\n\n/**\n * Enables or disables the audio subsystem globally.\n *\n * When set to `false`, this will pause all audio playback and prevent new audio from playing.\n * This is useful for implementing app-wide audio controls or responding to system events.\n *\n * @param active Whether audio should be active (`true`) or disabled (`false`).\n * @returns A Promise that resolves when the audio state has been updated.\n *\n * @example\n * ```tsx\n * import { setIsAudioActiveAsync } from 'expo-audio';\n *\n * // Disable all audio when app goes to background\n * const handleAppStateChange = async (nextAppState) => {\n * if (nextAppState === 'background') {\n * await setIsAudioActiveAsync(false);\n * } else if (nextAppState === 'active') {\n * await setIsAudioActiveAsync(true);\n * }\n * };\n * ```\n */\nexport async function setIsAudioActiveAsync(active: boolean): Promise<void> {\n return await AudioModule.setIsAudioActiveAsync(active);\n}\n\n/**\n * Configures the global audio behavior and session settings.\n *\n * This function allows you to control how your app's audio interacts with other apps,\n * background playback behavior, audio routing, and interruption handling.\n *\n * @param mode Partial audio mode configuration object. Only specified properties will be updated.\n * @returns A Promise that resolves when the audio mode has been applied.\n *\n * @example\n * ```tsx\n * import { setAudioModeAsync } from 'expo-audio';\n *\n * // Configure audio for background playback with mixing\n * await setAudioModeAsync({\n * playsInSilentMode: true,\n * shouldPlayInBackground: true,\n * interruptionMode: 'mixWithOthers'\n * });\n *\n * // Configure audio for recording\n * await setAudioModeAsync({\n * allowsRecording: true,\n * playsInSilentMode: true\n * });\n * ```\n */\nexport async function setAudioModeAsync(mode: Partial<AudioMode>): Promise<void> {\n const audioMode: Partial<AudioMode> =\n Platform.OS === 'ios'\n ? mode\n : {\n shouldPlayInBackground: mode.shouldPlayInBackground,\n shouldRouteThroughEarpiece: mode.shouldRouteThroughEarpiece,\n interruptionMode: mode.interruptionMode ?? mode.interruptionModeAndroid,\n allowsBackgroundRecording: mode.allowsBackgroundRecording,\n };\n return await AudioModule.setAudioModeAsync(audioMode);\n}\n\n/**\n * Requests permission to record audio from the microphone.\n *\n * This function prompts the user for microphone access permission, which is required\n * for audio recording functionality. On iOS, this will show the system permission dialog.\n * On Android, this requests the `RECORD_AUDIO` permission.\n *\n * @returns A Promise that resolves to a `PermissionResponse` object containing the permission status.\n *\n * @example\n * ```tsx\n * import { requestRecordingPermissionsAsync } from 'expo-audio';\n *\n * const checkPermissions = async () => {\n * const { status, granted } = await requestRecordingPermissionsAsync();\n *\n * if (granted) {\n * console.log('Recording permission granted');\n * } else {\n * console.log('Recording permission denied:', status);\n * }\n * };\n * ```\n */\nexport async function requestRecordingPermissionsAsync(): Promise<PermissionResponse> {\n return await AudioModule.requestRecordingPermissionsAsync();\n}\n\n/**\n * Checks the current status of recording permissions without requesting them.\n *\n * This function returns the current permission status for microphone access\n * without triggering a permission request dialog. Use this to check permissions\n * before deciding whether to call `requestRecordingPermissionsAsync()`.\n *\n * @returns A Promise that resolves to a `PermissionResponse` object containing the current permission status.\n *\n * @example\n * ```tsx\n * import { getRecordingPermissionsAsync, requestRecordingPermissionsAsync } from 'expo-audio';\n *\n * const ensureRecordingPermissions = async () => {\n * const { status } = await getRecordingPermissionsAsync();\n *\n * if (status !== 'granted') {\n * // Permission not granted, request it\n * const { granted } = await requestRecordingPermissionsAsync();\n * return granted;\n * }\n *\n * return true; // Already granted\n * };\n * ```\n */\nexport async function getRecordingPermissionsAsync(): Promise<PermissionResponse> {\n return await AudioModule.getRecordingPermissionsAsync();\n}\n\nexport { AudioModule };\n"]}
@@ -8,7 +8,7 @@
8
8
  "publication": {
9
9
  "groupId": "expo.modules.audio",
10
10
  "artifactId": "expo.modules.audio",
11
- "version": "1.1.0",
11
+ "version": "1.1.1",
12
12
  "repository": "local-maven-repo"
13
13
  }
14
14
  }
@@ -0,0 +1 @@
1
+ 7eaacaedf52a9405d5528160f5ea55d8ae2c3aee058e23c5ff38ea0eef49f857
@@ -0,0 +1 @@
1
+ 242a78fc0793a6c1dc7a6038366ca399a114d2fbc40a95dbdf12d6c6cd9c8332859c0db57df317f469bb094c7cc3d82ddadc55d0f451d1de19ca1752eab4afcd
@@ -0,0 +1 @@
1
+ ba11953f9a468b30e019884e27cf3a0d10ab4e64
@@ -0,0 +1 @@
1
+ 134bbd7cc66f91a1507fab5eb9798e513f59c4423cc2847958bd3cfc9f21fe8e
@@ -0,0 +1 @@
1
+ 33c1be4fbe060c3296bedfffeebeca73cda0f80d35784b2168c58ce2ce27462772cbc60bb406e84d805f223a2f5f1ef95608756002a52442cca5b97226dc3a99
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "expo.modules.audio",
5
5
  "module": "expo.modules.audio",
6
- "version": "1.1.0",
6
+ "version": "1.1.1",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
@@ -24,13 +24,13 @@
24
24
  },
25
25
  "files": [
26
26
  {
27
- "name": "expo.modules.audio-1.1.0.aar",
28
- "url": "expo.modules.audio-1.1.0.aar",
29
- "size": 257011,
30
- "sha512": "8b4103be253c0fcf9202ff5bec04b8e51f2178afafba2cc677e8dd1021f000262c7f73a4f67fc35d00fdecbce9257f82670a7c6187d589960c923d193ea0ca82",
31
- "sha256": "8f524d770bcc3e93938e2e34034dd1964a20e2d2dfe003a907a6c7fbf2c7ea4b",
32
- "sha1": "eff14cf9e092dfd21a3380992fdf11b2d49dda8e",
33
- "md5": "3af89778fbcaf88922ddd633de7f0fb4"
27
+ "name": "expo.modules.audio-1.1.1.aar",
28
+ "url": "expo.modules.audio-1.1.1.aar",
29
+ "size": 257267,
30
+ "sha512": "33c1be4fbe060c3296bedfffeebeca73cda0f80d35784b2168c58ce2ce27462772cbc60bb406e84d805f223a2f5f1ef95608756002a52442cca5b97226dc3a99",
31
+ "sha256": "134bbd7cc66f91a1507fab5eb9798e513f59c4423cc2847958bd3cfc9f21fe8e",
32
+ "sha1": "ba11953f9a468b30e019884e27cf3a0d10ab4e64",
33
+ "md5": "cfd2d097a5f6db7baa95c5dfc4731943"
34
34
  }
35
35
  ]
36
36
  },
@@ -109,13 +109,13 @@
109
109
  ],
110
110
  "files": [
111
111
  {
112
- "name": "expo.modules.audio-1.1.0.aar",
113
- "url": "expo.modules.audio-1.1.0.aar",
114
- "size": 257011,
115
- "sha512": "8b4103be253c0fcf9202ff5bec04b8e51f2178afafba2cc677e8dd1021f000262c7f73a4f67fc35d00fdecbce9257f82670a7c6187d589960c923d193ea0ca82",
116
- "sha256": "8f524d770bcc3e93938e2e34034dd1964a20e2d2dfe003a907a6c7fbf2c7ea4b",
117
- "sha1": "eff14cf9e092dfd21a3380992fdf11b2d49dda8e",
118
- "md5": "3af89778fbcaf88922ddd633de7f0fb4"
112
+ "name": "expo.modules.audio-1.1.1.aar",
113
+ "url": "expo.modules.audio-1.1.1.aar",
114
+ "size": 257267,
115
+ "sha512": "33c1be4fbe060c3296bedfffeebeca73cda0f80d35784b2168c58ce2ce27462772cbc60bb406e84d805f223a2f5f1ef95608756002a52442cca5b97226dc3a99",
116
+ "sha256": "134bbd7cc66f91a1507fab5eb9798e513f59c4423cc2847958bd3cfc9f21fe8e",
117
+ "sha1": "ba11953f9a468b30e019884e27cf3a0d10ab4e64",
118
+ "md5": "cfd2d097a5f6db7baa95c5dfc4731943"
119
119
  }
120
120
  ]
121
121
  },
@@ -129,13 +129,13 @@
129
129
  },
130
130
  "files": [
131
131
  {
132
- "name": "expo.modules.audio-1.1.0-sources.jar",
133
- "url": "expo.modules.audio-1.1.0-sources.jar",
134
- "size": 20435,
135
- "sha512": "3e2d63d13769736a93f26ffa5f706211ace6fdc6fd9ad4b897d9aa6aa7980377d51ffb2ac5bb84e1346797c63813b7453fca94229c6f0fc9092af5a70e64dba0",
136
- "sha256": "fac3684506f3f2ba7c412da318b4f6f35deef8ab953118f6520d6bd801a081a1",
137
- "sha1": "37e1561412a1cdb45a770959a1f493aca4373082",
138
- "md5": "2581b1b0da1549241cb1d73938662406"
132
+ "name": "expo.modules.audio-1.1.1-sources.jar",
133
+ "url": "expo.modules.audio-1.1.1-sources.jar",
134
+ "size": 20483,
135
+ "sha512": "242a78fc0793a6c1dc7a6038366ca399a114d2fbc40a95dbdf12d6c6cd9c8332859c0db57df317f469bb094c7cc3d82ddadc55d0f451d1de19ca1752eab4afcd",
136
+ "sha256": "7eaacaedf52a9405d5528160f5ea55d8ae2c3aee058e23c5ff38ea0eef49f857",
137
+ "sha1": "d24404ed25576653071c1902871ab2841c83990e",
138
+ "md5": "6eceff6c98804f919f041dab524799f7"
139
139
  }
140
140
  ]
141
141
  }
@@ -0,0 +1 @@
1
+ 6d9e543c5ec43405fc1f8d926be7f5c3ef8daaa4cff50bb5b7f52ec605828445
@@ -0,0 +1 @@
1
+ 49dc03522e03c905224cf6b8d68875098bc6fe0e6ccab313783f1d3011546cf54a8c12093c34067826f86f3d521d37df6cce3e623906014a529aa00a0123813a
@@ -9,7 +9,7 @@
9
9
  <modelVersion>4.0.0</modelVersion>
10
10
  <groupId>expo.modules.audio</groupId>
11
11
  <artifactId>expo.modules.audio</artifactId>
12
- <version>1.1.0</version>
12
+ <version>1.1.1</version>
13
13
  <packaging>aar</packaging>
14
14
  <name>expo.modules.audio</name>
15
15
  <url>https://github.com/expo/expo</url>
@@ -0,0 +1 @@
1
+ 4982f6df8fc93f1352196fe0e762a49c69dd0c16
@@ -0,0 +1 @@
1
+ 81cded6fc6972a09fdb41c13a001614f5aac4f9cd3032ad595284a7762815802
@@ -0,0 +1 @@
1
+ 6acc22cae1ba9b496db2add14d4f410d347a2d029ddfd39de0cfac6dead68c20b7e28bd71b3adfb889b5fbac2e0e2590aa9d8964d0014e2726e1d6f5255a8cd9
@@ -3,11 +3,11 @@
3
3
  <groupId>expo.modules.audio</groupId>
4
4
  <artifactId>expo.modules.audio</artifactId>
5
5
  <versioning>
6
- <latest>1.1.0</latest>
7
- <release>1.1.0</release>
6
+ <latest>1.1.1</latest>
7
+ <release>1.1.1</release>
8
8
  <versions>
9
- <version>1.1.0</version>
9
+ <version>1.1.1</version>
10
10
  </versions>
11
- <lastUpdated>20251211151715</lastUpdated>
11
+ <lastUpdated>20251217145123</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 9b7883b23785c72512400b0587f13123
1
+ 533e24ebee74453e60fe8a9d4fc222f3
@@ -1 +1 @@
1
- b5ae948cdb44d30f3767e6bee3327cd0258932c0
1
+ c8071432340aa2a6e6662a62a6394cd76861737c
@@ -1 +1 @@
1
- 6cdad33f00583563575cc8d79b8c4f1c078e960054f09e75d0fcbfd52008c1f4
1
+ f1704a96760526427d22e8e82c6a7cfbf61bfe6bb95883060a16db742693fe9f
@@ -1 +1 @@
1
- 3144da5fd46ca16ab8c195c1e5c4c86ae76c21f6fa08b755dac5d6d81cfa32b8f345d079e91bc21c2ec4fadc71d49b37aa9b38297e10e184fe7aaa9a88845eb2
1
+ 0898f57bd1c6e89d1d3dd84b0e6fcd25016e0bd876632ef1a7e05ff03bb67cbe2e7e7231c6ed4760defe3ec2aae4c2fc611fc1929d56776349325522df4bf2c7
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-audio",
3
3
  "title": "Expo Audio",
4
- "version": "1.1.0",
4
+ "version": "1.1.1",
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",
@@ -41,5 +41,5 @@
41
41
  "react-native": "*",
42
42
  "expo-asset": "*"
43
43
  },
44
- "gitHead": "e00d1696eff1e92611bd5b07b0f11e58373e3f30"
44
+ "gitHead": "ce76892f5b356dc1bbfeabaf29dd8a50a19aa08a"
45
45
  }
@@ -455,17 +455,22 @@ export type AudioMode = {
455
455
  */
456
456
  playsInSilentMode: boolean;
457
457
  /**
458
- * Determines how the audio session interacts with other sessions.
458
+ * Determines how the audio session interacts with other audio sessions.
459
459
  *
460
- * @platform ios
460
+ * - `'doNotMix'`: Requests exclusive audio focus. Other apps will pause their audio.
461
+ * - `'duckOthers'`: Requests audio focus with ducking. Other apps lower their volume but continue playing.
462
+ * - `'mixWithOthers'`: Audio plays alongside other apps without interrupting them.
463
+ * On Android, this means no audio focus is requested. Best suited for sound effects,
464
+ * UI feedback, or short audio clips.
461
465
  */
462
466
  interruptionMode: InterruptionMode;
463
467
  /**
464
468
  * Determines how the audio session interacts with other sessions on Android.
465
469
  *
466
470
  * @platform android
471
+ * @deprecated Use `interruptionMode` instead, which now works on both platforms.
467
472
  */
468
- interruptionModeAndroid: InterruptionModeAndroid;
473
+ interruptionModeAndroid?: InterruptionModeAndroid;
469
474
  /**
470
475
  * Whether the audio session allows recording.
471
476
  *
@@ -494,24 +499,24 @@ export type AudioMode = {
494
499
  };
495
500
 
496
501
  /**
497
- * Audio interruption behavior modes for iOS.
502
+ * Audio interruption behavior modes.
498
503
  *
499
- * Controls how your app's audio interacts with other apps' audio when interruptions occur.
500
- * This affects what happens when phone calls, notifications, or other apps play audio.
504
+ * Controls how your app's audio interacts with other apps' audio.
501
505
  *
502
506
  * @platform ios
507
+ * - `'doNotMix'`: Requests exclusive audio focus. Other apps will pause their audio.
508
+ * - `'duckOthers'`: Requests audio focus with ducking. Other apps lower their volume but continue playing.
509
+ * - `'mixWithOthers'`: Audio plays alongside other apps without interrupting them.
510
+ * On Android, this means no audio focus is requested - best suited for sound effects,
511
+ * UI feedback, or short audio clips. Note that on Android your app won't receive
512
+ * audio focus loss callbacks (for example, during phone calls) when using this mode.
503
513
  */
504
514
  export type InterruptionMode = 'mixWithOthers' | 'doNotMix' | 'duckOthers';
505
515
 
506
516
  /**
507
- * Audio interruption behavior modes for Android.
508
- *
509
- * Controls how your app's audio interacts with other apps' audio on Android.
510
- * Note that Android doesn't support 'mixWithOthers' mode; audio focus is more strictly managed.
511
- *
512
- * @platform android
517
+ * @deprecated Use `InterruptionMode` instead, which now works on both platforms.
513
518
  */
514
- export type InterruptionModeAndroid = 'doNotMix' | 'duckOthers';
519
+ export type InterruptionModeAndroid = InterruptionMode;
515
520
 
516
521
  /**
517
522
  * Recording source for android.
package/src/ExpoAudio.ts CHANGED
@@ -420,11 +420,10 @@ export async function setIsAudioActiveAsync(active: boolean): Promise<void> {
420
420
  * ```tsx
421
421
  * import { setAudioModeAsync } from 'expo-audio';
422
422
  *
423
- * // Configure audio for background playback
423
+ * // Configure audio for background playback with mixing
424
424
  * await setAudioModeAsync({
425
425
  * playsInSilentMode: true,
426
426
  * shouldPlayInBackground: true,
427
- * interruptionModeAndroid: 'duckOthers',
428
427
  * interruptionMode: 'mixWithOthers'
429
428
  * });
430
429
  *
@@ -442,7 +441,7 @@ export async function setAudioModeAsync(mode: Partial<AudioMode>): Promise<void>
442
441
  : {
443
442
  shouldPlayInBackground: mode.shouldPlayInBackground,
444
443
  shouldRouteThroughEarpiece: mode.shouldRouteThroughEarpiece,
445
- interruptionMode: mode.interruptionModeAndroid,
444
+ interruptionMode: mode.interruptionMode ?? mode.interruptionModeAndroid,
446
445
  allowsBackgroundRecording: mode.allowsBackgroundRecording,
447
446
  };
448
447
  return await AudioModule.setAudioModeAsync(audioMode);
@@ -1 +0,0 @@
1
- fac3684506f3f2ba7c412da318b4f6f35deef8ab953118f6520d6bd801a081a1
@@ -1 +0,0 @@
1
- 3e2d63d13769736a93f26ffa5f706211ace6fdc6fd9ad4b897d9aa6aa7980377d51ffb2ac5bb84e1346797c63813b7453fca94229c6f0fc9092af5a70e64dba0
@@ -1 +0,0 @@
1
- eff14cf9e092dfd21a3380992fdf11b2d49dda8e
@@ -1 +0,0 @@
1
- 8f524d770bcc3e93938e2e34034dd1964a20e2d2dfe003a907a6c7fbf2c7ea4b
@@ -1 +0,0 @@
1
- 8b4103be253c0fcf9202ff5bec04b8e51f2178afafba2cc677e8dd1021f000262c7f73a4f67fc35d00fdecbce9257f82670a7c6187d589960c923d193ea0ca82
@@ -1 +0,0 @@
1
- 3d183e50a43230bce0511ff774821337bc01a46e
@@ -1 +0,0 @@
1
- 1f8df1c58955b33d925a9f04ac7e8656635371f705428d8d5680085a5cccfd1b
@@ -1 +0,0 @@
1
- a06df0e2aab638365dc151027ff0afc4aedf4271d419bce182d04a69b9cb9b6e2a13f9637c81044375bca487c23a89d7951f8c5ed178ee6b35fc97f75e5459f8
@@ -1 +0,0 @@
1
- 8a2f4b6e7bd3a1550025c4b14dfe30111ea70dcd
@@ -1 +0,0 @@
1
- 4ec35760f835b450ad150a0e1a1f300c65cbb4cc286ef09bcbcf2bf1b1e1b9e5
@@ -1 +0,0 @@
1
- c7938086bce422e58a5a111fcc3797fd272df8120fb2981f5f253749196f7ac0878f65272453029b7da0f6ca21fdb876c9d4375446d1bf00f359664e90795577