You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Predictions语音转文本:浏览器录音后续音频解码失败

问题分析与解决方案

核心问题

  1. 重复创建AudioContext:每次调用convertAudio都新建AudioContext实例,浏览器对这类音频上下文实例的数量有限制,多次创建会导致后续解码失败。
  2. MediaRecorder片段无完整文件头:调用recorder.start(500)会每隔500ms触发ondataavailable,但这些片段是不完整的音频数据(缺少文件头信息),decodeAudioData无法解析这类片段。
  3. 媒体流未正确管理:每次录制未释放之前的媒体流轨道,可能导致资源泄漏;同时device.value存储的是Promise而非媒体流对象,代码逻辑存在冗余。
  4. 编码格式不匹配:MediaRecorder默认编码格式可能不被AWS Transcription或decodeAudioData兼容,需要指定明确的、双方支持的格式。

修复后的代码

// initialize refs
const isRecording = ref(false)
const mediaStream = ref(null)
const recorder = ref(null)
const audioChunks = ref([])
// 复用单个AudioContext实例
const audioContext = ref(new AudioContext())

async function recordAudio() {
  if (isRecording.value) return
  isRecording.value = true
  audioChunks.value = []
  
  // 正确获取媒体流并存储
  mediaStream.value = await navigator.mediaDevices.getUserMedia({ audio: true })
  
  // 指定兼容的编码格式,优先选择AWS支持的wav/mp3
  const mimeType = 'audio/wav' // 或尝试 'audio/mp3'(需浏览器支持)
  recorder.value = new MediaRecorder(mediaStream.value, { mimeType })
  
  recorder.value.ondataavailable = (e) => {
    if (e.data.size > 0) {
      audioChunks.value.push(e.data)
    }
  }
  
  // 录制结束后统一处理音频
  recorder.value.onstop = async () => {
    await convertAudio(audioChunks.value)
    // 释放媒体流轨道
    mediaStream.value.getTracks().forEach(track => track.stop())
    mediaStream.value = null
  }
  
  recorder.value.start()
}

// called on stop-button click
async function stop() {
  if (!isRecording.value || !recorder.value) return
  recorder.value.stop()
  isRecording.value = false
}

async function convertAudio(chunks) {
  const audioBlob = new Blob(chunks, { type: recorder.value.mimeType })
  const audioBuffer = await audioBlob.arrayBuffer()
  
  try {
    // 使用Promise形式的decodeAudioData,便于错误捕获
    const res = await audioContext.value.decodeAudioData(audioBuffer)
    const output = res.getChannelData(0)
    
    const result = await Predictions.convert({
      transcription: {
        source: {
          bytes: output
        },
        language: 'de-DE'
      }
    })
    
    console.log({ fullText: result.transcription.fullText })
  } catch (err) {
    console.error('音频解码或转录失败:', err)
  }
}

关键修改说明

  • 复用AudioContext:全局创建一个audioContext实例,避免重复创建导致的浏览器限制问题。
  • 收集完整音频片段:在ondataavailable中收集所有音频块,直到录制停止后再统一处理,确保音频数据完整(带文件头)。
  • 指定编码格式:明确设置MediaRecorder的mimeType为AWS Transcription支持的格式(如audio/wav),保证解码和转录兼容性。
  • 正确管理媒体流:录制停止后主动停止媒体流的所有轨道,释放资源;同时修正媒体流的存储方式,直接存储流对象而非Promise。
  • Promise化解码逻辑:使用await audioContext.value.decodeAudioData(audioBuffer)替代回调,更直观处理错误。

内容的提问来源于stack exchange,提问作者DontEatMyCookies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:22:36