使用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
说明

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

相关推荐
Holin_浩霖3 分钟前
函数式编程实现简单的 Fiber 架构
前端
一枚前端小能手8 分钟前
📚 JavaScript 数据类型与数据结构全攻略 - 原始值、对象、Map/Set与弱引用实战
前端·javascript
AI视觉网奇9 分钟前
yolo 获取异常样本 yolo 异常
开发语言·python·yolo
散峰而望10 分钟前
C++入门(二) (算法竞赛)
开发语言·c++·算法·github
沐知全栈开发26 分钟前
CSS Float(浮动)详解
开发语言
JarvanMo30 分钟前
我的app被工信部下架了,现在想重新上架
前端
景早30 分钟前
小黑记账清单案例(axios,echarts,vue)
前端·vue.js·echarts
Mintopia30 分钟前
🌐 《GraphQL in Next.js 初体验》中文笔记
前端·后端·全栈
Cx330❀32 分钟前
《C++ 搜索二叉树》深入理解 C++ 搜索二叉树:特性、实现与应用
java·开发语言·数据结构·c++·算法·面试
我穿棉裤了34 分钟前
使用css 给div添加四角线框
前端·css