Mux Sync Engine to sync Mux data based on webhooks to Postgres
npm install @mux/sync-engineMux Sync Engine is a service that syncs Mux data to Postgres based on webhooks. It provides an easy way to keep your database in sync with your Mux assets, live streams, and uploads.
- Automatic webhook signature verification: Ensures webhook events are genuine and from Mux
- Webhook callbacks: Run custom logic on webhook events
- Complete Mux event syncing: All Mux webhook events are synced to database tables for further analysis
- Backfill support: Sync existing Mux data to your database
- Related entity backfilling: Automatically ensures foreign key integrity by fetching related entities
The following Mux resources are automatically synced to your Postgres database under the mux schema:
- Assets (assets): Video assets, including encoding status, playback IDs, and metadata
- Live Streams (live_streams): Live streaming configurations and status
- Uploads (uploads): Direct upload URLs and their status
- Webhook Events (webhook_events): All webhook events for audit and debugging
``bash`
npm install @mux/sync-engine
`typescript
import { MuxSync, runMigrations } from '@mux/sync-engine';
// Run database migrations first
await runMigrations({
databaseUrl: 'postgresql://user:password@localhost:5432/database',
});
// Initialize the sync engine
const muxSync = new MuxSync({
databaseUrl: 'postgresql://user:password@localhost:5432/database',
muxTokenId: 'your-mux-token-id',
muxTokenSecret: 'your-mux-token-secret',
muxWebhookSecret: 'your-webhook-secret',
});
// Process a webhook (in your webhook handler)
app.post('/webhook', async (req, res) => {
try {
await muxSync.processWebhook(req.body, req.headers);
res.status(200).send('OK');
} catch (error) {
console.error('Webhook processing failed:', error);
res.status(400).send('Bad Request');
}
});
`
`typescript
const muxSync = new MuxSync({
databaseUrl: 'postgresql://user:password@localhost:5432/database',
muxTokenId: 'your-mux-token-id',
muxTokenSecret: 'your-mux-token-secret',
muxWebhookSecret: 'your-webhook-secret',
// Optional: Backfill related entities to ensure foreign key integrity
backfillRelatedEntities: true,
// Optional: Always fetch fresh data from Mux API instead of using webhook data
revalidateEntityViaMuxApi: false,
// Optional: Maximum number of Postgres connections
maxPostgresConnections: 10,
// Optional: Custom logger
logger: console,
});
`
You can backfill existing Mux data to your database:
`typescriptSynced ${result.muxAssets?.synced} assets
// Backfill all data
const result = await muxSync.syncBackfill({ object: 'all' });
console.log();Synced ${result.muxLiveStreams?.synced} live streams
console.log();Synced ${result.muxUploads?.synced} uploads
console.log();
// Backfill specific object types
await muxSync.syncBackfill({ object: 'mux_assets' });
await muxSync.syncBackfill({ object: 'mux_live_streams' });
await muxSync.syncBackfill({ object: 'mux_uploads' });
`
The sync engine creates tables under the mux schema:
- mux.assets - Video assets with encoding status and playback informationmux.live_streams
- - Live streaming configurationsmux.uploads
- - Direct upload URLs and statusmux.webhook_events
- - Webhook event metadata and payloads
`typescript
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
import { MuxSync } from 'npm:@mux/sync-engine';
const muxSync = new MuxSync({
databaseUrl: Deno.env.get('SUPABASE_DB_URL')!,
muxTokenId: Deno.env.get('MUX_TOKEN_ID')!,
muxTokenSecret: Deno.env.get('MUX_TOKEN_SECRET')!,
muxWebhookSecret: Deno.env.get('MUX_WEBHOOK_SECRET')!,
});
serve(async (req) => {
try {
const body = await req.text();
await muxSync.processWebhook(body, req.headers);
return new Response('OK', { status: 200 });
} catch (error) {
console.error('Webhook processing failed:', error);
return new Response('Bad Request', { status: 400 });
}
});
`
`bash`
npm install
npm run build
This package includes comprehensive tests using Vitest and Testcontainers:
`bashInstall dependencies
npm install
`
#### Test Structure
- src/test/migrations.test.ts - Tests for database migrationssrc/test/backfill.test.ts
- - Tests for sync functionalitysrc/test/helpers/mockMux.ts
- - Mock objects for Mux API
#### CI/CD
The tests are designed to run in CI environments. See .github/workflows/test.yml for GitHub Actions configuration.
For local development, tests use Testcontainers to spin up a PostgreSQL instance automatically.
The following environment variables are required:
- MUX_TOKEN_ID - Your Mux token IDMUX_TOKEN_SECRET
- - Your Mux token secretMUX_WEBHOOK_SECRET
- - Your webhook signing secretDATABASE_URL
- - PostgreSQL connection string
The sync engine handles all Mux webhook events, including:
- video.asset.createdvideo.asset.ready
- video.asset.errored
- video.asset.updated
- video.asset.deleted
- video.live_stream.created
- video.live_stream.connected
- video.live_stream.recording
- video.live_stream.active
- video.live_stream.disconnected
- video.live_stream.idle
- video.live_stream.updated
- video.live_stream.deleted
- video.upload.created
- video.upload.asset_created
- video.upload.cancelled
- video.upload.timeout
- video.upload.errored`
-
MIT