☰
官方客户端太难用广告还多?一气之下我用 AI 做了个网易云音乐桌面客户端(TaoToken 版)
2026/10/2 6:16:27 网站建设 项目流程

1. 官方客户端劝退之后,我决定自己动手做一个

网易云音乐官方桌面端这些年越来越臃肿,启动慢、弹窗多、后台常驻进程一堆,我身边不少做编曲和混音的朋友早就把它从主力机里卸了。但问题是,很多独立音乐人的作品首发就在网易云,想听自己的歌、看评论、管理歌单,还是绕不开它。于是我就想,能不能用 AI 编程工具从零撸一个轻量桌面客户端,只保留搜索、播放、歌单、评论这几个核心功能,界面干净、快捷键顺手、启动秒开。

这个想法听起来挺大,但真正动手之后我发现,借助 Claude Code CLI 这类 AI 编程工具,一个不熟悉 Electron 和前端框架的人也能把项目跑起来。我自己的主力语言是 Python 和一点 Go,对 TypeScript 和 Vue 只能算看得懂,但整个项目从初始化到能播放第一首歌,大概只花了两个周末。核心思路很简单:把需求拆成小步骤,每一步都让 AI 生成可运行的代码,然后本地验证、报错、再修。

这篇文章我会把完整流程拆开讲:项目怎么初始化、API 怎么对接、界面怎么生成、TaoToken 怎么作为统一 Key 通道接进 Claude Code CLI,以及本地启动和验证的具体命令。你不需要是前端高手,只要会装 Node、会复制命令、能看懂报错信息,就能跟着做出来。适合谁?适合那些被官方客户端折磨、又想练手 AI 编程的开发者,或者想给自己做一个专属音乐播放器的折腾党。

先说清楚一件事:这个项目是本地运行的个人工具,不涉及任何破解或绕过官方限制,所有数据都来自公开的 API 接口,登录也是走官方扫码流程。我们只是换了一个更顺手的壳。

2. TaoToken 前置准备:统一 Key 通道接入 Claude Code CLI

在开始写代码之前,得先把 AI 编程工具接好。我用的是 Claude Code CLI,它本身需要配置 API Key 才能调用模型。如果你同时用 Codex CLI、Cline 或者别的工具,每个都去单独配 Key 会很乱。TaoToken 在这里的作用就是提供一个统一的 Key 通道,一个 Key 可以给多个 AI 编程工具用,Base URL 和 Model ID 都统一管理。

先注册并拿到 Key。打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,注册后在控制台里创建一个 API Key。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,Key 列表在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。创建的时候给它起个名字,比如music-client-dev,方便后面区分。

拿到 Key 之后,Claude Code CLI 的配置方式有两种:一种是环境变量,一种是写配置文件。我推荐用配置文件,因为项目多了之后环境变量容易乱。Claude Code CLI 的配置文件默认在~/.claude/settings.json,如果没有就手动创建。内容大概长这样:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的TaoTokenKey", "ANTHROPIC_MODEL": "claude-sonnet-4-20250514" } }

注意 Base URL 这里写的是https://taotoken.net/api,不要加 UTM 参数,API 地址就是纯接口地址。Model ID 根据你实际用的模型填,TaoToken 的文档页 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里有当前支持的模型列表,选一个适合编码的就行。

如果你用的是 Codex CLI,配置方式类似,但文件是~/.codex/auth.json。这个文件里需要写全三件套:Base URL、Key、Model ID。格式如下:

{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的TaoTokenKey", "model": "claude-sonnet-4-20250514" }

Cline 或者 CC Switch 这类工具,也是在设置里填 Base URL、API Key、Model ID 这三项。Base URL 统一用https://taotoken.net/api,Key 用刚才创建的那个,Model ID 按需选。这样不管你换哪个 AI 编程工具,都不用重新申请 Key,改一下配置文件就行。

配置完之后,在终端里跑一下claude命令,看看能不能正常进入交互界面。如果提示认证失败,先检查 Key 有没有复制错、Base URL 有没有多空格。确认没问题后,我们就可以开始建项目了。

3. 项目初始化与可复制配置:从零搭起 Electron + Vue 骨架

项目初始化这一步,我让 Claude Code CLI 直接生成整个目录结构和配置文件。你可以在终端里新建一个文件夹,比如netease-desktop,然后进入这个目录,运行claude进入交互模式,把下面的需求描述贴进去:

帮我初始化一个 Electron + Vue 3 + Vite 的桌面项目,要求支持 TypeScript,主进程和渲染进程分开,渲染进程用 Vue 3 组合式 API,样式用 Tailwind CSS,打包用 electron-builder。项目名 netease-desktop,入口文件 main.ts,预加载脚本 preload.ts。

Claude Code CLI 会生成一整套文件,包括package.json、vite.config.ts、electron-builder.yml、src/main/main.ts、src/renderer/App.vue等等。生成完之后,你需要手动检查几个关键配置,确保和 TaoToken 的接入不冲突。

首先是package.json,里面要有这些依赖和脚本:

{ "name": "netease-desktop", "version": "0.1.0", "main": "dist/main/main.js", "scripts": { "dev": "vite", "build": "vue-tsc --noEmit && vite build && electron-builder", "start": "electron ." }, "devDependencies": { "electron": "^30.0.0", "electron-builder": "^24.0.0", "vite": "^5.0.0", "vue": "^3.4.0", "typescript": "^5.4.0", "tailwindcss": "^3.4.0" } }

然后是vite.config.ts,要配置好 Electron 的入口和渲染进程的根目录:

import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' export default defineConfig({ plugins: [vue()], root: path.join(__dirname, 'src/renderer'), base: './', build: { outDir: path.join(__dirname, 'dist/renderer'), emptyOutDir: true }, server: { port: 5173 } })

主进程src/main/main.ts里要创建窗口、加载渲染进程、处理快捷键。这里我让 AI 生成了一个基础版本,后面再逐步加功能:

import { app, BrowserWindow, globalShortcut } from 'electron' import path from 'path' let mainWindow: BrowserWindow | null = null function createWindow() { mainWindow = new BrowserWindow({ width: 1200, height: 800, webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, nodeIntegration: false } }) if (process.env.NODE_ENV === 'development') { mainWindow.loadURL('http://localhost:5173') } else { mainWindow.loadFile(path.join(__dirname, '../renderer/index.html')) } mainWindow.on('closed', () => { mainWindow = null }) } app.whenReady().then(() => { createWindow() globalShortcut.register('F5', () => { mainWindow?.reload() }) }) app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit() })

这些配置生成完之后,运行npm install安装依赖。如果网络慢,可以换淘宝镜像。安装完成后跑npm run dev,应该能看到一个空白窗口弹出来。这一步成功,说明骨架搭好了。

接下来是 API 对接。网易云音乐的公开接口有不少,我们主要用搜索、歌曲详情、播放地址、歌词、评论这几个。我让 Claude Code CLI 生成了一个src/renderer/api/netease.ts文件,封装了请求逻辑:

const BASE_URL = 'https://music.163.com/api' export async function searchSongs(keyword: string, limit = 30) { const res = await fetch(`${BASE_URL}/search/get`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ s: keyword, type: '1', limit: String(limit), offset: '0' }) }) return res.json() } export async function getSongUrl(id: number) { const res = await fetch(`${BASE_URL}/song/enhance/player/url?ids=[${id}]&br=320000`) return res.json() }

注意这些接口是公开的,不需要登录也能用一部分。如果要访问用户歌单和评论,需要走扫码登录,拿到 cookie 之后带上。登录部分我后面单独讲。

界面生成这块,我让 AI 直接生成了一个三栏布局:左侧是歌单和导航,中间是歌曲列表,底部是播放控制栏。用 Vue 组件拆成Sidebar.vue、SongList.vue、PlayerBar.vue。样式用 Tailwind 写,整体走暗色主题,减少视觉干扰。

<template> <div class="flex h-screen bg-gray-900 text-gray-100"> <Sidebar class="w-64 border-r border-gray-800" /> <div class="flex-1 flex flex-col"> <SongList class="flex-1 overflow-y-auto" /> <PlayerBar class="h-20 border-t border-gray-800" /> </div> </div> </template>

到这里,项目的基本结构和界面就出来了。你可以跑npm run dev看看效果,应该能看到一个暗色的音乐播放器界面,虽然还不能播放,但布局已经在了。

4. 验证请求与成功结果:本地跑通搜索、播放和快捷键

配置写完,最关键的一步是验证。先跑npm run dev,然后在搜索框里输入一首歌名,比如「晴天」,看看能不能返回结果。如果控制台报 CORS 错误,说明渲染进程直接请求网易云接口被浏览器拦截了。解决办法是在主进程里做代理,或者用 Electron 的session.defaultSession.webRequest修改请求头。

我让 Claude Code CLI 在主进程里加了一个简单的代理转发:

import { ipcMain } from 'electron' import fetch from 'node-fetch' ipcMain.handle('api-request', async (_event, url: string, options: any) => { const res = await fetch(url, { ...options, headers: { ...options.headers, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } }) return res.json() })

然后在渲染进程里通过window.electronAPI.apiRequest调用。这样请求就从主进程发出,不受 CORS 限制。

播放功能需要拿到歌曲的真实 URL。调用getSongUrl之后,返回的 JSON 里会有data[0].url,把这个 URL 赋给<audio>标签的src就能播放。我实测下来,大部分歌曲都能拿到 320kbps 的地址,少数版权受限的会返回 null,这时候界面上要给出提示。

const audio = new Audio() audio.src = songUrl audio.play()

快捷键这块,我在主进程里注册了全局快捷键,比如空格播放暂停、F3/F4 切歌、F1/F2 调音量。注意全局快捷键会和其他应用冲突,所以只在窗口聚焦时生效比较好。可以用mainWindow.on('focus')和blur来动态注册和注销。

mainWindow.on('focus', () => { globalShortcut.register('Space', () => { mainWindow?.webContents.send('toggle-play') }) }) mainWindow.on('blur', () => { globalShortcut.unregisterAll() })

验证成功的标志是:搜索能出结果、点击歌曲能播放、快捷键能控制播放状态、歌词能滚动显示。我跑通这些之后,又让 AI 加了评论树和歌单管理,整个项目就完整了。

如果你在验证过程中遇到401 Unauthorized,说明某些接口需要登录 cookie。扫码登录的实现是在主进程里打开一个隐藏窗口,加载网易云登录页,监听 cookie 变化,拿到MUSIC_U之后存到本地。下次启动时带上这个 cookie 请求即可。

5. 本篇常见错排查:401、local proxy failed、reading choices 怎么修

做这个项目的过程中,我踩了不少坑,这里把最常见的几个报错和解决办法列出来,你遇到的时候可以直接对照。

第一个是401 Unauthorized。这个通常出现在调用用户歌单或评论接口时,原因是请求里没有带登录 cookie。解决办法是先走扫码登录,拿到MUSIC_U这个 cookie,然后在请求头里加上Cookie: MUSIC_U=xxx。如果你用的是 TaoToken 的 Key 通道,注意区分:TaoToken 的 Key 是给 AI 编程工具用的,不是给网易云接口用的,两者不要混。

第二个是local proxy failed。这个报错一般出现在 Claude Code CLI 连接 TaoToken 的时候,说明 Base URL 配置错了。检查~/.claude/settings.json里的ANTHROPIC_BASE_URL是不是https://taotoken.net/api,不要写成https://taotoken.net/api/带斜杠,也不要在后面加 UTM 参数。如果还是不行,用curl https://taotoken.net/api测试一下网络通不通。

第三个是reading choices报错。这个通常出现在解析 API 返回的 JSON 时,代码期望choices字段但实际返回的是data或result。解决办法是打印完整的返回体,看看实际结构是什么。网易云的接口返回格式不统一,有的用result.songs,有的用data,需要针对每个接口单独处理。

第四个是 OAuth 相关报错。如果你用 Codex CLI 的auth.json配置,报 OAuth 失败,检查文件里是不是写全了三件套:base_url、api_key、model。缺任何一个都会导致认证流程走不通。另外注意auth.json的权限,在 Linux/macOS 下要设成600,否则可能被拒绝读取。

第五个是 Electron 打包后白屏。这个一般是vite.config.ts里的base没设成./,导致打包后的资源路径不对。改成base: './'重新打包即可。

第六个是快捷键不生效。检查是不是被其他应用占用了,比如 F5 在浏览器里是刷新,在 Electron 里如果没聚焦也可能不触发。用globalShortcut.isRegistered判断一下,注册失败就换一个组合键。

这些坑我都实际遇到过,大部分是配置问题,少数是接口返回格式变化。遇到报错不要慌,先看控制台完整日志,再让 Claude Code CLI 帮你分析,通常几分钟就能定位。

6. 后续扩展与接入文档:把项目跑起来之后还能做什么

项目跑通之后,你可以继续加功能。比如歌词滚动,用<audio>的timeupdate事件拿到当前播放时间,然后匹配歌词数组里的时间戳,高亮对应行。评论树可以用递归组件渲染,支持展开折叠。歌单管理可以加拖拽排序,用vuedraggable库。

如果你想让 AI 编程工具持续帮你迭代,建议把 TaoToken 的 Coding Plan 用起来,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。它适合长期编码和 Agent 场景,一个 Key 可以覆盖多个工具,不用每次换工具都重新配。

接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有各个工具的详细配置步骤。如果你只是想先试试模型对话,可以打开 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=chat&utm_campaign=rewrite 直接体验。

API Key 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ,建议给每个项目单独建一个 Key,方便追踪用量。控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 里能看到调用记录和余额。

最后说一个实用技巧:把项目的README.md写好,记录启动命令、配置路径、常见报错。下次换电脑或者重装系统,照着 README 十分钟就能恢复环境。我自己的 README 里就写了三行核心命令:npm install、npm run dev、npm run build,加上 TaoToken 的配置片段,足够用了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询