vue中使用wavesurfer.js绘制波形图和频谱图

在这里插入图片描述

新的实现方式:vue使用Canvas绘制频谱图

安装wavesurfer.js

npm install wavesurfer.js

第一版:

组件特点:

  • 一次性加载好所有的数据;
<template>
  <div class="audio-visualizer-container">
    <div class="visualization-container">
      <div ref="waveform" class="waveform"></div>
      <div ref="spectrogram" class="spectrogram"></div>
      <div v-if="loading" class="loading-indicator">音频加载中...</div>
      <div v-if="error" class="error-message">{
  
  { error }}</div>
    </div>

    <div class="audio-controls">
      <audio
        ref="audioPlayer"
        controls
        @play="startPlay"
        @pause="stopPlay"
        @seeked="handleSeek"
        controlsList="nodownload noplaybackrate"
      ></audio>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import Vue from 'vue'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import WaveSurfer from 'wavesurfer.js'
import Spectrogram from 'wavesurfer.js/dist/plugins/spectrogram.esm.js'
// https://juejin.cn/post/6979191645916889095

export default {
  name: 'AudioWaveform',
  props: {
    audioUrl: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      wavesurfer: null,
      spectrogramPlugin: null,
      isPlaying: false,
      audioBlobUrl: null,
      loading: false,
      error: null,
      isUserInteraction: false, // 标记是否是用户交互
    }
  },
  watch: {
    audioUrl(newVal) {
      this.handleAudioUrl(newVal)
    },
  },
  mounted() {
    this.initWaveSurfer()
    this.handleAudioUrl(this.audioUrl)
  },
  beforeDestroy() {
    this.cleanup()
  },
  methods: {
    async initWaveSurfer() {
      try {
        this.wavesurfer = WaveSurfer.create({
          container: this.$refs.waveform,
          waveColor: '#48a1e0',
          progressColor: '#25ebd7',
          cursorColor: '#333',
          // cursorWidth: 1,
          // barWidth: 2,
          // barRadius: 3,
          height: 150,
          sampleRate: 8000, // 明确指定采样率
          // normalize: true,
          // backend: 'WebAudio',

          // renderFunction: (channels, ctx) => {
          //   console.log('Custom render function called!') // 确保执行
          //   // this.drawWaveform(ctx, channels[0]) // 使用第一个声道数据绘制波形

          //   const { width, height } = ctx.canvas
          //   const channelData = channels[0] // 使用左声道数据
          //   const dataLength = channelData.length
          //   const step = Math.max(1, Math.floor(dataLength / width)) // 确保步长≥1,避免除零

          //   ctx.beginPath()
          //   ctx.lineWidth = 1
          //   ctx.strokeStyle = '#48a1e0' // 波形颜色

          //   // 中心线位置(对称波形)
          //   const centerY = height / 2

          //   for (let i = 0; i < width; i++) {
          //     // 使用 step 控制数据采样间隔
          //     const dataIndex = Math.min(Math.floor(i * step), dataLength - 1) // 防止数组越界
          //     const value = channelData[dataIndex] // 获取振幅值(-1 到 1)

          //     // 映射振幅到 Canvas 高度
          //     const amplitude = value * centerY
          //     console.log(`绘制点: x=${i},value=${value} amplitude=${amplitude} realMv=${this.calcRealMv(value)}`) // 调试输出
          //     const x = i
          //     const y = centerY - amplitude // 向上为正,向下为负

          //     if (i === 0) {
          //       ctx.moveTo(x, y)
          //     } else {
          //       ctx.lineTo(x, y)
          //     }
          //   }

          //   ctx.stroke() // 绘制路径
          //   ctx.closePath()
          // },
        })
        // 初始化频谱图插件
        this.spectrogramPlugin = this.wavesurfer.registerPlugin(
          Spectrogram.create({
            container: this.$refs.spectrogram,
            // labels: true,
            // labelsBackground: 'rgba(0,0,0,0.1)', //频率标签的背景
            height: 150,
            fftSamples: 1024,
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值