Bläddra i källkod

卡片交互由message改为call

chendeben 1 år sedan
förälder
incheckning
56eeadeafe

+ 1568 - 0
entry/src/main/ets/common/service/IndependentPlayerService.ets

@@ -0,0 +1,1568 @@
+/**
+ * 独立播放器服务
+ * 在EntryAbility中直接控制音频播放,不依赖LocalMusic
+ */
+
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { emitter } from '@kit.BasicServicesKit';
+import { common } from '@kit.AbilityKit';
+import { fileIo } from '@kit.CoreFileKit';
+import commonEventManager from '@ohos.commonEventManager';
+import { PLAYER_STATE_CHANGED_EVENT, PLAYER_SONG_CHANGED_EVENT } from '../widget/WidgetEventConstants';
+import { VideoItem } from '../../viewmodel/VideoItem';
+import { AppUtil, PreferencesUtil } from '@pura/harmony-utils';
+import { 
+  IjkMediaPlayer, 
+  InterruptEvent, 
+  InterruptHintType,
+  OnPreparedListener,
+  OnCompletionListener,
+  OnErrorListener,
+  LogUtils
+} from '@ohos/ijkplayer';
+import { WidgetData, PlayState as WidgetPlayState, SongInfo, PlayProgress, PlaylistState, WidgetConfig } from '../widget/WidgetTypes';
+
+/**
+ * 播放状态数据接口
+ */
+interface SavedPlaybackState {
+  isPlaying: boolean;
+  isPaused: boolean;
+  currentPosition: number;
+  duration: number;
+  timestamp: number;
+}
+
+const TAG = 'IndependentPlayerService';
+
+// 为了兼容性,定义一些本地使用的接口
+interface PlayState {
+  isPlaying: boolean;
+  isPaused: boolean;
+  isLoading: boolean;
+  currentPosition: number;
+  duration: number;
+}
+
+interface SongData {
+  id: string;
+  title: string;
+  artist: string;
+  album: string;
+  filePath: string;
+  duration: number;
+}
+
+interface ProgressData {
+  currentPosition: number;
+  duration: number;
+  percentage: number;
+  currentTimeText: string;
+  totalTimeText: string;
+}
+
+interface PlaylistInfo {
+  hasNext: boolean;
+  hasPrevious: boolean;
+  currentIndex: number;
+  totalCount: number;
+}
+
+interface PlayerStateData {
+  playState: PlayState;
+  currentSong: SongData;
+  progress: ProgressData;
+  playlist: PlaylistInfo;
+}
+
+interface SongChangeData {
+  currentSong: SongData;
+  playlist: PlaylistInfo;
+}
+
+interface PlayerCurrentState {
+  playState: PlayState;
+  currentSong: VideoItem | null;
+  playlist: VideoItem[];
+}
+
+interface DirectFormUpdateServiceInstance {
+  updateAllForms(data: WidgetData): Promise<void>;
+}
+
+interface DirectFormUpdateServiceClass {
+  getInstance(): DirectFormUpdateServiceInstance;
+}
+
+interface DirectFormUpdateServiceModule {
+  DirectFormUpdateService: DirectFormUpdateServiceClass;
+}
+
+/**
+ * 独立播放器服务
+ * 提供基本的音频播放控制功能,独立于LocalMusic运行
+ * 直接从PreferencesUtil获取播放列表数据,与LocalMusic保持一致
+ */
+export class IndependentPlayerService {
+  private static instance: IndependentPlayerService;
+  private ijkPlayer: IjkMediaPlayer | null = null;
+  private currentSong: VideoItem | null = null;
+  private playState: PlayState = {
+    isPlaying: false,
+    isPaused: false, // 初始状态设为未暂停,避免误判为可恢复播放
+    isLoading: false,
+    currentPosition: 0,
+    duration: 0
+  };
+  private playlist: VideoItem[] = [];
+  private currentIndex: number = 0;
+  private isInitialized: boolean = false;
+  private context: common.UIAbilityContext | null = null;
+  private retryCount: number = 0;
+  private maxRetries: number = 3;
+  private updateProgressTimer: number = 0; // 进度更新定时器
+  private lastProgressBroadcastTime: number = 0; // 上次进度广播时间
+  private readonly PROGRESS_BROADCAST_INTERVAL: number = 1000; // 进度广播间隔(1秒)
+  private lastStateBroadcastTime: number = 0; // 上次状态广播时间
+  private readonly STATE_BROADCAST_INTERVAL: number = 500; // 状态广播间隔(0.5秒)
+  savedDuration: number = 0; // 保存的歌曲时长
+
+  private constructor() {}
+
+  static getInstance(): IndependentPlayerService {
+    if (!IndependentPlayerService.instance) {
+      IndependentPlayerService.instance = new IndependentPlayerService();
+    }
+    return IndependentPlayerService.instance;
+  }
+
+  /**
+   * 初始化服务
+   */
+  async initialize(context: common.UIAbilityContext): Promise<void> {
+    if (this.isInitialized) {
+      hilog.info(0x0000, TAG, 'Service already initialized');
+      return;
+    }
+
+    try {
+      this.context = context;
+      AppUtil.init(this.context);
+      // 直接从PreferencesUtil获取播放列表数据,与LocalMusic保持一致
+      this.loadFromAppStorage();
+      
+      // 创建音频播放器
+      await this.createAudioPlayer();
+      
+      // 注册卡片控制事件监听器
+      this.registerWidgetControlListener();
+      
+      // 注册数据变化监听器,实时同步PreferencesUtil数据
+      this.registerAppStorageListener();
+      
+      this.isInitialized = true;
+      hilog.info(0x0000, TAG, `✅ IndependentPlayerService initialized with ${this.playlist.length} songs`);
+      
+      // 延迟广播初始状态
+      setTimeout(() => {
+        this.broadcastPlayerState();
+      }, 1000);
+      
+    } catch (error) {
+      hilog.error(0x0000, TAG, `❌ Failed to initialize IndependentPlayerService: ${error}`);
+    }
+  }
+
+  /**
+   * 创建音频播放器
+   */
+  private async createAudioPlayer(): Promise<void> {
+    try {
+      hilog.info(0x0000, TAG, 'Creating IjkMediaPlayer instance');
+
+      this.ijkPlayer = IjkMediaPlayer.getInstance();
+
+      hilog.info(0x0000, TAG, 'IjkPlayer audioId set to: independentPlayer');
+      
+      // 设置音频中断处理
+      this.setupAudioInterruptHandler();
+      
+      // 设置播放器回调
+      this.setupPlayerCallbacks();
+      
+      hilog.info(0x0000, TAG, 'IjkMediaPlayer created and configured successfully');
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to create IjkMediaPlayer: ${error}`);
+      throw new Error(`Failed to create IjkMediaPlayer: ${error}`);
+    }
+  }
+
+  /**
+   * 配置IjkPlayer选项(完全参考LocalMusic的配置)
+   */
+  private setupIjkPlayerOptions(): void {
+    if (!this.ijkPlayer) return;
+    
+    // 设置调试模式
+    this.ijkPlayer.setDebug(false);
+    
+    // 初始化配置
+    this.ijkPlayer.native_setup();
+    
+    // 设置音量(纯音频播放)
+    this.ijkPlayer.setVolume('1.0', '1.0');
+    
+    // 使用精确寻帧
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", "1");
+    
+    // 动态缓冲区大小配置(参考LocalMusic)
+    let bufferSize = 1 * 1024 * 1024; // 默认1MB缓冲区
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", bufferSize.toString());
+    
+    // 重连模式
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "reconnect", "1");
+    
+    // 缓冲帧数设置
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", "100");
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-frames", "1000");
+    
+    // 启动预加载
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", "1");
+    
+    // 设置无缓冲
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", "0");
+    
+    // 跳帧处理
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", "5");
+    
+    // 最大缓冲cache
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", "3000");
+    
+    // 无限制收流
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", "1");
+    this.ijkPlayer.setOptionLong(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", "1");
+    
+    // 屏幕常亮(音频播放也保持)
+    this.ijkPlayer.setScreenOnWhilePlaying(true);
+    
+    // 设置超时
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", "10000000");
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "connect_timeout", "10000000");
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "addrinfo_timeout", "10000000");
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_timeout", "10000000");
+    
+    // 变速播放支持
+    this.ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", "1");
+    this.ijkPlayer.setSpeed('1.0f');
+    
+    hilog.info(0x0000, TAG, 'IjkPlayer options configured with LocalMusic settings');
+  }
+
+  /**
+   * 设置音频中断处理
+   */
+  private setupAudioInterruptHandler(): void {
+    if (!this.ijkPlayer) return;
+    
+    const audioInterruptCallback = (event: InterruptEvent) => {
+      hilog.info(0x0000, TAG, `Audio interrupt event: ${JSON.stringify(event)}`);
+      
+      if (event.hintType === InterruptHintType.INTERRUPT_HINT_PAUSE) {
+        this.pausePlayback();
+      } else if (event.hintType === InterruptHintType.INTERRUPT_HINT_RESUME) {
+        // 可选择是否自动恢复播放
+        hilog.info(0x0000, TAG, 'Audio interrupt resumed, manual resume required');
+      } else if (event.hintType === InterruptHintType.INTERRUPT_HINT_STOP) {
+        this.stopPlayback();
+      }
+    };
+    
+    this.ijkPlayer.on('audioInterrupt', audioInterruptCallback);
+    hilog.info(0x0000, TAG, 'Audio interrupt handler set');
+  }
+
+  /**
+   * 设置播放器回调
+   */
+  private setupPlayerCallbacks(): void {
+    if (!this.ijkPlayer) return;
+    
+    // 准备完成回调
+    const onPreparedListener: OnPreparedListener = {
+      onPrepared: () => {
+        hilog.info(0x0000, TAG, 'IjkPlayer prepared successfully');
+        
+        // 现在可以安全地开始播放
+        try {
+          this.ijkPlayer?.start();
+          hilog.info(0x0000, TAG, 'Playback started after onPrepared');
+        } catch (error) {
+          hilog.error(0x0000, TAG, `Failed to start playback in onPrepared: ${error}`);
+          return;
+        }
+        
+        this.playState.isLoading = false;
+        this.playState.duration = this.ijkPlayer?.getDuration() || 0;
+        this.playState.isPlaying = true;
+        this.playState.isPaused = false;
+        
+        // 保存播放状态
+        this.savePlaybackState();
+        
+        // 立即广播状态更新
+        this.broadcastPlayerState();
+        
+        // 启动进度更新定时器
+        this.startProgressTask();
+        
+        hilog.info(0x0000, TAG, `Playback prepared and started for ${this.currentSong?.name}, duration: ${this.playState.duration}ms`);
+        
+        // 延迟恢复播放位置
+        setTimeout(() => {
+          this.restorePlaybackPosition();
+        }, 500);
+      }
+    };
+    this.ijkPlayer.setOnPreparedListener(onPreparedListener);
+    
+    // 播放完成回调
+    const onCompletionListener: OnCompletionListener = {
+      onCompletion: () => {
+        hilog.info(0x0000, TAG, 'Playback completed');
+        this.handlePlaybackCompletion();
+      }
+    };
+    this.ijkPlayer.setOnCompletionListener(onCompletionListener);
+    
+    // 错误回调
+    const onErrorListener: OnErrorListener = {
+      onError: (what: number, extra: number) => {
+        hilog.error(0x0000, TAG, `IjkPlayer error: what=${what}, extra=${extra}`);
+        this.playState.isLoading = false;
+        this.playState.isPlaying = false;
+        this.playState.isPaused = true;
+        this.broadcastPlayerState();
+        
+        // 尝试重试播放
+        if (this.retryCount < this.maxRetries) {
+          this.retryCount++;
+          hilog.info(0x0000, TAG, `Retrying playback, attempt ${this.retryCount}/${this.maxRetries}`);
+          setTimeout(() => {
+            this.play();
+          }, 1000);
+        } else {
+          hilog.error(0x0000, TAG, `Max retries exceeded, giving up`);
+          this.retryCount = 0;
+        }
+        
+        return true; // 表示错误已处理
+      }
+    };
+    this.ijkPlayer.setOnErrorListener(onErrorListener);
+    
+    hilog.info(0x0000, TAG, 'Player callbacks configured');
+  }
+
+  /**
+   * 从PreferencesUtil加载播放列表数据,保持与LocalMusic一致
+   */
+  private loadFromAppStorage(): void {
+    try {
+      // 直接从PreferencesUtil获取数据,与LocalMusic保持一致
+      this.playlist = PreferencesUtil.getSync('LastMusicList', []) as Array<VideoItem>;
+      this.currentSong = PreferencesUtil.getSync('LastMusicInfo', undefined) as VideoItem;
+      
+      hilog.info(0x0000, TAG, `Loaded ${this.playlist.length} songs from PreferencesUtil`);
+      
+      // 如果有播放列表但没有当前歌曲,使用第一首歌
+      if (this.playlist.length > 0 && !this.currentSong) {
+        this.currentSong = this.playlist[0];
+        this.currentIndex = 0;
+        hilog.info(0x0000, TAG, 'Using first song as current song');
+      } else if (this.currentSong && this.playlist.length > 0) {
+        // 在播放列表中查找当前歌曲的索引
+        const foundIndex = this.playlist.findIndex(song => 
+          song.id === this.currentSong!.id || 
+          song.filePath === this.currentSong!.filePath ||
+          song.name === this.currentSong!.name
+        );
+        this.currentIndex = foundIndex >= 0 ? foundIndex : 0;
+        hilog.info(0x0000, TAG, `Found current song index: ${this.currentIndex}`);
+      } else {
+        // 没有播放列表或当前歌曲
+        this.currentIndex = 0;
+        this.currentSong = null;
+        hilog.info(0x0000, TAG, 'No playlist or current song found');
+      }
+
+      // 恢复播放状态(包括duration等信息)
+      if (this.currentSong) {
+        this.restorePlaybackState();
+      }
+
+      // 同步到AppStorage以便其他组件访问
+      AppStorage.setOrCreate('songList', this.playlist);
+      AppStorage.setOrCreate('currIndex', this.currentIndex);
+      AppStorage.setOrCreate('currentSong', this.currentSong);
+
+      hilog.info(0x0000, TAG, `Current index: ${this.currentIndex}, current song: ${this.currentSong?.name || 'none'}`);
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to load from PreferencesUtil: ${error}`);
+      this.playlist = [];
+      this.currentIndex = 0;
+      this.currentSong = null;
+      
+      // 设置默认值到AppStorage
+      AppStorage.setOrCreate('songList', []);
+      AppStorage.setOrCreate('currIndex', 0);
+      AppStorage.setOrCreate('currentSong', null);
+    }
+  }
+
+  /**
+   * 注册数据变化监听器(主要监听PreferencesUtil数据变化)
+   */
+  private registerAppStorageListener(): void {
+    try {
+      // 设置初始值到AppStorage
+      AppStorage.setOrCreate('songList', this.playlist);
+      AppStorage.setOrCreate('currIndex', this.currentIndex);
+      
+      // 定期检查PreferencesUtil中的数据变化
+      setInterval(() => {
+        this.checkPreferencesChanges();
+      }, 1000);
+      
+      hilog.info(0x0000, TAG, 'PreferencesUtil data listeners registered successfully');
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to register data listeners: ${error}`);
+    }
+  }
+
+  /**
+   * 检查PreferencesUtil中的数据变化
+   */
+  private checkPreferencesChanges(): void {
+    try {
+      // 检查播放列表变化
+      const newPlaylist = PreferencesUtil.getSync('LastMusicList', []) as Array<VideoItem>;
+      const newCurrentSong = PreferencesUtil.getSync('LastMusicInfo', undefined) as VideoItem;
+      
+      if (JSON.stringify(newPlaylist) !== JSON.stringify(this.playlist)) {
+        const oldLength = this.playlist.length;
+        this.playlist = newPlaylist;
+        hilog.info(0x0000, TAG, `Playlist updated from PreferencesUtil: ${oldLength} -> ${this.playlist.length} songs`);
+        
+        // 如果当前索引超出范围,重置为0
+        if (this.currentIndex >= this.playlist.length) {
+          this.currentIndex = 0;
+          this.currentSong = this.playlist.length > 0 ? this.playlist[0] : null;
+        }
+        
+        // 同步到AppStorage
+        AppStorage.setOrCreate('songList', this.playlist);
+        this.broadcastPlayerState();
+      }
+      
+      // 检查当前歌曲变化
+      if (newCurrentSong && JSON.stringify(newCurrentSong) !== JSON.stringify(this.currentSong)) {
+        this.currentSong = newCurrentSong;
+        
+        // 在播放列表中查找新歌曲的索引
+        if (this.playlist.length > 0) {
+          const foundIndex = this.playlist.findIndex(song => 
+            song.id === newCurrentSong.id || 
+            song.filePath === newCurrentSong.filePath ||
+            song.name === newCurrentSong.name
+          );
+          if (foundIndex >= 0) {
+            this.currentIndex = foundIndex;
+            hilog.info(0x0000, TAG, `Current song updated from PreferencesUtil: ${this.currentIndex}`);
+          }
+        }
+        
+        // 同步到AppStorage
+        AppStorage.setOrCreate('currentSong', this.currentSong);
+        AppStorage.setOrCreate('currIndex', this.currentIndex);
+        this.broadcastPlayerState();
+      }
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to check PreferencesUtil changes: ${error}`);
+    }
+  }
+
+  /**
+   * 刷新播放列表数据(从PreferencesUtil重新加载)
+   */
+  private refreshPlaylistData(): void {
+    try {
+      const oldPlaylistLength = this.playlist.length;
+      const oldCurrentIndex = this.currentIndex;
+      
+      // 如果当前播放列表为空,强制重新加载
+      if (this.playlist.length === 0) {
+        hilog.info(0x0000, TAG, 'Playlist is empty, forcing reload from storage...');
+      }
+      
+      this.loadFromAppStorage();
+      
+      // 如果数据有变化,广播更新
+      if (this.playlist.length !== oldPlaylistLength || this.currentIndex !== oldCurrentIndex) {
+        hilog.info(0x0000, TAG, `Playlist data refreshed: ${oldPlaylistLength} -> ${this.playlist.length} songs, index: ${oldCurrentIndex} -> ${this.currentIndex}`);
+        this.broadcastPlayerState();
+      } else if (this.playlist.length === 0) {
+        hilog.warn(0x0000, TAG, 'Still no songs found after refresh');
+      }
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to refresh playlist data: ${error}`);
+    }
+  }
+
+  /**
+   * 注册卡片控制事件监听器
+   */
+  private registerWidgetControlListener(): void {
+    try {
+      const innerEvent: emitter.InnerEvent = { eventId: 9001 };
+      emitter.on(innerEvent, (eventData: emitter.EventData) => {
+        this.handleWidgetControlEvent(eventData);
+      });
+      
+      hilog.info(0x0000, TAG, 'Widget control listener registered');
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to register widget control listener: ${error}`);
+    }
+  }
+
+  /**
+   * 处理卡片控制事件
+   */
+  private handleWidgetControlEvent(eventData: emitter.EventData): void {
+    try {
+      const data = eventData.data as Record<string, Object>;
+      const command = data['command'] as string;
+      const source = data['source'] as string;
+
+      hilog.info(0x0000, TAG, `🎵 IndependentPlayer received command: ${command} from ${source}`);
+
+      switch (command) {
+        case 'PLAY_PAUSE':
+          this.togglePlayPause();
+          break;
+        case 'NEXT_SONG':
+          this.playNext();
+          break;
+        case 'PREV_SONG':
+          this.playPrevious();
+          break;
+        default:
+          hilog.warn(0x0000, TAG, `Unknown command: ${command}`);
+      }
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to handle widget control event: ${error}`);
+    }
+  }
+
+  /**
+   * 切换播放/暂停
+   */
+  async togglePlayPause(): Promise<void> {
+    try {
+      if (!this.ijkPlayer) {
+        hilog.error(0x0000, TAG, 'IjkPlayer not initialized');
+        // 尝试重新初始化
+        if (this.context) {
+          await this.initialize(this.context);
+        }
+        return;
+      }
+
+      // 如果没有播放列表,尝试刷新数据
+      if (this.playlist.length === 0) {
+        hilog.info(0x0000, TAG, 'No playlist found, attempting to refresh data...');
+        this.refreshPlaylistData();
+        
+        // 如果刷新后仍然没有数据,返回
+        if (this.playlist.length === 0) {
+          hilog.warn(0x0000, TAG, 'No songs available after refresh');
+          return;
+        }
+      }
+
+      // 使用内部状态来判断,而不是完全依赖ijkPlayer.isPlaying()
+      const shouldPause = this.playState.isPlaying;
+      hilog.info(0x0000, TAG, `Toggle action: shouldPause=${shouldPause}, current state - isPlaying=${this.playState.isPlaying}, isPaused=${this.playState.isPaused}, ijkPlayer.isPlaying=${this.ijkPlayer.isPlaying()}`);
+      
+      if (shouldPause) {
+        hilog.info(0x0000, TAG, 'Pausing playback');
+        await this.pause();
+      } else {
+        hilog.info(0x0000, TAG, 'Starting/Resuming playback');
+        await this.play();
+      }
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to toggle play/pause: ${error}`);
+      // 如果出错,尝试重置播放器
+      try {
+        await this.resetPlayer();
+      } catch (resetError) {
+        hilog.error(0x0000, TAG, `Failed to reset player after toggle error: ${resetError}`);
+      }
+    }
+  }
+
+  /**
+   * 恢复播放状态(包括duration等信息)
+   */
+  private restorePlaybackState(): void {
+    try {
+      if (!this.currentSong) return;
+      
+      // 恢复duration信息
+      const savedDuration = AppStorage.get<number>(`duration_${this.currentSong.filePath}`) || 0;
+      if (savedDuration > 0) {
+        this.playState.duration = savedDuration;
+        this.savedDuration = savedDuration; // 确保savedDuration也被设置
+        hilog.info(0x0000, TAG, `Restored duration: ${savedDuration}ms for ${this.currentSong.name}`);
+      }
+      
+      // 恢复播放状态
+      const stateStr = AppStorage.get<string>(`state_${this.currentSong.filePath}`) || '';
+      if (stateStr) {
+        try {
+          const stateData: SavedPlaybackState = JSON.parse(stateStr) as SavedPlaybackState;
+          // 检查状态是否太旧(超过24小时不恢复)
+          if (stateData && Date.now() - stateData.timestamp < 24 * 60 * 60 * 1000) {
+            // 恢复暂停状态,但不自动开始播放
+            this.playState.isPaused = stateData.isPaused;
+            this.playState.isPlaying = false; // 启动时总是设为未播放
+            this.playState.currentPosition = stateData.currentPosition || 0;
+            
+            // 如果从单独的duration存储中没有获取到duration,尝试从状态数据中获取
+            if (savedDuration === 0 && stateData.duration > 0) {
+              this.playState.duration = stateData.duration;
+              this.savedDuration = stateData.duration;
+              hilog.info(0x0000, TAG, `Used duration from state data: ${stateData.duration}ms`);
+            }
+            
+            hilog.info(0x0000, TAG, `Restored playback state: isPaused=${this.playState.isPaused}, position=${this.playState.currentPosition}, duration=${this.savedDuration}`);
+          }
+        } catch (parseError) {
+          hilog.error(0x0000, TAG, `Failed to parse saved state: ${parseError}`);
+        }
+      }
+      
+      // 如果没有保存的状态,设置默认值
+      if (!stateStr) {
+        this.playState.isPlaying = false;
+        this.playState.isPaused = true; // 默认为暂停状态
+        this.playState.isLoading = false;
+        this.playState.currentPosition = 0;
+      }
+      
+      hilog.info(0x0000, TAG, `Final restored state for ${this.currentSong.name}: isPlaying=${this.playState.isPlaying}, isPaused=${this.playState.isPaused}, duration=${this.savedDuration}`);
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to restore playback state: ${error}`);
+    }
+  }
+
+  /**
+   * 保存播放状态
+   */
+  private savePlaybackState(): void {
+    try {
+      if (!this.currentSong) return;
+      
+      // 保存duration信息
+      if (this.playState.duration > 0) {
+        AppStorage.setOrCreate(`duration_${this.currentSong.filePath}`, this.playState.duration);
+        hilog.info(0x0000, TAG, `Saved duration: ${this.playState.duration}ms for ${this.currentSong.name}`);
+      }
+      
+      // 保存播放状态
+      const stateData: SavedPlaybackState = {
+        isPlaying: this.playState.isPlaying,
+        isPaused: this.playState.isPaused,
+        currentPosition: this.playState.currentPosition || 0,
+        duration: this.playState.duration || 0,
+        timestamp: Date.now()
+      };
+      AppStorage.setOrCreate(`state_${this.currentSong.filePath}`, JSON.stringify(stateData));
+      hilog.info(0x0000, TAG, `Saved playback state: isPlaying=${this.playState.isPlaying}, isPaused=${this.playState.isPaused}`);
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to save playback state: ${error}`);
+    }
+  }
+
+  /**
+   * 播放
+   */
+  async play(): Promise<void> {
+    try {
+      if (!this.ijkPlayer) {
+        hilog.error(0x0000, TAG, 'IjkPlayer not initialized');
+        return;
+      }
+
+      // 刷新播放列表数据
+      this.refreshPlaylistData();
+
+      // 如果没有当前歌曲,尝试播放第一首
+      if (!this.currentSong && this.playlist.length > 0) {
+        hilog.info(0x0000, TAG, 'No current song, playing first song');
+        await this.playSongAtIndex(0);
+        return;
+      }
+
+      if (!this.currentSong) {
+        hilog.warn(0x0000, TAG, 'No song to play');
+        this.playState.isLoading = false;
+        this.playState.isPlaying = false;
+        this.playState.isPaused = true;
+        this.broadcastPlayerState();
+        return;
+      }
+
+      // 如果已经在播放,无需操作
+      if (this.ijkPlayer.isPlaying()) {
+        hilog.info(0x0000, TAG, 'Already playing');
+        return;
+      }
+
+      // 检查是否可以恢复播放(优先使用保存的duration)
+      const ijkDuration = this.ijkPlayer.getDuration();
+      const savedDuration = this.playState.duration;
+      const effectiveDuration = savedDuration > 0 ? savedDuration : ijkDuration;
+      
+      const canResume = this.playState.isPaused && 
+                       !this.playState.isLoading && 
+                       effectiveDuration > 0 && // 使用有效的duration
+                       !this.ijkPlayer.isPlaying(); // 确保确实没在播放
+
+      hilog.info(0x0000, TAG, `Play state check: isPaused=${this.playState.isPaused}, isLoading=${this.playState.isLoading}, ijkDuration=${ijkDuration}, savedDuration=${savedDuration}, effectiveDuration=${effectiveDuration}, canResume=${canResume}`);
+
+      if (canResume) {
+        try {
+          this.ijkPlayer.start();
+          this.playState.isPlaying = true;
+          this.playState.isPaused = false;
+          // 恢复duration如果播放器中为0
+          if (ijkDuration === 0 && savedDuration > 0) {
+            this.playState.duration = savedDuration;
+          }
+          this.startProgressTask(); // 启动进度更新
+          this.broadcastPlayerState();
+          hilog.info(0x0000, TAG, 'Resumed playback from pause');
+          return;
+        } catch (resumeError) {
+          hilog.warn(0x0000, TAG, `Failed to resume from pause: ${resumeError}, starting fresh`);
+          // 恢复失败,重置状态继续执行重新播放逻辑
+          this.playState.isPaused = false;
+        }
+      }
+
+      // 开始播放当前歌曲(重新准备数据源)
+      hilog.info(0x0000, TAG, `Attempting to play song: ${this.currentSong.filePath}`);
+      await this.playWithSimpleLogic();
+
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to play: ${error}`);
+      this.playState.isLoading = false;
+      this.playState.isPlaying = false;
+      this.playState.isPaused = true;
+      this.broadcastPlayerState();
+    }
+  }
+
+  /**
+   * 播放指定索引的歌曲
+   */
+  private async playSongAtIndex(index: number): Promise<void> {
+    try {
+      if (index < 0 || index >= this.playlist.length) {
+        hilog.error(0x0000, TAG, `Invalid song index: ${index}`);
+        return;
+      }
+
+      if (!this.ijkPlayer) {
+        hilog.error(0x0000, TAG, 'IjkPlayer not initialized');
+        return;
+      }
+
+      const song = this.playlist[index];
+      this.currentIndex = index;
+      this.currentSong = song;
+
+      // 更新AppStorage中的currIndex,与LocalMusic保持同步
+      AppStorage.setOrCreate('currIndex', this.currentIndex);
+
+      this.playState.isLoading = true;
+      this.broadcastPlayerState();
+
+      hilog.info(0x0000, TAG, `Switching to song: ${song.name}`);
+
+      // 使用简单播放逻辑
+      try {
+        await this.playWithSimpleLogic();
+        
+        // 恢复播放进度(记忆播放功能)
+        this.restorePlaybackPosition();
+
+        hilog.info(0x0000, TAG, `Successfully switched to song: ${song.name} by ${song.artist || '未知艺术家'}`);
+        
+      } catch (playError) {
+        hilog.error(0x0000, TAG, `Failed to switch song: ${playError}`);
+        this.playState.isLoading = false;
+        this.broadcastPlayerState();
+        throw new Error(`Failed to switch song: ${playError}`);
+      }
+      // 广播歌曲变化
+      this.broadcastSongChange();
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to play song at index ${index}: ${error}`);
+      this.playState.isLoading = false;
+      this.broadcastPlayerState();
+    }
+  }
+
+  /**
+   * 恢复播放进度(记忆播放功能)
+   */
+  private restorePlaybackPosition(): void {
+    try {
+      if (!this.currentSong || !this.ijkPlayer) return;
+      
+      // 从PreferencesUtil获取保存的播放位置
+      const savedPosition = AppStorage.get<number>(`playback_${this.currentSong.filePath}`) || 0;
+      
+      if (savedPosition > 0) {
+        // 延迟恢复播放位置,确保播放器已准备好
+        setTimeout(() => {
+          if (this.ijkPlayer && this.ijkPlayer.isPlaying()) {
+            this.ijkPlayer.seekTo(savedPosition.toString());
+            hilog.info(0x0000, TAG, `Restored playback position: ${savedPosition}ms for ${this.currentSong?.name}`);
+          }
+        }, 500);
+      }
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to restore playback position: ${error}`);
+    }
+  }
+
+  /**
+   * 保存播放进度
+   */
+  private savePlaybackPosition(): void {
+    try {
+      if (!this.currentSong || !this.ijkPlayer) return;
+      
+      const position = this.playState.currentPosition;
+      const duration = this.playState.duration;
+      const threshold = 5000; // 5秒阈值
+      
+      // 如果播放位置接近末尾,则保存为0
+      const playbackPosition = (duration - position < threshold) ? 0 : position;
+      
+      // 保存到AppStorage,这样LocalMusic也能访问到
+      AppStorage.setOrCreate(`playback_${this.currentSong.filePath}`, playbackPosition);
+      
+      hilog.info(0x0000, TAG, `Saved playback position: ${playbackPosition}ms for ${this.currentSong.name}`);
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to save playback position: ${error}`);
+    }
+  }
+
+  /**
+   * 暂停
+   */
+  async pause(): Promise<void> {
+    try {
+      if (!this.ijkPlayer) {
+        hilog.error(0x0000, TAG, 'IjkPlayer not initialized');
+        return;
+      }
+
+      // 保存播放进度
+      this.savePlaybackPosition();
+      
+      this.pausePlayback();
+      hilog.info(0x0000, TAG, 'Playback paused');
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to pause: ${error}`);
+    }
+  }
+
+  /**
+   * 处理播放完成
+   */
+  private handlePlaybackCompletion(): void {
+    try {
+      this.playState.isPlaying = false;
+      this.playState.isPaused = true;
+      this.playState.currentPosition = 0;
+      this.stopProgressTask(); // 停止进度更新
+      this.broadcastPlayerState();
+      
+      // 自动播放下一首
+      this.playNext().catch(() => {
+        hilog.error(0x0000, TAG, `Failed to auto play next`);
+      });
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to handle playback completion: ${error}`);
+    }
+  }
+
+
+  /**
+   * 简单播放逻辑(修复回调顺序问题)
+   */
+  private async playWithSimpleLogic(): Promise<void> {
+    return new Promise<void>((resolve, reject) => {
+      try {
+        if (!this.ijkPlayer || !this.currentSong) {
+          reject(new Error('IjkPlayer or currentSong not available'));
+          return;
+        }
+
+        hilog.info(0x0000, TAG, `Setting data source: ${this.currentSong.filePath}`);
+
+        // 重置播放器状态
+        this.ijkPlayer.reset();
+        this.playState.isLoading = true;
+
+        // 正确的IjkPlayer初始化顺序
+        // 1. 设置调试模式
+        this.ijkPlayer.setDebug(false);
+        
+        // 2. 初始化配置
+        this.ijkPlayer.native_setup();
+        
+        // 3. 设置音量
+        this.ijkPlayer.setVolume('1.0', '1.0');
+        
+        // 4. 设置数据源
+        this.ijkPlayer.setDataSource(this.currentSong.filePath);
+        
+        // 5. 设置数据源头部(可选,对于本地文件通常不需要)
+        let headers = new Map([
+          ["user_agent", "Mozilla/5.0 BiliDroid/7.30.0 (bbcallen@gmail.com)"],
+          ["referer", "https://www.bilibili.com"]
+        ]);
+        this.ijkPlayer.setDataSourceHeader(headers);
+        
+        // 6. 配置所有播放器选项
+        this.setupIjkPlayerOptions();
+        
+        // 7. 设置回调监听器(重要!必须在setMessageListener之前)
+        this.setupPlayerCallbacks();
+        hilog.info(0x0000, TAG, 'Player callbacks configured');
+        
+        // 8. 激活消息监听(必须在回调设置完成后,prepareAsync之前调用)
+        this.ijkPlayer.setMessageListener();
+        hilog.info(0x0000, TAG, 'Message listener activated');
+        
+        // 9. 异步准备(不要立即调用start,等待onPrepared回调)
+        this.ijkPlayer.prepareAsync();
+        hilog.info(0x0000, TAG, 'PrepareAsync called, waiting for onPrepared callback');
+        
+        // 设置加载状态并广播
+        this.playState.isLoading = true;
+        this.broadcastPlayerState();
+        
+        hilog.info(0x0000, TAG, 'IjkPlayer configuration and start completed');
+        
+        // 立即resolve,不等待onPrepared(onPrepared会在回调中处理播放状态)
+        resolve();
+
+      } catch (error) {
+        hilog.error(0x0000, TAG, `Failed in playWithSimpleLogic: ${error}`);
+        this.playState.isLoading = false;
+        this.broadcastPlayerState();
+        reject(error);
+      }
+    });
+  }
+
+  /**
+   * 播放下一首
+   */
+  async playNext(): Promise<void> {
+    try {
+      // 刷新播放列表数据
+      this.refreshPlaylistData();
+      
+      if (this.playlist.length === 0) {
+        hilog.warn(0x0000, TAG, 'No songs in playlist');
+        return;
+      }
+
+      const nextIndex = (this.currentIndex + 1) % this.playlist.length;
+      await this.playSongAtIndex(nextIndex);
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to play next: ${error}`);
+    }
+  }
+
+  /**
+   * 播放上一首
+   */
+  async playPrevious(): Promise<void> {
+    try {
+      // 刷新播放列表数据
+      this.refreshPlaylistData();
+      
+      if (this.playlist.length === 0) {
+        hilog.warn(0x0000, TAG, 'No songs in playlist');
+        return;
+      }
+
+      const prevIndex = this.currentIndex === 0 ? this.playlist.length - 1 : this.currentIndex - 1;
+      await this.playSongAtIndex(prevIndex);
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to play previous: ${error}`);
+    }
+  }
+
+
+
+  /**
+   * 处理播放器状态变化
+   */
+  private handlePlayerStateChange(state: string): void {
+    switch (state) {
+      case 'playing':
+        this.playState.isPlaying = true;
+        this.playState.isPaused = false;
+        this.playState.isLoading = false;
+        break;
+      case 'paused':
+        this.playState.isPlaying = false;
+        this.playState.isPaused = true;
+        this.playState.isLoading = false;
+        break;
+      case 'stopped':
+        this.playState.isPlaying = false;
+        this.playState.isPaused = true;
+        this.playState.isLoading = false;
+        this.playState.currentPosition = 0;
+        break;
+      case 'prepared':
+        this.playState.isLoading = false;
+        break;
+      case 'error':
+        this.playState.isPlaying = false;
+        this.playState.isPaused = true;
+        this.playState.isLoading = false;
+        break;
+    }
+
+    this.broadcastPlayerState();
+  }
+
+  /**
+   * 广播播放器状态
+   */
+  private broadcastPlayerState(): void {
+    // 节流:避免短时间内重复广播
+    const now = Date.now();
+    if (now - this.lastStateBroadcastTime < this.STATE_BROADCAST_INTERVAL) {
+      return;
+    }
+    this.lastStateBroadcastTime = now;
+    
+    try {
+      const playlistInfo: PlaylistInfo = {
+        hasNext: this.currentIndex < this.playlist.length - 1,
+        hasPrevious: this.currentIndex > 0,
+        currentIndex: this.currentIndex,
+        totalCount: this.playlist.length
+      };
+      
+      const currentSongData: SongData = this.currentSong ? {
+        id: this.currentSong.id,
+        title: this.currentSong.name,
+        artist: this.currentSong.artist || '未知艺术家',
+        album: this.currentSong.album || '未知专辑',
+        filePath: this.currentSong.filePath,
+        duration: parseInt(this.currentSong.duration || '0')
+      } : {
+        id: '',
+        title: '暂无播放',
+        artist: '未知艺术家',
+        album: '未知专辑',
+        filePath: '',
+        duration: 0
+      };
+
+      // 获取实时播放位置
+      const currentPosition = this.ijkPlayer?.getCurrentPosition() || this.playState.currentPosition;
+
+      const progressData: ProgressData = {
+        currentPosition: currentPosition,
+        duration: this.playState.duration,
+        percentage: this.playState.duration > 0 ? (currentPosition / this.playState.duration) * 100 : 0,
+        currentTimeText: this.formatTime(currentPosition / 1000),
+        totalTimeText: this.formatTime(this.playState.duration / 1000)
+      };
+
+      // 创建完整的WidgetData对象(与LocalMusic保持一致)
+      const widgetPlayState: WidgetPlayState = {
+        isPlaying: this.playState.isPlaying,
+        isPaused: this.playState.isPaused,
+        isLoading: this.playState.isLoading
+      };
+
+      const widgetSongInfo: SongInfo = this.currentSong ? {
+        id: this.currentSong.id,
+        title: this.currentSong.name,
+        artist: this.currentSong.artist || '未知艺术家',
+        album: this.currentSong.album || '未知专辑',
+        coverImagePath: this.currentSong.pixelMapPath || '',
+        duration: parseInt(this.currentSong.duration || '0')
+      } : {
+        id: '',
+        title: '暂无播放',
+        artist: '未知艺术家',
+        album: '未知专辑',
+        coverImagePath: '',
+        duration: 0
+      };
+
+      hilog.info(0x0000, TAG, `Broadcasting song info: artist="${this.currentSong?.artist}", title="${this.currentSong?.name}"`);
+
+      const widgetProgress: PlayProgress = {
+        currentPosition: currentPosition,
+        duration: this.playState.duration,
+        percentage: this.playState.duration > 0 ? (currentPosition / this.playState.duration) * 100 : 0,
+        currentTimeText: this.formatTime(currentPosition / 1000),
+        totalTimeText: this.formatTime(this.playState.duration / 1000)
+      };
+
+      const widgetPlaylist: PlaylistState = {
+        hasNext: this.currentIndex < this.playlist.length - 1,
+        hasPrevious: this.currentIndex > 0,
+        currentIndex: this.currentIndex,
+        totalCount: this.playlist.length
+      };
+
+      const widgetConfig: WidgetConfig = {
+        size: 'medium',
+        theme: 'auto',
+        showProgress: true,
+        showCover: true
+      };
+
+      const widgetData: WidgetData = {
+        playState: widgetPlayState,
+        currentSong: widgetSongInfo,
+        progress: widgetProgress,
+        playlist: widgetPlaylist,
+        config: widgetConfig
+      };
+
+      // 直接通过 DirectFormUpdateService 更新卡片数据(与LocalMusic保持一致)
+      try {
+        import('../widget/DirectFormUpdateService').then((module: DirectFormUpdateServiceModule) => {
+          const directFormService = module.DirectFormUpdateService.getInstance();
+          directFormService.updateAllForms(widgetData).then(() => {
+            hilog.info(0x0000, TAG, 'Direct form update completed successfully');
+          }).catch((error: Error) => {
+            hilog.error(0x0000, TAG, `Direct form update failed: ${error.message}`);
+          });
+        }).catch((importError: Error) => {
+          hilog.error(0x0000, TAG, `Failed to import DirectFormUpdateService: ${importError.message}`);
+        });
+      } catch (error) {
+        hilog.error(0x0000, TAG, `Failed to update widget via DirectFormUpdateService: ${error}`);
+      }
+
+      const stateData: PlayerStateData = {
+        playState: this.playState,
+        currentSong: currentSongData,
+        progress: progressData,
+        playlist: playlistInfo
+      };
+
+      const publishInfo: commonEventManager.CommonEventPublishData = {
+        data: JSON.stringify(stateData)
+      };
+
+      commonEventManager.publish(PLAYER_STATE_CHANGED_EVENT, publishInfo, (err) => {
+        if (err) {
+          hilog.error(0x0000, TAG, `Failed to broadcast player state: ${err}`);
+        } else {
+          hilog.info(0x0000, TAG, `Player state broadcasted: playing=${this.playState.isPlaying}, song=${this.currentSong?.name || 'none'}`);
+        }
+      });
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to broadcast player state: ${error}`);
+    }
+  }
+
+  /**
+   * 广播歌曲变化
+   */
+  private broadcastSongChange(): void {
+    try {
+      if (!this.currentSong) return;
+
+      const playlistInfo: PlaylistInfo = {
+        hasNext: this.currentIndex < this.playlist.length - 1,
+        hasPrevious: this.currentIndex > 0,
+        currentIndex: this.currentIndex,
+        totalCount: this.playlist.length
+      };
+      
+      const currentSongData: SongData = {
+        id: this.currentSong.id,
+        title: this.currentSong.name,
+        artist: this.currentSong.artist || '未知艺术家',
+        album: this.currentSong.album || '未知专辑',
+        filePath: this.currentSong.filePath,
+        duration: parseInt(this.currentSong.duration || '0')
+      };
+
+      const songData: SongChangeData = {
+        currentSong: currentSongData,
+        playlist: playlistInfo
+      };
+
+      const publishInfo: commonEventManager.CommonEventPublishData = {
+        data: JSON.stringify(songData)
+      };
+
+      commonEventManager.publish(PLAYER_SONG_CHANGED_EVENT, publishInfo, (err) => {
+        if (err) {
+          hilog.error(0x0000, TAG, `Failed to broadcast song change: ${err}`);
+        } else {
+          hilog.info(0x0000, TAG, `Song change broadcasted: ${this.currentSong?.name}`);
+        }
+      });
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to broadcast song change: ${error}`);
+    }
+  }
+
+  /**
+   * 启动进度更新定时器
+   */
+  private startProgressTask(): void {
+    // 避免重复启动定时器
+    if (this.updateProgressTimer > 0) {
+      return;
+    }
+    
+    this.updateProgressTimer = setInterval(() => {
+      if (this.ijkPlayer && this.playState.isPlaying) {
+        this.updateProgress();
+      }
+    }, 300); // 与LocalMusic保持一致:300ms间隔
+    
+    hilog.info(0x0000, TAG, 'Progress update timer started');
+  }
+
+  /**
+   * 停止进度更新定时器
+   */
+  private stopProgressTask(): void {
+    if (this.updateProgressTimer > 0) {
+      clearInterval(this.updateProgressTimer);
+      this.updateProgressTimer = 0;
+      hilog.info(0x0000, TAG, 'Progress update timer stopped');
+    }
+  }
+
+  /**
+   * 更新播放进度
+   */
+  private updateProgress(): void {
+    try {
+      if (!this.ijkPlayer || !this.currentSong) return;
+
+      const currentPosition = this.ijkPlayer.getCurrentPosition() || 0;
+      const duration = this.playState.duration;
+
+      // 更新内部状态
+      this.playState.currentPosition = currentPosition;
+
+      // 节流广播进度更新到卡片
+      this.broadcastProgressIfNeeded();
+
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to update progress: ${error}`);
+    }
+  }
+
+  /**
+   * 节流广播进度更新
+   */
+  private broadcastProgressIfNeeded(): void {
+    const now = Date.now();
+    if (now - this.lastProgressBroadcastTime >= this.PROGRESS_BROADCAST_INTERVAL) {
+      this.lastProgressBroadcastTime = now;
+      this.broadcastPlayerProgress();
+    }
+  }
+
+  /**
+   * 广播播放进度到卡片
+   */
+  private broadcastPlayerProgress(): void {
+    try {
+      const currentPos = this.ijkPlayer?.getCurrentPosition() || 0;
+      const progressData: ProgressData = {
+        currentPosition: currentPos,
+        duration: this.playState.duration || 0,
+        percentage: this.playState.duration > 0 ? (currentPos / this.playState.duration) * 100 : 0,
+        currentTimeText: this.formatTime(currentPos / 1000),
+        totalTimeText: this.formatTime(this.playState.duration / 1000)
+      };
+
+      // 广播播放进度变化
+      const publishInfo: commonEventManager.CommonEventPublishData = {
+        data: JSON.stringify(progressData)
+      };
+
+      commonEventManager.publish('com.ttmusic.player.progress', publishInfo, (err) => {
+        if (err) {
+          hilog.error(0x0000, TAG, `Failed to broadcast progress: ${err}`);
+        } else {
+          hilog.info(0x0000, TAG, `Progress broadcasted: ${progressData.percentage.toFixed(1)}%`);
+        }
+      });
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to broadcast progress: ${error}`);
+    }
+  }
+
+
+
+  /**
+   * 格式化时间显示
+   */
+  private formatTime(seconds: number): string {
+    const mins = Math.floor(seconds / 60);
+    const secs = Math.floor(seconds % 60);
+    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
+  }
+
+  /**
+   * 暂停播放
+   */
+  private pausePlayback(): void {
+    if (!this.ijkPlayer) return;
+    
+    try {
+      if (this.ijkPlayer.isPlaying()) {
+        this.ijkPlayer.pause();
+        this.playState.isPlaying = false;
+        this.playState.isPaused = true;
+        this.stopProgressTask(); // 停止进度更新
+        this.savePlaybackState(); // 保存播放状态
+        this.broadcastPlayerState();
+        hilog.info(0x0000, TAG, 'Playback paused');
+      } else {
+        // 即使没在播放,也要确保状态正确
+        this.playState.isPlaying = false;
+        this.playState.isPaused = true;
+        this.stopProgressTask();
+        this.savePlaybackState();
+        this.broadcastPlayerState();
+        hilog.info(0x0000, TAG, 'Playback paused (was not playing)');
+      }
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to pause playback: ${error}`);
+    }
+  }
+
+  /**
+   * 开始播放
+   */
+  private startPlayback(): void {
+    try {
+      if (this.ijkPlayer) {
+        hilog.info(0x0000, TAG, 'Starting playback after prepared');
+        // 在LocalMusic模式下,播放器已经在prepareAsync后自动开始
+        // 这里只需要更新状态
+        this.playState.isPlaying = true;
+        this.playState.isPaused = false;
+        this.playState.isLoading = false;
+        this.broadcastPlayerState();
+        hilog.info(0x0000, TAG, `Playback confirmed started for ${this.currentSong?.name}`);
+      }
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to start playback: ${error}`);
+      this.playState.isLoading = false;
+      this.playState.isPlaying = false;
+      this.playState.isPaused = true;
+      this.broadcastPlayerState();
+    }
+  }
+
+  /**
+   * 停止播放
+   */
+  private stopPlayback(): void {
+    if (!this.ijkPlayer) return;
+    
+    try {
+      if (this.ijkPlayer.isPlaying()) {
+        this.ijkPlayer.stop();
+      }
+      this.playState.isPlaying = false;
+      this.playState.isPaused = true;
+      this.playState.currentPosition = 0;
+      this.stopProgressTask(); // 停止进度更新
+      this.broadcastPlayerState();
+      hilog.info(0x0000, TAG, 'Playback stopped');
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to stop playback: ${error}`);
+    }
+  }
+
+
+  /**
+   * 等待播放器达到指定状态
+   */
+  private async waitForPlayerReady(timeout: number = 3000): Promise<void> {
+    return new Promise<void>((resolve, reject) => {
+      if (!this.ijkPlayer) {
+        reject(new Error('IjkPlayer is null'));
+        return;
+      }
+
+      // 对于 IjkPlayer,我们简单地检查它是否已创建并可用
+      if (this.ijkPlayer) {
+        resolve();
+        return;
+      }
+
+      const timeoutId = setTimeout(() => {
+        reject(new Error(`Timeout waiting for player ready`));
+      }, timeout);
+
+      // 简单延迟后解析,因为 IjkPlayer 不需要复杂的状态等待
+      setTimeout(() => {
+        clearTimeout(timeoutId);
+        if (this.ijkPlayer) {
+          resolve();
+        } else {
+          reject(new Error('Player not ready'));
+        }
+      }, 100);
+    });
+  }
+
+  /**
+   * 重置播放器(用于错误恢复)
+   */
+  private async resetPlayer(): Promise<void> {
+    try {
+      if (!this.ijkPlayer) {
+        hilog.error(0x0000, TAG, 'IjkPlayer is null, cannot reset');
+        return;
+      }
+
+      hilog.info(0x0000, TAG, `Resetting IjkPlayer`);
+      
+      // 先尝试停止播放器
+      try {
+        if (this.ijkPlayer.isPlaying()) {
+          this.ijkPlayer.pause();
+        }
+        this.ijkPlayer.stop();
+      } catch (stopError) {
+        hilog.warn(0x0000, TAG, `Failed to stop player during reset: ${stopError}`);
+      }
+
+      // 重新创建播放器
+      await this.recreatePlayer();
+      hilog.info(0x0000, TAG, `Player reset completed`);
+
+      // 重置播放状态
+      this.playState = {
+        isPlaying: false,
+        isPaused: true,
+        isLoading: false,
+        currentPosition: 0,
+        duration: 0
+      };
+
+      this.broadcastPlayerState();
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to reset player: ${error}`);
+      // 如果重置失败,尝试重新创建播放器
+      await this.recreatePlayer();
+    }
+  }
+
+  /**
+   * 重新创建播放器(最后的恢复手段)
+   */
+  private async recreatePlayer(): Promise<void> {
+    try {
+      hilog.warn(0x0000, TAG, 'Recreating IjkMediaPlayer...');
+      
+      // 释放旧播放器
+      if (this.ijkPlayer) {
+        try {
+          this.ijkPlayer.release();
+        } catch (releaseError) {
+          hilog.warn(0x0000, TAG, `Failed to release old player: ${releaseError}`);
+        }
+        this.ijkPlayer = null;
+      }
+
+      // 重置重试计数
+      this.retryCount = 0;
+
+      // 创建新播放器
+      await this.createAudioPlayer();
+      hilog.info(0x0000, TAG, 'IjkMediaPlayer recreated successfully');
+
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to recreate IjkMediaPlayer: ${error}`);
+      this.isInitialized = false;
+    }
+  }
+
+  /**
+   * 获取当前播放状态
+   */
+  getCurrentState(): PlayerCurrentState {
+    const currentState: PlayerCurrentState = {
+      playState: {
+        isPlaying: this.playState.isPlaying,
+        isPaused: this.playState.isPaused,
+        isLoading: this.playState.isLoading,
+        currentPosition: this.playState.currentPosition,
+        duration: this.playState.duration
+      },
+      currentSong: this.currentSong,
+      playlist: this.playlist.slice()
+    };
+    return currentState;
+  }
+
+  /**
+   * 销毁服务
+   */
+  async destroy(): Promise<void> {
+    try {
+      // 停止进度更新定时器
+      this.stopProgressTask();
+      
+      if (this.ijkPlayer) {
+        this.ijkPlayer.release();
+        this.ijkPlayer = null;
+      }
+
+      emitter.off(9001);
+      this.isInitialized = false;
+      
+      hilog.info(0x0000, TAG, 'IndependentPlayerService destroyed');
+    } catch (error) {
+      hilog.error(0x0000, TAG, `Failed to destroy service: ${error}`);
+    }
+  }
+}

+ 1 - 69
entry/src/main/ets/entryability/EntryAbility.ets

@@ -18,7 +18,6 @@ import { rpc } from '@kit.IPCKit';
 
 import { Utility } from '../common/util/Utility';
 import { WXApi, WXEventHandler } from '../common/util/WXApiWrap';
-import { WidgetPlayerControlService } from '../common/service/WidgetPlayerControlService';
 import { IndependentPlayerService } from '../common/service/IndependentPlayerService';
 
 import { systemShare } from '@kit.ShareKit';
@@ -143,10 +142,7 @@ export default class EntryAbility extends UIAbility {
         } catch (error) {
             hilog.error(0x0000, 'testTag', `❌ Failed to initialize IndependentPlayerService: ${error}`);
         }
-        
-        // 初始化卡片播放器控制服务(作为备用)
-        WidgetPlayerControlService.getInstance().initialize();
-        
+
         // 设置备用的CommonEvent监听器
         this.setupBackupCommonEventListener();
         
@@ -232,9 +228,6 @@ export default class EntryAbility extends UIAbility {
         // 注销卡片call事件监听器
         this.unregisterWidgetCallListeners();
         
-        // 销毁卡片播放器控制服务
-        WidgetPlayerControlService.getInstance().destroy();
-        
         let types: smartMobilityCommon.SmartMobilityType[] = [smartMobilityCommon.SmartMobilityType.CAR_HOP];
         // 出行连接状态回调函数
         const callBack = (info: smartMobilityCommon.SmartMobilityInfo) => {
@@ -525,43 +518,6 @@ export default class EntryAbility extends UIAbility {
                 return new MyParcelable(4, 'openApp_success');
             });
 
-            // 监听播放控制事件(新增,符合文档标准)
-            this.callee.on('playByAction', (data: rpc.MessageSequence) => {
-                hilog.info(0x0000, 'testTag', `Widget call: playByAction received`);
-                const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
-                const playActionType = params['playActionType'] as string;
-                hilog.info(0x0000, 'testTag', `Widget playByAction type: ${playActionType}`);
-                
-                // 发送播放控制事件
-                this.sendWidgetControlEvent(playActionType, params);
-                
-                return new MyParcelable(5, 'playByAction_success');
-            });
-
-            // 监听收藏事件(新增,符合文档标准)
-            this.callee.on('collectAction', (data: rpc.MessageSequence) => {
-                hilog.info(0x0000, 'testTag', `Widget call: collectAction received`);
-                const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
-                const collectActionType = params['collectActionType'] as string;
-                const songId = params['songId'] as string;
-                hilog.info(0x0000, 'testTag', `Widget collectAction type: ${collectActionType}, songId: ${songId}`);
-                
-                return new MyParcelable(6, 'collectAction_success');
-            });
-
-            // 监听卡片更新请求事件(新增,符合文档标准)
-            this.callee.on('requestUpdatePlayCard', (data: rpc.MessageSequence) => {
-                hilog.info(0x0000, 'testTag', `Widget call: requestUpdatePlayCard received`);
-                const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
-                const formId = params['formId'] as string;
-                hilog.info(0x0000, 'testTag', `Widget requestUpdate formId: ${formId}`);
-                
-                // 更新卡片数据
-                this.updatePlayCard(formId);
-                
-                return new MyParcelable(7, 'requestUpdatePlayCard_success');
-            });
-
             hilog.info(0x0000, 'testTag', 'Widget call listeners registered successfully');
         } catch (err) {
             hilog.error(0x0000, 'testTag', `Failed to register widget call listeners: ${JSON.stringify(err as BusinessError)}`);
@@ -586,30 +542,6 @@ export default class EntryAbility extends UIAbility {
         }
     }
 
-    /**
-     * 更新播放卡片
-     */
-    private async updatePlayCard(formId: string): Promise<void> {
-        try {
-            hilog.info(0x0000, 'testTag', `Updating play card: ${formId}`);
-            
-            // 获取当前播放状态
-            const isPlay = AppStorage.get<boolean>('isPlay') || false;
-            const currentSong = AppStorage.get<VideoItem>('currentSong');
-            
-            if (currentSong) {
-                // 使用FormUtils更新卡片
-                import('../common/widget/FormUtils').then((module) => {
-                    const formUtils = module.FormUtils.getInstance();
-                    formUtils.updateMusicControlCards(this.context, currentSong, isPlay);
-                });
-            }
-            
-            hilog.info(0x0000, 'testTag', `Play card update completed: ${formId}`);
-        } catch (error) {
-            hilog.error(0x0000, 'testTag', `Failed to update play card: ${error}`);
-        }
-    }
 
     /**
      * 发送卡片控制事件到主应用

+ 1 - 24
entry/src/main/ets/entryformability/EntryFormAbility.ets

@@ -1,4 +1,4 @@
-import { formBindingData, FormExtensionAbility, formInfo, formProvider } from '@kit.FormKit';
+import { formBindingData, FormExtensionAbility, formProvider } from '@kit.FormKit';
 import { Want } from '@kit.AbilityKit';
 import { hilog } from '@kit.PerformanceAnalysisKit';
 import { fileIo } from '@kit.CoreFileKit';
@@ -468,20 +468,6 @@ implements SizeChangeListener {
       hilog.error(0x0000, TAG, `Failed to register widget: ${error}`);
     }
 
-    // 注册到FormUtils活跃卡片列表
-    try {
-      import('../common/widget/FormUtils').then((module) => {
-        const formUtils = module.FormUtils.getInstance();
-        formUtils.registerActiveForm(formId);
-        
-        // 如果是音乐播控卡片,初始化数据
-        if (formName && formName.includes('PlayControlCard')) {
-          formUtils.updateMusicControlCard(formId, true);
-        }
-      });
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to register form to FormUtils: ${error}`);
-    }
 
     hilog.info(0x0000, TAG, `Detected widget size: ${widgetSize} for form: ${formId}`);
 
@@ -593,15 +579,6 @@ implements SizeChangeListener {
       hilog.info(0x0000, TAG, `🗑️ Form ID removal completed for: ${formId}`);
     });
 
-    // 从FormUtils活跃卡片列表中移除
-    try {
-      import('../common/widget/FormUtils').then((module) => {
-        const formUtils = module.FormUtils.getInstance();
-        formUtils.unregisterActiveForm(formId);
-      });
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to unregister form from FormUtils: ${error}`);
-    }
 
     // 注销各种监听器
     this.sizeAdapter.unregisterSizeChangeListener(formId);