feat(同步任务): 增加从URL提取songId的功能并优化媒体获取重试机制
在sync_jobs.js中添加从网易云音乐URL提取songId的逻辑,避免冗余匹配 在media_fetcher/index.js中增加重试机制和超时控制,提高媒体获取的稳定性
This commit is contained in:
@@ -92,6 +92,20 @@ async function createJob(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果前端没有传递 songId,尝试从 URL 中提取
|
||||||
|
if (!songId) {
|
||||||
|
logger.info(`[sync_jobs] No songId provided, trying to extract from URL: ${url}`);
|
||||||
|
// 支持网易云音乐PC版和手机版
|
||||||
|
if (url.indexOf('music.163.com') >= 0 || url.indexOf('m.music.163.com') >= 0) {
|
||||||
|
const match = url.match(/id=(\d+)/);
|
||||||
|
if (match && match[1]) {
|
||||||
|
songId = match[1];
|
||||||
|
logger.info(`[sync_jobs] Extracted netease songId from URL: ${songId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: 支持其他音乐平台 (QQ音乐等)
|
||||||
|
}
|
||||||
|
|
||||||
if (songId) {
|
if (songId) {
|
||||||
// 直接传递songId给后续处理,避免冗余的网易云匹配
|
// 直接传递songId给后续处理,避免冗余的网易云匹配
|
||||||
// 如果后续需要,可以根据songId进行精确匹配
|
// 如果后续需要,可以根据songId进行精确匹配
|
||||||
|
|||||||
@@ -212,45 +212,63 @@ async function getMetaWithUrl(url) {
|
|||||||
|
|
||||||
// Fallback to media-get only if TuneHub fails or URL format not supported
|
// Fallback to media-get only if TuneHub fails or URL format not supported
|
||||||
logger.warn(`[getMetaWithUrl] Falling back to media-get for ${url} (may be unstable)`);
|
logger.warn(`[getMetaWithUrl] Falling back to media-get for ${url} (may be unstable)`);
|
||||||
let args = ['-u', `"${url}"`, '-m', '--infoFormat=json', '-l=silence'];
|
|
||||||
|
|
||||||
try {
|
// 增加重试机制和超时控制
|
||||||
const {code, message} = await cmd(getBinPath(), args);
|
const maxRetries = 2;
|
||||||
logger.info('-------')
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
logger.info(code);
|
|
||||||
// logger.info(message);
|
|
||||||
logger.info('-------')
|
|
||||||
if (code != 0) {
|
|
||||||
logger.error(`getMetaWithUrl failed with ${url}, err: ${message}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let meta;
|
|
||||||
try {
|
try {
|
||||||
meta = JSON.parse(message);
|
logger.info(`[getMetaWithUrl] Attempt ${attempt}/${maxRetries} for ${url}`);
|
||||||
} catch (e) {
|
const {code, message} = await cmd(getBinPath(), ['-u', `"${url}"`, '-m', '--infoFormat=json', '-l=silence', '--timeout=30']);
|
||||||
logger.error(`[getMetaWithUrl] Failed to parse media-get response: ${e}`, message)
|
logger.info('-------')
|
||||||
return false;
|
logger.info(code);
|
||||||
}
|
// logger.info(message);
|
||||||
|
logger.info('-------')
|
||||||
|
if (code != 0) {
|
||||||
|
logger.error(`getMetaWithUrl failed with ${url}, err: ${message}`);
|
||||||
|
if (attempt === maxRetries) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 等待一段时间后重试
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
let meta;
|
||||||
songName: meta.title,
|
try {
|
||||||
artist: meta.artist,
|
meta = JSON.parse(message);
|
||||||
album: meta.album,
|
} catch (e) {
|
||||||
duration: meta.duration,
|
logger.error(`[getMetaWithUrl] Failed to parse media-get response: ${e}`, message);
|
||||||
coverUrl: meta.cover_url,
|
if (attempt === maxRetries) {
|
||||||
publicTime: meta.public_time,
|
return false;
|
||||||
isTrial: meta.is_trial,
|
}
|
||||||
resourceType: meta.resource_type,
|
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
|
||||||
audios: meta.audios,
|
continue;
|
||||||
fromMusicPlatform: meta.from_music_platform,
|
}
|
||||||
resourceForbidden: meta.resource_forbidden,
|
|
||||||
source: meta.source
|
return {
|
||||||
|
songName: meta.title,
|
||||||
|
artist: meta.artist,
|
||||||
|
album: meta.album,
|
||||||
|
duration: meta.duration,
|
||||||
|
coverUrl: meta.cover_url,
|
||||||
|
publicTime: meta.public_time,
|
||||||
|
isTrial: meta.is_trial,
|
||||||
|
resourceType: meta.resource_type,
|
||||||
|
audios: meta.audios,
|
||||||
|
fromMusicPlatform: meta.from_music_platform,
|
||||||
|
resourceForbidden: meta.resource_forbidden,
|
||||||
|
source: meta.source
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(`[getMetaWithUrl] media-get crashed or timed out for ${url}`, error);
|
||||||
|
if (attempt === maxRetries) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 等待一段时间后重试
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
logger.error(`[getMetaWithUrl] media-get crashed or timed out for ${url}`, error);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function searchSongFromAllPlatform({
|
async function searchSongFromAllPlatform({
|
||||||
|
|||||||
Reference in New Issue
Block a user