multi-scrobbler 0.13.3 API 使用详解
multi-scrobbler 0.13.3 HTTP API 实测详解:health/status/recent 三端点结构与监控集成,含真实排障实例。
multi-scrobbler 0.13.3 API 使用详解
目标:讲清 multi-scrobbler 0.13.3 对外暴露的 HTTP API——三个已实测可用的 GET 端点(
/api/health、/api/status、/api/recent)的完整返回结构、字段语义与监控集成方法,并以真实排障案例演示「用 API 判断服务健康、定位源故障、执行恢复」的完整链路。已在 Ubuntu 22.04 / Docker Engine 29.9.2 环境实测,全部回显逐行照抄。
一、环境信息
- 服务器系统:Ubuntu 22.04(x86_64),Docker Engine 29.9.2 / Compose v5.6.1
- multi-scrobbler:0.13.3(官方镜像
foxxmd/multi-scrobbler:0.13.3,启动日志实测Version: 0.13.3) - 服务端口:宿主
8147→ 服务内9078(Web 仪表盘与 API 同端口,官方默认 9078) - 验证栈:VLC 3.0.16 轮询源 + Maloja 3.2.4 目标(API 密钥
q1w2e3r4,宿主端口 8148),部署与配置见《multi-scrobbler Docker Compose 部署指南》《multi-scrobbler 0.13.3 配置参数详解》 - D 篇选型说明:multi-scrobbler 无传统 CLI 主命令(服务进程常驻,官方安装文档无任何「执行一次」式命令入口),故本文按 API/端点面成篇
- 查询日期:2026-10-29(官方 API 文档按当日官方文档站核定)
二、前置条件
- 服务运行中,仪表盘可访问(实测首页标题):
curl -s http://127.0.0.1:8147/ | grep -o '<title>[^<]*</title>'
# 实测输出:<title>Multi Scrobbler</title>
- 已配置至少一个源与一个目标(否则
/api/status返回空数组,仍可正常探活)。
三、API 总览
对 0.13.3 的 /api 前缀与常见路径做全量探测(实测,2026-10-29):
for ep in /api/health /api/status /api/recent /api/scrobbles /api/config /docs /api/openapi.json; do
printf '%-22s ' "$ep"; curl -s -o /tmp/p.out -w '%{http_code}' "http://127.0.0.1:8147$ep"
printf ' %s\n' "$(head -c 60 /tmp/p.out | tr -d '\n')"
done
# 实测输出:
# /api/health 200 {"messages":[]}
# /api/status 200 {"sources":[{"status":"Polling","type":"vlc","display":"Vlc",
# /api/recent 200 []
# /api/scrobbles 404 Not Found
# /api/config 404 Not Found
# /docs 301 <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Redirectin
# /api/openapi.json 404 Not Found
结论(以实测为准):
| 端点 | 方法 | 状态 | 用途 |
|---|---|---|---|
/api/health | GET | 200 | 健康探针:messages 为空即健康,非空列出故障项 |
/api/status | GET | 200 | 全量运行状态:源/目标列表、认证与轮询状态、scrobble 计数 |
/api/recent | GET | 200 | 源侧「上游最近播放」:仅对支持该能力的源返回数据(见 6.1) |
/api/scrobbles、/api/config、/api/openapi.json 等 | — | 404 | 不存在。0.13.3 没有 scrobble 明细查询、配置读写与 OpenAPI 描述端点(官方 API 文档也仅覆盖 health/status/recent 三个只读端点) |
💡 技术拓展:这三个端点都是只读的——multi-scrobbler 的配置变更走配置文件或环境变量(重启生效),运行管理走 Web 仪表盘;API 定位是「状态观测与探活」,不是「控制面」。这也是它与很多带管理 API 的自托管组件的差异点,排障入口对比见《multi-scrobbler 0.13.3 配置参数详解》。
四、GET /api/health(健康探针)
4.1 健康态返回
curl -s http://127.0.0.1:8147/api/health
# 实测输出(服务健康、源/目标全部正常):
# {"messages":[]}
4.2 故障态返回(实测:停止播放源进程后)
curl -s http://127.0.0.1:8147/api/health
# 实测输出(VLC 源进程被停止后):
# {"messages":["Source vlc - Lab VLC requires authentication.","Source vlc - Lab VLC is not polling."]}
4.3 字段与语义
messages:字符串数组,空数组 = 健康;每个元素是一条故障描述。本例两条消息分别对应「源无法认证/连接」与「源停止轮询」,措辞固定为Source <name> - <display> ...格式;- 目标(Client)故障同样会出现在
messages中(格式为Client ...,如认证失效、通信失败); - 语义注意:
requires authentication并非只有「密钥错误」一种含义——实测把播放源进程整个停掉(连接层失败)也会报这条消息。准确含义见/api/status的status字段(5.3); - 恢复验证(重启 VLC 进程 + 重启 multi-scrobbler 后实测):
curl -s http://127.0.0.1:8147/api/health
# 实测输出:{"messages":[]}
4.4 监控集成建议
/api/health 是给探活系统用的:messages 为空时 HTTP 状态为 200 且 body 无故障文案,任何支持 HTTP 探针的监控(Uptime Kuma、Prometheus blackbox exporter、反代健康检查)都可直接接入;对 JSON 敏感的监控可同时校验 messages 数组为空,实现「服务活着但源/目标有故障」的二级告警。
五、GET /api/status(运行状态全量)
5.1 健康态完整返回(实测回显)
curl -s http://127.0.0.1:8147/api/status
# 实测输出:
# {"sources":[{"status":"Polling","type":"vlc","display":"Vlc","tracksDiscovered":3,"name":"Lab VLC","canPoll":true,"hasAuth":true,"hasAuthInteraction":false,"authed":true,"players":{"5341c58b-3c4a-4573-90b0-2c21b6299627":{"playerid":"5341c58b-3c4a-4573-90b0-2c21b6299627","playerName":"vlc on 3573c8f61ad2","mediaType":"music","status":"playing","playbackStarted":1793287331.795,"title":"Neon Skyline","artists":["Lab Ensemble"],"album":{"name":"Test Sessions","artists":[]},"duration":150,"listenedFor":141.0,"playDate":"2026-10-29T23:02:11+08:00","mediaPlayer":"vlc","mediaPlayerVersion":"3.0.16 Vetinari"}},"sot":"player","supportsUpstreamRecentlyPlayed":false,"supportsManualListening":false}],"clients":[{"status":"Running","type":"maloja","display":"Maloja","scrobbled":1,"name":"labMaloja","hasAuth":true,"hasAuthInteraction":false,"authed":true,"initialized":true,"deadLetterScrobbles":0,"queued":0}]}
5.2 故障态返回(实测:播放源进程停止后)
# 实测输出(节选):
# {"sources":[{"status":"Communication Failed","type":"vlc",...,"authed":false,"players":{},...}],"clients":[{"status":"Running","type":"maloja",...,"authed":true,"initialized":true,"deadLetterScrobbles":0,"queued":0}]}
5.3 字段详解
sources[](每个源一个对象):
| 字段 | 类型 | 实测值 | 语义 |
|---|---|---|---|
status | 字符串 | Polling / Communication Failed | 源工作状态;Polling=正常轮询中,Communication Failed=无法连接源 |
type | 字符串 | vlc | 源类型(配置中的 type) |
display | 字符串 | Vlc | 类型显示名 |
name | 字符串 | Lab VLC | 源实例名(配置中的 name) |
tracksDiscovered | 数值 | 3 | 本实例累计发现的播放数 |
canPoll | 布尔 | true | 是否为轮询型源 |
hasAuth / authed | 布尔 | true / true(故障态 false) | 是否需要认证 / 当前认证是否通过 |
hasAuthInteraction | 布尔 | false | 认证是否需要交互(OAuth 类为 true,仪表盘上会出登录入口) |
players | 对象 | 见 5.1 | 当前播放器/播放对象实时状态(无播放时 {}) |
sot | 字符串 | player | 播放状态来源 |
supportsUpstreamRecentlyPlayed | 布尔 | false | 是否支持上游最近播放查询(决定 /api/recent 是否有数据,见 6.1) |
supportsManualListening | 布尔 | false | 是否支持手动添加监听 |
players 内的播放对象(本轮 VLC 播放实测):
| 字段 | 实测值 | 语义 |
|---|---|---|
status | playing | 播放器状态 |
title / artists / album | Neon Skyline / ["Lab Ensemble"] / Test Sessions | 当前曲目元数据(VLC 场景来自 ID3 标签) |
duration | 150 | 曲目总时长(秒) |
listenedFor | 141.0 | 已监听时长(秒) |
playDate | 2026-10-29T23:02:11+08:00 | 本轮播放开始时间 |
mediaPlayerVersion | 3.0.16 Vetinari | 播放器版本(MS 连接时探测所得) |
playerid / playerName | 5341c58b-… / vlc on 3573c8f61ad2 | 播放器实例标识 |
clients[](每个目标一个对象):
| 字段 | 实测值 | 语义 |
|---|---|---|
status | Running | 目标工作状态 |
type / display / name | maloja / Maloja / labMaloja | 同源侧三件套 |
scrobbled | 1 | 本次运行窗口内成功提交的 scrobble 数 |
hasAuth / authed | true / true | 目标认证状态 |
initialized | true | 目标是否完成初始化(通信+认证测试通过,对应日志 Fully Initialized!) |
queued / deadLetterScrobbles | 0 / 0 | 待重试队列 / 死信(重试耗尽)的 scrobble 数;非零即目标侧提交受阻 |
⚠️ 注意:
scrobbled与tracksDiscovered是运行时计数,服务重启后从 0 重新累计(实测:重启前scrobbled: 3,重启后恢复期间归 0、新 scrobble 后变 1);持久账本在配置目录的 SQLite 数据库中,两端看到的只是不同窗口的口径。
5.4 状态判定速查(实测总结)
| 现象 | status | authed | messages | 判断 |
|---|---|---|---|---|
| 源正常轮询 | Polling | true | [] | 健康 |
| 源进程停止/网络不通 | Communication Failed | false | requires authentication + is not polling | 连接层故障(不是密钥问题) |
| 源可达但密钥错 | 同上路径 | false | 同格式 | 认证层故障,核对凭据 |
| 目标密钥错/不可达 | Running 但 queued 增长 | false 或见 messages | Client ... | 目标侧提交受阻 |
六、GET /api/recent(上游最近播放)
6.1 返回结构(实测)
curl -s http://127.0.0.1:8147/api/recent
# 实测输出:
# []
本文验证栈(VLC 源)下恒为 []。原因与 /api/status 中的能力位直接相关:VLC 源的 supportsUpstreamRecentlyPlayed: false——该端点面向自带「最近播放」API 的源(如 last.fm、ListenBrainz 源)透出上游最近播放数据;不支持的源不产生数据(实测对 VLC 源加 ?source=Lab%20VLC、?client=labMaloja、?limit=5 等参数变体均仍返回 [])。
⚠️ 注意:判断你的部署里该端点是否有数据,先看
/api/status中对应源的supportsUpstreamRecentlyPlayed字段;true的源才有内容。/api/status的players/tracksDiscovered已能覆盖常规「最近听了什么」的观测需求。
七、仪表盘与 API 的关系
Web 仪表盘(http://<IP>:8147/,实测标题 Multi Scrobbler)与 API 同端口、数据同源:仪表盘展示的源/目标状态、播放对象、队列计数即 /api/status 的内容;API 适合做无人值守的监控集成,仪表盘适合人工核查与 OAuth 类源的交互授权(hasAuthInteraction: true 的源/目标在页面上出登录入口)。
八、运维排障实录
8.1 实例一:播放源进程停止导致健康检查告警
现象:/api/health 突然非空(实测回显见 4.2),仪表盘源状态红。
定位:/api/status 显示 status: "Communication Failed"、authed: false、players: {}。authed: false 极易误判为密钥问题,实测证明源进程整个停止时同样报 requires authentication——该字段表达「当前无法完成一次成功的认证通信」,连接层断开时必然为假。
恢复(全部实测):
# 1. 重启播放源进程(VLC 以普通用户运行,见部署指南 4.6)
docker compose -f /opt/multi-scrobbler/docker-compose.yml exec -d vlc bash -c \
'su vlcuser -c "vlc -I dummy --extraintf http --http-host 0.0.0.0 --http-port 8080 --http-password q1w2e3r4 --loop /music/neon-skyline.mp3 > /tmp/vlc3.log 2>&1"'
# 2. 重启 multi-scrobbler 立即重连(不等心跳)
docker compose -f /opt/multi-scrobbler/docker-compose.yml restart multi-scrobbler
# 实测输出:
# Container multi-scrobbler-0-13-3-app Restarting
# Container multi-scrobbler-0-13-3-app Started
# 3. 验证(约 30 秒后)
curl -s http://127.0.0.1:8147/api/health
# 实测输出:{"messages":[]}
curl -s http://127.0.0.1:8147/api/status | python3 -c "import json,sys; d=json.load(sys.stdin); s=d['sources'][0]; print(s['status'], s['authed'])"
# 实测输出:Polling True
闭环确认:恢复后新一轮播放再次触发 scrobble,clients[0].scrobbled 由 0 变 1,目标侧 Maloja 查询确认入库(实测):
curl -s -H 'Authorization: TOKEN q1w2e3r4' 'http://127.0.0.1:8148/apis/mlj_1/scrobbles?max=1'
# 实测输出(节选):
# {"status": "ok", "list": [{"time": 1793287336, "track": {"artists": ["Lab Ensemble"], "title": "Neon Skyline", ...}, "duration": 136, "origin": "client:default"}], ...}
8.2 实例二:源服务重装导致播放环境丢失(「恢复后仍故障」的坑)
现象:按实例一恢复后健康检查仍然报同样的 requires authentication,且无论怎么重启 multi-scrobbler 都不恢复。
定位:登录 VLC 所在服务器检查,发现 vlc/ffmpeg 可执行文件与运行用户全部消失:
which vlc; grep vlcuser /etc/passwd
# 实测输出(故障时):
# NO_VLC
# NO_USER
根因:VLC 是部署完成后在服务器上手工补装的(apt 安装 + useradd 都落在系统可写区,未沉淀为装机模板)。实验过程中该服务器环境被 重装/重建,系统盘状态整体作废——「重启」只重启进程、保留系统状态,而「重装」会全部丢失。这是「手工装配」与「固化装配(装机模板/标准化部署)」的本质差异。
教训与长期方案:凡部署后手工安装的软件、创建的用户、启动的进程,都不具备跨重建的持久性;长期方案是把源环境固化为可一键重放的装机模板(脚本固化安装步骤)或改用平台已有专栏的专用组件(Jellyfin/Navidrome/Audioserve 等),再把 multi-scrobbler 指向它们。本次验证栈按实例一流程重装 VLC 后恢复(/api/health 回到 {"messages":[]},回显见 4.3)。
8.3 实例三:重启后计数归零的「账目困惑」
现象:排障重启后 /api/status 的 scrobbled 从 3 变 0,怀疑 scrobble 数据丢失。
定位与结论:scrobbled/tracksDiscovered 是运行时计数器,重启即归零;持久账本在配置目录 SQLite 数据库中,与计数器无关(区分实测见 5.3 ⚠️ 注意)。核对账目应查目标侧统计(Maloja 的 scrobbles 列表)而非依赖运行时计数。
九、外部集成示例
cron 分钟级健康巡检脚本(服务器上保存为 /opt/scripts/ms-watch.sh,chmod +x 后加入 crontab):
#!/usr/bin/env bash
# multi-scrobbler 健康巡检:messages 非空即记录并告警
HEALTH=$(curl -sf --max-time 5 http://127.0.0.1:8147/api/health)
if [ $? -ne 0 ]; then
logger -t ms-watch "multi-scrobbler HTTP unreachable"
exit 1
fi
if [ "$HEALTH" != '{"messages":[]}' ]; then
logger -t ms-watch "unhealthy: $HEALTH"
fi
说明:logger 写入系统 syslog,按需替换为钉钉/ntfy 等 Webhook 告警;探针间隔建议 ≥60 秒(源轮询与故障上报本身有周期,秒级探针无意义)。
十、常见问题
Q1:/api/health 返回非 200 或连接被拒?
服务未启动或端口映射错误:先 curl http://127.0.0.1:8147/ 确认仪表盘可达,再核对 compose 端口映射(服务内端口固定 9078)。
Q2:为什么没有 scrobble 明细查询端点?
0.13.3 的公开 API 只有三个只读端点(实测探测见「三、API 总览」,/api/scrobbles 等均 404)。明细核对走目标侧统计服务(如 Maloja 的 /apis/mlj_1/scrobbles)或仪表盘。
Q3:/api/recent 一直返回 []?
见 6.1:先查 /api/status 中源的 supportsUpstreamRecentlyPlayed;VLC/Mopidy 这类本地播放源不支持上游最近播放,恒为空属正常。
Q4:authed: false 一定是 API 密钥错吗?
不一定。实测源进程停止(连接层断开)时同样 authed: false 且 health 报 requires authentication。先看 status 是否 Communication Failed:是则查连通性,不是才查密钥。
Q5:能否用 API 触发重新认证或重载配置?
不能。API 为只读(实测 404 集见「三、API 总览」);配置重载走重启(docker compose -f /opt/multi-scrobbler/docker-compose.yml restart multi-scrobbler),OAuth 授权走仪表盘页面交互。
十一、参考链接
- 官方 API 文档(health/status/recent):https://foxxmd.github.io/multi-scrobbler/api/
- 官方仪表盘说明:https://foxxmd.github.io/multi-scrobbler/dashboard/
- 配置总览:https://foxxmd.github.io/multi-scrobbler/configuration/
- Maloja API(目标侧核对用):https://github.com/krateng/maloja
- 本专栏相关:《multi-scrobbler 介绍与选型指南》《multi-scrobbler Docker Compose 部署指南》《multi-scrobbler 0.13.3 配置参数详解》