<template>
<div class="audio">
<audio :src="audioSrc" ref="audioRecord" ></audio>
<!-- controls -->
<div class="audio_controls" >
<button :class="play ? 'play':'pause'" @click="togglePlay"></button>
<Slider v-model="time_progress" class="time_progress" @on-change="sliderTime" :tip-format="formatTimeSlider"></Slider>
<div class="time_range">
{{this.formatTime(currentTime)}} / {{this.formatTime(duration)}}
</div>
<div class="voice_progress">
<button :class="sound ? 'lound':'slient'" @click="toggleSound"></button>
<Slider v-model="voice_progress" @on-change="sliderSound"></Slider>
</div>
</div>
</div>
</template>
<script>
export default {
name: "audioRecord",
props:['audioSrc'],
data(){
return{
play:true,
currentTime:0,
duration:0,
time_progress:0,
sound:true,
voice_progress:50
}
},
methods:{
formatTime(val){
let second = parseInt(val);
let HH = Math.floor(second / 3600),MM = Math.floor(second % 3600 / 60),SS = second % 60;
if(HH<10){HH = `0${HH}`};
if(MM<10){MM = `0${MM}`};
if(SS<10){SS = `0${SS}`};
let min = `${HH}:${MM}:${SS}`;
return min;
},
// 播放
togglePlay(){ // 开始暂停
let method = this.play ? 'play' : 'pause';
this.play = !this.play;
this.$refs.audioRecord[method]();
},
handleProgress(){
const audioRecord = this.$refs.audioRecord,
_currentTime = audioRecord ? audioRecord.currentTime : 0;
if(_currentTime==this.duration){
this.play = true;
}
this.currentTime = _currentTime;
this.time_progress = _currentTime/this.duration * 100;
},
sliderTime(val){ // 切换播放时间点
this.$refs.audioRecord.currentTime = (val/100) * this.duration;
},
formatTimeSlider(val){
return this.formatTime(val*this.duration/100);
},
// 音量
toggleSound(){ // 静音切换
this.sound = !this.sound;
if(this.sound){
this.$refs.audioRecord.volume = this.voice_progress/100;
}else{
this.$refs.audioRecord.volume = 0;
}
},
sliderSound(val){ // 音量调节
this.$refs.audioRecord.volume = val/100;
val==0 ? this.sound=false : this.sound=true;
}
},
mounted(){
const audioRecord = this.$refs.audioRecord;
audioRecord.oncanplay=()=>{ this.duration = audioRecord.duration}; // 监听oncanplay
this.$refs.audioRecord.addEventListener('timeupdate', this.handleProgress); // 监听播放
audioRecord.volume = this.voice_progress/100;
}
}
</script>
<style scope>
button{
border: 0;
outline: 0;
}
.audio{
width: 100%;
height: 48px;
border-radius: 2px;
background-color: #fafafa;
}
.audio_controls{
height: 100%;
display: -webkit-flex; /* Safari */
display: flex;
justify-content: center;
align-items: center;
align-content:center;
}
/* 开始/暂停按钮 */
.play,.pause{
width: 26px;
height: 26px;
background-color: #03a9f4;
background-position: center;
background-repeat: no-repeat;
background-image: url(../../assets/images/mp3/play.png);
border-radius: 50%;
margin-right: 10px;
}
.play{
background-image: url(../../assets/images/mp3/play.png);
}
.pause{
background-image: url(../../assets/images/mp3/pause.png);
}
/* 时间 */
.time_range{
width: 140px;
text-align: center;
}
/* 进度条 */
.time_progress{
width: 300px;
}
.voice_progress .ivu-slider{
width: 120px;
display: inline-block;
vertical-align: middle;
}
/* 音量 */
.voice_progress .ivu-tooltip-rel{
display:none;
}
.lound,.slient{
vertical-align: middle;
width: 26px;
height: 26px;
background-position: center;
background-repeat: no-repeat;
background-color: #fff;
}
.lound{
background-image: url(../../assets/images/mp3/openvoice.png);
}
.slient{
background-image: url(../../assets/images/mp3/closevoice.png);
background-position: left center;
}
</style>
实现逻辑
timeupdate监听播放,控制播放进度条play()、pause()实现播放与暂停duration属性获取音频时长currentTime音频当前播放位置的获取与设置volume音量的获取与设置代码
填坑:
audio.duration的值为NaN监听
canplay事件进度条与currentTime不匹配
获取的
currentTime不需要parseInt,在format事件格式的时候再parseInt参考: