Add call recording integration

This commit is contained in:
Sven committed 2026-11-02 11:45:41 +01:00
1 parent ce9e6816f8
commit b081ab275b
15 files changed
+1058 -19

No files matched your search

+107
View File
@@ -667,3 +667,110 @@ relevant:
- [IClientLineMgrPub](https://clientsdk.swyx.engineering/interface_i_client_line_mgr_pub.html)
- [CLMgrPubTypes.h — PubCLMgrMessages](https://clientsdk.swyx.engineering/_c_l_mgr_pub_types_8h.html)
- [NuGet: Swyx.Client.ClmgrAPI](https://www.nuget.org/packages/Swyx.Client.ClmgrAPI)
## Gespraechsaufnahme (WebSocket-Protokoll 10)
Aufnahmebefehle verwenden die 1-basierte `line` **und** `callId` aus dem aktuellen
Snapshot. `callId` stammt aus `IClientLineDisp.DispCallId`. Ein alter Auftrag wird
abgewiesen, wenn inzwischen ein anderer Anruf dieselbe Leitung belegt.
```json
{"id":21,"cmd":"recording.start","line":1,"callId":4711}
{"type":"result","id":21,"ok":true,"line":1,"callId":4711,"recordingRequested":true}
{"id":22,"cmd":"recording.stop","line":1,"callId":4711}
{"type":"result","id":22,"ok":true,"line":1,"callId":4711,"recordingRequested":false}
{"type":"call","event":"ended","line":1,"callId":4711,"peer":"Test","peerNumber":"123","peerName":"Test"}
```
`recording.start` ruft `DispStartRecording()` auf, sobald eine Sprechverbindung
besteht. Ein wiederholter Start desselben Anrufs ist wirkungslos. Stoppen ruft
`DispStopRecording()` auf, auch bei gehaltenen Gespraechen oder wenn die Aufnahme
in SwyxIt! selbst gestartet wurde. Fehler des SDK werden als `ok:false` gemeldet.
Alle COM-Zugriffe laufen weiterhin im STA-Thread.
`recordingRequested` in den Leitungs-Snapshots bezeichnet den letzten erfolgreich
an das SDK uebergebenen Auftrag dieser App. Das SDK stellt keinen lesbaren
Aufnahmestatus bereit; das Feld bestaetigt weder eine geschriebene Datei noch
manuelle Aenderungen in SwyxIt!. Dateiname und Speicherort bestimmt SwyxIt!
entsprechend seiner Aufnahmekonfiguration. Die SDK-Funktion setzt den normalen
Betriebsmodus und die Aufnahmeberechtigung voraus; eine Audiodatei wird nicht
ueber WebSocket uebertragen.
SwyxWeb sendet `answer` mit der Anrufkennung, wartet auf die aktive
Sprechverbindung desselben Anrufs und sendet dann `recording.start`. Ein Fehler
beim Start aendert nichts an der erfolgreichen Anrufannahme. Auflegen, Abbruch,
Wiederverwendung der Leitung und ein Timeout verhindern den verspaeteten Start.
`call/ended` folgt weiterhin auf den Snapshot und enthaelt die Kennung und
Gegenstelle des beendeten Anrufs. Ein Ausfall von CLMgr/Server wird nicht als
nachgewiesenes Gespraechsende gemeldet.
Pruefung ohne Telefonate oder COM-Aufrufe:
```powershell
dotnet build src/SwyxTray/SwyxTray.csproj -p:Platform=x64
dotnet run --project tests/SwyxTray.RecordingChecks -p:Platform=x64
```
API-Grundlage: [Swyx Client SDK, IClientLineDisp](https://www.swyxdownload.com/download/kb3373_SwyxClientSDKManual.pdf),
Methodensignaturen gegen das installierte NuGet-Paket 14.21.0 geprueft.
## Automatische WAV-Übergabe an SwyxWeb (Protokoll 11)
`recording.start` und `recording.stop` akzeptieren zusätzlich `recordingId` (UUID).
Snapshots und Aufnahmequittungen geben dieselbe Kennung zurück. Ein doppelter Start
behält die UUID bei; ein neuer Abschnitt erhält eine neue. Die Zuordnung bleibt bei
COM-Unterbrechungen erhalten; nur ein bestätigter Stopp oder ein gesunder Snapshot
mit beendeter/ersetzter Verbindung schließt den Abschnitt ab.
Der Aufnahmestopp allein gibt die Datei nicht zur Übertragung frei. Erst ein
gesunder Snapshot mit beendeter oder ersetzter Verbindung bestätigt das
Gesprächsende für alle Aufnahmeabschnitte dieses Gesprächs. Halten und ein
Verbindungsabbruch zählen nicht als Ende; die Sperre übersteht einen Neustart.
Ob SwyxWeb, SwyxIt!, das Telefon oder die Gegenstelle beendet hat, ist dabei
unerheblich. Auch `LSTerminated`, freigegebene/deaktivierte Leitungen und eine
neue Anrufkennung lösen die Übergabe ohne vorherigen `hangup`- oder
`recording.stop`-Befehl aus. Nach einer Unterbrechung genügt die Bestätigung
des Gesprächsendes im nächsten gesunden Snapshot.
Die neue `RecordingOutbox` liest den Aufnahmeordner aus `IClientConfig` und merkt
beim Start die bereits vorhandenen WAV-Dateien. Sie bietet nur eindeutig zuordenbare,
neu erzeugte, geschlossene WAVs mit stabiler Länge und gültigem RIFF-Dateikopf an.
Mehrdeutige Dateien werden als Fehler gemeldet und müssen in SwyxWeb manuell
zugeordnet werden. Originaldateien bleiben unverändert. Über SwyxIt! selbst
begonnene Mitschnitte haben keine automatische Zuordnung.
Warteschlange: `%LOCALAPPDATA%\SwyxTray\recordings` (atomare JSON-Manifeste und WAV-Kopien).
Unbestätigte Dateien überstehen Neustarts. `recording.ready` wird erst nach
bestätigtem Gesprächsende gesendet und enthält `transport: "websocket"`,
`recordingId`, `line`, `callId`, `callEnded: true`, `filename`, `bytes` und Gegenstelle.
Vorher meldet `recording.status` den Zustand `waiting_call_end`; die WAV darf lokal
vorbereitet werden, aber `recording.download` und `recording.ack` werden abgewiesen.
Es wird kein zusätzlicher HTTP-Endpunkt eingerichtet. Auf `recording.download`
mit UUID und Kommando-ID sendet die bestehende Sitzung binäre Nachrichten:
`SWYX` (4 ASCII-Bytes), Kommando-ID (Int32 LE), Offset (Int32 LE), maximal 65536 Audio-Bytes.
Am Ende folgt die normale `result`-Quittung. Telefonbefehle bleiben parallel nutzbar.
SwyxWeb reicht die WAV an sein Backend und von dort an SwyxTrans weiter. Erst danach
bestätigt der Browser mit `recording.ack`, `recordingId` und `jobId` (32 Hexzeichen).
Die Bestätigung wird vor dem Entfernen der temporären Kopie gespeichert. Das Original
wird nie entfernt. `recording.status` zeigt `waiting_call_end`, `waiting`, `error`, `submitted`; bei letzterem
enthält `jobId` die SwyxTrans-Kennung. Beim Verbinden und auf `status` werden alle offenen
Aufnahmen und die letzten 100 bestätigten Aufträge wiederholt. SwyxWeb verhindert
Doppelverarbeitung zusätzlich durch idempotente Uploads. Der Browser muss für die
Übertragung geöffnet und verbunden sein.
`hangup` akzeptiert zusätzlich `callId` und prüft unmittelbar vor dem SDK-Aufruf,
ob die Leitung noch genau dieses Gespräch führt. SwyxWeb deaktiviert **Auflegen**
während des Befehls und wartet auch nach dessen Quittung auf das bestätigte Ende.
Prüfungen ohne COM/Telefonate:
```powershell
dotnet run --project tests/SwyxTray.RecordingChecks -p:Platform=x64
dotnet build src/SwyxTray -p:Platform=x64
```
Die Checks prüfen außerdem Windows-Dateisperren, unvollständige WAVs, mehrdeutige
Zuordnung, dauerhaft gespeicherte Bestätigungen und den tatsächlichen Binärtransport
mit Verbindungsabbruch. `-- --serve` startet bei Bedarf eine lokale Browser-Testquelle
auf Port 17658 mit einer synthetischen WAV, ohne COM-Verbindung und ohne Telefonat.