|
|
@@ -206,11 +206,16 @@ export class PlaylistModel {
|
|
|
}
|
|
|
this.currentIndex = Math.max(0, Math.min(currentIndex, songs.length - 1));
|
|
|
this.playedIndices.clear();
|
|
|
- this.playHistory = [];
|
|
|
+
|
|
|
+ // 关键修复:不要清空播放历史缓存,保持随机播放的连续性
|
|
|
+ // this.playHistory = []; // 注释掉这行,保留播放历史
|
|
|
+
|
|
|
+ // 异步重新加载播放历史以确保数据同步
|
|
|
+ this.reloadPlayHistoryFromDatabase();
|
|
|
|
|
|
// 添加验证日志,包含调用源信息
|
|
|
const currentSong = this.getCurrentSong();
|
|
|
- LogUtils.getInstance().LOGI(`PlaylistModel: Playlist replaced with ${songs.length} songs, index ${this.currentIndex}, current song: ${currentSong?.name || 'null'}, caller: ${caller.trim()}`);
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel: Playlist replaced with ${songs.length} songs, index ${this.currentIndex}, current song: ${currentSong?.name || 'null'}, cache preserved: ${this.playHistory.length} records, caller: ${caller.trim()}`);
|
|
|
|
|
|
// 如果播放列表突然变小,记录更详细的信息
|
|
|
if (songs.length <= 20) {
|
|
|
@@ -287,10 +292,16 @@ export class PlaylistModel {
|
|
|
case PlayMode.NORMAL:
|
|
|
return this.currentIndex > 0;
|
|
|
case PlayMode.RANDOM:
|
|
|
- // 随机模式下:基于内存缓存的播放历史记录
|
|
|
+ // 随机模式下:优先使用内存缓存,如果缓存为空则假设有历史记录
|
|
|
+ // 因为真正的检查会在异步的 hasPrevious 方法中进行
|
|
|
const hasValidHistory = this.playHistory.length >= 2;
|
|
|
- LogUtils.getInstance().LOGI(`PlaylistModel.hasPreviousSync: RANDOM mode, cacheHistoryLength=${this.playHistory.length}, hasValidHistory=${hasValidHistory}`);
|
|
|
- return hasValidHistory;
|
|
|
+
|
|
|
+ // 如果内存缓存为空,但我们有播放过歌曲,则假设数据库中有历史记录
|
|
|
+ const assumeHasHistory = this.playHistory.length === 0 && this.currentIndex >= 0;
|
|
|
+
|
|
|
+ const result = hasValidHistory || assumeHasHistory;
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.hasPreviousSync: RANDOM mode, cacheHistoryLength=${this.playHistory.length}, hasValidHistory=${hasValidHistory}, assumeHasHistory=${assumeHasHistory}, result=${result}`);
|
|
|
+ return result;
|
|
|
default:
|
|
|
return false;
|
|
|
}
|
|
|
@@ -315,11 +326,17 @@ export class PlaylistModel {
|
|
|
LogUtils.getInstance().LOGI(`PlaylistModel.hasPrevious: NORMAL mode, currentIndex=${this.currentIndex}, result=${normalResult}`);
|
|
|
return normalResult;
|
|
|
case PlayMode.RANDOM:
|
|
|
- // 随机模式下:从数据库检查播放历史记录
|
|
|
- const dbHistory = await this.loadPlayHistoryFromDatabase();
|
|
|
- const hasValidHistory = dbHistory.length >= 2;
|
|
|
- LogUtils.getInstance().LOGI(`PlaylistModel.hasPrevious: RANDOM mode, dbHistoryLength=${dbHistory.length}, hasValidHistory=${hasValidHistory}`);
|
|
|
- return hasValidHistory;
|
|
|
+ // 随机模式下:优先使用内存缓存,缓存无效时才查询数据库
|
|
|
+ if (this.playHistory.length >= 2) {
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.hasPrevious: RANDOM mode, using cache, historyLength=${this.playHistory.length}`);
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ // 缓存不足,查询数据库
|
|
|
+ const dbHistory = await this.loadPlayHistoryFromDatabase();
|
|
|
+ const hasValidHistory = dbHistory.length >= 2;
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.hasPrevious: RANDOM mode, cache insufficient, dbHistoryLength=${dbHistory.length}, hasValidHistory=${hasValidHistory}`);
|
|
|
+ return hasValidHistory;
|
|
|
+ }
|
|
|
default:
|
|
|
LogUtils.getInstance().LOGI(`PlaylistModel.hasPrevious: Unknown mode, returning false`);
|
|
|
return false;
|
|
|
@@ -528,29 +545,37 @@ export class PlaylistModel {
|
|
|
* 获取随机播放模式下的上一首
|
|
|
*/
|
|
|
private async getRandomPrevious(): Promise<VideoItem | null> {
|
|
|
- // 从数据库加载最新的播放历史
|
|
|
- const dbHistory = await this.loadPlayHistoryFromDatabase();
|
|
|
- LogUtils.getInstance().LOGI(`PlaylistModel.getRandomPrevious: dbHistory.length=${dbHistory.length}, songs.length=${this.songs.length}, currentIndex=${this.currentIndex}`);
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.getRandomPrevious: Starting, cacheLength=${this.playHistory.length}, songsLength=${this.songs.length}, currentIndex=${this.currentIndex}`);
|
|
|
+
|
|
|
+ // 优先使用内存缓存,提高性能
|
|
|
+ let historyToUse = this.playHistory;
|
|
|
+
|
|
|
+ // 如果内存缓存不足,则从数据库加载
|
|
|
+ if (historyToUse.length < 2) {
|
|
|
+ LogUtils.getInstance().LOGI('PlaylistModel.getRandomPrevious: 内存缓存不足,从数据库加载历史记录');
|
|
|
+ historyToUse = await this.loadPlayHistoryFromDatabase();
|
|
|
+ // 同时更新内存缓存
|
|
|
+ this.playHistory = [...historyToUse];
|
|
|
+ }
|
|
|
|
|
|
// 随机播放模式下,上一首必须严格从播放历史记录中获取
|
|
|
- if (dbHistory.length >= 2) {
|
|
|
- // 返回历史记录的倒数第二首(倒数第一首应该是当前播放的)
|
|
|
- const prevSong = dbHistory[dbHistory.length - 2];
|
|
|
- LogUtils.getInstance().LOGI(`PlaylistModel.getRandomPrevious: 从数据库播放历史获取上一首: ${prevSong.name}`);
|
|
|
-
|
|
|
- // 在当前播放列表中查找这首歌曲
|
|
|
- const songIndex = this.songs.findIndex(song => song.filePath === prevSong.filePath);
|
|
|
- if (songIndex !== -1) {
|
|
|
- return this.songs[songIndex];
|
|
|
- } else {
|
|
|
- LogUtils.getInstance().LOGI(`PlaylistModel.getRandomPrevious: 上一首歌曲不在当前播放列表中: ${prevSong.name}`);
|
|
|
- return null;
|
|
|
+ if (historyToUse.length >= 2) {
|
|
|
+ for (let i = 0; i < historyToUse.length; i++) {
|
|
|
+ const prevSong = historyToUse[i];
|
|
|
+
|
|
|
+ // 在当前播放列表中查找这首歌曲
|
|
|
+ const songIndex = this.songs.findIndex(song => song.filePath === prevSong.filePath);
|
|
|
+ if (songIndex !== -1) {
|
|
|
+ return this.songs[songIndex];
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ LogUtils.getInstance().LOGI('PlaylistModel.getRandomPrevious: 历史记录中没有找到在当前播放列表中的歌曲');
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
// 如果播放历史记录不足,则没有真正的"上一首"
|
|
|
- // 在随机播放模式下,不应该随机选择一首歌曲作为上一首
|
|
|
- LogUtils.getInstance().LOGI('PlaylistModel.getRandomPrevious: 数据库播放历史记录不足,无法提供真正的上一首歌曲');
|
|
|
+ LogUtils.getInstance().LOGI('PlaylistModel.getRandomPrevious: 播放历史记录不足,无法提供真正的上一首歌曲');
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
@@ -565,6 +590,20 @@ export class PlaylistModel {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 从数据库重新加载播放历史到内存缓存
|
|
|
+ */
|
|
|
+ private async reloadPlayHistoryFromDatabase(): Promise<void> {
|
|
|
+ try {
|
|
|
+ const dbHistory = await this.loadPlayHistoryFromDatabase();
|
|
|
+ this.playHistory = [...dbHistory]; // 重新填充内存缓存
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.reloadPlayHistoryFromDatabase: Reloaded ${dbHistory.length} records to cache`);
|
|
|
+ } catch (error) {
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.reloadPlayHistoryFromDatabase: Error reloading history - ${error}`);
|
|
|
+ this.playHistory = []; // 发生错误时清空缓存
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 保存歌曲到数据库播放历史
|
|
|
*/
|
|
|
@@ -633,22 +672,28 @@ export class PlaylistModel {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 从数据库加载最新的播放历史
|
|
|
- const dbHistory = await this.loadPlayHistoryFromDatabase();
|
|
|
+ // 优先检查内存缓存
|
|
|
+ const isInMemoryHistory = this.playHistory.some(song => song.filePath === currentSong.filePath);
|
|
|
|
|
|
- // 检查当前歌曲是否已经在数据库播放历史中
|
|
|
+ if (isInMemoryHistory) {
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.ensureCurrentSongInHistory: 当前歌曲已在内存缓存中: ${currentSong.name}`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 内存缓存中没有,检查数据库
|
|
|
+ const dbHistory = await this.loadPlayHistoryFromDatabase();
|
|
|
const isInDbHistory = dbHistory.some(song => song.filePath === currentSong.filePath);
|
|
|
|
|
|
if (!isInDbHistory) {
|
|
|
// 如果不在数据库历史中,则保存当前歌曲
|
|
|
this.saveToPlayHistory(currentSong);
|
|
|
- LogUtils.getInstance().LOGI(`PlaylistModel.ensureCurrentSongInHistory: 保存当前歌曲到数据库播放历史: ${currentSong.name}`);
|
|
|
+ this.addToPlayHistory(currentSong); // 同时添加到内存缓存
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.ensureCurrentSongInHistory: 保存当前歌曲到数据库和内存: ${currentSong.name}`);
|
|
|
} else {
|
|
|
- LogUtils.getInstance().LOGI(`PlaylistModel.ensureCurrentSongInHistory: 当前歌曲已在数据库播放历史中: ${currentSong.name}`);
|
|
|
+ // 如果在数据库中但不在内存缓存中,更新内存缓存
|
|
|
+ this.playHistory = [...dbHistory];
|
|
|
+ LogUtils.getInstance().LOGI(`PlaylistModel.ensureCurrentSongInHistory: 当前歌曲已在数据库中,更新内存缓存: ${currentSong.name}`);
|
|
|
}
|
|
|
-
|
|
|
- // 更新内存中的播放历史缓存
|
|
|
- this.playHistory = dbHistory.slice(); // 创建副本
|
|
|
|
|
|
LogUtils.getInstance().LOGI(`PlaylistModel.ensureCurrentSongInHistory: 播放历史长度: ${this.playHistory.length}`);
|
|
|
}
|