Skip to main content
Glama
audio.md5.74 kB
--- title: Audio (expo-audio) description: A library that provides an API to implement audio playback and recording in apps. sourceCodeUrl: https://github.com/expo/expo/tree/sdk-53/packages/expo-audio packageName: expo-audio iconUrl: /static/images/packages/expo-av.png platforms: ["android", "ios", "web", "tvos"] --- `expo-audio` is a cross-platform audio library for accessing the native audio capabilities of the device. Note that audio automatically stops if headphones/bluetooth audio devices are disconnected. ## Installation ## Configuration in app config You can configure `expo-audio` using its built-in [config plugin](/config-plugins/introduction/) if you use config plugins in your project ([EAS Build](/build/introduction) or `npx expo run:[android|ios]`). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect. If your app does **not** use EAS Build, then you'll need to manually configure the package. ```json app.json { "expo": { "plugins": [ [ "expo-audio", { "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone." } ] ] } } ``` ## Usage ### Playing sounds ```jsx const audioSource = require('./assets/Hello.mp3'); const player = useAudioPlayer(audioSource); return ( <View style={styles.container}> <Button title="Play Sound" onPress={() => player.play()} /> <Button title="Replay Sound" onPress={() => { player.seekTo(0); player.play(); }} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', backgroundColor: '#ecf0f1', padding: 10, }, }); ``` > **Info** **Note:** If you're migrating from [`expo-av`](av.md), you'll notice that `expo-audio` doesn't automatically reset the playback position when audio finishes. After [`play()`](#play), the player stays paused at the end of the sound. To play it again, call [`seekTo(seconds)`](#seektoseconds) to reset the position — as shown in the example above. ### Recording sounds ```jsx import { useAudioRecorder, AudioModule, RecordingPresets, setAudioModeAsync, useAudioRecorderState, } from 'expo-audio'; const audioRecorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY); const recorderState = useAudioRecorderState(audioRecorder); const record = async () => { await audioRecorder.prepareToRecordAsync(); audioRecorder.record(); }; const stopRecording = async () => { // The recording will be available on `audioRecorder.uri`. await audioRecorder.stop(); }; useEffect(() => { (async () => { const status = await AudioModule.requestRecordingPermissionsAsync(); if (!status.granted) { Alert.alert('Permission to access microphone was denied'); } setAudioModeAsync({ playsInSilentMode: true, allowsRecording: true, }); })(); }, []); return ( <View style={styles.container}> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', backgroundColor: '#ecf0f1', padding: 10, }, }); ``` ### Playing or recording audio in background&ensp; On iOS, audio playback and recording in background is only available in standalone apps, and it requires some extra configuration. On iOS, each background feature requires a special key in `UIBackgroundModes` array in your **Info.plist** file. In standalone apps this array is empty by default, so to use background features you will need to add appropriate keys to your **app.json** configuration. See an example of **app.json** that enables audio playback in background: ```json { "expo": { ... "ios": { ... "infoPlist": { ... "UIBackgroundModes": [ "audio" ] } } } } ``` ### Using the AudioPlayer directly In most cases, the [`useAudioPlayer`](#useaudioplayersource-updateinterval) hook should be used to create a `AudioPlayer` instance. It manages the player's lifecycle and ensures that it is properly disposed of when the component is unmounted. However, in some advanced use cases, it might be necessary to create a `AudioPlayer` that does not get automatically destroyed when the component is unmounted. In those cases, the `AudioPlayer` can be created using the [`createAudioPlayer`](#audiocreateaudioplayersource-updateinterval) function. You need be aware of the risks that come with this approach, as it is your responsibility to call the [`release()`](../sdk/expo/#release) method when the player is no longer needed. If not handled properly, this approach may lead to memory leaks. ```tsx const player = createAudioPlayer(audioSource); ``` ### Notes on web usage - A MediaRecorder issue on Chrome produces WebM files missing the duration metadata. [See the open Chromium issue](https://bugs.chromium.org/p/chromium/issues/detail?id=642012). - MediaRecorder encoding options and other configurations are inconsistent across browsers, utilizing a Polyfill such as [kbumsik/opus-media-recorder](https://github.com/kbumsik/opus-media-recorder) or [ai/audio-recorder-polyfill](https://github.com/ai/audio-recorder-polyfill) in your application will improve your experience. Any options passed to `prepareToRecordAsync` will be passed directly to the MediaRecorder API and as such the polyfill. - Web browsers require sites to be served securely for them to listen to a mic. See [MediaDevices `getUserMedia()` security](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#security) for more details. ## API ```js ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jaksm/expo-docs-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server