From 9bd89265194d8b5db3a0201aedcc4b0ba113d109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B2=E6=82=A6?= Date: Thu, 8 Jan 2026 18:28:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(music=5Fplatform):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=B2=BE=E7=A1=AE=E6=A3=80=E6=9F=A5=E6=AD=8C=E6=9B=B2=E5=8F=AF?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E6=80=A7=E7=9A=84=E9=85=8D=E7=BD=AE=E9=80=89?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加全局配置开关来控制是否启用精确检查歌曲可播放性功能 降低批量检查的并发数量并增加请求间隔以减少网络压力 添加检查成功和失败的统计日志 --- .../service/music_platform/wycloud/index.js | 95 ++++++++++++------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/backend/src/service/music_platform/wycloud/index.js b/backend/src/service/music_platform/wycloud/index.js index 9b03c5d..02f5f5f 100644 --- a/backend/src/service/music_platform/wycloud/index.js +++ b/backend/src/service/music_platform/wycloud/index.js @@ -8,6 +8,7 @@ const fs = require('fs'); const path = require('path'); const {requestApi} = require('./transport'); const { buildSongUrl } = require('../tunehub'); +const configManager = require('../config_manager'); async function uploadSong(uid, filePath) { const response = await safeRequest(uid, cloud, { @@ -201,48 +202,70 @@ async function getSongsFromPlaylist(uid, source, playlistId) { songsMap[song.id] = song; }); - // 使用 check_music API 检查歌曲是否可播放 - // 注意:由于需要批量检查,这里优化为分批处理 - const checkSongsPlayable = async (songIds) => { - const batchSize = 50; // 每批检查50首 - const results = {}; + // 检查是否启用精确检查(默认禁用,因为批量检查可能导致网络问题) + const globalConfig = await configManager.getGlobalConfig(); + const enableAccurateCheck = globalConfig?.enableAccurateCheck === true; - for (let i = 0; i < songIds.length; i += batchSize) { - const batch = songIds.slice(i, i + batchSize); - const batchPromises = batch.map(async (songId) => { - try { - const response = await safeRequest(uid, check_music, { id: songId, br: 999000 }, false); - if (response && response.success === true) { - return { id: songId, playable: true }; - } else { - return { id: songId, playable: false }; + let playableResults = {}; + if (enableAccurateCheck) { + // 使用 check_music API 检查歌曲是否可播放 + // 注意:由于需要批量检查,这里优化为分批处理 + const checkSongsPlayable = async (songIds) => { + const batchSize = 20; // 每批检查20首(降低并发压力) + const results = {}; + let successCount = 0; + let failureCount = 0; + + for (let i = 0; i < songIds.length; i += batchSize) { + const batch = songIds.slice(i, i + batchSize); + const batchPromises = batch.map(async (songId) => { + try { + const response = await safeRequest(uid, check_music, { + id: songId, + br: 999000 + }, false); + + if (response && response.success === true) { + successCount++; + return { id: songId, playable: true }; + } else if (response && response.success === false) { + successCount++; + return { id: songId, playable: false }; + } else { + failureCount++; + return { id: songId, playable: null }; // API调用失败,回退到 privileges 判断 + } + } catch (error) { + failureCount++; + logger.warn(`check music failed for ${songId}: ${error.message}`); + // 如果检查失败,回退到基于 privileges 字段的判断 + return { id: songId, playable: null }; // null 表示未知,需要回退判断 } - } catch (error) { - logger.warn(`check music failed for ${songId}: ${error.message}`); - // 如果检查失败,回退到基于 privileges 字段的判断 - return { id: songId, playable: null }; // null 表示未知,需要回退判断 + }); + + const batchResults = await Promise.all(batchPromises); + batchResults.forEach(result => { + results[result.id] = result.playable; + }); + + // 添加延迟,避免请求过快 + if (i + batchSize < songIds.length) { + await new Promise(resolve => setTimeout(resolve, 300)); // 增加延迟到300ms } - }); - - const batchResults = await Promise.all(batchPromises); - batchResults.forEach(result => { - results[result.id] = result.playable; - }); - - // 添加延迟,避免请求过快 - if (i + batchSize < songIds.length) { - await new Promise(resolve => setTimeout(resolve, 100)); } - } - return results; - }; + logger.info(`[checkSongsPlayable] Success: ${successCount}, Failed: ${failureCount}`); + return results; + }; - // 检查所有歌曲的可播放性 - const songIds = songsResponse.songs.map(song => song.id); - logger.info(`[getSongsFromPlaylist] Checking playable status for ${songIds.length} songs...`); - const playableResults = await checkSongsPlayable(songIds); - logger.info(`[getSongsFromPlaylist] Checked ${Object.keys(playableResults).length} songs`); + // 检查所有歌曲的可播放性 + const songIds = songsResponse.songs.map(song => song.id); + logger.info(`[getSongsFromPlaylist] Checking playable status for ${songIds.length} songs...`); + playableResults = await checkSongsPlayable(songIds); + logger.info(`[getSongsFromPlaylist] Checked ${Object.keys(playableResults).length} songs`); + } else { + logger.info(`[getSongsFromPlaylist] Accurate check disabled, using privileges-based judgment`); + } const isBlockedSong = (song, songInfo, playable) => { // the song has been added to cloud if the pc field is present