Files
local-transcription/server/nodejs/README.md
jknapp ff067b3368 Add unified per-speaker font support and remote transcription service
Font changes:
- Consolidate font settings into single Display Settings section
- Support Web-Safe, Google Fonts, and Custom File uploads for both displays
- Fix Google Fonts URL encoding (use + instead of %2B for spaces)
- Fix per-speaker font inline style quote escaping in Node.js display
- Add font debug logging to help diagnose font issues
- Update web server to sync all font settings on settings change
- Remove deprecated PHP server documentation files

New features:
- Add remote transcription service for GPU offloading
- Add instance lock to prevent multiple app instances
- Add version tracking

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 19:09:57 -08:00

312 lines
6.6 KiB
Markdown

# Node.js Multi-User Transcription Server
A real-time multi-user transcription sync server for streamers and teams.
## Features
- **Real-time WebSocket** - Instant message delivery (< 100ms latency)
- **Per-speaker fonts** - Each user can have their own font style
- **Google Fonts support** - 1000+ free fonts loaded from CDN
- **Web-safe fonts** - Universal fonts that work everywhere
- **Custom font uploads** - Upload your own .ttf/.woff2 files
- **Easy deployment** - Works on any VPS, cloud platform, or locally
## Quick Start
### Installation
```bash
cd server/nodejs
npm install
```
### Run the Server
```bash
# Production
npm start
# Development (auto-restart on changes)
npm run dev
```
The server will start on port 3000 by default.
### Change Port
```bash
PORT=8080 npm start
```
## Usage
### For Desktop App Users
1. Open Local Transcription app
2. Go to Settings → Server Sync
3. Enable "Server Sync"
4. Enter:
- **Server URL**: `http://your-server.com:3000/api/send`
- **Room Name**: Your room (e.g., "my-stream-123")
- **Passphrase**: Shared secret (e.g., "mysecretpass")
### For OBS Browser Source
Add a Browser source with this URL:
```
http://your-server.com:3000/display?room=YOUR_ROOM&fade=10&timestamps=true&fontsource=websafe&websafefont=Arial
```
**Parameters:**
| Parameter | Default | Description |
|-----------|---------|-------------|
| `room` | default | Your room name (required) |
| `fade` | 10 | Seconds before text fades (0 = never fade) |
| `timestamps` | true | Show timestamps (true/false) |
| `maxlines` | 50 | Max lines visible (prevents scroll bars) |
| `fontsize` | 16 | Font size in pixels |
| `fontsource` | websafe | Font source: `websafe`, `google`, or `custom` |
| `websafefont` | Arial | Web-safe font name |
| `googlefont` | Roboto | Google Font name |
**Font Examples:**
```
# Web-safe font (works everywhere)
?room=myroom&fontsource=websafe&websafefont=Courier+New
# Google Font (loaded from CDN)
?room=myroom&fontsource=google&googlefont=Open+Sans
# Custom font (uploaded by users)
?room=myroom&fontsource=custom
```
**Per-Speaker Fonts:**
Each user can set their own font in the desktop app (Settings → Multi-User Server Sync → Font Source). Per-speaker fonts override the URL defaults, so different speakers can have different fonts on the same display.
## API Endpoints
### Send Transcription
```http
POST /api/send
Content-Type: application/json
{
"room": "my-room",
"passphrase": "my-secret",
"user_name": "Alice",
"text": "Hello everyone!",
"timestamp": "12:34:56",
"font_family": "Open Sans", // Optional: per-speaker font
"font_type": "google" // Optional: websafe, google, or custom
}
```
### List Transcriptions
```http
GET /api/list?room=my-room
```
### WebSocket Connection
```javascript
const ws = new WebSocket('ws://localhost:3000/ws?room=my-room');
ws.onmessage = (event) => {
const transcription = JSON.parse(event.data);
console.log(transcription);
};
```
## Deployment Options
### Option 1: VPS (DigitalOcean, Linode, etc.)
```bash
# SSH into your server
ssh user@your-server.com
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# Clone/upload your code
cd /opt
git clone <your-repo>
cd local-transcription/server/nodejs
# Install dependencies
npm install --production
# Install PM2 (process manager)
sudo npm install -g pm2
# Start server with PM2
pm2 start server.js --name transcription-server
# Make it start on boot
pm2 startup
pm2 save
# Check status
pm2 status
```
### Option 2: Docker
Create `Dockerfile`:
```dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
```
Run:
```bash
docker build -t transcription-server .
docker run -p 3000:3000 -v ./data:/app/data transcription-server
```
### Option 3: Heroku (Free Tier)
```bash
# Install Heroku CLI
curl https://cli-assets.heroku.com/install.sh | sh
# Login
heroku login
# Create app
cd server/nodejs
heroku create my-transcription-server
# Deploy
git init
git add .
git commit -m "Initial commit"
git push heroku main
# Your URL will be: https://my-transcription-server.herokuapp.com
```
### Option 4: Railway.app (Free Tier)
1. Go to https://railway.app
2. Connect your GitHub repo
3. Select the `server/nodejs` directory
4. Deploy automatically
5. Railway will provide a URL
### Option 5: Local Network (LAN Party, etc.)
```bash
# Run on your local machine
npm start
# Find your local IP
# Linux/Mac: ifconfig | grep "inet "
# Windows: ipconfig
# Others connect to: http://YOUR_LOCAL_IP:3000
```
## Reverse Proxy (Nginx)
If you want to use port 80/443 with SSL:
```nginx
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```
For SSL (Let's Encrypt):
```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
```
## Environment Variables
```bash
PORT=3000 # Server port (default: 3000)
DATA_DIR=/path/to/data # Data directory (default: ./data)
```
## Monitoring
### With PM2:
```bash
pm2 logs transcription-server # View logs
pm2 monit # Monitor resources
pm2 restart transcription-server # Restart
```
### Check if running:
```bash
curl http://localhost:3000/
```
## Troubleshooting
### Port already in use
```bash
# Find process using port 3000
lsof -i :3000
# Or on Linux:
sudo netstat -tlnp | grep 3000
# Kill it
kill -9 <PID>
```
### Permission denied on port 80
Ports below 1024 require root. Either:
1. Use port 3000+ and reverse proxy with Nginx
2. Or run with sudo (not recommended)
### WebSocket connection fails
- Check firewall allows port 3000
- Verify server is running: `curl http://your-server:3000`
- Check browser console for errors
### Data not persisting
- Ensure `data/` directory is writable
- Check disk space
- Verify PM2 is running: `pm2 status`
## Security Recommendations
1. **Use HTTPS in production** - Set up Let's Encrypt with Nginx
2. **Firewall** - Only allow necessary ports
3. **Rate Limiting** - Add express-rate-limit if public
4. **Strong Passphrases** - Use long, random passphrases for rooms
5. **Regular Updates** - Keep Node.js and dependencies updated
## Performance
**Tested with:**
- 50 concurrent WebSocket connections
- 10 transcriptions/second
- Average latency: < 100ms
- Memory usage: ~50MB
## License
Part of the Local Transcription project.