vue2 wavesurfer.js(7.8.5)简单使用

文档地址:https://wavesurfer.xyz/docs/

javascript 复制代码
<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>
相关推荐
这人是玩数学的几秒前
在 Cursor 中规范化生成 UI 稿实践
前端·ai编程·cursor
UncleKyrie2 分钟前
🎨 市面上主流 Figma to Code MCP 对比
前端
李明卫杭州3 分钟前
CSS `clamp()` 函数详解
javascript
奶丝兔蜜柚9 分钟前
栈溢出优化
javascript
南半球与北海道#14 分钟前
前端引入vue-super-flow流程图插件
前端·vue.js·流程图
然我21 分钟前
React 16.8:不止 Hooks 那么简单,这才是真正的划时代更新 🚀
前端·react.js·前端框架
小高00734 分钟前
📈前端图片压缩实战:体积直降 80%,LCP 提升 2 倍
前端·javascript·面试
OEC小胖胖38 分钟前
【React Hooks】封装的艺术:如何编写高质量的 React 自-定义 Hooks
前端·react.js·前端框架·web
BillKu1 小时前
vue3+element-plus 输入框el-input设置背景颜色和字体颜色,样式效果等同于不可编辑的效果
前端·javascript·vue.js
每天学习一丢丢1 小时前
Spring Boot + Vue 项目用宝塔面板部署指南
vue.js·spring boot·后端