前端实现 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对话搭建成果

相关推荐
ZPC82101 天前
如何创建一个单例类 (Singleton)
开发语言·前端·人工智能
紫_龙1 天前
最新版vue3+TypeScript开发入门到实战教程之重要详解readonly/shallowReadOnly
前端·javascript·typescript
AI周红伟1 天前
AI自动盯盘与定时行情分析:OpenClaw股票辅助Agent集成完整使用指南-周红伟
运维·服务器·人工智能·音视频·火山引擎
roamingcode1 天前
前端 AI Agent 多智能体协作架构:从对抗式排查到工作流解耦
前端·人工智能·架构·agent·team
蓝莓味的口香糖1 天前
【vue】初始化 Vue 项目
前端·javascript·vue.js
光影少年1 天前
数组去重方法
开发语言·前端·javascript
我命由我123451 天前
浏览器的 JS 模块化支持观察记录
开发语言·前端·javascript·css·html·ecmascript·html5
weixin_443478511 天前
Flutter第三方常用组件包之路由管理
前端·javascript·flutter
武藤一雄1 天前
C# 异步回调与等待机制
前端·microsoft·设计模式·微软·c#·.netcore
啥都不懂的小小白1 天前
前端CSS入门详解
前端·css