在Vue中使用音频可视化插件wavesurfer.js__Vue.js
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利
链接自取
一、基本用法
1.下载wavesurfer.js
$ npm install wavesurfer.js --save
# or
$ yarn add wavesurfer.js
2.导入
在模块中导入
<script>
import WaveSurfer from 'wavesurfer.js'
import Timeline from 'wavesurfer.js/dist/plugin/wavesurfer.timeline'//Timeline插件
import Region from 'wavesurfer.js/dist/plugin/wavesurfer.regions'//regions插件
...
export default {}
</script>
3.创建一个容器
<template>
<div>
<!-- 时间线容器 -->
<div id="timeline" ref="timeline" />
<!-- 音频容器 -->
<div id="waveform" ref="waveform" />
</div>
</template>
4.创建一个实例
data(){
return{
wavesurfer: '',
speed: 1
}
},
methods:{
...
this.wavesurfer = WaveSurfer.create({
container: this.$refs.waveform,//绑定容器,第一种方法
// container: document.querySelector('#waveform'),//第二种方法
// container: '#waveform',//第三种方法
audioRate: this.speed,//控制播放速度
forceDecode: true,
waveColor: '#A8DBA8',
progressColor: '#3B8686',
backend: 'MediaElement'
})
this.wavesurfer.load('https://mindflowai-open.oss-cn-hangzhou.aliyuncs.com/505/6mariyokwzjuqjql.wav')//加载音频
...
}
二、Timeline插件
1.导入插件
...
import Timeline from 'wavesurfer.js/dist/plugin/wavesurfer.timeline'
...
2.简单时间线实例
...
this.wavesurfer = WaveSurfer.create({
container: this.$refs.waveform,
...
plugins: [
Timeline.create({
container: '#timeline',//绑定容器
labelPadding: 2
})
]
})
...
3. 自定义复杂时间线
...
Timeline.create({
container: '#timeline',
secondaryColor: '#FF0000',//次要时间标签颜色,红色
secondaryFontColor: '#FF0000',
secondaryLabelInterval: this._secondaryLabelInterval,
primaryColor: '#3498DB',//主要时间标签颜色,蓝色
primaryFontColor: '#D3498DB',
primaryLabelInterval: this._primaryLabelInterval,
formatTimeCallback: this._formatTimeCallback,
timeInterval: this._timeInterval,
labelPadding: 2
})
...
4.重写formatTimeCallback
方法
重写时间线的时间格式:
_formatTimeCallback(seconds, pxPerSec) {
seconds = Number(seconds)
var minutes = Math.floor(seconds / 60)
seconds = seconds % 60
var secondsStr = Math.round(seconds).toString()
if (pxPerSec >= 25 * 10) {
secondsStr = seconds.toFixed(2)
} else if (pxPerSec >= 25 * 1) {
secondsStr = seconds.toFixed(1)
}
if (minutes > 0) {
if (seconds < 10) {
secondsStr = '0' + secondsStr
}
return `${minutes}:${secondsStr}`
}
return secondsStr
}
5.重写timeInterval
方法
重写时间间隔数,以分钟为单位的持续时间:
/**
* @param pxPerSec
* @return 以分钟为单位的值
*/
_timeInterval(pxPerSec) {
var retval = 1
if (pxPerSec >= 100) { // 0.5,1,1.5,2,...,9.5,10
retval = 0.5
} else if (pxPerSec >= 80) { // 1,2,...,9,10
retval = 1
} else if (pxPerSec >= 60) { // 2,4,6,8,10
retval = 2
} else if (pxPerSec >= 40) { // 5,10
retval = 1
} else if (pxPerSec >= 20) {
retval = 5
} else {
retval = Math.ceil(0.5 / pxPerSec) * 60
}
return retval
},
6.重写primaryLabelInterval
方法
重写主要时间标签的数量:
_primaryLabelInterval(pxPerSec) {
var retval = 1
if (pxPerSec >= 100) {
retval = 2
} else if (pxPerSec >= 80) {
retval = 1
} else if (pxPerSec >= 60) {
retval = 1
} else if (pxPerSec >= 40) {
retval = 5
} else if (pxPerSec >= 20) {
retval = 2
} else {
retval = 1
}
return retval
},
7.重写secondaryLabelInterval
方法
重写次要时间标签的数量:
_secondaryLabelInterval(pxPerSec) {
if (pxPerSec >= 20 && pxPerSec < 40) {
return 12
} else if (pxPerSec >= 0 && pxPerSec < 20) {
return 10
} else {
return Math.floor(10 / this._timeInterval(pxPerSec))
}
},
8. timeInterval
与primaryLabelInterval
和secondaryLabelInterval
关系
以传入的pxPerSec
大于等于100为例,_timeInterval(100)
返回0.5
,_primaryLabelInterval(100)
返回2
。此时,主要标签的时间间隔是1秒
(0.5*2),由2个0.5组成。_secondaryLabelInterval(100)
返回10个1秒
。
三、方法
1.播放
//play()
this.wavesurfer.play()
2.暂停
//pause()
this.wavesurfer.pause()
3.回到开始并停止
//stop()
this.wavesurfer.stop()
4.重播
//play([start[,end]]),可选参数
this.wavesurfer.play(0)
5.缩放
//zoom(pxPerSec)
this.wavesurfer.zoom(Number(this.valueZoom))
6.播放速度
//setPlaybackRate(rate)
this.wavesurfer.setPlaybackRate(this.speed)
7.调节声音
//setVolume(newVolume)-将播放音量设置为新值[0..1](0 =静音,1 =最大)
this.wavesurfer.setVolume(Number(this.valueRound * 0.01))
8.格式化时间
changeTime(seconds) {
seconds = Number(seconds)
var minutes = Math.floor(seconds / 60)
seconds = seconds % 60
var secondsStr = Math.round(seconds).toString()
secondsStr = seconds.toFixed(2)
if (minutes > 0) {
return `${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + secondsStr : secondsStr}`
}
return `00:${seconds < 10 ? '0' + secondsStr : secondsStr}`
},
四、事件
1.区域插件的region-click
事件
点击区域,打印该区域开始和结束的时间:
this.wavesurfer.on('region-click', (e)=> {
const { start, end } = e
console.log(this.changeTime(start), this.changeTime(end))
})
2.获取当前播放时间
监听audioprocess
事件,返回当前时间:
this.wavesurfer.on('audioprocess', function(e) {
this.currentTime =this.changeTime(this.wavesurfer.getCurrentTime())
})
五、Regions插件
1.导入
import Region from 'wavesurfer.js/dist/plugin/wavesurfer.regions'
2.初始化
...
this.wavesurfer = WaveSurfer.create({
container: this.$refs.waveform,
...
plugins: [
Timeline.create({...}),
Region.create({
regions: [
{
start: 1, //开始时间
end: 3, //结束时间
loop: false, //是否循环播放
color: 'hsla(400, 100%, 30%, 0.5)'//区域颜色
}, {
start: 5,
end: 7,
loop: false,
color: 'hsla(200, 50%, 70%, 0.4)'
}
],
dragSelection: {
slop: 5
}
}),
]
})
...
3.需求
- 新增区域后播放自动播放当前区域音频,并同时新增一条表格信息(包含开始时间、结束时间等);
- 点击区域自动播放当前区域音频,并高亮对应的表格信息;
- 删除表格信息的同时,删除在音频中对应的区域;
4.运用
1.获取区域列表
getRegionList(listArr) {
const _this = this
_this.tableData = []// 清除
if (listArr.length !== 0) {
for (let i = listArr.length - 1; i >= 0; i--) { // 最新的在最前面
_this.tableData.push({ id: listArr[i].id, startTime: _this.changeTime(listArr[i].start), endTime: _this.changeTime(listArr[i].end) })
}
_this.total = listArr.length
}
}
2.点击区域,播放当前音频
this.wavesurfer.on('region-click', (region, mouseEvent)=> {
this.currentRegion = region
region.play() // 播放当前区域,另一种播放方式: this.wavesurfer.play(start, end)
})
3.点击区域,对应的列表项高亮
给el-table
标签添加row-class-name
属性:
<el-table
:data="tableData"
:row-class-name="tableRowClassName"
>
...
tableRowClassName
方法如下:
tableRowClassName({ row, rowIndex }) {
if (this.currentRegion.id === row.id) {//通过区域id来判断
return 'success-row'
}
return ''
}
给表格添加样式:
.el-table .success-row {
background: #d9e2f8;
}
4.初次获取区域列表,并生成对应的表格
//wavesurfer.regions.list:获取音频中的区域列表
this.regionList = Object.values(this.wavesurfer.regions.list)
//将处理后的数据传入表格
this.getRegionList(this.regionList)
5.新增区域,播放当前音频,新增表格项
this.wavesurfer.on('region-update-end', (region) => {
/** 播放区域的两种方式 */
// this.wavesurfer.play(this.currentRegion.start, this.currentRegion.end)//①
region.play()// ②
/** 新增区域列表 */
this.regionList = Object.values(this.wavesurfer.regions.list)
this.getRegionList(this.regionList)
})
6.删除表格项,删除区域
deleteRegion(row) {
const arr = this.regionList
if (arr) {
arr.forEach((region, index) => {
if (row.id === region.id) {
region.remove()
arr.splice(index, 1)
this.getRegionList(arr)
}
})
}
},
六、Cursor插件
1.导入
import Cursor from 'wavesurfer.js/dist/plugin/wavesurfer.cursor'
2.初始化
...
this.wavesurfer = WaveSurfer.create({
container: this.$refs.waveform,
...
plugins: [
Timeline.create({...}),
Region.create({...}),
Cursor.create({
showTime: true,
opacity: 1,
customShowTimeStyle: {
'background-color': '#000',
color: '#fff',
padding: '2px',
'font-size': '10px'
}
})
]
})
...
3.完善样式
到目前为止的光标是全屏显示的,理想的样子是光标只在音频区域显示,需要添加样式如下:
#waveform{
position: relative;
}
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: Zz燕 原文链接:https://juejin.im/post/6862201364308492302