updating readme

This commit is contained in:
evilchili 2024-03-05 22:51:04 -08:00
parent 5f4418bbf6
commit affcf2d7dc
4 changed files with 42 additions and 48 deletions

View File

@ -1,13 +1,13 @@
# Croaker # Croaker
A command-and-control web application for icecast / liquidaudio, with helpers for D&D session music.
A shoutcast audio playlist designed for serving D&D session music.
## What? Why? ## What? Why?
Because I run an online D&D game, which includes a background music stream for my players. The stream is controlled by a bunch of bash scripts I cobbled together which are functional but brittle. Also, this currently requires me to have a terminal window open to my media server to control liquidsoap directly, and I'd rather integrate the music controls directly with the rest of my DM tools, all of which run on my laptop. A web-based commmand-and-control app lets me use vanilla HTTP requests to control liquidsoap. Because I run an online D&D game, which includes a background music stream for my players. The stream used to be served by liquidsoap and controlled by a bunch of bash scripts I cobbled together which are functional but brittle, and liquidsoap is a nightmare for the small use case. Also, this currently requires me to have a terminal window open to my media server to control liquidsoap directly, and I'd rather integrate the music controls directly with the rest of my DM tools, all of which run on my laptop.
*Now that is a powerful yak! -- Aesop Rock (misquoted)* *Now that is a powerful yak! -- Aesop Rock (misquoted)*
## Quick Start (Server) ## Quick Start (Server)
This assumes you have a functioning icecast2 installation already. This assumes you have a functioning icecast2 installation already.
@ -24,34 +24,44 @@ This assumes you have a functioning icecast2 installation already.
Now start the server, which will begin streaming the `session_start` playlist: Now start the server, which will begin streaming the `session_start` playlist:
``` ```
% croaker server start % croaker start
Daemonizing webserver on http://0.0.0.0:8003, pidfile and output in ~/.dnd/croaker INFO Daemonizing controller on (localhost, 8003); pidfile and logs in ~/.dnd/croaker
``` ```
## Quick Start (Client) Connnect to the command & control server:
``` ```
% mkdir -p ~/.dnd/croaker % telnet localhost 8003
% croaker setup > ~/.dnd/croaker/defaults # only the client config is required Trying 127.0.0.1...
% vi ~/.dnd/croaker/defaults # adjust to taste Connected to croaker.local.
Escape character is '^]'.
HELP
PLAY $PLAYLIST_NAME - Switch to the specified playlist.
FFWD - Skip to the next track in the playlist.
HELP - Display command help.
KTHX - Close the current connection.
STOP - Stop Croaker.
OK
``` ```
Switch to battle music -- roll initiative! Switch to battle music -- roll initiative!
``` ```
% croaker play battle PLAY battle
OK OK
``` ```
Skip this track and move on to the next: Skip this track and move on to the next:
``` ```
% croaker skip FFWD
OK OK
``` ```
Stop the server: Stop the server:
``` ```
% croaker stop STOP
OK Shutting down.
Connection closed by foreign host.
``` ```

View File

@ -19,25 +19,18 @@ SETUP_HELP = """
# Root directory for croaker configuration and logs. See also croaker --root. # Root directory for croaker configuration and logs. See also croaker --root.
CROAKER_ROOT=~/.dnd/croaker CROAKER_ROOT=~/.dnd/croaker
## COMMAND AND CONTROL WEBSERVER
# Please make sure you set SECRET_KEY in your environment if you are running
# the command and control webserver. Clients do not need this.
SECRET_KEY=
# Where the record the webserver daemon's PID
PIDFILE=~/.dnd/croaker/croaker.pid
HOST=0.0.0.0
PORT=8003
## MEDIA
# where to store playlist sources # where to store playlist sources
PLAYLIST_ROOT=~/.dnd/croaker/playlists #PLAYLIST_ROOT=$CROAKER_ROOT/playlists
# where to cache transcoded media files # where to cache transcoded media files
CACHE_ROOT=~/.dnd/croaker/cache #CACHE_ROOT=$CROAKER_ROOT/cache
# Where the record the daemon's PID
#PIDFILE=$CROAKER_ROOT/croaker.pid
# Command and Control TCP Server bind address
HOST=0.0.0.0
PORT=8003
# the kinds of files to add to playlists # the kinds of files to add to playlists
MEDIA_GLOB=*.mp3,*.flac,*.m4a MEDIA_GLOB=*.mp3,*.flac,*.m4a
@ -47,11 +40,6 @@ MEDIA_GLOB=*.mp3,*.flac,*.m4a
# the cached output location, respectively. # the cached output location, respectively.
TRANSCODER=/usr/bin/ffmpeg -i INFILE '-hide_banner -loglevel error -codec:v copy -codec:a libmp3lame -q:a 2' OUTFILE TRANSCODER=/usr/bin/ffmpeg -i INFILE '-hide_banner -loglevel error -codec:v copy -codec:a libmp3lame -q:a 2' OUTFILE
## LIQUIDSOAP AND ICECAST
# The liquidsoap executable
LIQUIDSOAP=/usr/bin/liquidsoap
# Icecast2 configuration for Liquidsoap # Icecast2 configuration for Liquidsoap
ICECAST_PASSWORD= ICECAST_PASSWORD=
ICECAST_MOUNT= ICECAST_MOUNT=
@ -108,13 +96,11 @@ def setup(context: typer.Context):
@app.command() @app.command()
def start( def start(
context: typer.Context, context: typer.Context,
daemonize: bool = typer.Option(True, help="Daemonize the webserver."), daemonize: bool = typer.Option(True, help="Daemonize the server."),
): ):
""" """
Start the Croaker command and control webserver. Start the Croaker command and control server.
""" """
logger.debug("Switching to session_start playlist...")
logger.debug("Starting server...")
if daemonize: if daemonize:
server.daemonize() server.daemonize()
else: else:
@ -124,7 +110,7 @@ def start(
@app.command() @app.command()
def stop(): def stop():
""" """
Terminate the webserver process and liquidsoap. Terminate the server.
""" """
server.stop() server.stop()

View File

@ -10,15 +10,10 @@ def root():
def cache_root(): def cache_root():
path = Path(os.environ.get("CACHE_ROOT", root() / Path("cache"))).expanduser() path = Path(os.environ.get("CACHE_ROOT", root() / "cache")).expanduser()
return path return path
def playlist_root(): def playlist_root():
path = Path(os.environ.get("PLAYLIST_ROOT", root() / Path("playlsits"))).expanduser() path = Path(os.environ.get("PLAYLIST_ROOT", root() / "playlists")).expanduser()
return path
def transcoded_media(relpath):
path = cache_root() / Path(relpath + ".webm")
return path return path

View File

@ -73,9 +73,12 @@ class CroakerServer(socketserver.TCPServer):
def tell_controller(self, msg): def tell_controller(self, msg):
self._queue.put(msg) self._queue.put(msg)
def bind_address(self):
return (os.environ["HOST"], int(os.environ["PORT"]))
def daemonize(self) -> None: def daemonize(self) -> None:
logger.info(f"Daemonizing controller; pidfile and output in {path.root()}") logger.info(f"Daemonizing controller on {self.bind_address()}; pidfile and output in {path.root()}")
super().__init__((os.environ["HOST"], int(os.environ["PORT"])), RequestHandler) super().__init__(self.bind_address(), RequestHandler)
self._context.pidfile = self._pidfile() self._context.pidfile = self._pidfile()
self._context.stdout = open(path.root() / Path("croaker.out"), "wb") self._context.stdout = open(path.root() / Path("croaker.out"), "wb")