|
|
@@ -825,3 +825,115 @@ export function extractFtpRelativePath(song: VideoItem): string {
|
|
|
}
|
|
|
return song.filePath.replace(/^\/+/, '');
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 检查网盘歌曲是否已缓存
|
|
|
+ * @param song 歌曲对象
|
|
|
+ * @returns Promise<boolean> true表示已缓存,false表示未缓存或检查失败
|
|
|
+ */
|
|
|
+export async function isRemoteSongCached(song: VideoItem): Promise<boolean> {
|
|
|
+ if (!song || !isRemoteCloudType(song.type) || !song.webdav_account_id) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const manager = RemoteDriveManager.getInstance();
|
|
|
+ const account = await manager.getWebDavAccountById(song.webdav_account_id);
|
|
|
+ if (!account) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // WebDAV类型
|
|
|
+ if (isWebDavType(song.type)) {
|
|
|
+ const relativePath = song.remote_rel_path || song.filePath;
|
|
|
+ const cachePath = await findWebDavCacheIfExists(account, relativePath);
|
|
|
+ return cachePath !== null && cachePath !== undefined;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Navidrome类型
|
|
|
+ if (isNavidromeType(song.type)) {
|
|
|
+ const navSongId = song.remote_rel_path || song.id || song.filePath;
|
|
|
+ const normalizedRelative = normalizeCacheRelativePath(navSongId);
|
|
|
+ const pathInfo = await resolveCacheFilePath(
|
|
|
+ RemoteCacheType.NAVIDROME,
|
|
|
+ account.id?.toString(),
|
|
|
+ normalizedRelative
|
|
|
+ );
|
|
|
+ const exists = await FileManager.isExist(pathInfo.cachePath);
|
|
|
+ if (!exists) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const size = await FileManager.getFileSize(pathInfo.cachePath);
|
|
|
+ // 检查文件完整性
|
|
|
+ if (song.videoSize > 0 && size < song.videoSize * 0.95) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Jellyfin类型
|
|
|
+ if (isJellyfinType(song.type)) {
|
|
|
+ const jellyfinSongId = song.remote_rel_path || song.id || song.filePath;
|
|
|
+ const normalizedRelative = normalizeCacheRelativePath(jellyfinSongId);
|
|
|
+ const pathInfo = await resolveCacheFilePath(
|
|
|
+ RemoteCacheType.JELLYFIN,
|
|
|
+ account.id?.toString(),
|
|
|
+ normalizedRelative
|
|
|
+ );
|
|
|
+ const exists = await FileManager.isExist(pathInfo.cachePath);
|
|
|
+ if (!exists) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const size = await FileManager.getFileSize(pathInfo.cachePath);
|
|
|
+ if (song.videoSize > 0 && size < song.videoSize * 0.95) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Emby类型
|
|
|
+ if (isEmbyType(song.type)) {
|
|
|
+ const embySongId = song.remote_rel_path || song.id || song.filePath;
|
|
|
+ const normalizedRelative = normalizeCacheRelativePath(embySongId);
|
|
|
+ const pathInfo = await resolveCacheFilePath(
|
|
|
+ RemoteCacheType.EMBY,
|
|
|
+ account.id?.toString(),
|
|
|
+ normalizedRelative
|
|
|
+ );
|
|
|
+ const exists = await FileManager.isExist(pathInfo.cachePath);
|
|
|
+ if (!exists) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const size = await FileManager.getFileSize(pathInfo.cachePath);
|
|
|
+ if (song.videoSize > 0 && size < song.videoSize * 0.95) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 百度网盘类型
|
|
|
+ if (isBaiduType(song.type)) {
|
|
|
+ const relativePath = song.remote_rel_path || song.name || song.fileName || song.filePath;
|
|
|
+ const cachedPath = await resolveCacheFilePath(
|
|
|
+ RemoteCacheType.BAIDU,
|
|
|
+ account.id?.toString(),
|
|
|
+ relativePath
|
|
|
+ );
|
|
|
+ const fileExists = await FileManager.isExist(cachedPath.cachePath);
|
|
|
+ if (!fileExists) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const fileSize = await FileManager.getFileSize(cachedPath.cachePath);
|
|
|
+ if (song.videoSize > 0 && fileSize < song.videoSize * 0.9) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ } catch (error) {
|
|
|
+ const err = error as Error;
|
|
|
+ Logger.error(TAG, `检查网盘歌曲缓存状态失败: ${err.message}`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|