效果
屏幕录制2021-02-01 下午5.gif库文件
使用到的库有react-native-audio,teaset两第三方库,react-native-audio用来录音,teaset中使用Toast展示录音效果图。
首先
主要说明一下这个效果,录音功能最后说,向上代码
export default class RecordView extends React.Component {
static key = null;
static show(text) {
let showIcon;
if (RecordView.key) RecordView.hide()
if (text == '松开手指取消发送') {
showIcon = (<Image source={icCancel} style={{ width: 100, height: 100 }} />)
} else {
showIcon = (
<Image source={icMic} style={{ width: 100, height: 100 }} />
);
}
RecordView.key = Toast.show({
text: (
<Text style={{ fontSize: 13, color: 'white' }}>
{text}
</Text>
),
icon: showIcon,
position: 'center',
duration: 1000000,
});
}
static hide() {
if (!RecordView.key) return;
Toast.hide(RecordView.key);
RecordView.key = null;
}
}
清晰明了,2个方法,一个显示一个隐藏。里面包含两张图片icCancel和icMic, 用来展示。
其次
接下来就是如何调用这个方法来, 包括什么时机调用
this.Gesture = {
onStartShouldSetResponder: (evt) => true,
onMoveShouldSetResponder: (evt) => true,
onResponderGrant: (evt) => {
// console.log(evt);
this.setState(
{
isRecord: true,
recordTitle: '手指上滑动,取消发送',
isCancel: false,
currentPageY: evt.nativeEvent.pageY,
},
() => {
RecordToast.show(this.state.recordTitle);
this._record();
this.props.onScroll(false);
},
);
},
onResponderMove: (evt) => {
// console.log(evt);
if (evt.nativeEvent.pageY - this.state.currentPageY < -5) {
if (
this.state.isRecord &&
this.state.recordTitle == '手指上滑动,取消发送'
) {
this.setState(
{
recordTitle: '松开手指取消发送',
isCancel: true,
},
() => {
RecordToast.show(this.state.recordTitle);
},
);
}
} else if (evt.nativeEvent.pageY - this.state.currentPageY > 5) {
if (
this.state.isRecord &&
this.state.recordTitle == '松开手指取消发送'
) {
this.setState(
{
recordTitle: '手指上滑动,取消发送',
isCancel: false,
},
() => {
RecordToast.show(this.state.recordTitle);
},
);
}
} else {
if (!this.state.isRecord) {
this.setState(
{
isRecord: true,
recordTitle: '手指上滑动,取消发送',
isCancel: false,
},
() => {
RecordToast.show(this.state.recordTitle);
this._record();
this.props.onScroll(false);
},
);
}
}
},
onResponderRelease: (evt) => {
console.log('3333');
this.setState(
{
isRecord: false,
},
() => {
RecordToast.hide();
this._cancel(this.state.isCancel);
this.props.onScroll(true);
},
);
},
onResponderTerminationRequest: (evt) => false,
};
在componentDidMount方法中,初始化手势识别代码,复制给触发事件的组件,
用来展示录音图片和取消图片
<View
{...this.Gesture}
</View>
最后
进行录音,引入头文件
import {AudioRecorder, AudioUtils} from 'react-native-audio';
紧接着在componentDidMount方法中
AudioRecorder.onProgress = (data) => {
let temp = Math.floor(data.currentTime);
if (temp >= 60) {
this.setState(
{
isRecord: false,
recordTitle: '手指上滑动,取消发送',
},
() => {
RecordToast.hide();
Alert.alert('录制时间不能超过60秒');
this._cancel(false);
this.props.onScroll(true);
},
);
} else {
this.setState({
currentTime: temp,
});
}
};
AudioRecorder.onFinished = (data) => {
};
进行坚挺录音和结束的方法
录音开始录音
_record = async () => {
if(CommonUtils.ios) {
this.audioPath =
AudioUtils.CachesDirectoryPath + `${new Date().getTime()}.aac`;
} else {
this.audioPath = AudioUtils.DocumentDirectoryPath + `${new Date().getTime()}.aac`;
}
this.prepareRecordingPath(this.audioPath);
try {
const filePath = await AudioRecorder.startRecording();
return filePath;
} catch (error) {
console.log(error);
}
};
prepareRecordingPath = (audioPath) => {
AudioRecorder.prepareRecordingAtPath(audioPath, {
SampleRate: 22050,
Channels: 1,
AudioQuality: 'Low',
AudioEncoding: 'aac',
OutputFormat: 'aac_adts',
});
};
这个地方需要注意一下,因为存在路径的问题, AudioUtils.CachesDirectoryPath是iOS的缓存路径,在真机和模拟器上都可以找到,如果遇到无法录音的情况,看下log大部分都是无法创建datafile之类的,说明路径不对。
如果遇到android上传不了文件的问题,注意看下log和路径。一般都是类似这类问题
停止录音和取消录音
_cancel = (canceled) => {
this._stop();
if (canceled) return;
if (this.state.currentTime < 1) {
Alert.alert('录制时间太短了');
setTimeout(() => {
RecordToast.hide();
}, 300);
return;
}
this.setState({currentTime: null});
setTimeout(() => {
// 上传音频文件,操作
}, 500);
};
_stop = async () => {
try {
const filePath = await AudioRecorder.stopRecording();
return filePath;
} catch (error) {}
};
到此大功告成。
网友评论