项目是基于creat-react-app框架的,
点击录音按钮时,弹出录音框,实现开始录音,录音试听,确认本次录音,将本次录音内容传递给第二个audio标签
import React, { Component } from 'react';
import "./index.less";
let recorder;
class Audio extends Component {
constructor(props) {
super(props);
this.state = {
records: [],//当前录音数据 可暂停叠加
isAudio: false,//是否正在录音
isAudioCtn: false,//是否是继续录音
isListen: false, //是否正在试听录音
teaMp3Blob: Blob,//录音的Blob文件
mp3: '',
showMod: false,
}
}
componentDidMount() {
}
//点击录音按钮
readyAudio = () => {
var that = this;
that.setState({
showMod: true,
isAudio: false,
isAudioCtn: false,
records: [],
isListen: false,
}, () => {
var audioObj = {
video: false,
audio: true
};
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(audioObj).then(function (stream) {
onSuccess(stream)
}).catch(function (err) {
console.log(err);
})
} else {
alert("您的浏览器不支持录音功能");
}
function onSuccess(stream) {
recorder = new MediaRecorder(stream);
recorder.ondataavailable = (ev) => {
let { records } = that.state;
records.push(ev.data);
that.setState({
records
})
};
}
})
}
//开始录音
beginAudio = (e) => {
var that = this;
let { isAudio, isListen } = that.state;
if (isListen) {
let myAudio = document.getElementById('myAudio');
myAudio.pause();// 这个就是暂停();
if (isAudio) {
recorder.stop();
that.setState({
isAudio: false,
isAudioCtn: true,
isListen: false,
})
} else {
if (recorder) {
recorder.start();
that.setState({
isAudio: true,
isListen: false,
})
}
}
} else {
if (isAudio) {
recorder.stop();
that.setState({
isAudio: false,
isAudioCtn: true,
isListen: false,
})
} else {
if (recorder) {
recorder.start();
that.setState({
isAudio: true,
isListen: false,
})
}
}
}
}
//录音试听
playAudio = () => {
let that = this;
let { records, isAudio, isListen } = that.state;
if (isAudio) return
if (records.length == 0) {
console.log("error", "提示", "暂无录音文件", 5)
return;
}
if (isListen) {
that.setState({
isListen: false
})
let myAudio = document.getElementById('myAudio');
myAudio.pause();// 这个就是暂停();
} else {
that.setState({
isListen: true
})
const blob = new Blob(records, { type: 'audio/mp3' });
const reader = new FileReader();
reader.addEventListener('load', (ev) => {
document.getElementById('myAudio').src = ev.target.result;
that.myAudioPlay();
}, false);
reader.readAsDataURL(blob);
}
}
myAudioPlay = () => {
let myAudio = document.getElementById('myAudio');
let that = this;
myAudio.addEventListener('loadedmetadata', (ev) => {
myAudio.play();
}, false);
myAudio.addEventListener('ended', function () {
that.setState({
isListen: false
})
}, false);
}
//确定本次录音文件
sure = () => {
let that = this;
let { isAudio, records } = that.state;
if (isAudio) return
if (records.length == 0) return
const blob = new Blob(records, { type: 'audio/mp3' });
const reader = new FileReader();
reader.addEventListener('load', (ev) => {
var mp3 = ev.target.result;
if (!mp3 || mp3.length < 6) {
console.log("error", "提示", "暂无录音文件", 3)
return;
}
this.setState({
mp3
});
this.cancel()
}, false);
reader.readAsDataURL(blob);
}
cancel = () => {
this.setState({
showMod: false,
isAudio: false,
isAudioCtn: false,
records: [],
isListen: false,
})
}
render() {
let { isAudio, isAudioCtn, isListen, records, mp3, showMod } = this.state;
return (
<div className='audio_page'>
<button onClick={this.readyAudio}>录音</button>
{showMod
?(<div className='audio_model'>
<audio id='myAudio' preload='true'></audio>
<button className={isAudio ? 'act' : ''} onClick={this.beginAudio}>{isAudio ? '暂停录音' : (isAudioCtn ? '继续录音' : '开始录音')}</button>
<button className={isAudio ? 'noclick' : (isListen ? 'act' : '')} onClick={this.playAudio}>{isListen ? '停止播放' : '录音试听'}</button>
<button className={isAudio || records.length == 0 ? 'noclick' : ''} onClick={this.sure}>确认录音</button>
<button onClick={this.cancel}>取消录音</button>
</div>)
: null}
{mp3 ? <audio controls src={mp3}></audio> : null}
</div>
)
}
}
export default Audio;
首先判断浏览器是否支持录音,并创建录音对象,
录音时每次录音时可以叠加的,如果不想叠加就在取消时清空recorders数组,当然在readyAudio方法的success中也可以控制录音是否叠加.
下面是less文件
.audio_page {
position: relative;
width: 100%;
padding: 15px 2%;
box-sizing: border-box;
.noclick {
&:hover {
cursor: not-allowed;
}
}
.audio_model{
position: relative;
z-index: 2;
top: 20%;
left: 20%;
>button {
height: 30px;
line-height: 28px;
padding: 0 20px;
letter-spacing: 2px;
color: #333;
border: 1px solid #333;
border-radius: 5px;
margin-right: 14px;
font-size: 12px;
margin-bottom: 10px;
background-color: #fff;
}
.act{
color: red;
}
}
}