From 34cad2543d7c44f98a7ec5373b9f08ccc30fe9ed Mon Sep 17 00:00:00 2001 From: francis_fh <13935151924@163.com> Date: Fri, 23 Jan 2026 12:34:04 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9F=B3=E9=A2=91=E9=97=AE=E9=A2=98=E8=A7=A3?= =?UTF-8?q?=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hook/useTTSPlayer.js | 198 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 157 insertions(+), 41 deletions(-) diff --git a/hook/useTTSPlayer.js b/hook/useTTSPlayer.js index 2864987..71108d1 100644 --- a/hook/useTTSPlayer.js +++ b/hook/useTTSPlayer.js @@ -23,6 +23,7 @@ export function useTTSPlayer(httpUrl) { // #ifdef MP-WEIXIN const audioContext = null // 微信小程序不支持 AudioContext let innerAudioContext = null // 微信小程序音频上下文 + let backgroundAudioManager = null // 微信小程序背景音频管理器 // #endif let currentAudioBuffer = null @@ -31,41 +32,64 @@ export function useTTSPlayer(httpUrl) { // 初始化微信小程序音频上下文 // #ifdef MP-WEIXIN - const initInnerAudioContext = () => { - if (!innerAudioContext) { - innerAudioContext = uni.createInnerAudioContext() - innerAudioContext.autoplay = false - innerAudioContext.onPlay(() => { - console.log('🎵 微信小程序音频播放开始') + const initAudioManager = () => { + // 优先使用BackgroundAudioManager,更适合真机环境 + try { + console.log('� 微信小程序:创建背景音频管理器') + backgroundAudioManager = uni.getBackgroundAudioManager() + + // 设置默认配置 + backgroundAudioManager.title = 'AI语音播报' + backgroundAudioManager.singer = 'KS AI' + backgroundAudioManager.coverImgUrl = '/static/icon/logo.png' + backgroundAudioManager.volume = 1.0 + + backgroundAudioManager.onPlay(() => { + console.log('🎵 微信小程序背景音频播放开始') isSpeaking.value = true isPaused.value = false }) - innerAudioContext.onPause(() => { - console.log('⏸️ 微信小程序音频播放暂停') + + backgroundAudioManager.onPause(() => { + console.log('⏸️ 微信小程序背景音频播放暂停') isPaused.value = true }) - innerAudioContext.onStop(() => { - console.log('⏹️ 微信小程序音频播放停止') + + backgroundAudioManager.onStop(() => { + console.log('⏹️ 微信小程序背景音频播放停止') isSpeaking.value = false isComplete.value = true }) - innerAudioContext.onEnded(() => { - console.log('🎵 微信小程序音频播放结束') + + backgroundAudioManager.onEnded(() => { + console.log('🎵 微信小程序背景音频播放结束') isSpeaking.value = false isComplete.value = true }) - innerAudioContext.onError((res) => { - console.error('❌ 微信小程序音频播放错误:', res.errMsg) + + backgroundAudioManager.onError((res) => { + console.error('❌ 微信小程序背景音频播放错误:', res.errMsg, '错误码:', res.errCode) isSpeaking.value = false isComplete.value = false }) - innerAudioContext.onCanplay(() => { - console.log('🎵 微信小程序音频可以播放了') - // 只有在需要播放且未播放状态下才调用play - if (isSpeaking.value && !isPaused.value) { - innerAudioContext.play() - } + + backgroundAudioManager.onCanplay(() => { + console.log('🎵 微信小程序背景音频可以播放了') }) + + backgroundAudioManager.onWaiting(() => { + console.log('⏳ 微信小程序背景音频加载中...') + }) + + backgroundAudioManager.onTimeUpdate(() => { + console.log('⏱️ 微信小程序背景音频播放进度:', backgroundAudioManager.currentTime) + }) + + console.log('✅ 微信小程序背景音频管理器初始化成功') + return true + } catch (e) { + console.error('❌ 微信小程序背景音频管理器初始化失败:', e) + return false } } // #endif @@ -84,15 +108,62 @@ export function useTTSPlayer(httpUrl) { console.log('🔗 Final GET URL:', url); // #ifdef MP-WEIXIN - // 微信小程序环境,使用微信音频API - initInnerAudioContext() - console.log('🎵 微信小程序:设置音频 src 为:', url); + // 微信小程序环境,使用背景音频管理器 + const isBackgroundAudioAvailable = initAudioManager() + // 重置音频状态 isSpeaking.value = true isPaused.value = false isComplete.value = false - // 设置src,等待onCanplay事件触发后再播放 - innerAudioContext.src = url + + if (isBackgroundAudioAvailable && backgroundAudioManager) { + console.log('🎵 微信小程序:使用背景音频管理器播放,URL:', url); + + // 设置背景音频参数 + backgroundAudioManager.title = 'AI语音播报' + backgroundAudioManager.singer = 'KS AI' + backgroundAudioManager.coverImgUrl = '/static/icon/logo.png' + + // 直接设置src并播放 + backgroundAudioManager.src = url + console.log('🎵 微信小程序背景音频开始播放'); + } else { + // 降级方案:使用InnerAudioContext + console.log('🔄 微信小程序:背景音频不可用,降级使用InnerAudioContext'); + + // 如果已有音频上下文,先销毁再重新创建 + if (innerAudioContext) { + innerAudioContext.destroy() + innerAudioContext = null + } + + innerAudioContext = uni.createInnerAudioContext() + innerAudioContext.autoplay = false + innerAudioContext.obeyMuteSwitch = false + innerAudioContext.volume = 1.0 + + innerAudioContext.onPlay(() => { + console.log('🎵 微信小程序InnerAudioContext播放开始') + isSpeaking.value = true + isPaused.value = false + }) + + innerAudioContext.onEnded(() => { + console.log('🎵 微信小程序InnerAudioContext播放结束') + isSpeaking.value = false + isComplete.value = true + }) + + innerAudioContext.onError((res) => { + console.error('❌ 微信小程序InnerAudioContext错误:', res.errMsg, '错误码:', res.errCode) + isSpeaking.value = false + isComplete.value = false + }) + + innerAudioContext.src = url + innerAudioContext.play() + console.log('🎵 微信小程序InnerAudioContext开始播放'); + } // #endif // #ifdef H5 @@ -177,11 +248,29 @@ export function useTTSPlayer(httpUrl) { // #endif const pause = () => { + console.log('⏸️ TTS pause called'); + // #ifdef MP-WEIXIN + // 优先使用背景音频管理器 + if (backgroundAudioManager) { + try { + backgroundAudioManager.pause() + console.log('⏸️ 微信小程序背景音频暂停'); + return + } catch (e) { + console.error('❌ 微信小程序背景音频暂停失败:', e); + } + } + + // 降级使用InnerAudioContext if (innerAudioContext && isSpeaking.value && !isPaused.value) { - console.log('⏸️ 微信小程序音频暂停'); - innerAudioContext.pause() - return + try { + innerAudioContext.pause() + console.log('⏸️ 微信小程序InnerAudioContext暂停'); + return + } catch (e) { + console.error('❌ 微信小程序InnerAudioContext暂停失败:', e); + } } // #endif @@ -191,24 +280,40 @@ export function useTTSPlayer(httpUrl) { return; } - console.log('⏸️ TTS pause called'); - if (audioContext.state === 'running') { audioContext.suspend() isPaused.value = true // 保存当前播放位置 playTimeOffset = audioContext.currentTime - console.log('✅ Audio paused successfully'); + console.log('✅ H5 Audio paused successfully'); } // #endif } const resume = () => { + console.log('▶️ TTS resume called'); + // #ifdef MP-WEIXIN + // 优先使用背景音频管理器 + if (backgroundAudioManager) { + try { + backgroundAudioManager.play() + console.log('▶️ 微信小程序背景音频恢复播放'); + return + } catch (e) { + console.error('❌ 微信小程序背景音频恢复失败:', e); + } + } + + // 降级使用InnerAudioContext if (innerAudioContext && isSpeaking.value && isPaused.value) { - console.log('▶️ 微信小程序音频恢复播放'); - innerAudioContext.play() - return + try { + innerAudioContext.play() + console.log('▶️ 微信小程序InnerAudioContext恢复播放'); + return + } catch (e) { + console.error('❌ 微信小程序InnerAudioContext恢复失败:', e); + } } // #endif @@ -218,12 +323,10 @@ export function useTTSPlayer(httpUrl) { return; } - console.log('▶️ TTS resume called'); - if (audioContext.state === 'suspended') { audioContext.resume() isPaused.value = false - console.log('✅ Audio resumed successfully'); + console.log('✅ H5 Audio resumed successfully'); } // #endif } @@ -236,12 +339,25 @@ export function useTTSPlayer(httpUrl) { console.log('⏹️ TTS stop called'); // #ifdef MP-WEIXIN + // 优先使用背景音频管理器 + if (backgroundAudioManager) { + try { + backgroundAudioManager.stop() + console.log('✅ 微信小程序背景音频停止'); + } catch (e) { + console.error('❌ 微信小程序背景音频停止失败:', e); + } + } + + // 降级使用InnerAudioContext if (innerAudioContext) { try { innerAudioContext.stop() - console.log('✅ 微信小程序音频停止'); + console.log('✅ 微信小程序InnerAudioContext停止'); + innerAudioContext.destroy() + innerAudioContext = null } catch (e) { - console.error('❌ 微信小程序音频停止错误:', e); + console.error('❌ 微信小程序InnerAudioContext停止错误:', e); } } // #endif @@ -252,7 +368,7 @@ export function useTTSPlayer(httpUrl) { currentSource.stop() currentSource.disconnect() } catch (e) { - console.error('❌ Error stopping audio source:', e); + console.error('❌ Error stopping H5 audio source:', e); } currentSource = null } @@ -261,7 +377,7 @@ export function useTTSPlayer(httpUrl) { try { audioContext.suspend() } catch (e) { - console.error('❌ Error suspending audio context:', e); + console.error('❌ Error suspending H5 audio context:', e); } } // #endif