细节修改
This commit is contained in:
@@ -128,9 +128,42 @@ class AudioManager {
|
||||
this.failedLoadKeys = new Set();
|
||||
// 加载代数,用于 reloadAll 时作废旧的加载循环
|
||||
this.loadGeneration = 0;
|
||||
// 本地路径缓存 Map: { url: localPath }
|
||||
this.localFileCache = uni.getStorageSync("audio_local_files") || {};
|
||||
// 启动时自动清理过期的缓存文件(URL 已不在 audioFils 中的文件)
|
||||
this.cleanObsoleteCache();
|
||||
this.initAudios();
|
||||
}
|
||||
|
||||
// 清理不再使用的缓存文件
|
||||
cleanObsoleteCache() {
|
||||
const activeUrls = new Set(Object.values(audioFils));
|
||||
const cachedUrls = Object.keys(this.localFileCache);
|
||||
let hasChanges = false;
|
||||
|
||||
for (const url of cachedUrls) {
|
||||
if (!activeUrls.has(url)) {
|
||||
debugLog(`发现废弃音频缓存,正在清理: ${url}`);
|
||||
const path = this.localFileCache[url];
|
||||
// 移除物理文件
|
||||
uni.removeSavedFile({
|
||||
filePath: path,
|
||||
complete: () => {
|
||||
// 忽略移除结果,直接移除记录
|
||||
},
|
||||
});
|
||||
// 移除记录
|
||||
delete this.localFileCache[url];
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasChanges) {
|
||||
uni.setStorageSync("audio_local_files", this.localFileCache);
|
||||
debugLog("废弃缓存清理完成");
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化音频(两阶段:首轮串行加载全部,次轮仅串行加载失败项一次)
|
||||
initAudios() {
|
||||
if (this.isLoading) {
|
||||
@@ -244,7 +277,7 @@ class AudioManager {
|
||||
});
|
||||
}
|
||||
|
||||
// 创建单个音频实例(统一在失败时记录,而非立即重试)
|
||||
// 创建单个音频实例(支持本地缓存)
|
||||
createAudio(key, callback) {
|
||||
this.currentLoadingIndex++;
|
||||
const src = audioFils[key];
|
||||
@@ -287,7 +320,7 @@ class AudioManager {
|
||||
clearTimeout(loadTimeout);
|
||||
this.readyMap.set(key, true);
|
||||
this.failedLoadKeys.delete(key);
|
||||
debugLog(`音频 ${key} 已加载完成`, this.getLoadProgress());
|
||||
// debugLog(`音频 ${key} 已加载完成`, this.getLoadProgress());
|
||||
uni.$emit("audioLoaded", key);
|
||||
const loadedAudioKeys = uni.getStorageSync("loadedAudioKeys") || {};
|
||||
loadedAudioKeys[key] = true;
|
||||
@@ -298,11 +331,20 @@ class AudioManager {
|
||||
audio.onError((res) => {
|
||||
clearTimeout(loadTimeout);
|
||||
debugLog(`音频 ${key} 加载失败:`, res.errMsg);
|
||||
// 如果是本地文件加载失败,可能是文件损坏,清除缓存以便下次重新下载
|
||||
if (realSrc !== src && this.localFileCache[src] === realSrc) {
|
||||
debugLog(`本地缓存失效,移除记录: ${key}`);
|
||||
delete this.localFileCache[src];
|
||||
uni.setStorageSync("audio_local_files", this.localFileCache);
|
||||
// 移除文件
|
||||
uni.removeSavedFile({ filePath: realSrc });
|
||||
}
|
||||
this.recordLoadFailure(key);
|
||||
this.audioMap.delete(key);
|
||||
audio.destroy();
|
||||
if (this.readyMap.get(key)) {
|
||||
this.readyMap.set(key, false);
|
||||
// 这里不要去除,不然检查进度的时候由于没有重新加载而进度卡住,等播放失败的时候会重新加载
|
||||
// this.readyMap.set(key, false);
|
||||
} else {
|
||||
if (callback) callback();
|
||||
}
|
||||
@@ -326,23 +368,72 @@ class AudioManager {
|
||||
this.audioMap.set(key, audio);
|
||||
};
|
||||
|
||||
// 统一先下载到本地再加载
|
||||
uni.downloadFile({
|
||||
url: src,
|
||||
timeout: 20000,
|
||||
success: (res) => {
|
||||
// 成功必须有临时文件路径
|
||||
if (res.tempFilePath) {
|
||||
setupAudio(res.tempFilePath);
|
||||
} else {
|
||||
this.recordLoadFailure(key);
|
||||
if (callback) callback();
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
this.recordLoadFailure(key);
|
||||
if (callback) callback();
|
||||
},
|
||||
// 检查是否有可用的本地缓存
|
||||
this.checkLocalFile(src).then((localPath) => {
|
||||
if (localPath) {
|
||||
debugLog(`命中本地缓存: ${key}`);
|
||||
setupAudio(localPath);
|
||||
} else {
|
||||
console.log("download");
|
||||
// 下载并尝试保存
|
||||
uni.downloadFile({
|
||||
url: src,
|
||||
timeout: 20000,
|
||||
success: (res) => {
|
||||
if (res.tempFilePath) {
|
||||
// 尝试保存文件到本地存储(持久化)
|
||||
uni.saveFile({
|
||||
tempFilePath: res.tempFilePath,
|
||||
success: (saveRes) => {
|
||||
const savedPath = saveRes.savedFilePath;
|
||||
this.localFileCache[src] = savedPath;
|
||||
uni.setStorageSync("audio_local_files", this.localFileCache);
|
||||
debugLog(`音频已缓存到本地: ${key}`);
|
||||
setupAudio(savedPath);
|
||||
},
|
||||
fail: (err) => {
|
||||
debugLog(
|
||||
`保存音频失败(可能空间不足),使用临时文件: ${key}`,
|
||||
err
|
||||
);
|
||||
setupAudio(res.tempFilePath);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.recordLoadFailure(key);
|
||||
if (callback) callback();
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
this.recordLoadFailure(key);
|
||||
if (callback) callback();
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 检查本地文件是否有效
|
||||
checkLocalFile(url) {
|
||||
return new Promise((resolve) => {
|
||||
const path = this.localFileCache[url];
|
||||
if (!path) {
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
// 检查文件是否存在
|
||||
uni.getFileSystemManager().getFileInfo({
|
||||
filePath: path,
|
||||
success: () => {
|
||||
resolve(path);
|
||||
},
|
||||
fail: () => {
|
||||
// 文件不存在,清理记录
|
||||
delete this.localFileCache[url];
|
||||
uni.setStorageSync("audio_local_files", this.localFileCache);
|
||||
resolve(null);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -550,9 +641,28 @@ class AudioManager {
|
||||
return Number((loaded / total).toFixed(2));
|
||||
}
|
||||
|
||||
|
||||
// 清理本地音频缓存文件
|
||||
clearCache() {
|
||||
debugLog("开始清理本地音频缓存...");
|
||||
const cache = uni.getStorageSync("audio_local_files") || {};
|
||||
const paths = Object.values(cache);
|
||||
for (const path of paths) {
|
||||
uni.removeSavedFile({
|
||||
filePath: path,
|
||||
complete: (res) => {
|
||||
// 无论成功失败都继续
|
||||
},
|
||||
});
|
||||
}
|
||||
uni.removeStorageSync("audio_local_files");
|
||||
this.localFileCache = {};
|
||||
debugLog("本地音频缓存清理完成");
|
||||
}
|
||||
|
||||
// 手动重置并重新加载所有音频(用于卡住时恢复)
|
||||
reloadAll() {
|
||||
debugLog("执行 reloadAll: 重置所有状态并重新加载");
|
||||
|
||||
// 1. 停止所有播放
|
||||
this.stopAll();
|
||||
|
||||
@@ -573,6 +683,10 @@ class AudioManager {
|
||||
this.sequenceIndex = 0;
|
||||
this.isSequenceRunning = false;
|
||||
|
||||
// 清理一下可能损坏的缓存(可选,如果用户因为缓存坏了卡住,这一步很有用)
|
||||
// 这里选择不自动全清,而是依赖 onError 里的单点清除。如果需要彻底重置,可取消注释:
|
||||
// this.clearCache();
|
||||
|
||||
// 4. 强制重置加载锁
|
||||
this.isLoading = false;
|
||||
this.loadingPromise = null;
|
||||
|
||||
Reference in New Issue
Block a user