Files
threadnet-call/docs/axion1337-fork.md
T
Thore Cimbal dc2a041b83 docs: repoint commit references after the history rewrite
The anonymisation rewrite of 2026-08-07 gave every touched commit a new SHA, leaving the references in these documents pointing at objects that no longer exist. The mapping was reconstructed from the backup branches and each pair verified by tree and commit message before substituting.

Prefix lookups were built for lengths 7 to 12 and any ambiguous prefix would have been skipped; none were ambiguous across all 251 pairs.
2026-08-09 12:00:00 +00:00

124 lines
7.0 KiB
Markdown

# 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).
## 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:
- **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.
- **`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.
**Verifiziert** am CI-Artefakt von Pipeline 189 (`ac688d3`), 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.
## 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.