目录:
- 思路
- 安装中间件
- 获取录音权限、实现录音功能
- 调用接口,实现上传录音文件
思路
- 获取用户录音权限;
- 实现本地录音功能、播放录音(注意点:播放时,需要使用本地路径,而不是服务器地址)、删除录音
- 实现上传接口的封装,需要 formData 对象的格式
- 调用上传接口,实现录音上传 (使用的
fetch
请求接口)
具体步骤
1. 安装中间件 react-native-audio
和 react-native-sound
版本:
"react": "16.8.3",
"react-native": "0.59.9",
"react-native-audio": "4.3.0",
"react-native-sound": "0.11.0"
2. 获取用户录音权限、实现本地录音功能、播放录音、删除录音
- (注意⚠️点:播放时,需要使用本地路径,而不是服务器地址)
【主要代码如下】
【- 组织中引入中间件 `react-native-audio`(实现录音功能)、`react-native-sound`(实现播放语音功能)】
【- 获取录音授权】
【- 实现本地录音】
【- 本地录音播放、删除】
...
import React, { Component } from 'react';
import { AudioRecorder, AudioUtils } from 'react-native-audio';
import Sound from 'react-native-sound';
import {requestAudio} from './audioAction'; // 此文件内容在下面
...
class Test extends Component {
constructor(props) {
super(props);
this.state = {
...
hasPermission: undefined, //录音 授权状态
audioPath: AudioUtils.DocumentDirectoryPath + `/quick_audio_${new Date().getTime()}.aac`, // 文件路径
stop: false, //录音是否停止
currentTime: 0, //录音时长
...
}
}
componentDidMount() {
this.getAudioAuthorize()
}
// 请求录音授权
getAudioAuthorize() {
AudioRecorder.requestAuthorization()
.then(isAuthor => {
console.log('是否授权: ' + isAuthor)
if(!isAuthor) {
return alert('APP需要使用录音,请打开录音权限允许APP使用')
}
this.setState({hasPermission: isAuthor})
this.prepareRecordingPath(this.state.audioPath);
// 录音进展
AudioRecorder.onProgress = (data) => {
this.setState({
currentTime: Math.ceil(data.currentTime)
});
};
// 完成录音
AudioRecorder.onFinished = (data) => {
// data 录音数据,可以在此存储需要传给接口的路径数据
console.log(this.state.currentTime)
};
})
}
/**
* AudioRecorder.prepareRecordingAtPath(path,option)
* 录制路径
* path 路径
* option 参数
*/
prepareRecordingPath = (path) => {
const option = {
SampleRate: 44100.0, //采样率
Channels: 2, //通道
AudioQuality: 'High', //音质
AudioEncoding: 'aac', //音频编码 aac
OutputFormat: 'mpeg_4', //输出格式
MeteringEnabled: false, //是否计量
MeasurementMode: false, //测量模式
AudioEncodingBitRate: 32000, //音频编码比特率
IncludeBase64: true, //是否是base64格式
AudioSource: 0, //音频源
}
AudioRecorder.prepareRecordingAtPath(path,option)
}
// 开始录音
handleStartAudio = async () => {
if(!this.state.hasPermission) {
return alert('APP需要使用录音,请打开录音权限允许APP使用')
}
show('录音开始')
if(this.state.stop) {
// 初始化录音
this.prepareRecordingPath(this.state.audioPath)
}
try {
await AudioRecorder.startRecording()
} catch (err) {
console.error(err)
}
}
// 停止录音
handleStopAudio = async () => {
show('录音结束')
try {
await AudioRecorder.stopRecording();
this.setState({ stop: true, recording: false });
} catch (error) {
console.error(error);
}
}
// 播放录音
handlePlayAudio = async () => {
let self = this
show('正在播放')
self.whoosh = new Sound(this.state.audioPath, '', (err) => {
if(err) {
show('加载音频失败')
return console.warn(err)
}
self.whoosh.play(success => {
if(success) {
console.warn('success - 播放成功')
show('播放完毕')
}else {
console.warn('fail - 播放失败')
show('播放失败')
}
})
})
}
// 删除录音
handleDelAudio = async () => {
// 初始化录音
this.prepareRecordingPath(this.state.audioPath)
let {listOptionData} = this.state
listOptionData[11].value = ''
this.setState({
currentTime: 0,
stop: false,
listOptionData
})
}
// 注意⚠️,在此处调用接口,传递录音
async handlesubmit() {
let {stop, audioPath} = this.state
if(stop) {
// 有录音
let params = {
path: audioPath // 根据自己项目修改参数哈
}
let audioResult = await requestAudio(params); // requestAudio 是封装的请求接口的函数,具体内容在下面
console.log('audioResult----请求接口后返回的数据:', audioResult)
}
}
...
render() {
return (
录音
停止录音
播放录音
删除录音
this.handlesubmit()}
>
提交录音
)
}
...
}
3. 封装的录音请求后端接口的函数 requestAudio
,需要 formData
对象的格式,即【调用上传接口】,实现录音上传;
【文件 `audioAction` 内容如下:】
import {UploadRequest} from './util'; // 该函数内容在下面哈
...
// 上传语音
export const requestAudio = async (params) => {
let { path } = params
let formData = new FormData()
let soundPath = `file://${path}` // 注意需要增加前缀 `file://`
let fileName = path.substring(path.lastIndexOf('/') + 1, path.length) // 文件名
let file = { uri: soundPath, type: "multipart/form-data", name: fileName} // 注意 `uri` 表示文件地址,`type` 表示接口接收的类型,一般为这个,跟后端确认一下
formData.append('file', file)
return await UploadRequest('自己的接口地址', formData) // `UploadRequest` 上传也是封装过,具体参考下面
}
...
4. 【fetch
上传】文件的封装;
【文件 `util` 内容如下:】
...
// 上传
export const UploadRequest(url, datas) {
let BaseUrl = 'http://www.baidu.com' // 域名地址,根据自己的修改
const params = {
method: 'POST',
body: datas,
headers: {
'Content-Type': 'multipart/form-data'
},
timeout: 5000 // 5s超时
};
return fetch(`${BaseUrl}${url}`, params)
.then(response => response.json())
.then(data => data)
.catch(error => {
return {error_code: -3, error_msg:'请求异常,请重试'}
})
}
...
写给自己的随笔,有问题欢迎指出