【全 AI 开发】给飞牛 NAS 搭了个家庭 KTV,手机扫码就能点歌
最近用 AI 从头到尾做了一个家庭 KTV 项目,叫 Home KTV,想着家里有 NAS 和电视的朋友可能会用得上,拿出来分享一下。
简单说就是:服务端跑在飞牛 NAS 上,电视负责播放,手机或微信扫一下电视上的二维码就能点歌。家里人各点各的,歌曲排队播放,手机还能当遥控器,不用每个人都装一个 App。
先把话说在前面:这是全 AI 开发
这个项目从需求、架构、写代码、测试到整理文档,基本都是 AI 完成的。
现在能干什么
- 电视装 APK,手机或微信扫码点歌
- 按歌名、歌手搜索,也支持中文、全拼和拼音首字母
- 多个人一起点歌,可以排队、顶歌、删自己的歌,还能打散队列
- 手机控制播放、暂停、重唱、切歌、音量,以及原唱/伴奏切换
- 收藏、最近唱过、热门榜单、歌单和一键再唱
- 电视显示双行歌词,支持普通 LRC 和逐字歌词
- 播放时可以放鼓掌、欢呼、倒彩、干杯这些现场音效
- 扫描曲库、识别媒体格式、MD5 去重、直拷和批量转码
- 在管理后台改歌名、歌手、语种、歌词、音轨和封面
- 查看曲库、转码进度、播放状态,还能做数据库备份和恢复
项目地址和 TV 端 APK
电视端支持 Android 10 及以上。去 Releases 下载适合自己电视或盒子 CPU 架构的 APK,装好后连接 NAS 服务端就可以了。
在飞牛 NAS 上怎么跑
启动完成后,在手机或电脑浏览器里访问下面的地址。把 192.168.1.10 换成你自己飞牛 NAS 的局域网 IP:
- 手机点歌页:
http://192.168.1.10:8080/m
- 管理后台:
http://192.168.1.10:8080/m/admin
- 检查服务是否正常:
http://192.168.1.10:8080/api/health
电视端安装 APK 后,也可以在首次设置页面自动扫描服务;如果扫描不到,就手动填写 192.168.1.10:8080 这种地址。手机点歌页打开后,电视待机页会显示二维码,之后直接微信扫码就能点歌。
下面这几处配置建议重点看一下:
devices: /dev/dri:/dev/dri:把飞牛主机的显卡设备映射进容器,主要给 Intel 核显 VAAPI 硬件转码使用。有这个设备并且驱动正常时,可以减少转码时的 CPU 占用。如果你的飞牛设备没有 /dev/dri,可以删除或注释掉整个 devices 配置,使用 CPU 转码;不要只改成其他路径。目前只测试了n100的cpu
source-music:原始歌曲目录。把自己准备好的 MP4、MKV、MP3 等文件放在这里,系统会从这里扫描、分析、去重,再导入或转码。这个目录和下面的 music 不要设成同一个目录!!!
music:正式曲库目录。这里放的是已经可以被手机点歌和 TV 播放的文件(不要自己放东西到这里,在系统页面上操作),系统会把直拷或转码后的结果写到这里。两个目录都要保证容器有读写权限。
source 和 target:source 是飞牛主机上的实际目录,路径相对于 docker-compose.nas.yml 所在目录;target 是容器内部看到的目录,通常保持不动。想把曲库放到其他硬盘时,改 source 即可。
create_host_path: true:如果 source 指向的目录还不存在,Docker Compose 会尝试自动创建它;但目录创建后仍要确认飞牛和容器有读写权限。
docker-compose配置
name: home-ktv
x-db-name: &db-name ktv
x-db-user: &db-user ktv
x-db-password: &db-password change-me-before-deploy
x-timezone: &timezone Asia/Shanghai
services:
db:
image: docker.m.daocloud.io/library/postgres:16-alpine
container_name: ktv-db
environment:
POSTGRES_DB: *db-name
POSTGRES_USER: *db-user
POSTGRES_PASSWORD: *db-password
TZ: *timezone
volumes:
- type: bind
source: ./postgres
target: /var/lib/postgresql/data
bind:
create_host_path: true
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ktv -d ktv"]
interval: 5s
timeout: 5s
retries: 20
start_period: 10s
restart: unless-stopped
stop_grace_period: 1m
ktv:
image: ghcr.io/zhayinggang/ktv-home:latest
container_name: ktv-app
devices:
- /dev/dri:/dev/dri
environment:
SERVER_PORT: 8080
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/ktv
SPRING_DATASOURCE_USERNAME: *db-user
SPRING_DATASOURCE_PASSWORD: *db-password
KTV_SOURCE_LIBRARY_PATH: /source-music
KTV_LIBRARY_PATH: /music
KTV_DATA_PATH: /data
KTV_DISCOVERY_ENABLED: "true"
KTV_DISCOVERY_UDP_PORT: 18888
KTV_DISCOVERY_NAME: 家庭KTV
KTV_AI_ENABLED: "false"
KTV_AI_BASE_URL: https://api.deepseek.com
KTV_AI_API_KEY: ""
KTV_AI_MODEL: deepseek-v4-flash
KTV_AI_AUTO_APPLY_CONFIDENCE: "0.90"
JAVA_TOOL_OPTIONS: -XX:MaxRAMPercentage=70 -Xmx512m
TZ: *timezone
ports:
- "8080:8080/tcp"
- "18888:18888/udp"
volumes:
- type: bind
source: ./source-music
target: /source-music
bind:
create_host_path: true
- type: bind
source: ./music
target: /music
bind:
create_host_path: true
- type: bind
source: ./data
target: /data
bind:
create_host_path: true
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8080/api/health | grep -q '\"status\":\"UP\"'"]
interval: 10s
timeout: 5s
retries: 20
start_period: 30s
restart: unless-stopped
stop_grace_period: 30s
把自己的歌曲放进配置好的源目录,打开管理后台点“扫描”。系统会自动分析格式、识别歌曲信息、去重,能直接播放的就放进正式曲库,其他文件可以在后台排队转码。
端口这里一定要注意
这个地方真的建议大家不要手痒去改。默认端口是:
- TCP
8080:手机点歌、管理后台、接口、实时控制和媒体播放
- UDP
18888:TV 端局域网自动发现服务
服务端端口不要随意更换。 TV 端的自动扫描依赖默认端口配置,尤其是 HTTP 服务端口改了以后,TV 端可能根本扫描不到 NAS;UDP 18888 改掉,也会影响自动发现。
如果一定要改,Docker Compose、服务端、TV 端连接配置和 NAS 防火墙要一起改,不能只改其中一处。否则就只能在电视上手动填地址,严重时还会连不上。正常使用时,NAS 防火墙记得放行 TCP 8080 和 UDP 18888。
几个提前说好的小限制
- 目前更适合在家里的可信局域网使用,不建议把服务直接暴露到公网。
- 手机、电视和 NAS 要在同一个能互相访问的局域网里,路由器开了 AP 隔离或访客网络隔离时,可能会连不上。
- 项目不提供歌曲、MV 或伴奏资源,曲库需要大家自己准备,并确认有使用权限。
- Intel 核显硬件转码有实际验证,其他平台要看具体设备、驱动和 FFmpeg 支持情况。
- 建议用 USB 或有线麦克风。
- 不同 KTV 视频的原唱和伴奏音轨顺序可能不一样,第一次导入后最好抽查一下。