使用wavesurferJs实现录音音波效果

效果图展示
插件安装
js 复制代码
npm i wavesurfer
实现过程
js 复制代码
<!-- 
@author: weileiming
@date: 2025-04-26 14:04:08
@description: 悬浮音波层
@props:
  isRecord: 录制状态
  waveOptions: 音波基础配置
  overlayStyle: 基础蒙层配置
@methods:
  togglePlay: 切换录制状态
-->
<template>
    <div>
      <!-- 悬浮音波层 -->
      <div v-if="isRecord" class="floating-wave" :style="overlayStyle">
        <div id="waveform"></div>
      </div>
    </div>
  </template>
  
  <script setup>
  import { ref, nextTick, watch } from "vue";
  import WaveSurfer from "wavesurfer.js";
  import RecordPlugin from "wavesurfer.js/dist/plugins/record.esm.js";
  
  const props = defineProps({
    // 录制状态
    isRecord: {
      type: Boolean,
      required: true,
    },
    // 音波基础配置
    waveOptions: {
      type: Object,
      default: () => ({
        waveColor: "#4CAF50",
        progressColor: "#52C41A",
        height: 20,
        barWidth: 2,
        barGap: 3,
        barRadius: 2,
        barMinHeight: 1,
        normalize: true,
        interact: false,
        fillParent: true,
        pixelRatio: 1,
        minPxPerSec: 50,
        cursorWidth: 0,
        responsive: true,
        partialRender: true,
        removeMediaControl: true,
        hideScrollbar: true,
      }),
    },
    // 基础蒙层配置
    overlayStyle: {
      type: Object,
      default: () => ({
        background: 'rgba(0, 0, 0, 0.15)',
        width: '150px',
        height: '50px',
        minWidth: '150px',
        padding: '15px 10px',
        boxSizing:'border-box',
      }),
    },
  });
  
  const wavesurfer = ref(null);
  const recorder = ref(null);
  // 先声明 createWaveform
  const createWaveform = async () => {
    await nextTick();
  
    try {
      wavesurfer.value = WaveSurfer.create({
        container: "#waveform",
        ...props.waveOptions,
      });
  
      // 创建录音插件前先检查权限
      await navigator.mediaDevices.getUserMedia({ audio: true });
      recorder.value = wavesurfer.value.registerPlugin(
        RecordPlugin.create({
          scrollingWaveform: true,
          renderRecordedAudio: false,
          mediaRecorderOptions: {
            audioBitsPerSecond: 128000,
          },
        })
      );
  
      recorder.value.on("record-start", () => {
        console.log("录音开始");
      });
  
      recorder.value.on("record-end", () => {
        console.log("录音结束");
      });
    } catch (err) {
      console.error("创建 WaveSurfer 实例失败:", err);
      throw err;
    }
  };
  
  // 初始化录制
  const initRecorder = async () => {
    if (!wavesurfer.value) {
      await createWaveform();
    }
  };
  
  // 监听当前的启动状态 使用initRecorder 保证父组件获取到的状态和组件一致
  watch(
    () => props.isRecord,
    async (newVal) => {
      try {
        await initRecorder();
        if (newVal) {
          await recorder.value.startRecording();
        } else {
          await recorder.value.stopRecording();
        }
      } catch (error) {
        console.error("录音操作失败:", error);
      }
    },
    { immediate: true }
  );
  
  const togglePlay = async () => {
    try {
      await initRecorder();
    } catch (error) {
      console.error("麦克风访问错误:", error);
      alert("请允许访问麦克风");
    }
  };
  // 暴露方法
  defineExpose({
    togglePlay,
  });
  </script>
  
  <style scoped>
  
  </style>
  
使用示例
js 复制代码
<script setup>
import { ref } from 'vue';
import SoundWave from './components/SoundWave/SoundWave.vue'
const mkRef = ref(null);
const isRecord = ref(false);
const handleToggle = () => {
  console.log('handleToggle', mkRef.value);
  mkRef.value.togglePlay();
  isRecord.value = !isRecord.value;
};
</script>

<template>
 <button class="control-btn" @click="handleToggle">START</button>
 <SoundWave ref="mkRef" :isRecord="isRecord"></SoundWave>
</template>

<style scoped>
.control-btn {
  background-color: #4CAF50; 
  border: none; 
  color: white; 
  padding: 10px 20px; 
  text-align: center; 
  text-decoration: none; 
  display: inline-block; 
  font-size: 16px; 
  margin: 4px; 
  cursor: pointer; 
  border-radius: 4px; 
  transition: background-color 0.3s ease; 
}

.control-btn:hover {
  background-color: #45a049; 
}
</style>
npm下载该功能

上面功能可以直接去我的npm主页下载

js 复制代码
npm i vue-sound-wave
说明

只针对麦克风音波效果开发,不做音频文件导出

相关推荐
gnip4 小时前
企业级配置式表单组件封装
前端·javascript·vue.js
一只叫煤球的猫4 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
excel5 小时前
Three.js 材质(Material)详解 —— 区别、原理、场景与示例
前端
掘金安东尼6 小时前
抛弃自定义模态框:原生Dialog的实力
前端·javascript·github
hj5914_前端新手9 小时前
javascript基础- 函数中 this 指向、call、apply、bind
前端·javascript
薛定谔的算法9 小时前
低代码编辑器项目设计与实现:以JSON为核心的数据驱动架构
前端·react.js·前端框架
Hilaku10 小时前
都2025年了,我们还有必要为了兼容性,去写那么多polyfill吗?
前端·javascript·css
yangcode10 小时前
iOS 苹果内购 Storekit 2
前端
LuckySusu10 小时前
【js篇】JavaScript 原型修改 vs 重写:深入理解 constructor的指向问题
前端·javascript
LuckySusu10 小时前
【js篇】如何准确获取对象自身的属性?hasOwnProperty深度解析
前端·javascript