Files
local-transcription/server/php
Josh Knapp 2870d45bdc Add Apache ProxyTimeout configuration for SSE support
Created apache-sse-config.conf with required Apache settings to support
long-running SSE connections. Apache's mod_proxy_fcgi has a default
timeout of 30-60 seconds which kills SSE connections prematurely.

The configuration sets ProxyTimeout to 21600 seconds (6 hours) to match
HAProxy's timeout and allow long streaming sessions.

Added note to .htaccess explaining this requirement, as ProxyTimeout
cannot be set in .htaccess and must be configured in the virtual host.

To fix 504 Gateway Timeout errors:
1. Add ProxyTimeout directive to Apache virtual host config
2. Reload Apache
3. Test SSE connection

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-26 15:29:56 -08:00
..

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)

  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&timestamps=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

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

  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

chmod 755 /path/to/transcription
# Data directory will be created automatically

Server disconnects frequently

  • Increase PHP's max_execution_time for 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:

  1. Check this README
  2. Review server logs
  3. Test with browser's Network tab
  4. Create an issue on GitHub