The player

A track that plays where it lands

One message, with the sleeve, the title and the duration. Not a link to somewhere else.

What decides the shape

A track plays inside the chat client itself, with cover art, title and duration, in one message. The cover alone decides the shape of that message: with one, the track travels as a still-image video carrying the audio at full quality and the sleeve as the picture; without one, the title arrives as its own message and the audio follows as the bare player.

A successful play sends no text line at all. The track arriving is the reply, which is the difference between a bot that plays music and a bot that talks about playing music.

Why the bare player needs an empty caption 1 lines · 118 characters
because an empty caption is what produces the bare player rather than a framed one (measured in Stage 0, not inferred)
Source site material Block 4 section 2 · the Music Library plugin, gathered 2026-08-30 in a read-only session
Why the preview keeps the sleeve shape 1 lines · 50 characters
a sleeve is not round, and it is not square either
Source site material Block 4 section 2 · the Music Library plugin, gathered 2026-08-30 in a read-only session
The honest dependency

Half of it rests on behaviour nobody documented

The part that could be taken away by somebody else, said plainly, with the fallback that is already written.

The standing rule, in the repository 1 lines · 65 characters
the voice player, which accepted an MP3 the source never promised
Source site material Block 4 section 2 · the Music Library plugin, gathered 2026-08-30 in a read-only session

What happens if it stops

A client update could stop accepting encoded audio there. The recorded degrade path is a plain file attachment, counted on the dashboard, and never silence.

This is the one part of the plugin that a third party could break without warning. It is named here rather than in a footnote, because a buyer deciding whether to depend on it needs it before they decide.

Formats and storage

What she accepts, and where it goes

Tags read and never retyped, originals kept byte for byte, and member uploads never stored at all.

QuestionAnswer
Formats Library upload: common containers with tags read, never retyped, with title, artist, album and genre pre-filled and duration from the probe rather than the tag. Member upload: MP3 only, extension AND magic bytes, with a 10 MB default bound
Where files live The byte-identical original beside its cover and a cached video, plaintext deliberately because it is the operator own broadcast content; boot refuses a music root inside the media root. Member uploads are never stored, played from a temp spool and swept after a day
Cover art, end to end The embedded cover is extracted or uploaded, re-encoded through a rotate and fit as a crafted-image defence, and decides the shape; it is encoded as the still of the video with odd dimensions cropped one pixel, and the in-message preview keeps the sleeve shape
Scheduling Whichever comes first per assignment, every N minutes and every N member messages, plus the operator budgets for unbidden sends only: 3 per room per day, a 60 minute gap, separate for music and spots. A member asking consults no budget. One send in flight per group, and every refused slot is a counted skip with its reason, never silence
Reaches outside Nothing third-party: pinned local ffmpeg, local tag reading, local image work, and sends travel only the SimpleX network. No model anywhere on the send path
Why an upload is checked twice 1 lines · 57 characters
the extension is a CLAIM and the first bytes are the fact
Source site material Block 4 section 2 · the Music Library plugin, gathered 2026-08-30 in a read-only session
Cadence and budgets

A timer that a member can always outrank

Unbidden sends are budgeted, asked-for tracks are not, and a refused slot is counted rather than dropped.

Why an asked-for track spends no budget 1 lines · 73 characters
a requested track and an unbidden advert are different things to a member
Source site material Block 4 section 2 · the Music Library plugin, gathered 2026-08-30 in a read-only session
Why no model touches the send path 1 lines · 91 characters
content that plays into a group on a timer must not be a place a prompt injection can steer
Source site material Block 4 section 2 · the Music Library plugin, gathered 2026-08-30 in a read-only session

Refused, and counted

Every refused slot is a counted skip carrying its reason. A bot that decided not to send says why on the dashboard rather than simply not sending, which is the difference between a quiet system and a broken one.

When it fails

Locked lines, and never a plausible substitute

Every failure has a line she actually says, because a bot that goes quiet is indistinguishable from a bot that is broken.

When a track cannot be played

  • 🎵 I cannot reach my library just now.
  • 🎵 I found it, but the send failed on my way out. It is on record for the operator; ask me again in a little while.
  • 🎵 One is already on its way to this room. Ask me again when it lands.

When an upload cannot be played back

  • 🎧 I only re-send MP3 files. That one is not an MP3, so I will leave it be.
  • 🎧 That file is bigger than I am allowed to carry: {limit} is my line.
  • 🎧 I see no file of yours here to make playable. Send it first, then ask me.
  • 🎧 Playing back uploads is switched off for me.
What the operator asked, in the fourth live test 1 lines · 23 characters
play was wird geschehen
Source site material Block 4 section 2 · the locked failure lines, quoted verbatim
What he got 1 lines · 63 characters
a decorated title line, twice, identically — and nothing played
Source site material Block 4 section 2 · the locked failure lines, quoted verbatim

What was removed

The video send and the retry had both failed, and a last-resort degrade emitted the caption as text, twice. That last resort is structurally gone: the member now gets one of the locked lines above and the fault reaches the dashboard. A silent fallback that produces something plausible is worse than a failure that says so.