diff --git a/backend/src/service/media_fetcher/index.js b/backend/src/service/media_fetcher/index.js index afa4cff..455f6c5 100644 --- a/backend/src/service/media_fetcher/index.js +++ b/backend/src/service/media_fetcher/index.js @@ -6,6 +6,7 @@ const cmd = require('../../utils/cmd'); const fs = require('fs'); const configManager = require('../config_manager') const downloadFile = require('../../utils/download'); +const { getSongInfo, buildSongUrl } = require('../music_platform/tunehub'); const { getBinPath } = require('./media_get'); @@ -16,6 +17,64 @@ if (!fs.existsSync(basePath)) { } logger.info(`[tmp path] use ${basePath}`) +function parseTunehubParams(url) { + try { + const parsed = new URL(url); + if (!parsed.hostname.includes('music-dl.sayqz.com')) { + return null; + } + const source = parsed.searchParams.get('source'); + const id = parsed.searchParams.get('id'); + if (!source || !id) { + return null; + } + return { source, id }; + } catch (err) { + return null; + } +} + +function parsePageUrlParams(url) { + if (!url) { + return null; + } + if (url.indexOf('music.163.com') >= 0 || url.indexOf('m.music.163.com') >= 0) { + const match = url.match(/id=(\d+)/); + if (match && match[1]) { + return { source: 'netease', id: match[1] }; + } + } + if (url.indexOf('y.qq.com') >= 0) { + const match = url.match(/songDetail\/([A-Za-z0-9]+)/); + if (match && match[1]) { + return { source: 'qq', id: match[1] }; + } + } + return null; +} + +function buildMetaFromTunehub(source, info, url, songId) { + return { + songName: info.name || '', + artist: info.artist || '', + album: info.album || '', + duration: 0, + coverUrl: info.pic || '', + publicTime: '', + isTrial: false, + resourceType: '', + audios: [ + { + url: info.url || buildSongUrl(source, songId), + } + ], + fromMusicPlatform: true, + resourceForbidden: false, + source, + pageUrl: url, + }; +} + async function downloadViaSourceUrl(url) { logger.info(`downloadViaSourceUrl params: url: ${url}`); @@ -82,6 +141,14 @@ async function fetchWithUrl(url, { async function getMetaWithUrl(url) { logger.info(`getMetaWithUrl from ${url}`); + const params = parseTunehubParams(url) || parsePageUrlParams(url); + if (params) { + const tunehubInfo = await getSongInfo(params.source, params.id); + if (tunehubInfo) { + return buildMetaFromTunehub(params.source, tunehubInfo, url, params.id); + } + } + let args = ['-u', `"${url}"`, '-m', '--infoFormat=json', '-l=silence']; const {code, message} = await cmd(getBinPath(), args); @@ -177,4 +244,4 @@ module.exports = { fetchWithUrl: fetchWithUrl, getMetaWithUrl: getMetaWithUrl, searchSongFromAllPlatform: searchSongFromAllPlatform, -} \ No newline at end of file +}