feat(music_platform): 增加精确检查歌曲可播放性的配置选项
添加全局配置开关来控制是否启用精确检查歌曲可播放性功能 降低批量检查的并发数量并增加请求间隔以减少网络压力 添加检查成功和失败的统计日志
This commit is contained in:
@@ -8,6 +8,7 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const {requestApi} = require('./transport');
|
const {requestApi} = require('./transport');
|
||||||
const { buildSongUrl } = require('../tunehub');
|
const { buildSongUrl } = require('../tunehub');
|
||||||
|
const configManager = require('../config_manager');
|
||||||
|
|
||||||
async function uploadSong(uid, filePath) {
|
async function uploadSong(uid, filePath) {
|
||||||
const response = await safeRequest(uid, cloud, {
|
const response = await safeRequest(uid, cloud, {
|
||||||
@@ -201,48 +202,70 @@ async function getSongsFromPlaylist(uid, source, playlistId) {
|
|||||||
songsMap[song.id] = song;
|
songsMap[song.id] = song;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 使用 check_music API 检查歌曲是否可播放
|
// 检查是否启用精确检查(默认禁用,因为批量检查可能导致网络问题)
|
||||||
// 注意:由于需要批量检查,这里优化为分批处理
|
const globalConfig = await configManager.getGlobalConfig();
|
||||||
const checkSongsPlayable = async (songIds) => {
|
const enableAccurateCheck = globalConfig?.enableAccurateCheck === true;
|
||||||
const batchSize = 50; // 每批检查50首
|
|
||||||
const results = {};
|
|
||||||
|
|
||||||
for (let i = 0; i < songIds.length; i += batchSize) {
|
let playableResults = {};
|
||||||
const batch = songIds.slice(i, i + batchSize);
|
if (enableAccurateCheck) {
|
||||||
const batchPromises = batch.map(async (songId) => {
|
// 使用 check_music API 检查歌曲是否可播放
|
||||||
try {
|
// 注意:由于需要批量检查,这里优化为分批处理
|
||||||
const response = await safeRequest(uid, check_music, { id: songId, br: 999000 }, false);
|
const checkSongsPlayable = async (songIds) => {
|
||||||
if (response && response.success === true) {
|
const batchSize = 20; // 每批检查20首(降低并发压力)
|
||||||
return { id: songId, playable: true };
|
const results = {};
|
||||||
} else {
|
let successCount = 0;
|
||||||
return { id: songId, playable: false };
|
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 字段的判断
|
const batchResults = await Promise.all(batchPromises);
|
||||||
return { id: songId, playable: null }; // null 表示未知,需要回退判断
|
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);
|
const songIds = songsResponse.songs.map(song => song.id);
|
||||||
logger.info(`[getSongsFromPlaylist] Checking playable status for ${songIds.length} songs...`);
|
logger.info(`[getSongsFromPlaylist] Checking playable status for ${songIds.length} songs...`);
|
||||||
const playableResults = await checkSongsPlayable(songIds);
|
playableResults = await checkSongsPlayable(songIds);
|
||||||
logger.info(`[getSongsFromPlaylist] Checked ${Object.keys(playableResults).length} songs`);
|
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) => {
|
const isBlockedSong = (song, songInfo, playable) => {
|
||||||
// the song has been added to cloud if the pc field is present
|
// the song has been added to cloud if the pc field is present
|
||||||
|
|||||||
Reference in New Issue
Block a user