|
| 1 | +--- |
| 2 | +sidebar_position: 1 |
| 3 | +--- |
| 4 | + |
| 5 | +import { Optional, ReadOnly, OnlyiOS } from '@site/src/components/Badges'; |
| 6 | + |
| 7 | +# AudioManager |
| 8 | + |
| 9 | +The `AudioManager` is a layer of an abstraction between user and a system. |
| 10 | +It provides a set of system-specific functions that are invoked directly in native code, by related system. |
| 11 | + |
| 12 | +## Example |
| 13 | + |
| 14 | +```tsx |
| 15 | +import { AudioManager } from 'react-native-audio-api'; |
| 16 | +import { useEffect } from 'react'; |
| 17 | + |
| 18 | +function App() { |
| 19 | + // set AVAudioSession example options (iOS only) |
| 20 | + AudioManager.setAudioSessionOptions({ |
| 21 | + iosCategory: 'playback', |
| 22 | + iosMode: 'default', |
| 23 | + iosOptions: ['allowBluetooth', 'allowAirPlay'], |
| 24 | + }) |
| 25 | + |
| 26 | + // set info for track to be visible while device is locked |
| 27 | + AudioManager.setLockScreenInfo({ |
| 28 | + title: 'Audio file', |
| 29 | + artist: 'Software Mansion', |
| 30 | + album: 'Audio API', |
| 31 | + duration: 10, |
| 32 | + }); |
| 33 | + |
| 34 | + useEffect(() => { |
| 35 | + |
| 36 | + // enabling emission of events |
| 37 | + AudioManager.enableRemoteCommand('remotePlay', true); |
| 38 | + AudioManager.enableRemoteCommand('remotePause', true); |
| 39 | + AudioManager.observeAudioInterruptions(true); |
| 40 | + |
| 41 | + // callback to be invoked on 'remotePlay' event |
| 42 | + const remotePlaySubscription = AudioManager.addSystemEventListener( |
| 43 | + 'remotePlay', |
| 44 | + (event) => { |
| 45 | + console.log('remotePlay event:', event); |
| 46 | + } |
| 47 | + ); |
| 48 | + |
| 49 | + // callback to be invoked on 'remotePause' event |
| 50 | + const remotePauseSubscription = AudioManager.addSystemEventListener( |
| 51 | + 'remotePause', |
| 52 | + (event) => { |
| 53 | + console.log('remotePause event:', event); |
| 54 | + } |
| 55 | + ); |
| 56 | + |
| 57 | + // callback to be invoked on 'interruption' event |
| 58 | + const interruptionSubscription = AudioManager.addSystemEventListener( |
| 59 | + 'interruption', |
| 60 | + (event) => { |
| 61 | + console.log('Interruption event:', event); |
| 62 | + } |
| 63 | + ); |
| 64 | + |
| 65 | + |
| 66 | + return () => { |
| 67 | + remotePlaySubscription?.remove(); |
| 68 | + remotePauseSubscription?.remove(); |
| 69 | + interruptionSubscription?.remove(); |
| 70 | + }; |
| 71 | + }, []); |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +## Methods |
| 76 | + |
| 77 | +### `setLockScreenInfo` |
| 78 | + |
| 79 | +| Parameters | Type | Description | |
| 80 | +| :---: | :---: | :-----: | |
| 81 | +| `info` | [`LockScreenInfo`](/system/audio-manager#lockscreeninfo) | Information to be displayed on the lock screen | |
| 82 | + |
| 83 | +#### Returns `undefined` |
| 84 | + |
| 85 | +### `resetLockScreenInfo` |
| 86 | + |
| 87 | +Resets all of the lock screen data. |
| 88 | + |
| 89 | +#### Returns `undefined` |
| 90 | + |
| 91 | +### `setAudioSessionOptions` <OnlyiOS /> |
| 92 | + |
| 93 | +| Parameters | Type | Description | |
| 94 | +| :---: | :---: | :---- | |
| 95 | +| options | [`SessionOptions`](/system/audio-manager#sessionoptions) | Options to be set for AVAudioSession | |
| 96 | + |
| 97 | +#### Returns `undefined` |
| 98 | + |
| 99 | +### `setAudioSessionActivity` <OnlyiOS /> |
| 100 | + |
| 101 | +| Parameters | Type | Description | |
| 102 | +| :---: | :---: | :---- | |
| 103 | +| enabled | `boolean` | It is used to set/unset AVAudioSession activity | |
| 104 | + |
| 105 | +#### Returns promise of `boolean` type, which is resolved to `true` if invokation ended with success, `false` otherwise. |
| 106 | + |
| 107 | +### `getDevicePreferredSampleRate` |
| 108 | + |
| 109 | +#### Returns `number`. |
| 110 | + |
| 111 | +### `observeAudioInterruptions` |
| 112 | + |
| 113 | +| Parameters | Type | Description | |
| 114 | +| :---: | :---: | :---- | |
| 115 | +| `enabled` | `boolean` | It is used to enable/disable observing audio interruptions | |
| 116 | + |
| 117 | +#### Returns `undefined` |
| 118 | + |
| 119 | +### `observeVolumeChanges` |
| 120 | + |
| 121 | +| Parameters | Type | Description | |
| 122 | +| :---: | :---: | :---- | |
| 123 | +| `enabled` | `boolean` | It is used to enable/disable observing volume changes | |
| 124 | + |
| 125 | +#### Returns `undefined` |
| 126 | + |
| 127 | +### `enableRemoteCommand` |
| 128 | + |
| 129 | +Enables emition of some system events. |
| 130 | + |
| 131 | +| Parameters | Type | Description | |
| 132 | +| :---: | :---: | :---- | |
| 133 | +| `name` | [`RemoteCommandEventName`](/system/audio-manager#systemeventname--remotecommandeventname) | Name of an event | |
| 134 | +| `enabled` | `boolean` | Indicates the start or the end of event emission | |
| 135 | + |
| 136 | +#### Returns `undefined` |
| 137 | + |
| 138 | +:::info |
| 139 | + |
| 140 | +If you want to add callback upon hearing event, remember to call [`addSystemEventListener`](/system/audio-manager#addsystemeventlistener) |
| 141 | +with proper parameters. |
| 142 | + |
| 143 | +::: |
| 144 | + |
| 145 | + |
| 146 | +### `addSystemEventListener` |
| 147 | + |
| 148 | +Adds callback to be invoked upon hearing an event. |
| 149 | + |
| 150 | +| Parameters | Type | Description | |
| 151 | +| :---: | :---: | :---- | |
| 152 | +| `name` | [`SystemEventName`](/system/audio-manager#systemeventname--remotecommandeventname) | Name of an event listener | |
| 153 | +| `callback` | [`SystemEventCallback`](/system/audio-manager#systemeventname--remotecommandeventname) | Callback that will be invoked upon hearing an event | |
| 154 | + |
| 155 | +#### Returns [`AudioEventSubscription`](/system/audio-manager#audioeventsubscription) if `enabled` is set to true, `undefined` otherwise |
| 156 | + |
| 157 | +### `requestRecordingPermissions` |
| 158 | + |
| 159 | +Allows to bring up the system microphone permissions pop-up on demand. The pop-up automatically shows if microphone data |
| 160 | +is directly requested, but sometimes it is better to ask beforehand. |
| 161 | + |
| 162 | +#### Returns promise of [`PermissionStatus`](/system/audio-manager#permissionstatus) type, which is resolved after receiving answer from the system. |
| 163 | + |
| 164 | +### `checkRecordingPermissions` |
| 165 | + |
| 166 | +Allows to check if permissions were previously granted. |
| 167 | + |
| 168 | +#### Returns promise of [`PermissionStatus`](/system/audio-manager#permissionstatus) type, which is resolved after receiving answer from the system. |
| 169 | + |
| 170 | +## Remarks |
| 171 | + |
| 172 | +### `LockScreenInfo` |
| 173 | + |
| 174 | +<details> |
| 175 | +<summary>Type definitions</summary> |
| 176 | +```typescript |
| 177 | +interface BaseLockScreenInfo { |
| 178 | + [key: string]: string | boolean | number | undefined; |
| 179 | +} |
| 180 | + |
| 181 | +//state_playing if track is played, state_paused otherwise |
| 182 | +type MediaState = 'state_playing' | 'state_paused'; |
| 183 | + |
| 184 | +interface LockScreenInfo extends BaseLockScreenInfo { |
| 185 | + title?: string; //title of the track |
| 186 | + artwork?: string; //uri to the artwork |
| 187 | + artist?: string; //name of the artist |
| 188 | + album?: string; //name of the album |
| 189 | + duration?: number; //duration in seconds |
| 190 | + description?: string; // android only, description of the track |
| 191 | + state?: MediaState; |
| 192 | + speed?: number; //playback rate |
| 193 | + elapsedTime?: number; //elapsed time of an audio in seconds |
| 194 | +} |
| 195 | +``` |
| 196 | +</details> |
| 197 | + |
| 198 | +### `SessionOptions` |
| 199 | + |
| 200 | +<details> |
| 201 | +<summary>Type definitions</summary> |
| 202 | +```typescript |
| 203 | +type IOSCategory = |
| 204 | + | 'record' |
| 205 | + | 'ambient' |
| 206 | + | 'playback' |
| 207 | + | 'multiRoute' |
| 208 | + | 'soloAmbient' |
| 209 | + | 'playAndRecord'; |
| 210 | + |
| 211 | +type IOSMode = |
| 212 | + | 'default' |
| 213 | + | 'gameChat' |
| 214 | + | 'videoChat' |
| 215 | + | 'voiceChat' |
| 216 | + | 'measurement' |
| 217 | + | 'voicePrompt' |
| 218 | + | 'spokenAudio' |
| 219 | + | 'moviePlayback' |
| 220 | + | 'videoRecording'; |
| 221 | + |
| 222 | +type IOSOption = |
| 223 | + | 'duckOthers' |
| 224 | + | 'allowAirPlay' |
| 225 | + | 'mixWithOthers' |
| 226 | + | 'allowBluetooth' |
| 227 | + | 'defaultToSpeaker' |
| 228 | + | 'allowBluetoothA2DP' |
| 229 | + | 'overrideMutedMicrophoneInterruption' |
| 230 | + | 'interruptSpokenAudioAndMixWithOthers'; |
| 231 | + |
| 232 | +interface SessionOptions { |
| 233 | + iosMode?: IOSMode; |
| 234 | + iosOptions?: IOSOption[]; |
| 235 | + iosCategory?: IOSCategory; |
| 236 | +} |
| 237 | +``` |
| 238 | +</details> |
| 239 | + |
| 240 | + |
| 241 | +### `SystemEventName` | `RemoteCommandEventName` |
| 242 | + |
| 243 | +<details> |
| 244 | +<summary>Type definitions</summary> |
| 245 | +```typescript |
| 246 | +interface EventEmptyType {} |
| 247 | + |
| 248 | +interface EventTypeWithValue { |
| 249 | + value: number; |
| 250 | +} |
| 251 | + |
| 252 | +interface OnInterruptionEventType { |
| 253 | + type: 'ended' | 'began'; //if interruption event has started or ended |
| 254 | + shouldResume: boolean; //if we should resume playing after interruption |
| 255 | +} |
| 256 | + |
| 257 | +interface OnRouteChangeEventType { |
| 258 | + reason: |
| 259 | + | 'Unknown' |
| 260 | + | 'Override' |
| 261 | + | 'CategoryChange' |
| 262 | + | 'WakeFromSleep' |
| 263 | + | 'NewDeviceAvailable' |
| 264 | + | 'OldDeviceUnavailable' |
| 265 | + | 'ConfigurationChange' |
| 266 | + | 'NoSuitableRouteForCategory'; |
| 267 | +} |
| 268 | + |
| 269 | +// visit https://developer.apple.com/documentation/mediaplayer/mpremotecommandcenter?language=objc |
| 270 | +// for further info |
| 271 | +interface RemoteCommandEvents { |
| 272 | + remotePlay: EventEmptyType; |
| 273 | + remotePause: EventEmptyType; |
| 274 | + remoteStop: EventEmptyType; |
| 275 | + remoteTogglePlayPause: EventEmptyType; // iOS only |
| 276 | + remoteChangePlaybackRate: EventTypeWithValue; |
| 277 | + remoteNextTrack: EventEmptyType; |
| 278 | + remotePreviousTrack: EventEmptyType; |
| 279 | + remoteSkipForward: EventTypeWithValue; |
| 280 | + remoteSkipBackward: EventTypeWithValue; // iOS only |
| 281 | + remoteSeekForward: EventEmptyType; // iOS only |
| 282 | + remoteSeekBackward: EventEmptyType; |
| 283 | + remoteChangePlaybackPosition: EventTypeWithValue; |
| 284 | +} |
| 285 | + |
| 286 | +type SystemEvents = RemoteCommandEvents & { |
| 287 | + volumeChange: EventTypeWithValue; //triggered when volume level is changed |
| 288 | + interruption: OnInterruptionEventType; //triggered when f.e. some app wants to play music when we are playing |
| 289 | + routeChange: OnRouteChangeEventType; //change of output f.e. from speaker to headphones, events are always emitted! |
| 290 | +}; |
| 291 | + |
| 292 | +type RemoteCommandEventName = keyof RemoteCommandEvents; |
| 293 | +type SystemEventName = keyof SystemEvents; |
| 294 | +type SystemEventCallback<Name extends SystemEventName> = ( |
| 295 | + event: SystemEvents[Name] |
| 296 | +) => void; |
| 297 | +``` |
| 298 | +</details> |
| 299 | + |
| 300 | + |
| 301 | +### `AudioEventSubscription` |
| 302 | + |
| 303 | +<details> |
| 304 | +<summary>Type definitions</summary> |
| 305 | +```typescript |
| 306 | +class AudioEventSubscription { |
| 307 | + private readonly audioEventEmitter: AudioEventEmitter; |
| 308 | + private readonly eventName: AudioEventName; |
| 309 | + /** @internal */ |
| 310 | + public readonly subscriptionId: string; |
| 311 | + |
| 312 | + constructor( |
| 313 | + subscriptionId: string, |
| 314 | + eventName: AudioEventName, |
| 315 | + audioEventEmitter: AudioEventEmitter |
| 316 | + ) { |
| 317 | + this.subscriptionId = subscriptionId; |
| 318 | + this.eventName = eventName; |
| 319 | + this.audioEventEmitter = audioEventEmitter; |
| 320 | + } |
| 321 | + |
| 322 | + public remove(): void { |
| 323 | + this.audioEventEmitter.removeAudioEventListener( |
| 324 | + this.eventName, |
| 325 | + this.subscriptionId |
| 326 | + ); |
| 327 | + } |
| 328 | +} |
| 329 | +``` |
| 330 | +</details> |
| 331 | + |
| 332 | +### `PermissionStatus` |
| 333 | + |
| 334 | +<details> |
| 335 | +<summary>Type definitions</summary> |
| 336 | +```typescript |
| 337 | +type PermissionStatus = 'Undetermined' | 'Denied' | 'Granted'; |
| 338 | +``` |
| 339 | +</details> |
0 commit comments