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
|
||||||
|
|
||||||
Skald is a hard fork of Galene that is being turned into an audio-only
|
Skald is a hard fork of Galene into an audio-only hall conferencing
|
||||||
hall conferencing server. The current development repository is
|
server. The current development repository is
|
||||||
<https://git.stormux.org/storm/skald>.
|
<https://git.stormux.org/storm/skald>.
|
||||||
|
|
||||||
Skald is not protocol-compatible or API-compatible with Galene. Its public
|
Skald is not protocol-compatible or API-compatible with Galene. Its public
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# shellcheck shell=bash disable=SC2034,SC2154
|
# shellcheck shell=bash disable=SC2034,SC2154
|
||||||
|
|
||||||
pkgname=skald-git
|
pkgname=skald-git
|
||||||
pkgver=0.0.0.r1553.g0c852e8
|
pkgver=2026.07.08
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc='Audio-only hall-based conferencing server'
|
pkgdesc='Audio-only hall-based conferencing server'
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
@@ -28,10 +28,10 @@ sha256sums=(
|
|||||||
pkgver() {
|
pkgver() {
|
||||||
cd skald || return
|
cd skald || return
|
||||||
local describe
|
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'
|
printf '%s\n' "$describe" | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g'
|
||||||
else
|
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
|
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>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Skald</title>
|
<title>Skald Version 2026.07.08</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="/common.css">
|
<link rel="stylesheet" href="/common.css">
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="home">
|
<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">
|
<form id="hallform">
|
||||||
<label for="hall">Hall:</label>
|
<label for="hall">Hall:</label>
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Skald</title>
|
<title>Skald Version 2026.07.08</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="ScreenOrientation" content="autoRotate:disabled">
|
<meta http-equiv="ScreenOrientation" content="autoRotate:disabled">
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<div class="row full-height">
|
<div class="row full-height">
|
||||||
<nav id="left-sidebar" class="connected-only invisible" aria-hidden="true">
|
<nav id="left-sidebar" class="connected-only invisible" aria-hidden="true">
|
||||||
<div class="users-header">
|
<div class="users-header">
|
||||||
<div class="skald-header">Skald</div>
|
<div class="skald-header">Skald Version 2026.07.08</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-sep"></div>
|
<div class="header-sep"></div>
|
||||||
<div id="users"></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">
|
<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>
|
<i class="fas fa-align-left" aria-hidden="true"></i>
|
||||||
</button>
|
</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>
|
</div>
|
||||||
|
|
||||||
<ul class="nav-menu">
|
<ul class="nav-menu">
|
||||||
|
|||||||
+3
-2
@@ -2033,6 +2033,7 @@ function displayUsername() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let presentRequested = null;
|
let presentRequested = null;
|
||||||
|
const skaldVersionLabel = 'Skald Version 2026.07.08';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} s
|
* @param {string} s
|
||||||
@@ -2047,12 +2048,12 @@ function capitalise(s) {
|
|||||||
* @param {string} title
|
* @param {string} title
|
||||||
*/
|
*/
|
||||||
function setTitle(title) {
|
function setTitle(title) {
|
||||||
let displayTitle = 'Skald';
|
let displayTitle = skaldVersionLabel;
|
||||||
if(title) {
|
if(title) {
|
||||||
let status = hallStatus.locked ? 'locked' : 'unlocked';
|
let status = hallStatus.locked ? 'locked' : 'unlocked';
|
||||||
if(hallRecording)
|
if(hallRecording)
|
||||||
status += ', recording';
|
status += ', recording';
|
||||||
displayTitle = `Hall: ${title} (${status})`;
|
displayTitle = `Hall: ${title} (${status}) - ${skaldVersionLabel}`;
|
||||||
}
|
}
|
||||||
document.title = displayTitle;
|
document.title = displayTitle;
|
||||||
document.getElementById('title').textContent = 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()
|
state.reset()
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// the "message" permission was introduced in Skald 0.9,
|
// The "message" permission was introduced before the
|
||||||
// so add it to tokens read from disk. We can remove this
|
// Skald fork, so add it to older tokens read from disk.
|
||||||
// hack in late 2024.
|
|
||||||
if !member("message", t.Permissions) {
|
if !member("message", t.Permissions) {
|
||||||
t.Permissions = append(t.Permissions, "message")
|
t.Permissions = append(t.Permissions, "message")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,10 +70,14 @@ func TestStaticLiveRegionAnnouncementsStayWired(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestHallHeadingIncludesCurrentStatus(t *testing.T) {
|
func TestHallHeadingIncludesCurrentStatus(t *testing.T) {
|
||||||
|
html := readStaticFile(t, "skald.html")
|
||||||
js := readStaticFile(t, "skald.js")
|
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", "hallStatus.locked ? 'locked' : 'unlocked'")
|
||||||
requireFunctionContains(t, js, "setTitle", "status += ', recording'")
|
requireFunctionContains(t, js, "setTitle", "status += ', recording'")
|
||||||
|
requireFunctionContains(t, js, "setTitle", "${skaldVersionLabel}")
|
||||||
requireFunctionContains(t, js, "gotJoined", "hallStatus.locked = false")
|
requireFunctionContains(t, js, "gotJoined", "hallStatus.locked = false")
|
||||||
requireFunctionContains(t, js, "gotJoined", "hallStatus.recording = false")
|
requireFunctionContains(t, js, "gotJoined", "hallStatus.recording = false")
|
||||||
requireFunctionContains(t, js, "gotJoined", "hallRecording = !!hallStatus.recording")
|
requireFunctionContains(t, js, "gotJoined", "hallRecording = !!hallStatus.recording")
|
||||||
|
|||||||
Reference in New Issue
Block a user