GoChatIAI -Go语言AI应用服务平台(2)

本次功能开发

TTS语音合成

接口路由

图片

页面展示

图片

接入百度云语音合成

获取百度相关的client_id还有client_secret
登录进入百度智能云,搜索语音合成
图片
点击立即使用(注意:中途可能会让你注册服务什么的,直接开通服务即可)
图片
点击下面的API在线调试
图片
从这里可以查看对应client_id还有client_secret
图片

代码块

// 播放文件
const pendingAudioUrl = ref(null)
const isGenerating = ref(false)
const currentAudio = ref(null)
const audioReady = ref(false) // 新增标志
// TTS
const playTTS = async (text) => {


  // 如果音频已就绪,直接播放
  if (audioReady.value && pendingAudioUrl.value) {
    await playAudio(pendingAudioUrl.value)
    audioReady.value = false // 播放后重置
    return
  }

  // 否则生成新的音频
  await generateTTS(text)



};

const generateTTS = async (text) => {
  try {
    isGenerating.value = true
    audioReady.value = false
    // 创建tts任务
    const createResponse = await api.post('/AI/chat/tts', { text })
    if (createResponse.data && createResponse.data.status_code === 1000 && createResponse.data.task_id) {
      const taskId = createResponse.data.task_id

      // 先等待5秒钟再开始轮询
      await new Promise(resolve => setTimeout(resolve, 5000))
      // 轮询查询任务结果
      const maxAttempts = 30
      const pollInterval = 2000
      let attempts = 0

      const pollResult = async () => {
        const queryResponse = await api.get('/AI/chat/tts/query', { params: { task_id: taskId } })
        if (queryResponse.data && queryResponse.data.status_code === 1000) {
          const taskStatus = queryResponse.data.task_status
          if (taskStatus === 'Success' && queryResponse.data.task_result) {
            // 任务完成,播放音频
            // 后端返回的 task_result 是直接的 URL 字符串

            // 保存音频URL
            pendingAudioUrl.value = queryResponse.data.task_result
            isGenerating.value = false
            audioReady.value = true // 标记音频已就绪

            // 提示用户
            ElMessage.success('语音已就绪,点击播放')

            return true
          }
          else if (taskStatus === 'Running' || taskStatus === 'Created') {
            // 任务进行中,继续轮询
            attempts++
            if (attempts < maxAttempts) {
              await new Promise(resolve => setTimeout(resolve, pollInterval))
              return await pollResult()
            } else {
              ElMessage.error('语音合成超时')
              return true
            }
          }
          else {
            // 其他状态(如失败)
            ElMessage.error('语音合成失败')
            return true
          }

        }

        attempts++
        if (attempts < maxAttempts) {
          await new Promise(resolve => setTimeout(resolve, pollInterval))
          return await pollResult()
        } else {
          ElMessage.error('语音合成超时')
          return true
        }

      }

      await pollResult()
    }
    else {
      ElMessage.error('无法创建语音合成任务')

    }
  }
  catch (error) {
    isGenerating.value = false
    ElMessage.error('请求语音接口失败' + error)

  }
}

// 播放音频(必须在用户手势中调用)
const playAudio = async (url) => {
  try {
    // 如果已有播放中的音频,先暂停
    if (currentAudio.value) {
      currentAudio.value.pause()
    }

    // 创建新音频
    currentAudio.value = new Audio(url)

    // 添加事件监听
    currentAudio.value.addEventListener('ended', () => {
      pendingAudioUrl.value = null // 播放完成,清除待播放状态
    })

    // 播放
    await currentAudio.value.play()
    ElMessage.success('播放中...')

  } catch (error) {
    ElMessage.warning('请再次点击播放按钮' + error)

    // 保留pendingAudioUrl,让用户可以再次点击播放
  }
}
posted @ 2026-03-17 15:31  oow3b  阅读(51)  评论(0)    收藏  举报