Browse Source

合并切歌逻辑

chendeben 1 năm trước cách đây
mục cha
commit
10a71f1446
1 tập tin đã thay đổi với 32 bổ sung78 xóa
  1. 32 78
      entry/src/main/ets/common/service/UnifiedPlayerService.ets

+ 32 - 78
entry/src/main/ets/common/service/UnifiedPlayerService.ets

@@ -731,118 +731,72 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
 
   // 播放列表控制方法
   async playNext(): Promise<void> {
-    try {
-      // 设置手动歌曲切换标志,防止自动播放干扰
-      this.isManualSongChange = true;
-      
-      // 首先检查服务是否已准备就绪
-      if (!this.isAllServicesReady()) {
-        LogUtils.getInstance().LOGI('UnifiedPlayerService: playNext - 服务未就绪,等待服务初始化完成');
-        // 在自动播放场景下,减少等待时间避免阻塞
-        const isReady = await this.waitForAllServicesReady(500, false);
-        if (!isReady) {
-          LogUtils.getInstance().LOGI('UnifiedPlayerService: Services not ready for playNext, skipping');
-          this.isManualSongChange = false;
-          return; // 直接返回,不抛出错误
-        }
-      }
-
-      const playMode = this.stateModel.getState().playMode;
-
-      if (!this.playlistModel.hasNext(playMode)) {
-        this.isManualSongChange = false;
-        return;
-      }
-      const moved = this.playlistModel.moveToNext(playMode);
-      if (!moved) {
-        this.isManualSongChange = false;
-        return;
-      }
-
-      // 更新状态模型的索引
-      const newIndex = this.playlistModel.getCurrentIndex();
-      const newSong = this.playlistModel.getCurrentSong();
-      this.stateModel.updateCurrentIndex(newIndex);
-
-      if (newSong) {
-        this.stateModel.updateCurrentSong(newSong);
-      }
-
-      // 静默停止当前播放(不触发状态变化通知)
-      await this.stopSilently();
-
-      // 直接播放新歌曲,不调用通用的恢复逻辑
-      await this.playNewSongDirectly(newSong);
-
-      // 更新状态模型中的播放列表状态
-      this.updatePlaylistStateInModel();
-
-      // 强制更新卡片显示新歌曲(重要事件)
-      if (newSong) {
-        await this.updateWidgetsForSongChange(newSong, true);
-      }
-
-    } catch (error) {
-      await this.handlePlaybackError(error as Error, PlayerErrorType.PLAYBACK_ERROR);
-    } finally {
-      // 确保在任何情况下都清除手动切换标志
-      setTimeout(() => {
-        this.isManualSongChange = false;
-      }, 1000); // 延迟1秒清除,确保播放器状态稳定
-    }
+    return this.changeTrack('next');
   }
 
   async playPrevious(): Promise<void> {
+    return this.changeTrack('previous');
+  }
+  /**
+   * 切换歌曲(下一首或上一首)
+   * @param direction - 切换方向,'next' 或 'previous'
+   */
+  async changeTrack(direction: 'next' | 'previous'): Promise<void> {
     try {
-      // 设置手动歌曲切换标志,防止自动播放干扰
+      // 1. 设置手动歌曲切换标志,防止自动播放等逻辑干扰
       this.isManualSongChange = true;
-      
-      // 首先检查服务是否已准备就绪
+
+      // 2. 检查服务是否已准备就绪
       if (!this.isAllServicesReady()) {
-        LogUtils.getInstance().LOGI('UnifiedPlayerService: playPrevious - 服务未就绪,等待服务初始化完成');
+        LogUtils.getInstance().LOGI(`UnifiedPlayerService: ${direction} - 服务未就绪,等待服务初始化完成`);
         const isReady = await this.waitForAllServicesReady(500, false);
         if (!isReady) {
-          const error = new Error('Services not ready for playPrevious');
-          await this.handlePlaybackError(error, PlayerErrorType.INITIALIZATION_ERROR);
+          LogUtils.getInstance().LOGI(`UnifiedPlayerService: Services not ready for ${direction}, skipping`);
+          // 统一处理方式:在服务未就绪时直接返回,避免抛出错误中断用户体验
           this.isManualSongChange = false;
           return;
         }
       }
 
       const playMode = this.stateModel.getState().playMode;
+      let moved = false;
 
-      if (!(await this.playlistModel.hasPrevious(playMode))) {
-        this.isManualSongChange = false;
-        return;
+      // 3. 根据 direction 参数执行不同的逻辑
+      if (direction === 'next') {
+        if (this.playlistModel.hasNext(playMode)) {
+          moved = this.playlistModel.moveToNext(playMode);
+        }
+      } else { // direction === 'previous'
+        if (await this.playlistModel.hasPrevious(playMode)) {
+          // 注意:'previous' 相关的操作是异步的,需要 await
+          moved = await this.playlistModel.moveToPrevious(playMode);
+        }
       }
 
-      // 先获取当前歌曲信息用于日志
-
-      const moved = await this.playlistModel.moveToPrevious(playMode);
+      // 如果没有成功移动(列表到头/尾,或移动失败),则直接返回
       if (!moved) {
         this.isManualSongChange = false;
         return;
       }
 
-      // 更新状态模型的索引
       const newIndex = this.playlistModel.getCurrentIndex();
       const newSong = this.playlistModel.getCurrentSong();
-      this.stateModel.updateCurrentIndex(newIndex);
 
+      this.stateModel.updateCurrentIndex(newIndex);
       if (newSong) {
         this.stateModel.updateCurrentSong(newSong);
       }
 
-      // 静默停止当前播放(不触发状态变化通知)
+      // 静默停止当前播放
       await this.stopSilently();
 
-      // 直接播放新歌曲,不调用通用的恢复逻辑
+      // 直接播放新歌曲
       await this.playNewSongDirectly(newSong);
 
-      // 更新状态模型中的播放列表状态
+      // 更新播放列表状态
       this.updatePlaylistStateInModel();
 
-      // 强制更新卡片显示新歌曲(重要事件
+      // 强制更新UI(如卡片)
       if (newSong) {
         await this.updateWidgetsForSongChange(newSong, true);
       }
@@ -850,7 +804,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
     } catch (error) {
       await this.handlePlaybackError(error as Error, PlayerErrorType.PLAYBACK_ERROR);
     } finally {
-      // 确保在任何情况下都清除手动切换标志
+      // 5. 在任何情况下都清除手动切换标志
       setTimeout(() => {
         this.isManualSongChange = false;
       }, 1000); // 延迟1秒清除,确保播放器状态稳定