multi-scrobbler 0.13.3 API 使用详解

multi-scrobbler 0.13.3 HTTP API 实测详解:health/status/recent 三端点结构与监控集成,含真实排障实例。

multi-scrobblermulti-scrobbler音乐DockerDocker Compose2026/10/30

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 文档按当日官方文档站核定)

二、前置条件

  1. 服务运行中,仪表盘可访问(实测首页标题):
curl -s http://127.0.0.1:8147/ | grep -o '<title>[^<]*</title>'
# 实测输出:<title>Multi Scrobbler</title>
  1. 已配置至少一个源与一个目标(否则 /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/healthGET200健康探针:messages 为空即健康,非空列出故障项
/api/statusGET200全量运行状态:源/目标列表、认证与轮询状态、scrobble 计数
/api/recentGET200源侧「上游最近播放」:仅对支持该能力的源返回数据(见 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 播放实测):

字段实测值语义
statusplaying播放器状态
title / artists / albumNeon Skyline / ["Lab Ensemble"] / Test Sessions当前曲目元数据(VLC 场景来自 ID3 标签)
duration150曲目总时长(秒)
listenedFor141.0已监听时长(秒)
playDate2026-10-29T23:02:11+08:00本轮播放开始时间
mediaPlayerVersion3.0.16 Vetinari播放器版本(MS 连接时探测所得)
playerid / playerName5341c58b-… / vlc on 3573c8f61ad2播放器实例标识

clients[](每个目标一个对象):

字段实测值语义
statusRunning目标工作状态
type / display / namemaloja / Maloja / labMaloja同源侧三件套
scrobbled1本次运行窗口内成功提交的 scrobble 数
hasAuth / authedtrue / true目标认证状态
initializedtrue目标是否完成初始化(通信+认证测试通过,对应日志 Fully Initialized!)
queued / deadLetterScrobbles0 / 0待重试队列 / 死信(重试耗尽)的 scrobble 数;非零即目标侧提交受阻

⚠️ 注意:scrobbled 与 tracksDiscovered 是运行时计数,服务重启后从 0 重新累计(实测:重启前 scrobbled: 3,重启后恢复期间归 0、新 scrobble 后变 1);持久账本在配置目录的 SQLite 数据库中,两端看到的只是不同窗口的口径。

5.4 状态判定速查(实测总结)

现象statusauthedmessages判断
源正常轮询Pollingtrue[]健康
源进程停止/网络不通Communication Failedfalserequires authentication + is not polling连接层故障(不是密钥问题)
源可达但密钥错同上路径false同格式认证层故障,核对凭据
目标密钥错/不可达Running 但 queued 增长false 或见 messagesClient ...目标侧提交受阻

六、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 授权走仪表盘页面交互。

十一、参考链接