From b38b38d0c8a1c19bb0b6081e00dd046423b11431 Mon Sep 17 00:00:00 2001 From: yuzhiran Date: Sun, 5 Jul 2026 14:14:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BD=95=E9=9F=B3=20-=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=20uni.authorize=20+=20=E4=BF=AE=E5=A4=8D=20encodeBitR?= =?UTF-8?q?ate=20=E8=B6=8A=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 录音按住松手无效根因有两处: 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。 --- zhiyin-app/src/pages/interview/interview.vue | 47 ++++++-------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/zhiyin-app/src/pages/interview/interview.vue b/zhiyin-app/src/pages/interview/interview.vue index fb95bb1..30df71e 100644 --- a/zhiyin-app/src/pages/interview/interview.vue +++ b/zhiyin-app/src/pages/interview/interview.vue @@ -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() }