| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071 |
- import { VideoItem } from '../../viewmodel/VideoItem';
- import { PlayerState, PlayMode } from './PlayerStateModel';
- import { PreferencesUtil } from '@pura/harmony-utils';
- import { common } from '@kit.AbilityKit';
- /**
- * 存储键名接口
- */
- interface StorageKeys {
- PLAYLIST: string;
- PLAYER_STATE: string;
- PROGRESS_PREFIX: string;
- COMPLETED_SONGS: string;
- }
- /**
- * 播放进度数据接口
- */
- export interface PlaybackProgress {
- songId: string;
- filePath: string;
- position: number;
- duration: number;
- timestamp: number;
- completed: boolean;
- }
- /**
- * 播放列表数据接口
- */
- export interface PlaylistData {
- songs: VideoItem[];
- currentIndex: number;
- playMode: PlayMode;
- timestamp: number;
- }
- /**
- * 播放状态数据接口
- */
- export interface PlayerStateData {
- isPlaying: boolean;
- isPaused: boolean;
- currentIndex: number;
- playMode: PlayMode;
- volume: number;
- speed: number;
- timestamp: number;
- }
- /**
- * 数据统计信息接口
- */
- export interface DataStats {
- playlistSize: number;
- progressRecords: number;
- completedSongs: number;
- lastUpdate: number;
- }
- /**
- * 同步状态接口
- */
- export interface SyncStatus {
- autoSyncEnabled: boolean;
- lastSyncTimestamp: number;
- syncInterval: number;
- }
- /**
- * 数据持久化服务接口
- */
- export interface IDataPersistenceService {
- // 播放进度相关
- savePlaybackProgress(songId: string, filePath: string, position: number, duration: number): Promise<void>;
- loadPlaybackProgress(songId: string): Promise<PlaybackProgress | null>;
- clearPlaybackProgress(songId: string): Promise<void>;
- clearCompletedProgress(): Promise<void>;
- // 播放列表相关
- savePlaylist(playlist: VideoItem[], currentIndex: number, playMode: PlayMode): Promise<void>;
- loadPlaylist(): Promise<PlaylistData | null>;
- // 播放状态相关
- savePlayerState(state: PlayerState): Promise<void>;
- loadPlayerState(): Promise<PlayerStateData | null>;
- // 初始化和清理
- initialize(context: common.UIAbilityContext): Promise<void>;
- reinitialize(context: common.UIAbilityContext): Promise<void>;
- isContextValid(): boolean;
- clearAllData(): Promise<void>;
- }
- /**
- * 数据持久化服务实现
- * 处理播放列表、播放状态和播放进度的持久化存储
- */
- export class DataPersistenceService implements IDataPersistenceService {
- private static instance: DataPersistenceService | null = null;
- private context: common.UIAbilityContext | null = null;
- private isInitialized: boolean = false;
- // 存储键名常量
- private static readonly KEYS: StorageKeys = {
- PLAYLIST: 'player_playlist',
- PLAYER_STATE: 'player_state',
- PROGRESS_PREFIX: 'playback_progress_',
- COMPLETED_SONGS: 'completed_songs'
- };
- // 播放完成阈值(5秒)
- private static readonly COMPLETION_THRESHOLD = 5000;
- private constructor() {
-
- }
- public static getInstance(): DataPersistenceService {
- if (!DataPersistenceService.instance) {
- DataPersistenceService.instance = new DataPersistenceService();
- }
- return DataPersistenceService.instance;
- }
- async initialize(context: common.UIAbilityContext): Promise<void> {
- if (this.isInitialized && this.context) {
-
-
- return;
- }
- try {
- // 验证context是否有效
- if (!context) {
-
- throw new Error('Context is null');
- }
- this.context = context;
- this.isInitialized = true;
-
-
- } catch (error) {
-
-
- throw new Error;
- }
- }
- /**
- * 重新初始化context(用于context失效后的恢复)
- */
- async reinitialize(context: common.UIAbilityContext): Promise<void> {
-
-
- try {
- if (!context) {
-
- throw new Error('Context is null');
- }
- this.context = context;
- this.isInitialized = true;
-
-
- } catch (error) {
-
-
- throw new Error;
- }
- }
- /**
- * 检查context是否有效
- */
- isContextValid(): boolean {
- return this.isInitialized && this.context !== null;
- }
- // ==================== 播放进度记忆功能实现 ====================
- /**
- * 保存播放进度
- * 实现播放位置的自动保存机制
- */
- async savePlaybackProgress(songId: string, filePath: string, position: number, duration: number): Promise<void> {
- try {
- if (!this.isInitialized) {
- throw new Error('DataPersistenceService not initialized');
- }
- // 检查是否接近播放完成
- const isCompleted = duration > 0 && (duration - position) < DataPersistenceService.COMPLETION_THRESHOLD;
- const progressData: PlaybackProgress = {
- songId,
- filePath,
- position: isCompleted ? 0 : position, // 播放完成时保存为0
- duration,
- timestamp: Date.now(),
- completed: isCompleted
- };
- const key = DataPersistenceService.KEYS.PROGRESS_PREFIX + songId;
- // 首先保存到AppStorage以便快速访问
- AppStorage.setOrCreate(key, progressData);
- // 如果context有效,尝试保存到PreferencesUtil
- if (this.context) {
- try {
- PreferencesUtil.putSync(key, JSON.stringify(progressData));
- } catch (error) {
-
-
- // 即使PreferencesUtil失败,AppStorage已保存,不抛出异常
- }
- }
- // 如果播放完成,添加到已完成列表
- if (isCompleted) {
- await this.addToCompletedSongs(songId);
- }
-
- } catch (error) {
-
- throw new Error;
- }
- }
- /**
- * 加载播放进度
- * 实现应用重启后的播放位置恢复
- */
- async loadPlaybackProgress(songId: string): Promise<PlaybackProgress | null> {
- try {
- if (!this.isInitialized) {
- throw new Error('DataPersistenceService not initialized');
- }
- const key = DataPersistenceService.KEYS.PROGRESS_PREFIX + songId;
- // 优先从AppStorage获取(内存中的数据)
- let progressData = AppStorage.get<PlaybackProgress>(key);
- if (!progressData && this.context) {
- // 从PreferencesUtil获取持久化数据,增加重试机制
- const maxRetries = 2;
- let retryCount = 0;
- while (retryCount < maxRetries) {
- try {
- const progressStr = PreferencesUtil.getStringSync(key, '');
- if (progressStr) {
- try {
- const parsedData = JSON.parse(progressStr) as PlaybackProgress;
- progressData = parsedData;
- // 同步到AppStorage
- AppStorage.setOrCreate(key, progressData);
- break; // 成功,跳出循环
- } catch (parseError) {
-
- return null;
- }
- } else {
- break; // 没有数据
- }
- } catch (preferencesError) {
-
-
- if (preferencesError.toString().includes('context is invalid') && retryCount < maxRetries - 1) {
- await new Promise<void>(resolve => setTimeout(resolve, 50));
- } else {
- break;
- }
-
- retryCount++;
- }
- }
- }
- if (progressData) {
-
- return progressData;
- }
- return null;
- } catch (error) {
-
- return null;
- }
- }
- /**
- * 清除播放进度
- * 添加播放完成时的进度清理逻辑
- */
- async clearPlaybackProgress(songId: string): Promise<void> {
- try {
- if (!this.isInitialized) {
- throw new Error('DataPersistenceService not initialized');
- }
- const key = DataPersistenceService.KEYS.PROGRESS_PREFIX + songId;
- // 从PreferencesUtil删除
- PreferencesUtil.deleteSync(key);
- // 从AppStorage删除
- AppStorage.delete(key);
-
- } catch (error) {
-
- throw new Error;
- }
- }
- /**
- * 清理已完成播放的进度记录
- */
- async clearCompletedProgress(): Promise<void> {
- try {
- if (!this.isInitialized) {
- throw new Error('DataPersistenceService not initialized');
- }
- // 获取已完成的歌曲列表
- const completedSongs = await this.getCompletedSongs();
- // 清理每个已完成歌曲的进度记录
- for (const songId of completedSongs) {
- await this.clearPlaybackProgress(songId);
- }
- // 清空已完成列表
- PreferencesUtil.deleteSync(DataPersistenceService.KEYS.COMPLETED_SONGS);
- AppStorage.delete(DataPersistenceService.KEYS.COMPLETED_SONGS);
-
- } catch (error) {
-
- throw new Error;
- }
- }
- /**
- * 添加歌曲到已完成列表
- */
- private async addToCompletedSongs(songId: string): Promise<void> {
- try {
- const completedSongs = await this.getCompletedSongs();
- if (!completedSongs.includes(songId)) {
- completedSongs.push(songId);
- PreferencesUtil.putSync(DataPersistenceService.KEYS.COMPLETED_SONGS, JSON.stringify(completedSongs));
- AppStorage.setOrCreate(DataPersistenceService.KEYS.COMPLETED_SONGS, completedSongs);
- }
- } catch (error) {
-
- }
- }
- /**
- * 获取已完成播放的歌曲列表
- */
- private async getCompletedSongs(): Promise<string[]> {
- try {
- // 优先从AppStorage获取
- let completedSongs = AppStorage.get<string[]>(DataPersistenceService.KEYS.COMPLETED_SONGS);
- if (!completedSongs) {
- // 从PreferencesUtil获取
- const completedStr = PreferencesUtil.getStringSync(DataPersistenceService.KEYS.COMPLETED_SONGS, '[]');
- try {
- const parsedData = JSON.parse(completedStr) as string[];
- completedSongs = parsedData;
- AppStorage.setOrCreate(DataPersistenceService.KEYS.COMPLETED_SONGS, completedSongs);
- } catch (parseError) {
-
- completedSongs = [];
- }
- }
- return completedSongs || [];
- } catch (error) {
-
- return [];
- }
- }
- // ==================== 播放列表持久化功能实现 ====================
- /**
- * 保存播放列表
- */
- async savePlaylist(playlist: VideoItem[], currentIndex: number, playMode: PlayMode): Promise<void> {
- try {
- if (!this.isInitialized) {
-
- throw new Error('DataPersistenceService not initialized');
- }
- const playlistData: PlaylistData = {
- songs: playlist,
- currentIndex,
- playMode,
- timestamp: Date.now()
- };
- // 首先保存到AppStorage(确保内存中有数据)
- AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYLIST, playlistData);
-
- // 如果context有效,尝试保存到PreferencesUtil
- if (this.context) {
- const maxRetries = 3;
- let retryCount = 0;
- let lastError: Error | null = null;
- while (retryCount < maxRetries) {
- try {
- PreferencesUtil.putSync(DataPersistenceService.KEYS.PLAYLIST, JSON.stringify(playlistData));
-
- break; // 成功,跳出循环
- } catch (error) {
- lastError = error;
-
-
- if (error.toString().includes('context is invalid')) {
-
- await new Promise<void>(resolve => setTimeout(resolve, 100 * (retryCount + 1)));
- } else {
- // 其他错误,不重试
- break;
- }
-
- retryCount++;
- }
- }
- if (retryCount >= maxRetries && lastError) {
-
-
- }
- } else {
-
- }
-
- } catch (error) {
-
-
- throw new Error;
- }
- }
- /**
- * 加载播放列表
- */
- async loadPlaylist(): Promise<PlaylistData | null> {
- try {
- if (!this.isInitialized) {
-
- throw new Error('DataPersistenceService not initialized');
- }
- // 优先从AppStorage获取
- let playlistData = AppStorage.get<PlaylistData>(DataPersistenceService.KEYS.PLAYLIST);
- if (!playlistData) {
- // 检查context是否有效
- if (!this.context) {
-
- return null;
- }
- // 从PreferencesUtil获取,增加重试机制
-
- const maxRetries = 3;
- let retryCount = 0;
- let lastError: Error | null = null;
- while (retryCount < maxRetries) {
- try {
- const playlistStr = PreferencesUtil.getStringSync(DataPersistenceService.KEYS.PLAYLIST, '');
-
- if (playlistStr) {
- try {
- const parsedData = JSON.parse(playlistStr) as PlaylistData;
- playlistData = parsedData;
-
- // 同步到AppStorage
- AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYLIST, playlistData);
- break; // 成功,跳出循环
- } catch (parseError) {
-
-
- return null;
- }
- } else {
- // 空字符串,没有数据
- break;
- }
- } catch (preferencesError) {
- lastError = preferencesError;
-
-
- // 如果是context无效错误,增加等待时间
- if (preferencesError.toString().includes('context is invalid')) {
-
- await new Promise<void>(resolve => setTimeout(resolve, 100 * (retryCount + 1)));
- } else {
- // 其他错误,不重试
- break;
- }
-
- retryCount++;
- }
- }
- // 如果所有重试都失败了
- if (retryCount >= maxRetries && lastError) {
-
- return null;
- }
- }
- if (playlistData) {
-
- return playlistData;
- }
-
- return null;
- } catch (error) {
-
- return null;
- }
- }
- // ==================== 播放状态持久化功能实现 ====================
- /**
- * 保存播放状态
- */
- async savePlayerState(state: PlayerState): Promise<void> {
- try {
- if (!this.isInitialized) {
-
- throw new Error('DataPersistenceService not initialized');
- }
- const stateData: PlayerStateData = {
- isPlaying: state.isPlaying,
- isPaused: state.isPaused,
- currentIndex: state.currentIndex,
- playMode: state.playMode,
- volume: state.volume,
- speed: state.speed,
- timestamp: Date.now()
- };
- // 首先保存到AppStorage(确保内存中有数据)
- AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYER_STATE, stateData);
- // 如果context有效,尝试保存到PreferencesUtil
- if (this.context) {
- const maxRetries = 3;
- let retryCount = 0;
- let lastError: Error | null = null;
- while (retryCount < maxRetries) {
- try {
- PreferencesUtil.putSync(DataPersistenceService.KEYS.PLAYER_STATE, JSON.stringify(stateData));
- break; // 成功,跳出循环
- } catch (error) {
- lastError = error;
-
-
- if (error.toString().includes('context is invalid')) {
-
- await new Promise<void>(resolve => setTimeout(resolve, 100 * (retryCount + 1)));
- } else {
- // 其他错误,不重试
- break;
- }
-
- retryCount++;
- }
- }
- if (retryCount >= maxRetries && lastError) {
-
-
- }
- } else {
-
- }
-
- } catch (error) {
-
-
- throw new Error;
- }
- }
- /**
- * 加载播放状态
- */
- async loadPlayerState(): Promise<PlayerStateData | null> {
- try {
- if (!this.isInitialized) {
-
- throw new Error('DataPersistenceService not initialized');
- }
-
- // 优先从AppStorage获取
- let stateData = AppStorage.get<PlayerStateData>(DataPersistenceService.KEYS.PLAYER_STATE);
- if (!stateData) {
- // 检查context是否有效
- if (!this.context) {
-
- return null;
- }
- // 从PreferencesUtil获取,增加重试机制
-
- const maxRetries = 3;
- let retryCount = 0;
- let lastError: Error | null = null;
- while (retryCount < maxRetries) {
- try {
- const stateStr = PreferencesUtil.getStringSync(DataPersistenceService.KEYS.PLAYER_STATE, '');
-
- if (stateStr) {
- try {
- const parsedData = JSON.parse(stateStr) as PlayerStateData;
- stateData = parsedData;
-
- // 同步到AppStorage
- AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYER_STATE, stateData);
- break; // 成功,跳出循环
- } catch (parseError) {
-
-
- return null;
- }
- } else {
- // 空字符串,没有数据
- break;
- }
- } catch (preferencesError) {
- lastError = preferencesError;
-
-
- // 如果是context无效错误,增加等待时间
- if (preferencesError.toString().includes('context is invalid')) {
-
- await new Promise<void>(resolve => setTimeout(resolve, 100 * (retryCount + 1)));
- } else {
- // 其他错误,不重试
- break;
- }
-
- retryCount++;
- }
- }
- // 如果所有重试都失败了
- if (retryCount >= maxRetries && lastError) {
-
- return null;
- }
- }
- if (stateData) {
- return stateData;
- }
-
- return null;
- } catch (error) {
-
-
- return null;
- }
- }
- // ==================== 数据清理和维护功能 ====================
- /**
- * 清除所有持久化数据
- */
- async clearAllData(): Promise<void> {
- try {
- if (!this.isInitialized) {
- throw new Error('DataPersistenceService not initialized');
- }
- // 清除播放列表
- PreferencesUtil.deleteSync(DataPersistenceService.KEYS.PLAYLIST);
- AppStorage.delete(DataPersistenceService.KEYS.PLAYLIST);
- // 清除播放状态
- PreferencesUtil.deleteSync(DataPersistenceService.KEYS.PLAYER_STATE);
- AppStorage.delete(DataPersistenceService.KEYS.PLAYER_STATE);
- // 清除所有播放进度
- await this.clearCompletedProgress();
-
- } catch (error) {
-
- throw new Error;
- }
- }
- /**
- * 数据同步检查
- * 确保AppStorage和PreferencesUtil数据一致性
- */
- async syncData(): Promise<void> {
- try {
- if (!this.isInitialized) {
- return;
- }
- // 同步播放列表数据
- const playlistData = await this.loadPlaylist();
- if (playlistData) {
- AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYLIST, playlistData);
- }
- // 同步播放状态数据
- const stateData = await this.loadPlayerState();
- if (stateData) {
- AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYER_STATE, stateData);
- }
-
- } catch (error) {
-
- }
- }
- /**
- * 获取数据统计信息
- */
- async getDataStats(): Promise<DataStats> {
- try {
- const playlistData = await this.loadPlaylist();
- const completedSongs = await this.getCompletedSongs();
- const stats: DataStats = {
- playlistSize: playlistData?.songs.length || 0,
- progressRecords: 0, // 这里可以扩展统计所有进度记录
- completedSongs: completedSongs.length,
- lastUpdate: Math.max(
- playlistData?.timestamp || 0,
- (await this.loadPlayerState())?.timestamp || 0
- )
- };
- return stats;
- } catch (error) {
-
- const errorStats: DataStats = {
- playlistSize: 0,
- progressRecords: 0,
- completedSongs: 0,
- lastUpdate: 0
- };
- return errorStats;
- }
- }
- }
- /**
- * 播放列表同步服务
- * 实现与PreferencesUtil的数据同步和数据变化监听
- */
- export class PlaylistSyncService {
- private static instance: PlaylistSyncService | null = null;
- private dataPersistence: DataPersistenceService;
- private syncListeners: Set<PlaylistSyncListener> = new Set();
- private autoSyncEnabled: boolean = true;
- private syncTimer: number = -1;
- private lastSyncTimestamp: number = 0;
- // 同步间隔(毫秒)
- private static readonly SYNC_INTERVAL = 5000; // 5秒
- private constructor() {
- this.dataPersistence = DataPersistenceService.getInstance();
-
- }
- public static getInstance(): PlaylistSyncService {
- if (!PlaylistSyncService.instance) {
- PlaylistSyncService.instance = new PlaylistSyncService();
- }
- return PlaylistSyncService.instance;
- }
- /**
- * 初始化同步服务
- */
- async initialize(context: common.UIAbilityContext): Promise<void> {
- try {
- await this.dataPersistence.initialize(context);
- if (this.autoSyncEnabled) {
- this.startAutoSync();
- }
-
- } catch (error) {
-
- throw new Error;
- }
- }
- /**
- * 同步播放列表到持久化存储
- * 确保与LocalMusic的播放列表数据一致性
- */
- async syncPlaylistToStorage(playlist: VideoItem[], currentIndex: number, playMode: PlayMode): Promise<void> {
- try {
- // 保存到持久化存储
- await this.dataPersistence.savePlaylist(playlist, currentIndex, playMode);
- // 更新同步时间戳
- this.lastSyncTimestamp = Date.now();
- // 通知监听器
- this.notifyPlaylistSynced(playlist, currentIndex, playMode);
-
- } catch (error) {
-
- throw new Error;
- }
- }
- /**
- * 从持久化存储同步播放列表
- */
- async syncPlaylistFromStorage(): Promise<PlaylistData | null> {
- try {
- const playlistData = await this.dataPersistence.loadPlaylist();
- if (playlistData) {
- // 通知监听器
- this.notifyPlaylistLoaded(playlistData);
-
- }
- return playlistData;
- } catch (error) {
-
- return null;
- }
- }
- /**
- * 双向同步播放列表
- * 比较本地和存储中的数据,选择最新的版本
- */
- async bidirectionalSync(localPlaylist: VideoItem[], localIndex: number, localPlayMode: PlayMode): Promise<PlaylistData> {
- try {
- const storedData = await this.dataPersistence.loadPlaylist();
- // 如果没有存储的数据,使用本地数据
- if (!storedData) {
- await this.syncPlaylistToStorage(localPlaylist, localIndex, localPlayMode);
- return {
- songs: localPlaylist,
- currentIndex: localIndex,
- playMode: localPlayMode,
- timestamp: Date.now()
- };
- }
- // 比较时间戳,使用更新的数据
- const localTimestamp = this.lastSyncTimestamp || Date.now();
- if (storedData.timestamp > localTimestamp) {
- // 存储的数据更新,使用存储的数据
-
- return storedData;
- } else {
- // 本地数据更新,同步到存储
- await this.syncPlaylistToStorage(localPlaylist, localIndex, localPlayMode);
-
- return {
- songs: localPlaylist,
- currentIndex: localIndex,
- playMode: localPlayMode,
- timestamp: Date.now()
- };
- }
- } catch (error) {
-
- // 出错时返回本地数据
- return {
- songs: localPlaylist,
- currentIndex: localIndex,
- playMode: localPlayMode,
- timestamp: Date.now()
- };
- }
- }
- /**
- * 启动自动同步
- */
- startAutoSync(): void {
- if (this.syncTimer !== -1) {
- return; // 已经启动
- }
- this.syncTimer = setInterval(async () => {
- try {
- await this.performAutoSync();
- } catch (error) {
-
- }
- }, PlaylistSyncService.SYNC_INTERVAL);
-
- }
- /**
- * 停止自动同步
- */
- stopAutoSync(): void {
- if (this.syncTimer !== -1) {
- clearInterval(this.syncTimer);
- this.syncTimer = -1;
-
- }
- }
- /**
- * 执行自动同步
- */
- private async performAutoSync(): Promise<void> {
- try {
- // 检查数据一致性
- await this.dataPersistence.syncData();
- // 通知监听器执行同步检查
- this.notifyAutoSyncPerformed();
- } catch (error) {
-
- }
- }
- /**
- * 设置自动同步开关
- */
- setAutoSyncEnabled(enabled: boolean): void {
- this.autoSyncEnabled = enabled;
- if (enabled) {
- this.startAutoSync();
- } else {
- this.stopAutoSync();
- }
-
- }
- /**
- * 添加同步监听器
- */
- addSyncListener(listener: PlaylistSyncListener): void {
- this.syncListeners.add(listener);
-
- }
- /**
- * 移除同步监听器
- */
- removeSyncListener(listener: PlaylistSyncListener): void {
- this.syncListeners.delete(listener);
-
- }
- /**
- * 通知播放列表已同步到存储
- */
- private notifyPlaylistSynced(playlist: VideoItem[], currentIndex: number, playMode: PlayMode): void {
- this.syncListeners.forEach(listener => {
- try {
- listener.onPlaylistSynced?.(playlist, currentIndex, playMode);
- } catch (error) {
-
- }
- });
- }
- /**
- * 通知播放列表已从存储加载
- */
- private notifyPlaylistLoaded(playlistData: PlaylistData): void {
- this.syncListeners.forEach(listener => {
- try {
- listener.onPlaylistLoaded?.(playlistData);
- } catch (error) {
-
- }
- });
- }
- /**
- * 通知自动同步已执行
- */
- private notifyAutoSyncPerformed(): void {
- this.syncListeners.forEach(listener => {
- try {
- listener.onAutoSyncPerformed?.();
- } catch (error) {
-
- }
- });
- }
- /**
- * 获取同步状态
- */
- getSyncStatus(): SyncStatus {
- const status: SyncStatus = {
- autoSyncEnabled: this.autoSyncEnabled,
- lastSyncTimestamp: this.lastSyncTimestamp,
- syncInterval: PlaylistSyncService.SYNC_INTERVAL
- };
- return status;
- }
- /**
- * 清理资源
- */
- release(): void {
- this.stopAutoSync();
- this.syncListeners.clear();
-
- }
- }
- /**
- * 播放列表同步监听器接口
- */
- export interface PlaylistSyncListener {
- onPlaylistSynced?(playlist: VideoItem[], currentIndex: number, playMode: PlayMode): void;
- onPlaylistLoaded?(playlistData: PlaylistData): void;
- onAutoSyncPerformed?(): void;
- onSyncError?(error: Error): void;
- }
|