面向 Android TV 机顶盒的 KTV 点歌系统:把电视变成一台可以扫码点歌、投屏加歌、异地远程控制的点唱机。电视界面、WebUI 与解析器以 TypeScript 为主,Android 系统边界(热点、DLNA、Media3 播放、前台服务与内嵌 HTTP 服务)使用少量 Kotlin。
- 扫码点歌:电视右上角常显二维码,手机扫码进入控制页即可搜索或粘贴链接点歌,无需安装 App。
- 多来源解析:支持 YouTube、Bilibili、网易云音乐链接,也支持直链与 DLNA 投屏(投屏只加入待播列表,不抢占控制权)。
- KTV 字幕:视频与网易云歌词均可逐字描色;日文可开启平假名或罗马音注音(二者互斥);多语言字幕可在控制页切换或关闭。
- 队列自动播放:区分已播/未播,播完自动接续下一首;全部播完后新添加的曲目自动开播。
- 异地远程控制:通过 Cloudflare 中继,用 8 位 PIN 在远端网页管理队列、控制播放与字幕(不支持跨网 DLNA)。
- 本地热点桥接:电视可开启热点并把局域网控制地址桥接给同一 Wi-Fi 下的手机;界面常显 SSID 与密码。
- 自动更新:启动后自动检查 GitHub Release,电视端一键下载安装(下载默认走 GitHub 反代镜像加速)。
从 GitHub Releases 下载对应机顶盒架构的 APK:
| 文件 | 适用设备 |
|---|---|
singbox-ktv-vX.Y.Z-arm64-v8a.apk |
绝大多数新机顶盒(推荐) |
singbox-ktv-vX.Y.Z-armeabi-v7a.apk |
较老的 32 位机顶盒 |
singbox-ktv-vX.Y.Z-x86_64.apk |
模拟器 / x86 盒子 |
singbox-ktv-vX.Y.Z-debug.apk |
通用包(体积最大) |
安装方式任选其一:拷贝 APK 到 U 盘用文件管理器安装、通过 ADB 安装,或先安装任意旧版后在电视端一键更新。首次安装需在系统设置中允许“安装未知来源应用”。
注意:GitHub Actions 的 Artifacts 下载是 zip 包裹,不是安装包;请从 Release 页面下载原始 APK。
- 打开 App(已支持开机自启并回到前台)。
- 手机连上机顶盒所在的同一 Wi-Fi,扫描电视右上角的二维码进入控制页;若电视开启了热点,则手机连接热点后扫码。
- 在控制页搜索网易云、粘贴 YouTube / Bilibili 链接,或用支持 DLNA 的音乐/视频 App 投屏,歌曲会进入待播列表。
- 电视端支持方向键遥控:按方向键唤出控制栏,按确认键播放/暂停;更新横幅出现时焦点会默认落在更新按钮。
电视联网并保持 App 在前台时,二维码会自动切换为外网控制地址。手机访问 https://ktv.111917.xyz,输入电视界面显示的 8 位 PIN 即可远程管理队列与播放。
- 支持 Bilibili / YouTube 的多语言字幕轨与网易云歌词(LRC/YRC 优先)。
- 双行固定行位显示:正在演唱与下一条各占一行,过期字幕在原位淡出、新字幕淡入,不上下滚动。
- 逐字描色在快节奏段落会平滑追赶真实进度,避免前几字瞬间跳色。
- 日语歌词可在控制页开启平假名注音或罗马音(互斥),也可关闭。
- 控制页提供调试入口,可一键添加测试曲目、导出字幕诊断报告。
需要 Node.js 22+。二维码优先调用系统中的 Python qrcode 包(Android APK 使用 ZXing,不依赖 Python)。
npm install
npm test
HOST=0.0.0.0 PORT=8090 npm start- 电视预览:
http://机子IP:8090/tv - 手机控制:
http://机子IP:8090/control
也可直接运行仓库已包含的构建产物:
node apps/mock-tv-server/dist/server.js需要 JDK 17/21、Android SDK 36,建议 arm64-v8a 真机:
npm install
npm run build # 构建 WebUI 并同步到 APK assets
cd android-shell
./gradlew :app:assembleDebugAPK 输出到 android-shell/app/build/outputs/apk/debug/,包含按 ABI 拆分的多个 APK 与通用包。
- APK 默认使用内置 Bilibili / YouTube(NewPipeExtractor)/ 网易云解析器;Bilibili 字幕与高清晰度需要有效 Cookie,可在控制页“主机设置”中注入(Cookie 只保存在电视应用私有设置中)。
- 网易云 Host 侧依赖自部署的兼容 API,配置
NETEASE_API_BASE;也支持ENABLE_YTDLP=1使用 yt-dlp 作为回退。 - 解析器只获取媒体元数据与可播放地址,不绕过 DRM。请自行确认内容授权与平台条款。
电视端启动后约 8 秒自动检查 GitHub Releases,发现新版本后在界面显示更新横幅,确认后按设备架构优先下载同架构 APK,并调用系统安装器完成安装。
下载源默认优先使用 GitHub 反代镜像(ghfast.top、gh-proxy.com、ghproxy.net)以加速,直连 GitHub 作为兜底。
apps/
tv/ React Native TV / TypeScript 电视界面
web-lite/ APK 内嵌的轻量 WebUI
mock-tv-server/ Node.js Host、解析器和协议回测器
resolver-worker/ Cloudflare Worker 远程控制中继与远程 WebUI
android-shell/ Kotlin Android TV 壳与原生运行时
packages/
shared/ 共享 TypeScript 类型
core/ 队列、DLNA、链接分类、字幕转换
test/ Node 端到端测试和 Android 静态契约测试
docs/ 架构、调研和真机验收说明
- 不是 Expo:热点、组播、前台服务、Media3、开机/后台运行和未来的本地模型推理都需要原生 Android 能力。
- 解析器与播放器解耦:各来源最终输出统一
QueueItem,播放器不感知来源 API。 - DLNA 只入队不控制:投屏客户端看到的状态恒为 STOPPED,避免误以为拥有播放/进度控制权。
- 热点兼容性:部分 Android TV 固件会关闭 LocalOnlyHotspot 或组播,失败会显示在状态中,可回退路由器局域网模式。
详见 架构说明、技术调研 和 Android 真机验收。