THMR / Public API

公共 API 调用文档

这些接口面向播放器、状态展示和第三方只读集成。管理端、上传、控制、配置和鉴权后台接口不在本文档范围内。

GET only JSON + audio/mpeg + HLS CORS enabled
Base endpoint https://radio.yunmoan.cn
Basics

请求约定

所有公开 JSON 接口都使用 GET,响应为 UTF-8 JSON。播放流接口用于播放器或流媒体客户端,不返回 JSON。

  • 电台 ID 示例使用 touhou。实际接入时先读取 /api/stations 或状态接口中的 station.id
  • 码率 ID station.bitrates[].id 选择,例如 320k128k。不要硬编码未确认的码率。
  • 时间字段 字段名以 Ms 结尾时为 Unix epoch milliseconds;durationSec 为秒。
Auth & CORS

鉴权与跨域

公开 JSON 状态接口可直接读取。播放流如果启用了 stream auth,需要携带播放 token。

  • Query token ?token=YOUR_TOKEN,浏览器音频和 HLS 播放器推荐使用这种方式。
  • Header token X-Stream-Token: YOUR_TOKEN,适合后端或命令行客户端。
  • CORS 公开路径允许跨域 GETHEADOPTIONS,并允许 Content-TypeX-Stream-Token 请求头。
Endpoints

公开接口

以下为当前 THMR 公共接口。路径均以 https://radio.yunmoan.cn 为前缀。

GET /api/version

读取后端名称和版本,用于客户端兼容性显示或健康探测。

Response
{ "name": "radio-livestream", "version": "1.0.0" }
curl
curl -s https://radio.yunmoan.cn/api/version
GET /api/stations

读取电台摘要列表,包含公开状态、当前曲目、听众数、曲库数量和可用码率。

Response
数组。每个元素包含 idnameenabledpublicEnabledstreamAuthEnabledcurrentlistenerstrackCountbitrates
curl
curl -s https://radio.yunmoan.cn/api/stations
GET /api/stations/{stationId}/status

读取单个电台的完整公开运行状态。播放器通常使用它来获取当前曲目、下一批队列、码率列表和听众统计。

Path
stationId 为电台 ID,例如 touhou
Response
对象。包含 stationruntimetotalsprofileslibraryCountcurrentpreviousqueuepreviewbackend
示例响应结构
{
  "station": {
    "id": "touhou",
    "name": "THMR",
    "enabled": true,
    "public": {
      "enabled": true,
      "title": "东方音乐电台 THMR",
      "accentColor": "#c65a69",
      "description": "直播中"
    },
    "streamAuthEnabled": false,
    "bitrates": [
      {
        "id": "320k",
        "enabled": true,
        "bitrateKbps": 320,
        "sampleRate": 44100,
        "channels": 2
      }
    ]
  },
  "totals": {
    "listeners": 0,
    "rawConnections": 0,
    "uniqueIps": 0
  },
  "profiles": [
    {
      "id": "320k",
      "bitrateKbps": 320,
      "sampleRate": 44100,
      "channels": 2,
      "listeners": 0,
      "rawConnections": 0
    }
  ],
  "current": {
    "trackId": "track-id",
    "title": "Track title",
    "artist": "Artist",
    "relativePath": "music/example.mp3",
    "startedAtMs": 1784280000000,
    "expectedEndMs": 1784280240000,
    "positionSec": 42,
    "durationSec": 240
  },
  "previous": null,
  "queue": [
    {
      "trackId": "next-track-id",
      "title": "Next track",
      "artist": "Artist",
      "relativePath": "music/next.mp3",
      "plannedStartMs": 1784280240000,
      "plannedEndMs": 1784280500000,
      "durationSec": 260
    }
  ],
  "preview": null,
  "backend": {
    "name": "radio-livestream",
    "version": "1.0.0"
  }
}
GET /api/stations/{stationId}/playlist

读取当前运行队列,响应内容等同于状态接口中的 queue 字段。

Response
数组。元素包含 trackIdtitleartistrelativePathplannedStartMsplannedEndMsdurationSec
curl
curl -s https://radio.yunmoan.cn/api/stations/touhou/playlist
GET /api/stations/{stationId}/preview

读取预生成的节目预告。可选 date=YYYY-MM-DD,不传时返回当前可用预告。

Query
date 可选,本地日期格式,例如 2026-07-18
Response
{ "date": "2026-07-18", "entries": [...] },未生成或日期不匹配时返回 404。
curl
curl -s "https://radio.yunmoan.cn/api/stations/touhou/preview?date=2026-07-18"
GET /radio/{stationId}/{profileId}

直连 MP3 播放流。适合 audio 标签、mpv、VLC、ffplay 等客户端。

Content-Type
audio/mpeg
Alias
/radio/{stationId}/{profileId}.mp3 和兼容路径 /live/{stationId}/{profileId}
HTML
<audio controls src="https://radio.yunmoan.cn/radio/touhou/320k"></audio>
GET /radio/{stationId}/{profileId}.m3u8

HLS 播放列表入口。服务端会把分片地址改写为 /hls/{stationId}/{profileId}/{filename}

Content-Type
application/vnd.apple.mpegurl
Cache
响应设置为 no-store, no-cache, must-revalidate
播放器 URL
https://radio.yunmoan.cn/radio/touhou/320k.m3u8
GET /hls/{stationId}/{profileId}/{filename}

HLS 分片文件。通常不要手动拼接这个地址,直接让 HLS 播放器消费 .m3u8 中返回的分片路径。

来源
/radio/{stationId}/{profileId}.m3u8 返回。
鉴权
如果播放流启用了 token,.m3u8 会把 ?token=... 追加到分片路径。
Errors

状态码

JSON 接口的错误通常返回 { "error": "..." };播放流接口的错误为纯文本。

200 请求成功。JSON 接口返回对象或数组;播放流开始传输音频或 HLS 内容。
403 播放流 token 无效或缺失。为 URL 加上 ?token=YOUR_TOKEN,或使用 X-Stream-Token 请求头。
404 电台、码率、预告日期或 HLS 分片不存在。
503 电台已停用,或 HLS 播放列表尚未准备好。