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

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

相关推荐
点正几秒前
ResizeObserver 和nextTick 的用途
前端
狗子的狗粮3 分钟前
Node.js 模块加载与 exports 和 module.exports 的区别
javascript
zayyo3 分钟前
Web 应用轻量化实战
前端·javascript·面试
kovli7 分钟前
红宝书第十七讲:通俗详解JavaScript的Promise与链式调用
前端·javascript
lilye667 分钟前
精益数据分析(19/126):走出数据误区,拥抱创业愿景
前端·人工智能·数据分析
李是啥也不会13 分钟前
Vue中Axios实战指南:高效网络请求的艺术
前端·javascript·vue.js
jerry60914 分钟前
c++流对象
开发语言·c++·算法
fmdpenny14 分钟前
用python写一个相机选型的简易程序
开发语言·python·数码相机
xiaoliang18 分钟前
《DNS优化真经》
前端
一只小海獭20 分钟前
了解uno.config.ts文件的配置项---转化器
前端