• 作者:老汪软件技巧
  • 发表时间:2024-08-30 17:01
  • 浏览量:

前言

在上一篇文章里面(传送门),我利用 vue3 langchain.js node.js 实现了一个能够和ai进行对话的dmeo, 主要的功能是前端进行语音识别,把识别到的文字传给后端,然后后端调用大模型,返回文字。从现在开始,我逐渐要把这个demo完善,升级为一个小项目。

主要升级的点有:

前端实现录音功能

前端的录音功能这里是用MediaRecorder来实现的。

 const mediaRecorder = ref(null)
 const chunks = ref([])
 const blob = ref(null)
 navigator.mediaDevices
      .getUserMedia({ audio: true })
      .then((stream) => {
        mediaRecorder.value = new MediaRecorder(stream)
        mediaRecorder.value.start()
        mediaRecorder.value.addEventListener('stop', () => {
          blob.value = new Blob(chunks.value, { type: 'audio/webm' })
          chunks.value = []
          recordFinish.value = true
        })
        mediaRecorder.value.addEventListener('dataavailable', (e) => {
          chunks.value.push(e.data)
        })
      })
      .catch((error) => {
        console.error('Error:', error)
      })

前端这里的处理比较简单,只要得到录制完成的blob数据就可以。

后端处理音频文件

_语音模块怎么播放语音_语音播放模块程序设计流程图

后端这里的处理,主要就是把得到的音频文件传给百度的接口,但是这里会涉及到音频格式的转化,因为百度的语音识别对音频的格式有特定的要求,所以这里用到了ffmpeg这个包。

 router.post('/tts', upload.single('audio'), async (ctx) => {
    const file = ctx.req.file
    const webmFilePath = path.join('uploads', file.filename)
    const wavFilePath = path.join(`${webmFilePath.replace('.webm', '')}.wav`)
    await new Promise((resolve, reject) => {
      ffmpeg(webmFilePath)
        .output(wavFilePath)
        .format('wav')
        .outputOptions('-sample_fmt s16')
        .outputOptions('-ar 16000')
        .outputOptions('-ac 1')
        .on('end', async () => {
          let voice = fs.readFileSync(wavFilePath)
          let voiceBase64 = Buffer.from(voice)
          try {
            const res = await ttsClient.recognize(voiceBase64, 'wav', 16000, {
              dev_pid: 1737
            })
            ctx.body = {
              message: '',
              code: 200,
              data: {
                content: Array.isArray(res.result) ? res.result[0] : res.result
              }
            }
            resolve()
          } catch (err) {
            console.log('err-', err)
          }
        })
        .on('error', (err) => {
          console.error('Error during conversion:', err)
          reject(err)
        })
        .run()
    })
  })

语音合成

这里的语音合成主要是针对AI输出的文字,进行语音合成。对于我们自己的声音,因为已经进行了录音,前端是有音频数据的,所以只要直接播放就能听到自己的声音了。

而对于AI返回文字的语音合成,这部分主要是后端调用一下百度的语音合成的接口:

 const input = ctx.request.body.input
    const config = ctx.request.body.config
    try {
      const res = await ttsClient.text2audio(input, config)
      ctx.set('Content-Type', 'audio/mpeg')
      ctx.set('Content-Disposition', 'attachment; filename=tts.mpVoice.mp3')
      ctx.body = res.data
    } catch (err) {
      console.log('err', err)
    }

项目地址

感兴趣的朋友,可以用安卓手机体验一下

项目体验地址:italk