TSBot 是一个基于 TeamSpeak 的音乐机器人;voice-service 主客户端连接已支持 TS6(历史环境变量名仍保留 TSBOT_TS3_*),提供:
- TeamSpeak 语音播放(通过
voice-service连接 TeamSpeak 服务器并播放音频;主客户端连接支持 TS3/TS6) - 播放队列/控制(暂停/继续/下一首/上一首、音量、随机/循环等)
- 网易云音乐搜索/歌单/喜欢/歌词(通过外部
NeteaseCloudMusicApi服务) - QQ 音乐搜索/歌单/歌词/播放链接(后端内建适配,登录态能力可通过 Web 控制台配置)
- B 站视频搜索与音频播放(支持搜索视频、展示简介/点赞/收藏/投币,并在播放时缓存音频;有字幕的视频可在歌词页显示字幕时间轴,支持通过管理员登录态补抓 AI 字幕)
- Web 控制台(Vue3 前端,用于搜索/队列/最近播放/本地收藏/歌词/设置)
- 外部集成 API(
/external/*提供统一搜索、入队、状态读取、历史读取与历史重播)

这个项目主要是为了解决旧方案带来的“依赖地狱”和不可维护性。
原有常见组合:
TS3AudioBotNeteaseCloudMusicApiTS3AudioBot-NetEaseCloudmusic-plugin
在实践中会遇到:
- 依赖耦合严重:三者版本/接口/运行方式强绑定,部署和排障成本高。
- API 难以更新替换:网易云相关接口经常变化,想替换/升级 API 实现时,改动面会蔓延到 bot 主体或插件。
- 关键插件项目丢失:
TS3AudioBot-NetEaseCloudmusic-plugin在项目完全丢失/不可获取的情况下,整条链路直接断掉,无法继续维护。
TSBot 的目标是把边界重新划清:
- 语音与业务解耦:
voice-service只负责“连接 TeamSpeak + 播放音频”,通过 gRPC 暴露稳定控制接口。 - 网易云作为可替换依赖:后端通过
TSBOT_NETEASE_API_BASE对接外部NeteaseCloudMusicApi,未来即使要替换/升级,也主要收敛在后端适配层。 - 可维护/可演进:前端/后端/语音服务三模块独立迭代,减少“一个组件挂了全挂”的情况。
项目由 3 个组件组成:
- backend/: Python/FastAPI 后端(队列/搜索/网易云与 QQ 音乐接口/控制语音服务)
- voice-service/: Rust 语音服务(连接 TeamSpeak、播放音频,提供 gRPC 给后端调用)
- web/: Vue3 + Vite 前端(Web 控制台/播放器 UI)
更多文档:
HOWTOSTART.md(部署/运行指南)LOGGING.md(统一日志系统)docs/API.md(后端 API 详细文档)web/README.md(前端详细说明)
- Linux(推荐 Ubuntu 20.04+)
- Python: 3.8+
- Node.js: 16+
- Rust: 1.70+(用于
voice-service)
音乐源依赖说明:
- NeteaseCloudMusicApi(仅网易云能力需要;需单独部署 HTTP 服务)
- QQ 音乐(后端内建适配;用户歌单和更稳定的播放链接通常需要管理员 QQ 音乐 Cookie)
- Playwright Chromium(仅 B 站扫码登录和登录态 AI 字幕抓取需要;安装 Python 依赖后执行
python -m playwright install chromium)
[web (Vue3)] <--HTTP--> [backend (FastAPI)] <--gRPC--> [voice-service (Rust)] --> TeamSpeak (TS3/TS6)
|
| HTTP
v
[NeteaseCloudMusicApi]
voice-service的主客户端连接路径已经适配 TeamSpeak 服务器登录、进频道、收发文字消息和音频播放,当前可用于 TS3/TS6 服务器。- 为兼容旧配置,环境变量名仍保持为
TSBOT_TS3_*,但它们同样用于 TS6 的主客户端连接。 - 代码中仍保留一条可选的 legacy
ServerQueryfallback,仅用于旧式client_description更新;它不是 TS6 的 HTTP(S) Query 接口。 - 如果你希望 bot 直接以“模拟客户端”的方式更新自己的简介,可在环境变量中开启
TSBOT_TS3_ALLOW_DIRECT_CLIENTUPDATE_DESCRIPTION=1。
本项目 不直接 调用网易云官方接口;而是通过你自行部署的 NeteaseCloudMusicApi 服务转发/封装。
部署完成后,把服务地址写到环境变量 TSBOT_NETEASE_API_BASE(例如 http://127.0.0.1:3000/)。
常见部署方式(任选其一,具体参数以官方文档为准):
# 方式 A:使用 npx 直接启动
npx NeteaseCloudMusicApi@latest
# 方式 B:使用 Docker(常见镜像:binaryify/neteasecloudmusicapi)
# docker run -d --name ncm-api -p 3000:3000 binaryify/neteasecloudmusicapi建议把该服务部署在 backend 可访问 的位置(同机 127.0.0.1:3000 或内网地址)。
QQ 音乐能力由后端直接提供,不需要额外部署独立的 QQ 音乐 API 服务。
- 已提供搜索、歌曲详情、歌单详情、歌词、专辑/歌手/MV 信息等接口。
- 播放链接、用户歌单等依赖登录态的能力,通常需要管理员 QQ 音乐 Cookie。
- 管理员可以通过 Web 控制台扫码登录,或调用
/admin/qqmusic/*接口写入/确认 Cookie。
B 站能力由后端直接适配,不需要额外部署独立 API 服务。
- 支持搜索 B 站视频,并返回统一后的标题、UP 主、分区、简介、点赞、收藏、投币、封面和原视频链接。
- 支持按
BV/av/ 视频 URL 入队。 - 实际播放时,后端会先把音频下载到本地缓存,再交给
voice-service播放。 - 可通过 Web 控制台或
/admin/bilibili/*接口保存管理员 B 站 Cookie,用于登录态 API 和 Playwright 抓取 AI 字幕。 - 当公开视频接口拿不到字幕轨时,后端会在存在管理员 B 站 Cookie 的前提下,尝试使用登录态接口和 Playwright 页面环境补抓 AI 字幕。
- 可通过
TSBOT_BILIBILI_MAX_DURATION_MINUTES限制允许点播的最长视频时长,避免超长视频拖垮播放链路。
复制模板并修改:
cp tsbot.env.example tsbot.env你至少需要设置:
TSBOT_TS3_HOST/TSBOT_TS3_PORT/TSBOT_TS3_CHANNEL_ID(TeamSpeak 连接信息;变量名沿用历史TSBOT_TS3_*)TSBOT_COOKIE_KEY(用于加密存储管理员 Cookie;务必改成自己的随机字符串)
按音乐源补充设置:
- 使用网易云:设置
TSBOT_NETEASE_API_BASE为你部署的NeteaseCloudMusicApi地址,例如http://127.0.0.1:3000/ - 使用 QQ 音乐登录态能力:通过 Web 控制台或
/admin/qqmusic/*接口写入管理员 QQ 音乐 Cookie - 使用 B 站登录态 AI 字幕抓取:通过 Web 控制台或
/admin/bilibili/*接口写入管理员 B 站 Cookie
可选:
TSBOT_TS3_SERVER_PASSWORD/TSBOT_TS3_CHANNEL_PASSWORD/TSBOT_TS3_CHANNEL_PATHTSBOT_TS3_IDENTITY/TSBOT_TS3_IDENTITY_FILETSBOT_TS3_ALLOW_DIRECT_CLIENTUPDATE_DESCRIPTION:允许 bot 直接通过客户端自身更新client_descriptionTSBOT_TS3_CLIENT_DESCRIPTION_TITLE/TSBOT_TS3_CLIENT_DESCRIPTION_INTRO:配置频道内显示的简介标题和介绍正文(支持\n)TSBOT_TS3_AVATAR_FILE/TSBOT_TS3_AVATAR_DIR:配置 bot 客户端头像TSBOT_ADMIN_TOKEN:开启后端 admin 接口保护(请求头x-admin-token)TSBOT_API_TOKEN/TSBOT_API_TOKENS:为后端非 admin 接口开启共享 token 保护(支持Authorization: Bearer <token>或x-api-token)TSBOT_WEB_HOST/TSBOT_WEB_PORT:前端生产预览服务监听地址/端口(run-web.sh/nohup-start.sh使用)TSBOT_WEB_API_PROXY_TARGET:前端 dev / preview 代理到后端的目标地址(默认根据TSBOT_HOST/TSBOT_PORT推导)TSBOT_WEB_ALLOWED_HOSTS:当你通过域名访问 Vite dev / preview 时允许的 host 白名单(逗号分隔)VITE_DEV_HOST/VITE_DEV_PORT:前端本地 dev server 监听地址/端口VITE_API_BASE:前端请求后端的 Base URL(推荐默认/api,由 dev / preview / Docker 反向代理转发)VITE_WEB_PUBLIC_URL:网页公网 URL(用于页面 canonical / og:url,也会补充到 allowedHosts)VITE_WEB_APP_NAME:网页显示名称(浏览器标题、侧边栏品牌)VITE_WEB_APP_ICON:网页 icon / favicon URLVITE_API_TOKEN:如果你启用了TSBOT_API_TOKEN且仍需要 Web 控制台访问后端,请把同一个 token 传给前端
后端(Python):
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python -m playwright install chromium
cd ..前端(Node):
cd web
npm install
cd ..语音服务(Rust):
# 安装 Rust(如未安装)
# https://rustup.rs/
# 构建 voice-service
make voice-build也可以直接使用仓库里补好的常用构建目标:
make backend-setup
make web-build
make all开 3 个终端分别运行:
./run-voicemake.sh./run-backend.sh./run-web.sh以上脚本会自动读取项目根目录下的 tsbot.env。其中 run-web.sh 会先构建前端产物,再以 preview 方式监听 TSBOT_WEB_PORT(默认 8080)。
chmod +x ./nohup-start.sh ./nohup-stop.sh ./nohup-status.sh
# 启动(会分别启动 voice/backend/web,并写日志到 logs/)
./nohup-start.sh
# 查看状态(端口 + 日志路径)
./nohup-status.sh
# 停止
./nohup-stop.sh开 3 个终端分别运行:
./run-voicemake.shbackend/.venv/bin/uvicorn backend.main:app --reload --reload-exclude "backend/_generated/*" --host 127.0.0.1 --port 8009npm --prefix web run dev本地开发默认访问 http://127.0.0.1:5173,并通过 /api 代理到后端。
cp tsbot.env.example tsbot.env至少确认以下配置:
TSBOT_TS3_HOST/TSBOT_TS3_PORT/TSBOT_TS3_CHANNEL_IDTSBOT_COOKIE_KEYTSBOT_NETEASE_API_BASE(如果你在宿主机跑 NeteaseCloudMusicApi,可设为http://host.docker.internal:3000/)
docker compose up -d --builddocker compose ps
docker compose logs -f backend
docker compose logs -f webdocker compose downCompose 默认会启动 3 个服务:
voice-service(50051)backend(8009)web(8080,Nginx 托管生产前端产物,并将/api/*反向代理到 backend)
如果你不想在本机构建,也可以直接使用仓库 GitHub Actions 发布好的预构建镜像。项目额外提供了 docker-compose.prebuilt.yml,默认拉取 Docker Hub 官方镜像:
# Docker Hub(默认 latest)
docker compose -f docker-compose.prebuilt.yml up -d
# 固定版本,例如 v0.4.0
TSBOT_IMAGE_TAG=v0.4.0 docker compose -f docker-compose.prebuilt.yml up -d
# 切换到 GHCR
TSBOT_IMAGE_REGISTRY=ghcr.io \
TSBOT_IMAGE_NAMESPACE=yichen11818 \
docker compose -f docker-compose.prebuilt.yml up -d镜像命名格式如下(Docker Hub 默认 namespace 为 yumi118;当前 GitHub Packages / GHCR owner 为 yichen11818;fork 可通过环境变量覆盖):
docker.io/<namespace>/neteasetsbot-backend:<tag>docker.io/<namespace>/neteasetsbot-web:<tag>docker.io/<namespace>/neteasetsbot-voice-service:<tag>ghcr.io/<owner>/neteasetsbot-backend:<tag>ghcr.io/<owner>/neteasetsbot-web:<tag>ghcr.io/<owner>/neteasetsbot-voice-service:<tag>
说明:
- GitHub 的 Packages 页面只显示 GHCR 包;如果只推 Docker Hub,这里会是空的。
- 现在会看到 3 个镜像仓库,这是正常现象,因为项目按
backend/web/voice-service三个服务分别构建与发布。 - GitHub 的 Releases 页面会额外附带
tsbot-<version>-linux-amd64.tar.gz和SHA256SUMS.txt,那是软件包,不是容器镜像。
- voice-service gRPC:
127.0.0.1:50051 - backend:
127.0.0.1:8009(TSBOT_PORT) - web(生产脚本 / Docker):
127.0.0.1:8080(TSBOT_WEB_PORT;Docker Compose 也暴露8080) - web(本地 dev server):
127.0.0.1:5173(VITE_DEV_PORT)
后端 OpenAPI 文档:
http://127.0.0.1:8009/docs
如果你希望把 backend 暴露给外部脚本、面板或机器人调用,建议配置:
TSBOT_API_TOKEN="<长随机字符串>":单个共享 token- 或
TSBOT_API_TOKENS="token_a,token_b":多个 token(逗号或空白分隔)
启用后,非 /admin/* 的后端接口 都需要携带 token,支持两种写法:
Authorization: Bearer <token>x-api-token: <token>
如果你同时还要继续使用 Web 控制台,需要在前端启动/构建时再配置:
VITE_API_TOKEN="<与后端相同的 token>"
文档详见: docs/API.md
推荐外部集成优先使用稳定的 /external/* 路由,而不是直接依赖前端内部用的细碎接口。常用能力包括:
/external/status:读取当前播放状态和队列预览/external/search:统一搜索netease/qqmusic/bilibili/external/queue:按 ID 或关键词点歌/external/history:读取最近播放/external/history/{history_id}/replay:按历史记录重新加入队列或立即播放
后端会把“管理员网易云 Cookie”加密存储到数据库(tsbot.db)中,用于:
- 获取更稳定的歌曲 URL(避免部分接口匿名受限)
- 访问歌单/喜欢列表等需要登录态的能力
设置方式(需要 admin token 时请带上请求头 x-admin-token: <TSBOT_ADMIN_TOKEN>):
POST /admin/cookie:写入 cookieGET /admin/status:查看是否已设置GET /admin/account:验证 cookie 是否有效GET /admin/qr/key/GET /admin/qr/create/GET /admin/qr/check:管理员二维码登录
前端也提供了设置入口(详见 web/README.md)。
后端同样会把“管理员 QQ 音乐 Cookie”加密存储到数据库(tsbot.db)中,用于:
- 获取更稳定的 QQ 音乐播放链接
- 访问需要登录态的用户歌单、账号信息等能力
设置方式(需要 admin token 时请带上请求头 x-admin-token: <TSBOT_ADMIN_TOKEN>):
GET /admin/qqmusic/status:查看是否已设置POST /admin/qqmusic/cookie:手动写入 cookiePOST /admin/qqmusic/qr/confirm:确认 Web 扫码登录后写入 cookie
Web 控制台内置了 QQ 音乐扫码登录入口。
日志默认写入 logs/:
logs/backend.loglogs/voice.loglogs/web.log
详见 LOGGING.md(包含 scripts/log-viewer.sh / scripts/unified-logger.sh)。
.
├── backend/ # FastAPI 后端
├── web/ # Vue3 前端
├── voice-service/ # Rust 语音服务(gRPC + TeamSpeak)
├── proto/ # gRPC proto 定义
├── data/ # 运行数据/配置(如 config.json)
├── logs/ # 运行日志(启动脚本会自动创建)
├── HOWTOSTART.md
├── LOGGING.md
└── tsbot.env.example
-
web 端口到底是 5173 还是 8080?
5173是本地开发的 Vite dev server(npm --prefix web run dev/VITE_DEV_PORT)。8080是生产前台启动和 Docker 的默认端口(run-web.sh/nohup-start.sh/TSBOT_WEB_PORT)。
-
前端请求报错 / 连不上后端?
- 推荐默认使用
VITE_API_BASE=/api,由 dev server / preview / Docker Nginx 反向代理到 backend。 - 如果你的前端和后端不走同源代理,可显式设置
VITE_API_BASE,或者把TSBOT_WEB_API_PROXY_TARGET改成对应后端地址。
- 推荐默认使用
-
通过域名访问 Vite dev / preview 报安全错误?
- 这是 Vite 的 host 校验。
- 在
tsbot.env里设置TSBOT_WEB_ALLOWED_HOSTS="dev.example.com,.example.com",按需白名单放行,不要直接全开。
-
后端连不上 voice-service?
- 检查
TSBOT_VOICE_GRPC_ADDR是否为127.0.0.1:50051 - 确保
make voice-run/run-voicemake.sh已启动
- 检查
-
TS6 是不是已经完全支持?
- 当前主客户端连接已支持 TS6,连接参数仍沿用
TSBOT_TS3_*命名。 - 但 legacy
TSBOT_TS3_SERVERQUERY_*仍是旧式 ServerQuery fallback,不是 TS6 的 HTTP(S) Query。
- 当前主客户端连接已支持 TS6,连接参数仍沿用
See LICENSE.