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

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

相关推荐
Lu Yao_11 分钟前
用golang实现二叉搜索树(BST)
开发语言·数据结构·golang
程序猿阿伟27 分钟前
《社交应用动态表情:RN与Flutter实战解码》
javascript·flutter·react native
明似水29 分钟前
Flutter 开发入门:从一个简单的计数器应用开始
前端·javascript·flutter
沐土Arvin34 分钟前
前端图片上传组件实战:从动态销毁Input到全屏预览的全功能实现
开发语言·前端·javascript
找不到、了36 分钟前
Spring-Beans的生命周期的介绍
java·开发语言·spring
(・Д・)ノ1 小时前
python打卡day29
开发语言·python
若水晴空初如梦1 小时前
QT聊天项目DAY11
开发语言·qt
Zww08911 小时前
el-dialog鼠标在遮罩层松开会意外关闭,教程图文并茂
javascript·vue.js·计算机外设
爱编程的鱼1 小时前
C#接口(Interface)全方位讲解:定义、特性、应用与实践
java·前端·c#
sunbyte1 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | 页面布局 与 Vue Router 路由配置
前端·javascript·vue.js·tailwindcss