前端实现 web获取麦克风权限 录制音频 (需求:ai对话问答)

下载插件

javascript 复制代码
npm i recordrtc

文档:https://recordrtc.org/RecordRTC.html

相关方法整理

获取设备
javascript 复制代码
getvice() {
      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        var Mic = [];
        // 弹框获取麦克风
        navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
          navigator.mediaDevices.enumerateDevices().then((devices) => {
            devices.forEach((device) => {
              if (device.kind === "audioinput") {
                // 麦克风
                if (
                  device.deviceId != "default" &&
                  device.deviceId != "communications"
                ) {
                  this.Mic.push(device);//获取到的麦克风设备
                }
              }
            });
          });
          // 只是为了获取麦克风权限,获取以后立马关闭
          stream.getTracks().forEach((track) => track.stop());
          console.log(this.Mic, 22);
        });
      }
    },

开始录音

javascript 复制代码
 // 开始录音
    startRecord() {
      var that = this;
      // this.voiceStatus = true;
      // mediaDevices可提供对相机和麦克风等媒体输入设备的连接访问
      window.navigator.mediaDevices
        .getUserMedia({ audio: { deviceId: this.Mic[0].deviceId } })//设置{ audio: true}会选择电脑默认设置的麦克风设备
        .then((stream) => {
          this.stream = stream;
          this.getVoice();

          this.recorder = RecordRTC(stream, {
            type: "audio",//类型
            mimeType: "audio/wav",//音频格式
            recorderType: RecordRTC.StereoAudioRecorder,
            desiredSampRate: 16000,//频率
            numberOfAudioChannels: 2, // 单声道
            timeSlice: 1000,
            // bufferSize: 4096, // 缓存大小
            // ondataavailable: this.sendData,//有音频时的回调,一般及时传输websocket有用
            checkForInactiveTracks: true,
          });
          this.recorder.startRecording();
        })
        .catch(function (err) {
          console.log(err);
          console.log("当前浏览器不支持开启麦克风!");
          // that.voiceStatus = false;
        });
    },

停止录音

javascript 复制代码
  // 结束录音
    stopRecord() {
      // this.voiceStatus = false;
      if (this.recorder != null) {
        let recorder = this.recorder;
        // var internalRecorder = recorder.getInternalRecorder();
        // console.log("停止录音回调internalRecorder", internalRecorder);
        //停止录音
        recorder.stopRecording(() => {
          //   var BB = new Blob([recorder.getBlob()], {
          //   type: "audio/wav; codecs=opus",
          // });
          let blob = recorder.getBlob();//获取blob
          var audioURL = window.URL.createObjectURL(blob);

          // let a = document.createElement("a");
          // a.href = audioURL;
          // a.download = "测试";
          // a.click();
          // 将录音文件 以文件对象形式传给后端
          var form = new FormData();
          form.append("upfile", blob);
          console.log("form", form, blob);

          // 释放这个临时的对象url
          window.URL.revokeObjectURL(audioURL);
        });
        let stream = this.stream;
        clearInterval(this.timer1);
        RMSList = [//记录音频大小,用于音频波动样式绘制用
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0,
        ];
        //结束媒体
        stream.getAudioTracks().forEach((track) => track.stop());
      }
    },

获取音量大小

javascript 复制代码
 // 获取音量值大小
    getVoice() {
      const audioContext = new (window.AudioContext ||
        window.webkitAudioContext)();
      // 将麦克风的声音输入这个对象
      const mediaStreamSource = audioContext.createMediaStreamSource(
        this.stream
      );
      // 创建分析节点
      const analyserNode = audioContext.createAnalyser();
      // 连接节点
      mediaStreamSource.connect(analyserNode);
      // 可以实时听到麦克风采集的声音
      // analyserNode.connect(audioContext.destination)

      // 获取音量数据
      const dataArray = new Uint8Array(analyserNode.frequencyBinCount);

      function getVolume() {
        analyserNode.getByteFrequencyData(dataArray);
        let sum = 0;
        for (let i = 0; i < dataArray.length; i++) {
          sum += dataArray[i];
        }
        // 计算平均音量
        const averageVolume = sum / dataArray.length;
        return averageVolume;
      }

      // 每隔一段时间获取一次音量
      this.timer1 = setInterval(() => {
        const volume = getVolume();
        console.log("音量:", Math.round(volume));
        RMSList.unshift(Math.round(volume));
        RMSList.pop();
        // 在这里可以根据需要进行相应的处理
      }, 100);
    },

以上用于记录,后续补充文章,整理AI对话搭建成果

相关推荐
这是个栗子2 小时前
【问题解决】npm包下载速度慢
前端·npm·node.js
Komorebi_99992 小时前
数组和对象的深拷贝和浅拷贝的方法
前端·web
weixin_584121432 小时前
vue3+ts+elementui-表格根据相同值合并
前端·javascript·elementui
吃手机用谁付的款3 小时前
HTML常见标签
前端·html
好好研究4 小时前
CSS样式中的布局、字体、响应式布局
前端·css
拉不动的猪5 小时前
前端小白之 CSS弹性布局基础使用规范案例讲解
前端·javascript·css
伍哥的传说5 小时前
React强大且灵活hooks库——ahooks入门实践之开发调试类hook(dev)详解
前端·javascript·react.js·ecmascript·hooks·react-hooks·ahooks
界面开发小八哥5 小时前
界面控件Kendo UI for Angular 2025 Q2新版亮点 - 增强跨设备的无缝体验
前端·ui·界面控件·kendo ui·angular.js
枷锁—sha7 小时前
从零掌握XML与DTD实体:原理、XXE漏洞攻防
xml·前端·网络·chrome·web安全·网络安全
F2E_Zhangmo7 小时前
基于cornerstone3D的dicom影像浏览器 第二章,初始化页面结构
前端·javascript·vue·cornerstone3d·cornerstonejs