Skip to content

# kg2lx 手机端无法播放修复方案 #1

@ding2548-ui

Description

@ding2548-ui

问题现象

播放结果 说明
桌面端(Windows/macOS) ✅ 正常 可以搜索、获取链接、播放
手机端(Android/iOS) ❌ 一直缓冲,随后 URL 过期 脚本请求未到达后端

根因

唯一问题:body: JSON.stringify(body)

原版脚本中 body 被手动序列化为字符串,而洛雪 request API 期望 body 为对象,框架内部会自动序列化。手动 JSON.stringify() 会导致:

  1. body 从对象变成字符串
  2. 框架看到 body 不是对象,跳过自动序列化逻辑
  3. 实际发出的 HTTP 请求体变成双重转义的字符串
  4. 后端收到后无法正确解析,返回空数据或错误

为什么桌面端能用但手机端不行:

  • 桌面端 Node.js 环境对这种异常处理更宽松,可能自动修正
  • 手机端轻量级 JS 引擎直接失败,请求没有正确发出去

修复方案

只需修改 server/src/services/script.rs,其他文件均不需要修改

核心修改:1 处

- body: JSON.stringify(body),
+ body: body,

即将 body: JSON.stringify(body) 改为直接传对象。

额外改进:1 处(非必须)

timeout: 20000 防止手机端网络不稳定时请求卡死。

完整修复后脚本模板

/**
 * @name {source_name}
 * @description kg2lx 专属酷狗概念版音源脚本,仅供通过 kg2lx 解析歌曲链接
 * @version 0.2.0
 */
const { EVENT_NAMES, request, on, send } = globalThis.lx
const API = '{public_base_url}/api/v1/runtime/music-url'
const TOKEN = '{runtime_token}'
const qualityMap = { '128k': '128k', '320k': '320k', flac: 'flac', flac24bit: 'flac24bit' }
const httpPost = (url, body) => new Promise((resolve, reject) => {
  request(url, {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      authorization: `Bearer ${TOKEN}`,
    },
    body,
    timeout: 20000,
  }, (err, resp) => {
    if (err) return reject(err)
    try {
      const data = typeof resp.body === 'string' ? JSON.parse(resp.body) : (resp.body || {})
      if (resp.statusCode && resp.statusCode >= 400) return reject(new Error(data.message || `request failed: ${resp.statusCode}`))
      if (!data.url) return reject(new Error('empty url'))
      resolve(data.url)
    } catch (e) {
      reject(e)
    }
  })
})
on(EVENT_NAMES.request, ({ source, action, info }) => {
  if (source !== 'kg' || action !== 'musicUrl') return Promise.reject(new Error('unsupported action'))
  const musicInfo = info.musicInfo || {}
  const quality = qualityMap[info.type]
  if (!quality) return Promise.reject(new Error(`unsupported quality: ${info.type}`))
  return httpPost(API, {
    hash: musicInfo.hash,
    album_audio_id: musicInfo.album_audio_id || musicInfo.albumAudioId || null,
    quality,
  })
})
send(EVENT_NAMES.inited, {
  openDevTools: false,
  sources: {
    kg: {
      name: '{source_name}',
      type: 'music',
      actions: ['musicUrl'],
      qualitys: ['128k', '320k', 'flac', 'flac24bit'],
    },
  },
})

与原版的 diff

 const httpPost = (url, body) => new Promise((resolve, reject) => {
   request(url, {
     method: 'POST',
     headers: {
       'content-type': 'application/json',
       authorization: `Bearer ${TOKEN}`,
     },
-    body: JSON.stringify(body),
+    body,
+    timeout: 20000,
   }, (err, resp) => {

改动仅 2 行:JSON.stringify(body)body,加 timeout

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions