Version 2026.07.08 release. First public tagged version.
This commit is contained in:
@@ -1,444 +0,0 @@
|
||||
Skald 0.1 (unreleased):
|
||||
|
||||
* Forked from Galene after commit f718385.
|
||||
* Renamed the project, module, command, control tool, static assets, and
|
||||
documentation entrypoints from Galene to Skald.
|
||||
|
||||
Galene 1.1 (unreleased):
|
||||
|
||||
* Implemented "galenectl initial-setup".
|
||||
* Implemented global tokens.
|
||||
* Added options "-unrestricted-tokens" and "-auto-subgroups" to
|
||||
galenectl group commands.
|
||||
* Reworked the documentation.
|
||||
* Fixed a bug that could cause multiple reads of the token file.
|
||||
* Explicitly use blobs for file transfer, this should allow
|
||||
transferring files larger than available memory. This was the intent
|
||||
all along, but the spec changed behind our back.
|
||||
* Implemented support for RSA tokens. Thanks to Jean Dupouy.
|
||||
* Added support for include-inferiors in cryptographic tokens. Thanks
|
||||
to izeau.
|
||||
* Fixed an issue with the chat window and the users' list disappearing
|
||||
on mobile. Thanks to Kirill smelkov.
|
||||
* Fixed an issue that made it impossible to add a wildcard user to a
|
||||
group with no users. Thanks to Andrea Zucchelli.
|
||||
* Added some more protection against denial of service attacks. Thanks
|
||||
to Vinayak Mishra.
|
||||
|
||||
9 August 2025: Galene 1.0
|
||||
|
||||
* Upgrade to Pion v4.
|
||||
* Add support for ETags and ICE restarts to the WHIP server.
|
||||
* Implement UDP multiplexing.
|
||||
* Implement hierarchical tokens.
|
||||
* Add rotate filter; this is useful when using a mobile phone that is
|
||||
upside down as a webcam.
|
||||
* Implement /sharescreen, rename /stopshare to /unsharescreen.
|
||||
* Implement JSON templates in galenectl.
|
||||
* Make the TURN server less verbose.
|
||||
* Replace the configuration field "publicServer" with "allowOrigin" and
|
||||
"allowAdminOrigin". This is an incompatible change.
|
||||
* Fix a race condtion in the setdata request. Thanks to git-lui.
|
||||
|
||||
8 March 2025: Galene 0.96.3
|
||||
|
||||
* Change username validation to validate the effectively used username,
|
||||
which is not necessarily the same as the one typed by the user.
|
||||
Thanks to K900.
|
||||
* Allow empty usernames again, they were mistakenly disallowed in 0.96.1.
|
||||
* Reverted a change that caused the chat button to disappear on mobile.
|
||||
|
||||
21 January 2025: Galene 0.96.2
|
||||
|
||||
* Fix a bug, introduced in 0.96.1, that could cause plaintext passwords
|
||||
to be erroneously accepted even when incorrect.
|
||||
* Implement background blur on Safari.
|
||||
* Set the minimum TLS version to 1.2.
|
||||
* Change the default hashing algorithm to bcrypt. We use a cost of 8 in
|
||||
order to keep hashing times under 25ms, even though 10 is currently
|
||||
the recommended minimum.
|
||||
* Limit the number of concurrent password hashing operations to the
|
||||
number of CPUs. This avoids using excessive memory when many users
|
||||
log in at the same time.
|
||||
|
||||
18 January 2025: Galene 0.96.1
|
||||
|
||||
* Avoid path traversal in disk writer.
|
||||
* Forbid backslashes in group names on all systesm (we used to only
|
||||
forbid them on Windows). This is an incompatible change.
|
||||
* Minor restrictions on usernames: forbid usernames starting with
|
||||
a slash, forbid usernames containing the string "/.", and forbid
|
||||
backslashes. This is an incompatible change.
|
||||
* Ensure cleartext passwords are veryfied in constant time.
|
||||
* Remove "data:" from allowed image sources in CSP header.
|
||||
* Disable the unmute button before presenting. Thanks to Sacha Chua.
|
||||
* Fix PCMA audio (don't ask).
|
||||
* Update fontawesome to version 6.7.2.
|
||||
* Delay requesting microphone permissions on Safari until after
|
||||
successful login.
|
||||
|
||||
1 January 2025: Galene 0.96
|
||||
|
||||
* Implemented asynchronous filters.
|
||||
* Implemented background blur.
|
||||
* More fixes to RTCP feedback signalling (thanks to Sean DuBois).
|
||||
|
||||
4 December 2024: Galene 0.95
|
||||
|
||||
* Galene now requires Go 1.20.
|
||||
* Added "galenectl" utility and removed "galene-password-generator".
|
||||
This is an incompatible change.
|
||||
* Fixed a number of bugs in the management protocol.
|
||||
* Implemented captions for the galene-stt tool.
|
||||
* Reworked the peer-to-peer file transfer protocol. This is an
|
||||
incompatible change.
|
||||
* Added an id to every chat message, and made it possible to remove
|
||||
a single chat message.
|
||||
* Fixed a race condition that prevented operators from joining an
|
||||
AutoKick group.
|
||||
* Fixed a bug that could cause us to signal our ability to do RTCP
|
||||
feedback incorrectly.
|
||||
* Fixed a bug that would trigger JavaScript errors when a user attempted
|
||||
to send a file to themself.
|
||||
|
||||
15 July 2024: Galene 0.9.1
|
||||
|
||||
* Added an example client with minimal functionality under static/example.
|
||||
* Changed the token login to force a user interaction in order to avoid
|
||||
issues with autoplay.
|
||||
* Fixed a race condition that would cause the client to run with
|
||||
undefined settings if the initial connection was extremely fast.
|
||||
* Implemented client-side timeouts (we already had one on the server side).
|
||||
* Reduced the server-side timeout.
|
||||
* Don't attempt to set the file descriptor limit, since recent versions
|
||||
of the Go runtime do it automatically.
|
||||
|
||||
26 May 2024: Galene 0.9
|
||||
|
||||
* Reworked the group definition format to be more modular. There are
|
||||
some incompatible changes: multiple users with the same username but
|
||||
distinct passords are no longer supported, and the field
|
||||
"allow-anonymous" is ignored.
|
||||
* Reworked the definition of administrator passwords in config.json.
|
||||
The old field "admin" is ignored, a new field "users" is required.
|
||||
This is an incompatible change.
|
||||
* Implemented an administrative API over HTTP. Set the field
|
||||
"writableGroups" in config.json to enable it. The API is described in
|
||||
the file "README.API", a JavaScript library is in management.js.
|
||||
* Implemented a form to allow users to change their password. If the
|
||||
HTTP API is enabled, a link will appear in the side menu.
|
||||
* Implemented a new command "/identify" (also availble in the users
|
||||
menu) that discloses the IP address from which a user connected.
|
||||
* Implemented a contextual menu that triggers on a double click on
|
||||
a chat entry.
|
||||
* Added a new command "/stopshare".
|
||||
* Added a new permission "message" and new commands "shutup" and "unshutup".
|
||||
* Changed stateless token validation to attempt all keys rather than
|
||||
just the first matching one.
|
||||
|
||||
26 May 2024: Galene 0.8.3
|
||||
|
||||
* Fixed a bug that could allow any user to clear the chat.
|
||||
|
||||
14 April 2024: Galene 0.8.2
|
||||
|
||||
* Fixed possible crashes in the VP8 and AV1 parsers.
|
||||
* Fixed keyframe detection for VP8 and VP9.
|
||||
|
||||
9 March 2024: Galene 0.8.1
|
||||
|
||||
* Security fixes to WHIP ingress.
|
||||
* Improved error messages for authentication failures.
|
||||
* Added "expires" and "not-before" to group descriptions.
|
||||
* Allow proxyURL to contain a path, for people who run Galene at
|
||||
non-root URLs. This requires manually modifying the files under
|
||||
'static/' in order to point at the right locations.
|
||||
|
||||
25 November 2023: Galene 0.8
|
||||
|
||||
* Added a new configuration option "publicServer".
|
||||
* Implemented the WHIP protocol (draft-ietf-wish-whip).
|
||||
* Disabled simulcast on Firefox by default.
|
||||
* Removed support for protocol version 1 (used before version 0.7)
|
||||
* Worked around clients that don't set the VP9 and H.264 profiles.
|
||||
* Updated the activity detection code to work with newer browsers.
|
||||
Thanks to Jackson Vieira.
|
||||
* Constrained videos sent from a browser to use 4:3 aspect.
|
||||
* Implemented BCrypt as an alternate password encryption algorithm.
|
||||
|
||||
9 July 2023: Galene 0.7.2
|
||||
|
||||
* Improved workaround for Safari's autoplay-related mis-features.
|
||||
* Fixed minor bugs related to stateful tokens.
|
||||
|
||||
14 May 2023: Galene 0.7.1
|
||||
|
||||
* Fixed incorrect error-handling in token parsing, which could cause
|
||||
Galene to crash after receiving a mis-formatted token.
|
||||
* Implement a dialog for creating tokens.
|
||||
* Tweaked peer-to-peer file transfer to more reliably return an error
|
||||
message to the user.
|
||||
* Fixed the workaround for non-standard simulcast in older Firefox
|
||||
versions.
|
||||
|
||||
10 April 2023: Galene 0.7.0
|
||||
|
||||
* Updated the protocol version to 2. Dates are now represented in
|
||||
ISO 8601 format, and there is a new "error" field in error messages
|
||||
that contains a machine-readable identifier.
|
||||
* Implemented stateful tokens ("invitations").
|
||||
* Made more errors non-fatal, which makes it possible for the client
|
||||
to recover in more situations.
|
||||
* Reworked the progress indicator used during file transfer.
|
||||
* Added Referrer-Policy and X-Content-Type-Options headers to HTTP
|
||||
responses (Galene was already generating HTML links with the
|
||||
"noreferrer" option). Thanks to Alexandre Iooss.
|
||||
* Fixed a bug in the handling of leave messages. (The bundled client
|
||||
never sends leave, it just disconnects, so the bug never triggerred.)
|
||||
* Changed the way simulcast tracks are selected to not depend on the rid.
|
||||
|
||||
11 January 2023: Galene 0.6.2
|
||||
|
||||
* Disable simulcast for screensharing; this didn't work well with many
|
||||
browsers.
|
||||
* Fix parsing of VP8 packets with degenerate headers.
|
||||
* Fix computation of group URL when running in insecure mode.
|
||||
* Add configuration option "proxyURL", which makes it easier to run
|
||||
Galene behind a reverse proxy.
|
||||
* Disable ulimit checking on BSD systems, where our code doesn't compile.
|
||||
|
||||
7 October 2022: Galene 0.6.1
|
||||
|
||||
* Add a camera/microphone indicator in the users list, and hide
|
||||
audio-only peers by default. They can be reenabled in the side menu.
|
||||
* Ensure that autolocked groups are locked on creation. Thanks to
|
||||
Michael Ströder.
|
||||
* Don't send chat history multiple times. Thanks to Rémy Nollet.
|
||||
* Fix status display for remote (redirected) groups.
|
||||
|
||||
10 September 2022: Galene 0.6
|
||||
|
||||
* Version the protocol: the handshake message now contains a version
|
||||
number, and the server will warn if it is incorrect. This will become
|
||||
a hard error in the future.
|
||||
* Rework the peer-to-peer file transfer protocol. It now lives in
|
||||
protocol.js, which makes it easy to use by third-party clients.
|
||||
* Extend the authorization protocol to allow the authorization server to
|
||||
request that the client fall back to password authorization.
|
||||
* Make it possible to run the web server on a Unix domain socket.
|
||||
Thanks to Martin Pépin.
|
||||
* Check that a given group exists before redirecting from the landing
|
||||
page. This avoids an unsightly 404 error when the user makes a typo.
|
||||
* Publish the group name end websocket endpoint in the group status.
|
||||
This avoids hardwirint the server structure in the client.
|
||||
* Fix a race condition that could cause chathistory messages to be sent
|
||||
before the joined status.
|
||||
|
||||
23 July 2022: Galene 0.5.5
|
||||
|
||||
* Fix a longstanding bug with time conversion that would occasionally
|
||||
cause us to miscalculate rates and send incorrect sender reports.
|
||||
Thanks to lamhai1401.
|
||||
* Update srtp to a version that includes Adrian Cable's optimisations.
|
||||
This should yield a 10% to 20% improvement for AES-CTR (but modern
|
||||
browsers use GCM).
|
||||
* Reword the Safari warning to be more frightening, since screensharing
|
||||
on Safari tends to get stuck.
|
||||
|
||||
5 May 2022: Galene 0.5.4
|
||||
|
||||
* Fix username check when a token is present.
|
||||
* Improve the performance of AES in CTR mode.
|
||||
* Tweak detection of keyframes with H.264.
|
||||
|
||||
25 April 2022: Galene 0.5.3
|
||||
|
||||
* Remove a forgotten "replace" that prevented 0.5.2 from compiling
|
||||
unless "pion/ice" was downloaded manually.
|
||||
* Fix a race condition in the rate estimator.
|
||||
* Update pion/ice to a version that handles aggressive nomination; this
|
||||
avoids broken connection in some (fairly rare) cases.
|
||||
|
||||
20 April 2022: Galene 0.5.2
|
||||
|
||||
* Implement audio-video sync in the diskwriter.
|
||||
* Fix setting of the keyframe flag in audio samples in diskwriter.
|
||||
* Don't use high-quality audio for screenshare by default, obey the
|
||||
hqaudio preference in all cases.
|
||||
* Maintain user information for oneself, not just other users.
|
||||
* Call the onuser callback when a user deletes a stream.
|
||||
|
||||
25 March 2022: Galene 0.5.1
|
||||
|
||||
* Enable simulcast on Firefox.
|
||||
* Fix rate control on Firefox.
|
||||
* Fix corruption after packet reordering when saving to disk.
|
||||
* Fix the H.264 profile for compatibility with older iPhones.
|
||||
* Display a warning when joining a locked group.
|
||||
* Add a hook that allows the client to influence the ICE policy.
|
||||
* Fix error handling in peer-to-peer file transfer.
|
||||
|
||||
8 March 2022: Galene 0.5
|
||||
|
||||
* Implement third-party (token-based) authentication.
|
||||
* Implement peer-to-peer file transfer (/sendfile).
|
||||
* Add a contextual menu to the users list.
|
||||
* Removed the "Broadcast file" entry in the side menu, it is now
|
||||
available as a context menu entry and a chat command (/presentfile).
|
||||
* Add side-menu options for high-quality audio (Opus at 128kbps) and
|
||||
disabling audio preprocessing.
|
||||
* Send audio in addition to video when sharing browser tabs.
|
||||
|
||||
1 February 2022: Galene 0.4.4
|
||||
|
||||
* Update dependencies. Pion WebRTC v3.1.19 fixes a bug that could cause
|
||||
audio tracks to be discarded under some circumstances.
|
||||
* Fix a bug that could cause user statuses (raisehand) to be discarded.
|
||||
* Fix incorrect maxRate value in statistics display.
|
||||
|
||||
27 January 2022: Galène 0.4.3
|
||||
|
||||
* Fix a locking issue that could cause a deadlock when massive numbers
|
||||
of clients join at the same time.
|
||||
* Add support for displaying raised hands (thanks to Sascha Silbe).
|
||||
* Update the MIME type for AV1 to track recent browsers.
|
||||
* Avoid overflow during rate estimation.
|
||||
* More fixes to the disk writer.
|
||||
|
||||
1 December 2021: Galène 0.4.2
|
||||
|
||||
* Update the samplebuilder to avoid a crash when a single frame is so
|
||||
large that it overflows the buffer.
|
||||
* Various other changes that improve the quality of disk recordings.
|
||||
|
||||
4 November 2021: Galène 0.4.1
|
||||
|
||||
* Create a new file data/config.json with global configuration.
|
||||
* Remove data/passwd and the -redirect option with entries in config.json;
|
||||
these are incompatible changes.
|
||||
* Change the group URL from /group/name to /group/name/, which allows
|
||||
using relative links. The old URL is redirected to the new one.
|
||||
* Extend the protocol with the ability to consult the group status before
|
||||
joining; this allows using the group's displayName before the user has
|
||||
logged in, and will be required for new authorisation schemes.
|
||||
* Allow scrolling of the login dialog, useful on small devices.
|
||||
* Fixed a typo that prevented the group name from being displayed.
|
||||
* Made failed videos more visible.
|
||||
* No longer attempt to save passwords in browser JavaScript, it's
|
||||
insecure and not very useful.
|
||||
|
||||
5 September 2021: Galène 0.4
|
||||
|
||||
* Implemented simulcast.
|
||||
* Implemented scalable video coding (SVC) for VP8 and VP9.
|
||||
* Preliminary support for the AV1 codec.
|
||||
* Fixed the profile announced for VP9.
|
||||
* Reworked the disk writer, which should no longer cause corruption
|
||||
after packet loss.
|
||||
* Added support for recording H.264 tracks.
|
||||
* Reworked the signalling protocol, it is now possible to request
|
||||
different tracks for distinct streams, and there are provisions to
|
||||
carry user permissions and statuses; this is not yet used by the user
|
||||
interface.
|
||||
* Reworked internal signalling; this will hopefully fix issues with
|
||||
losing tracks under load.
|
||||
* Added an option to limit the range of UDP ports used by the server.
|
||||
* Added a close button in every locally-generated video; this allows
|
||||
closing individual screen shares and simplifies the UI by not creating
|
||||
close buttons in the top bar.
|
||||
* The server will now attempt to increase the file descriptor limit at
|
||||
startup.
|
||||
* Stats are now exported as JSON and formatted on the client side; the
|
||||
stats URL is now /stats.html rather than just /stats.
|
||||
|
||||
27 April 2021: Galène 0.3.4
|
||||
|
||||
* Fixed a bug in the loss estimator. We will now reduce the rate more
|
||||
aggressively when there is loss in the client->serer direction.
|
||||
* Fixed display of the chat on some devices.
|
||||
* Exported the group.Description data structure for the sake of external
|
||||
configuration tools.
|
||||
|
||||
16 April 2021: Galène 0.3.3
|
||||
|
||||
* Fixed an off-by-one error that could occasionally lead to a server
|
||||
crash. Thanks to Louis Gesbert.
|
||||
* Attempt to negotiate stereo Opus audio.
|
||||
|
||||
3 March 2021: Galène 0.3.2
|
||||
|
||||
* Fixed compatibility with versions of Go earlier than 1.15 (thanks to
|
||||
Michael Ströder).
|
||||
* Fixed a race condition in the disk writer.
|
||||
|
||||
26 February 2021: Galène 0.3.1
|
||||
|
||||
* We now notice when the TLS certificate has changed on disk; the
|
||||
certificate can therefore be rotated without a restart.
|
||||
* We now generate a self-signed certificate if none is found on disk.
|
||||
|
||||
18 February 2021: Galène 0.3
|
||||
|
||||
* Implemented the command /muteall. This allows muting all users except
|
||||
yourself.
|
||||
* Implemented the autolock and autokick user group options, that cause,
|
||||
a group to be locked or all users to be kicked out when the last
|
||||
administrator leaves.
|
||||
* Implemented client-side filters that are run over the video before it
|
||||
is sent to the server. A pair of mirroring filters are provided,
|
||||
which are useful when using a mirror in front of a webcam.
|
||||
* Included a built-in TURN server, which drastically simplifies
|
||||
deployment in common cases.
|
||||
* Implemented testing of TURN servers, on both the client and the server
|
||||
side. Connectivity will be checked by the server every 12 hours, and
|
||||
by the client whenever a user uses the /relay-test command.
|
||||
* Group configurations are now checked at startup, and any failures are
|
||||
logged. This implies that it is no longer possible to use undefined
|
||||
keys in group definition files (this is a breaking change).
|
||||
* Reworked the client API, which is now simpler and more uniform.
|
||||
* Subgroups can now be public.
|
||||
* Added an option to disable the mirror view, which is useful when writing.
|
||||
* Ported file playback to Firefox.
|
||||
* We now display a friendly error message when the user has disabled
|
||||
WebRTC under Firefox.
|
||||
* Implemented renegotiation of down streams, which reduces the amount of
|
||||
flicker in the user interface.
|
||||
* Fixed a number of race conditions that could cause audio tracks to
|
||||
become muted or video tracks to freeze.
|
||||
|
||||
9 January 2021: Galène 0.2
|
||||
|
||||
* We now work around a limitation of the Go runtime that used to cause
|
||||
a crash on 32-bit architectures.
|
||||
* Recording to disk now works on Windows too.
|
||||
* Error handling has been improved. In particular, group operators now
|
||||
receive a friendly warning when recording to disk fails for some reason.
|
||||
* It is now possible to configure a group to use codecs such as VP9 and
|
||||
H.264. The default is still to use VP8 and Opus, as this yields the
|
||||
best compatibility across browsers. Only VP8, VP9 and Opus can be
|
||||
saved to disk.
|
||||
* The command-line option "-relay-only" can be used to specify that all
|
||||
media traffic should go through a TURN server.
|
||||
* It is now possible to generate TURN passwords automatically, which
|
||||
avoids leaking long-term TURN credentials. See the "credentialType"
|
||||
value "hmac-sha1" described in README.
|
||||
* The ICE configuration will now be checked periodically, and new
|
||||
clients will use an updated configuration.
|
||||
* The client-server protocol has been reworked to be more symmetric
|
||||
and more secure. It is now documented in the file README.PROTOCOL.
|
||||
* The stream abort protocol message is now supported in the client->server
|
||||
direction, making it possible for the client to reject a stream.
|
||||
* The delay before sending NACKs has been reduced, which gives a major
|
||||
boost in video quality.
|
||||
* The play from disk button is not available when the browser doesn't
|
||||
support the required API. We used to display a cryptic error message
|
||||
in that case.
|
||||
* The command-line option -insecure allows using plain HTTP, which is
|
||||
useful when running behind a reverse proxy.
|
||||
* When saving to disk to disk, the keyframe interval has been reduced to 4s.
|
||||
* We now send keepalives after 55s at most, which should fix issues with
|
||||
reverse proxies timing out the WebSocket.
|
||||
|
||||
19 December 2020: Galène 0.1
|
||||
|
||||
* Initial release.
|
||||
@@ -1,7 +1,7 @@
|
||||
# Skald
|
||||
|
||||
Skald is a hard fork of Galene that is being turned into an audio-only
|
||||
hall conferencing server. The current development repository is
|
||||
Skald is a hard fork of Galene into an audio-only hall conferencing
|
||||
server. The current development repository is
|
||||
<https://git.stormux.org/storm/skald>.
|
||||
|
||||
Skald is not protocol-compatible or API-compatible with Galene. Its public
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# shellcheck shell=bash disable=SC2034,SC2154
|
||||
|
||||
pkgname=skald-git
|
||||
pkgver=0.0.0.r1553.g0c852e8
|
||||
pkgver=2026.07.08
|
||||
pkgrel=1
|
||||
pkgdesc='Audio-only hall-based conferencing server'
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -28,10 +28,10 @@ sha256sums=(
|
||||
pkgver() {
|
||||
cd skald || return
|
||||
local describe
|
||||
if describe="$(git describe --long --tags 2>/dev/null)"; then
|
||||
if describe="$(git describe --long --tags --match '[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]' 2>/dev/null)"; then
|
||||
printf '%s\n' "$describe" | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g'
|
||||
else
|
||||
printf '0.0.0.r%s.g%s' "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
printf '2026.07.08.r%s.g%s' "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# Void Linux packaging
|
||||
|
||||
This directory contains a local `xbps-src` template for Skald.
|
||||
|
||||
Copy `skald-git/` into `srcpkgs/skald-git/` in a Void packages checkout,
|
||||
then build it with:
|
||||
|
||||
```sh
|
||||
./xbps-src pkg skald-git
|
||||
```
|
||||
|
||||
The package installs both `skald` and `skaldctl`, creates a `skald` system
|
||||
account, creates `/var/lib/skald/{data,halls,recordings}`, and provides a
|
||||
runit service named `skald`.
|
||||
|
||||
To use a private repository, prefer SSH authentication by changing
|
||||
`repository` in the template, for example:
|
||||
|
||||
```sh
|
||||
repository="ssh://git@git.stormux.org/storm/skald.git"
|
||||
```
|
||||
|
||||
Make sure the build environment has access to the needed SSH key or Git
|
||||
credential helper. Do not put passwords in the template.
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
# shellcheck disable=SC3045
|
||||
exec 2>&1
|
||||
cd /var/lib/skald || exit 1
|
||||
ulimit -n 65536
|
||||
exec chpst -u skald:skald /usr/bin/skald \
|
||||
-static /usr/share/skald/static \
|
||||
-data /var/lib/skald/data \
|
||||
-halls /var/lib/skald/halls \
|
||||
-recordings /var/lib/skald/recordings
|
||||
@@ -1,60 +0,0 @@
|
||||
# Template file for 'skald-git'
|
||||
# shellcheck shell=bash disable=SC2034,SC2154
|
||||
pkgname=skald-git
|
||||
version=0.0.0
|
||||
revision=1
|
||||
hostmakedepends="git go"
|
||||
depends="ffmpeg"
|
||||
short_desc="Audio-only hall-based conferencing server"
|
||||
maintainer="Stormux <storm_dragon@stormux.org>"
|
||||
license="MIT"
|
||||
homepage="https://git.stormux.org/storm/skald"
|
||||
repository="https://git.stormux.org/storm/skald.git"
|
||||
provides="skald-${version}_${revision}"
|
||||
conflicts="skald>=0"
|
||||
wrksrc="skald"
|
||||
system_accounts="skald"
|
||||
skald_homedir="/var/lib/skald"
|
||||
make_dirs="
|
||||
/var/lib/skald 0750 skald skald
|
||||
/var/lib/skald/data 0750 skald skald
|
||||
/var/lib/skald/halls 0750 skald skald
|
||||
/var/lib/skald/recordings 0750 skald skald"
|
||||
|
||||
do_fetch() {
|
||||
if [ -d "${XBPS_BUILDDIR}/${wrksrc}/.git" ]; then
|
||||
git -C "${XBPS_BUILDDIR}/${wrksrc}" fetch --depth=1 origin "${SKALD_GIT_BRANCH:-master}"
|
||||
git -C "${XBPS_BUILDDIR}/${wrksrc}" checkout FETCH_HEAD
|
||||
else
|
||||
git clone --depth=1 --branch "${SKALD_GIT_BRANCH:-master}" "$repository" "${XBPS_BUILDDIR}/${wrksrc}"
|
||||
fi
|
||||
}
|
||||
|
||||
do_build() {
|
||||
export CGO_ENABLED=0
|
||||
export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw"
|
||||
mkdir -p build
|
||||
go build -ldflags='-s -w' -o build/skald .
|
||||
go build -ldflags='-s -w' -o build/skaldctl ./skaldctl
|
||||
}
|
||||
|
||||
do_check() {
|
||||
go test ./...
|
||||
}
|
||||
|
||||
do_install() {
|
||||
vbin build/skald
|
||||
vbin build/skaldctl
|
||||
|
||||
vmkdir usr/share/skald/static
|
||||
vcopy "static/*" usr/share/skald/static
|
||||
|
||||
vdoc README.md
|
||||
vdoc skald.md
|
||||
vdoc skald-api.md
|
||||
vdoc skald-client.md
|
||||
vdoc skald-install.md
|
||||
vdoc skald-protocol.md
|
||||
|
||||
vsv skald
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
# Skald Fork Inventory
|
||||
|
||||
This file records the baseline surfaces found during the early hard-fork
|
||||
inventory. It is intentionally short; implementation work should update the
|
||||
main docs and tests, not expand this into a second task list.
|
||||
|
||||
## Static And Generated Assets
|
||||
|
||||
The served static tree is `static/`. Current first-party static files are:
|
||||
|
||||
- `404.css`, `404.html`
|
||||
- `change-password.css`, `change-password.html`, `change-password.js`
|
||||
- `common.css`
|
||||
- `index.html`
|
||||
- `mainpage.css`, `mainpage.js`
|
||||
- `management.js`
|
||||
- `protocol.js`
|
||||
- `skald.css`, `skald.html`, `skald.js`
|
||||
- `stats.html`, `stats.js`
|
||||
- `tsconfig.json`
|
||||
|
||||
The static tree still includes `static/background-blur-worker.js`, which is a
|
||||
video-era asset to remove during the audio-only frontend/backend work.
|
||||
|
||||
The `static/example/` directory contains `example.html` and `example.js`.
|
||||
|
||||
Third-party static assets are vendored under `static/third-party/`:
|
||||
|
||||
- Font Awesome CSS, fonts, and license files.
|
||||
- `contextual` CSS/JS and license.
|
||||
- `toastify` CSS/JS and license.
|
||||
|
||||
No generated static output directory is currently present in the checkout.
|
||||
|
||||
## Public URL Surfaces
|
||||
|
||||
Current active Skald URL surfaces found in the server and browser code:
|
||||
|
||||
- `/hall/name/`
|
||||
- `/public-halls.json`
|
||||
- `/recordings/`
|
||||
- `/skald-api/v0/`
|
||||
- `/skald-api/v0/.halls/`
|
||||
- `/skald-api/v0/.stats`
|
||||
|
||||
Old Galene URL surfaces from the planning checklist are not active routes in
|
||||
the current server code:
|
||||
|
||||
- `/group/`
|
||||
- `/public-groups.json`
|
||||
- `/galene-api/`
|
||||
- `.groups`
|
||||
|
||||
The old `/group/name/` spelling remains in historical `CHANGES` text only.
|
||||
|
||||
## Config And Data Paths
|
||||
|
||||
Current runtime defaults and config paths:
|
||||
|
||||
- `-static ./static/`
|
||||
- `-data ./data/`
|
||||
- `-halls ./halls/`
|
||||
- `-recordings ./recordings/`
|
||||
- `data/config.json`
|
||||
- `data/ice-servers.json`
|
||||
- `data/var/tokens.jsonl`
|
||||
- `halls/hallname.json`
|
||||
|
||||
The old `groups/`, `galenectl.json`, and `skaldctl.json` paths are not current
|
||||
runtime defaults.
|
||||
Existing Galene installations should be treated as incompatible unless a later
|
||||
task explicitly adds a one-shot manual migration tool or documented manual
|
||||
conversion procedure.
|
||||
|
||||
## Binary, Service, And Install Names
|
||||
|
||||
Current binary and service surfaces found in active docs/code:
|
||||
|
||||
- Server binary: `skald`
|
||||
- Control tool binary: `skaldctl`
|
||||
- Service example: `skald.service`
|
||||
- Service user and group examples: `skald`
|
||||
|
||||
Remaining `galene`, `Galene`, and `galenectl` references are historical
|
||||
changelog entries, fork attribution, or the master todo's record of completed
|
||||
rename work.
|
||||
|
||||
## License And Attribution
|
||||
|
||||
The upstream `LICENCE` file remains in place. Skald docs also keep explicit
|
||||
fork attribution to Galene where appropriate.
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Skald</title>
|
||||
<title>Skald Version 2026.07.08</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/common.css">
|
||||
@@ -13,7 +13,7 @@
|
||||
<body>
|
||||
|
||||
<div class="home">
|
||||
<h1 id="title" class="navbar-brand">Skald</h1>
|
||||
<h1 id="title" class="navbar-brand">Skald Version 2026.07.08</h1>
|
||||
|
||||
<form id="hallform">
|
||||
<label for="hall">Hall:</label>
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Skald</title>
|
||||
<title>Skald Version 2026.07.08</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="ScreenOrientation" content="autoRotate:disabled">
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="row full-height">
|
||||
<nav id="left-sidebar" class="connected-only invisible" aria-hidden="true">
|
||||
<div class="users-header">
|
||||
<div class="skald-header">Skald</div>
|
||||
<div class="skald-header">Skald Version 2026.07.08</div>
|
||||
</div>
|
||||
<div class="header-sep"></div>
|
||||
<div id="users"></div>
|
||||
@@ -31,7 +31,7 @@
|
||||
<button class="collapse" aria-label="Toggle left panel" aria-expanded="true" aria-controls="left-sidebar" id="sidebarCollapse">
|
||||
<i class="fas fa-align-left" aria-hidden="true"></i>
|
||||
</button>
|
||||
<h1 id="title" class="header-title" tabindex="-1">Skald</h1>
|
||||
<h1 id="title" class="header-title" tabindex="-1">Skald Version 2026.07.08</h1>
|
||||
</div>
|
||||
|
||||
<ul class="nav-menu">
|
||||
|
||||
+3
-2
@@ -2033,6 +2033,7 @@ function displayUsername() {
|
||||
}
|
||||
|
||||
let presentRequested = null;
|
||||
const skaldVersionLabel = 'Skald Version 2026.07.08';
|
||||
|
||||
/**
|
||||
* @param {string} s
|
||||
@@ -2047,12 +2048,12 @@ function capitalise(s) {
|
||||
* @param {string} title
|
||||
*/
|
||||
function setTitle(title) {
|
||||
let displayTitle = 'Skald';
|
||||
let displayTitle = skaldVersionLabel;
|
||||
if(title) {
|
||||
let status = hallStatus.locked ? 'locked' : 'unlocked';
|
||||
if(hallRecording)
|
||||
status += ', recording';
|
||||
displayTitle = `Hall: ${title} (${status})`;
|
||||
displayTitle = `Hall: ${title} (${status}) - ${skaldVersionLabel}`;
|
||||
}
|
||||
document.title = displayTitle;
|
||||
document.getElementById('title').textContent = displayTitle;
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
# Skald Recording Quality Roadmap
|
||||
#
|
||||
# Current state:
|
||||
# The original hard-fork checklist is retired. Skald is live on the user's
|
||||
# server, Galene rooms have been migrated as Skald halls, and basic recording
|
||||
# has been verified with real users.
|
||||
#
|
||||
# Goal:
|
||||
# Make Skald's single mixed Ogg Opus recordings sound good, stay reliable
|
||||
# under larger audio-only halls, and avoid avoidable CPU/process overhead.
|
||||
#
|
||||
# Legend:
|
||||
# - item = needs doing.
|
||||
# + item = implemented, needs testing.
|
||||
# X item = tested and done.
|
||||
#
|
||||
# Constraints:
|
||||
# - Keep recordings as one mixed Ogg Opus file per hall recording session.
|
||||
# - Preserve clear recording start/stop announcements and operator feedback.
|
||||
# - Do not block WebRTC packet handling on recording work.
|
||||
# - Favor small, testable stages over one large rewrite.
|
||||
# - Keep live-server safety in mind; staged improvements should be deployable
|
||||
# independently.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 0: BASELINE AND MEASUREMENT
|
||||
# ============================================================================
|
||||
|
||||
X Confirm the current live deployment can start and stop a Skald recording.
|
||||
X Confirm migrated Galene rooms work as Skald halls on meet.stormux.org.
|
||||
X Document the current recording pipeline in skald.md for maintainers:
|
||||
incoming Opus RTP -> per-source ffmpeg decoder -> PCM mixer -> ffmpeg Opus
|
||||
encoder -> Ogg Opus file.
|
||||
X Add lightweight recording metrics in logs or debug output:
|
||||
active recorded sources, dropped source frames, mixer write errors, ffmpeg
|
||||
decoder starts/stops, and encoder failures.
|
||||
X Add a synthetic recording smoke tool that can simulate multiple decoded PCM
|
||||
sources without needing browser clients.
|
||||
- Add a synthetic RTP/Opus recording benchmark that exercises per-source
|
||||
decoder subprocesses without needing browser clients.
|
||||
- Record baseline CPU, process count, and output quality for 1, 5, 10, and 25
|
||||
active sources on a representative server.
|
||||
- Define practical target limits for "normal hall", "large moderated hall",
|
||||
and "stress test" recording scenarios.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 1: MIX QUALITY BEFORE PIPELINE REWRITE
|
||||
# ============================================================================
|
||||
|
||||
X Add mixer tests for multiple simultaneous PCM sources, including clipping
|
||||
cases and quiet/loud source combinations.
|
||||
X Replace raw summing with a safer mix strategy:
|
||||
per-source attenuation, headroom, or another deterministic approach that
|
||||
reduces clipping when multiple users speak.
|
||||
X Add a simple limiter to prevent harsh clipping in the final mixed PCM.
|
||||
X Add tests proving the limiter preserves normal speech-level samples and
|
||||
bounds overloaded samples.
|
||||
- Add optional per-source level tracking so logs or future UI can identify
|
||||
sources that dominate the recording.
|
||||
- Verify recordings with 2-5 simultaneous speakers sound cleaner than the
|
||||
current clamped sum.
|
||||
- Verify the limiter does not create pumping, distortion, or excessive volume
|
||||
loss for a single speaker.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 2: SOURCE LIFECYCLE AND SILENCE HANDLING
|
||||
# ============================================================================
|
||||
|
||||
X Track whether each recording source is active, silent, stalled, or closed.
|
||||
X Treat missing frames as silence without blocking the mixer.
|
||||
- Drop or de-prioritize stale silent sources after a short timeout.
|
||||
- Ensure mute/unmute transitions do not leave stale audio in the mixed output.
|
||||
- Ensure participant join/leave during recording never stops the recording file.
|
||||
- Add tests for source join, leave, mute, unmute, stall, and recovery during an
|
||||
active recording.
|
||||
- Verify a long recording remains valid when sources repeatedly join and leave.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 3: REDUCE PROCESS OVERHEAD
|
||||
# ============================================================================
|
||||
|
||||
- Evaluate Go-native Opus decode options against the current ffmpeg decoder
|
||||
subprocesses:
|
||||
sound quality, maintenance risk, packaging impact, CGO requirements, and CPU.
|
||||
- Decide whether in-process Opus decoding is worth the dependency and packaging
|
||||
tradeoff.
|
||||
- If keeping ffmpeg decoders, pool or supervise decoder processes more
|
||||
deliberately and improve failure recovery.
|
||||
- If replacing ffmpeg decoders, implement one in-process decoder path behind
|
||||
tests before removing the subprocess path.
|
||||
- Verify recording still handles dynamic payload type, RTP sequence behavior,
|
||||
packet loss, and source restarts.
|
||||
- Measure CPU and process-count improvement with 10+ active sources.
|
||||
- Keep one final encoder path to Ogg Opus unless there is a proven reason to
|
||||
replace it too.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 4: ENCODER AND CONTAINER HARDENING
|
||||
# ============================================================================
|
||||
|
||||
- Decide whether the final Ogg Opus encoder should remain ffmpeg or move
|
||||
in-process later.
|
||||
- Make encoder startup errors operator-visible and log the exact ffmpeg error.
|
||||
X Ensure encoder stdin writes cannot block the mixer indefinitely.
|
||||
- Ensure recorder close handles encoder failure, stdin close failure, and wait
|
||||
failure without leaving misleading successful output.
|
||||
- Verify interrupted or failed recordings are either clearly marked as failed or
|
||||
produce a playable partial file.
|
||||
X Verify completed files with ffprobe or equivalent in tests where available.
|
||||
- Verify completed files play in common players after long recordings.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 5: LARGE-HALL OPERATIONS
|
||||
# ============================================================================
|
||||
|
||||
- Add documentation for recommended large-hall permissions:
|
||||
most users observe/message, only presenters publish audio, operators control
|
||||
recording.
|
||||
- Document expected scaling limits in terms of active speakers, not just total
|
||||
connected users.
|
||||
- Add guidance for max-clients, TURN bandwidth, CPU monitoring, and recording
|
||||
expectations for 50, 100, and 250 user events.
|
||||
- Add an operator-facing warning or log message when active recorded sources
|
||||
exceed a conservative threshold.
|
||||
- Test a large moderated hall with many listeners and a few active speakers.
|
||||
- Test a stress hall with many active speakers and document the observed limit.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 6: FINAL CLEANUP AND RELEASE READINESS
|
||||
# ============================================================================
|
||||
|
||||
- Update skald.md and skald-install.md with the final recording architecture.
|
||||
- Update package dependencies if recording dependency choices change.
|
||||
- Run focused recording tests and webserver recording-control tests.
|
||||
- Run `go test ./...` in a clean tree without distro package build artifacts.
|
||||
- Run live browser testing for recording start, stop, join, leave, mute, and
|
||||
playback.
|
||||
- Do a final review for accidental regressions in recording announcements,
|
||||
hall permissions, and migrated-hall compatibility.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 7: WEB UI AUDIO DEFAULTS AND EVENT SOUNDS
|
||||
# ============================================================================
|
||||
|
||||
+ Default new sessions to high-quality audio.
|
||||
+ Default new sessions to no browser noise suppression, echo cancellation, or
|
||||
automatic gain control.
|
||||
+ Ensure the default microphone path also receives explicit audio constraints.
|
||||
+ Add generated browser notification sounds without binary sound assets.
|
||||
+ Add a user-facing Notification sounds setting.
|
||||
+ Play generated sounds for recording start, recording stop, raised hand,
|
||||
lowered hand, user join, user leave, and incoming chat message.
|
||||
- Verify sounds play after login in Chromium.
|
||||
- Verify sounds play after login in Firefox.
|
||||
- Verify sounds never replace screen-reader live-region announcements.
|
||||
- Tune sound levels and shapes with live users.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 8: LOCAL SKALDCTL ADMINISTRATION
|
||||
# ============================================================================
|
||||
|
||||
X Remove skaldctl's remote HTTPS administration path and operate directly on
|
||||
the server's local data, hall, and token files.
|
||||
X Add `create-hall -interactive` for guided hall settings, operator accounts,
|
||||
and an optional shared participant password.
|
||||
X Document that skaldctl runs on the Skald server with filesystem access.
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 9: HALL HEADING STATUS
|
||||
# ============================================================================
|
||||
|
||||
X Show lock and recording state in the browser's hall heading.
|
||||
+2
-3
@@ -184,9 +184,8 @@ func (state *state) load() (string, error) {
|
||||
state.reset()
|
||||
return "", err
|
||||
}
|
||||
// the "message" permission was introduced in Skald 0.9,
|
||||
// so add it to tokens read from disk. We can remove this
|
||||
// hack in late 2024.
|
||||
// The "message" permission was introduced before the
|
||||
// Skald fork, so add it to older tokens read from disk.
|
||||
if !member("message", t.Permissions) {
|
||||
t.Permissions = append(t.Permissions, "message")
|
||||
}
|
||||
|
||||
@@ -70,10 +70,14 @@ func TestStaticLiveRegionAnnouncementsStayWired(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHallHeadingIncludesCurrentStatus(t *testing.T) {
|
||||
html := readStaticFile(t, "skald.html")
|
||||
js := readStaticFile(t, "skald.js")
|
||||
|
||||
requireContains(t, html, "Skald Version 2026.07.08", "hall page title")
|
||||
requireContains(t, js, "const skaldVersionLabel = 'Skald Version 2026.07.08'", "version label")
|
||||
requireFunctionContains(t, js, "setTitle", "hallStatus.locked ? 'locked' : 'unlocked'")
|
||||
requireFunctionContains(t, js, "setTitle", "status += ', recording'")
|
||||
requireFunctionContains(t, js, "setTitle", "${skaldVersionLabel}")
|
||||
requireFunctionContains(t, js, "gotJoined", "hallStatus.locked = false")
|
||||
requireFunctionContains(t, js, "gotJoined", "hallStatus.recording = false")
|
||||
requireFunctionContains(t, js, "gotJoined", "hallRecording = !!hallStatus.recording")
|
||||
|
||||
Reference in New Issue
Block a user