Soundboard (Discord-style): sound-pack rooms, admin controls, compatibility mode #95

Open
opened 2026-10-07 20:39:57 +00:00 by robocub · 0 comments
Member

Discord-style soundboard in calls: short clips anyone can play, everyone hears, with room admins in control.

Draft spec (initial, NOT reviewed yet — to be read through and amended):
docs/specs/soundboard.md on branch docs/soundboard-spec

Summary of the draft

  • Sound packs live in rooms, like sticker rooms: state event im.vommet.room.sound_pack, the same shape as the stable m.room.image_pack from Matrix v1.19. Subscriptions go in account data (im.vommet.sound_pack.rooms) and personal sounds in im.vommet.user_sounds.
  • Admin policy state event im.vommet.soundboard in the call room: switch the soundboard off, open / defaults_only / allowlist modes, default packs everyone sees on joining, allow or deny members' own subscribed packs, allowlisted sounds pinned by mxc (so a pack editor can't swap a sound after approval), blocked sounds, a minimum power level, soundboard-only mutes, a rate limit and a maximum clip length.
  • Native mode (copies how Discord itself works): a small trigger goes over the LiveKit data channel and each Vommet client plays the clip locally. Every receiver enforces the policy, so a modified sender gains nothing.
  • Compatibility mode for Element Call, upstream Commet and the voice bridge: the clip is published on a separate vommet-soundboard audio track. Hybrid: the track is published only when someone in the call lacks support, and Vommet clients never play it, so nobody hears the sound twice.
  • Encrypted packs (v2): an encrypted manifest event behind an unencrypted, power-level-guarded pointer in state. This works without encrypted state (MSC3414/MSC4362 is still unaccepted). Late joiners get the keys through MSC4268 history sharing.

Dependencies found (checked 2026-10-07)

  • Commet's SDK fork (commetchat/[email protected]) and current upstream famedly matrix-dart-sdk main:

    • no MSC4268 history sharing (in the spec since v1.19);
    • only the unstable im.ponies.* image pack names, not stable m.room.image_pack / m.image_pack.rooms.

    Both deserve their own issues. Stable pack names also matter for stickers (#19).

  • When MSC4268 is implemented: send shared_history and also accept matrix-rust-sdk's m.shared_history (matrix-org/matrix-rust-sdk#7153).

First step

A spike: do Element Call and upstream Commet play a second, tagged audio track from one participant? Compatibility mode depends on the answer. Reuse the screen-share audio publishing path (#4).

Related: #4 (second audio track), #3 (local playback must be mixed after voice processing), #19 (sticker rooms), #59 (moderation), nether/nether-voicebridge (Discord soundboard relay, §6 of the draft).

Discord-style soundboard in calls: short clips anyone can play, everyone hears, with room admins in control. **Draft spec (initial, NOT reviewed yet — to be read through and amended):** [`docs/specs/soundboard.md` on branch `docs/soundboard-spec`](https://nether.codes/nether/vommet/src/branch/docs/soundboard-spec/docs/specs/soundboard.md) ## Summary of the draft - **Sound packs live in rooms**, like sticker rooms: state event `im.vommet.room.sound_pack`, the same shape as the stable `m.room.image_pack` from Matrix v1.19. Subscriptions go in account data (`im.vommet.sound_pack.rooms`) and personal sounds in `im.vommet.user_sounds`. - **Admin policy** state event `im.vommet.soundboard` in the call room: switch the soundboard off, `open` / `defaults_only` / `allowlist` modes, **default packs everyone sees on joining**, allow or deny members' own subscribed packs, allowlisted sounds **pinned by mxc** (so a pack editor can't swap a sound after approval), blocked sounds, a minimum power level, soundboard-only mutes, a rate limit and a maximum clip length. - **Native mode** (copies how Discord itself works): a small trigger goes over the LiveKit data channel and each Vommet client plays the clip locally. Every receiver enforces the policy, so a modified sender gains nothing. - **Compatibility mode** for Element Call, upstream Commet and the voice bridge: the clip is published on a separate `vommet-soundboard` audio track. **Hybrid:** the track is published only when someone in the call lacks support, and Vommet clients never play it, so nobody hears the sound twice. - **Encrypted packs (v2):** an encrypted manifest event behind an unencrypted, power-level-guarded pointer in state. This works without encrypted state (MSC3414/MSC4362 is still unaccepted). Late joiners get the keys through MSC4268 history sharing. ## Dependencies found (checked 2026-10-07) - Commet's SDK fork (`commetchat/[email protected]`) and current upstream famedly `matrix-dart-sdk` main: - **no MSC4268 history sharing** (in the spec since v1.19); - **only the unstable `im.ponies.*` image pack names**, not stable `m.room.image_pack` / `m.image_pack.rooms`. Both deserve their own issues. Stable pack names also matter for stickers (#19). - When MSC4268 is implemented: send `shared_history` and also accept matrix-rust-sdk's `m.shared_history` (matrix-org/matrix-rust-sdk#7153). ## First step A spike: do Element Call and upstream Commet play a second, tagged audio track from one participant? Compatibility mode depends on the answer. Reuse the screen-share audio publishing path (#4). Related: #4 (second audio track), #3 (local playback must be mixed after voice processing), #19 (sticker rooms), #59 (moderation), nether/nether-voicebridge (Discord soundboard relay, §6 of the draft).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
nether/vommet#95
No description provided.