|
@@ -14,7 +14,7 @@ import { WebDavAccount } from '../viewmodel/WebDavAccount';
|
|
|
import Logger from '../common/util/Logger';
|
|
import Logger from '../common/util/Logger';
|
|
|
import { RemoteDriveType } from '../common/enums/RemoteDriveType';
|
|
import { RemoteDriveType } from '../common/enums/RemoteDriveType';
|
|
|
import { navidromeRestApi, NavidromeRestAlbum, NavidromeRestArtist, NavidromeRestSong, NavidromeRestPlaylist } from '../common/network/NavidromeRestApi';
|
|
import { navidromeRestApi, NavidromeRestAlbum, NavidromeRestArtist, NavidromeRestSong, NavidromeRestPlaylist } from '../common/network/NavidromeRestApi';
|
|
|
-import { Utility } from '../common/util/Utility';
|
|
|
|
|
|
|
+import { resolveAudioQualityTag, Utility } from '../common/util/Utility';
|
|
|
import { Constants } from '../Constants';
|
|
import { Constants } from '../Constants';
|
|
|
import { EventConstants } from '../common/constants/EventConstants';
|
|
import { EventConstants } from '../common/constants/EventConstants';
|
|
|
import { emitter } from '@kit.BasicServicesKit';
|
|
import { emitter } from '@kit.BasicServicesKit';
|
|
@@ -77,6 +77,85 @@ class AudioStationAlbumKey {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function parseAudioMetricValue(value?: string): number | undefined {
|
|
|
|
|
+ if (!value || value.trim().length === 0) {
|
|
|
|
|
+ return undefined;
|
|
|
|
|
+ }
|
|
|
|
|
+ const normalized = value.trim().toLowerCase();
|
|
|
|
|
+ const directValue = Number(normalized);
|
|
|
|
|
+ if (Number.isFinite(directValue) && directValue > 0) {
|
|
|
|
|
+ return directValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ const numericValue = parseFloat(normalized);
|
|
|
|
|
+ if (!Number.isFinite(numericValue) || numericValue <= 0) {
|
|
|
|
|
+ return undefined;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (normalized.includes('kbps') || normalized.includes('khz')) {
|
|
|
|
|
+ return numericValue * 1000;
|
|
|
|
|
+ }
|
|
|
|
|
+ return numericValue;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function buildRemoteSongFileName(song: NavidromeRestSong): string {
|
|
|
|
|
+ const title = song.title ?? Constants.UNKNOWN_TITLE;
|
|
|
|
|
+ return `${title}${song.suffix ? '.' + song.suffix : ''}`;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function extractAudioExtension(fileName: string): string {
|
|
|
|
|
+ if (!fileName || fileName.length === 0) {
|
|
|
|
|
+ return '';
|
|
|
|
|
+ }
|
|
|
|
|
+ const lastDotIndex = fileName.lastIndexOf('.');
|
|
|
|
|
+ if (lastDotIndex < 0 || lastDotIndex >= fileName.length - 1) {
|
|
|
|
|
+ return '';
|
|
|
|
|
+ }
|
|
|
|
|
+ return fileName.substring(lastDotIndex);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function resolveInitialRemoteSongQuality(formatHint: string, fallbackFileName: string, bitrate?: number,
|
|
|
|
|
+ sampleRate?: number): string {
|
|
|
|
|
+ const directQuality = resolveAudioQualityTag(formatHint, bitrate, sampleRate);
|
|
|
|
|
+ if (directQuality.length > 0) {
|
|
|
|
|
+ return directQuality;
|
|
|
|
|
+ }
|
|
|
|
|
+ const fallbackExtension = extractAudioExtension(fallbackFileName);
|
|
|
|
|
+ if (fallbackExtension.length === 0) {
|
|
|
|
|
+ return '';
|
|
|
|
|
+ }
|
|
|
|
|
+ return resolveAudioQualityTag(fallbackExtension, bitrate, sampleRate);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function applyInitialRemoteSongQuality(videoItem: VideoItem, song: NavidromeRestSong, fallbackFileName: string): void {
|
|
|
|
|
+ const quality = resolveInitialRemoteSongQuality(song.suffix ?? song.contentType ?? '', fallbackFileName, song.bitRate,
|
|
|
|
|
+ song.sampleRate);
|
|
|
|
|
+ if (quality.length > 0) {
|
|
|
|
|
+ videoItem.md5Str = quality;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (song.sampleRate !== undefined && song.sampleRate !== null && song.sampleRate > 0) {
|
|
|
|
|
+ videoItem.sampleRate = song.sampleRate.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function applyInitialQualityToExistingVideoItem(videoItem: VideoItem): void {
|
|
|
|
|
+ if (!videoItem || (videoItem.md5Str && videoItem.md5Str.length > 0)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const fallbackFileName = videoItem.fileName ?? videoItem.name ?? '';
|
|
|
|
|
+ const bitrate = parseAudioMetricValue(videoItem.bit_rate);
|
|
|
|
|
+ const sampleRate = parseAudioMetricValue(videoItem.sampleRate);
|
|
|
|
|
+ const quality = resolveInitialRemoteSongQuality(videoItem.mimeType ?? '', fallbackFileName, bitrate, sampleRate);
|
|
|
|
|
+ if (quality.length > 0) {
|
|
|
|
|
+ videoItem.md5Str = quality;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function buildSongQualityLabelText(quality?: string): string {
|
|
|
|
|
+ if (!quality || quality.length === 0) {
|
|
|
|
|
+ return '';
|
|
|
|
|
+ }
|
|
|
|
|
+ return quality.includes('Lossless') ? '无损' : quality;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* taskpool 任务结果接口
|
|
* taskpool 任务结果接口
|
|
|
* 返回带封面的完整数据
|
|
* 返回带封面的完整数据
|
|
@@ -505,6 +584,7 @@ export struct RemoteMusicPage {
|
|
|
|
|
|
|
|
let loadedFromCache = false;
|
|
let loadedFromCache = false;
|
|
|
if (cachedData.songs && cachedData.songs.length > 0) {
|
|
if (cachedData.songs && cachedData.songs.length > 0) {
|
|
|
|
|
+ this.hydrateSongQuality(cachedData.songs);
|
|
|
this.allVideos = cachedData.songs;
|
|
this.allVideos = cachedData.songs;
|
|
|
this.songDataSource.pushArrayData(cachedData.songs);
|
|
this.songDataSource.pushArrayData(cachedData.songs);
|
|
|
loadedFromCache = true;
|
|
loadedFromCache = true;
|
|
@@ -560,6 +640,7 @@ export struct RemoteMusicPage {
|
|
|
|
|
|
|
|
// 直接更新数据(封面已在后台处理)
|
|
// 直接更新数据(封面已在后台处理)
|
|
|
if (taskResult.songs && taskResult.songs.length > 0) {
|
|
if (taskResult.songs && taskResult.songs.length > 0) {
|
|
|
|
|
+ this.hydrateSongQuality(taskResult.songs);
|
|
|
this.allVideos = taskResult.songs;
|
|
this.allVideos = taskResult.songs;
|
|
|
this.songDataSource.pushArrayData(taskResult.songs);
|
|
this.songDataSource.pushArrayData(taskResult.songs);
|
|
|
}
|
|
}
|
|
@@ -1889,6 +1970,7 @@ export struct RemoteMusicPage {
|
|
|
artistId: song.artistId,
|
|
artistId: song.artistId,
|
|
|
duration: song.durationSeconds,
|
|
duration: song.durationSeconds,
|
|
|
bitRate: song.bitRate,
|
|
bitRate: song.bitRate,
|
|
|
|
|
+ sampleRate: song.sampleRate,
|
|
|
suffix: song.suffix,
|
|
suffix: song.suffix,
|
|
|
size: song.size,
|
|
size: song.size,
|
|
|
track: song.track,
|
|
track: song.track,
|
|
@@ -1910,6 +1992,7 @@ export struct RemoteMusicPage {
|
|
|
artistId: song.artistId,
|
|
artistId: song.artistId,
|
|
|
duration: song.durationSeconds,
|
|
duration: song.durationSeconds,
|
|
|
bitRate: song.bitRate,
|
|
bitRate: song.bitRate,
|
|
|
|
|
+ sampleRate: song.sampleRate,
|
|
|
suffix: song.suffix,
|
|
suffix: song.suffix,
|
|
|
size: song.size,
|
|
size: song.size,
|
|
|
track: song.track,
|
|
track: song.track,
|
|
@@ -1934,6 +2017,7 @@ export struct RemoteMusicPage {
|
|
|
artistId: artistName,
|
|
artistId: artistName,
|
|
|
duration: song.durationSeconds,
|
|
duration: song.durationSeconds,
|
|
|
bitRate: song.bitRate,
|
|
bitRate: song.bitRate,
|
|
|
|
|
+ sampleRate: song.sampleRate,
|
|
|
suffix: song.container,
|
|
suffix: song.container,
|
|
|
size: song.size,
|
|
size: song.size,
|
|
|
track: song.track,
|
|
track: song.track,
|
|
@@ -1957,6 +2041,7 @@ export struct RemoteMusicPage {
|
|
|
artistId: song.artistId,
|
|
artistId: song.artistId,
|
|
|
duration: song.durationSeconds,
|
|
duration: song.durationSeconds,
|
|
|
bitRate: song.bitRate,
|
|
bitRate: song.bitRate,
|
|
|
|
|
+ sampleRate: song.sampleRate,
|
|
|
suffix: song.suffix,
|
|
suffix: song.suffix,
|
|
|
size: song.size,
|
|
size: song.size,
|
|
|
track: song.track,
|
|
track: song.track,
|
|
@@ -1980,6 +2065,7 @@ export struct RemoteMusicPage {
|
|
|
artistId: song.artistId,
|
|
artistId: song.artistId,
|
|
|
duration: song.durationSeconds,
|
|
duration: song.durationSeconds,
|
|
|
bitRate: song.bitRate,
|
|
bitRate: song.bitRate,
|
|
|
|
|
+ sampleRate: song.sampleRate ?? undefined,
|
|
|
suffix: song.suffix,
|
|
suffix: song.suffix,
|
|
|
size: song.size,
|
|
size: song.size,
|
|
|
track: song.track,
|
|
track: song.track,
|
|
@@ -2398,6 +2484,7 @@ export struct RemoteMusicPage {
|
|
|
private convertSongToVideoItem(song: NavidromeRestSong, account: WebDavAccount, coverUrl?: string): VideoItem {
|
|
private convertSongToVideoItem(song: NavidromeRestSong, account: WebDavAccount, coverUrl?: string): VideoItem {
|
|
|
const title = song.title ?? Constants.UNKNOWN_TITLE;
|
|
const title = song.title ?? Constants.UNKNOWN_TITLE;
|
|
|
const libraryInfo = this.resolveLibraryInfo(account);
|
|
const libraryInfo = this.resolveLibraryInfo(account);
|
|
|
|
|
+ const fileName = buildRemoteSongFileName(song);
|
|
|
|
|
|
|
|
// 调试日志:记录从playlist或其他API获取的歌曲的id字段
|
|
// 调试日志:记录从playlist或其他API获取的歌曲的id字段
|
|
|
void ServerLogUtil.debug('SongConvert', `转换歌曲: ${title}`);
|
|
void ServerLogUtil.debug('SongConvert', `转换歌曲: ${title}`);
|
|
@@ -2416,7 +2503,7 @@ export struct RemoteMusicPage {
|
|
|
undefined,
|
|
undefined,
|
|
|
song.artist ?? Constants.UNKNOWN_ARTIST,
|
|
song.artist ?? Constants.UNKNOWN_ARTIST,
|
|
|
song.album ?? '',
|
|
song.album ?? '',
|
|
|
- `${title}${song.suffix ? '.' + song.suffix : ''}`
|
|
|
|
|
|
|
+ fileName
|
|
|
);
|
|
);
|
|
|
const durationStr = this.formatSongDuration(song.duration);
|
|
const durationStr = this.formatSongDuration(song.duration);
|
|
|
if (durationStr) {
|
|
if (durationStr) {
|
|
@@ -2445,6 +2532,7 @@ export struct RemoteMusicPage {
|
|
|
if (song.contentType) {
|
|
if (song.contentType) {
|
|
|
videoItem.mimeType = song.contentType;
|
|
videoItem.mimeType = song.contentType;
|
|
|
}
|
|
}
|
|
|
|
|
+ applyInitialRemoteSongQuality(videoItem, song, fileName);
|
|
|
|
|
|
|
|
// 记录最终生成的VideoItem路径
|
|
// 记录最终生成的VideoItem路径
|
|
|
void ServerLogUtil.debug('SongConvert', `- VideoItem.filePath: ${videoItem.filePath}`);
|
|
void ServerLogUtil.debug('SongConvert', `- VideoItem.filePath: ${videoItem.filePath}`);
|
|
@@ -2939,6 +3027,17 @@ export struct RemoteMusicPage {
|
|
|
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
|
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
|
|
|
|
|
|
|
Row() {
|
|
Row() {
|
|
|
|
|
+ if (StrUtil.isNotEmpty(song.md5Str)) {
|
|
|
|
|
+ Text(this.buildSongQualityLabel(song))
|
|
|
|
|
+ .fontSize(this.twoFingerType == 1 ? 8 : 10)
|
|
|
|
|
+ .fontColor($r('app.color.index_tab_font_color'))
|
|
|
|
|
+ .fontWeight(500)
|
|
|
|
|
+ .padding({ top: 2, right: 6, left: 6, bottom: 2 })
|
|
|
|
|
+ .borderRadius(4)
|
|
|
|
|
+ .backgroundColor('#FFC107')
|
|
|
|
|
+ .opacity(0.92)
|
|
|
|
|
+ .margin({ right: 6 })
|
|
|
|
|
+ }
|
|
|
Text((song.artist ?? '') + " ")
|
|
Text((song.artist ?? '') + " ")
|
|
|
.fontSize(this.twoFingerType == 1 ? 11 : this.twoFingerType == 2 ? 12 : 14)
|
|
.fontSize(this.twoFingerType == 1 ? 11 : this.twoFingerType == 2 ? 12 : 14)
|
|
|
.fontColor(this.currentSong?.filePath == song.filePath ? this.themeColor : $r('app.color.index_tab_font_color'))
|
|
.fontColor(this.currentSong?.filePath == song.filePath ? this.themeColor : $r('app.color.index_tab_font_color'))
|
|
@@ -3141,6 +3240,19 @@ export struct RemoteMusicPage {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private hydrateSongQuality(items: VideoItem[]): void {
|
|
|
|
|
+ if (!items || items.length === 0) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (let i = 0; i < items.length; i++) {
|
|
|
|
|
+ applyInitialQualityToExistingVideoItem(items[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private buildSongQualityLabel(song: VideoItem): string {
|
|
|
|
|
+ return buildSongQualityLabelText(song.md5Str);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private buildSongMetaLine(song: VideoItem): string {
|
|
private buildSongMetaLine(song: VideoItem): string {
|
|
|
const parts: string[] = [];
|
|
const parts: string[] = [];
|
|
|
if (song.duration) {
|
|
if (song.duration) {
|
|
@@ -3720,7 +3832,18 @@ export struct RemoteMusicPage {
|
|
|
// .fontSize(this.twoFingerType == 1 ? 10 : this.twoFingerType == 2 ? 12 : 14)
|
|
// .fontSize(this.twoFingerType == 1 ? 10 : this.twoFingerType == 2 ? 12 : 14)
|
|
|
// .fontColor($r('app.color.text_color'))
|
|
// .fontColor($r('app.color.text_color'))
|
|
|
Row(){
|
|
Row(){
|
|
|
-
|
|
|
|
|
|
|
+ if (StrUtil.isNotEmpty(item.md5Str)) {
|
|
|
|
|
+ Text(this.buildSongQualityLabel(item))
|
|
|
|
|
+ .fontSize(this.twoFingerType == 1 ? 8 : 9)
|
|
|
|
|
+ .fontColor($r('app.color.index_tab_font_color'))
|
|
|
|
|
+ .fontWeight(500)
|
|
|
|
|
+ .padding({ top: 2, right: 5, left: 5, bottom: 2 })
|
|
|
|
|
+ .borderRadius(4)
|
|
|
|
|
+ .backgroundColor('#FFC107')
|
|
|
|
|
+ .opacity(0.92)
|
|
|
|
|
+ .margin({ top: 2, right: 6 })
|
|
|
|
|
+ .visibility(StrUtil.isEmpty(item.md5Str) ? Visibility.None : Visibility.Visible)
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
Text((item.artist ?? '') + " ")
|
|
Text((item.artist ?? '') + " ")
|
|
|
.fontSize(this.twoFingerType == 1 ? 10 : this.twoFingerType == 2 ? 12 : 13)
|
|
.fontSize(this.twoFingerType == 1 ? 10 : this.twoFingerType == 2 ? 12 : 13)
|
|
@@ -3751,7 +3874,7 @@ export struct RemoteMusicPage {
|
|
|
}
|
|
}
|
|
|
.width(this.getGridWight())
|
|
.width(this.getGridWight())
|
|
|
.borderRadius(12)
|
|
.borderRadius(12)
|
|
|
- .backgroundColor(this.isDarkMode ? '#141414' : '#F7F7F7')
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.com_bg'))
|
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
|
|
|
|
|
|
|
|
|
|
@@ -3887,7 +4010,7 @@ export struct RemoteMusicPage {
|
|
|
}
|
|
}
|
|
|
.width(this.getGridWight())
|
|
.width(this.getGridWight())
|
|
|
.borderRadius(12)
|
|
.borderRadius(12)
|
|
|
- .backgroundColor(this.isDarkMode ? '#141414' : '#F7F7F7')
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.com_bg'))
|
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -3971,7 +4094,7 @@ export struct RemoteMusicPage {
|
|
|
}
|
|
}
|
|
|
.width(this.getGridWight())
|
|
.width(this.getGridWight())
|
|
|
.borderRadius(12)
|
|
.borderRadius(12)
|
|
|
- .backgroundColor(this.isDarkMode ? '#141414' : '#F7F7F7')
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.com_bg'))
|
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -4055,7 +4178,7 @@ export struct RemoteMusicPage {
|
|
|
}
|
|
}
|
|
|
.width(this.getGridWight())
|
|
.width(this.getGridWight())
|
|
|
.borderRadius(12)
|
|
.borderRadius(12)
|
|
|
- .backgroundColor(this.isDarkMode ? '#141414' : '#F7F7F7')
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.com_bg'))
|
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -4437,6 +4560,17 @@ export struct RemoteMusicPage {
|
|
|
.fontColor(this.currentSong?.filePath === item.filePath ? this.themeColor : $r('app.color.text_color'))
|
|
.fontColor(this.currentSong?.filePath === item.filePath ? this.themeColor : $r('app.color.text_color'))
|
|
|
|
|
|
|
|
Row() {
|
|
Row() {
|
|
|
|
|
+ if (StrUtil.isNotEmpty(item.md5Str)) {
|
|
|
|
|
+ Text(this.buildSongQualityLabel(item))
|
|
|
|
|
+ .fontSize(this.columns == 4 || this.columns == 3 ? 8 : 9)
|
|
|
|
|
+ .fontColor($r('app.color.index_tab_font_color'))
|
|
|
|
|
+ .fontWeight(500)
|
|
|
|
|
+ .padding({ top: 2, right: 5, left: 5, bottom: 2 })
|
|
|
|
|
+ .borderRadius(4)
|
|
|
|
|
+ .backgroundColor('#FFC107')
|
|
|
|
|
+ .opacity(0.92)
|
|
|
|
|
+ .margin({ top: 2, right: 6 })
|
|
|
|
|
+ }
|
|
|
Text(item.artist || '')
|
|
Text(item.artist || '')
|
|
|
.fontSize(this.columns == 4 || this.columns == 3 ? 10 : this.columns == 2 ? 12 : 13)
|
|
.fontSize(this.columns == 4 || this.columns == 3 ? 10 : this.columns == 2 ? 12 : 13)
|
|
|
.maxLines(1)
|
|
.maxLines(1)
|
|
@@ -4458,7 +4592,7 @@ export struct RemoteMusicPage {
|
|
|
}
|
|
}
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
.borderRadius(12)
|
|
.borderRadius(12)
|
|
|
- .backgroundColor(this.isDarkMode ? '#141414' : '#F7F7F7')
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.com_bg'))
|
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -4525,7 +4659,7 @@ export struct RemoteMusicPage {
|
|
|
}
|
|
}
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
.borderRadius(12)
|
|
.borderRadius(12)
|
|
|
- .backgroundColor(this.isDarkMode ? '#141414' : '#F7F7F7')
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.com_bg'))
|
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -4592,7 +4726,7 @@ export struct RemoteMusicPage {
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
.height('auto')
|
|
.height('auto')
|
|
|
.borderRadius(12)
|
|
.borderRadius(12)
|
|
|
- .backgroundColor(this.isDarkMode ? '#141414' : '#F7F7F7')
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.com_bg'))
|
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -4658,7 +4792,7 @@ export struct RemoteMusicPage {
|
|
|
}
|
|
}
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
.borderRadius(12)
|
|
.borderRadius(12)
|
|
|
- .backgroundColor(this.isDarkMode ? '#141414' : '#F7F7F7')
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.com_bg'))
|
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
.animation({ curve: Curve.Sharp, duration: 300 })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -4716,6 +4850,7 @@ async function loadNavidromeDataTask(accountData: AccountData, ticket: number):
|
|
|
for (let i = 0; i < chunk.length; i++) {
|
|
for (let i = 0; i < chunk.length; i++) {
|
|
|
const song: NavidromeRestSong = chunk[i];
|
|
const song: NavidromeRestSong = chunk[i];
|
|
|
const title: string = song.title ?? Constants.UNKNOWN_TITLE;
|
|
const title: string = song.title ?? Constants.UNKNOWN_TITLE;
|
|
|
|
|
+ const fileName: string = `${title}${song.suffix ? '.' + song.suffix : ''}`;
|
|
|
|
|
|
|
|
// 获取库类型
|
|
// 获取库类型
|
|
|
let libraryType = CommonConstants.TYPE_NAVIDROME;
|
|
let libraryType = CommonConstants.TYPE_NAVIDROME;
|
|
@@ -4739,7 +4874,7 @@ async function loadNavidromeDataTask(accountData: AccountData, ticket: number):
|
|
|
undefined,
|
|
undefined,
|
|
|
song.artist ?? Constants.UNKNOWN_ARTIST,
|
|
song.artist ?? Constants.UNKNOWN_ARTIST,
|
|
|
song.album ?? '',
|
|
song.album ?? '',
|
|
|
- `${title}${song.suffix ? '.' + song.suffix : ''}`
|
|
|
|
|
|
|
+ fileName
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
// 设置时长
|
|
// 设置时长
|
|
@@ -4769,6 +4904,21 @@ async function loadNavidromeDataTask(accountData: AccountData, ticket: number):
|
|
|
if (song.contentType) {
|
|
if (song.contentType) {
|
|
|
videoItem.mimeType = song.contentType;
|
|
videoItem.mimeType = song.contentType;
|
|
|
}
|
|
}
|
|
|
|
|
+ let initialQuality: string = resolveAudioQualityTag(song.suffix ?? song.contentType ?? '', song.bitRate,
|
|
|
|
|
+ song.sampleRate);
|
|
|
|
|
+ if (initialQuality.length === 0) {
|
|
|
|
|
+ const lastDotIndex = fileName.lastIndexOf('.');
|
|
|
|
|
+ if (lastDotIndex >= 0 && lastDotIndex < fileName.length - 1) {
|
|
|
|
|
+ const fallbackExtension = fileName.substring(lastDotIndex);
|
|
|
|
|
+ initialQuality = resolveAudioQualityTag(fallbackExtension, song.bitRate, song.sampleRate);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (initialQuality.length > 0) {
|
|
|
|
|
+ videoItem.md5Str = initialQuality;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (song.sampleRate !== undefined && song.sampleRate !== null && song.sampleRate > 0) {
|
|
|
|
|
+ videoItem.sampleRate = song.sampleRate.toString();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 处理封面(在 worker 线程中调用 API)
|
|
// 处理封面(在 worker 线程中调用 API)
|
|
|
let coverUrl: string | undefined = undefined;
|
|
let coverUrl: string | undefined = undefined;
|