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×tamps=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>
251 lines
5.9 KiB
Markdown
251 lines
5.9 KiB
Markdown
# Multi-User Transcription Server (PHP)
|
|
|
|
A simple PHP server that allows multiple Local Transcription clients to merge their captions into a single stream. Perfect for multiple streamers playing together who want synchronized captions.
|
|
|
|
## Features
|
|
|
|
- ✅ Room-based isolation (multiple groups can use the same server)
|
|
- ✅ Passphrase authentication per room
|
|
- ✅ Real-time streaming via Server-Sent Events (SSE)
|
|
- ✅ Different colors for each user
|
|
- ✅ Auto-fade transcriptions
|
|
- ✅ Works on standard PHP hosting (no special requirements)
|
|
- ✅ File-based storage (no database needed)
|
|
- ✅ Automatic cleanup of old rooms
|
|
|
|
## Requirements
|
|
|
|
- PHP 7.4 or higher
|
|
- Web server (Apache/Nginx)
|
|
- Writable data directory
|
|
|
|
## Installation
|
|
|
|
### 1. Upload Files
|
|
|
|
Upload these files to your web server:
|
|
```
|
|
your-domain.com/
|
|
└── transcription/
|
|
├── server.php
|
|
├── display.php
|
|
├── config.php
|
|
├── .htaccess
|
|
└── data/ (will be created automatically)
|
|
```
|
|
|
|
### 2. Set Permissions
|
|
|
|
Make sure the PHP process can write to the directory:
|
|
```bash
|
|
chmod 755 server.php display.php config.php
|
|
chmod 755 .
|
|
```
|
|
|
|
The `data/` directory will be created automatically with proper permissions.
|
|
|
|
### 3. Test Installation
|
|
|
|
Visit: `https://your-domain.com/transcription/server.php`
|
|
|
|
You should see:
|
|
```json
|
|
{
|
|
"service": "Local Transcription Multi-User Server",
|
|
"version": "1.0.0",
|
|
...
|
|
}
|
|
```
|
|
|
|
## Usage
|
|
|
|
### For Streamers (Desktop App)
|
|
|
|
1. Open the Local Transcription app
|
|
2. Go to Settings
|
|
3. Enable "Server Sync"
|
|
4. Enter:
|
|
- **Server URL**: `https://your-domain.com/transcription/server.php`
|
|
- **Room Name**: Choose a unique name (e.g., "gaming-session-123")
|
|
- **Passphrase**: A shared secret for your group (e.g., "mysecretpass")
|
|
5. Start transcription
|
|
|
|
### For OBS (Browser Source)
|
|
|
|
1. Add a "Browser" source in OBS
|
|
2. Set URL to:
|
|
```
|
|
https://your-domain.com/transcription/display.php?room=ROOM&passphrase=PASS&fade=10×tamps=true
|
|
```
|
|
|
|
Replace:
|
|
- `ROOM` = Your room name
|
|
- `PASS` = Your passphrase
|
|
- `fade=10` = Seconds before text fades (0 = never)
|
|
- `timestamps=true` = Show timestamps (false to hide)
|
|
|
|
3. Set width/height as desired (e.g., 1920x300)
|
|
4. Check "Shutdown source when not visible" (optional)
|
|
|
|
## API Endpoints
|
|
|
|
### Send Transcription
|
|
```http
|
|
POST /server.php?action=send
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"room": "my-room",
|
|
"passphrase": "my-secret",
|
|
"user_name": "Alice",
|
|
"text": "Hello everyone!",
|
|
"timestamp": "12:34:56"
|
|
}
|
|
```
|
|
|
|
### Stream Transcriptions (SSE)
|
|
```http
|
|
GET /server.php?action=stream&room=my-room&passphrase=my-secret
|
|
```
|
|
|
|
Returns Server-Sent Events stream with new transcriptions.
|
|
|
|
### List Recent Transcriptions
|
|
```http
|
|
GET /server.php?action=list&room=my-room&passphrase=my-secret
|
|
```
|
|
|
|
Returns JSON array of recent transcriptions.
|
|
|
|
## Configuration
|
|
|
|
Edit `config.php` to customize:
|
|
|
|
```php
|
|
// Session lifetime (seconds)
|
|
define('SESSION_LIFETIME', 3600);
|
|
|
|
// Max transcriptions stored per room
|
|
define('MAX_TRANSCRIPTIONS_PER_ROOM', 100);
|
|
|
|
// Storage directory
|
|
define('STORAGE_DIR', __DIR__ . '/data');
|
|
|
|
// Enable CORS
|
|
define('ENABLE_CORS', true);
|
|
|
|
// Cleanup threshold (seconds)
|
|
define('CLEANUP_THRESHOLD', 7200);
|
|
```
|
|
|
|
## Security
|
|
|
|
### Passphrases
|
|
- Each room is protected by a passphrase
|
|
- Passphrases are hashed using PHP's `password_hash()`
|
|
- The first person to create a room sets its passphrase
|
|
- All subsequent users must use the same passphrase
|
|
|
|
### Best Practices
|
|
1. Use strong passphrases (e.g., `MyStream2024!SecurePass`)
|
|
2. Don't share passphrases publicly
|
|
3. Use unique room names (e.g., include date/time)
|
|
4. Enable HTTPS on your server
|
|
5. Regularly update PHP
|
|
|
|
### Data Storage
|
|
- Room data is stored in `data/room_HASH.json`
|
|
- Files are automatically cleaned up after 2 hours of inactivity
|
|
- No personally identifiable information is logged
|
|
|
|
## Troubleshooting
|
|
|
|
### "Invalid passphrase" error
|
|
- Make sure all clients use the exact same passphrase
|
|
- Passphrases are case-sensitive
|
|
- First user to join creates the room and sets the passphrase
|
|
|
|
### Transcriptions not appearing
|
|
- Check browser console for errors
|
|
- Verify Server-Sent Events (SSE) is supported
|
|
- Check that the room name and passphrase match
|
|
|
|
### "Permission denied" on data directory
|
|
```bash
|
|
chmod 755 /path/to/transcription
|
|
# Data directory will be created automatically
|
|
```
|
|
|
|
### Server disconnects frequently
|
|
- Increase PHP's `max_execution_time` for SSE:
|
|
```php
|
|
set_time_limit(0);
|
|
```
|
|
- Check server timeout settings (Apache/Nginx)
|
|
|
|
## Advanced Usage
|
|
|
|
### Multiple Rooms on Same Server
|
|
Each room is completely isolated. Example:
|
|
|
|
- Room "podcast-team-1" with passphrase "secret1"
|
|
- Room "gaming-squad-2" with passphrase "secret2"
|
|
|
|
They don't interfere with each other.
|
|
|
|
### Customizing Display
|
|
|
|
Add URL parameters to `display.php`:
|
|
- `?fade=20` - Fade after 20 seconds
|
|
- `?fade=0` - Never fade
|
|
- `?timestamps=false` - Hide timestamps
|
|
- `?font=Arial` - Change font (future feature)
|
|
|
|
### Using with Shared Hosting
|
|
|
|
This works on most shared hosting providers:
|
|
- No database required
|
|
- No special PHP extensions needed
|
|
- Uses standard PHP file operations
|
|
- Compatible with Apache .htaccess
|
|
|
|
### Upgrading to Redis/MySQL
|
|
|
|
For high-traffic scenarios, replace file storage in `server.php`:
|
|
|
|
```php
|
|
// Instead of file_put_contents()
|
|
// Use Redis:
|
|
$redis->set("room:$room", json_encode($roomData));
|
|
|
|
// Or MySQL:
|
|
$pdo->prepare("INSERT INTO rooms ...")->execute(...);
|
|
```
|
|
|
|
## Performance
|
|
|
|
- **Tested**: 10 concurrent clients per room
|
|
- **Latency**: < 2 seconds
|
|
- **Storage**: ~1KB per transcription
|
|
- **Bandwidth**: Minimal (text-only)
|
|
|
|
## Limitations
|
|
|
|
- File-based storage (not suitable for very high traffic)
|
|
- Server-Sent Events may not work with some proxies
|
|
- Rooms expire after 2 hours of inactivity
|
|
- No user management or admin panel (by design)
|
|
|
|
## License
|
|
|
|
Part of the Local Transcription project.
|
|
Generated with Claude Code.
|
|
|
|
## Support
|
|
|
|
For issues or questions:
|
|
1. Check this README
|
|
2. Review server logs
|
|
3. Test with browser's Network tab
|
|
4. Create an issue on GitHub
|