电台收听接入指导(radio_relay)¶
本文面向接入电台播放的开发者(网页 / App / 播放器 / 未来固件)。radio_relay 是纯实时流式转播:服务端把国内电台的公开 MP3 网络流原样转发,播放器直接拉流播放,服务端不解码、零转码。
两句话版本:取数拿 payload.stream_url → 播放器直接播放该 URL,即延迟几十秒的直播。上游真实地址全程不暴露——所有响应里只有本平台的 stream_url 与脱敏电台目录(code/name/tags)。
1. 功能与前提¶
| 项 | 说明 |
|---|---|
| 内容 | 国内电台公开 MP3 网络流(央广中国之声、广东音乐之声、羊城交通电台、江苏经典流行音乐、安徽小说评书广播等) |
| 交付 | HTTP/1.1 chunked 长连接(audio/mpeg),即时起播,网页 <audio>/手机/PC/VLC 直接可用 |
| 按需开播 | 服务端在首个听众到达时才连上游;无人收听 30 分钟后自动回收连接 |
| 通用前提 | 订阅 radio_relay(未订阅取数报 40302);stream_require_auth=false(默认)时播放 URL 匿名可听 |
设备(盒子)提示:现役固件 HTTP 栈不支持 chunked 长连接,暂不能直接消费本源;待固件验证 chunked 后无需服务端改动即可接入(见 §5)。
2. 选择电台¶
取数返回目录(推荐):GET /api/v1/data/radio_relay?station=cnr1 的 payload.stations 即脱敏目录:
{ "stations": [ { "code": "cnr1", "name": "中国之声", "tags": "news" },
{ "code": "gd_music", "name": "广东音乐之声", "tags": "music" }, ... ] }
用 code 作播放参数,name 作界面展示(≤10 字符 × 10 台)。目录=内置实测清单 + radio-browser.info 每日刷新 + 管理员密钥覆盖(均只存服务端)。
3. 播放流程¶
① 取数 GET /api/v1/data/radio_relay?station=<code>
→ payload.stream_url(如 /api/v1/stream/radio_relay?station=cnr1)
→ payload.stations 做换台菜单;live/listeners 做状态展示(缓存 ≤30s,参考值)
② 播放 <同主机><stream_url> ← 播放器直接打开,即点即播
③ 换台 = 用新 station 重新取数 + 播放新 stream_url(各台独立,无需等待)
payload 关键字段:
| 字段 | 用途 |
|---|---|
stream_url |
播放源(本平台地址,上游已隐藏) |
stations |
脱敏电台目录(code/name/tags) |
live / listeners |
该台是否在播 / 听众数(缓存 ≤30s 的参考值) |
bitrate_kbps / sample_rate |
探测到的码率/采样率(0 = 未在播) |
source_name |
合规标注(转播来源 + 仅供个人收听) |
4. 状态与异常处理¶
| 情况 | 表现 | 客户端动作 |
|---|---|---|
| 正常 | 持续出流 | 照常播放 |
| 上游短暂断流 | 服务端退避重连(1s→30s),听众短暂缓冲后继续 | 播放器自然缓冲,无需处理 |
| 上游长时间静默(>90s) | 服务端结束听众流 | 播放器收到流结束:提示"信号中断",自动重连 stream_url 即恢复 |
| 上游非 MP3(错误页等) | 服务端拦截,一个字节都不会透传 | 同"长时间静默"处理 |
| 未订阅 | 取数 40302 | 引导用户订阅"国内电台转播" |
| 听众满 | 播放 URL 返回 42901 | 按 retry_after 提示稍后重试(默认 10/源、30 总) |
| 冷启动 | 头几秒无声音 | 正常直播缓冲,无需处理 |
5. (盒子固件)接入前提¶
固件 MicroPython requests 目前不解析 chunked——接入本源前需验证:
# PC 侧先验证服务端:应立即持续出字节
# curl -N "https://api.wwzu.com/api/v1/stream/radio_relay?station=cnr1"
固件侧以小超时循环读验证能持续收到数据后,可边读边喂 MP3 解码(mp3dec/minimp3,采样率常见 44100/48000 Hz,不要假设 24000)。服务端零改动。
6. 联调检查单¶
# ① 取数(需设备头)
curl -s -H 'X-Device-SN: <SN>' -H 'X-Device-Token: <TOKEN>' \
'https://api.wwzu.com/api/v1/data/radio_relay?station=cnr1'
# → code=0,payload.stream_url 存在,stations 为脱敏目录
# ② 播放(匿名可听)
curl -N 'https://api.wwzu.com/api/v1/stream/radio_relay?station=cnr1'
# → 立即持续出字节;响应无任何上游主机(qtfm/qingting/stm.rthk)
- [ ]
radio_relay已订阅(40302说明没订) - [ ] 播放 URL 即点即播,连续收听 ≥30 分钟无中断
- [ ] 换台正常(新 station 立即可播)
- [ ] 断流后重播能恢复(服务端静默 >90s 会结束听众流)
- [ ] 响应与页面中无任何上游真实地址
7. 常见问题¶
Q:能下载整段音乐/节目吗? 不能。本源是实时转播(直播语义),服务端不留存任何音频,也没有分段下载路径(2026-09-18 起移除)。
Q:stream_url 可以分享给别人吗?
URL 匿名可听(默认口径与 /media 一致);但取数需要设备头与订阅。服务端有听众数上限与限流兜底。
Q:上游电台地址在哪里? 不提供。上游真实地址是服务端内部配置(密钥/radio-browser 刷新),全链路脱敏:响应、日志、目录均不出现。
Q:40302 / 42901 分别什么意思?
未订阅 / 播放听众数超限。