一个开箱即用的「同步听歌」电台系统:Python 服务端 + Android 客户端。
- 服务端:Flask + Socket.IO,支持本地音乐库与网易云歌单双模式、实时聊天/留言、公告栏、毛玻璃轮换背景、天气、管理后台
- 安卓端:WebView UI + 原生 ExoPlayer 后台播放服务,锁屏、后台不中断
- 所有听众实时同步播放同一首歌,支持点歌、切歌、随机/顺序/单曲循环
DuShuRadio/
├── dushu_radio_v4.py # 服务端(单文件)
├── requirements.txt # Python 依赖
├── netease_config.json # 网易云歌单 ID + Cookie(部署后自行填写)
├── radio/ # ★ 音乐文件夹,把你的歌放这里
│ └── README.md
├── DuShuRadioAndroid/ # 安卓客户端源码
└── screenshots/ # 界面截图
需要 Python 3.8+:
pip install -r requirements.txtpython dushu_radio_v4.py启动后:
| 入口 | 地址 | 说明 |
|---|---|---|
| 电台主页 | http://<本机IP>:5000 |
听众页面(手机/电脑浏览器直接打开) |
| 管理后台 | http://<本机IP>:5000/admin |
播放控制、公告、背景图、网易云、留言管理 |
默认切歌密码
123456、管理后台密码dushu-radio-admin,部署后请立即在管理后台修改(脚本顶部配置区也可直接改)。
把音乐文件放进与 dushu_radio_v4.py 同级的 radio/ 文件夹:
DuShuRadio/
└── radio/ ← 音乐放这里
├── 流行/某某歌手 - 歌名.mp3
├── 古典/xxx.flac
└── 电台插曲/yyy.ogg
- 支持
mp3 / wav / flac / aac / ogg / m4a / wma,自动递归子文件夹 - 歌曲名 = 文件名(不含扩展名),建议
歌手 - 歌名命名 - 新增音乐后,进管理后台点「刷新播放列表」即可,无需重启服务器
- 音乐文件不随本仓库分发(版权原因),请自行准备
电台支持「第二模式」:整台电台同步播放一个网易云歌单(VIP 歌也能听完整版)。
第一步:获取歌单 ID
打开网易云网页版 → 进入任意歌单 → 地址栏 https://music.163.com/#/playlist?id=3778678 里的数字就是歌单 ID。
第二步:获取 MUSIC_U Cookie(VIP 完整版必需,免费歌可不填)
- 电脑浏览器(Chrome/Edge)登录 music.163.com;
- 按
F12打开开发者工具 → 切到 Application(应用) 标签 → 左侧 **Cookies → https://music.163.com**; - 找到名为
MUSIC_U的条目,复制它的 Value(整串很长); - 管理后台 →「音乐来源」卡片 → 把 Cookie 粘贴到「网易云登录 Cookie」输入框 → 点「保存 Cookie」,再填入歌单 ID 点「加载歌单」;
- 点「网易云歌单」按钮切换音源,全台同步播放该歌单。
也可以直接把
netease_config.json改成:{"playlist_id": "你的歌单ID", "cookie": "你的MUSIC_U值"}然后重启服务器。
⚠️ netease_config.json已被.gitignore忽略,不会上传到仓库,请放心填写。
电台默认只在局域网内可访问。要让手机流量 / 异地朋友也能听,需要内网穿透把服务器的 5000 端口映射成一个公网地址(免费/付费均可,常见:ngrok、cpolar、natapp、花生壳、Tailscale Funnel 等)。
以 cpolar 为例:
cpolar http 5000成功后会得到类似这样的公网地址:
https://xxxxx.cpolar.top
如果穿透服务商给了
https://xxx.xxx:端口这种带端口的形式,请完整保留(含端口号)。
验证:手机浏览器打开这个公网地址,能正常看到电台主页即成功。
服务端地址是写死在 App 里的,穿透地址变了就要改两处并重新打包。
① DuShuRadioAndroid/app/src/main/assets/radio.html 顶部:
const SERVER_URL = 'https://xxxxx.cpolar.top'; // 改成你的穿透地址② DuShuRadioAndroid/app/src/main/java/com/dushu/radio/RadioService.kt 顶部:
const val SERVER_BASE = "https://xxxxx.cpolar.top" // 改成你的穿透地址两处必须完全一致,末尾不要带
/。
方式 A:Android Studio(推荐)
- 打开 Android Studio → Open → 选择
DuShuRadioAndroid文件夹; - 等待 Gradle 同步完成;
- Build → Build Bundle(s) / APK(s) → Build APK(s);
- 完成后 APK 在
app/build/outputs/apk/debug/app-debug.apk。
方式 B:命令行
cd DuShuRadioAndroid
gradlew.bat assembleDebug # Windows
./gradlew assembleDebug # macOS / Linux- 把
app-debug.apk发到手机安装(需允许「未知来源」); - 打开 App,能听到服务器当前播放的歌曲、看到歌单列表即封装成功;
- 锁屏 / 切后台继续播放 = 原生服务工作正常。
| 场景 | 要改的地方 |
|---|---|
| 穿透地址变了 | radio.html 的 SERVER_URL + RadioService.kt 的 SERVER_BASE(两处)→ 重新构建 APK |
| 只改歌单 / Cookie | 管理后台改,或改 netease_config.json → 重启服务器(App 不用动) |
| 只换音乐 | 往 radio/ 放文件 → 管理后台「刷新播放列表」 |
| 想改 App 名字 | app/src/main/res/values/strings.xml 的 app_name |
服务端主页 / 管理后台截图见 screenshots/ 目录(安卓端截图见仓库 README 顶部展示图)。
- 本项目仅用于个人学习与娱乐,请遵守当地法律法规;
- 网易云音乐内容版权归网易云音乐及版权方所有,请勿将歌曲用于商业用途;
- 音乐文件不包含在本仓库内。
MIT