1.查看效果图
向前选中:
向后选中:
代码如下(示例):
<template>
<div class= "waveSurfer" >
<div class= "top" >
<span @click= "leftSelect" >向前选中</span>
<span @click= "rightSelect" >向后选中</span>
<span @click= "Region" >标注</span>
</div>
<!-- 时间轴 -->
<div id= "wave-timeline" />
<!-- 频谱图 -->
<div id= "waveform" >
<progress
id= "progress"
class= "progress progress-striped"
value= "0"
max= "100"
></progress>
</div>
<div v-show= "ppt" id= "wave-spectrogram" class= "mt-20" />
<!-- 控制按钮 -->
<div class= "title" >
<ul>
<li>
<span @click= "zoomIn" ></span>
</li>
<li>
<span @click= "rew" ></span>
</li>
<li>
<span :class= "{ on: isPlay }" @click= "plays" ></span>
</li>
<li>
<span @click= "speek" ></span>
</li>
<li>
<span @click= "zoomOut" ></span>
</li>
<li>
<span @click= "replay" ></span>
</li>
<li @click= "toggleMute" :class= "{ on: toggleMutebutton }" class= "sound" >
<span></span>
</li>
<li>
<input
@mouseup= "volumeBarHandle"
v-model= "volValue"
type= "range"
min= "0"
max= "1"
value= "0.8"
step= "0.01"
/>
</li>
<li @click= "DoubleSpeed(index)" >
{{ speed[index] + " X" }}
</li>
</ul>
</div>
</div>
</template>
<script>
import WaveSurfer from "wavesurfer.js" ;
import Timeline from "wavesurfer.js/dist/plugin/wavesurfer.timeline.js" ;
import Regions from "wavesurfer.js/dist/plugin/wavesurfer.regions.js" ;
export default {
data: function () {
return {
index: 0,
speed: [1.0, 1.5, 2.0, 0.5],
isPlay: false ,
ppt: false ,
ds: 1.0,
zoomValue: 100,
zoomMin: 100,
fast: 3,
back: 3,
noteData: [],
toggleMutebutton: true ,
volValue: 0,
audioUrl: "" ,
loading: true ,
};
},
// computed: {
// // 计算属性的 getter
// getUrl: function() {
// // `this` 指向 vm 实例
// return this.$store.state.voicetrain.url
// }
// },
// watch: {
// getUrl(newUrl) {
// this.loading = true
// this.audioUrl = newUrl
// document.getElementById('waveform').innerHTML = ''
// this.init()
// }
// },
mounted() {
this .audioUrl =
"http://192.168.1.101:8080/api/files/20201104/62afa213458d44b0a99440b33fb694b9" ;
this .init();
},
methods: {
// 初始化
init() {
document.getElementById( "progress" ).style.display = "block" ;
this .$nextTick(() => {
this .wavesurfer = WaveSurfer.create({
container: "#waveform" ,
cursorColor: "#DB7093" , // 声波播放进度线color
audioRate: 1,
scrollParent: true ,
backend: "WebAudio" ,
barHeight: 1.5,
waveColor: "#43d996" , // 声波color
progressColor: "#43d996" , // 已播放声波color
loaderColor: "#8B0000" ,
hideScrollbar: false ,
autoCenter: true ,
height: 120,
splitChannels: true ,
responsive: true ,
minPxPerSec: 1,
plugins: [
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.load( this .audioUrl);
this .value = this .wavesurfer.getVolume() * 100; // 获取音量
this .zoomValue = this .wavesurfer.params.minPxPerSec;
this .zoomMin = this .wavesurfer.params.minPxPerSec;
this .wavesurfer.zoom(Number( this .zoomValue));
this .wavesurfer.panner = this .wavesurfer.backend.ac.createPanner();
this .wavesurfer.backend.setFilter( this .wavesurfer.panner);
let _this = this ;
_this.wavesurfer.on( "ready" , function () {
_this.wavesurfer.enableDragSelection({
color: "rgba(0, 180, 0, 0.3)" ,
});
_this.wavesurfer.clearRegions();
_this.wavesurfer.zoom(_this.zoomValue);
// 音频加载完成
document.getElementById( "progress" ).style.display = "none" ;
document.getElementById( "progress" ).value = 0;
_this.isPlay = true ;
_this.wavesurfer.play(0);
});
document.getElementById( "waveform" ).onclick = function () {
_this.isPlay = false ;
_this.wavesurfer.clearRegions();
};
// 更新区域时。回调将接收该Region对象。
// this.wavesurfer.on("region-updated", function (region) {
// region.playLoop(); // 循环播放选中区域
// _this.isPlay = true;
// });
_this.wavesurfer.on( "region-created" , _this.addRegion);
_this.wavesurfer.on( "region-click" , _this.editAnnotation);
_this.wavesurfer.on( "finish" , function () {
_this.wavesurfer.play(0);
});
});
},
addRegion(params) {
this .wavesurfer.clearRegions();
params.handleLeftEl.style.backgroundColor = "transparent" ;
params.handleRightEl.style.backgroundColor = "transparent" ;
},
toggleMute() {
if ( this .toggleMutebutton) {
this .volumeCached = this .wavesurfer.getVolume();
this .wavesurfer.setVolume(0);
this .toggleMutebutton = false ;
this .volValue = 0;
} else {
if ( this .volumeCached == 0) this .volumeCached = 1;
this .wavesurfer.setVolume( this .volumeCached);
this .toggleMutebutton = true ;
this .volValue = this .volumeCached;
}
},
volumeBarHandle(e) {
if (e.offsetX >= 0 && e.offsetX <= 80) {
this .toggleMutebutton = true ;
this .wavesurfer.setVolume(e.offsetX / 80);
} else if (e.offsetX < 0) {
this .toggleMutebutton = false ;
this .wavesurfer.setVolume(0);
} else {
this .wavesurfer.setVolume(1);
this .toggleMutebutton = true ;
}
},
// 标注
Region() {
console.log(
Object.getOwnPropertyNames( this .wavesurfer.regions.list).length
);
if (
Object.getOwnPropertyNames( this .wavesurfer.regions.list).length == 0
) {
alert( "请选择波纹" );
return ;
}
let start = 0,
end = 0;
for ( var k in this .wavesurfer.regions.list) {
let obj = this .wavesurfer.regions.list[k];
start = obj.start.toFixed(2) * 1000;
end = obj.end.toFixed(2) * 1000;
}
console.log( this .wavesurfer);
console.log( "开始" , start);
console.log( "结束" , end);
},
// 播放
plays() {
this .isPlay = ! this .isPlay;
this .wavesurfer.playPause(); //切换播放,应用播放或暂停
},
// 回退
rew() {
this .wavesurfer.skip(- this .back);
this .goPlay();
},
// 快进
speek() {
this .wavesurfer.skip( this .fast);
this .goPlay();
},
// 重载
replay() {
this .isPlay = true ;
this .wavesurfer.stop();
this .wavesurfer.clearRegions();
this .wavesurfer.play(0);
},
// 倍速
DoubleSpeed(index) {
if (index === 3) {
this .index = 0;
this .wavesurfer.setPlaybackRate( this .speed[ this .index]);
} else {
this .index = index + 1;
this .wavesurfer.setPlaybackRate( this .speed[ this .index]);
}
console.log( this .wavesurfer);
},
// 缩放百分比显示格式
formatZoom(val) {
return val + 100 + " 像素 / 秒" ;
},
// 点击缩小
zoomIn() {
if ( this .zoomValue >= 100) {
return ;
}
this .zoomValue += 1;
this .wavesurfer.zoom( this .zoomValue);
},
// 点击扩大
zoomOut() {
if ( this .zoomValue < -100) {
return ;
}
this .zoomValue -= 1;
this .wavesurfer.zoom( this .zoomValue);
},
// 缩放监听
zoomChange() {
this .wavesurfer.zoom(Number( this .zoomValue));
},
goPlay() {
let start = this .wavesurfer.getCurrentTime();
this .wavesurfer.play(start);
},
// 向前选中
leftSelect() {
let end = this .wavesurfer.getCurrentTime(); // 获取当前播放位置
this .waveRegion( this .wavesurfer, 0, end, "rgba(0,180,0,.3)" , true );
},
// 向后选中
rightSelect() {
let start = this .wavesurfer.getCurrentTime(); // 获取当前播放位置
let end = this .wavesurfer.getDuration(); // 获取音频片段的持续时间
this .waveRegion( this .wavesurfer, start, end, "rgba(0,180,0,.3)" , true );
},
waveRegion(wavesurfer, start, end, color, clear) {
if (!clear) {
wavesurfer.clearRegions();
}
wavesurfer.addRegion({
start: start,
end: end,
color: color,
drag: false ,
});
},
// 区域点击事件新建
saveRegions() {
console.log( "声纹点击---" );
this .noteData = [];
const _this = this ;
this .noteData = Object.keys(_this.wavesurfer.regions.list).map( function (
id
) {
const region = _this.wavesurfer.regions.list[id];
return {
id: id,
edit: false ,
start: Math.round(region.start * 10) / 10,
end: Math.round(region.end * 10) / 10,
attributes: region.attributes,
data: { note: region.data.note || "" },
};
});
},
// 区域点击
editAnnotation() {
this .isPlay = false ;
},
showNote(region) {
if (! this .showNote.el) {
this .showNote.el = document.querySelector( "#subtitle" );
}
this .showNote.el.textContent = region.data.note || "–" ;
},
// 设置音量
setVolume(val) {
console.log(val);
this .wavesurfer.setVolume(val / 100);
},
// 实例点击
clearReagion() {
this .wavesurfer.clearRegions();
},
},
};
</script>
<style lang= "scss" scoped>
#waveform {
position: relative;
}
.top {
width: 100%;
flex-basis: 70px;
line-height: 40px;
flex-shrink: 0;
color: white;
text-indent: 15px;
span,
el-slider {
color: rgb(39, 39, 39);
font-size: 13px;
font-weight: 700;
margin-right: 20px;
padding: 4px 10px;
border: 1px solid #ccc;
border-radius: 10px;
}
}
.title {
width: 100%;
flex-basis: 70px;
line-height: 40px;
text-align: left;
flex-shrink: 0;
color: white;
text-indent: 15px;
ul {
list-style-type: none;
padding-inline-start: 0;
.speed {
display: flex;
flex-direction: column;
}
li {
position: relative;
display: inline-block;
cursor: default ;
&:hover {
}
&:active {
}
span {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
}
&:nth-child(1) span {
width: 27px;
height: 27px;
background: url( "img/缩小.png" ) right;
background-size: cover;
}
&:nth-child(2) span {
background: url( "img/kuaitui_bg.png" ) right;
background-size: cover;
}
&:nth-child(3) {
span {
background: url( "img/bofang_bg.png" ) right;
background-size: cover;
}
.on {
background: url( "img/zanting_bg.png" ) right;
background-size: cover;
}
}
&:nth-child(4) span {
background: url( "img/kuaijin_bg.png" ) right;
background-size: cover;
}
&:nth-child(5) span {
background: url( "img/缩放.png" ) right;
background-size: cover;
}
&:nth-child(6) span {
background: url( "img/zhongbo.png" ) right;
background-size: cover;
}
&:nth-child(9) {
color: rgb(39, 39, 39);
font-size: 13px;
font-weight: 700;
}
&:nth-child(7) {
background: none;
span {
width: 25px;
height: 25px;
background: url( "img/静音.png" ) no-repeat;
background-size: cover;
}
&.on {
span {
width: 25px;
height: 25px;
background: url( "img/喇叭.png" ) no-repeat;
background-size: cover;
}
}
}
&:nth-child(8) {
width: 80px;
background: none;
input {
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
width: 80px;
height: 3px;
background-color: #bbbbbb;
position: absolute;
left: 0;
top: -14px;
&::-webkit-slider-thumb {
-webkit-appearance: none;
}
&::-moz-range-trackpseduo {
-moz-appearance: none;
}
&::-ms-track {
width: 100%;
cursor: pointer;
background: transparent; /* Hides the slider so custom styles can be added */
border-color: transparent;
color: transparent;
}
&:focus {
outline: none;
}
&::-webkit-slider-thumb {
-webkit-appearance: none;
height: 9px;
width: 9px;
margin-top: -1px;
background: #bbb;
border-radius: 50%;
border: solid 0.125em rgba(205, 224, 230, 0.5);
}
&::-moz-range-thumb {
-moz-appearance: none;
height: 6px;
width: 6px;
margin-top: -1px;
background: #bbb;
border-radius: 50%;
border: solid 0.125em rgba(205, 224, 230, 0.5);
}
&::-ms-track {
-moz-appearance: none;
height: 6px;
width: 6px;
margin-top: -1px;
background: #bbb;
border-radius: 50%;
border: solid 0.125em rgba(205, 224, 230, 0.5);
}
}
}
}
}
}
#wave-timeline {
height: 21px;
}
#waveform {
width: 100%;
flex-basis: 128px;
flex-shrink: 0;
position: relative;
}
#progress {
position: absolute;
width: 100%;
height: 4px;
background: #ccc;
top: 48%;
opacity: 0.7;
z-index: 44;
}
.mt-20 {
margin-top: 20px;
}
.mt-30 {
margin-top: 30px;
}
.waveSurfer {
width: 470px;
}
.waveSurfer >>> .el-slider__runway {
margin: 6px 0;
}
</style>
链接:https://wavesurfer-js.org
到此这篇关于wavesurfer.js绘制音频波形图的实现的文章就介绍到这了,更多相关wavesurfer.js 音频波形图内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/m0_37714008/article/details/109776548
查看更多关于wavesurfer.js绘制音频波形图的实现的详细内容...