export default { player: null, isApp: uni.getSystemInfoSync().platform === 'ios' || uni.getSystemInfoSync().platform === 'android', initPlayer() { if (!this.player) { this.player = uni.createInnerAudioContext() this.player.obeyMuteSwitch = false } return this.player }, // 提取音频信息 extractAudioInfo(wordData) { const audioInfo = { main: null, syllables: [], frequencies: [] } if (wordData.yinpin) { audioInfo.main = { id: `word_${wordData.id}_main`, url: wordData.yinpin, type: 'main', text: wordData.name } } if (wordData.yinjie?.length) { audioInfo.syllables = wordData.yinjie.map((item, index) => ({ id: `word_${wordData.id}_syllable_${index}`, url: item.yinpin, type: 'syllable', text: item.cigen, index })).filter(item => item.url) } if (wordData.pindu?.length) { audioInfo.frequencies = wordData.pindu.map((item, index) => ({ id: `word_${wordData.id}_frequency_${index}`, url: item.yinpin, type: 'frequency', text: item.cigen, index })).filter(item => item.url) } return audioInfo }, // 缓存单词的所有音频 async cacheWordAudios(wordData) { try { const { main, syllables, frequencies } = this.extractAudioInfo(wordData) const allAudios = [] if (main) allAudios.push(main) allAudios.push(...syllables) allAudios.push(...frequencies) // App环境才进行真实下载 if (this.isApp) { await this.downloadAndSaveAudios(allAudios) } this.saveAudioInfoToStorage(wordData.id, { main, syllables, frequencies }) return true } catch (error) { console.error('音频缓存失败:', error) return false } }, // 下载并保存音频(仅App环境) async downloadAndSaveAudios(audioList) { const downloadPromises = audioList.map(audio => { return new Promise((resolve, reject) => { // 先检查是否已缓存 const cachedPath = uni.getStorageSync(`audio_file_${audio.id}`) if (cachedPath) return resolve() uni.downloadFile({ url: audio.url, success: (res) => { if (res.statusCode === 200) { uni.setStorageSync(`audio_file_${audio.id}`, res.tempFilePath) resolve() } else { reject(new Error(`下载失败,状态码: ${res.statusCode}`)) } }, fail: reject }) }).catch(e => { console.warn(`音频 ${audio.id} 预加载失败:`, e) // 即使下载失败也继续其他下载 }) }) await Promise.all(downloadPromises) }, // 播放音频(优先本地,失败后回退网络) playAudio(audioInfo) { if (!audioInfo?.url) return const player = this.initPlayer() player.stop() // 在App环境尝试使用本地缓存 if (this.isApp) { const cachedPath = uni.getStorageSync(`audio_file_${audioInfo.id}`) if (cachedPath) { player.src = cachedPath player.play() return player } } // 非App环境或缓存失败时使用网络 console.warn(`使用网络音频: ${audioInfo.id}`) player.src = audioInfo.url player.play() // App环境下后台继续尝试缓存 if (this.isApp) { this.downloadAndSaveAudios([audioInfo]).catch(console.error) } player.onError((err) => { console.error('播放失败:', err) uni.showToast({ title: '播放失败', icon: 'none' }) }) return player }, // 其他方法保持不变... saveAudioInfoToStorage(wordId, audioInfo) { const cacheKey = `word_audio_${wordId}` uni.setStorageSync(cacheKey, { timestamp: Date.now(), ...audioInfo }) }, getAudioInfoFromStorage(wordId) { const cacheKey = `word_audio_${wordId}` return uni.getStorageSync(cacheKey) || null }, clearWordCache(wordId) { uni.removeStorageSync(`word_audio_${wordId}`) const prefix = `word_${wordId}_` const keys = uni.getStorageInfoSync().keys keys.filter(key => key.startsWith('audio_file_') && key.includes(prefix)) .forEach(key => uni.removeStorageSync(key)) } }