release v0.1.2: rewrite all plugins based on official zq_tx_v3 format
This commit is contained in:
@@ -56,13 +56,23 @@ function requestUrl(urlStr, method, headers, body) {
|
|||||||
return doRequest(protocol, options, postData);
|
return doRequest(protocol, options, postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPlayTime(seconds) {
|
// ===== 格式化辅助 =====
|
||||||
if (!seconds) return '00:00';
|
function formatPlayTime(time) {
|
||||||
var m = Math.floor(seconds / 60);
|
if (!time) return '--/--';
|
||||||
var s = Math.floor(seconds % 60);
|
var m = Math.floor(time / 60);
|
||||||
|
var s = Math.floor(time % 60);
|
||||||
|
if (m === 0 && s === 0) return '--/--';
|
||||||
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sizeFormate(bytes) {
|
||||||
|
if (typeof bytes === 'string') bytes = parseFloat(bytes.replace(/[^0-9.]/g, ''));
|
||||||
|
var n = parseFloat(bytes);
|
||||||
|
if (isNaN(n) || n < 0) return '0.00MB';
|
||||||
|
var mb = n / (1024 * 1024);
|
||||||
|
return mb.toFixed(2) + 'MB';
|
||||||
|
}
|
||||||
|
|
||||||
// ===== Git音源配置 =====
|
// ===== Git音源配置 =====
|
||||||
var GITCODE_CONFIG = { owner: 'ikun_0014', repo: 'music', token: 'WzsER9knWNgC_4tjeJCtHKcN' };
|
var GITCODE_CONFIG = { owner: 'ikun_0014', repo: 'music', token: 'WzsER9knWNgC_4tjeJCtHKcN' };
|
||||||
function getGitcodeUrl() {
|
function getGitcodeUrl() {
|
||||||
@@ -71,6 +81,7 @@ function getGitcodeUrl() {
|
|||||||
var cachedList = null;
|
var cachedList = null;
|
||||||
var cacheTime = 0;
|
var cacheTime = 0;
|
||||||
var CACHE_TTL = 5 * 60 * 1000;
|
var CACHE_TTL = 5 * 60 * 1000;
|
||||||
|
var cachedLyricMap = null;
|
||||||
|
|
||||||
function fetchAllGitMusic() {
|
function fetchAllGitMusic() {
|
||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
@@ -78,22 +89,39 @@ function fetchAllGitMusic() {
|
|||||||
return requestUrl(getGitcodeUrl(), 'GET', { 'User-Agent': 'Mozilla/5.0' }).then(function(res) {
|
return requestUrl(getGitcodeUrl(), 'GET', { 'User-Agent': 'Mozilla/5.0' }).then(function(res) {
|
||||||
var body = Array.isArray(res.body) ? res.body : [];
|
var body = Array.isArray(res.body) ? res.body : [];
|
||||||
var list = [];
|
var list = [];
|
||||||
for (var i = 0; i < body.length; i++) list.push(formatGitItem(body[i]));
|
var lyricMap = {};
|
||||||
|
for (var i = 0; i < body.length; i++) {
|
||||||
|
var formatted = formatGitItem(body[i]);
|
||||||
|
if (formatted) {
|
||||||
|
list.push(formatted);
|
||||||
|
var lid = formatted.id;
|
||||||
|
if (lid) lyricMap[lid] = (body[i].lyrics || body[i].lyric || '');
|
||||||
|
}
|
||||||
|
}
|
||||||
cachedList = list;
|
cachedList = list;
|
||||||
|
cachedLyricMap = lyricMap;
|
||||||
cacheTime = now;
|
cacheTime = now;
|
||||||
return list;
|
return list;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatGitItem(item) {
|
function formatGitItem(item) {
|
||||||
|
if (!item) return null;
|
||||||
var qualities = {};
|
var qualities = {};
|
||||||
var fmt = (item.format || '').toLowerCase();
|
var fmt = (item.format || '').toLowerCase();
|
||||||
if (fmt === 'flac' && item.filesize) qualities.lossless = String(item.filesize);
|
if (fmt === 'flac' && item.filesize) {
|
||||||
else if (fmt === 'mp3' && item.filesize) qualities.exhigh = String(item.filesize);
|
qualities['flac'] = sizeFormate(item.filesize);
|
||||||
else if (item.filesize) qualities.standard = String(item.filesize);
|
qualities['320k'] = sizeFormate(item.filesize);
|
||||||
var picUrl = item.img || '';
|
} else if (fmt === 'mp3' && item.filesize) {
|
||||||
|
if (item.bitrate && Number(item.bitrate) >= 320) qualities['320k'] = sizeFormate(item.filesize);
|
||||||
|
else qualities['128k'] = sizeFormate(item.filesize);
|
||||||
|
} else if (item.filesize) {
|
||||||
|
qualities['128k'] = sizeFormate(item.filesize);
|
||||||
|
}
|
||||||
|
var picUrl = item.img || item.cover || '';
|
||||||
|
var songId = item.hash || item.relative_path || item.id || '';
|
||||||
return {
|
return {
|
||||||
id: item.relative_path || '',
|
id: String(songId),
|
||||||
name: item.title || item.filename || '',
|
name: item.title || item.filename || '',
|
||||||
artists: item.artist || '未知歌手',
|
artists: item.artist || '未知歌手',
|
||||||
source: 'git',
|
source: 'git',
|
||||||
@@ -101,10 +129,9 @@ function formatGitItem(item) {
|
|||||||
mPic: picUrl,
|
mPic: picUrl,
|
||||||
sPic: picUrl,
|
sPic: picUrl,
|
||||||
albumName: item.album || '未知专辑',
|
albumName: item.album || '未知专辑',
|
||||||
albumId: '',
|
albumId: String(item.albumId || ''),
|
||||||
interval: '',
|
interval: String(formatPlayTime(item.duration) || '--/--'),
|
||||||
qualities: qualities,
|
qualities: qualities
|
||||||
_gitcodeData: item
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,14 +165,14 @@ function search(str, page, limit, retryNum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== 播放链接 =====
|
// ===== 播放链接 =====
|
||||||
function getUrl(songInfo, type) {
|
function getUrl(songId, quality) {
|
||||||
var q = (type === 'standard' ? '128k' : type === 'exhigh' ? '320k' : type === 'lossless' || type === 'hires' || type === 'jymaster' ? 'flac' : type) || '128k';
|
songId = String(songId || '');
|
||||||
var songId = songInfo.id || '';
|
quality = String(quality || '128k');
|
||||||
if (!songId) return Promise.resolve('');
|
if (!songId) return Promise.resolve('');
|
||||||
var ceruKey = CERU_KEY || '';
|
var ceruKey = CERU_KEY || '';
|
||||||
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
||||||
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
||||||
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=git&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(q), 'GET', headers)
|
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=git&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(quality), 'GET', headers)
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
||||||
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
||||||
@@ -156,14 +183,19 @@ function getUrl(songInfo, type) {
|
|||||||
|
|
||||||
// ===== 封面图 =====
|
// ===== 封面图 =====
|
||||||
function getPic(songInfo) {
|
function getPic(songInfo) {
|
||||||
if (songInfo.pic) return Promise.resolve(songInfo.pic);
|
if (songInfo && songInfo.pic) return Promise.resolve(songInfo.pic);
|
||||||
return Promise.resolve('');
|
return Promise.resolve('');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 歌词 =====
|
// ===== 歌词 =====
|
||||||
function getLyric(songInfo) {
|
function getLyric(songInfo) {
|
||||||
if (songInfo._gitcodeData && songInfo._gitcodeData.lyrics) return Promise.resolve(songInfo._gitcodeData.lyrics);
|
var id = (songInfo && songInfo.id) || '';
|
||||||
return Promise.resolve('');
|
if (!id) return Promise.resolve('');
|
||||||
|
if (cachedLyricMap && cachedLyricMap[id]) return Promise.resolve(cachedLyricMap[id]);
|
||||||
|
return fetchAllGitMusic().then(function() {
|
||||||
|
if (cachedLyricMap && cachedLyricMap[id]) return cachedLyricMap[id];
|
||||||
|
return '';
|
||||||
|
}).catch(function() { return ''; });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 音乐详情 =====
|
// ===== 音乐详情 =====
|
||||||
@@ -195,18 +227,18 @@ var pluginInfo = {
|
|||||||
info: {
|
info: {
|
||||||
id: 'koneko_ceru_git',
|
id: 'koneko_ceru_git',
|
||||||
name: 'GIT音源 - Koneko 聆澜',
|
name: 'GIT音源 - Koneko 聆澜',
|
||||||
version: '0.1.0',
|
version: '0.1.2',
|
||||||
source: 'git',
|
source: 'git',
|
||||||
description: 'GIT音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
description: 'GIT音源,基于 GitCode audio_database.json 本地搜索 + Ceru 播放接口'
|
||||||
},
|
},
|
||||||
ext: [],
|
ext: [],
|
||||||
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
||||||
quality: [
|
quality: [
|
||||||
{ name: '标准', ui: '标', id: '128k' },
|
{ name: '标准音质', ui: '标', id: '128k' },
|
||||||
{ name: '高品', ui: 'HQ', id: '320k' },
|
{ name: '高品音质', ui: 'HQ', id: '320k' },
|
||||||
{ name: '无损', ui: 'SQ', id: 'flac' }
|
{ name: '无损音质', ui: 'SQ', id: 'flac' }
|
||||||
],
|
],
|
||||||
supportFunc: []
|
supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric']
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -215,7 +247,7 @@ module.exports = {
|
|||||||
hotSearch: { getList: hotSearch },
|
hotSearch: { getList: hotSearch },
|
||||||
leaderboard: { getBoards: leaderboard },
|
leaderboard: { getBoards: leaderboard },
|
||||||
songList: songList,
|
songList: songList,
|
||||||
artists: singer,
|
singer: singer,
|
||||||
album: album,
|
album: album,
|
||||||
getLyric: getLyric,
|
getLyric: getLyric,
|
||||||
getPic: getPic,
|
getPic: getPic,
|
||||||
@@ -56,6 +56,30 @@ function requestUrl(urlStr, method, headers, body) {
|
|||||||
return doRequest(protocol, options, postData);
|
return doRequest(protocol, options, postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== 格式化辅助 =====
|
||||||
|
function formatPlayTime(time) {
|
||||||
|
if (!time) return '--/--';
|
||||||
|
var m = Math.floor(time / 60);
|
||||||
|
var s = Math.floor(time % 60);
|
||||||
|
if (m === 0 && s === 0) return '--/--';
|
||||||
|
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sizeFormate(bytes) {
|
||||||
|
if (typeof bytes === 'string') bytes = parseFloat(bytes.replace(/[^0-9.]/g, ''));
|
||||||
|
var n = parseFloat(bytes);
|
||||||
|
if (isNaN(n) || n < 0) return '0.00MB';
|
||||||
|
var mb = n / (1024 * 1024);
|
||||||
|
return mb.toFixed(2) + 'MB';
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatSingerName(arr, key) {
|
||||||
|
if (!arr || !arr.length) return '';
|
||||||
|
var names = [];
|
||||||
|
for (var i = 0; i < arr.length; i++) names.push(arr[i][key] || arr[i]);
|
||||||
|
return names.join('、');
|
||||||
|
}
|
||||||
|
|
||||||
// ===== QQ音乐zzcSign =====
|
// ===== QQ音乐zzcSign =====
|
||||||
var PART_1_INDEXES = [23, 14, 6, 36, 16, 40, 7, 19];
|
var PART_1_INDEXES = [23, 14, 6, 36, 16, 40, 7, 19];
|
||||||
var PART_2_INDEXES = [16, 1, 32, 12, 19, 27, 8, 5];
|
var PART_2_INDEXES = [16, 1, 32, 12, 19, 27, 8, 5];
|
||||||
@@ -105,13 +129,6 @@ function signRequest(data) {
|
|||||||
}, JSON.stringify(data));
|
}, JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPlayTime(seconds) {
|
|
||||||
if (!seconds) return '00:00';
|
|
||||||
var m = Math.floor(seconds / 60);
|
|
||||||
var s = Math.floor(seconds % 60);
|
|
||||||
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== 搜索实现 =====
|
// ===== 搜索实现 =====
|
||||||
function musicSearch(str, page, limit) {
|
function musicSearch(str, page, limit) {
|
||||||
var body = {
|
var body = {
|
||||||
@@ -126,37 +143,33 @@ function musicSearch(str, page, limit) {
|
|||||||
|
|
||||||
function handleSearchResult(rawList) {
|
function handleSearchResult(rawList) {
|
||||||
var list = [];
|
var list = [];
|
||||||
|
if (!rawList) return list;
|
||||||
for (var i = 0; i < rawList.length; i++) {
|
for (var i = 0; i < rawList.length; i++) {
|
||||||
var item = rawList[i];
|
var item = rawList[i];
|
||||||
if (!item.file || !item.file.media_mid) continue;
|
if (!item.file || !item.file.media_mid) continue;
|
||||||
var qualities = {};
|
var qualities = {};
|
||||||
var file = item.file;
|
var file = item.file;
|
||||||
if (file.size_128mp3 !== 0) qualities.standard = String(file.size_128mp3 || '');
|
if (file.size_128mp3) qualities['128k'] = sizeFormate(file.size_128mp3);
|
||||||
if (file.size_320mp3 !== 0) qualities.exhigh = String(file.size_320mp3 || '');
|
if (file.size_320mp3) qualities['320k'] = sizeFormate(file.size_320mp3);
|
||||||
if (file.size_flac !== 0) qualities.lossless = String(file.size_flac || '');
|
if (file.size_flac) qualities['flac'] = sizeFormate(file.size_flac);
|
||||||
if (file.size_hires !== 0) qualities.hires = String(file.size_hires || '');
|
|
||||||
var albumId = '';
|
var albumId = '';
|
||||||
var albumName = '';
|
var albumName = '';
|
||||||
if (item.album) { albumName = item.album.name; albumId = item.album.mid; }
|
if (item.album) { albumName = item.album.name; albumId = item.album.mid; }
|
||||||
var singerName = '';
|
var singerName = formatSingerName(item.singer, 'name');
|
||||||
if (item.singer && item.singer.length) {
|
var picUrl = albumId && albumId !== '空'
|
||||||
var ns = [];
|
? 'https://y.gtimg.cn/music/photo_new/T002R500x500M000' + albumId + '.jpg'
|
||||||
for (var j = 0; j < item.singer.length; j++) ns.push(item.singer[j].name);
|
: (item.singer && item.singer.length ? 'https://y.gtimg.cn/music/photo_new/T001R500x500M000' + item.singer[0].mid + '.jpg' : '');
|
||||||
singerName = ns.join('、');
|
|
||||||
}
|
|
||||||
var picUrl = albumId ? 'https://y.gtimg.cn/music/photo_new/T002R500x500M000' + albumId + '.jpg' : (item.singer && item.singer.length ? 'https://y.gtimg.cn/music/photo_new/T001R500x500M000' + item.singer[0].mid + '.jpg' : '');
|
|
||||||
list.push({
|
list.push({
|
||||||
id: item.mid,
|
id: String(item.mid),
|
||||||
songId: item.id,
|
|
||||||
name: item.name + (item.title_extra || ''),
|
name: item.name + (item.title_extra || ''),
|
||||||
artists: singerName,
|
artists: singerName,
|
||||||
source: 'tx',
|
source: 'tx',
|
||||||
interval: formatPlayTime(item.interval),
|
|
||||||
pic: picUrl,
|
pic: picUrl,
|
||||||
mPic: picUrl,
|
mPic: picUrl,
|
||||||
sPic: picUrl,
|
sPic: picUrl,
|
||||||
albumName: albumName,
|
albumName: albumName,
|
||||||
albumId: albumId,
|
albumId: String(albumId || ''),
|
||||||
|
interval: String(formatPlayTime(item.interval) || '--/--'),
|
||||||
qualities: qualities
|
qualities: qualities
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -177,13 +190,13 @@ function search(str, page, limit, retryNum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== 播放链接 =====
|
// ===== 播放链接 =====
|
||||||
function getUrl(songInfo, type) {
|
function getUrl(songId, quality) {
|
||||||
var q = (type === 'standard' ? '128k' : type === 'exhigh' ? '320k' : type === 'lossless' || type === 'hires' || type === 'jymaster' ? 'flac' : type) || '128k';
|
songId = String(songId || '');
|
||||||
var songId = songInfo.id || songInfo.songId || '';
|
quality = String(quality || '128k');
|
||||||
var ceruKey = CERU_KEY || '';
|
var ceruKey = CERU_KEY || '';
|
||||||
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
||||||
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
||||||
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=tx&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(q), 'GET', headers)
|
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=tx&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(quality), 'GET', headers)
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
||||||
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
||||||
@@ -194,16 +207,15 @@ function getUrl(songInfo, type) {
|
|||||||
|
|
||||||
// ===== 封面图 =====
|
// ===== 封面图 =====
|
||||||
function getPic(songInfo) {
|
function getPic(songInfo) {
|
||||||
if (songInfo.pic) return Promise.resolve(songInfo.pic);
|
if (songInfo && songInfo.pic) return Promise.resolve(songInfo.pic);
|
||||||
if (songInfo.img) return Promise.resolve(songInfo.img);
|
var albumId = songInfo && songInfo.albumId ? String(songInfo.albumId) : '';
|
||||||
var albumId = songInfo.albumId || '';
|
|
||||||
if (albumId) return Promise.resolve('https://y.gtimg.cn/music/photo_new/T002R500x500M000' + albumId + '.jpg');
|
if (albumId) return Promise.resolve('https://y.gtimg.cn/music/photo_new/T002R500x500M000' + albumId + '.jpg');
|
||||||
return Promise.resolve('');
|
return Promise.resolve('');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 歌词 =====
|
// ===== 歌词 =====
|
||||||
function getLyric(songInfo) {
|
function getLyric(songInfo) {
|
||||||
var songmid = songInfo.id || '';
|
var songmid = (songInfo && songInfo.id) || (songInfo && songInfo.songId) || '';
|
||||||
return requestUrl('https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?format=json&nobase64=1&songmid=' + encodeURIComponent(songmid), 'GET', {
|
return requestUrl('https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?format=json&nobase64=1&songmid=' + encodeURIComponent(songmid), 'GET', {
|
||||||
'User-Agent': 'Mozilla/5.0 (Linux; Android 10)',
|
'User-Agent': 'Mozilla/5.0 (Linux; Android 10)',
|
||||||
'Referer': 'https://y.qq.com/portal/player.html'
|
'Referer': 'https://y.qq.com/portal/player.html'
|
||||||
@@ -226,15 +238,19 @@ function musicDetail(songmid) {
|
|||||||
if (res.body && res.body.req && res.body.req.data && res.body.req.data.info && res.body.req.data.info.track_info) {
|
if (res.body && res.body.req && res.body.req.data && res.body.req.data.info && res.body.req.data.info.track_info) {
|
||||||
var t = res.body.req.data.info.track_info;
|
var t = res.body.req.data.info.track_info;
|
||||||
var albumId = t.album ? t.album.mid : '';
|
var albumId = t.album ? t.album.mid : '';
|
||||||
var singerName = '';
|
var singerName = formatSingerName(t.singer, 'name');
|
||||||
if (t.singer && t.singer.length) { var ns = []; for (var j = 0; j < t.singer.length; j++) ns.push(t.singer[j].name); singerName = ns.join('、'); }
|
|
||||||
var picUrl = albumId ? 'https://y.gtimg.cn/music/photo_new/T002R500x500M000' + albumId + '.jpg' : '';
|
var picUrl = albumId ? 'https://y.gtimg.cn/music/photo_new/T002R500x500M000' + albumId + '.jpg' : '';
|
||||||
return {
|
return {
|
||||||
id: t.mid, songId: t.id,
|
id: String(t.mid),
|
||||||
name: t.name, artists: singerName,
|
name: t.name,
|
||||||
albumName: t.album ? t.album.name : '', albumId: albumId,
|
artists: singerName,
|
||||||
source: 'tx', interval: formatPlayTime(t.interval),
|
source: 'tx',
|
||||||
pic: picUrl, mPic: picUrl, sPic: picUrl,
|
pic: picUrl,
|
||||||
|
mPic: picUrl,
|
||||||
|
sPic: picUrl,
|
||||||
|
albumName: t.album ? t.album.name : '',
|
||||||
|
albumId: String(albumId || ''),
|
||||||
|
interval: String(formatPlayTime(t.interval) || '--/--'),
|
||||||
qualities: {}
|
qualities: {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -294,18 +310,18 @@ var pluginInfo = {
|
|||||||
info: {
|
info: {
|
||||||
id: 'koneko_ceru_tx',
|
id: 'koneko_ceru_tx',
|
||||||
name: 'QQ音乐 - Koneko 聆澜',
|
name: 'QQ音乐 - Koneko 聆澜',
|
||||||
version: '0.1.0',
|
version: '0.1.2',
|
||||||
source: 'tx',
|
source: 'tx',
|
||||||
description: 'QQ音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
description: 'QQ音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
||||||
},
|
},
|
||||||
ext: [],
|
ext: [],
|
||||||
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
||||||
quality: [
|
quality: [
|
||||||
{ name: '标准', ui: '标', id: '128k' },
|
{ name: '标准音质', ui: '标', id: '128k' },
|
||||||
{ name: '高品', ui: 'HQ', id: '320k' },
|
{ name: '高品音质', ui: 'HQ', id: '320k' },
|
||||||
{ name: '无损', ui: 'SQ', id: 'flac' }
|
{ name: '无损音质', ui: 'SQ', id: 'flac' }
|
||||||
],
|
],
|
||||||
supportFunc: []
|
supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric']
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -314,7 +330,7 @@ module.exports = {
|
|||||||
hotSearch: { getList: hotSearch },
|
hotSearch: { getList: hotSearch },
|
||||||
leaderboard: { getBoards: leaderboard },
|
leaderboard: { getBoards: leaderboard },
|
||||||
songList: songList,
|
songList: songList,
|
||||||
artists: singer,
|
singer: singer,
|
||||||
album: album,
|
album: album,
|
||||||
getLyric: getLyric,
|
getLyric: getLyric,
|
||||||
getPic: getPic,
|
getPic: getPic,
|
||||||
@@ -56,13 +56,23 @@ function requestUrl(urlStr, method, headers, body) {
|
|||||||
return doRequest(protocol, options, postData);
|
return doRequest(protocol, options, postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPlayTime(seconds) {
|
// ===== 格式化辅助 =====
|
||||||
if (!seconds) return '00:00';
|
function formatPlayTime(time) {
|
||||||
var m = Math.floor(seconds / 60);
|
if (!time) return '--/--';
|
||||||
var s = Math.floor(seconds % 60);
|
var m = Math.floor(time / 60);
|
||||||
|
var s = Math.floor(time % 60);
|
||||||
|
if (m === 0 && s === 0) return '--/--';
|
||||||
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sizeFormate(bytes) {
|
||||||
|
if (typeof bytes === 'string') bytes = parseFloat(bytes.replace(/[^0-9.]/g, ''));
|
||||||
|
var n = parseFloat(bytes);
|
||||||
|
if (isNaN(n) || n < 0) return '0.00MB';
|
||||||
|
var mb = n / (1024 * 1024);
|
||||||
|
return mb.toFixed(2) + 'MB';
|
||||||
|
}
|
||||||
|
|
||||||
// ===== 搜索实现 =====
|
// ===== 搜索实现 =====
|
||||||
function musicSearch(str, page, limit) {
|
function musicSearch(str, page, limit) {
|
||||||
var url = 'https://jadeite.migu.cn/music_search/v3/search?text=' + encodeURIComponent(str) + '&pageNo=' + page + '&pageSize=' + limit + '&searchSwitch={"song":1}';
|
var url = 'https://jadeite.migu.cn/music_search/v3/search?text=' + encodeURIComponent(str) + '&pageNo=' + page + '&pageSize=' + limit + '&searchSwitch={"song":1}';
|
||||||
@@ -78,21 +88,24 @@ function musicSearch(str, page, limit) {
|
|||||||
|
|
||||||
function handleSearchResult(rawList) {
|
function handleSearchResult(rawList) {
|
||||||
var list = [];
|
var list = [];
|
||||||
|
if (!rawList) return list;
|
||||||
for (var i = 0; i < rawList.length; i++) {
|
for (var i = 0; i < rawList.length; i++) {
|
||||||
var item = rawList[i];
|
var item = rawList[i];
|
||||||
var qualities = {};
|
var qualities = {};
|
||||||
if (item.newRateFormats) {
|
if (item.newRateFormats) {
|
||||||
for (var j = 0; j < item.newRateFormats.length; j++) {
|
for (var j = 0; j < item.newRateFormats.length; j++) {
|
||||||
var fmt = item.newRateFormats[j];
|
var fmt = item.newRateFormats[j];
|
||||||
if (fmt.formatType === 'SQ' && fmt.size) qualities.lossless = String(fmt.size);
|
if (fmt.formatType === 'LQ' && fmt.size) qualities['128k'] = sizeFormate(fmt.size);
|
||||||
if (fmt.formatType === 'HQ' && fmt.size) qualities.exhigh = String(fmt.size);
|
if (fmt.formatType === 'HQ' && fmt.size) qualities['320k'] = sizeFormate(fmt.size);
|
||||||
if (fmt.formatType === 'LQ' && fmt.size) qualities.standard = String(fmt.size);
|
if (fmt.formatType === 'SQ' && fmt.size) qualities['flac'] = sizeFormate(fmt.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var picUrl = item.img || (item.albumImgs && item.albumImgs.length ? item.albumImgs[0].img : '');
|
var picUrl = item.img || (item.albumImgs && item.albumImgs.length ? item.albumImgs[0].img : '');
|
||||||
if (picUrl && picUrl.startsWith('/')) picUrl = 'https://d.musicapp.migu.cn' + picUrl;
|
if (picUrl && picUrl.indexOf('/') === 0) picUrl = 'https://d.musicapp.migu.cn' + picUrl;
|
||||||
|
var intervalStr = item.length ? String(item.length).replace(/.*(\d\d:\d\d)$/, '$1') : '--/--';
|
||||||
|
if (!intervalStr) intervalStr = '--/--';
|
||||||
list.push({
|
list.push({
|
||||||
id: item.copyrightId || item.id || '',
|
id: String(item.copyrightId || item.id || ''),
|
||||||
name: item.title || item.songName || '',
|
name: item.title || item.songName || '',
|
||||||
artists: item.artist || item.singerName || '',
|
artists: item.artist || item.singerName || '',
|
||||||
source: 'mg',
|
source: 'mg',
|
||||||
@@ -100,8 +113,8 @@ function handleSearchResult(rawList) {
|
|||||||
mPic: picUrl,
|
mPic: picUrl,
|
||||||
sPic: picUrl,
|
sPic: picUrl,
|
||||||
albumName: item.album || item.albumName || '',
|
albumName: item.album || item.albumName || '',
|
||||||
albumId: item.albumId || '',
|
albumId: String(item.albumId || ''),
|
||||||
interval: item.length ? item.length.replace(/.*(\d\d:\d\d)$/, '$1') : '',
|
interval: intervalStr,
|
||||||
qualities: qualities
|
qualities: qualities
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -119,13 +132,13 @@ function search(str, page, limit, retryNum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== 播放链接 =====
|
// ===== 播放链接 =====
|
||||||
function getUrl(songInfo, type) {
|
function getUrl(songId, quality) {
|
||||||
var q = (type === 'standard' ? '128k' : type === 'exhigh' ? '320k' : type === 'lossless' || type === 'hires' || type === 'jymaster' ? 'flac' : type) || '128k';
|
songId = String(songId || '');
|
||||||
var songId = songInfo.id || '';
|
quality = String(quality || '128k');
|
||||||
var ceruKey = CERU_KEY || '';
|
var ceruKey = CERU_KEY || '';
|
||||||
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
||||||
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
||||||
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=mg&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(q), 'GET', headers)
|
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=mg&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(quality), 'GET', headers)
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
||||||
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
||||||
@@ -136,13 +149,13 @@ function getUrl(songInfo, type) {
|
|||||||
|
|
||||||
// ===== 封面图 =====
|
// ===== 封面图 =====
|
||||||
function getPic(songInfo) {
|
function getPic(songInfo) {
|
||||||
if (songInfo.pic) return Promise.resolve(songInfo.pic);
|
if (songInfo && songInfo.pic) return Promise.resolve(songInfo.pic);
|
||||||
return Promise.resolve('');
|
return Promise.resolve('');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 歌词 =====
|
// ===== 歌词 =====
|
||||||
function getLyric(songInfo) {
|
function getLyric(songInfo) {
|
||||||
var copyrightId = songInfo.id || '';
|
var copyrightId = (songInfo && songInfo.id) || '';
|
||||||
if (!copyrightId) return Promise.resolve('');
|
if (!copyrightId) return Promise.resolve('');
|
||||||
return requestUrl('http://music.migu.cn/v3/api/music/audioPlayer/getLyric?copyrightId=' + encodeURIComponent(copyrightId), 'GET', {
|
return requestUrl('http://music.migu.cn/v3/api/music/audioPlayer/getLyric?copyrightId=' + encodeURIComponent(copyrightId), 'GET', {
|
||||||
'User-Agent': 'Mozilla/5.0 (Linux; Android 10)',
|
'User-Agent': 'Mozilla/5.0 (Linux; Android 10)',
|
||||||
@@ -182,18 +195,18 @@ var pluginInfo = {
|
|||||||
info: {
|
info: {
|
||||||
id: 'koneko_ceru_mg',
|
id: 'koneko_ceru_mg',
|
||||||
name: '咪咕音乐 - Koneko 聆澜',
|
name: '咪咕音乐 - Koneko 聆澜',
|
||||||
version: '0.1.0',
|
version: '0.1.2',
|
||||||
source: 'mg',
|
source: 'mg',
|
||||||
description: '咪咕音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
description: '咪咕音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
||||||
},
|
},
|
||||||
ext: [],
|
ext: [],
|
||||||
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
||||||
quality: [
|
quality: [
|
||||||
{ name: '标准', ui: '标', id: '128k' },
|
{ name: '标准音质', ui: '标', id: '128k' },
|
||||||
{ name: '高品', ui: 'HQ', id: '320k' },
|
{ name: '高品音质', ui: 'HQ', id: '320k' },
|
||||||
{ name: '无损', ui: 'SQ', id: 'flac' }
|
{ name: '无损音质', ui: 'SQ', id: 'flac' }
|
||||||
],
|
],
|
||||||
supportFunc: []
|
supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric']
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -202,7 +215,7 @@ module.exports = {
|
|||||||
hotSearch: { getList: hotSearch },
|
hotSearch: { getList: hotSearch },
|
||||||
leaderboard: { getBoards: leaderboard },
|
leaderboard: { getBoards: leaderboard },
|
||||||
songList: songList,
|
songList: songList,
|
||||||
artists: singer,
|
singer: singer,
|
||||||
album: album,
|
album: album,
|
||||||
getLyric: getLyric,
|
getLyric: getLyric,
|
||||||
getPic: getPic,
|
getPic: getPic,
|
||||||
@@ -112,12 +112,22 @@ function weapi(params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== 格式化辅助 =====
|
// ===== 格式化辅助 =====
|
||||||
function formatPlayTime(seconds) {
|
function formatPlayTime(time) {
|
||||||
var m = Math.floor(seconds / 60);
|
if (!time) return '--/--';
|
||||||
var s = Math.floor(seconds % 60);
|
var m = Math.floor(time / 60);
|
||||||
|
var s = Math.floor(time % 60);
|
||||||
|
if (m === 0 && s === 0) return '--/--';
|
||||||
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sizeFormate(bytes) {
|
||||||
|
if (typeof bytes === 'string') bytes = parseFloat(bytes.replace(/[^0-9.]/g, ''));
|
||||||
|
var n = parseFloat(bytes);
|
||||||
|
if (isNaN(n) || n < 0) return '0.00MB';
|
||||||
|
var mb = n / (1024 * 1024);
|
||||||
|
return mb.toFixed(2) + 'MB';
|
||||||
|
}
|
||||||
|
|
||||||
function formatSingerName(arr, key) {
|
function formatSingerName(arr, key) {
|
||||||
if (!arr || !arr.length) return '';
|
if (!arr || !arr.length) return '';
|
||||||
var names = [];
|
var names = [];
|
||||||
@@ -125,6 +135,13 @@ function formatSingerName(arr, key) {
|
|||||||
return names.join('、');
|
return names.join('、');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatPlayCount(count) {
|
||||||
|
if (!count && count !== 0) return '';
|
||||||
|
if (count >= 100000000) return (count / 100000000).toFixed(1) + '亿';
|
||||||
|
if (count >= 10000) return (count / 10000).toFixed(1) + '万';
|
||||||
|
return String(count);
|
||||||
|
}
|
||||||
|
|
||||||
// ===== 搜索实现 =====
|
// ===== 搜索实现 =====
|
||||||
function musicSearch(str, page, limit) {
|
function musicSearch(str, page, limit) {
|
||||||
var form = eapi('/api/search/song/list/page', {
|
var form = eapi('/api/search/song/list/page', {
|
||||||
@@ -154,14 +171,12 @@ function handleSearchResult(rawList) {
|
|||||||
if (!item.baseInfo || !item.baseInfo.simpleSongData) continue;
|
if (!item.baseInfo || !item.baseInfo.simpleSongData) continue;
|
||||||
var s = item.baseInfo.simpleSongData;
|
var s = item.baseInfo.simpleSongData;
|
||||||
var qualities = {};
|
var qualities = {};
|
||||||
if (s.l && s.l.size) qualities.standard = String(s.l.size);
|
if (s.l && s.l.size) qualities['128k'] = sizeFormate(s.l.size);
|
||||||
if (s.m && s.m.size) qualities.standard = String(s.m.size);
|
if (s.h && s.h.size) qualities['320k'] = sizeFormate(s.h.size);
|
||||||
if (s.h && s.h.size) qualities.exhigh = String(s.h.size);
|
if (s.sq && s.sq.size) qualities['flac'] = sizeFormate(s.sq.size);
|
||||||
if (s.sq && s.sq.size) qualities.lossless = String(s.sq.size);
|
|
||||||
if (s.hr && s.hr.size) qualities.hires = String(s.hr.size);
|
|
||||||
var picUrl = s.al && s.al.picUrl ? s.al.picUrl : '';
|
var picUrl = s.al && s.al.picUrl ? s.al.picUrl : '';
|
||||||
list.push({
|
list.push({
|
||||||
id: s.id,
|
id: String(s.id),
|
||||||
name: s.name,
|
name: s.name,
|
||||||
artists: formatSingerName(s.ar, 'name'),
|
artists: formatSingerName(s.ar, 'name'),
|
||||||
source: 'wy',
|
source: 'wy',
|
||||||
@@ -169,8 +184,8 @@ function handleSearchResult(rawList) {
|
|||||||
mPic: picUrl,
|
mPic: picUrl,
|
||||||
sPic: picUrl,
|
sPic: picUrl,
|
||||||
albumName: s.al && s.al.name ? s.al.name : '',
|
albumName: s.al && s.al.name ? s.al.name : '',
|
||||||
albumId: s.al && s.al.id ? s.al.id : '',
|
albumId: String(s.al && s.al.id ? s.al.id : ''),
|
||||||
interval: formatPlayTime((s.dt || 0) / 1000),
|
interval: String(formatPlayTime((s.dt || 0) / 1000) || '--/--'),
|
||||||
qualities: qualities
|
qualities: qualities
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -197,13 +212,13 @@ function search(str, page, limit, retryNum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== 播放链接 =====
|
// ===== 播放链接 =====
|
||||||
function getUrl(songInfo, type) {
|
function getUrl(songId, quality) {
|
||||||
var q = (type === 'standard' ? '128k' : type === 'exhigh' ? '320k' : type === 'lossless' || type === 'hires' || type === 'jymaster' ? 'flac' : type) || '128k';
|
songId = String(songId || '');
|
||||||
var songId = songInfo.id || '';
|
quality = String(quality || '128k');
|
||||||
var ceruKey = CERU_KEY || '';
|
var ceruKey = CERU_KEY || '';
|
||||||
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
||||||
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
||||||
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=wy&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(q), 'GET', headers)
|
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=wy&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(quality), 'GET', headers)
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
||||||
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
||||||
@@ -215,14 +230,16 @@ function getUrl(songInfo, type) {
|
|||||||
|
|
||||||
// ===== 封面图 =====
|
// ===== 封面图 =====
|
||||||
function getPic(songInfo) {
|
function getPic(songInfo) {
|
||||||
if (songInfo.pic) return Promise.resolve(songInfo.pic);
|
if (songInfo && songInfo.pic) return Promise.resolve(songInfo.pic);
|
||||||
|
var id = songInfo && songInfo.id ? String(songInfo.id) : '';
|
||||||
|
if (!id) return Promise.resolve('');
|
||||||
return requestUrl('https://music.163.com/weapi/v3/song/detail', 'POST', {
|
return requestUrl('https://music.163.com/weapi/v3/song/detail', 'POST', {
|
||||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36',
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36',
|
||||||
'Referer': 'https://music.163.com/song?id=' + songInfo.id,
|
'Referer': 'https://music.163.com/song?id=' + id,
|
||||||
'Origin': 'https://music.163.com',
|
'Origin': 'https://music.163.com',
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
'Cookie': WY_COOKIE
|
'Cookie': WY_COOKIE
|
||||||
}, querystring.stringify(weapi({ c: '[{"id":' + songInfo.id + '}]', ids: '[' + songInfo.id + ']' })))
|
}, querystring.stringify(weapi({ c: '[{"id":' + id + '}]', ids: '[' + id + ']' })))
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
if (res.body && res.body.songs && res.body.songs.length) return res.body.songs[0].al.picUrl;
|
if (res.body && res.body.songs && res.body.songs.length) return res.body.songs[0].al.picUrl;
|
||||||
return '';
|
return '';
|
||||||
@@ -232,8 +249,8 @@ function getPic(songInfo) {
|
|||||||
|
|
||||||
// ===== 歌词 =====
|
// ===== 歌词 =====
|
||||||
function getLyric(songInfo) {
|
function getLyric(songInfo) {
|
||||||
var songmid = songInfo.id || '';
|
var songmid = (songInfo && songInfo.id) || '';
|
||||||
return requestUrl('https://music.163.com/api/song/lyric?id=' + songmid + '&lv=1&kv=1&tv=-1', 'GET', {
|
return requestUrl('https://music.163.com/api/song/lyric?id=' + encodeURIComponent(songmid) + '&lv=1&kv=1&tv=-1', 'GET', {
|
||||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36',
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36',
|
||||||
'Referer': 'https://music.163.com/song?id=' + songmid,
|
'Referer': 'https://music.163.com/song?id=' + songmid,
|
||||||
'Cookie': WY_COOKIE
|
'Cookie': WY_COOKIE
|
||||||
@@ -256,7 +273,7 @@ function musicDetail(songmid) {
|
|||||||
var s = res.body.songs[0];
|
var s = res.body.songs[0];
|
||||||
var picUrl = s.al && s.al.picUrl ? s.al.picUrl : '';
|
var picUrl = s.al && s.al.picUrl ? s.al.picUrl : '';
|
||||||
return {
|
return {
|
||||||
id: s.id,
|
id: String(s.id),
|
||||||
name: s.name,
|
name: s.name,
|
||||||
artists: formatSingerName(s.ar, 'name'),
|
artists: formatSingerName(s.ar, 'name'),
|
||||||
source: 'wy',
|
source: 'wy',
|
||||||
@@ -264,8 +281,8 @@ function musicDetail(songmid) {
|
|||||||
mPic: picUrl,
|
mPic: picUrl,
|
||||||
sPic: picUrl,
|
sPic: picUrl,
|
||||||
albumName: s.al && s.al.name ? s.al.name : '',
|
albumName: s.al && s.al.name ? s.al.name : '',
|
||||||
albumId: s.al && s.al.id ? s.al.id : '',
|
albumId: String(s.al && s.al.id ? s.al.id : ''),
|
||||||
interval: formatPlayTime((s.dt || 0) / 1000),
|
interval: String(formatPlayTime((s.dt || 0) / 1000) || '--/--'),
|
||||||
qualities: {}
|
qualities: {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -356,7 +373,7 @@ function leaderboardGetList(id, page) {
|
|||||||
var item = tracks[i];
|
var item = tracks[i];
|
||||||
var picUrl = item.al && item.al.picUrl ? item.al.picUrl : '';
|
var picUrl = item.al && item.al.picUrl ? item.al.picUrl : '';
|
||||||
list.push({
|
list.push({
|
||||||
id: item.id,
|
id: String(item.id),
|
||||||
name: item.name,
|
name: item.name,
|
||||||
artists: formatSingerName(item.ar, 'name'),
|
artists: formatSingerName(item.ar, 'name'),
|
||||||
source: 'wy',
|
source: 'wy',
|
||||||
@@ -364,8 +381,8 @@ function leaderboardGetList(id, page) {
|
|||||||
mPic: picUrl,
|
mPic: picUrl,
|
||||||
sPic: picUrl,
|
sPic: picUrl,
|
||||||
albumName: item.al && item.al.name ? item.al.name : '',
|
albumName: item.al && item.al.name ? item.al.name : '',
|
||||||
albumId: item.al && item.al.id ? item.al.id : '',
|
albumId: String(item.al && item.al.id ? item.al.id : ''),
|
||||||
interval: formatPlayTime((item.dt || 0) / 1000),
|
interval: String(formatPlayTime((item.dt || 0) / 1000) || '--/--'),
|
||||||
qualities: {}
|
qualities: {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -373,14 +390,11 @@ function leaderboardGetList(id, page) {
|
|||||||
}).catch(function() { return { list: [], total: 0, source: 'wy' }; });
|
}).catch(function() { return { list: [], total: 0, source: 'wy' }; });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 歌单 =====
|
function leaderboard() {
|
||||||
function formatPlayCount(count) {
|
return Promise.resolve(BOARD_LIST);
|
||||||
if (!count && count !== 0) return '';
|
|
||||||
if (count >= 100000000) return (count / 100000000).toFixed(1) + '亿';
|
|
||||||
if (count >= 10000) return (count / 10000).toFixed(1) + '万';
|
|
||||||
return String(count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== 歌单 =====
|
||||||
var songList = {
|
var songList = {
|
||||||
limit_list: 30,
|
limit_list: 30,
|
||||||
sortList: [
|
sortList: [
|
||||||
@@ -461,14 +475,14 @@ var songList = {
|
|||||||
var item = tracks[i];
|
var item = tracks[i];
|
||||||
var picUrl = item.al && item.al.picUrl ? item.al.picUrl : '';
|
var picUrl = item.al && item.al.picUrl ? item.al.picUrl : '';
|
||||||
list.push({
|
list.push({
|
||||||
id: item.id,
|
id: String(item.id),
|
||||||
name: item.name,
|
name: item.name,
|
||||||
artists: formatSingerName(item.ar, 'name'),
|
artists: formatSingerName(item.ar, 'name'),
|
||||||
source: 'wy',
|
source: 'wy',
|
||||||
pic: picUrl, mPic: picUrl, sPic: picUrl,
|
pic: picUrl, mPic: picUrl, sPic: picUrl,
|
||||||
albumName: item.al && item.al.name ? item.al.name : '',
|
albumName: item.al && item.al.name ? item.al.name : '',
|
||||||
albumId: item.al && item.al.id ? item.al.id : '',
|
albumId: String(item.al && item.al.id ? item.al.id : ''),
|
||||||
interval: formatPlayTime((item.dt || 0) / 1000),
|
interval: String(formatPlayTime((item.dt || 0) / 1000) || '--/--'),
|
||||||
qualities: {}
|
qualities: {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -532,11 +546,11 @@ var singer = {
|
|||||||
var item = res.body.songs[i];
|
var item = res.body.songs[i];
|
||||||
var picUrl = item.al && item.al.picUrl ? item.al.picUrl : '';
|
var picUrl = item.al && item.al.picUrl ? item.al.picUrl : '';
|
||||||
list.push({
|
list.push({
|
||||||
id: item.id, name: item.name, artists: formatSingerName(item.artists, 'name'),
|
id: String(item.id), name: item.name, artists: formatSingerName(item.artists, 'name'),
|
||||||
source: 'wy', pic: picUrl, mPic: picUrl, sPic: picUrl,
|
source: 'wy', pic: picUrl, mPic: picUrl, sPic: picUrl,
|
||||||
albumName: item.album && item.album.name ? item.album.name : '',
|
albumName: item.album && item.album.name ? item.album.name : '',
|
||||||
albumId: item.album && item.album.id ? item.album.id : '',
|
albumId: String(item.album && item.album.id ? item.album.id : ''),
|
||||||
interval: formatPlayTime((item.duration || 0) / 1000), qualities: {}
|
interval: String(formatPlayTime((item.duration || 0) / 1000) || '--/--'), qualities: {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return { list: list, total: res.body.total || 0, page: page, limit: limit, source: 'wy' };
|
return { list: list, total: res.body.total || 0, page: page, limit: limit, source: 'wy' };
|
||||||
@@ -593,11 +607,11 @@ var album = {
|
|||||||
var item = res.body.songs[i];
|
var item = res.body.songs[i];
|
||||||
var picUrl = item.al && item.al.picUrl ? item.al.picUrl : '';
|
var picUrl = item.al && item.al.picUrl ? item.al.picUrl : '';
|
||||||
list.push({
|
list.push({
|
||||||
id: item.id, name: item.name, artists: formatSingerName(item.ar, 'name'),
|
id: String(item.id), name: item.name, artists: formatSingerName(item.ar, 'name'),
|
||||||
source: 'wy', pic: picUrl, mPic: picUrl, sPic: picUrl,
|
source: 'wy', pic: picUrl, mPic: picUrl, sPic: picUrl,
|
||||||
albumName: item.al && item.al.name ? item.al.name : '',
|
albumName: item.al && item.al.name ? item.al.name : '',
|
||||||
albumId: item.al && item.al.id ? item.al.id : '',
|
albumId: String(item.al && item.al.id ? item.al.id : ''),
|
||||||
interval: formatPlayTime((item.dt || 0) / 1000), qualities: {}
|
interval: String(formatPlayTime((item.dt || 0) / 1000) || '--/--'), qualities: {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return { list: list, total: list.length, page: page, limit: limit, source: 'wy' };
|
return { list: list, total: list.length, page: page, limit: limit, source: 'wy' };
|
||||||
@@ -610,7 +624,7 @@ var pluginInfo = {
|
|||||||
info: {
|
info: {
|
||||||
id: 'koneko_ceru_wy',
|
id: 'koneko_ceru_wy',
|
||||||
name: '网易云音乐 - Koneko 聆澜',
|
name: '网易云音乐 - Koneko 聆澜',
|
||||||
version: '0.1.0',
|
version: '0.1.2',
|
||||||
source: 'wy',
|
source: 'wy',
|
||||||
description: '网易云音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
description: '网易云音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
||||||
},
|
},
|
||||||
@@ -623,11 +637,11 @@ var pluginInfo = {
|
|||||||
{ key: 'cookie', name: '网易云Cookie', description: '网易云音乐登录Cookie(需包含MUSIC_U=),用于个人歌单、收藏等功能' }
|
{ key: 'cookie', name: '网易云Cookie', description: '网易云音乐登录Cookie(需包含MUSIC_U=),用于个人歌单、收藏等功能' }
|
||||||
],
|
],
|
||||||
quality: [
|
quality: [
|
||||||
{ name: '标准', ui: '标', id: '128k' },
|
{ name: '标准音质', ui: '标', id: '128k' },
|
||||||
{ name: '高品', ui: 'HQ', id: '320k' },
|
{ name: '高品音质', ui: 'HQ', id: '320k' },
|
||||||
{ name: '无损', ui: 'SQ', id: 'flac' }
|
{ name: '无损音质', ui: 'SQ', id: 'flac' }
|
||||||
],
|
],
|
||||||
supportFunc: ['musicSearch', 'tipSearch', 'hotSearch', 'leaderboard', 'songList', 'singer', 'album', 'getLyric', 'getPic', 'getUrl', 'musicDetail', 'musicInfo']
|
supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric']
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -56,13 +56,23 @@ function requestUrl(urlStr, method, headers, body) {
|
|||||||
return doRequest(protocol, options, postData);
|
return doRequest(protocol, options, postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPlayTime(seconds) {
|
// ===== 格式化辅助 =====
|
||||||
if (!seconds) return '00:00';
|
function formatPlayTime(time) {
|
||||||
var m = Math.floor(seconds / 60);
|
if (!time) return '--/--';
|
||||||
var s = Math.floor(seconds % 60);
|
var m = Math.floor(time / 60);
|
||||||
|
var s = Math.floor(time % 60);
|
||||||
|
if (m === 0 && s === 0) return '--/--';
|
||||||
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sizeFormate(bytes) {
|
||||||
|
if (typeof bytes === 'string') bytes = parseFloat(bytes.replace(/[^0-9.]/g, ''));
|
||||||
|
var n = parseFloat(bytes);
|
||||||
|
if (isNaN(n) || n < 0) return '0.00MB';
|
||||||
|
var mb = n / (1024 * 1024);
|
||||||
|
return mb.toFixed(2) + 'MB';
|
||||||
|
}
|
||||||
|
|
||||||
// ===== 搜索实现 =====
|
// ===== 搜索实现 =====
|
||||||
function musicSearch(str, page, limit) {
|
function musicSearch(str, page, limit) {
|
||||||
var url = 'https://kuwo-api.vercel.app/api/search?key=' + encodeURIComponent(str) + '&page=' + page + '&limit=' + limit;
|
var url = 'https://kuwo-api.vercel.app/api/search?key=' + encodeURIComponent(str) + '&page=' + page + '&limit=' + limit;
|
||||||
@@ -74,15 +84,19 @@ function musicSearch(str, page, limit) {
|
|||||||
|
|
||||||
function handleSearchResult(rawList) {
|
function handleSearchResult(rawList) {
|
||||||
var list = [];
|
var list = [];
|
||||||
|
if (!rawList) return list;
|
||||||
for (var i = 0; i < rawList.length; i++) {
|
for (var i = 0; i < rawList.length; i++) {
|
||||||
var item = rawList[i];
|
var item = rawList[i];
|
||||||
var qualities = {};
|
var qualities = {};
|
||||||
if (item.filesize) qualities.standard = String(item.filesize);
|
var size128 = item.filesize || item.mp3size || item.mp3Size || 0;
|
||||||
if (item.sqfilesize) qualities.exhigh = String(item.sqfilesize);
|
var size320 = item.sqfilesize || item.hqsize || item['320size'] || item['320filesize'] || 0;
|
||||||
if (item.flacfilesize) qualities.lossless = String(item.flacfilesize);
|
var sizeFlac = item.flacfilesize || item.flacsize || item.flacSize || 0;
|
||||||
var picUrl = item.pic || '';
|
if (size128) qualities['128k'] = sizeFormate(size128);
|
||||||
|
if (size320) qualities['320k'] = sizeFormate(size320);
|
||||||
|
if (sizeFlac) qualities['flac'] = sizeFormate(sizeFlac);
|
||||||
|
var picUrl = item.pic || item.albumpic || '';
|
||||||
list.push({
|
list.push({
|
||||||
id: item.id || item.rid || '',
|
id: String(item.rid || item.id || ''),
|
||||||
name: item.name || '',
|
name: item.name || '',
|
||||||
artists: item.artist || '',
|
artists: item.artist || '',
|
||||||
source: 'kw',
|
source: 'kw',
|
||||||
@@ -90,8 +104,8 @@ function handleSearchResult(rawList) {
|
|||||||
mPic: picUrl,
|
mPic: picUrl,
|
||||||
sPic: picUrl,
|
sPic: picUrl,
|
||||||
albumName: item.album || '',
|
albumName: item.album || '',
|
||||||
albumId: item.albumid || '',
|
albumId: String(item.albumid || ''),
|
||||||
interval: item.duration ? formatPlayTime(item.duration) : '',
|
interval: String(formatPlayTime(item.duration) || '--/--'),
|
||||||
qualities: qualities
|
qualities: qualities
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -109,13 +123,13 @@ function search(str, page, limit, retryNum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== 播放链接 =====
|
// ===== 播放链接 =====
|
||||||
function getUrl(songInfo, type) {
|
function getUrl(songId, quality) {
|
||||||
var q = (type === 'standard' ? '128k' : type === 'exhigh' ? '320k' : type === 'lossless' || type === 'hires' || type === 'jymaster' ? 'flac' : type) || '128k';
|
songId = String(songId || '');
|
||||||
var songId = songInfo.id || '';
|
quality = String(quality || '128k');
|
||||||
var ceruKey = CERU_KEY || '';
|
var ceruKey = CERU_KEY || '';
|
||||||
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
||||||
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
||||||
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=kw&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(q), 'GET', headers)
|
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=kw&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(quality), 'GET', headers)
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
||||||
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
||||||
@@ -126,13 +140,13 @@ function getUrl(songInfo, type) {
|
|||||||
|
|
||||||
// ===== 封面图 =====
|
// ===== 封面图 =====
|
||||||
function getPic(songInfo) {
|
function getPic(songInfo) {
|
||||||
if (songInfo.pic) return Promise.resolve(songInfo.pic);
|
if (songInfo && songInfo.pic) return Promise.resolve(songInfo.pic);
|
||||||
return Promise.resolve('');
|
return Promise.resolve('');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 歌词 =====
|
// ===== 歌词 =====
|
||||||
function getLyric(songInfo) {
|
function getLyric(songInfo) {
|
||||||
var rid = songInfo.id || '';
|
var rid = (songInfo && songInfo.id) || '';
|
||||||
if (!rid) return Promise.resolve('');
|
if (!rid) return Promise.resolve('');
|
||||||
return requestUrl('https://kuwo-api.vercel.app/api/lyric?id=' + encodeURIComponent(rid), 'GET', {
|
return requestUrl('https://kuwo-api.vercel.app/api/lyric?id=' + encodeURIComponent(rid), 'GET', {
|
||||||
'User-Agent': 'Mozilla/5.0 (Linux; Android 10)'
|
'User-Agent': 'Mozilla/5.0 (Linux; Android 10)'
|
||||||
@@ -171,18 +185,18 @@ var pluginInfo = {
|
|||||||
info: {
|
info: {
|
||||||
id: 'koneko_ceru_kw',
|
id: 'koneko_ceru_kw',
|
||||||
name: '酷我音乐 - Koneko 聆澜',
|
name: '酷我音乐 - Koneko 聆澜',
|
||||||
version: '0.1.0',
|
version: '0.1.2',
|
||||||
source: 'kw',
|
source: 'kw',
|
||||||
description: '酷我音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
description: '酷我音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
||||||
},
|
},
|
||||||
ext: [],
|
ext: [],
|
||||||
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
||||||
quality: [
|
quality: [
|
||||||
{ name: '标准', ui: '标', id: '128k' },
|
{ name: '标准音质', ui: '标', id: '128k' },
|
||||||
{ name: '高品', ui: 'HQ', id: '320k' },
|
{ name: '高品音质', ui: 'HQ', id: '320k' },
|
||||||
{ name: '无损', ui: 'SQ', id: 'flac' }
|
{ name: '无损音质', ui: 'SQ', id: 'flac' }
|
||||||
],
|
],
|
||||||
supportFunc: []
|
supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric']
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -191,7 +205,7 @@ module.exports = {
|
|||||||
hotSearch: { getList: hotSearch },
|
hotSearch: { getList: hotSearch },
|
||||||
leaderboard: { getBoards: leaderboard },
|
leaderboard: { getBoards: leaderboard },
|
||||||
songList: songList,
|
songList: songList,
|
||||||
artists: singer,
|
singer: singer,
|
||||||
album: album,
|
album: album,
|
||||||
getLyric: getLyric,
|
getLyric: getLyric,
|
||||||
getPic: getPic,
|
getPic: getPic,
|
||||||
@@ -56,33 +56,44 @@ function requestUrl(urlStr, method, headers, body) {
|
|||||||
return doRequest(protocol, options, postData);
|
return doRequest(protocol, options, postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPlayTime(seconds) {
|
// ===== 格式化辅助 =====
|
||||||
if (!seconds) return '00:00';
|
function formatPlayTime(time) {
|
||||||
var m = Math.floor(seconds / 60);
|
if (!time) return '--/--';
|
||||||
var s = Math.floor(seconds % 60);
|
var m = Math.floor(time / 60);
|
||||||
|
var s = Math.floor(time % 60);
|
||||||
|
if (m === 0 && s === 0) return '--/--';
|
||||||
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sizeFormate(bytes) {
|
||||||
|
if (typeof bytes === 'string') bytes = parseFloat(bytes.replace(/[^0-9.]/g, ''));
|
||||||
|
var n = parseFloat(bytes);
|
||||||
|
if (isNaN(n) || n < 0) return '0.00MB';
|
||||||
|
var mb = n / (1024 * 1024);
|
||||||
|
return mb.toFixed(2) + 'MB';
|
||||||
|
}
|
||||||
|
|
||||||
// ===== 搜索实现 =====
|
// ===== 搜索实现 =====
|
||||||
function musicSearch(str, page, limit) {
|
function musicSearch(str, page, limit) {
|
||||||
var url = 'http://mobilecdn.kugou.com/api/v3/search/song?showtype=14&highlight=em&pagesize=' + limit + '&page=' + page + '&keyword=' + encodeURIComponent(str);
|
var url = 'http://mobilecdn.kugou.com/api/v3/search/song?showtype=14&highlight=em&pagesize=' + limit + '&page=' + page + '&keyword=' + encodeURIComponent(str);
|
||||||
return requestUrl(url, 'GET', { 'User-Agent': 'Mozilla/5.0 (Linux; Android 10)' }).then(function(res) {
|
return requestUrl(url, 'GET', { 'User-Agent': 'Mozilla/5.0 (Linux; Android 10)' }).then(function(res) {
|
||||||
if (res.body && res.body.data && res.body.data.info) return res.body.data.info;
|
if (res.body && res.body.data && res.body.data.info) return res.body.data;
|
||||||
throw new Error('kg search failed');
|
throw new Error('kg search failed');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSearchResult(rawList) {
|
function handleSearchResult(rawList) {
|
||||||
var list = [];
|
var list = [];
|
||||||
|
if (!rawList) return list;
|
||||||
for (var i = 0; i < rawList.length; i++) {
|
for (var i = 0; i < rawList.length; i++) {
|
||||||
var item = rawList[i];
|
var item = rawList[i];
|
||||||
var qualities = {};
|
var qualities = {};
|
||||||
if (item.filesize) qualities.standard = String(item.filesize);
|
if (item.filesize) qualities['128k'] = sizeFormate(item.filesize);
|
||||||
if (item.sqfilesize) qualities.exhigh = String(item.sqfilesize);
|
if (item.sqfilesize) qualities['320k'] = sizeFormate(item.sqfilesize);
|
||||||
if (item.flacfilesize) qualities.lossless = String(item.flacfilesize);
|
if (item.flacfilesize) qualities['flac'] = sizeFormate(item.flacfilesize);
|
||||||
var picUrl = item.img || '';
|
var picUrl = item.img || '';
|
||||||
list.push({
|
list.push({
|
||||||
id: item.hash || item.audio_id || '',
|
id: String(item.hash || item.audio_id || ''),
|
||||||
name: item.songname || '',
|
name: item.songname || '',
|
||||||
artists: item.singername || '',
|
artists: item.singername || '',
|
||||||
source: 'kg',
|
source: 'kg',
|
||||||
@@ -90,8 +101,8 @@ function handleSearchResult(rawList) {
|
|||||||
mPic: picUrl,
|
mPic: picUrl,
|
||||||
sPic: picUrl,
|
sPic: picUrl,
|
||||||
albumName: item.album_name || '',
|
albumName: item.album_name || '',
|
||||||
albumId: item.album_id || '',
|
albumId: String(item.album_id || ''),
|
||||||
interval: item.duration ? formatPlayTime(item.duration) : '',
|
interval: String(formatPlayTime(item.duration) || '--/--'),
|
||||||
qualities: qualities
|
qualities: qualities
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -102,20 +113,22 @@ function search(str, page, limit, retryNum) {
|
|||||||
if (retryNum === undefined) retryNum = 0;
|
if (retryNum === undefined) retryNum = 0;
|
||||||
if (++retryNum > 3) return Promise.reject(new Error('try max num'));
|
if (++retryNum > 3) return Promise.reject(new Error('try max num'));
|
||||||
if (!limit) limit = 30;
|
if (!limit) limit = 30;
|
||||||
return musicSearch(str, page, limit).then(function(rawList) {
|
return musicSearch(str, page, limit).then(function(data) {
|
||||||
|
var rawList = data.info || [];
|
||||||
|
var total = data.total || rawList.length * 10;
|
||||||
var list = handleSearchResult(rawList);
|
var list = handleSearchResult(rawList);
|
||||||
return { list: list, allPage: page + 1, limit: limit, total: list.length * 10, source: 'kg' };
|
return { list: list, allPage: Math.ceil(total / limit), limit: limit, total: total, source: 'kg' };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 播放链接 =====
|
// ===== 播放链接 =====
|
||||||
function getUrl(songInfo, type) {
|
function getUrl(songId, quality) {
|
||||||
var q = (type === 'standard' ? '128k' : type === 'exhigh' ? '320k' : type === 'lossless' || type === 'hires' || type === 'jymaster' ? 'flac' : type) || '128k';
|
songId = String(songId || '');
|
||||||
var songId = songInfo.id || '';
|
quality = String(quality || '128k');
|
||||||
var ceruKey = CERU_KEY || '';
|
var ceruKey = CERU_KEY || '';
|
||||||
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
var headers = { 'User-Agent': 'QZMusic/2.0' };
|
||||||
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
if (ceruKey) headers['X-API-Key'] = ceruKey;
|
||||||
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=kg&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(q), 'GET', headers)
|
return requestUrl('https://source.shiqianjiang.cn/api/music/url?source=kg&songId=' + encodeURIComponent(songId) + '&quality=' + encodeURIComponent(quality), 'GET', headers)
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
if (res.body && typeof res.body === 'object' && res.body.url) return res.body.url;
|
||||||
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
if (res.body && typeof res.body === 'object' && res.body.data && res.body.data.url) return res.body.data.url;
|
||||||
@@ -126,13 +139,13 @@ function getUrl(songInfo, type) {
|
|||||||
|
|
||||||
// ===== 封面图 =====
|
// ===== 封面图 =====
|
||||||
function getPic(songInfo) {
|
function getPic(songInfo) {
|
||||||
if (songInfo.pic) return Promise.resolve(songInfo.pic);
|
if (songInfo && songInfo.pic) return Promise.resolve(songInfo.pic);
|
||||||
return Promise.resolve('');
|
return Promise.resolve('');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 歌词 =====
|
// ===== 歌词 =====
|
||||||
function getLyric(songInfo) {
|
function getLyric(songInfo) {
|
||||||
var hash = songInfo.id || '';
|
var hash = (songInfo && songInfo.id) || '';
|
||||||
if (!hash) return Promise.resolve('');
|
if (!hash) return Promise.resolve('');
|
||||||
return requestUrl('https://krcs.kugou.com/search?ver=1&man=yes&client=mobi&keyword=&duration=&hash=' + encodeURIComponent(hash) + '&album_audio_id=', 'GET', {
|
return requestUrl('https://krcs.kugou.com/search?ver=1&man=yes&client=mobi&keyword=&duration=&hash=' + encodeURIComponent(hash) + '&album_audio_id=', 'GET', {
|
||||||
'User-Agent': 'Mozilla/5.0 (Linux; Android 10)'
|
'User-Agent': 'Mozilla/5.0 (Linux; Android 10)'
|
||||||
@@ -182,18 +195,18 @@ var pluginInfo = {
|
|||||||
info: {
|
info: {
|
||||||
id: 'koneko_ceru_kg',
|
id: 'koneko_ceru_kg',
|
||||||
name: '酷狗音乐 - Koneko 聆澜',
|
name: '酷狗音乐 - Koneko 聆澜',
|
||||||
version: '0.1.0',
|
version: '0.1.2',
|
||||||
source: 'kg',
|
source: 'kg',
|
||||||
description: '酷狗音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
description: '酷狗音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口'
|
||||||
},
|
},
|
||||||
ext: [],
|
ext: [],
|
||||||
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜播放接口密钥' }],
|
||||||
quality: [
|
quality: [
|
||||||
{ name: '标准', ui: '标', id: '128k' },
|
{ name: '标准音质', ui: '标', id: '128k' },
|
||||||
{ name: '高品', ui: 'HQ', id: '320k' },
|
{ name: '高品音质', ui: 'HQ', id: '320k' },
|
||||||
{ name: '无损', ui: 'SQ', id: 'flac' }
|
{ name: '无损音质', ui: 'SQ', id: 'flac' }
|
||||||
],
|
],
|
||||||
supportFunc: []
|
supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric']
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -202,7 +215,7 @@ module.exports = {
|
|||||||
hotSearch: { getList: hotSearch },
|
hotSearch: { getList: hotSearch },
|
||||||
leaderboard: { getBoards: leaderboard },
|
leaderboard: { getBoards: leaderboard },
|
||||||
songList: songList,
|
songList: songList,
|
||||||
artists: singer,
|
singer: singer,
|
||||||
album: album,
|
album: album,
|
||||||
getLyric: getLyric,
|
getLyric: getLyric,
|
||||||
getPic: getPic,
|
getPic: getPic,
|
||||||
Reference in New Issue
Block a user