77 lines
7.9 KiB
Markdown
77 lines
7.9 KiB
Markdown
Protocol
|
|
========
|
|
|
|
This document describes the workflows of the software.
|
|
|
|
Preliminaries
|
|
-------------
|
|
|
|
- **Song**: A reference to the file containing the audio and video. Can be separated into two files (e.g. mp3+cdg) or a link (e.g. a YouTube link)
|
|
- **Source**: A collection of _songs_, that can be searched and played back from. (e.g. a folder, a s3 storage or YouTube)
|
|
- **Performer**: The person(s) doing the actual singing
|
|
- **Entry**: A _song_ together with a _performer_
|
|
- **Queue**: A list of _entries_. Once the first entry is completely played back, the next entry is played.
|
|
- **Waiting Room**: A list of _entries_. To limit one performer filling the entire _queue_, a waiting room can be configured. If so, each performer can only have one entry in the queue. Each additional entry is put in the waiting room. Once the last entry of a performer left the queue, the first entry of that performer in the waiting room is added at the end of the queue.
|
|
- **Recents**: A list of _entries_. Once an entry successfully leaves the _queue_, it is added to the recents.
|
|
- **Playback client**: Part of the software, that does the actual playback, usually hooked to a video output device like a monitor or a projector. This needs to have access to the configured sources.
|
|
- **Web client**: User facing part of the software. Used to search and add _entries_ to the _queue_. Has an admin view to manipulate the queue and the _waiting room_.
|
|
- **Room**: One specific karaoke event, consisting of one _queue_, one _recents_, up to one _waiting room_, one _playback client_ and several _web clients_. It has an identifier and a _secret_, used to authenticate as an admin.
|
|
- **Server**: Manages all _rooms_.
|
|
|
|
We will use the abbreviations _P_, _W_, and _S_ when talking about the _playback client_, _web client_ and the _server_.
|
|
|
|
Communication usually happens between P ↔ S and W ↔ S and as messages on top of web sockets, using [socket.io](https://socket.io/docs/v4/client-api/).
|
|
|
|
### Entry
|
|
|
|
Entries are regularly sent between all participants and are encoded in JSON as follows:
|
|
|
|
| Key | Type | Description | Optional |
|
|
|----------|-------|----------------------------------------------------------------------------------|------------------------------------------|
|
|
| ident | `str` | Identifier for the entry in its given source. E.g. a file name or a YouTube Link | No |
|
|
| source | `str` | Name of the source (`files`, `s3`, `youtube`, etc.) | No |
|
|
| duration | `int` | Duration of the song | No |
|
|
| title | `str` | Name of the song | No |
|
|
| artist | `str` | Artist of the original song | No |
|
|
| album | `str` | Name of the collection this song belongs to | No |
|
|
| uuid | `str` | A UUID for this entry | Yes (generated automatically if omitted) |
|
|
|
|
### Client Config
|
|
|
|
A client config specifies the knowlege the server has of a specific playback client.
|
|
|
|
| Key | Type | Description | Optional | Default |
|
|
|---------------------|------|----------------------------------------------------------------------------------------------------------|----------|--------------------------|
|
|
| server | str | URL of the server | Yes | `https://localhost:8080` |
|
|
| room | str | Identifier of the room the client wants to connect to | Yes | Generated by the server |
|
|
| secret | str | The secret for the room | No | |
|
|
| preview_duration | int | Time between songs, where a preview is shown for the next song | Yes | 3 |
|
|
| last_song | int | Unix timestamp of the last song allowed to be played | Yes | None |
|
|
| waiting_room_policy | str | `forced` if waiting room is forced, `optional` if performers are given the choice, `None` if deactivated | Yes | None |
|
|
|
|
Workflow
|
|
--------
|
|
|
|
### Connect P ↔ S
|
|
|
|
When a playback client connects to a server, it can provide a room identifier and a room secret.
|
|
If none are given, the server will generate both and send them to the client.
|
|
If the server does not know a room with that identifier, a new room is created with the given secret.
|
|
The client sends its initial configuration to the server (including an initial possible empty queue, waiting room and recent list),
|
|
and the configuration of each configured source.
|
|
If the server has already registered a room with the given identifier, if the secret is the same, the connection to the new playback client is stored and the old connection is forgotten.
|
|
The server-side config is updated with the values of the new client.
|
|
|
|
The following messages are exchanged during connection:
|
|
|
|
- **Direction:** P -> S, **Message**: `connect`, **Parameters** None
|
|
Socket.io connect
|
|
|
|
| Communication | Message | Params | Notes |
|
|
|---------------|---------------------|-------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
| P → S | `connect` | -- | Socket.io connect |
|
|
| S → P | `connect` | -- | Socket.io connect |
|
|
| P → S | `register-client` | `{ queue: list[Entry], waiting_room: list[Entry], recents: list[Entry], config: Config }` | The playback client can push an initial queue, waiting_room and recents to the server. |
|
|
| S -> P | `client-registered` | `{ success: bool, room: str }` | sucess is `true` if requested room is not in use or secrets match, otherwise `false`. The server confirms the room name, if it was requested in `register-client`, otherwise a new room name is returned |
|
|
| S -> P | `state` | `{ queue: list[Entry], waiting_room: list[Entry], recents: list[Entry], config: Config}` | The server returns
|
|
|