1、引入组件
import Wavesurfer from '@/components/Wavesurfer'
export default {
name: 'App',
components: { Wavesurfer },
data: () => ({
fileUrl: ''
}),
methods: {
playVoice(fileUrl) {
this.fileUrl= fileUrl
this.$refs.playAudio.playAu()
}
}
}
2、 使用
<div class="wave">
<Wavesurfer btnShow :height="22" :filePath="fileUrl" ref="playAudio" />
</div>
<el-button @click="playVoice(fileUrl)" type="primary" plain>调听</el-button>
3、组件
<template>
<div class="waveSurfer">
<div ref="wavesurfer" id="waveform">
<progress id="progress" class="progress progress-striped" value="0" max="100"></progress>
</div>
<div id="wave-timeline" ref="wave-timeline">
<!--时间轴 -->
</div>
<div class="palyButton" v-if="wavesurfer">
<el-button type="primary" @click="playAudio">
<i class="el-icon-video-play"></i>
播放 /
<i class="el-icon-video-pausee"></i>
暂停
</el-button>
</div>
</div>
</template>
<script>
import WaveSurfer from 'wavesurfer.js'
import CursorPlugin from 'wavesurfer.js/dist/plugin/wavesurfer.cursor.js'
import Timeline from 'wavesurfer.js/dist/plugin/wavesurfer.timeline.js'
import Regions from 'wavesurfer.js/dist/plugin/wavesurfer.regions.js'
export default {
props: {
filePath: String,
height: { type: Number, default: 100 },
},
data() {
return {
wavesurfer: null,
playing: false,
readyState: false
}
},
mounted() {
// this.renderAudio()
},
beforeDestroy() {
this.destroy()
},
watch: {
filePath() {
this.destroy()
this.renderAudio()
}
},
computed: {
playState() {
return this.playing ? 'el-icon-video-pause' : 'el-icon-video-play'
}
},
methods: {
renderAudio() {
this.wavesurfer = WaveSurfer.create({
container: this.$refs.wavesurfer,
height: this.height,
audioRate: 1,
cursorWidth: 1,
barHeight: 5,
mediaControls: false,
waveColor: '#43d996', // 声波color
progressColor: '#43d996', // 已播放声波color
backgroundColor: '#f0f5f9',
cursorColor: '#006de6',
backend: 'MediaElement',
plugins: [
CursorPlugin.create({
showTime: true,
opacity: 1,
customShowTimeStyle: {
'background-color': '#000',
color: '#fff',
'font-size': '10px'
}
}),
// 注册的一组插件定义 时间
Timeline.create({
container: '#wave-timeline',
fontSize: 14,
primaryFontColor: '#9191a5',
secondaryFontColor: '#9191a5',
primaryColor: '#9191a5',
secondaryColor: '#9191a5'
}),
Regions.create({})
]
})
this.wavesurfer.addRegion({
loop: false,
drag: false,
resize: false,
color: 'rgba(254, 255, 255, 0.4)'
})
// 加载进度条
this.wavesurfer.on('loading', function (percents) {
document.getElementById('progress').value = percents
})
this.wavesurfer.on('ready', () => {
this.wavesurfer.enableDragSelection({
color: 'rgba(0, 180, 0, 0.3)'
})
this.wavesurfer.clearRegions() // 音频加载完成
document.getElementById('progress').style.display = 'none'
document.getElementById('progress').value = 0
this.readyState = true
this.setPlayState()
})
this.wavesurfer.on('finish', () => {
this.stopAudio()
this.setPlayState()
})
this.wavesurfer.on('error', () => {
this.readyState = false
})
document.getElementById('waveform').onclick = function () {
this.wavesurfer.clearRegions()
}
// 更新区域时。回调将接收该Region对象。
this.wavesurfer.on('region-updated', function (region) {
region.playLoop() // 循环播放选中区域
})
this.wavesurfer.on('region-created', () => {
this.wavesurfer.clearRegions()
})
},
getWavLoad(filePath) {
filePath && this.wavesurfer.load(filePath)
},
stopAudio() {
this.readyState && this.wavesurfer.stop()
this.setPlayState()
},
playAu() {
this.$nextTick(() => {
this.getWavLoad(this.filePath)
this.wavesurfer.playPause()
this.setPlayState()
})
},
// 播放/暂停 button
playAudio() {
this.$nextTick(() => {
if (!this.isPlaying && !this.readyState) {
this.getWavLoad(this.filePath)
}
this.wavesurfer.playPause()
this.setPlayState()
})
},
setPlayState() {
this.playing = this.wavesurfer.isPlaying()
},
destroy() {
this.wavesurfer && this.stopAudio()
this.wavesurfer && this.wavesurfer.destroy()
this.wavesurfer = null
},
pause() {
this.wavesurfer && this.playing && this.wavesurfer.pause()
}
}
}
</script>
<style lang="scss">
#waveform {
position: relative;
}
#wave-timeline {
height: 6px;
}
#waveform {
width: 100%;
flex-basis: 128px;
flex-shrink: 0;
position: relative;
}
#progress {
position: absolute;
width: 100%;
height: 4px;
top: 48%;
opacity: 0.7;
z-index: 44;
}
.waveSurfer {
width: 100%;
padding-top: 20px;
}
.waveSurfer >>> .el-slider__runway {
margin: 6px 0;
}
.palyButton {
margin-top: 28px;
}
</style>