123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- // utils/audioManager.js
- 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 // iOS静音模式设置
- }
- 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 && Array.isArray(wordData.yinjie)) {
- 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 && Array.isArray(wordData.pindu)) {
- 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 {
- // 1. 提取音频信息
- const { main, syllables, frequencies } = this.extractAudioInfo(wordData)
-
- // 2. 准备所有需要缓存的音频
- const allAudios = []
- if (main) allAudios.push(main)
- allAudios.push(...syllables)
- allAudios.push(...frequencies)
-
-
- // App环境才进行真实下载
- if (this.isApp) {
- await this.downloadAndSaveAudios(allAudios)
- }
-
-
- // 4. 保存音频信息到统一存储
- this.saveAudioInfoToStorage(wordData.id, {
- main,
- syllables,
- frequencies
- })
-
- return true
- } catch (error) {
- console.error('音频缓存失败:', error)
- return false
- }
- },
- // 保存音频信息到storage(结构化存储)
- saveAudioInfoToStorage(wordId, audioInfo) {
- const cacheKey = `word_audio_${wordId}`
- const cachedData = {
- timestamp: Date.now(),
- ...audioInfo
- }
- uni.setStorageSync(cacheKey, cachedData)
- },
- // 从storage获取音频信息
- getAudioInfoFromStorage(wordId) {
- const cacheKey = `word_audio_${wordId}`
- return uni.getStorageSync(cacheKey) || null
- },
- // 下载并保存音频(仅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()
- console.log('audio.url',audio.url);
- 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)
- },
- // 缓存单个音频
- async cacheSingleAudio(id, url) {
- return new Promise((resolve, reject) => {
- uni.downloadFile({
- url,
- success: (res) => {
- if (res.statusCode === 200) {
- // 存储音频文件路径
- uni.setStorageSync(`audio_file_${id}`, res.tempFilePath)
- resolve()
- } else {
- reject(new Error(`下载失败,状态码: ${res.statusCode}`))
- }
- },
- fail: reject
- })
- })
- },
- // 播放音频(优先本地,失败后回退网络)
- playAudio(audioInfo) {
- if (!audioInfo?.url) return
-
- const player = this.initPlayer()
- player.stop()
- console.log('this.isApp',this.isApp);
- // 在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}`)
- console.log('player',player);
- console.log('audioInfo.url',audioInfo.url);
- 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
- },
- // 清理指定单词的缓存
- clearWordCache(wordId) {
- // 1. 清理音频信息
- uni.removeStorageSync(`word_audio_${wordId}`)
-
- // 2. 清理所有相关音频文件
- const prefix = `word_${wordId}_`
- const keys = uni.getStorageInfoSync().keys
-
- keys.filter(key => key.startsWith('audio_file_') && key.includes(prefix))
- .forEach(key => uni.removeStorageSync(key))
- },
- // 清理所有缓存
- clearAllCache() {
- // 1. 清理所有音频信息
- const keys = uni.getStorageInfoSync().keys
- keys.filter(key => key.startsWith('word_audio_'))
- .forEach(key => uni.removeStorageSync(key))
-
- // 2. 清理所有音频文件
- keys.filter(key => key.startsWith('audio_file_'))
- .forEach(key => uni.removeStorageSync(key))
- }
- }
|