【wavesurfer.js实战范例】多区域音频标注(含区域实时切换显示)

简介: 【wavesurfer.js实战范例】多区域音频标注(含区域实时切换显示)

通过多选框,实现多区域显示的实时切换,实现原理:

  1. 每次切换时先清除所有区域
  2. 对选中区域进行重绘
<template>
  <div style="padding: 30px">
    <el-row type="flex" justify="center">
      <el-checkbox-group v-model="showList" @change="showListChange">
        <el-checkbox
          v-for="(regionInfo, regionKey) in regionDic"
          :label="regionKey"
          :key="'region' + regionKey"
        >
          <div class="colorTag" :style="{ background: regionInfo.color }"></div>
          {{ regionInfo.label }}</el-checkbox
        >
      </el-checkbox-group>
    </el-row>
    <div class="waveBox" ref="wave_Ref"></div>
  </div>
</template>

<script>
import WaveSurfer from "wavesurfer.js";
// 导入插件--区域
import RegionsPlugin from "wavesurfer.js/dist/plugin/wavesurfer.regions.min.js";
// 导入插件--指针轴
import CursorPlugin from "wavesurfer.js/dist/plugin/wavesurfer.cursor.js";

export default {
  data() {
    return {
      showList: ["1", "2", "3", "4", "5"],
      wavesurfer: null,
      regionDic: {
        1: {
          label: "前奏",
          color: "rgba(255, 255, 0, 0.5)",
          dataMark: "preludeList",
        },
        2: {
          label: "男声",
          color: "rgba(0, 0, 255, 0.5)",
          dataMark: "boyVoiceList",
        },
        3: {
          label: "女声",
          color: "rgba(255, 0, 0, 0.5)",
          dataMark: "girlVoiceList",
        },
        4: {
          label: "男/女合唱",
          color: "rgba(0, 255, 255, 0.5)",
          dataMark: "chorusList",
        },
        5: {
          label: "间奏",
          color: "rgba(255, 0, 255, 0.5)",
          dataMark: "interludeList",
        },
      },

      boyVoiceList: [
        {
          start: 14,
          end: 26,
        },
        {
          start: 59,
          end: 64,
        },
        {
          start: 109,
          end: 134,
        },
        {
          start: 148,
          end: 160,
        },
      ],

      girlVoiceList: [
        {
          start: 27,
          end: 39,
        },
        {
          start: 52,
          end: 58,
        },
      ],

      preludeList: [
        {
          start: 0,
          end: 14,
        },
      ],

      // 男女合唱
      chorusList: [
        {
          start: 40,
          end: 52,
        },
        {
          start: 65,
          end: 71,
        },
        {
          start: 97,
          end: 109,
        },
        {
          start: 135,
          end: 147,
        },
        {
          start: 161,
          end: 173,
        },
      ],
      // 间奏
      interludeList: [
        {
          start: 72,
          end: 96,
        },
      ],
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.wavesurfer = WaveSurfer.create({
        container: this.$refs.wave_Ref,
        plugins: [
          // 插件--区域的配置
          RegionsPlugin.create({}),

          // 插件--指针轴的配置
          CursorPlugin.create({
            showTime: true,
            opacity: 1,
            customShowTimeStyle: {
              "background-color": "#000",
              color: "#fff",
              padding: "2px",
              "font-size": "10px",
            },
          }),
        ],
      });
      this.wavesurfer.load(require("./《祝福你》群星_粤语.mp3"));
      // 自动播放
      let that = this;
      this.wavesurfer.on("ready", function () {
        that.wavesurfer.play();
      });
      this.drawRegion();
    });
  },
  methods: {
    showListChange() {
      this.wavesurfer.clearRegions();
      this.drawRegion();
    },
    wavesurferAddRegion(start, end, color) {
      this.wavesurfer.addRegion({
        start: start, // 区域开始时间
        end: end, // 区域结束时间
        color: color, // 区域颜色
        drag: false, // 是否可拖拽
        resize: false, // 是否可改变大小
      });
    },
    drawRegion() {
      this.showList.forEach((regionType) => {
        let regionInfo = this.regionDic[regionType];
        this[regionInfo.dataMark].forEach((item) => {
          this.wavesurferAddRegion(item.start, item.end, regionInfo.color);
        });
      });
    },
  },
};
</script>
<style scoped>
.colorTag {
  display: inline-block;
  height: 10px;
  width: 30px;
}
.waveBox {
  border: 1px solid gray;
  margin-top: 15px;
}
</style>
目录
相关文章
|
3月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
3天前
|
前端开发 API 开发者
Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
这篇文章介绍了Framer Motion,一个为React设计的动画库,提供了声明式API处理动画和页面转换,适合创建响应式用户界面。文章包括首屏加载动画、路由加载Loading、路由进场和退场动画等主题,并提供了使用Framer Motion和next.js实现这些动画的示例代码。最后,文章总结了这些效果,并邀请读者探讨更好的实现方案。
|
28天前
Next.js 实战 (二):搭建 Layouts 基础排版布局
本文介绍了作者在Next.js v15.x版本发布后,对一个旧项目的重构过程。文章详细说明了项目开发规范配置、UI组件库选择(最终选择了Ant-Design)、以及使用Ant Design的Layout组件实现中后台布局的方法。文末展示了布局的初步效果,并提供了GitHub仓库链接供读者参考学习。
Next.js 实战 (二):搭建 Layouts 基础排版布局
|
23天前
|
存储 网络架构
Next.js 实战 (四):i18n 国际化的最优方案实践
这篇文章介绍了Next.js国际化方案,作者对比了网上常见的方案并提出了自己的需求:不破坏应用程序的目录结构和路由。文章推荐使用next-intl库来实现国际化,并提供了详细的安装步骤和代码示例。作者实现了国际化切换时不改变路由,并把当前语言的key存储到浏览器cookie中,使得刷新浏览器后语言不会失效。最后,文章总结了这种国际化方案的优势,并提供Github仓库链接供读者参考。
|
24天前
Next.js 实战 (三):优雅的实现暗黑主题模式
这篇文章介绍了在Next.js中实现暗黑模式的具体步骤。首先,需要安装next-themes库。然后,在/components/ThemeProvider/index.tsx文件中新增ThemeProvider组件,并在/app/layout.tsx文件中注入该组件。如果想要加入过渡动画,可以修改代码实现主题切换时的动画效果。最后,需要在需要的位置引入ThemeModeButton组件,实现暗黑模式的切换。
|
2月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
37 2
|
3月前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
40 1
|
3月前
|
SQL 前端开发 JavaScript
Nest.js 实战 (十五):前后端分离项目部署的最佳实践
这篇文章介绍了如何使用现代前端框架Vue3和后端Node.js框架Nest.js实现的前后端分离架构的应用,并将其部署到生产环境。文章涵盖了准备阶段,包括云服务器的设置、1Panel面板的安装、数据库的安装、域名的实名认证和备案、SSL证书的申请。在部署Node服务环节,包括了Node.js环境的创建、数据库的配置、用户名和密码的设置、网站信息的填写、静态网站的部署、反向代理的配置以及可能遇到的常见问题。最后,作者总结了部署经验,并希望对读者有所帮助。
233 11
|
3月前
|
存储 JavaScript 前端开发
前端开发:Vue.js入门与实战
【10月更文挑战第9天】前端开发:Vue.js入门与实战
|
2月前
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
50 0