Просмотр исходного кода

歌单模式和文件夹模式 随机播放 不能是全部的随机

onecold 6 месяцев назад
Родитель
Сommit
0502cc52fd
1 измененных файлов с 69 добавлено и 5 удалено
  1. 69 5
      entry/src/main/ets/view/LocalMusic.ets

+ 69 - 5
entry/src/main/ets/view/LocalMusic.ets

@@ -364,6 +364,7 @@ export struct LocalMusic {
   @State currentSongList: Array<VideoItem> = []//当前歌单
   @Consume currentSongListName:string //当前歌单名称
   @Consume @Watch('onIDChange') currentSongListID:string //当前歌单ID
+  @State currentPlaylistSongFilePaths: string[] = [] //当前歌单的歌曲路径列表(用于随机播放)
   @State isRefreshing: boolean = false;
   @State maxRefreshingHeight: number = 100.0;
   @State isPlayerLoading: boolean = false; // 播放器加载状态
@@ -526,11 +527,17 @@ export struct LocalMusic {
     console.log('onecold 歌单id发生变化获取缓存7 playlistSongs='+playlistSongs.length)
     if (ArrayUtil.isEmpty(playlistSongs)) {
       this.updateListData([], true)
+      // 清空歌单路径列表
+      this.currentPlaylistSongFilePaths = [];
     } else {
       this.currentSongList = await convertPlaylistSongsToVideoItems(this.context, playlistSongs);
       console.log('onecold 从数据库读取的歌曲为 playlistSongs='+this.currentSongList.length)
       this.updateListData(this.currentSongList, true)
 
+      // 保存歌单的歌曲路径列表,用于随机播放
+      this.currentPlaylistSongFilePaths = playlistSongs.map(song => song.songFilePath);
+      Logger.info('heanup doSongListTask', `保存歌单歌曲路径列表,歌单ID=${this.currentSongListID}, 数量=${this.currentPlaylistSongFilePaths.length}`);
+
       if (ArrayUtil.isNotEmpty(this.currentSongList)&&this.currentSongList.length  > 100) {
         // 只保存前100条记录到缓存中
         let canceList = this.currentSongList.slice(0,  100);
@@ -6822,6 +6829,11 @@ export struct LocalMusic {
           // 确保播放列表是完整的歌单歌曲列表(已在finishLoadingPlaylist中设置)
           Logger.info(`heanup isFromSonPlayList分支 - 当前播放列表长度: ${this.songList.length}, 当前索引: ${this.curIndex}`)
           this.playQueueScope = 'playlist'
+          // 确保歌单路径列表已设置(从songList重新构建,以防被清空)
+          if (this.currentPlaylistSongFilePaths.length === 0 && this.songList.length > 0) {
+            this.currentPlaylistSongFilePaths = this.songList.map(song => song.filePath);
+            Logger.info(`heanup isFromSonPlayList - 重新构建歌单路径列表,数量=${this.currentPlaylistSongFilePaths.length}`);
+          }
         }else {
           const globalVideoList = this.buildPlayQueueFromView();
           this.curIndex = Utility.getCurIndexFromGlobalList(globalVideoList, item.filePath)
@@ -6832,7 +6844,20 @@ export struct LocalMusic {
           this.songList = globalVideoList
           this.sonDataSource.pushArrayData(this.songList)
           this.currentSong = this.songList[this.curIndex]
-          Logger.info(`heanup doPlay设置播放列表 - 总歌曲数: ${this.songList.length}, 当前索引: ${this.curIndex}, 当前歌曲: ${this.currentSong?.name}`)
+
+          // 只在非歌单模式下清空歌单路径列表
+          if (this.modeType !== 4) {
+            this.currentPlaylistSongFilePaths = [];
+            Logger.info(`heanup doPlay设置播放列表 - 总歌曲数: ${this.songList.length}, 当前索引: ${this.curIndex}, 当前歌曲: ${this.currentSong?.name}, 已清空歌单路径列表(modeType=${this.modeType})`)
+          } else {
+            // 歌单模式:确保歌单路径列表已设置
+            if (this.currentPlaylistSongFilePaths.length === 0 && this.songList.length > 0) {
+              this.currentPlaylistSongFilePaths = this.songList.map(song => song.filePath);
+              Logger.info(`heanup doPlay设置播放列表 - 从songList重新构建歌单路径列表,数量=${this.currentPlaylistSongFilePaths.length}`);
+            } else {
+              Logger.info(`heanup doPlay设置播放列表 - 歌单模式,保持歌单路径列表,数量=${this.currentPlaylistSongFilePaths.length}`);
+            }
+          }
         }
 
         AppStorage.setOrCreate('currentSong',this.currentSong) ;
@@ -7538,7 +7563,8 @@ export struct LocalMusic {
       newInput = tempOutPath
       tempOutPath  = ''
     }
-    const isWav:boolean = newInput.toLowerCase().endsWith('.wav');
+    const isWav:boolean = newInput.toLowerCase().endsWith('.wav')
+      ||newInput.toLowerCase().endsWith('.ape');
     //内嵌下标签的值,设置overwrite为true会直接修改原文件
     const result:boolean = await repairAudioMetadata(
       newInput,
@@ -7579,7 +7605,7 @@ export struct LocalMusic {
         if (result) {
           console.log(" onecold 编辑信息成功,数据库已同步");
           if(isWav){
-            ToastUtil.showToast('wav格式有可能内嵌失败,但是编辑信息成功')
+            ToastUtil.showToast('wav或者ape格式有可能内嵌失败,但是编辑信息成功')
           }else{
             ToastUtil.showToast('内嵌音乐标签成功')
           }
@@ -10383,7 +10409,8 @@ export struct LocalMusic {
     Row() {
       Stack() {
 
-        Image(this.cover)
+        Image( StrUtil.isNotEmpty(this.cover)?
+          this.cover:$r('app.media.alt'))
           .height(58)
           .width(58)
           .clip(true)
@@ -13610,7 +13637,8 @@ export struct LocalMusic {
     }
 
     // 如果是WebDAV网络音频,使用webdav_account_id获取认证信息(等待完成后再设置一次性头部)
-    if (this.currentSong && isRemoteCloudType(this.currentSong.type) && !isBaiduType(this.currentSong.type)) {
+    // SMB类型通过本地HTTP代理播放,不需要认证头,排除SMB和百度类型
+    if (this.currentSong && isRemoteCloudType(this.currentSong.type) && !isBaiduType(this.currentSong.type) && !isSmbType(this.currentSong.type)) {
       Logger.info(`heanup WebDAV歌曲认证 - 歌曲名: ${this.currentSong.name}, webdav_account_id: ${this.currentSong.webdav_account_id || '未设置'}`);
       if (this.currentSong.webdav_account_id) {
         try {
@@ -13629,6 +13657,8 @@ export struct LocalMusic {
       } else {
         Logger.error(`heanup WebDAV歌曲 "${this.currentSong.name}" 缺少webdav_account_id,无法进行认证`);
       }
+    } else if (this.currentSong && isSmbType(this.currentSong.type)) {
+      Logger.info(`heanup SMB歌曲通过HTTP代理播放,无需认证头`);
     }
     // 统一设置带认证的请求头
     // 百度类型也需要特殊请求头
@@ -15290,10 +15320,28 @@ export struct LocalMusic {
         if (currentFilePath) {
           this.playedLocalFilePaths.add(currentFilePath);
         }
+
+        // 根据modeType构建不同的查询选项
         const localOptions: RandomSongQueryOptions = {
           type: CommonConstants.TYPE_LOCAL,
           excludeFilePaths: Array.from(this.playedLocalFilePaths)
         };
+
+        Logger.info(TAG, `randomPlay: 本地播放模式, modeType=${this.modeType}, currentPlaylistSongFilePaths.length=${this.currentPlaylistSongFilePaths.length}, currentPath=${this.currentPath}`);
+
+        // modeType==0: 文件夹模式,添加parentPath过滤
+        if (this.modeType === 0 && this.currentPath) {
+          localOptions.parentPath = this.currentPath;
+          Logger.info(TAG, `randomPlay: 文件夹模式, parentPath=${this.currentPath}`);
+        }
+        // modeType==4: 歌单模式,添加playlistSongFilePaths
+        else if (this.modeType === 4 && this.currentPlaylistSongFilePaths.length > 0) {
+          localOptions.playlistSongFilePaths = this.currentPlaylistSongFilePaths;
+          Logger.info(TAG, `randomPlay: 歌单模式,歌曲数量=${this.currentPlaylistSongFilePaths.length}, 前3首=${this.currentPlaylistSongFilePaths.slice(0, 3).join(', ')}`);
+        } else if (this.modeType === 4) {
+          Logger.warn(TAG, `randomPlay: 歌单模式但没有歌曲路径列表! currentPlaylistSongFilePaths.length=${this.currentPlaylistSongFilePaths.length}`);
+        }
+
         let randomLocalSong = await this.table.queryRandomSong(localOptions);
         if (!randomLocalSong) {
           this.playedLocalFilePaths.clear();
@@ -15304,6 +15352,12 @@ export struct LocalMusic {
             type: CommonConstants.TYPE_LOCAL,
             excludeFilePaths: currentFilePath ? [currentFilePath] : []
           };
+          // fallback时也要保持modeType的过滤条件
+          if (this.modeType === 0 && this.currentPath) {
+            fallbackLocalOptions.parentPath = this.currentPath;
+          } else if (this.modeType === 4 && this.currentPlaylistSongFilePaths.length > 0) {
+            fallbackLocalOptions.playlistSongFilePaths = this.currentPlaylistSongFilePaths;
+          }
           randomLocalSong = await this.table.queryRandomSong(fallbackLocalOptions);
         }
         if (randomLocalSong !== null) {
@@ -15346,6 +15400,9 @@ export struct LocalMusic {
           this.curIndex = this.preloadNextRandomIndex;
           this.playedIndices.add(this.curIndex);
           this.preloadNextRandomIndex = -1; // 重置预缓存索引
+
+          // 立即预缓存下一首,避免下次点击时没有预缓存
+          void this.preloadNextSongInternal();
         } else {
           // 如果没有预缓存索引,则正常随机选择
           // 如果所有歌曲都播放过一次,清空已播放索引集合
@@ -15394,6 +15451,9 @@ export struct LocalMusic {
       this.artist = this.songList[this.curIndex].artist
       // this.cover = this.songList[this.curIndex].pixelMapPath
       this.changeImageAnimation()
+
+      // 预缓存下一首(包括网盘和本地)
+      void this.preloadNextSongInternal();
     }
   }
 
@@ -16127,6 +16187,10 @@ export struct LocalMusic {
 
     this.curIndex = startIndex
 
+    // 保存歌单的歌曲路径列表,用于随机播放
+    this.currentPlaylistSongFilePaths = songs.map(song => song.filePath);
+    Logger.info('heanup finishLoadingPlaylist', `保存歌单歌曲路径列表,数量=${this.currentPlaylistSongFilePaths.length}`);
+
     if (songs[startIndex]) {
       // 确保当前播放的歌曲也更新到存储
       AppStorage.setOrCreate('currentSong', songs[startIndex])