小程序模板:专业的小程序模板与静态模板分享平台
小程序
教程
搜索
当前位置 : 首页> 小程序教程> 微信小程序实现AI语音对话的功能

微信小程序实现AI语音对话的功能

用户语音检测与沉默判断

通过录音管理器的RecorderManager.onFrameRecorded监测已录制完指定帧大小的文件事件,然后对ArrayBuffer文件进行处理,判断用户是否开始说话,说话是否结束等。

  onLoad: function (options) {
    this.data.recordingManager = wx.getRecorderManager()
    const audioCtx = wx.createWebAudioContext()
    const analyser = audioCtx.createAnalyser();
    this.data.recordingManager.onFrameRecorded(listener => {
      if (listener.isLastFrame) {
        this.handleSoundIntensityChange(0);
      } else {
        audioCtx.decodeAudioData(listener.frameBuffer, buffer => {
          let source = audioCtx.createBufferSource()
          source.buffer = buffer
          source.connect(analyser)
          source.start()
          let n = new Uint8Array(analyser.frequencyBinCount)
          analyser.getByteTimeDomainData(n)
          let i = 0,
            r = 0,
            s = 0
          r = Math.max.apply(null, n)
          s = Math.min.apply(null, n)
          i = (r - s) / 128
          i = Math.round(i * 100 / 2)
          i = i > 100 ? 100 : i
          this.handleSoundIntensityChange(i)
        }, err => {
          console.error('decodeAudioData fail', err)
        })
      }
    })
  },
     // 处理声音强度变化
  handleSoundIntensityChange(i) {
    if ((i >= 0 && i <= 10) && this.data.isAllowStart) {
      if (!this.data.timer) {
        this.data.timer = setTimeout(() => {
          if (!this.data.isSpeaking) {
            this.data.isSpeaking = true;
            this.data.recordingManager.stop();
            this.setData({
              theDesc: '回答中...'
            })
            clearTimeout(this.data.timer);
            this.data.timer = null;
            console.log('说话完毕');
          }
        }, 2000); // 2秒内没有值变化,认为“说话完毕”
      }
    } else if (i > 10) {
      if (this.data.theNumber <= 2) {
        this.data.theNumber++
      } else {
        this.data.isAllowStart = true
        if (this.data.timer) {
          clearTimeout(this.data.timer);
          this.data.timer = null;
        }
      }
    }
  },

录音结束,发送消息

说话结束,发送包含录音文件的消息。然后对websocket的推送数据进行处理,播放音频文件

    this.data.recordingManager.onStop((res) => {
      // 录音停止后的回调函数
      if (this.data.isSpeaking) {
        this.sendAudio(res.tempFilePath)
      }
    });
    sendAudio(url) {
    let that = this
    wx.uploadFile({
      url: 'xxx你的地址',
      filePath: url,
      name: 'file',
      success: (uploadRes) => {
        const data = JSON.parse(uploadRes.data);
        if (data.data && data.data.url) {
            that.createChat('', () => {
              const ws = that.data.ws;
              if (ws && ws.send) {
                ws.send({
                  data: JSON.stringify({
                    fileUrl: data.data.url,
                    token: app.globalData.sessionKey,
                    chatID: that.data.theChatId
                  }),
                });
            }
          }
        }
      },
      fail: (err) => {
        console.error('上传文件失败', err);
      }
    });
  },

处理PCM16格式音频文件

	//websocket消息处理
    socket.onMessage((event) => {
      const message = event.data;
      if (message != '{"type":"ping"}') {
        that.data.isGoing = true
        if (message.includes('[DONE]')) {
          that.data.isOver = true
          //音频文件格式处理
          const wavData = that.convertToWav(wx.base64ToArrayBuffer(that.data.baseUrl), 22000, 1);
          const fs = wx.getFileSystemManager();
          const filePath = `${wx.env.USER_DATA_PATH}/audio${Date.now()}.wav`;
          const uint8ArrayData = new Uint8Array(wavData);
          fs.writeFile({
            filePath: filePath,
            data: uint8ArrayData.buffer,
            encoding: 'binary',
            success: function () {
              if (!that.data.isPlayIng) {
                innerAudioContext.src = filePath;
                innerAudioContext.play();
              } else {
                that.data.theAudioList.push(filePath)
              }
            },
            fail: function (err) {
              console.error('保存 WAV 文件失败', err);
            }
          });
          return;
        }
        if (!(message.includes('completion_tokens'))) {
          //执行你的音频播放逻辑
        }
      } else {
        if (that.data.isGoing && !that.data.stopTimer) {
          that.data.stopTimer = setTimeout(() => {
            that.data.isGoing = false
            that.data.isOver = true
            that.data.stopTimer = null
          }, 2000);
        }
      }
    });


联系客服 意见反馈

签到成功!

已连续签到1天,签到3天将获得积分VIP1天

知道了