better descriptions
This commit is contained in:
@@ -8,14 +8,70 @@
|
||||
rkt-web-player/users))
|
||||
|
||||
@title{RKT Web Player}
|
||||
@author{Hans van Dijkema}
|
||||
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
|
||||
|
||||
@defmodule[rkt-web-player]
|
||||
|
||||
RKT Web Player combines local playback through @tt{racket-audio}
|
||||
with UPnP and Sonos discovery and playback through
|
||||
@tt{racket-audio-dlna}. The user interface is served to a web
|
||||
browser by Racket's web server.
|
||||
RKT Web Player is a central music server for a trusted network. It makes one
|
||||
or more configured music libraries available through a web interface and
|
||||
plays that music on different kinds of renderers: the server's own audio
|
||||
device, UPnP devices, Sonos groups, and player agents. The package also
|
||||
provides those player agents as GUI and headless CLI applications, so a
|
||||
computer without UPnP support can become a network renderer of its own. The
|
||||
central server and each agent communicate over HTTP; the agent downloads its
|
||||
assigned tracks and plays them on its local audio device.
|
||||
|
||||
@section{What the player provides}
|
||||
|
||||
The central server is the heart of the application. Its main features are:
|
||||
|
||||
@itemlist[
|
||||
@item{Multiple named music libraries, including local and UNC/network paths.}
|
||||
@item{Lazy directory browsing: startup reads only the library roots, while
|
||||
recursive contents and audio metadata are read when needed.}
|
||||
@item{Playback of the central library through the server's local audio
|
||||
device, discovered UPnP renderers, Sonos groups, or registered agents.}
|
||||
@item{Playlist tabs with adding, removing, reordering, renaming and
|
||||
drag-and-drop support. Tracks from different libraries can share a
|
||||
playlist.}
|
||||
@item{Gapless network playback where the renderer or playback agent supports
|
||||
preloading the next track, with a server-side fallback.}
|
||||
@item{Transport controls, seeking, volume, repeat mode and live playback
|
||||
status.}
|
||||
@item{Embedded album art and adjacent @tt{cover}, @tt{folder} and
|
||||
@tt{front} JPEG/PNG artwork.}
|
||||
@item{Per-user playlists, language preference and playback pipeline, with
|
||||
shared physical outputs that can be transferred between users.}
|
||||
@item{Dutch, English, German, French, Spanish, Italian, Swedish, Norwegian,
|
||||
Finnish and Icelandic interfaces.}
|
||||
@item{Optional Argon2id browser authentication and a separate default-deny
|
||||
allowlist for playback agents.}
|
||||
]
|
||||
|
||||
The browser is a thin remote control, not a second player. It polls a complete
|
||||
JSON state snapshot once per second and sends commands to the central server;
|
||||
playlists, preferences and playback state are kept there. The server exposes
|
||||
the browser application under the root URL and its JSON API under @tt{/api}.
|
||||
The API includes state, discovery, playback commands, preferences, artwork and
|
||||
the agent registration, polling and media routes.
|
||||
|
||||
@subsection{Player agents}
|
||||
|
||||
A player agent is an additional renderer implemented by this package. It runs
|
||||
on a computer connected to speakers, registers with the central server, polls
|
||||
for commands, downloads the selected music and plays it locally. Agents do not
|
||||
open an inbound network port. The package supplies two forms:
|
||||
|
||||
@itemlist[
|
||||
@item{The GUI agent, with a desktop window and system-tray integration.}
|
||||
@item{The headless CLI agent, suitable for a small always-on computer or a
|
||||
machine without a graphical desktop.}
|
||||
]
|
||||
|
||||
The server treats each registered agent as an output alongside UPnP and Sonos
|
||||
renderers. The server can prefetch the next track to an agent for gapless
|
||||
transitions. A 256-bit application ID identifies the agent; the server's
|
||||
@tt{[playback-agents]} allowlist decides which agents may connect.
|
||||
|
||||
@defproc[(run-web-player
|
||||
[music-paths (listof (or/c path-string?
|
||||
@@ -29,7 +85,10 @@ browser by Racket's web server.
|
||||
[#:dlna-port dlna-port exact-positive-integer? 8734]
|
||||
[#:local-output? local-output? boolean? #t]
|
||||
[#:playlist-keystore playlist-keystore (or/c path-string? #f)]
|
||||
[#:launch-browser? launch-browser? boolean? #t]) any/c] {
|
||||
[#:log-file log-file path-string?]
|
||||
[#:log-retention-days log-retention-days exact-positive-integer? 7]
|
||||
[#:log-level log-level symbol? 'debug]
|
||||
[#:launch-browser? launch-browser? boolean? #t]) any/c]{
|
||||
|
||||
Treats every entry in @racket[music-paths] as a separate music library. A
|
||||
two-element list supplies an explicit display name and path. The
|
||||
@@ -60,10 +119,127 @@ Sessions have a sliding idle timeout; an active browser cookie is renewed once
|
||||
half of @racket[session-seconds] has elapsed. Playback-agent endpoints continue
|
||||
to use their separate application-ID allowlist.
|
||||
|
||||
Logging is written to @racket[log-file]. Files are rotated after
|
||||
@racket[log-retention-days] days, and @racket[log-level] selects the
|
||||
@tt{simple-log} level. The default log file is
|
||||
@tt{data/rkt-web-player.log} below the installed collection. The
|
||||
@racket[playlist-keystore], @racket[log-file] and @racket[log-level] arguments
|
||||
are useful when embedding the player; the command-line entry point can also
|
||||
read these values from an INI file.
|
||||
|
||||
The default listen address only exposes the interface to the local computer.
|
||||
Use a LAN address deliberately if other devices should control the player.
|
||||
}
|
||||
|
||||
@section{Command line and INI configuration}
|
||||
|
||||
The package entry point accepts one or more music directories:
|
||||
|
||||
@verbatim{
|
||||
racket main.rkt MUSIC-DIRECTORY [...]
|
||||
racket main.rkt --config rkt-web-player.ini --no-browser
|
||||
}
|
||||
|
||||
The @tt{--config} option reads defaults from an INI file. The file is normally
|
||||
named @tt{rkt-web-player.ini} and is read from the current directory when the
|
||||
server is started with @tt{--config}. Relative paths are interpreted in the
|
||||
process's working directory.
|
||||
|
||||
Command-line values for @tt{--listen-ip}, @tt{--port}, @tt{--dlna-port},
|
||||
@tt{--playlist-keystore}, @tt{--log-file} and @tt{--no-browser} override the
|
||||
corresponding defaults. Logging retention, log level, authentication and the
|
||||
playback-agent allowlist are configured in the INI file. Libraries configured
|
||||
under @tt{[libraries]} use the INI key as their display name and the value as
|
||||
the root directory. The legacy @tt{[library] paths} setting accepts a
|
||||
semicolon-separated list and is also supported. A complete example is:
|
||||
|
||||
@verbatim{
|
||||
[server]
|
||||
listen-ip=127.0.0.1
|
||||
port=8080
|
||||
|
||||
[player]
|
||||
dlna-port=8734
|
||||
local-output=true
|
||||
playlist-keystore=data/playlists.keystore
|
||||
|
||||
[logging]
|
||||
log-file=data/rkt-web-player.log
|
||||
log-retention-days=7
|
||||
log-level=debug
|
||||
|
||||
[authentication]
|
||||
trusted-proxies=127.0.0.0/8;::1/128
|
||||
session-seconds=604800
|
||||
|
||||
[playback-agents]
|
||||
; 64 hexadecimal characters, copied from an agent
|
||||
0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef=true
|
||||
|
||||
[users]
|
||||
; Generate hashes with make-password-hash or set-user.
|
||||
hans=$argon2id$v=19$m=19456,t=2,p=1$...
|
||||
}
|
||||
|
||||
The @tt{[server]} section controls the browser server. The default
|
||||
@tt{listen-ip} is @tt{127.0.0.1}, so the interface is local-only by default;
|
||||
@tt{0.0.0.0} or a LAN address makes it reachable from other machines.
|
||||
@tt{port} defaults to @tt{8080}.
|
||||
|
||||
The @tt{[player]} section controls playback. @tt{dlna-port} defaults to
|
||||
@tt{8734} and must be reachable by network renderers when they play files
|
||||
published by the server. @tt{local-output=true} (the default) adds the
|
||||
server's own audio device as an output. @tt{playlist-keystore} selects the
|
||||
keystore for playlist tabs and language preferences; omission uses
|
||||
@tt{data/playlists.keystore} below the installed collection. When embedding
|
||||
the player through @racket[run-web-player], passing @racket[#f] disables
|
||||
persistence.
|
||||
|
||||
The @tt{[logging]} section controls the rotating log file. The default file is
|
||||
@tt{data/rkt-web-player.log}, retention defaults to seven days, and the default
|
||||
level is @tt{debug}. The level is passed to @tt{simple-log}; use a level
|
||||
supported by that package.
|
||||
|
||||
The @tt{[playback-agents]} section is a default-deny allowlist. Each key must
|
||||
be the complete 64-character hexadecimal application ID of an agent and a
|
||||
value other than @tt{false} permits registration. An empty section rejects all
|
||||
agents. This ID is a shared bearer credential, not a replacement for HTTPS.
|
||||
|
||||
The @tt{[authentication]} section enables browser login when @tt{[users]} has
|
||||
at least one entry. Each user value is an Argon2id hash, not a plaintext
|
||||
password. @tt{session-seconds} defaults to seven days and is a sliding idle
|
||||
timeout. @tt{trusted-proxies} is a semicolon-separated list of IP addresses or
|
||||
CIDR ranges whose forwarded client address may be trusted; keep it limited to
|
||||
the actual reverse proxy. The application does not terminate TLS, so use
|
||||
HTTPS at the reverse proxy before exposing an authenticated instance beyond a
|
||||
trusted LAN.
|
||||
|
||||
Create a password hash with @racket[make-password-hash], or run
|
||||
@racket[set-user] in the directory containing the INI file. The
|
||||
@racket[set-user] procedure updates @tt{rkt-web-player.ini} interactively.
|
||||
|
||||
@subsection{Playback-agent INI file}
|
||||
|
||||
The GUI and CLI agents use a separate private INI file named
|
||||
@tt{rkt-web-player-agent.ini} in the user's Racket configuration directory.
|
||||
It contains the following values:
|
||||
|
||||
@verbatim{
|
||||
[server]
|
||||
url=http://127.0.0.1:8080
|
||||
|
||||
[agent]
|
||||
name=My playback
|
||||
app-id=64 hexadecimal characters
|
||||
}
|
||||
|
||||
The agent generates @tt{app-id} once and reuses it so the server allowlist
|
||||
continues to work. The GUI writes the server URL and display name; the CLI can
|
||||
override them with @tt{--server} and @tt{--name}. Use @tt{--config} with the
|
||||
CLI to select another agent INI file and therefore another identity. Agents
|
||||
make only outbound HTTP requests: they register and poll the server, download
|
||||
assigned tracks, and play them locally. They do not open an inbound port.
|
||||
|
||||
@defmodule[rkt-web-player/users]
|
||||
|
||||
@defproc[(make-password-hash [password string?]) string?] {
|
||||
|
||||
Reference in New Issue
Block a user