Răsfoiți Sursa

优化切歌后播放状态同步,确保播放器在切歌时正确启动进度定时器

chendeben 11 luni în urmă
părinte
comite
4323194a3c

+ 10 - 5
entry/src/main/ets/common/service/PlayerManager.ets

@@ -44,6 +44,7 @@ export interface IPlayerManager {
   // 状态查询
   isPausedState(): boolean;
   clearPausedState(): void;
+  setShouldAutoPlay(shouldAutoPlay: boolean): void;
   
   // 清理资源
   release(): void;
@@ -59,6 +60,7 @@ export class PlayerManager implements IPlayerManager {
   private audioInterruptCallback: ((event: InterruptEvent) => void) | null = null;
   private stateCallback: PlayerStateCallback | null = null;
   private isPaused: boolean = false; // 跟踪暂停状态
+  private shouldAutoPlay: boolean = true; // 新增:是否应该自动播放
   private playType: number = 0; //0:连续播放  1:单片重复播放 2:正常播放 3:随机播放
   
   private constructor() {
@@ -149,14 +151,12 @@ export class PlayerManager implements IPlayerManager {
       onPrepared: () => {
         LogUtils.getInstance().LOGI('PlayerManager: Player prepared, starting playback');
         try {
-          // 只有在非暂停状态下才自动开始播放
-          // 如果当前是暂停状态,仅通知准备完成,不自动开始播放
-          if (!this.isPaused) {
+          if (this.shouldAutoPlay && !this.isPaused) {
             this.mIjkMediaPlayer.start();
-            LogUtils.getInstance().LOGI('PlayerManager: Playback started after prepared');
+            LogUtils.getInstance().LOGI('PlayerManager: Playback started after prepared (shouldAutoPlay=true)');
             this.stateCallback?.onPlaybackStarted();
           } else {
-            LogUtils.getInstance().LOGI('PlayerManager: Player prepared but in paused state, not auto-starting');
+            LogUtils.getInstance().LOGI(`PlayerManager: Player prepared but not auto-starting (shouldAutoPlay=${this.shouldAutoPlay}, isPaused=${this.isPaused})`);
           }
           
           // 总是通知准备完成
@@ -344,6 +344,11 @@ export class PlayerManager implements IPlayerManager {
     this.isPaused = false;
   }
 
+  setShouldAutoPlay(shouldAutoPlay: boolean): void {
+    LogUtils.getInstance().LOGI(`PlayerManager setShouldAutoPlay: ${shouldAutoPlay}`);
+    this.shouldAutoPlay = shouldAutoPlay;
+  }
+
   release(): void {
     try {
       // 移除音频中断监听

+ 20 - 4
entry/src/main/ets/common/service/UnifiedPlayerService.ets

@@ -951,7 +951,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
    * 直接播放新歌曲,避免恢复逻辑干扰
    * 专为 playNext/playPrevious 设计
    */
-  private async playNewSongDirectly(song: VideoItem | null): Promise<void> {
+  private async playNewSongDirectly(song: VideoItem | null, shouldAutoPlay: boolean = true): Promise<void> {
     if (!song) {
       throw new Error('No song provided for direct play');
     }
@@ -977,6 +977,17 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
       await this.playlistModel.ensureCurrentSongInHistory();
     }
 
+    // 关键修复:设置播放器的自动播放状态
+    this.playerManager.setShouldAutoPlay(shouldAutoPlay);
+    
+    // 如果需要自动播放,清除暂停状态,确保播放器能正常启动
+    if (shouldAutoPlay) {
+      this.playerManager.clearPausedState();
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: playNewSongDirectly - cleared paused state for auto-play`);
+    }
+    
+    LogUtils.getInstance().LOGI(`UnifiedPlayerService: playNewSongDirectly - shouldAutoPlay: ${shouldAutoPlay}`);
+
     // 设置播放源和配置
     await this.setupPlayerForSong(song);
 
@@ -1129,6 +1140,11 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
       // 1. 设置手动歌曲切换标志,防止自动播放等逻辑干扰
       this.isManualSongChange = true;
 
+      // 关键修复:切歌操作应该总是开始播放新歌曲,无论之前是什么状态
+      // 这是用户的明确意图:切换到新歌曲并播放
+      const shouldAutoPlayNewSong = true;
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: changeTrack - will auto-play new song: ${shouldAutoPlayNewSong}`);
+
       // 2. 检查服务是否已准备就绪
       if (!this.isAllServicesReady()) {
         LogUtils.getInstance().LOGI(`Heanup UnifiedPlayerService: ${direction} - 服务未就绪,等待服务初始化完成`);
@@ -1180,8 +1196,8 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
       // 静默停止当前播放(不再保存位置,因为已经在上面保存了)
       await this.stopSilentlyWithoutSave();
 
-      // 直接播放新歌曲
-      await this.playNewSongDirectly(newSong);
+      // 直接播放新歌曲,切歌操作总是自动播放
+      await this.playNewSongDirectly(newSong, shouldAutoPlayNewSong);
 
       // 更新播放列表状态
       await this.updatePlaylistStateInModel();
@@ -1239,7 +1255,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
 
       // 直接播放新歌曲,而不是恢复播放
       const newCurrentSong = this.playlistModel.getCurrentSong();
-      await this.playNewSongDirectly(newCurrentSong);
+      await this.playNewSongDirectly(newCurrentSong, true); // 直接点击播放,应该自动开始
 
       // 更新状态模型中的播放列表状态
       await this.updatePlaylistStateInModel();

+ 58 - 0
entry/src/main/ets/view/LocalMusic.ets

@@ -12542,6 +12542,35 @@ export struct LocalMusic {
           this.changeImageAnimation();
         }
 
+        // 关键修复:切歌后同步播放状态和启动进度定时器
+        setTimeout(() => {
+          try {
+            const actualPlaying = this.unifiedPlayerService.getActualPlayingState();
+            LogUtils.getInstance().LOGI(`playNext: Syncing state after track change - actualPlaying: ${actualPlaying}`);
+            
+            if (actualPlaying) {
+              // 更新UI播放状态
+              this.setIsPlaying(true);
+              this.CONTROL_PlayStatus = PlayStatus.PLAY;
+              this.mDestroyPage = false;
+              
+              // 启动进度定时器
+              this.stopProgressTask();
+              this.startProgressTask();
+              
+              // 立即更新进度
+              this.setProgress();
+              
+              // 更新播放按钮状态
+              this.playChange();
+              
+              LogUtils.getInstance().LOGI('playNext: Progress timer started and state synchronized');
+            }
+          } catch (error) {
+            LogUtils.getInstance().LOGI(`playNext state sync error: ${error}`);
+          }
+        }, 300); // 延迟300ms,确保UnifiedPlayerService的播放状态已经稳定
+
       }
     } catch (error) {
       ToastUtil.showToast(`切换下一首失败: ${error}`);
@@ -12840,6 +12869,35 @@ export struct LocalMusic {
 
           this.changeImageAnimation();
         }
+
+        // 关键修复:切歌后同步播放状态和启动进度定时器
+        setTimeout(() => {
+          try {
+            const actualPlaying = this.unifiedPlayerService.getActualPlayingState();
+            LogUtils.getInstance().LOGI(`playPrevious: Syncing state after track change - actualPlaying: ${actualPlaying}`);
+            
+            if (actualPlaying) {
+              // 更新UI播放状态
+              this.setIsPlaying(true);
+              this.CONTROL_PlayStatus = PlayStatus.PLAY;
+              this.mDestroyPage = false;
+              
+              // 启动进度定时器
+              this.stopProgressTask();
+              this.startProgressTask();
+              
+              // 立即更新进度
+              this.setProgress();
+              
+              // 更新播放按钮状态
+              this.playChange();
+              
+              LogUtils.getInstance().LOGI('playPrevious: Progress timer started and state synchronized');
+            }
+          } catch (error) {
+            LogUtils.getInstance().LOGI(`playPrevious state sync error: ${error}`);
+          }
+        }, 300); // 延迟300ms,确保UnifiedPlayerService的播放状态已经稳定
       }
 
     } catch (error) {