Snapcast 0.35.0 常用 CLI 命令与工具详解

Snapcast 0.35.0 命令全解:snapserver -hh 选项表、snapclient 全参数要点、JSON-RPC 三入口实测回显(含 -32601 排障)、日志形态速查与三则排障实录。

SnapcastSnapcast音频流媒体媒体服务器2026/10/30

Snapcast 0.35.0 常用 CLI 命令与工具详解

目标:备齐 Snapcast 0.35.0 日常操作的全套命令——snapserver/snapclient 全部命令行选项(真实默认值)、JSON-RPC 控制命令(含实测回显与错误示范)、日志出口与排障实录。已在 Debian 12(x86_64)实测全部命令。

一、环境信息

本文所有命令与回显均在以下实测环境采集:

  • 操作系统:Debian GNU/Linux 12 (bookworm)
  • 架构:x86_64
  • Snapserver / Snapclient:v0.35.0 (rev f1237347),deb 安装
  • 拓扑:1 台服务器(10.89.61.2)+ 2 台客户端(10.89.61.3 / 10.89.61.4),客户端 ID 实测为 86:4c:86:eb:df:d7 与 1e:66:50:a2:56:b7
  • 端口:1704(流)/ 1705(TCP JSON-RPC)/ 1780(HTTP JSON-RPC)
  • 音源:pipe:///serverdata/snapfifo?name=SineTest(440Hz 正弦波,44100:16:2,pcm)
  • 实测数据日期:2026-10-30

二、工具概览

Snapcast 的日常操作面由「两个二进制 + 一个控制协议 + 日志」构成:

工具/入口类型用途
snapserver服务端二进制启动流服务器;全部参数支持配置文件与命令行双轨
snapclient客户端二进制接入服务器并播放;全部参数走命令行
JSON-RPC 2.0控制协议HTTP(1780)/TCP(1705)/WebSocket 三入口等价,管理分组/音量/切流
Snapweb网页控制台1780 端口内置前端,可视化等价 JSON-RPC
systemd 单元进程托管snapserver.service / snapclient.service(deb 自带)
journald日志systemd 模式下 journalctl -u snapserver 查看日志

💡 说明:deb 安装的 systemd 单元实测原文——snapserver.service 的 ExecStart=/usr/bin/snapserver --logging.sink=system --server.datadir=${HOME} $SNAPSERVER_OPTS(User=snapserver),snapclient.service 的 ExecStart=/usr/bin/snapclient --logsink=system $SNAPCLIENT_OPTS(User=snapclient)。$SNAPSERVER_OPTS/$SNAPCLIENT_OPTS 来自 /etc/default/snapserver、/etc/default/snapclient,是追加命令行参数的正规入口。

三、前置条件

  • 服务端已安装 snapserver 并运行(systemctl is-active snapserver → active);
  • 客户端已安装 snapclient;
  • 版本确认(两台机器同版本,避免协议不兼容):
snapserver --version | head -1
snapclient --version | head -1
snapserver v0.35.0 (rev f1237347)
snapclient v0.35.0 (rev f1237347)

四、snapserver 命令行详解

4.1 基础选项

snapserver -h 实测输出(前 8 行):

Allowed options
  -h, --help                          Produce help message, use -hh to show options from config file
  -v, --version                       Show version number
  -d, --daemon [=arg(=0)]             Daemonize
                                      optional process priority [-20..19]
  -c, --config arg (=/etc/snapserver.conf)
                                      Path to the configuration file
  • -h:只看基础选项;-hh:追加打印全部可覆盖的配置文件选项(见 4.2);
  • -d:守护化,可带进程优先级(-20~19,默认 0);systemd 托管时不要用;
  • -c:指定配置文件路径,默认 /etc/snapserver.conf。

4.2 配置覆盖选项(-hh 全量)

--<section>.<name> 形式的选项与 /etc/snapserver.conf 一一对应,命令行优先。snapserver -hh 实测输出全文按段整理(默认值为实测值):

选项默认值说明
--server.threads-1工作线程数
--server.pidfile/var/run/snapserver/pid守护模式 pid 文件
--server.user / --server.groupsnapserver / (空)守护模式运行账号/组
--server.datadir(空)server.json 持久化目录
--server.mdns_enabled1mDNS 发布开关
--ssl.certificate / --ssl.certificate_key(空)TLS 证书/私钥(PEM)
--ssl.key_password(空)私钥口令
--ssl.verify_clients0客户端证书校验
--ssl.client_cert(空,可多次)客户端 CA 列表
--authorization.enabled0JSON-RPC 鉴权开关
--authorization.role(空)角色定义 <Role name>:<permissions>
--authorization.user(空)用户定义 <User name>:<password>:<role>
--http.enabled / --http.port1 / 1780HTTP JSON-RPC 开关/端口
--http.bind_to_address::HTTP 监听地址
--http.ssl_enabled / --http.ssl_port0 / 1788HTTPS 开关/端口
--http.doc_root(空)静态站点根目录(Snapweb)
--http.host<hostname>封面外链主机名
--http.url_prefix(空)封面外链 URL 前缀
--http.publish_http / --http.publish_https1 / 1mDNS 发布开关
--tcp.enabled / --tcp.port1 / 1705(已弃用别名,等价 tcp-control)
--tcp-control.enabled / --tcp-control.port1 / 1705TCP JSON-RPC 开关/端口
--tcp-streaming.enabled / --tcp-streaming.port1 / 1704音频流开关/端口
--stream.plugin_dir/usr/share/snapserver/plug-insmeta 插件目录
--stream.sandbox_dir/usr/share/snapserver/sandbox可执行源沙箱目录
--stream.streampipe:///tmp/snapfifo?name=default(已弃用别名,等价 stream.source)
--stream.sourcepipe:///tmp/snapfifo?name=default音源 URI(可多次)
--stream.default_source(空)新客户端默认流
--stream.sampleformat48000:16:2默认采样格式
--stream.codecflac默认传输编码
--stream.stream_buffer20(已弃用别名,等价 chunk_ms)
--stream.chunk_ms20读取/编码时间片(ms)
--stream.buffer1000端到端同步缓冲(ms)
--stream.send_to_muted0静音客户端是否推流
--streaming_client.initial_volume100新客户端初始音量
--logging.sink(空)日志出口
--logging.filter*:info日志级别

💡 说明:三个 deprecated 选项(--tcp.*、--stream.stream、--stream.stream_buffer)是旧版本拼写,新配置一律用 --tcp-control.*、--stream.source、--stream.chunk_ms;codec 专属参数实测见站内《Snapcast 0.35.0 配置参数详解》5.2 节。

五、snapclient 命令行详解

5.1 基础用法与服务器地址

snapclient --help 实测输出的头部(url 语义官方原文):

Usage: snapclient [options...] [url]

 With 'url' = <tcp|ws|wss>://<snapserver host or IP or mDNS service name>[:port]
 For example: 'tcp://192.168.1.1:1704', or 'ws://)homeserver.local' or 'wss://_snapcast-https._tcp'
 If 'url' is not configured, snapclient defaults to 'tcp://_snapcast._tcp'

三种写法(实测以显式 tcp 连接):tcp://10.89.61.2:1704(生产标配)、ws://10.89.61.2:1780(走 HTTP 端口)、不写 url(mDNS 自动发现,需服务器与客户端同网段且 avahi 可用)。连接成功日志实测:

2026-10-30 00-51-59.275 [Info] (Snapclient) Version 0.35.0, revision f1237347
2026-10-30 00-51-59.276 [Info] (Connection) Resolving host IP for: server
2026-10-30 00-51-59.277 [Info] (Connection) Connecting to host: 10.89.61.2:1704, port: 1704, protocol: tcp
2026-10-30 00-51-59.277 [Notice] (Connection) Connected to server
2026-10-30 00-51-59.277 [Info] (Connection) My MAC: "ae:91:13:92:a7:29", socket: 8
2026-10-30 00-51-59.287 [Info] (Controller) ServerSettings - buffer: 1000, latency: 0, volume: 100, muted: 0
2026-10-30 00-51-59.298 [Info] (Controller) diff to server [ms]: -0.001

diff to server [ms] 即客户端与服务器时钟差估计值,是同步质量的直接指标(局域网通常在 ±1ms 内)。

5.2 设备与音频参数

  • -l, --list:列出 PCM 设备,无声卡环境实测:
0: null
Discard all samples (playback) or generate zero samples (capture)
  • -s, --soundcard:设备索引或名称,默认 default;无声卡机器接 ALSA null 设备即可验证同步链路(实测 --soundcard null 连接后正常收流);
  • --latency:声卡固有延迟补偿(毫秒),默认 0;
  • --sampleformat:强制客户端重采样为 <rate>:<bits>:<channels>;
  • --player:输出后端,默认 alsa;file 后端把原始 PCM 写到 stdout(实测日志:Player name: file, device: stdout, description: Raw PCM file output),适合管道转接,例如把客户端输出交给本地 recorder 分析:
snapclient tcp://10.89.61.2:1704 --player file | head -c 1000000 > /dev/null
  • --mixer:混音器实现,默认 software(客户端软件调音量,最通用);hardware 走声卡硬件混音(音质最好,依赖驱动支持)、script 自定义脚本(联动外部功放)、none 禁用(音量/静音控制失效)。

💡 技术拓展:mixer 四选对比——

mixer原理取舍
software客户端进程内软件缩放采样通用性最好,默认;CPU 略耗
hardwareALSA 混音器硬件通道零 CPU、音质无损,需声卡支持
script调用外部脚本可联动功放串口/网络控制
none不做音量处理音量/静音键失效,仅特殊场景

树莓派等板载声卡用默认 software 即可;有硬件混音的 USB 声卡可切 hardware。

5.3 身份与安全参数

  • --hostID:客户端唯一身份,默认 MAC。实测环境客户端以 MAC 形式出现在服务器(如 86:4c:86:eb:df:d7);虚拟机/重建环境 MAC 会变,导致服务器端的名字/音量/分组失联,此类环境必须显式固定(--hostID living-room);
  • --instance:同机多实例编号,默认 1(一块声卡跑多路时区分);
  • --cert / --cert-key / --key-password / --server-cert:对接服务器 TLS 的客户端证书三件套与 CA 校验(对应服务器 --ssl.verify_clients)。

5.4 运行方式参数

  • -d, --daemon:守护化,默认 nice -3;--user:守护化降权账号(user[:group]);
  • --logsink:日志出口(null/system/stdout/stderr/file:),--logfilter:级别过滤,默认 *:info;排障改 --logfilter '*:debug'。

六、JSON-RPC 控制命令详解

6.1 入口与约定

三个等价入口(实测均可用):HTTP POST http://<server>:1780/jsonrpc、TCP 1705 每行一个请求、WebSocket(1780 同端口)。协议版本查询:

curl -s http://10.89.61.2:1780/jsonrpc -H 'Content-Type: application/json' \
  -d '{"id":3,"jsonrpc":"2.0","method":"Server.GetRPCVersion"}'
{
    "id": 3,
    "jsonrpc": "2.0",
    "result": {
        "major": 23,
        "minor": 0,
        "patch": 0
    }
}

TCP 入口实测(裸 TCP 发一行 JSON):

{"id":1,"jsonrpc":"2.0","method":"Server.GetRPCVersion"}
{"id":1,"jsonrpc":"2.0","result":{"major":23,"minor":0,"patch":0}}

方法命名空间:Server.*(全局)、Group.*(分组)、Client.*(单客户端)、Stream.*(流属性)。参数中的客户端 ID 即 --hostID 值(默认 MAC),组 ID 为服务器生成的 UUID。以下全部回显为实测原文。

6.2 Server.* 全局命令

Server.GetStatus——全栈状态(组/客户端/流),最常用。实测回显(节选):

{
    "id": 2,
    "jsonrpc": "2.0",
    "result": {
        "server": {
            "groups": [
                {
                    "clients": [
                        {
                            "config": {
                                "instance": 1,
                                "latency": 0,
                                "name": "",
                                "volume": {
                                    "muted": false,
                                    "percent": 100
                                }
                            },
                            "connected": true,
                            "host": {
                                "arch": "x86_64",
                                "ip": "::ffff:10.89.61.3",
                                "mac": "66:5f:2e:b8:5e:7f",
                                "name": "a2cb3822d765",
                                "os": "Debian GNU/Linux 12 (bookworm)"
                            },
                            "id": "66:5f:2e:b8:5e:7f",
                            "snapclient": {
                                "protocolVersion": 2,
                                "version": "0.35.0"
                            }
                        }
                    ],
                    "id": "49007f3a-2eef-a835-23a5-7cbe99977a2c",
                    "muted": false,
                    "name": "",
                    "stream_id": "SineTest"
                }
            ],
            "server": {
                "host": {
                    "name": "snapserver",
                    "os": "Debian GNU/Linux 12 (bookworm)"
                },
                "snapserver": {
                    "controlProtocolVersion": 1,
                    "protocolVersion": 1,
                    "version": "0.35.0"
                }
            },
            "streams": [
                {
                    "id": "SineTest",
                    "properties": {
                        "canControl": false,
                        "canPause": false,
                        "canPlay": false
                    },
                    "status": "playing"
                }
            ]
        }
    }
}

解读:groups[].clients[] 是拓扑,streams[] 是流列表;properties.canControl=false 表示 pipe 源不支持播放/暂停类控制(上游是裸 PCM 管道,没有元数据通道),meta 源(librespot 等)则为 true。

Server.DeleteClient——清理失联客户端记录(客户端 MAC 变更/退役后残留 connected: false 记录):

curl -s http://10.89.61.2:1780/jsonrpc -H 'Content-Type: application/json' \
  -d '{"id":11,"jsonrpc":"2.0","method":"Server.DeleteClient","params":{"id":"42:f4:13:da:e0:32"}}'
{"id":11,"jsonrpc":"2.0","result":{"server":{"groups":[{"clients":[{"config":{"instance":1,"latency":10,"name":"LivingRoom","volume":{"muted":false,"percent":65}},"connected":true,"host":{"arch":"x86_64","ip":"::ffff:10.89.61.3","mac":"66:5f:2e:b8:5e:7f","name":"a2cb3822d765","os":"Debian GNU/Linux 12 (bookworm)"

(输出节选:返回删除后的全栈状态,孤儿记录已消失。)

6.3 Group.* 分组命令

Group.SetClients——把客户端并入/移出组(多房间同播的核心命令)。实测把第二台客户端并入第一台所在组:

curl -s http://10.89.61.2:1780/jsonrpc -H 'Content-Type: application/json' \
  -d '{"id":7,"jsonrpc":"2.0","method":"Group.SetClients","params":{"id":"49007f3a-2eef-a835-23a5-7cbe99977a2c","clients":["66:5f:2e:b8:5e:7f","ae:91:13:92:a7:29"]}}'
{
    "id": 7,
    "jsonrpc": "2.0",
    "result": {
        "server": {
            "groups": [
                {
                    "clients": [
                        { "id": "66:5f:2e:b8:5e:7f", "connected": true },
                        { "id": "ae:91:13:92:a7:29", "connected": true }
                    ],
                    "id": "49007f3a-2eef-a835-23a5-7cbe99977a2c",
                    "muted": false,
                    "name": "",
                    "stream_id": "SineTest"
                }
            ]
        }
    }
}

(输出节选:两客户端已同组。)被移出的客户端会自动落入新建组,无需手工建组。

Group.SetName / Group.SetMute / Group.SetStream——组命名、组级静音、整组切流:

curl -s http://10.89.61.2:1780/jsonrpc -H 'Content-Type: application/json' \
  -d '{"id":8,"jsonrpc":"2.0","method":"Group.SetName","params":{"id":"49007f3a-2eef-a835-23a5-7cbe99977a2c","name":"GroundFloor"}}'
{
    "id": 8,
    "jsonrpc": "2.0",
    "result": {
        "name": "GroundFloor"
    }
}
== Group.SetMute true ==
{"id":9,"jsonrpc":"2.0","result":{"mute":true}}
== Group.SetStream ==
{"id":10,"jsonrpc":"2.0","result":{"stream_id":"SineTest"}}

6.4 Client.* 客户端命令

Client.GetStatus——单客户端详情:

curl -s http://10.89.61.2:1780/jsonrpc -H 'Content-Type: application/json' \
  -d '{"id":2,"jsonrpc":"2.0","method":"Client.GetStatus","params":{"id":"66:5f:2e:b8:5e:7f"}}'
{
    "id": 2,
    "jsonrpc": "2.0",
    "result": {
        "client": {
            "config": {
                "instance": 1,
                "latency": 0,
                "name": "",
                "volume": {
                    "muted": false,
                    "percent": 100
                }
            },
            "connected": true,
            "host": {
                "arch": "x86_64",
                "ip": "::ffff:10.89.61.3",
                "mac": "66:5f:2e:b8:5e:7f",
                "name": "a2cb3822d765",
                "os": "Debian GNU/Linux 12 (bookworm)"
            },
            "id": "66:5f:2e:b8:5e:7f",
            "lastSeen": {
                "sec": 1793322353,
                "usec": 286198
            },
            "snapclient": {
                "name": "Snapclient",
                "protocolVersion": 2,
                "version": "0.35.0"
            }
        }
    }
}

Client.SetVolume——音量与静音(客户端静音的唯一入口,见下方排障实录):

== Client.SetVolume 65 ==
{
    "id": 4,
    "jsonrpc": "2.0",
    "result": {
        "volume": {
            "muted": false,
            "percent": 65
        }
    }
}
== 静音(volume.muted 置 true)==
{"id":1,"jsonrpc":"2.0","result":{"volume":{"muted":true,"percent":100}}}

Client.SetName / Client.SetLatency——命名与延迟补偿:

== Client.SetName ==
{"id":5,"jsonrpc":"2.0","result":{"name":"LivingRoom"}}
== Client.SetLatency 10 ==
{"id":6,"jsonrpc":"2.0","result":{"latency":10}}

错误示范排障实录:想当然地调用 Client.SetMute 会得到 Method not found(实测原文):

{
    "error": {
        "code": -32601,
        "message": "Method not found"
    },
    "id": 1,
    "jsonrpc": "2.0"
}

结论:JSON-RPC 23 中没有 Client.SetMute 方法,客户端静音必须走 Client.SetVolume 并把 volume.muted 置 true(见上方实测回显);组级静音用 Group.SetMute。遇到 -32601 优先核对该版本 RPC 方法名(方法集随 major 版本演进)。

6.5 Stream.* 流属性观测

流列表与属性在 Server.GetStatus 的 streams[] 中(见 6.2)。pipe/file/process 类「裸 PCM 源」canControl 为 false——没有可控制的播放器元数据;librespot/airplay/meta 源由上游暴露播放/暂停/切曲能力,属性为 true 后 Snapweb 才显示播放控制按钮。本文实测流状态:

{
    "id": "SineTest",
    "properties": {
        "canControl": false,
        "canGoNext": false,
        "canGoPrevious": false,
        "canPause": false,
        "canPlay": false,
        "canSeek": false
    },
    "status": "playing",
    "uri": {
        "raw": "pipe:///serverdata/snapfifo?chunk_ms=20&codec=pcm&name=SineTest&sampleformat=44100%3A16%3A2",
        "scheme": "pipe"
    }
}

七、日志与排障

7.1 日志出口与级别

  • 出口:--logging.sink(server)/ --logsink(client),可选 null、system、stdout、stderr、file:<路径>;systemd 托管默认 system,用 journalctl -u snapserver -f 跟踪;
  • 级别:--logging.filter(server)/ --logfilter(client),格式 <tag>:<level> 逗号组合,级别 trace/debug/info/notice/warning/error/fatal;排障临时用 *:debug,恢复 *:info。

7.2 常见日志形态速查(全部实测原文)

正常连接(客户端):

[Notice] (Connection) Connected to server
[Info] (Controller) ServerSettings - buffer: 1000, latency: 0, volume: 100, muted: 0
[Info] (Controller) diff to server [ms]: -0.001

正常启动(服务器,输出节选):

[Info] (Snapserver) Version 0.35.0, revision f1237347
[Info] (Snapserver) Adding source: pipe:///serverdata/snapfifo?name=SineTest&sampleformat=44100:16:2
[Info] (PipeStream) PipeStream mode: create
[Info] (StreamServer) Creating TCP stream acceptor for address: ::, port: 1704
[Info] (ControlServer) Creating TCP control acceptor for address: ::, port: 1705
[Info] (ControlServer) Creating HTTP acceptor for address: ::, port: 1780

mDNS 不可用(无 avahi 守护进程环境,不影响 TCP 直连):

[Error] (Avahi) Failed to create client: Daemon not running

源无数据(pipe 写端断开/未启动):

[Info] (Stream) No chunks available
[Info] (Alsa) Failed to get chunk

缓冲告警(网络抖动或 buffer 过小):

[Info] (Stream) abs(age > 500): 559969

7.3 排障实录

实录一:pipe 写端 BrokenPipe

现象:宿主侧 PCM 生成进程退出,日志报(实测原文):

Traceback (most recent call last):
  File "sine_writer.py", line 20, in <module>
    f.write(bytes(frames))
BrokenPipeError: [Errno 32] Broken pipe

定位:命名管道读端(snapserver)重启期间管道被重置,写端进程未捕获信号直接崩溃;重新拉起写端即可(数据流本身无状态)。预防:写端进程用 systemd/脚本守护或对 BrokenPipe 做重连重试。

实录二:客户端记录残留与身份漂移

现象:Server.GetStatus 出现多个 connected: false 的旧客户端记录;重启后新记录的 MAC 与旧配置对不上。定位:客户端唯一身份默认是 MAC,环境重建后 MAC 变化(实测 66:5f:2e:b8:5e:7f → 86:4c:86:eb:df:d7),旧记录残留且配置失联。解决:①稳定环境给 snapclient 显式 --hostID;②残留记录用 Server.DeleteClient 清理(6.2 实测)。

实录三:Method not found(-32601)

现象与解决见 6.4 排障实录:方法名与 RPC major 版本强相关,Client.SetMute 在 v23 不存在,静音走 Client.SetVolume 的 volume.muted。

八、注意事项

  1. 服务器与客户端必须同大版本部署(协议版本随 Release 演进,本文实测双方均为 0.35.0、协议 v2);
  2. --stream.source 可配置多行,但每行 URI 的 name 必须唯一,重名会导致源注册失败;
  3. JSON-RPC 改动即时生效且写入运行态,服务器重启后按 datadir 的 server.json 恢复——重要分组/音量变更前确认 datadir 已持久化;
  4. 控制面(1705/1780)默认无鉴权,公网暴露前必须配置 TLS+authorization 或防火墙限制;
  5. -d 守护模式与 systemd 托管二选一,混用会产生双进程抢占端口。

九、常见问题

Q1:snapclient 连不上服务器? 按序检查:ss -lntp | grep -E '1704|1705|1780' 确认服务器三端口监听;客户端 url 的 IP/端口正确;防火墙放行 1704;客户端日志若停在 Resolving host IP 则是 DNS/主机名问题,改用 IP 直连。

Q2:如何只看某个模块的调试日志? filter 按 tag 过滤,例如只看流模块:snapserver --logging.filter 'Stream:debug,*:info'(tag 即日志行中的 (Stream) 名)。

Q3:Client.SetVolume 的 percent 和 muted 是同时设置吗? 是。volume 是整体对象,请求里两个都要给(省略 muted 按false 处理),返回值即设置后的完整音量状态(见 6.4 实测回显)。

Q4:批量查所有客户端的音量/延迟? 无单独列表方法,用 Server.GetStatus 一次拿全(groups[].clients[].config),脚本按 id 遍历即可。

Q5:Snapweb 打不开? 确认 /etc/snapserver.conf 的 [http] doc_root = /usr/share/snapserver/snapweb(deb 默认已带)且 http.enabled = true;访问 http://<server>:1780/ 应返回 200(实测 HTTP/1.1 200 OK、Server: Snapcast)。

十、参考链接

  1. JSON-RPC API 文档(方法全集,按 RPC 版本对照):https://github.com/snapcast/snapcast/blob/develop/doc/json_rpc_api/
  2. 官方仓库 man 手册(snapserver/snapclient):https://github.com/snapcast/snapcast/tree/develop/doc
  3. 站内相关篇目:《Snapcast 0.35.0 介绍与选型指南》、《Snapcast 0.35.0 Docker Compose 部署指南》、《Snapcast 0.35.0 配置参数详解》