Files
Koneko_api_for_QZ-Music/QZ_Music-V2 插件规范(初版)│QZ_Music-V2-Plugin-Development-Guide.md

22 KiB
Raw Blame History

鎻掍欢寮€鍙戝府鍔╂枃妗?

鐩綍

  1. 姒傝堪
  2. 鏍稿績璁捐鍘熷垯
  3. [浠庡叾浠栧钩鍙拌縼绉绘寚鍗梋(#浠庡叾浠栧钩鍙拌縼绉绘寚鍗?
  4. 鎻掍欢鍩烘湰缁撴瀯
  5. 鏁版嵁鏍煎紡瑙勮寖
  6. 绀轰緥浠g爜璇﹁В
  7. [骞冲彴閰嶇疆鍙傝€僝(#骞冲彴閰嶇疆鍙傝€?
  8. 甯歌闂

姒傝堪

鏈枃妗g敤浜庢寚瀵煎紑鍙戣€呯紪鍐欓煶婧愭彃浠躲€傛湰绯荤粺浣跨敤 Node.js 杩愯鏃剁幆澧冿紝鎻掍欢閲囩敤 CommonJS 妯″潡瑙勮寖锛岄€氳繃 module.exports 瀵煎嚭鍔熻兘鎺ュ彛銆?

涓庡叾浠栫郴缁熺殑鍖哄埆

鐗规€? 鏈郴缁? 鍏朵粬绯荤粺
杩愯鏃? Node.js JavaScript 杩愯鏃?
妯″潡瑙勮寖 CommonJS 鍏ㄥ眬浜嬩欢鐩戝惉
瀵煎嚭鏂瑰紡 module.exports 浜嬩欢鍙戦€?
閫氫俊鏂瑰紡 鐩存帴鍑芥暟璋冪敤 浜嬩欢椹卞姩
HTTP 璇锋眰 axios 鎴栧唴缃?httpFetch 鍏ㄥ眬璇锋眰瀵硅薄

鎻掍欢绫诲瀷

鏈郴缁熸彃浠跺睘浜?*瀹屾暣闊虫簮鎻掍欢**锛屾牳蹇冨姛鑳藉寘鎷細

  • 鎼滅储鍐呭
  • 鑾峰彇鎾斁 URL
  • 鑾峰彇姝岃瘝
  • 鑾峰彇鍒楄〃/鍚堥泦淇℃伅
  • 鑾峰彇鐑悳/鎺掕姒?

鏍稿績璁捐鍘熷垯

1. 鍗曞钩鍙板師鍒欙紙閲嶈锛?

**姣忎釜鎻掍欢鍙敮鎸佷竴涓钩鍙?*锛屼緥濡傦細

  • 鉁?骞冲彴A鎻掍欢锛堜粎鏀寔 A锛?- 鉁?骞冲彴B鎻掍欢锛堜粎鏀寔 B锛?- 鉂?鑱氬悎鎻掍欢锛堝悓鏃舵敮鎸?A + B + C锛? 鍘熷洜璇存槑锛?``` 鐢ㄦ埛鍚戞彃浠朵紶閰嶇疆鍙兘閫氳繃鐜鍙橀噺锛坋nv锛?濡傛灉鎻掍欢鏀寔澶氬钩鍙帮紝鍒囨崲骞冲彴鏃堕渶瑕佷慨鏀圭幆澧冨彉閲忥紝鎿嶄綔绻佺悙 鍗曞钩鍙版彃浠舵洿娓呮櫚锛岀淮鎶ゆ垚鏈綆锛屼笉鏄撳嚭鐜?浠g爜灞庡北"

**濡傞渶澶氬钩鍙版敮鎸?*锛氬缓璁嚜寤哄悗绔湇鍔★紝缁熶竴澶勭悊鎼滅储鍜?URL 鑾峰彇锛屽墠绔彃浠跺彧浣滀负浠g悊銆?
### 2. 閰嶇疆鏂瑰紡

閫氳繃 `global.env` 璇诲彇鐜鍙橀噺锛圝SON 鏍煎紡锛夛細

```javascript
// 璇诲彇鐢ㄦ埛閰嶇疆鐨?API 瀵嗛挜
const API_KEY = global.env.API_KEY || ''

// 璇诲彇鑷畾涔夋湇鍔$鍦板潃
const CUSTOM_SERVER = global.env.SERVER_URL || '榛樿鍦板潃'

鐜鍙橀噺鍔犺浇鏂瑰紡锛?```javascript const plugin = require('./index.js') global.env = $envCommand // 鐢辩郴缁熸敞鍏ワ紝鏍煎紡涓?JSON

// 鍦ㄦ彃浠朵唬鐮佷腑閫氳繃 global.env 璇诲彇 const env = global.env || {} const API_KEY = env.API_KEY || ''


### 3. 鏀寔鐨勯煶璐ㄦ爣璇?
| 鏍囪瘑 | 璇存槑 |
|------|------|
| `128k` | 鏍囧噯闊宠川 |
| `320k` | 楂樺搧闊宠川 |
| `flac` | 鏃犳崯闊宠川 |
| `flac24bit` | 楂樿В鏋愬害鏃犳崯 |
| `hires` | 瓒呴珮瑙f瀽搴?|

---

## 浠庡叾浠栧钩鍙拌縼绉绘寚鍗?
### 杩佺Щ瀵圭収琛?
| 鍏朵粬绯荤粺 | 鏈郴缁?| 璇存槑 |
|----------|--------|------|
| `globalThis.lx` | `require` 妯″潡 | 涓嶅啀闇€瑕佸叏灞€瀵硅薄 |
| `globalThis.lx.request` | `axios` 鎴?`httpFetch` | 浣跨敤鏍囧噯 HTTP 搴?|
| `globalThis.lx.env` | `global.env` | 鐜鍙橀噺璇诲彇鏂瑰紡 |
| `on(EVENT_NAMES.request, ...)` | 鐩存帴瀵煎嚭鍑芥暟 | 鏀逛负鍑芥暟瀵煎嚭 |
| `send(EVENT_NAMES.inited, ...)` | `module.exports` | 鏀逛负妯″潡瀵煎嚭 |
| `musicInfo.songmid` | `musicInfo.id` | 瀛楁鍚嶅彲鑳戒笉鍚?|
| `info.type` | `quality` 鍙傛暟 | 闊宠川鍙傛暟浣嶇疆 |

### 杩佺Щ姝ラ

#### 姝ラ 1锛氫慨鏀规ā鍧楀鍏?
**鍏朵粬绯荤粺鍘熶唬鐮侊細**
```javascript
const { EVENT_NAMES, request, on, send, env, version } = globalThis.lx

*鏈郴缁熸柊浠g爜锛?

const axios = require('axios')
const crypto = require('crypto')

// 鐜鍙橀噺浠?global.env 璇诲彇
const env = global.env || {}
const API_KEY = env.API_KEY || ''

姝ラ 2锛氫慨鏀?HTTP 璇锋眰

鍏朵粬绯荤粺鍘熶唬鐮侊細

function httpRequest(url) {
  return new Promise((resolve, reject) => {
    request(url, { headers }, (err, resp) => {
      if (err) return reject(err)
      resolve(resp.body)
    })
  })
}

*鏈郴缁熸柊浠g爜锛?

async function httpRequest(url, options = {}) {
  const response = await axios({
    url,
    method: options.method || 'GET',
    headers: options.headers,
    timeout: options.timeout || 10000
  })
  return response.data
}

姝ラ 3锛氫慨鏀瑰嚱鏁板鍑?

鍏朵粬绯荤粺鍘熶唬鐮侊細

// 浜嬩欢鐩戝惉鏂瑰紡
on(EVENT_NAMES.request, ({ action, source, info }) => {
  switch (action) {
    case 'musicUrl':
      return getMusicUrl(info.musicInfo, info.type)
  }
})

// 鍒濆鍖栦簨浠?send(EVENT_NAMES.inited, {
  status: true,
  sources: musicSource
})

*鏈郴缁熸柊浠g爜锛?

// 鐩存帴瀵煎嚭鍑芥暟
module.exports = {
  // 鎼滅储鍔熻兘
  musicSearch,
  
  // 鑾峰彇 URL
  getUrl,
  
  // 鑾峰彇姝岃瘝
  getLyric,
  
  // 鑾峰彇鍒楄〃
  songList,
  
  // 鑾峰彇鍚堥泦
  album,
  
  // 鑾峰彇鐑悳
  hotSearch,
  
  // 鎻掍欢淇℃伅
  pluginInfo: {
    info: { id: 'A', name: '骞冲彴A', version: '3' },
    quality: [...],
    supportFunc: [...]
  }
}

姝ラ 4锛氫慨鏀硅繑鍥炴暟鎹牸寮?

鍏朵粬绯荤粺鍘熶唬鐮侊細

// 鐩存帴杩斿洖 URL 瀛楃涓?return 'https://example.com/audio.mp3'

// 鎴栬繑鍥炴瓕璇嶅璞?return {
  lyric: '[00:00.000]姝岃瘝鍐呭',
  tlyric: '[00:00.000]缈昏瘧姝岃瘝'
}

*鏈郴缁熸柊浠g爜锛?

// 鎼滅储杩斿洖缁熶竴鏍煎紡
return {
  list: [{
    id: '123456',
    name: '鍐呭鍚?,
    artists: '鍒涗綔鑰?,
    source: 'A',
    pic: '灏侀潰URL',
    mPic: '涓皝闈RL',
    sPic: '灏忓皝闈RL',
    albumName: '鍚堥泦鍚?,
    albumId: '鍚堥泦ID',
    interval: '03:45',
    qualities: { '128k': '4.2M', 'flac': '35M' }
  }],
  total: 100,
  page: 1,
  limit: 20,
  allPage: 5,
  source: 'A'
}

// 姝岃瘝杩斿洖鏍煎紡
return {
  lyric: '姝岃瘝鍐呭',
  tlyric: '缈昏瘧姝岃瘝'
}

鎻掍欢鍩烘湰缁撴瀯

鏂囦欢澶撮儴娉ㄩ噴

/**
 * @name 骞冲彴A闊虫簮
 * @description 闊虫簮鎻掍欢
 * @version 3.0.0
 * @author 寮€鍙戣€? * @homepage https://github.com/your-repo
 * @license MIT
 * 
 * 鏀寔骞冲彴: 骞冲彴A
 * 鏀寔闊宠川: 128k, 320k, flac
 */

鏍稿績瀵煎叆

'use strict'

// 鏍囧噯 Node.js 妯″潡
const axios = require('axios')
const crypto = require('crypto')

閰嶇疆鍖哄煙

// ========== 鐢ㄦ埛鍙厤缃尯鍩?==========

// 浠?global.env 璇诲彇鐜鍙橀噺锛圝SON 鏍煎紡锛?const env = global.env || {}

// 鏈嶅姟绔湴鍧€锛堢敤鎴峰彲閫氳繃鐜鍙橀噺瑕嗙洊锛?const API_BASE = env.SERVER_URL || 'https://your-server.com'

// API 瀵嗛挜锛堢敤鎴烽€氳繃鐜鍙橀噺璁剧疆锛?const API_KEY = env.API_KEY || ''

// 褰撳墠骞冲彴鏍囪瘑锛堝崟骞冲彴鎻掍欢鍥哄畾鍊硷級
const PLATFORM = 'A'

// 鏀寔鐨勯煶璐ㄥ垪琛?const SUPPORT_QUALITIES = ['128k', '320k', 'flac']

瀵煎嚭缁撴瀯

// ========== 鎻掍欢瀵煎嚭 ==========

module.exports = {
  // 鏍稿績鍔熻兘锛堝繀椤诲疄鐜帮級
  musicSearch,      // 鍐呭鎼滅储
  getUrl,           // 鑾峰彇 URL
  
  // 鍙€夊姛鑳?  getLyric,         // 鑾峰彇姝岃瘝
  songList,         // 鍒楄〃璇︽儏
  album,            // 鍚堥泦璇︽儏
  hotSearch,        // 鐑悳璇?  tipSearch,        // 鎼滅储鎻愮ず
  leaderboard,      // 鎺掕姒?  
  // 鎻掍欢淇℃伅锛堝繀椤伙級
  pluginInfo: {
    info: {
      id: 'A',                    // 骞冲彴鏍囪瘑
      name: '骞冲彴A',               // 鏄剧ず鍚嶇О
      description: '骞冲彴A鎻掍欢',     // 鎻忚堪
      version: '3'                 // 鐗堟湰鍙?    },
    env: [                          // 鐜鍙橀噺閰嶇疆
      { key: 'API_KEY', name: 'API瀵嗛挜', description: '鏈嶅姟绔疉PI瀵嗛挜' }
    ],
    ext: [],                        // 鎵╁睍鍔熻兘
    quality: [                      // 鏀寔鐨勯煶璐?      { name: '鏍囧噯闊宠川', ui: '鏍?, id: '128k' },
      { name: '楂樺搧闊宠川', ui: 'HQ', id: '320k' },
      { name: '鏃犳崯闊宠川', ui: 'SQ', id: 'flac' }
    ],
    supportFunc: [                  // 鏀寔鐨勫姛鑳?      'search_song',
      'search_playlist',
      'playlist',
      'album',
      'lyric'
    ]
  }
}

鏁版嵁鏍煎紡瑙勮寖

鎼滅储缁撴灉缁熶竴鏍煎紡

{
  list: [
    {
      id: String,              // 鍞竴鏍囪瘑
      name: String,             // 鍚嶇О
      artists: String,          // 鍒涗綔鑰咃紙鐢?"銆? 鍒嗛殧锛?      source: String,           // 骞冲彴鏍囪瘑
      pic: String,              // 澶у皝闈?URL
      mPic: String,             // 涓皝闈?URL
      sPic: String,             // 灏忓皝闈?URL
      albumName: String,        // 鍚堥泦鍚?      albumId: String,          // 鍚堥泦 ID
      interval: String,         // 鏃堕暱 "mm:ss"
      qualities: {              // 闊宠川 -> 鏂囦欢澶у皬
        '128k': '4.2M',
        '320k': '8.5M',
        'flac': '35M'
      }
    }
  ],
  total: Number,               // 鎬绘暟閲?  page: Number,                // 褰撳墠椤电爜
  limit: Number,               // 姣忛〉鏁伴噺
  allPage: Number,             // 鎬婚〉鏁?  source: String               // 骞冲彴鏍囪瘑
}

姝岃瘝缁熶竴鏍煎紡

{
  lyric: String,       // 鏅€氭瓕璇?  tlyric: String,      // 缈昏瘧姝岃瘝
  qrc: String,         // 閫愬瓧姝岃瘝
  roma: String         // 闊宠瘧姝岃瘝
}

// 娉ㄦ剰锛氳嚦灏戣繑鍥?lyric 鎴?qrc 涔嬩竴

鍒楄〃璇︽儏缁熶竴鏍煎紡

{
  list: [/* 鍐呭鍒楄〃锛屾牸寮忓悓鎼滅储缁撴灉 */],
  page: Number,
  limit: Number,
  total: Number,
  source: String,
  info: {
    name: String,        // 鍒楄〃鍚?    img: String,         // 灏侀潰鍥?    desc: String,        // 鎻忚堪
    author: String       // 鍒涘缓鑰?  }
}

鍚堥泦璇︽儏缁熶竴鏍煎紡

{
  list: [/* 鍐呭鍒楄〃锛屾牸寮忓悓鎼滅储缁撴灉 */],
  page: Number,
  limit: Number,
  total: Number,
  source: String,
  info: {
    name: String,        // 鍚堥泦鍚?    img: String,         // 灏侀潰鍥?    desc: String,        // 鎻忚堪
    author: String       // 鍒涗綔鑰?  }
}

绀轰緥浠g爜璇﹁В

瀹屾暣鎻掍欢妯℃澘

/**
 * @name 骞冲彴A闊虫簮
 * @description 闊虫簮鎻掍欢绀轰緥
 * @version 3.0.0
 * @author 寮€鍙戣€? * 
 * 鏀寔骞冲彴: 骞冲彴A
 * 鏀寔闊宠川: 128k, 320k, flac
 */

'use strict'

// ==================== 鏍稿績瀵煎叆 ====================

const axios = require('axios')
const crypto = require('crypto')

// ==================== 閰嶇疆鍖哄煙 ====================

// 浠?global.env 璇诲彇鐜鍙橀噺锛圝SON 鏍煎紡锛?const env = global.env || {}

// 骞冲彴鏍囪瘑锛堝浐瀹氬€硷紝鍗曞钩鍙版彃浠讹級
const PLATFORM = 'A'

// 鏈嶅姟绔厤缃?const CONFIG = {
  serverUrl: env.SERVER_URL || 'https://api.example.com',
  apiKey: env.API_KEY || '',
  timeout: 10000
}

// 鏀寔鐨勯煶璐?const SUPPORT_QUALITIES = ['128k', '320k', 'flac']

// ==================== 宸ュ叿鍑芥暟 ====================

/**
 * 鏂囦欢澶у皬鏍煎紡鍖? * @param {number} size - 瀛楄妭鏁? * @returns {string} 鏍煎紡鍖栧悗鐨勫瓧绗︿覆
 */
function sizeFormate(size) {
  if (!size || isNaN(size)) return ''
  if (size > 104857600) return (size / 104857600).toFixed(1) + 'MB'
  if (size > 1048576) return (size / 1048576).toFixed(1) + 'MB'
  if (size > 1024) return (size / 1024).toFixed(1) + 'KB'
  return size + 'B'
}

/**
 * 鎾斁鏃堕棿鏍煎紡鍖? * @param {number} time - 绉掓暟
 * @returns {string} 鏍煎紡鍖栧悗鐨勫瓧绗︿覆
 */
function formatPlayTime(time) {
  if (!time || isNaN(time)) return '--/--'
  const m = Math.floor(time / 60)
  const s = Math.floor(time % 60)
  return m + ':' + s.toString().padStart(2, '0')
}

/**
 * 鍒涗綔鑰呭悕绉版牸寮忓寲
 * @param {Array} artistList - 鍒涗綔鑰呭垪琛? * @returns {string} 鐢?"銆? 杩炴帴鐨勫垱浣滆€呭悕
 */
function formatArtistName(artistList) {
  if (!artistList || !Array.isArray(artistList)) return ''
  return artistList.map(a => a.name || a).join('銆?)
}

/**
 * HTML 瀹炰綋瑙g爜
 * @param {string} str - 鍚?HTML 瀹炰綋鐨勫瓧绗︿覆
 * @returns {string} 瑙g爜鍚庣殑瀛楃涓? */
function decodeName(str) {
  if (!str) return ''
  return str
    .replace(/'/g, "'")
    .replace(/"/g, '"')
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&amp;/g, '&')
    .replace(/&nbsp;/g, ' ')
}

// ==================== 鏍稿績鍔熻兘 ====================

/**
 * 鎼滅储鍐呭
 * @param {string} str - 鎼滅储鍏抽敭璇? * @param {number} page - 椤电爜锛屼粠 1 寮€濮? * @param {number} limit - 姣忛〉鏁伴噺
 * @returns {Promise<Object>} 鎼滅储缁撴灉
 */
async function musicSearch(str, page = 1, limit = 20) {
  // 鏋勯€犺姹傚弬鏁?  const params = {
    keyword: str,
    page: page,
    limit: limit
  }
  
  // 鍙戦€佽姹?  const url = `${CONFIG.serverUrl}/search`
  const response = await axios.get(url, { 
    params,
    headers: { 'X-API-Key': CONFIG.apiKey },
    timeout: CONFIG.timeout
  })
  
  // 瑙f瀽鏁版嵁
  const data = response.data
  
  // 杞崲涓虹粺涓€鏍煎紡
  const list = data.items.map(item => ({
    id: String(item.id),
    name: decodeName(item.name),
    artists: formatArtistName(item.artists),
    source: PLATFORM,
    pic: item.picUrl || '',
    mPic: item.picUrl || '',
    sPic: item.picUrl || '',
    albumName: decodeName(item.album?.name || ''),
    albumId: String(item.album?.id || ''),
    interval: formatPlayTime(item.duration),
    qualities: {
      '128k': sizeFormate(item.size128),
      '320k': sizeFormate(item.size320),
      'flac': sizeFormate(item.sizeFlac)
    }
  }))
  
  return {
    list,
    total: data.total,
    page: page,
    limit: limit,
    allPage: Math.ceil(data.total / limit),
    source: PLATFORM
  }
}

/**
 * 鑾峰彇鎾斁 URL
 * @param {string} id - 鍐呭 ID
 * @param {string} quality - 闊宠川鏍囪瘑
 * @returns {Promise<string>} 鎾斁 URL
 */
async function getUrl(id, quality) {
  // 妫€鏌ラ煶璐?  if (!SUPPORT_QUALITIES.includes(quality)) {
    quality = SUPPORT_QUALITIES[0]
  }
  
  // 鍙戦€佽姹?  const url = `${CONFIG.serverUrl}/url`
  const response = await axios.get(url, {
    params: { id: id, quality: quality },
    headers: { 'X-API-Key': CONFIG.apiKey },
    timeout: CONFIG.timeout
  })
  
  const data = response.data
  
  if (!data.url || !data.url.startsWith('http')) {
    throw new Error('鑾峰彇閾炬帴澶辫触')
  }
  
  return data.url
}

/**
 * 鑾峰彇姝岃瘝
 * @param {string} id - 鍐呭 ID
 * @returns {Promise<Object>} 姝岃瘝瀵硅薄
 */
async function getLyric(id) {
  const url = `${CONFIG.serverUrl}/lyric`
  const response = await axios.get(url, {
    params: { id: id },
    headers: { 'X-API-Key': CONFIG.apiKey },
    timeout: CONFIG.timeout
  })
  
  const data = response.data
  
  return {
    lyric: data.lyric || '',
    tlyric: data.tlyric || ''
  }
}

/**
 * 鑾峰彇鍒楄〃璇︽儏
 * @param {string} id - 鍒楄〃 ID
 * @param {number} page - 椤电爜
 * @param {number} limit - 姣忛〉鏁伴噺
 * @returns {Promise<Object>} 鍒楄〃璇︽儏
 */
async function songList(id, page = 1, limit = 20) {
  const url = `${CONFIG.serverUrl}/list`
  const response = await axios.get(url, {
    params: { id, page, limit },
    headers: { 'X-API-Key': CONFIG.apiKey },
    timeout: CONFIG.timeout
  })
  
  const data = response.data
  
  // 杞崲鍐呭鍒楄〃
  const list = data.items.map(item => ({
    id: String(item.id),
    name: decodeName(item.name),
    artists: formatArtistName(item.artists),
    source: PLATFORM,
    pic: item.picUrl || '',
    mPic: item.picUrl || '',
    sPic: item.picUrl || '',
    albumName: decodeName(item.album?.name || ''),
    albumId: String(item.album?.id || ''),
    interval: formatPlayTime(item.duration),
    qualities: {}
  }))
  
  return {
    list,
    page,
    limit,
    total: data.total,
    source: PLATFORM,
    info: {
      name: data.name || '',
      img: data.cover || '',
      desc: data.description || '',
      author: data.creator?.name || ''
    }
  }
}

/**
 * 鑾峰彇鍚堥泦璇︽儏
 * @param {string} id - 鍚堥泦 ID
 * @param {number} page - 椤电爜
 * @returns {Promise<Object>} 鍚堥泦璇︽儏
 */
async function album(id, page = 1) {
  const url = `${CONFIG.serverUrl}/album`
  const response = await axios.get(url, {
    params: { id, page },
    headers: { 'X-API-Key': CONFIG.apiKey },
    timeout: CONFIG.timeout
  })
  
  const data = response.data
  
  // 杞崲鍐呭鍒楄〃
  const list = data.items.map(item => ({
    id: String(item.id),
    name: decodeName(item.name),
    artists: formatArtistName(item.artists),
    source: PLATFORM,
    pic: item.picUrl || data.cover || '',
    mPic: item.picUrl || data.cover || '',
    sPic: item.picUrl || data.cover || '',
    albumName: decodeName(data.name || ''),
    albumId: String(id),
    interval: formatPlayTime(item.duration),
    qualities: {}
  }))
  
  return {
    list,
    page,
    limit: 1000,
    total: data.total,
    source: PLATFORM,
    info: {
      name: data.name || '',
      img: data.cover || '',
      desc: data.description || '',
      author: data.artist?.name || ''
    }
  }
}

/**
 * 鑾峰彇鐑悳璇? * @returns {Promise<Object>} 鐑悳鍒楄〃
 */
async function hotSearch() {
  const url = `${CONFIG.serverUrl}/hotsearch`
  const response = await axios.get(url, {
    headers: { 'X-API-Key': CONFIG.apiKey },
    timeout: CONFIG.timeout
  })
  
  return {
    source: PLATFORM,
    list: response.data.list || []
  }
}

// ==================== 鎻掍欢瀵煎嚭 ====================

module.exports = {
  // 鏍稿績鍔熻兘
  musicSearch,
  getUrl,
  getLyric,
  songList,
  album,
  hotSearch,
  
  // 鎻掍欢淇℃伅
  pluginInfo: {
    info: {
      id: PLATFORM,
      name: '骞冲彴A',
      description: '骞冲彴A鎻掍欢',
      version: '3'
    },
    env: [
      { key: 'SERVER_URL', name: '鏈嶅姟绔湴鍧', description: '畾涔夋湇鍔$鍦板潃' },
      { key: 'API_KEY', name: 'API瀵嗛挜', description: '鏈嶅姟绔疉PI瀵嗛挜' }
    ],
    ext: [],
    quality: [
      { name: '鏍囧噯闊宠川', ui: '?, id: '128k' },
      { name: '楂樺搧闊宠川', ui: 'HQ', id: '320k' },
      { name: '鏃犳崯闊宠川', ui: 'SQ', id: 'flac' }
    ],
    supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric']
  }
}

骞冲彴閰嶇疆鍙傝€?

鍚勫钩鍙版爣璇嗗鐓ц〃

骞冲彴 鏍囪瘑 甯歌 ID 瀛楁
骞冲彴A A id
骞冲彴B B id
骞冲彴C C id, hash
骞冲彴D D hash, id
骞冲彴E E id
骞冲彴F F id

闊宠川鏀寔鍙傝€?

// 鍚勫钩鍙板父瑙侀煶璐ㄩ厤缃?const PLATFORM_QUALITIES = {
  A: ['128k', '320k', 'flac', 'flac24bit', 'hires'],
  B: ['128k', '320k', 'flac', 'flac24bit', 'hires'],
  C: ['128k', '320k', 'flac', 'flac24bit'],
  D: ['128k', '320k', 'flac', 'flac24bit', 'hires'],
  E: ['128k', '320k', 'flac', 'flac24bit'],
  F: ['128k', '320k', 'flac']
}

甯歌闂

Q1: 濡備綍浠庡叾浠栫郴缁熻縼绉诲埌鏈郴缁燂紵

A: 鍙傝€冩湰鏂囨。鐨?浠庡叾浠栧钩鍙拌縼绉绘寚鍗?绔犺妭锛屼富瑕佷慨鏀圭偣锛?1. 灏?globalThis.lx.request 鏀逛负 axios 2. 灏嗕簨浠剁洃鍚敼涓哄嚱鏁板鍑?3. 淇敼鏁版嵁杩斿洖鏍煎紡 4. 娣诲姞 module.exports 瀵煎嚭 5. 鐜鍙橀噺浠?global.env 璇诲彇

Q2: 鎻掍欢鍔犺浇澶辫触鎬庝箞鍔烇紵

A: 妫€鏌ヤ互涓嬪嚑鐐癸細

  1. 鏂囦欢璇硶鏄惁姝锛歚node -c your-plugin.js`
  2. pluginInfo 鏄惁瀹屾暣
  3. 瀵煎嚭鐨勫嚱鏁板悕鏄惁姝g‘
  4. 渚濊禆妯″潡鏄惁宸插畨瑁咃紙濡?axios锛?

Q3: 鎼滅储杩斿洖绌虹粨鏋滐紵

A: 妫€鏌ワ細

  1. API 璇锋眰鏄惁鎴愬姛锛堟煡鐪嬫棩蹇楋級
  2. 鍝嶅簲鏁版嵁瑙f瀽鏄惁姝g‘
  3. 鏁版嵁鏍煎紡鏄惁绗﹀悎瑙勮寖
  4. 杩斿洖鐨?source 鏄惁涓庡钩鍙版爣璇嗕竴鑷?

Q4: 鎾斁澶辫触锛?

A: 妫€鏌ワ細

  1. getUrl 杩斿洖鐨?URL 鏄惁鏈夋晥
  2. URL 鏄惁浠?http 寮€澶?3. 闊宠川鏍囪瘑鏄惁姝g‘
  3. 鏄惁鏈夎法鍩熸垨鏉冮檺闂

Q5: 鐢ㄦ埛濡備綍閰嶇疆鎻掍欢锛?

A: 鐢ㄦ埛閫氳繃璁剧疆鐣岄潰閰嶇疆鐜鍙橀噺锛?

SERVER_URL = 鑷畾涔夋湇鍔$鍦板潃
API_KEY = 鐢ㄦ埛鐨凙PI瀵嗛挜

鎻掍欢閫氳繃 global.env 璇诲彇锛?

const env = global.env || {}
const SERVER_URL = env.SERVER_URL || '榛樿鍦板潃'

闄勫綍

鍙傝€冭祫婧?

  • Node.js 瀹樻柟鏂囨。
  • axios 鏂囨。

鐗堟湰鍘嗗彶

  • v1.0.0 (2024-05-28): 鍒濆鐗堟湰

鏂囨。缁撴潫