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

相关推荐
小二·9 分钟前
Python Web 开发进阶实战:神经符号系统 —— 在 Flask + Vue 中融合深度学习与知识图谱
前端·python·flask
Yan.love11 分钟前
【CSS-动画与过渡】丝滑的艺术,从简单位移到贝塞尔曲线
前端·css
黎轩栀海12 分钟前
Element-UI 用命令行主题工具修改主题色
前端
梦65024 分钟前
Vue 中 v-for 与 v-if 优先级
前端·javascript·vue.js
一只小bit30 分钟前
Qt 多媒体:快速解决音视频播放问题
前端·c++·qt·音视频·cpp·页面
梦65030 分钟前
React 高阶组件
前端·react.js·前端框架
CHU72903530 分钟前
智慧回收新体验:同城废品回收小程序的便捷功能探索
java·前端·人工智能·小程序·php
Marshmallowc30 分钟前
从URL变化到组件重绘:React Router 状态分发机制与组件挂载逻辑深度全解
前端·react.js·前端框架·react router·组件生命周期
老兵发新帖34 分钟前
实时视频流检测问题分析:11秒视频保存的标注视频只有3秒
音视频
虹少侠1 小时前
基于 WebKit 构建 macOS 多浮窗视频播放的技术实践(含完整产品落地)
前端·macos·swift·webkit