Skip to content

X Server

The X Server is a Node.js automation server that handles platform-specific publishing via Playwright browser automation, API integrations, video processing, and AI-powered features.

Repository Location

The X Server source code is located in the x repository: AmericanMedia/x

Overview

Why X Server?

Many platforms don't have official APIs for all needed operations (especially livestream creation). The X Server uses Playwright to automate browser interactions and integrates with APIs where available:

  • Livestream Creation — Set up streams on platforms without APIs
  • Video Uploads — Upload with full metadata control
  • Stream Key Retrieval — Get RTMP credentials programmatically
  • Video Processing — FFmpeg-based video editing and conversion
  • AI Analysis — OpenAI/LangChain integration for content analysis
  • CDN Upload — Direct upload to Bunny CDN storage

Technology Stack

TechnologyVersionPurpose
Node.js20+Runtime
Express4.xHTTP Server
Playwright1.57+Browser automation
FFmpeg5.xVideo processing
OpenAI4.xAI integrations
LangChain0.3.xAI orchestration
Axios1.xHTTP client

Configuration

Set the X Server URL in your environment:

bash
X_SERVER_URL=http://your-x-server:3000

Supported Endpoints

Livestream Endpoints

EndpointPlatformDescription
/rumble-createRumbleCreate livestream, get RTMP
/rumble-deleteRumbleDelete livestream
/youtube-createYouTubeCreate YouTube Live
/youtube-deleteYouTubeDelete YouTube Live
/boxcast-livestreamBoxcastCreate Boxcast broadcast
/boxcast-deleteBoxcastDelete Boxcast broadcast
/brighteon-createBrighteonCreate Brighteon stream
/odysee-createOdyseeCreate Odysee stream
/restream-createRestreamCreate Restream event
/banned-createBanned.VideoCreate Banned.Video stream

Upload Endpoints

EndpointPlatformDescription
/rumble-episodeRumbleUpload video to Rumble
/rumble-latest-episodeRumbleScrape latest episode info
/rumble-latest-episodesRumbleScrape multiple episodes
/boxcast-media-uploadBoxcastUpload media file
/boxcast-createBoxcastCreate broadcast
/brighteon-uploadBrighteonUpload video
/brighteon-statusBrighteonCheck upload status
/odysee-uploadOdyseeUpload video
/odysee-statusOdyseeCheck upload status
/banned-statusBanned.VideoCheck upload status
/bitchute-createBitchuteCreate Bitchute content
/bitchute-uploadBitchuteUpload video
/bitchute-statusBitchuteCheck upload status
/transistor-uploadTransistorUpload podcast episode
/transistor-transcriptTransistorGet podcast transcripts
/substack-createSubstackCreate newsletter post
/substack-uploadSubstackUpload to Substack
/substack-exportSubstackExport Substack content

CDN & Storage Endpoints

EndpointServiceDescription
/bunny-storage-uploadBunny CDNUpload single file to storage
/bunny-storage-upload-multipleBunny CDNUpload multiple files
/bunny-stream-uploadBunny CDNUpload to streaming library
/bunny-create-folderBunny CDNCreate storage folder

Video Processing Endpoints

EndpointDescription
/video-editor/exportExport edited video with segments
/video-editor/status/:videoIdCheck export status
/video-editor/transcribeTranscribe video using Deepgram
/clips/youtube-downloadDownload YouTube video for clips
/descript-uploadUpload to Descript
/descript-create-projectCreate Descript project
/descript-statusCheck Descript status

Social & Integration Endpoints

EndpointServiceDescription
/ayrshare-createAyrshareCreate social post
/ayrshare-deleteAyrshareDelete social post
/fb-store-tokenFacebookStore Facebook auth token
/shortlinkShort.ioCreate short links
/telegramTelegramSend Telegram messages

Utility Endpoints

EndpointDescription
/statusServer health check
/webhookGit pull and restart webhook
/nocodb/*NocoDB database proxy
/n8n/*n8n workflow triggers
/runpod/*RunPod GPU operations
/cloudflare-traceCloudflare trace lookup

Request/Response Format

Livestream Request

json
POST /rumble-create
{
  "title": "Episode 42: The Future",
  "description": "Join us for an exciting discussion...",
  "scheduledAt": "2026-02-10T14:00:00.000Z",
  "thumbnailUrl": "https://example.com/thumb.jpg",
  "visibility": "public"
}

Livestream Response

json
{
  "success": true,
  "platformId": "v12345",
  "platformUrl": "https://rumble.com/v12345-episode-42.html",
  "streamUrl": "rtmp://live.rumble.com/live",
  "streamKey": "abc123xyz"
}

Upload Request

json
POST /rumble-episode
{
  "title": "Episode 42: The Future",
  "description": "Full episode description...",
  "videoUrl": "https://cdn.example.com/video.mp4",
  "thumbnailUrl": "https://example.com/thumb.jpg",
  "tags": "podcast,tech,ai",
  "visibility": "public"
}

Upload Response

json
{
  "success": true,
  "platformId": "v67890",
  "platformUrl": "https://rumble.com/v67890-episode-42.html"
}

Video Editor Export Request

json
POST /video-editor/export
{
  "videoId": "abc123",
  "files": [
    {
      "url": "https://cdn.example.com/source.mp4",
      "keepSegments": [[0, 10.5], [15.2, 30.0], [45.0, 60.0]]
    }
  ]
}

Video Editor Status Response

json
GET /video-editor/status/abc123
{
  "status": "completed",
  "progress": 100,
  "outputUrl": "https://cdn.example.com/output.mp4"
}

Project Structure

x/
├── server.js              # Main Express server
├── routes/                # Route handlers
│   ├── index.js           # Route registration
│   ├── rumble.js          # Rumble endpoints
│   ├── youtube.js         # YouTube endpoints
│   ├── boxcast.js         # Boxcast endpoints
│   ├── brighteon.js       # Brighteon endpoints
│   ├── odysee.js          # Odysee endpoints
│   ├── transistor.js      # Transistor endpoints
│   ├── substack.js        # Substack endpoints
│   ├── bunny.js           # Bunny CDN endpoints
│   ├── video-editor.js    # Video editing endpoints
│   ├── clips.js           # Clip creation endpoints
│   ├── ayrshare.js        # Social media endpoints
│   └── ...                # Additional platform routes
├── helpers/               # Business logic
│   ├── rumble/            # Rumble automation
│   ├── youtube/           # YouTube automation
│   ├── boxcast/           # Boxcast integration
│   ├── brighteon/         # Brighteon automation
│   ├── odysee/            # Odysee automation
│   ├── substack/          # Substack automation
│   ├── transistor/        # Transistor API
│   ├── bunny/             # Bunny CDN client
│   ├── video-editor/      # FFmpeg processing
│   ├── openai/            # AI integrations
│   ├── storage/           # File storage helpers
│   ├── sessions/          # Browser sessions
│   ├── loggers/           # Logging utilities
│   └── ...                # Additional helpers
├── scripts/               # Standalone scripts
├── public/                # Static assets
└── .auth/                 # Browser auth state (gitignored)

Running the Server

Development Mode

bash
# Using npm script
npm run dev

# Or directly
./dev-start.sh

Production Mode

bash
# With Playwright browsers
npm run prod

# Or directly
./start-playwright.sh

Docker Deployment

bash
docker build -t x-server .
docker run -d -p 3000:3000 --name x-server x-server

Environment Variables

VariableRequiredDescription
PORTNoServer port (default: 3000)
ENVNoEnvironment mode (development/production)
BUNNY_MEDIAMAGIC_API_KEYYesBunny CDN API key
DEEPGRAM_API_KEYYesDeepgram transcription key
OPENAI_API_KEYYesOpenAI API key
AYRSHARE_API_KEYYesAyrshare social API key

Bridge Integration

The Bridge forwards requests to X Server:

javascript
// bridge/helpers/xserver/client.js
import axios from 'axios';

const client = axios.create({
  baseURL: process.env.X_SERVER_URL,
  timeout: 300000, // 5 min for uploads
});

export async function createLivestream(platform, data) {
  const endpoint = PLATFORM_ROUTES[platform].livestream;
  const response = await client.post(endpoint, data);
  return response.data;
}

export async function uploadContent(platform, data) {
  const endpoint = PLATFORM_ROUTES[platform].upload;
  const response = await client.post(endpoint, data);
  return response.data;
}

Platform Credentials

The X Server stores platform credentials internally in the .auth/ directory (gitignored):

x/
├── .auth/                 # Browser authentication state
│   ├── rumble/            # Rumble session cookies
│   ├── youtube/           # YouTube auth tokens
│   └── ...                # Other platform sessions
├── .env                   # Environment variables (gitignored)
└── .facebook-auth/        # Facebook-specific auth

Browser Session Management

Playwright sessions are persisted to avoid re-authentication:

javascript
// helpers/sessions/getSession.js
import { chromium } from 'playwright';

export async function getSession(platform) {
  const userDataDir = `.auth/${platform}`;
  const browser = await chromium.launchPersistentContext(userDataDir, {
    headless: process.env.NODE_ENV === 'production'
  });
  return browser;
}

Error Handling

X Server errors are captured and stored in EspoCRM:

json
{
  "success": false,
  "error": "Authentication failed",
  "code": "AUTH_ERROR",
  "details": "Session expired, re-login required"
}

The Bridge updates the PlatformPublish record:

javascript
await espoClient.update('PlatformPublish', id, {
  status: 'Failed',
  apiResponse: JSON.stringify(error)
});

Retry Logic

When X Server fails:

  1. Check apiResponse field in EspoCRM for error details
  2. Resolve the issue (re-auth, fix data, etc.)
  3. Set status back to "Queued" to retry

Health Check

bash
curl http://your-x-server:3000/status

Expected response:

json
{
  "ok": true,
  "environment": "Digital Ocean",
  "hostname": "x-server",
  "user": "root",
  "port": 3000,
  "mode": "production"
}

Deployment Options

Local Development

bash
cd x
npm install
npm run dev

Digital Ocean Droplet

The server can be deployed to a Digital Ocean droplet and accessed via ngrok or direct IP.

RunPod GPU

For GPU-intensive operations (video processing), the server can run on RunPod.

NPM Scripts

ScriptDescription
npm run devStart in development mode with nodemon
npm run prodStart in production mode with Playwright
npm run stopStop the server
npm run statusCheck if server is running
npm run reset-authReset authentication sessions
npm run killForce kill server and ngrok
npm run brighteon-uploadRun standalone Brighteon upload

Security Considerations

Credentials

X Server stores platform passwords/cookies. Ensure it's properly secured:

  • Run on internal network only or behind VPN
  • Use environment variables for sensitive data
  • Regular credential rotation
  • Audit logging via helpers/loggers/
  • .auth/ directory is gitignored

MediaMagic CRM Documentation