Files
local-transcription/server/nodejs
jknapp 89819f5d1b Add user-configurable colors for transcription display
- Add color settings (user_color, text_color, background_color) to config
- Add color picker buttons in Settings dialog with alpha support for backgrounds
- Update local web display to use configurable colors
- Send per-user colors with transcriptions to multi-user server
- Update Node.js server to apply per-user colors on display page
- Improve server landing page: replace tech details with display options reference
- Bump version to 1.3.2

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:59:13 -08:00
..
2025-12-26 16:15:52 -08:00
2025-12-26 16:15:52 -08:00

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

cd server/nodejs
npm install

Run the Server

# Production
npm start

# Development (auto-restart on changes)
npm run dev

The server will start on port 3000 by default.

Change Port

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

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

GET /api/list?room=my-room

WebSocket Connection

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.)

# 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:

FROM node:18-alpine

WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .

EXPOSE 3000
CMD ["npm", "start"]

Run:

docker build -t transcription-server .
docker run -p 3000:3000 -v ./data:/app/data transcription-server

Option 3: Heroku (Free Tier)

# 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.)

# 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:

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):

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com

Environment Variables

PORT=3000              # Server port (default: 3000)
DATA_DIR=/path/to/data # Data directory (default: ./data)

Monitoring

With PM2:

pm2 logs transcription-server  # View logs
pm2 monit                       # Monitor resources
pm2 restart transcription-server # Restart

Check if running:

curl http://localhost:3000/

Troubleshooting

Port already in use

# 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.