Expo 音频 (expo-audio)
一个提供用于在应用中实现音频播放和录制的 API 的库。
For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.
expo-audio 是一个跨平台音频库,用于访问设备的原生音频能力。
请注意,如果耳机/蓝牙音频设备断开连接,音频会自动停止。
安装
- npx expo install expo-audioIf you are installing this in an existing React Native app, make sure to install expo in your project.
在 app 配置中进行配置
如果你在项目中使用配置插件(Continuous Native Generation (CNG)),你可以使用 expo-audio 内置的 config plugin 来进行配置。该插件允许你配置各种无法在运行时设置、且需要构建新的应用二进制文件后才会生效的属性。如果你的应用不使用 CNG,那么你需要手动配置该库。
Example app.json with config plugin
{ "expo": { "plugins": [ [ "expo-audio", { "microphonePermission": "允许 $(PRODUCT_NAME) 访问你的麦克风。" } ] ] } }
Configurable properties
| Name | Default | Description |
|---|---|---|
microphonePermission | "允许 $(PRODUCT_NAME) 访问你的麦克风" | Only for: iOS 用于设置 |
使用
播放声音
import { View, StyleSheet, Button } from 'react-native'; import { useAudioPlayer } from 'expo-audio'; const audioSource = require('./assets/Hello.mp3'); export default function App() { const player = useAudioPlayer(audioSource); return ( <View style={styles.container}> <Button title="播放声音" onPress={() => player.play()} /> <Button title="重新播放声音" onPress={() => { player.seekTo(0); player.play(); }} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', backgroundColor: '#ecf0f1', padding: 10, }, });
信息 注意: 如果你是从
expo-av迁移过来的,你会注意到expo-audio在音频结束时不会自动重置播放位置。执行play()后,播放器会在声音末尾保持暂停状态。要再次播放,请调用seekTo(seconds)来重置位置——如上面的示例所示。
录制声音
import { useState, useEffect } from 'react'; import { View, StyleSheet, Button } from 'react-native'; import { useAudioRecorder, AudioModule, RecordingPresets, setAudioModeAsync, useAudioRecorderState, } from 'expo-audio'; export default function App() { const audioRecorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY); const recorderState = useAudioRecorderState(audioRecorder); const record = async () => { await audioRecorder.prepareToRecordAsync(); audioRecorder.record(); }; const stopRecording = async () => { // 录音文件将可在 `audioRecorder.uri` 中获取。 await audioRecorder.stop(); }; useEffect(() => { (async () => { const status = await AudioModule.requestRecordingPermissionsAsync(); if (!status.granted) { Alert.alert('麦克风访问权限被拒绝'); } setAudioModeAsync({ playsInSilentMode: true, allowsRecording: true, }); })(); }, []); return ( <View style={styles.container}> <Button title={recorderState.isRecording ? '停止录音' : '开始录音'} onPress={recorderState.isRecording ? stopRecording : record} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', backgroundColor: '#ecf0f1', padding: 10, }, });
在后台播放或录制音频 iOS
在 iOS 上,后台音频播放和录制仅适用于独立应用,并且需要额外配置。
在 iOS 上,每个后台功能都需要在你的 Info.plist 文件中的 UIBackgroundModes 数组里添加一个特殊键。
在独立应用中,这个数组默认是空的,因此要使用后台功能,你需要在你的 app.json 配置中添加相应的键。
以下是启用后台音频播放的 app.json 示例:
{ "expo": { ... "ios": { ... "infoPlist": { ... "UIBackgroundModes": [ "audio" ] } } } }
直接使用 AudioPlayer
在大多数情况下,应使用 useAudioPlayer 钩子来创建 AudioPlayer 实例。它会管理播放器的生命周期,并确保在组件卸载时正确释放。然而,在某些高级用例中,可能需要创建一个在组件卸载时不会自动销毁的 AudioPlayer。
在这种情况下,可以使用 createAudioPlayer 函数来创建 AudioPlayer。你需要了解这种方式带来的风险,因为当播放器不再需要时,调用 release() 方法是你的责任。如果处理不当,这种方式可能会导致内存泄漏。
import { createAudioPlayer } from 'expo-audio'; const player = createAudioPlayer(audioSource);
Web 使用说明
- Chrome 上的一个 MediaRecorder 问题会生成缺少时长元数据的 WebM 文件。查看未解决的 Chromium 问题。
- MediaRecorder 的编码选项和其他配置在不同浏览器之间并不一致,在你的应用中使用 kbumsik/opus-media-recorder 或 ai/audio-recorder-polyfill 等 Polyfill 会改善你的体验。传递给
prepareToRecordAsync的任何选项都会直接传递给 MediaRecorder API,因此也会传递给 Polyfill。 - Web 浏览器要求网站通过安全方式提供服务,以便它们监听麦克风。有关更多细节,请参见 MediaDevices
getUserMedia()security。
API
import { useAudioPlayer, useAudioRecorder } from 'expo-audio';
Constants
Type: Record<string, RecordingOptions>
Constant which contains definitions of the two preset examples of RecordingOptions, as implemented in the Audio SDK.
HIGH_QUALITY
RecordingPresets.HIGH_QUALITY = { extension: '.m4a', sampleRate: 44100, numberOfChannels: 2, bitRate: 128000, android: { outputFormat: 'mpeg4', audioEncoder: 'aac', }, ios: { outputFormat: IOSOutputFormat.MPEG4AAC, audioQuality: AudioQuality.MAX, linearPCMBitDepth: 16, linearPCMIsBigEndian: false, linearPCMIsFloat: false, }, web: { mimeType: 'audio/webm', bitsPerSecond: 128000, }, };
LOW_QUALITY
RecordingPresets.LOW_QUALITY = { extension: '.m4a', sampleRate: 44100, numberOfChannels: 2, bitRate: 64000, android: { extension: '.3gp', outputFormat: '3gp', audioEncoder: 'amr_nb', }, ios: { audioQuality: AudioQuality.MIN, outputFormat: IOSOutputFormat.MPEG4AAC, linearPCMBitDepth: 16, linearPCMIsBigEndian: false, linearPCMIsFloat: false, }, web: { mimeType: 'audio/webm', bitsPerSecond: 128000, }, };
Hooks
| Parameter | Type |
|---|---|
| options | RecordingOptions |
| statusListener(optional) | (status: RecordingStatus) => void |
AudioRecorderClasses
Type: Class extends SharedObject<AudioEvents>
AudioPlayer Properties
booleanBoolean value indicating whether audio sampling is supported on the platform.
booleanBoolean value indicating whether the player is finished loading.
booleanBoolean value indicating whether the player is currently paused.
booleanBoolean value indicating whether the player is currently playing.
booleanA boolean describing if we are correcting the pitch for a changed rate.
AudioPlayer Methods
| Parameter | Type | Description |
|---|---|---|
| seconds | number | The number of seconds to seek by. |
Seeks the playback by the given number of seconds.
Promise<void>| Parameter | Type | Description |
|---|---|---|
| rate | number | The playback rate of the audio. |
| pitchCorrectionQuality(optional) | PitchCorrectionQuality | The quality of the pitch correction. |
Sets the current playback rate of the audio.
voidType: Class extends SharedObject<RecordingEvents>
AudioRecorder Properties
booleanBoolean value indicating whether the recording is in progress.
AudioRecorder Methods
Returns a list of available recording inputs. This method can only be called if the Recording has been prepared.
RecordingInput[]A Promise that is fulfilled with an array of RecordingInput objects.
Returns the currently-selected recording input. This method can only be called if the Recording has been prepared.
RecordingInputA Promise that is fulfilled with a RecordingInput object.
Status of the current recording.
RecorderState| Parameter | Type |
|---|---|
| options(optional) | Partial<RecordingOptions> |
Prepares the recording for recording.
Promise<void>| Parameter | Type | Description |
|---|---|---|
| seconds | number | The time in seconds to stop recording at. |
Stops the recording once the specified time has elapsed.
void| Parameter | Type | Description |
|---|---|---|
| inputUid | string | The uid of a |
Sets the current recording input.
voidA Promise that is resolved if successful or rejected if not.
| Parameter | Type | Description |
|---|---|---|
| seconds | number | The time in seconds to start recording at. |
Starts the recording at the given time.
voidStop the recording.
Promise<void>Methods
| Parameter | Type |
|---|---|
| source(optional) | AudioSource |
| updateInterval(optional) | number |
Creates an instance of an AudioPlayer that doesn't release automatically.
For most use cases you should use theuseAudioPlayerhook instead. See the Using theAudioPlayerdirectly section for more details.
AudioPlayerPromise<PermissionResponse>Promise<PermissionResponse>Promise<void>Event Subscriptions
Types
Literal Type: string
Acceptable values are: 'default' | 'amr_nb' | 'amr_wb' | 'aac' | 'he_aac' | 'aac_eld'
Literal Type: string
Acceptable values are: 'default' | '3gp' | 'mpeg4' | 'amrnb' | 'amrwb' | 'aac_adts' | 'mpeg2ts' | 'webm'
| Property | Type | Description |
|---|---|---|
| audioSampleUpdate | (data: AudioSample) => void | - |
| playbackStatusUpdate | (status: AudioStatus) => void | - |
| Property | Type | Description |
|---|---|---|
| allowsRecording(optional) | boolean | Only for: iOS Whether the audio session allows recording. Default: false |
| interruptionMode | InterruptionMode | Only for: iOS Determines how the audio session interacts with other sessions. |
| interruptionModeAndroid | InterruptionModeAndroid | Only for: Android Determines how the audio session interacts with other sessions on Android. |
| playsInSilentMode | boolean | Only for: iOS Determines if audio playback is allowed when the device is in silent mode. |
| shouldPlayInBackground(optional) | boolean | Whether the audio session stays active when the app moves to the background. Default: false |
| shouldRouteThroughEarpiece | boolean | Only for: Android Whether the audio should route through the earpiece. |
| Property | Type | Description |
|---|---|---|
| channels | AudioSampleChannel[] | - |
| timestamp | number | - |
Type: string or number or null or object shaped as below:
| Property | Type | Description |
|---|---|---|
| assetId(optional) | number | The asset ID of a local audio asset, acquired with the |
| headers(optional) | Record<string, string> | An object representing the HTTP headers to send along with the request for a remote audio source.
On web requires the |
| uri(optional) | string | A string representing the resource identifier for the audio, which could be an HTTPS address, a local file path, or the name of a static audio file resource. |
| Property | Type | Description |
|---|---|---|
| currentTime | number | - |
| didJustFinish | boolean | - |
| duration | number | - |
| id | number | - |
| isBuffering | boolean | - |
| isLoaded | boolean | - |
| loop | boolean | - |
| mute | boolean | - |
| playbackRate | number | - |
| playbackState | string | - |
| playing | boolean | - |
| reasonForWaitingToPlay | string | - |
| shouldCorrectPitch | boolean | - |
| timeControlStatus | string | - |
Literal Type: string
Acceptable values are: 'constant' | 'longTermAverage' | 'variableConstrained' | 'variable'
Literal Type: string
Acceptable values are: 'mixWithOthers' | 'doNotMix' | 'duckOthers'
Literal Type: string
Acceptable values are: 'doNotMix' | 'duckOthers'
Literal Type: union
Permission expiration time. Currently, all permissions are granted permanently.
Acceptable values are: 'never' | number
An object obtained by permissions get and request functions.
| Property | Type | Description |
|---|---|---|
| canAskAgain | boolean | Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission. |
| expires | PermissionExpiration | Determines time when the permission expires. |
| granted | boolean | A convenience boolean that indicates if the permission is granted. |
| status | PermissionStatus | Determines the status of the permission. |
Literal Type: string
Acceptable values are: 'low' | 'medium' | 'high'
| Property | Type | Description |
|---|---|---|
| canRecord | boolean | - |
| durationMillis | number | - |
| isRecording | boolean | - |
| mediaServicesDidReset | boolean | - |
| metering(optional) | number | - |
| url | string | null | - |
| Property | Type | Description |
|---|---|---|
| recordingStatusUpdate | (status: RecordingStatus) => void | - |
| Property | Type | Description |
|---|---|---|
| android | RecordingOptionsAndroid | Only for: Android Recording options for the Android platform. |
| bitRate | number | The desired bit rate. Example
|
| extension | string | The desired file extension. Example
|
| ios | RecordingOptionsIos | Only for: iOS Recording options for the iOS platform. |
| isMeteringEnabled(optional) | boolean | A boolean that determines whether audio level information will be part of the status object under the "metering" key. |
| numberOfChannels | number | The desired number of channels. Example
|
| sampleRate | number | The desired sample rate. Example
|
| web(optional) | RecordingOptionsWeb | Only for: Web Recording options for the Web platform. |
| Property | Type | Description |
|---|---|---|
| audioEncoder | AndroidAudioEncoder | The desired audio encoder. See the |
| extension(optional) | string | The desired file extension. Example
|
| maxFileSize(optional) | number | The desired maximum file size in bytes, after which the recording will stop (but Example
|
| outputFormat | AndroidOutputFormat | The desired file format. See the |
| sampleRate(optional) | number | The desired sample rate. Example
|
| Property | Type | Description |
|---|---|---|
| audioQuality | AudioQuality | number | The desired audio quality. See the |
| bitDepthHint(optional) | number | The desired bit depth hint. Example
|
| bitRateStrategy(optional) | number | The desired bit rate strategy. See the next section for an enumeration of all valid values of |
| extension(optional) | string | The desired file extension. Example
|
| linearPCMBitDepth(optional) | number | The desired PCM bit depth. Example
|
| linearPCMIsBigEndian(optional) | boolean | A boolean describing if the PCM data should be formatted in big endian. |
| linearPCMIsFloat(optional) | boolean | A boolean describing if the PCM data should be encoded in floating point or integral values. |
| outputFormat(optional) | string | IOSOutputFormat | number | The desired file format. See the |
| sampleRate(optional) | number | The desired sample rate. Example
|
| Property | Type | Description |
|---|---|---|
| bitsPerSecond(optional) | number | - |
| mimeType(optional) | string | - |
| Property | Type | Description |
|---|---|---|
| error | string | null | - |
| hasError | boolean | - |
| id | number | - |
| isFinished | boolean | - |
| url | string | null | - |