Enhanced JavaScript debugging with: - Detailed connection state logging (CONNECTING/OPEN/CLOSED) - EventSource object inspection - Real-time readyState monitoring - Verbose error information (type, target, readyState) - URL and location details for troubleshooting - Console grouping for organized output This will help diagnose SSE connection issues by providing detailed information in the browser console. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
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:
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:
{
"service": "Local Transcription Multi-User Server",
"version": "1.0.0",
...
}
Usage
For Streamers (Desktop App)
- Open the Local Transcription app
- Go to Settings
- Enable "Server Sync"
- 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")
- Server URL:
- Start transcription
For OBS (Browser Source)
-
Add a "Browser" source in OBS
-
Set URL to:
https://your-domain.com/transcription/display.php?room=ROOM&passphrase=PASS&fade=10×tamps=trueReplace:
ROOM= Your room namePASS= Your passphrasefade=10= Seconds before text fades (0 = never)timestamps=true= Show timestamps (false to hide)
-
Set width/height as desired (e.g., 1920x300)
-
Check "Shutdown source when not visible" (optional)
API Endpoints
Send Transcription
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)
GET /server.php?action=stream&room=my-room&passphrase=my-secret
Returns Server-Sent Events stream with new transcriptions.
List Recent Transcriptions
GET /server.php?action=list&room=my-room&passphrase=my-secret
Returns JSON array of recent transcriptions.
Configuration
Edit config.php to customize:
// 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
- Use strong passphrases (e.g.,
MyStream2024!SecurePass) - Don't share passphrases publicly
- Use unique room names (e.g., include date/time)
- Enable HTTPS on your server
- 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
chmod 755 /path/to/transcription
# Data directory will be created automatically
Server disconnects frequently
- Increase PHP's
max_execution_timefor SSE: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:
// 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:
- Check this README
- Review server logs
- Test with browser's Network tab
- Create an issue on GitHub