文档地址:https://wavesurfer.xyz/docs/
<template>
<div>
<el-row>
<el-card class="card">
<div id="waveform" ref="waveform"></div>
</el-card>
</el-row>
<div>总时长:{{ totalTime }}</div>
<div>
<el-button type="primary" @click="playMusic">
<i v-if="play" class="el-icon-video-play"></i>
<i v-else class="el-icon-video-pause"></i>
播放 / 暂停
</el-button>
<el-button type="primary" @click="stopMusic">
<i class="el-icon-refresh-left"></i>
停止
</el-button>
<el-button type="primary" @click="retreatMusic">
<i class="el-icon-d-arrow-left"></i>
快退
</el-button>
<el-button type="primary" @click="enterMusic">
快进
<i class="el-icon-d-arrow-right"></i>
</el-button>
<div style="width: 200px;">
音量
<el-slider v-model="volume" @change="changeVolume"></el-slider>
</div>
<el-button type="primary" @click="reSlowDownMusic">
<i class="el-icon-remove-outline"></i>
减速
</el-button>
<span>{{ speed }}</span>
<el-button type="primary" @click="accelerateMusic">
加速
<i class="el-icon-circle-plus-outline"></i>
</el-button>
<div>
从第
<el-input-number v-model="time"></el-input-number>
秒开始播放
<el-button type="primary" @click="timeMusic">
<i class="el-icon-caret-right"></i>
开始
</el-button>
</div>
</div>
</div>
</template>
<script>
import WaveSurfer from "wavesurfer.js";
import Timeline from "wavesurfer.js/dist/plugins/timeline.js";
import Regions from "wavesurfer.js/dist/plugins/regions.js";
export default {
name: "Details",
data() {
return {
wavesurfer: null,
play: true,
volume: 1,
speed: 1,
time: 0,
totalTime: 0,
};
},
mounted() {
this.$nextTick(() => {
const regions = Regions.create();
this.wavesurfer = WaveSurfer.create({
container: "#waveform", // 波形图的容器
barWidth: 1, // 波形条的宽度
cursorColor: "black", // 播放进度光标条的颜色
progressColor: "blue", // 已播放波形的颜色
backend: "MediaElement",
audioRate: "1", // 音频的播放速度
// height: 10, // 波形图的高度 单位px
// scrollParent: true, // 是否显示滚动条
// barHeight: 0.8, // 波形的振幅(高度),默认为1
// barRadius: 2, // 波形条的圆角
// barWidth: 1, // 波形条的宽度
// barGap: 3, // 波形条间的间距
plugins: [
Timeline.create({
timeInterval: 5,
primaryLabelInterval: 10, // 数字标签之间的间隔(秒)
style: { // 自定义内联样式以应用于容器
fontSize: "10px",
color: "#6A3274",
},
}),
regions,
],
});
this.wavesurfer.on("ready", () => {
// 当wavesurfer准备好后,获取总时长
this.totalTime = this.getMinute(this.wavesurfer.getDuration());
this.volume = this.wavesurfer.getVolume() * 100;
});
// 范围
const random = (min, max) => Math.random() * (max - min) + min;
const randomColor = () =>
`rgba(${random(0, 255)}, ${random(0, 255)}, ${random(0, 255)}, 0.5)`;
this.wavesurfer.on("decode", () => {
// regions
regions.addRegion({
start: 10, // 开始位置
end: 60, // 结束位置
content: "范围1", // 内容
color: randomColor(), // 颜色
drag: false, // 是否可拖动
resize: false, // 是否可改变大小
});
regions.addRegion({
start: 80,
end: 120,
content: "范围2",
color: randomColor(),
drag: false,
resize: false,
});
regions.addRegion({
start: 160,
content: "Marker",
color: randomColor(),
});
});
regions.on("region-clicked", (region, e) => {
e.stopPropagation(); // prevent triggering a click on the waveform
region.play();
region.setOptions({ color: randomColor() });
});
// 特别提醒:此处需要使用require(相对路径),否则会报错
this.wavesurfer.load(require("../assets/测试文档/music.mp3"));
});
},
methods: {
getMinute(second) {
const totalMinutes = Math.floor(second / 60);
const remainingSeconds = Math.round((second % 60) * 100) / 100; // 保留两位小数
return `${totalMinutes}:${remainingSeconds}`;
},
// 播放 / 暂停
playMusic() {
this.play = !this.play;
this.wavesurfer.playPause.bind(this.wavesurfer)();
},
// 停止
stopMusic() {
this.wavesurfer.stop();
},
// 快退
retreatMusic() {
// 从当前位置向后快进2秒播放
this.wavesurfer.skip(-2);
},
// 快进
enterMusic() {
// 从当前位置向后快进2秒播放
this.wavesurfer.skip(2);
},
// 音量参数为0-1
changeVolume(val) {
let num = val * 0.01;
this.wavesurfer.setVolume(num);
},
// 减速
reSlowDownMusic() {
if (this.speed > 1) {
this.speed--;
this.wavesurfer.setPlaybackRate(this.speed);
}
},
// 加速
accelerateMusic() {
if (this.speed < 6) {
this.speed++;
this.wavesurfer.setPlaybackRate(this.speed);
}
},
// 跳转到指定时间
timeMusic() {
this.wavesurfer.setTime(this.time);
this.wavesurfer.play();
},
},
};
</script>
<style scoped lang="scss">
.mixin-components-container {
width: 100% !important;
padding: 30px;
/* min-height: calc(100vh - 84px); */
}
.el-card__body {
height: 70px !important;
padding: 0 auto !important;
.card {
height: 70px;
#waveform {
wave {
height: 50px !important;
}
}
}
}
</style>