广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >wavesurfer.js绘制音频波形图的实现
  • 417
分享到

wavesurfer.js绘制音频波形图的实现

2024-04-02 19:04:59 417人浏览 泡泡鱼
摘要

1.查看效果图 向前选中: 向后选中: 代码如下(示例): <template> <div class="waveSurfer"> <d

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; 
      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 音频波形图内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: wavesurfer.js绘制音频波形图的实现

本文链接: https://www.lsjlt.com/news/123000.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • wavesurfer.js绘制音频波形图的实现
    1.查看效果图 向前选中: 向后选中: 代码如下(示例): <template> <div class="waveSurfer"> <d...
    99+
    2022-11-12
  • Qt利用QChart实现实时波形图的绘制
    目录前言1.QChart配置以及使用1.1QChart环境配置1.2控件使用1.3代码配置2.QChat设置动态折线图2.1基础数据设置2.2定时器控制数据变动3.实际硬件数据采集图...
    99+
    2022-11-13
  • Qt中PaintEvent绘制实时波形图的实现示例
    目录绘制思路1:接收硬件传入的数据2:定时器动态刷新页面3:真实数据处理第一步:每进行一次数据更新,都需要剔除超时显示数据。第二步:筛查有效数据,并记录4:图形绘制上一篇文章讲述了如...
    99+
    2022-11-13
  • Qt中怎么使用PaintEvent绘制实时波形图
    本文小编为大家详细介绍“Qt中怎么使用PaintEvent绘制实时波形图”,内容详细,步骤清晰,细节处理妥当,希望这篇“Qt中怎么使用PaintEvent绘制实时波形图”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧...
    99+
    2023-06-30
  • python如何绘制音频的语谱图
    这篇文章主要介绍python如何绘制音频的语谱图,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!本文介绍如何通过python的pyplot来绘制音频的语谱图。语谱图,也就是语音频谱图,也叫时频图,横坐标是时间,纵坐标是...
    99+
    2023-06-19
  • Python如果实现图形绘制
    这篇文章主要介绍Python如果实现图形绘制,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、画第一个图形第一个图形从简单的开始。1.1 代码# importing the requir...
    99+
    2023-06-22
  • QT+OpenGL实现简单图形的绘制
    继承于QOpenGLWindow,描画出来。新建类myopengl,头文件如下: #ifndef MYOPENGL_H #define MYOPENGL_H #include &...
    99+
    2022-12-28
    QT OpenGL绘制图形 QT 绘制图形 OpenGL绘制图形 QT OpenGL
  • Android实现音频条形图效果(仿音频动画无监听音频输入)
    音频条形图 如下图所示就是这次的音频条形图: 由于只是自定义View的用法,我们就不去真实地监听音频输入了,随机模拟一些数字即可。 如果要实现一个如上图的静态音频条形图,相信...
    99+
    2022-06-06
    输入 监听 条形图 动画 Android
  • Python matplotlib如何实现图形绘制
    本篇内容主要讲解“Python matplotlib如何实现图形绘制”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python matplotlib如何实现图形绘制”吧!1....
    99+
    2023-06-21
  • Python OpenCV实现基本图形绘制
    1.导入模块 import cv2 as cv import numpy as np 2.OpenCV绘图大致步骤 OpenCV 图形绘制步骤 (1)先定义基础画布canv...
    99+
    2022-11-12
  • Matplotlib实现各种条形图绘制
    目录1. 条形图的绘制2. 横向条形图3. 分组条形图4. 堆叠条形图5. 条形图应用场景1. 条形图的绘制 plt.bar 方法有以下常用参数: x :一个数组或者列表,代表需要绘...
    99+
    2022-11-13
  • WPF如何实现绘制3D图形
    今天小编给大家分享一下WPF如何实现绘制3D图形的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。关键概念视口视口指的是图像要展...
    99+
    2023-07-05
  • C++ opencv实现几何图形绘制
    目录1.矩形 rectangle()2. 圆 circle()3.椭圆 elliple()在学习过程中,我们可以在图像中绘制一些几何图形,比如矩形,椭圆,线段,填充多边形等,这些函数...
    99+
    2022-11-13
  • Qt实现实时鼠标绘制图形
    目录功能实现1:记录图形第一个绘制点2:实时获取鼠标最新位置并绘图3:释放绘制点,绘制最终图形总结上一章节介绍了关于QGraphicsView的基础讲解,以及简单的类图创建,由上一章...
    99+
    2022-11-13
  • PHP中Grafika如何实现图形绘制
    这篇文章主要介绍了PHP中Grafika如何实现图形绘制,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、绘制贝塞尔曲线贝塞尔曲线绘制,需要两个端点,一头一尾,还有两个控制点...
    99+
    2023-06-17
  • 使用c++实现OpenCV绘制旋转矩形图形
    目录功能函数测试代码测试效果  功能函数 // 绘制旋转矩形 void DrawRotatedRect(cv::Mat mask,const cv::RotatedRe...
    99+
    2022-11-12
  • WPF实现绘制3D图形的示例代码
    目录关键概念视口相机光源材质3D对象命中测试(鼠标交互)3D对象中2D控件渲染外部导入3D模型WPF的3D功能可以在不编写任何c#代码的情况下进行绘制,只需要使用xaml即可完成3D...
    99+
    2023-03-02
    WPF绘制3D图形 WPF 3D图形 WPF 3D
  • Android自定义View实现shape图形绘制
    概述 之前曾写过一篇文章介绍了Android中drawable使用Shape资源,通过定义drawable中的shape资源能够绘制简单的图形效果,如矩形,椭圆形,线形和圆环等...
    99+
    2022-06-06
    shape view Android
  • Python利用Matplotlib库实现绘制饼形图
    目录1.plt.pie()2. 饼图基本3. 饼状图进阶4. 环形图5. 内嵌环形图1.plt.pie() 饼图 常常用来显示 整体中各部分所占的比例,在python-matplot...
    99+
    2022-11-10
  • Flask框架利用Echarts实现绘制图形
    目录实现绘制饼状图实现绘制柱状图实现绘制折线图echarts是百度推出的一款开源的基于JavaScript的可视化图表库,该开发库目前发展非常不错,且支持各类图形的绘制可定制程度高,...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作