fix: 录音 - 移除 uni.authorize + 修复 encodeBitRate 越界
录音按住松手无效根因有两处: 1. encodeBitRate:128000 对 sampleRate:16000 越界(微信规定16000Hz 下 encodeBitRate 必须在 24000~96000 之间),导致 recorder.start() 立即触发 onError,修改为 encodeBitRate:48000 2. uni.authorize 异步回调延迟 recorder.start(),用户松手时 stopRecord 已执行但 recorder 尚未开始录,且之前的 recordingStarted 守卫跳过 stopRecord 后 authorize 回调又启动录音无法停止。 解决方案: 直接调 recorder.start(),不再前置 uni.authorize。 微信会在需要时自动弹录音权限窗。 format 从 wav 改为 mp3(mp3 在微信各平台兼容性更好), 后端 ffmpeg 会自动转码为 wav 后再送 whisper。
This commit is contained in:
@@ -147,7 +147,7 @@ const isSpeaking = ref(false)
|
||||
const dhRef = ref(null)
|
||||
const isRecording = ref(false)
|
||||
let recorder = null
|
||||
let recordingStarted = false // 标记 recorder.start() 是否已实际调用,避免 stopRecord 在 start 前触发
|
||||
|
||||
|
||||
// 录音初始化(一次性创建 recorder 并设置事件)
|
||||
function initRecorder() {
|
||||
@@ -155,18 +155,15 @@ function initRecorder() {
|
||||
if (recorder) return // 已初始化
|
||||
recorder = uni.getRecorderManager()
|
||||
recorder.onStart(() => {
|
||||
recordingStarted = true
|
||||
console.log('[Recorder] start recording')
|
||||
})
|
||||
recorder.onError((err) => {
|
||||
console.error('[Recorder] error:', err)
|
||||
isRecording.value = false
|
||||
recordingStarted = false
|
||||
uni.showToast({ title: '录音失败,请重试', icon: 'none' })
|
||||
})
|
||||
recorder.onStop(async (res) => {
|
||||
isRecording.value = false
|
||||
recordingStarted = false
|
||||
console.log('[Recorder] stop, tempFilePath:', res.tempFilePath)
|
||||
if (!res.tempFilePath) {
|
||||
uni.showToast({ title: '录音文件为空', icon: 'none' })
|
||||
@@ -412,38 +409,22 @@ function startRecord() {
|
||||
if (aiLoading.value || isComplete.value) return
|
||||
// #ifdef MP-WEIXIN
|
||||
if (isRecording.value) return
|
||||
recordingStarted = false
|
||||
isRecording.value = true
|
||||
uni.authorize({
|
||||
scope: 'scope.record',
|
||||
success: () => {
|
||||
if (!recorder) initRecorder()
|
||||
if (!recorder) {
|
||||
isRecording.value = false
|
||||
uni.showToast({ title: '录音初始化失败', icon: 'none' })
|
||||
return
|
||||
}
|
||||
recorder.start({
|
||||
format: 'wav',
|
||||
sampleRate: 16000,
|
||||
numberOfChannels: 1,
|
||||
encodeBitRate: 128000,
|
||||
})
|
||||
uni.vibrateShort({ type: 'medium' })
|
||||
},
|
||||
fail: () => {
|
||||
isRecording.value = false
|
||||
uni.showModal({
|
||||
title: '需要录音权限',
|
||||
content: '请在「设置」中开启「麦克风」权限后再使用语音输入',
|
||||
confirmText: '去设置',
|
||||
success: (r) => { if (r.confirm) uni.openSetting({}) },
|
||||
})
|
||||
},
|
||||
if (!recorder) initRecorder()
|
||||
if (!recorder) {
|
||||
isRecording.value = false
|
||||
uni.showToast({ title: '录音初始化失败', icon: 'none' })
|
||||
return
|
||||
}
|
||||
recorder.start({
|
||||
format: 'mp3',
|
||||
sampleRate: 16000,
|
||||
numberOfChannels: 1,
|
||||
encodeBitRate: 48000,
|
||||
})
|
||||
uni.vibrateShort({ type: 'medium' })
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
isRecording.value = false
|
||||
uni.showToast({ title: '语音输入仅支持小程序', icon: 'none' })
|
||||
// #endif
|
||||
}
|
||||
@@ -451,8 +432,6 @@ function startRecord() {
|
||||
function stopRecord() {
|
||||
if (!isRecording.value) return
|
||||
isRecording.value = false
|
||||
// 松手太快,recorder.start() 还没实际执行(authorize 异步或录音尚未开始),直接跳过
|
||||
if (!recordingStarted) return
|
||||
if (!recorder) return
|
||||
recorder.stop()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user