2026-07-31 12:00:00 +00:00
|
|
|
# threadnet-call: Fork-Anpassungen für axion1337.chat
|
|
|
|
|
|
|
|
|
|
Dieses Dokument beschreibt alles, was dieser Fork gegenüber Upstream Element Call ändert. Die
|
|
|
|
|
übrigen Dateien in `docs/` sind unverändertes Upstream-Material.
|
|
|
|
|
|
|
|
|
|
## 1. Warum Fork von `emmick4/element-call` (Branch `livekit`)?
|
|
|
|
|
|
|
|
|
|
Nicht direkt von `element-hq/element-call` geforkt, sondern von `emmick4/element-call`s
|
|
|
|
|
`livekit`-Branch, weil dieser bereits den noch nicht upstream gemergten PR
|
|
|
|
|
[element-hq/element-call#3736](https://github.com/element-hq/element-call/pull/3736)
|
|
|
|
|
enthält - config-driven `media_quality`. Ohne diesen PR wäre eigener Custom-Code nötig gewesen,
|
|
|
|
|
um Video-/Audio-Qualitätslimits pro Deployment konfigurierbar zu machen.
|
|
|
|
|
|
|
|
|
|
## 2. media_quality-Defaults
|
|
|
|
|
|
|
|
|
|
Konfiguriert in `vite-embedded.config.ts` (im `generateFile`-Plugin-Aufruf, der
|
|
|
|
|
`media_quality` in die zur Build-Zeit gebackene `config.json` des Embedded-Packages schreibt):
|
|
|
|
|
|
|
|
|
|
- Kamera: **1440p / 60fps / ~8 Mbps** (`video.max_resolution/max_framerate/max_bitrate`)
|
|
|
|
|
- Screen-Share: **1440p / 30fps / ~6 Mbps**
|
|
|
|
|
- 720p-Zwischen-Simulcast-Layer (`video.simulcast_layers`) - ohne diesen fiel die Übertragung
|
|
|
|
|
bei kleinsten Netzwerkschwankungen direkt von 1440p auf blockiges 360p
|
|
|
|
|
- `video_codec: "h264"` (siehe Incident unten für die Begründung)
|
|
|
|
|
|
|
|
|
|
Das sind Startwerte, keine harten Limits - Nutzer können in den Call-Settings weiter hochdrehen.
|
|
|
|
|
|
|
|
|
|
## 3. VP9-Incident (2026-07-28) — ⚠️ nicht ohne Browser-Repro erneut versuchen
|
|
|
|
|
|
|
|
|
|
Erster Versuch setzte `video_codec: "vp9"` (Commit `83db5224`). Das hat Calls **live komplett
|
|
|
|
|
kaputt gemacht** (kein Bild/Ton), obwohl die LiveKit-SFU-Server-Logs den
|
|
|
|
|
Codec-Regression-Fallback auf VP8 als scheinbar erfolgreich zeigten. Sofort zurückgerollt
|
|
|
|
|
(Commit `f845d81e`). Vermutete Ursache: LiveKit nutzt für VP9/AV1 SVC statt klassischem
|
|
|
|
|
Simulcast, aber `buildPublishOptions()` in diesem Fork setzt immer Simulcast-Layer - ein
|
|
|
|
|
echter Code-Fix wäre nötig, um das aufzulösen. **Root Cause nie abschließend isoliert** (hätte
|
|
|
|
|
einen Browser-Konsolen-/WebRTC-Internals-Repro gebraucht). Danach auf 720p-Zwischen-Layer +
|
|
|
|
|
`h264` (klassisches Simulcast, kein SVC-Risiko, oft hardwarebeschleunigt v.a. auf iOS)
|
|
|
|
|
umgestellt - live verifiziert (7/8 Tracks nativ H.264, 1 sauberer VP8-Fallback).
|
|
|
|
|
|
|
|
|
|
**Nicht erneut versuchen, ohne vorher einen echten Browser-Repro zu haben.**
|
|
|
|
|
|
|
|
|
|
## 4. npm-Publish zu Gitea (`@sorb/threadnet-call-embedded`)
|
|
|
|
|
|
|
|
|
|
Das Embedded-Package (`embedded/web/package.json`, aktuell `0.19.2-threadnet.5`) wird zu
|
|
|
|
|
Gitea's npm-Registry veröffentlicht (`https://rohana.axion1337.de/api/packages/sorb/npm/`,
|
|
|
|
|
Scope `@sorb`). Der obere Versionierungs-Track hier (`0.19.2-threadnet.N`) ist unabhängig von
|
|
|
|
|
den Docker-Image-Tags, unter denen das fertig gebaute Widget im gitops-Repo deployt wird (z.B.
|
|
|
|
|
`v0.2.3-elementcall-h264` als `threadnet-web`-Image-Tag) - zwei getrennte Versionsschemata für
|
|
|
|
|
zwei verschiedene Artefakte (npm-Package vs. Docker-Image).
|
|
|
|
|
|
|
|
|
|
Der aktuelle Publish-Vorgang läuft manuell/lokal - das committete
|
|
|
|
|
`.github/workflows/publish-embedded-packages.yaml` zielt noch auf `registry.npmjs.org`/
|
|
|
|
|
`@element-hq`-Scope (Upstream-Konfiguration, nicht an die Gitea-Registry angepasst). Registry-
|
|
|
|
|
Zugangsdaten liegen in einer lokalen, **nicht committeten** `.npmrc` - nicht Teil dieses Repos.
|
|
|
|
|
|
|
|
|
|
## 5. Bewusst keine Server-seitige ML-Rauschunterdrückung
|
|
|
|
|
|
|
|
|
|
Nur der client-seitige WebRTC-Standardtoggle (Echo/Noise/Gain-Suppression, aus derselben
|
|
|
|
|
Upstream-PR-Linie) wurde übernommen. Bewusst **kein** LiveKit-Agents-basiertes Server-seitiges
|
|
|
|
|
ML-Noise-Cancellation (z.B. selbst gehostetes DTLN/RNNoise) - LiveKits eigene Dokumentation
|
|
|
|
|
beschreibt diesen Baustein als für AI-Voice-Agents gedacht, nicht für Mensch-zu-Mensch-Calls
|
|
|
|
|
(kein unterstützter Weg, bereinigtes Audio an andere Teilnehmer weiterzuleiten).
|
|
|
|
|
|
2026-08-06 12:00:00 +00:00
|
|
|
## 6. Produktname im Widget (`.env.production`)
|
|
|
|
|
|
|
|
|
|
`VITE_PRODUCT_NAME=aXion1337.Chat` in `.env.production` — eine Zeile, keine
|
|
|
|
|
Quelldatei angefasst. Upstream liest den Namen an jeder Stelle als
|
|
|
|
|
`import.meta.env.VITE_PRODUCT_NAME || "Element Call"`; die Variable zu setzen ist
|
|
|
|
|
deshalb die vollständige Umbenennung **ohne Merge-Reibung**.
|
|
|
|
|
|
|
|
|
|
Der Name folgt der Regel aus `management/shared/branding.md`: „in der Anwendung"
|
|
|
|
|
heißt es aXion1337.Chat — und das Call-Widget läuft in der Anwendung.
|
|
|
|
|
|
|
|
|
|
**Was dadurch tatsächlich umbenannt wird** (Inventur 2026-08-06, embedded-Modus):
|
|
|
|
|
|
|
|
|
|
| Stelle | sichtbar wo |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `error.matrix_rtc_transport_missing` | Fehlermeldung „Der Server ist nicht für … konfiguriert" |
|
|
|
|
|
| `error.open_elsewhere_description` | „… wurde in einem anderen Tab geöffnet" |
|
|
|
|
|
| `DeveloperSettingsTab` Versionszeile | Einstellungen → Entwicklermodus |
|
|
|
|
|
| `usePageTitle` → `document.title` | im iframe unsichtbar, der Vollständigkeit halber |
|
|
|
|
|
|
|
|
|
|
**Was im Embedded-Build ohnehin nie erscheint** — und deshalb *nicht* angefasst
|
|
|
|
|
wurde:
|
|
|
|
|
|
2026-08-06 12:00:00 +00:00
|
|
|
- **Die Logo-SVGs.** Alle vier sind importiert und liegen im Bundle — gerendert wird
|
|
|
|
|
im Widget aber keins, und zwar jeweils durch dieselbe Bedingung gesperrt:
|
|
|
|
|
|
|
|
|
|
| SVG | gerendert von | Sperre |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| `Logo` | `Header.tsx` (`HeaderLogo`) | `FullScreenView` zeigt den Header nur bei `header === "standard"` |
|
|
|
|
|
| `LogoMark`, `LogoType` | `CallFooter.tsx` | `showLogo = headerStyle === HeaderStyle.Standard` |
|
|
|
|
|
| `LogoLarge` | `LoginPage`, `RegisterPage` | gibt es nur standalone |
|
|
|
|
|
|
|
|
|
|
`HeaderStyle.Standard` ist der Default für **Nicht**-Widget-Nutzung; als Widget ist
|
|
|
|
|
der Header `None` (Desktop) oder `AppBar` (Web/Mobile) — siehe `UrlParams.ts`. Das
|
|
|
|
|
gilt auch für Fehlerseiten: `FullScreenView` prüft dieselbe Bedingung, ein Absturz
|
|
|
|
|
im Widget zeigt also kein Logo.
|
|
|
|
|
|
|
|
|
|
⚠️ Nicht danach greppen, ob ein Logo „irgendwo vorkommt" — im gebauten Bundle steht
|
|
|
|
|
`<desc>Element Call (Beta)</desc>` aus `Logo.svg` drin, obwohl es nie gezeichnet
|
|
|
|
|
wird. Maßgeblich ist die Render-Bedingung, nicht der Treffer.
|
2026-08-06 12:00:00 +00:00
|
|
|
- **`header_label` („Element Call-Startseite") und `login_subheading`.** Startseite
|
|
|
|
|
und Login gibt es nur im Standalone-Modus.
|
|
|
|
|
- **Die drei deutschen `developer_mode.matrixRTCMode.*.description`.** Die reden über
|
|
|
|
|
*Gegenstellen* („alle beteiligten Element Call Clients v0.17.0 oder neuer") — das
|
|
|
|
|
ist eine Kompatibilitätsaussage über fremde Clients, keine Selbstbezeichnung. Sie
|
|
|
|
|
umzubenennen wäre inhaltlich falsch.
|
|
|
|
|
|
|
|
|
|
⚠️ `build:embedded:development` läuft mit `--mode development` und lädt
|
|
|
|
|
`.env.production` nicht — ein Dev-Build zeigt weiter „Element Call". Beabsichtigt;
|
|
|
|
|
ausgeliefert wird der Produktions-Build.
|
|
|
|
|
|
2026-08-06 12:00:00 +00:00
|
|
|
**Verifiziert** am CI-Artefakt von Pipeline 189 (`077dd43`), nicht am Quelltext: das
|
|
|
|
|
gebaute Bundle enthält „aXion1337.Chat"; die verbliebenen „Element Call"-Treffer sind
|
|
|
|
|
Source-Maps, die 22 Sprachdateien (`header_label`, standalone) und die
|
|
|
|
|
`<desc>`-Zeile aus `Logo.svg` — keine davon im Widget sichtbar.
|
|
|
|
|
|
2026-07-31 12:00:00 +00:00
|
|
|
## Repo-Topologie (seit 2026-07-31)
|
|
|
|
|
|
|
|
|
|
**Kanonisch ist `git.lab/axion1337.chat/threadnet-call`** (Homelab-GitLab) — die Kopie auf
|
|
|
|
|
`rohana.axion1337.de/sorb/threadnet-call` ist ein automatischer **Push-Mirror** (Lesekopie,
|
|
|
|
|
Issues, npm-Registry). **Niemals direkt nach rohana pushen** — der Mirror überschreibt
|
|
|
|
|
divergente Stände.
|