|
@@ -76,7 +76,7 @@ import { secondToTime,getTransverterText } from '../common/util/CommUtils';
|
|
|
import { CommonConstants2 } from '../common/util/CommonConstants2';
|
|
import { CommonConstants2 } from '../common/util/CommonConstants2';
|
|
|
import { hilog } from '@kit.PerformanceAnalysisKit';
|
|
import { hilog } from '@kit.PerformanceAnalysisKit';
|
|
|
import { LazyDataSource } from '../common/util/LazyDataSource';
|
|
import { LazyDataSource } from '../common/util/LazyDataSource';
|
|
|
-import MediaTable, { PageQueryOptions, PageQueryResult } from '../common/util/MediaTable';
|
|
|
|
|
|
|
+import MediaTable, { PageQueryOptions, PageQueryResult, RandomSongQueryOptions } from '../common/util/MediaTable';
|
|
|
import FileDeletionWatcher from '../common/util/FileDeletionWatcher';
|
|
import FileDeletionWatcher from '../common/util/FileDeletionWatcher';
|
|
|
import LyricUtil from '../common/util/LyricUtil';
|
|
import LyricUtil from '../common/util/LyricUtil';
|
|
|
import NetAxiosUtil from '../common/util/NetAxiosUtil';
|
|
import NetAxiosUtil from '../common/util/NetAxiosUtil';
|
|
@@ -3236,7 +3236,7 @@ export struct LocalMusic {
|
|
|
y: this.alphabetHeight / 2
|
|
y: this.alphabetHeight / 2
|
|
|
})
|
|
})
|
|
|
.onSelect((index: number) => {
|
|
.onSelect((index: number) => {
|
|
|
- this.onSelectIndexItem(this.alphaBet[index])
|
|
|
|
|
|
|
+ void this.onSelectIndexItem(this.alphaBet[index])
|
|
|
})
|
|
})
|
|
|
.onTouch((event: TouchEvent) =>{
|
|
.onTouch((event: TouchEvent) =>{
|
|
|
this.isShowAlphaBet = true
|
|
this.isShowAlphaBet = true
|
|
@@ -3277,29 +3277,48 @@ export struct LocalMusic {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- onSelectIndexItem(letter: string) {
|
|
|
|
|
- let songs = this.videoLocalList
|
|
|
|
|
- let targetIndex = -1;
|
|
|
|
|
- for (let i = 0; i < songs.length; i++) {
|
|
|
|
|
- let song = songs[i]
|
|
|
|
|
- let text = this.isShowFileName?song.fileName:
|
|
|
|
|
- (song.type!=CommonConstants.TYPE_IS_DIR&&song.pyStr)?song.pyStr:song.name
|
|
|
|
|
- if(this.sortType === 0||this.sortType==1){
|
|
|
|
|
- text = song.artist
|
|
|
|
|
- }else if(this.sortType === 2||this.sortType==3){
|
|
|
|
|
- text = song.album
|
|
|
|
|
- }
|
|
|
|
|
- if(text){
|
|
|
|
|
- let firstPinyin = getFirstLetter(text)
|
|
|
|
|
- if (firstPinyin&&firstPinyin === letter) {
|
|
|
|
|
- targetIndex = i;
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ async onSelectIndexItem(letter: string) {
|
|
|
|
|
+ const findTargetIndex = (): number => {
|
|
|
|
|
+ const songs = this.videoLocalList;
|
|
|
|
|
+ for (let i = 0; i < songs.length; i++) {
|
|
|
|
|
+ const song = songs[i];
|
|
|
|
|
+ let text = this.isShowFileName ? song.fileName :
|
|
|
|
|
+ (song.type != CommonConstants.TYPE_IS_DIR && song.pyStr) ? song.pyStr : song.name;
|
|
|
|
|
+ if (this.sortType === 0 || this.sortType == 1) {
|
|
|
|
|
+ text = song.artist;
|
|
|
|
|
+ } else if (this.sortType === 2 || this.sortType == 3) {
|
|
|
|
|
+ text = song.album;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (text) {
|
|
|
|
|
+ const firstPinyin = getFirstLetter(text);
|
|
|
|
|
+ if (firstPinyin && firstPinyin === letter) {
|
|
|
|
|
+ return i;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ let targetIndex = findTargetIndex();
|
|
|
|
|
+ let attempts = 0;
|
|
|
|
|
+ const canLoadMore = () =>
|
|
|
|
|
+ !this.isCanBack &&
|
|
|
|
|
+ (this.modeType === 1 || this.modeType === 2 || this.modeType === 3) &&
|
|
|
|
|
+ this.hasMoreData &&
|
|
|
|
|
+ !this.isLoadingPage;
|
|
|
|
|
|
|
|
|
|
+ while (targetIndex === -1 && canLoadMore() && attempts < 10) {
|
|
|
|
|
+ await this.loadNextPage();
|
|
|
|
|
+ targetIndex = findTargetIndex();
|
|
|
|
|
+ attempts++;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
if (targetIndex !== -1) {
|
|
if (targetIndex !== -1) {
|
|
|
- this.listScroller.scrollToIndex(targetIndex);
|
|
|
|
|
|
|
+ if (this.isGridMusic || this.twoFingerType == 4) {
|
|
|
|
|
+ this.scroller.scrollToIndex(targetIndex, false);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.listScroller.scrollToIndex(targetIndex);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
// 找到对应字母表的索引
|
|
// 找到对应字母表的索引
|
|
@@ -14602,13 +14621,95 @@ export struct LocalMusic {
|
|
|
|
|
|
|
|
// 存储已播放的歌曲索引
|
|
// 存储已播放的歌曲索引
|
|
|
private playedIndices: Set<number> = new Set();
|
|
private playedIndices: Set<number> = new Set();
|
|
|
|
|
+ // 存储已播放的本地歌曲路径(随机播放去重用)
|
|
|
|
|
+ private playedLocalFilePaths: Set<string> = new Set();
|
|
|
|
|
|
|
|
//随机播放
|
|
//随机播放
|
|
|
private async randomPlay() {
|
|
private async randomPlay() {
|
|
|
// if (!this.debounce()) {
|
|
// if (!this.debounce()) {
|
|
|
// return;
|
|
// return;
|
|
|
// }
|
|
// }
|
|
|
|
|
+ if (this.currentSong) {
|
|
|
|
|
+ const isCurrentRemote = isRemoteCloudType(this.currentSong.type);
|
|
|
|
|
+ const currentFilePath = this.currentSong.filePath;
|
|
|
|
|
+ if (isCurrentRemote) {
|
|
|
|
|
+ const remoteOptions: RandomSongQueryOptions = {
|
|
|
|
|
+ type: this.currentSong.type,
|
|
|
|
|
+ excludeFilePaths: currentFilePath ? [currentFilePath] : []
|
|
|
|
|
+ };
|
|
|
|
|
+ const randomRemoteSong = await this.table.queryRandomSong(remoteOptions);
|
|
|
|
|
+ if (randomRemoteSong) {
|
|
|
|
|
+ let nextIndex = this.songList.findIndex(song => song.filePath === randomRemoteSong.filePath);
|
|
|
|
|
+ if (nextIndex < 0) {
|
|
|
|
|
+ this.songList = [...this.songList, randomRemoteSong];
|
|
|
|
|
+ this.sonDataSource.pushArrayData(this.songList);
|
|
|
|
|
+ nextIndex = this.songList.length - 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.curIndex = nextIndex;
|
|
|
|
|
+ this.playedIndices.add(this.curIndex);
|
|
|
|
|
+ this.CONTROL_PlayStatus = PlayStatus.INIT;
|
|
|
|
|
+ this.stop();
|
|
|
|
|
+ this.currentSong = randomRemoteSong;
|
|
|
|
|
+ // 设置videoUrl,WebDAV歌曲会通过webdav_account_id构建完整URL
|
|
|
|
|
+ this.videoUrl = await setVideoUrlForSong(this.currentSong, {
|
|
|
|
|
+ context: this.context,
|
|
|
|
|
+ autoParseMusicName: this.autoParseMusicName
|
|
|
|
|
+ });
|
|
|
|
|
+ this.name = this.currentSong.name;
|
|
|
|
|
+ this.artist = this.currentSong.artist;
|
|
|
|
|
+ this.changeImageAnimation();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Logger.warn(TAG, '随机播放未获取到网盘歌曲,回退到列表随机');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (currentFilePath) {
|
|
|
|
|
+ this.playedLocalFilePaths.add(currentFilePath);
|
|
|
|
|
+ }
|
|
|
|
|
+ const localOptions: RandomSongQueryOptions = {
|
|
|
|
|
+ type: CommonConstants.TYPE_LOCAL,
|
|
|
|
|
+ excludeFilePaths: Array.from(this.playedLocalFilePaths)
|
|
|
|
|
+ };
|
|
|
|
|
+ let randomLocalSong = await this.table.queryRandomSong(localOptions);
|
|
|
|
|
+ if (!randomLocalSong) {
|
|
|
|
|
+ this.playedLocalFilePaths.clear();
|
|
|
|
|
+ if (currentFilePath) {
|
|
|
|
|
+ this.playedLocalFilePaths.add(currentFilePath);
|
|
|
|
|
+ }
|
|
|
|
|
+ const fallbackLocalOptions: RandomSongQueryOptions = {
|
|
|
|
|
+ type: CommonConstants.TYPE_LOCAL,
|
|
|
|
|
+ excludeFilePaths: currentFilePath ? [currentFilePath] : []
|
|
|
|
|
+ };
|
|
|
|
|
+ randomLocalSong = await this.table.queryRandomSong(fallbackLocalOptions);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (randomLocalSong !== null) {
|
|
|
|
|
+ const selectedLocalSong = randomLocalSong;
|
|
|
|
|
+ let nextIndex = this.songList.findIndex(song => song.filePath === selectedLocalSong.filePath);
|
|
|
|
|
+ if (nextIndex < 0) {
|
|
|
|
|
+ this.songList = [...this.songList, selectedLocalSong];
|
|
|
|
|
+ this.sonDataSource.pushArrayData(this.songList);
|
|
|
|
|
+ nextIndex = this.songList.length - 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.curIndex = nextIndex;
|
|
|
|
|
+ this.playedIndices.add(this.curIndex);
|
|
|
|
|
+ this.CONTROL_PlayStatus = PlayStatus.INIT;
|
|
|
|
|
+ this.stop();
|
|
|
|
|
+ this.currentSong = selectedLocalSong;
|
|
|
|
|
+ this.videoUrl = await setVideoUrlForSong(this.currentSong, {
|
|
|
|
|
+ context: this.context,
|
|
|
|
|
+ autoParseMusicName: this.autoParseMusicName
|
|
|
|
|
+ });
|
|
|
|
|
+ this.name = this.currentSong.name;
|
|
|
|
|
+ this.artist = this.currentSong.artist;
|
|
|
|
|
+ this.changeImageAnimation();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Logger.warn(TAG, '随机播放未获取到本地歌曲,回退到列表随机');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
if (ArrayUtil.isNotEmpty(this.songList)) {
|
|
if (ArrayUtil.isNotEmpty(this.songList)) {
|
|
|
|
|
+ if (this.curIndex >= 0 && this.curIndex < this.songList.length) {
|
|
|
|
|
+ this.playedIndices.add(this.curIndex);
|
|
|
|
|
+ }
|
|
|
if (this.songList.length > 3) {
|
|
if (this.songList.length > 3) {
|
|
|
// 优先使用预缓存的随机索引(仅网盘播放时)
|
|
// 优先使用预缓存的随机索引(仅网盘播放时)
|
|
|
const nextSong = this.songList[this.preloadNextRandomIndex >= 0 ? this.preloadNextRandomIndex : 0];
|
|
const nextSong = this.songList[this.preloadNextRandomIndex >= 0 ? this.preloadNextRandomIndex : 0];
|