Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,20 @@ for the walkthrough, including the firewall rule a server needs to reach it.

The player advertises itself on the local network and a Sendspin server finds it.
Connections are encrypted, and a server must pair with the player before it can play.
Print the token to paste into the server:
Pair it from the server, and the player shows a six-digit code to type in. Read it from
`status`:

```bash
# Linux service, as installed above
sudo sendspin-cli pair-token --control-socket /run/sendspin-cli/control.sock
sudo sendspin-cli status --control-socket /run/sendspin-cli/control.sock

# --user-service, macOS, Windows, or a player started from your own shell
sendspin-cli pair-token
sendspin-cli status
```

[Pairing a player](https://github.com/Sendspin/sendspin-cpp-cli/wiki/Pairing-a-Player)
covers that and the two code-based ways. `--allow-unpaired` lets any server on the network
play without pairing.
covers that and a fixed code you choose yourself. `--allow-unpaired` lets any server on the
network play without pairing.

## Everyday use

Expand Down
36 changes: 35 additions & 1 deletion docs/wiki/Advanced-Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ product that embeds this player and should be listed as itself.
Every connection is encrypted, and a server has to **pair** with the player before it may
play on it. A server that has not paired can still connect, but stays idle; the `trust` line
of `sendspin-cli status` reads `paired` or `unpaired` for the server connected now.
[Pairing a Player](Pairing-a-Player) walks through the three ways to pair.
[Pairing a Player](Pairing-a-Player) walks through the two ways to pair.

`--allow-unpaired` (or `allow-unpaired = true`) lets any server on the network play without
pairing. It is off by default, and the player says so once at startup:
Expand All @@ -262,6 +262,40 @@ pairing. It is off by default, and the player says so once at startup:
I cli: A server must pair with this player before it can play -- pass --allow-unpaired to let any server play
```

### Pairing from another system

The pairing token is for a system that pairs the player on your behalf, such as a script or
a platform that sets players up through a server's API. To pair by hand, use
[a code](Pairing-a-Player) instead.

The token carries this player's identity and a pairing secret in one `SP:…` string. Print
it on the player's host:

```console
$ sendspin-cli pair-token
SP:0TNMH6…
```

A server given the token connects and pairs with no further step on the player:

```
I cli: Pairing started with server lhYYqOOH80zi…
I cli: Paired with server lhYYqOOH80zi…
I cli: Connected server is paired
```

The token is the same every time, across restarts, for as long as the
[state file](Configuration#the-state-file) is kept. While no server is paired the player
also logs it once at startup, to the terminal or the journal, never to a `--logfile`:

```console
$ journalctl -u sendspin-cli | grep 'Pairing token'
```

**Treat the token like a password.** Anyone who has it can pair a server with this player.
It stops being logged once a server is paired, and it works whichever code method the player
offers.

## Stream hooks

`--hook-start` and `--hook-stop` run a shell command when a stream starts or stops,
Expand Down
2 changes: 1 addition & 1 deletion docs/wiki/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ already does that.
| `allow-unpaired` | `--allow-unpaired` | `true`/`false` — let a server that has not paired with this player play on it | `false` |
| `fixed-volume` | `--fixed-volume` | `true`/`false` — play at full volume, unmuted, and offer the server neither volume nor mute, for an output whose level is set elsewhere (a line-out into an amplifier). A remembered volume is kept but ignored, and returns once the key is dropped | `false` |
| `release-device` | `--release-device` | `true`/`false` — close the output device at each stream end and reopen it at the next stream start, for an exclusive device such as an ALSA `hw:` DAC shared with other players (Squeezelite, AirPlay, Spotify). The trade-off: another app can take the device between streams, and the next stream is then discarded; each stream also pays a fresh open. ALSA and PortAudio only; other backends ignore it | `false` |
| `pairing-code` | `--pairing-code` | exactly 8 digits — a static code a server can pair with, confirmed each time with `sendspin-cli pair confirm`; replaces the 6-digit code the player otherwise shows. See [Pairing a Player](Pairing-a-Player#3-static-code) | none |
| `pairing-code` | `--pairing-code` | exactly 8 digits — a static code a server can pair with, confirmed each time with `sendspin-cli pair confirm`; replaces the 6-digit code the player otherwise shows. See [Pairing a Player](Pairing-a-Player#2-static-code) | none |
| `no-mdns` | `--no-mdns` | `true`/`false` — do not advertise `_sendspin._tcp` | `false` |
| `mdns-name` | `--mdns-name` | the instance label to advertise, when it should differ from `name` | `name` |
| `control-socket` | `--control-socket` | the Unix socket the subcommands talk to | `$XDG_RUNTIME_DIR/sendspin-cli-<port>.sock` |
Expand Down
3 changes: 2 additions & 1 deletion docs/wiki/Controlling-the-Player.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ is also what lets `seek-rel -5000` be an offset rather than a flag cluster.

Twelve of those go out to the server as `controller@v1` commands. Four never leave the host:
`status`, formatted from the daemon's own view, `delay`, which drives this endpoint's own
player role, and `pair-token` and `pair`, which are [Pairing a Player](Pairing-a-Player).
player role, `pair`, which is [Pairing a Player](Pairing-a-Player), and `pair-token`, which is
[Pairing from another system](Advanced-Usage#pairing-from-another-system).

## Three that are easy to misread

Expand Down
2 changes: 1 addition & 1 deletion docs/wiki/Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ every other player in the group.
| [Getting Started on a Raspberry Pi](Getting-Started-on-a-Raspberry-Pi) | The same script, plus what a Pi does differently |
| [Installation](Installation) | Every way in: release archive, macOS `.pkg`, source |
| [Configuration](Configuration) | The config file, and what the player remembers by itself |
| [Pairing a Player](Pairing-a-Player) | Letting a server play: the token, the dynamic code and the static code |
| [Pairing a Player](Pairing-a-Player) | Letting a server play: the dynamic code and the static code |
| [Controlling the Player](Controlling-the-Player) | `sendspin-cli pause` and the other fifteen subcommands |
| [Running as a Service](Running-as-a-Service) | The systemd unit, the account it runs as, drop-ins, and reading the log |
| [Advanced Usage](Advanced-Usage) | Connection modes, output selection, logging, buffering, and stream hooks |
Expand Down
52 changes: 10 additions & 42 deletions docs/wiki/Pairing-a-Player.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ play on it. Pairing is done once per server: the player remembers it in its
[state file](Configuration#the-state-file), and from then on that server just
connects and plays.

There are three ways to pair. All of them work from a terminal on the player's own host,
and all of them end the same way:
There are two ways to pair. Both work from a terminal on the player's own host, and both
end the same way:

```console
$ sendspin-cli status | grep -E '^(trust|pairing)'
Expand All @@ -16,46 +16,14 @@ pairing: none

| Method | You carry to the server | Player setup | Use it when |
|---|---|---|---|
| [Pairing token](#1-pairing-token) | a long `SP:…` string, pasted | none | you can copy and paste between the player and the server |
| [Dynamic code](#2-dynamic-code) | 6 digits, fresh each attempt | none | you can read the player's log or run `status` while pairing |
| [Static code](#3-static-code) | 8 digits you chose | `pairing-code` | you want a code written down ahead of time, e.g. on a label |
| [Dynamic code](#1-dynamic-code) | 6 digits, fresh each attempt | none | you can read the player's log or run `status` while pairing. This is the default |
| [Static code](#2-static-code) | 8 digits you chose | `pairing-code` | you want a code written down ahead of time, e.g. on a label |

Where a step says "in the server", it means the server's own screen for adding or pairing a
player; the wording differs from server to server.
player; the wording differs from server to server. To pair from a script or another system
instead, see [the pairing token](Advanced-Usage#pairing-from-another-system).

## 1. Pairing token

The token carries this player's identity and a pairing secret in one string.

1. Print it on the player's host:

```console
$ sendspin-cli pair-token
SP:0TNMH6…
```

2. In the server, choose to pair with a token and paste it.

The server connects and pairs with no further step on the player:

```
I cli: Pairing started with server lhYYqOOH80zi…
I cli: Paired with server lhYYqOOH80zi…
I cli: Connected server is paired
```

The token is the same every time, across restarts, for as long as the state file is kept.
While no server is paired the player also logs it once at startup — to the terminal or the
journal, never to a `--logfile` — so on a fresh service it is in the journal:

```console
$ journalctl -u sendspin-cli | grep 'Pairing token'
```

**Treat the token like a password.** Anyone who has it can pair a server with this player.
It stops being logged once a server is paired.

## 2. Dynamic code
## 1. Dynamic code

The player makes up a 6-digit code for each attempt and shows it to you; you type it into
the server.
Expand All @@ -79,7 +47,7 @@ The code is withdrawn when the attempt ends, whichever way it ends. After repeat
codes the player holds further attempts back until you run `sendspin-cli pair confirm` (see
[the pairing window](#the-pairing-window)).

## 3. Static code
## 2. Static code

A code you choose once, for a player you cannot easily read a fresh code from.

Expand Down Expand Up @@ -107,7 +75,7 @@ A code you choose once, for a player you cannot easily read a fresh code from.

A static code never changes, so every attempt with it needs that `pair confirm`: the code
alone does not let a server in. A player with a static code offers it **instead of** the
dynamic code; the pairing token keeps working either way.
dynamic code.

## The pairing window

Expand All @@ -133,7 +101,7 @@ A failed attempt is logged with its reason:
W cli: Pairing with server wn_sX1iDNhQ… failed: the pairing code did not match
```

- **`sendspin-cli pair-token` says nothing is listening** — the player is not running, or it
- **`sendspin-cli status` says nothing is listening** — the player is not running, or it
runs on another `--port`; see [Finding the socket](Controlling-the-Player#finding-the-socket).
- **The player forgets its pairings on every restart** — it has no state directory. See
[Running as a Service](Running-as-a-Service).
Expand Down
Loading