Add multi-user server sync (PHP server + client)

Phase 2 implementation: Multiple streamers can now merge their captions
into a single stream using a PHP server.

PHP Server (server/php/):
- server.php: API endpoint for sending/streaming transcriptions
- display.php: Web page for viewing merged captions in OBS
- config.php: Server configuration
- .htaccess: Security settings
- README.md: Comprehensive deployment guide

Features:
- Room-based isolation (multiple groups on same server)
- Passphrase authentication per room
- Real-time streaming via Server-Sent Events (SSE)
- Different colors for each user
- File-based storage (no database required)
- Auto-cleanup of old rooms
- Works on standard PHP hosting

Client-Side:
- client/server_sync.py: HTTP client for sending to PHP server
- Settings dialog updated with server sync options
- Config updated with server_sync section

Server Configuration:
- URL: Server endpoint (e.g., http://example.com/transcription/server.php)
- Room: Unique room name for your group
- Passphrase: Shared secret for authentication

OBS Integration:
Display URL format:
http://example.com/transcription/display.php?room=ROOM&passphrase=PASS&fade=10&timestamps=true

NOTE: Main window integration pending (client sends transcriptions)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-26 10:09:12 -08:00
parent aa8c294fdc
commit 9c3a0d7678
8 changed files with 982 additions and 2 deletions

View File

@@ -147,6 +147,29 @@ class SettingsDialog(QDialog):
display_group.setLayout(display_layout)
main_layout.addWidget(display_group)
# Server Sync Group
server_group = QGroupBox("Multi-User Server Sync (Optional)")
server_layout = QFormLayout()
self.server_enabled_check = QCheckBox()
server_layout.addRow("Enable Server Sync:", self.server_enabled_check)
self.server_url_input = QLineEdit()
self.server_url_input.setPlaceholderText("http://example.com/transcription/server.php")
server_layout.addRow("Server URL:", self.server_url_input)
self.server_room_input = QLineEdit()
self.server_room_input.setPlaceholderText("my-room-name")
server_layout.addRow("Room Name:", self.server_room_input)
self.server_passphrase_input = QLineEdit()
self.server_passphrase_input.setEchoMode(QLineEdit.Password)
self.server_passphrase_input.setPlaceholderText("shared-secret")
server_layout.addRow("Passphrase:", self.server_passphrase_input)
server_group.setLayout(server_layout)
main_layout.addWidget(server_group)
# Buttons
button_layout = QHBoxLayout()
button_layout.addStretch()
@@ -210,6 +233,12 @@ class SettingsDialog(QDialog):
self.font_size_input.setText(str(self.config.get('display.font_size', 12)))
self.fade_seconds_input.setText(str(self.config.get('display.fade_after_seconds', 10)))
# Server sync settings
self.server_enabled_check.setChecked(self.config.get('server_sync.enabled', False))
self.server_url_input.setText(self.config.get('server_sync.url', ''))
self.server_room_input.setText(self.config.get('server_sync.room', 'default'))
self.server_passphrase_input.setText(self.config.get('server_sync.passphrase', ''))
def _save_settings(self):
"""Save settings to config."""
try:
@@ -248,6 +277,12 @@ class SettingsDialog(QDialog):
fade_seconds = int(self.fade_seconds_input.text())
self.config.set('display.fade_after_seconds', fade_seconds)
# Server sync settings
self.config.set('server_sync.enabled', self.server_enabled_check.isChecked())
self.config.set('server_sync.url', self.server_url_input.text())
self.config.set('server_sync.room', self.server_room_input.text())
self.config.set('server_sync.passphrase', self.server_passphrase_input.text())
# Call save callback
if self.on_save:
self.on_save()