|
|
@@ -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])
|