@r-delfino/mux-sync-supabase
v0.0.20
Published
CLI tool to initialize Mux Sync Engine with Supabase
Maintainers
Readme
@mux/supabase
@mux/supabase contains a CLI for integrating your Mux account with your Supabase account. Setting this up will:
- Create a
muxschema that contains tables for:assets(Assets)live_streams(Live Streams)uploads(Direct Uploads)events(Webhook events)
- Set up an edge function for receiving webhooks and keeping data in the
muxschema up-to-date
Getting started
Dependencies
Before setting this up, you should already have Supabase initialized in your project (your project should already have a supabase directory). If you have not already done this, run npx supabase init and see this guide.
Local Setup
You should run this after your supabase project is running with npx supabase start
Run init and follow the prompts. Then env vars should be in the .env file within the supabase/functions directory.
npx @mux/supabase initThis will:
- Create the
muxschema and corresponding tables - Create a function in
/supabase/functions/mux-webhookwhich uses the@mux/sync-enginepackage to sync your data - Prompt you to configure the
MUX_TOKEN_IDandMUX_TOKEN_SECRET.
Running the Webhook locally
@mux/supabase handles webhooks & keeping data updated in the mux schema.
To test the webhook locally, run:
npx supabase functions serve mux-webhookThis will run the Edge function locally on port 54321. To test with Mux, you need to expose the function to the internet. Use a service like ngrok for this.
Once done, get the public URL of your function (it should have a format like https://d99d3b847eb8.ngrok-free.app/functions/v1/mux-webhook) and set it in Mux following these steps: Listen for webhooks.
After that, copy the webhook secret from Mux into MUX_WEBHOOK_SECRET in your .env file.
Verify that it's working
Go to your Mux dashboard, make sure you're in the correct environment and upload an asset. Then navigate to your local Supabase dashboard and you should see a row for the Asset in the mux schema assets table and the id should match the ID for the Asset in the Mux dashboard.
Backfilling Existing Data
If you already have Mux assets, live streams, or uploads in your account, you can backfill them to your Supabase database using the CLI command:
npx @mux/supabase backfillThis will prompt you for the database URL where it will store the data and your Mux token and secret to sync the data.
If you prefer not to use the command, you can use the sync-engine directly:
import { MuxSync } from '@mux/sync-engine';
const muxSync = new MuxSync({
databaseUrl: 'your-supabase-database-url',
muxTokenId: 'your-mux-token-id',
muxTokenSecret: 'your-mux-token-secret',
muxWebhookSecret: 'your-mux-webhook-secret',
});
// Backfill all data
const result = await muxSync.syncBackfill({ object: 'all' });
console.log(`Synced ${result.muxAssets?.synced} assets`);
console.log(`Synced ${result.muxLiveStreams?.synced} live streams`);
console.log(`Synced ${result.muxUploads?.synced} uploads`);
// Backfill specific object types
await muxSync.syncBackfill({ object: 'mux_assets' });
await muxSync.syncBackfill({ object: 'mux_live_streams' });
await muxSync.syncBackfill({ object: 'mux_uploads' });Core Concepts
Most Mux integrations require saving data into a database. The general flow to use Mux is:
- Videos can be uploaded directly to Mux with the Direct Uploads API
- Videos can be uploaded with a URL pointing to a publicly available video file
- Videos can be uploaded directly in the Mux dashboard
When a video (or audio file) is uploaded to Mux, it is an Asset.
Saving data associated with each video
When saving data into a database, typically the application would save information about the Mux Asset, like:
- Asset ID
- Playback ID
- Duration
- Aspect ratio
@mux/supabase will save all this data for you under the mux schema.
In addition to the information from Mux, the application also keeps track of things like:
- Which user uploaded the video
- Structural/organization things, like if the video is part of a series or related to other videos
- Video details like: description, summary, chapter markers, etc.
- Who has access to view the video
@mux/supabase does not save this kind of information, which is an application-level concern.
Mux Assets DO have fields for metadata:
title,creator_idandexternal_idwhich will be saved under themetaJSON column in theassetstable. Higher-level concepts (titles, chapters, permissions, etc.) are still considered application-level concerns.
AI Workflows on Supabase
This considered alpha right now and may change in future versions
Env setup
You should have a local .env file in your project's root (same level as the supabase folder). This is a different .env file that what you have in supabase/functions/.env
SUPABASE_DB_URLIf you're running supabase locally the value would be:postgresql://postgres:[email protected]:54322/postgresSUPABASE_SERVICE_ROLE_KEYRunnpx supabase status -o envand look forSERVICE_ROLE_KEYSUPABASE_URLIf you are developing locally this is:http://supabase_kong_[name_of_supabase_project]:8000(replace[name_of_supabase_project]with your actual project name)
You should only run this command after you have gone through the @mux/supabase init flow.
npx @mux/supabase init-workflowsThis will
- Set-up and run migrations to set up Supabase Queues & Supabase Cron. Both of these are required to run workflows
- Set up 3 secrets in
db.vault. When migrations are run, the vault values are updated. These values need to be in the vault in order for the workflows to be called - Create
supabase/functions/mux.tomlfile, where you will configure workflows
Define a workflow and when it should run:
mux.toml
# supabase/functions/mux-webhook/mux.toml
[workflows.content-moderation]
events = ["video.asset.ready"]This means that when the video.asset.track.ready event fires, it will run your Supabase Edge Function called content-moderation
Create the Supabase Edge Function:
npx supabase functions new content-moderationOpen up supabase/functions/content-moderation/index.ts
Deno.serve(async (req) => {
try {
const event = (await req.json()) as UnwrapWebhookEvent;
const asset = event.data;
if (!track) {
console.log('No text track');
return new Response('No asset in webhook', { status: 500 });
}
console.log(`Running modeartion for: ${asset.id}`)
// do your logic to make API calls, write data into your db, etc
return new Response('Moderation complete', { status: 200 });
} catch (error) {
console.error("Error running content-moderation.ts:", error)
return new Response(
JSON.stringify({ error: "500" }),
{
status: 500,
headers: { "Content-Type": "application/json" }
}
)
}
})Testing
To test, run supabase functions serve, this will execute all created functions and then try creating an Asset and see that your content-moderation function runs.
Troubleshooting
If the Cron returns bearer token issues, make sure you have properly set the secret_key in the vault with the SERVICE_ROLE_KEY as mentioned in the Dependencies section.
You can find this in the Supabase dashboard under Integrations -> Vault and check what value is set for secret_key.
Note that vault values are loaded/modified when migrations are applied (supabase migration up).
In any case, if you want to test ignoring this, you can run the functions with JWT verification disabled using the command:
npx supabase functions serve --no-verify-jwtProduction Deployment
To deploy to a Supabase project, you need to do the following:
1. Modify the root .env with production values:
SUPABASE_DB_URL: Find this value in the "Connect" section of the Dashboard and set it (should have the formatpostgresql://...)SUPABASE_SERVICE_ROLE_KEY: This is found in the Dashboard under Project Settings -> API Keys. Use the value of the service_role.SUPABASE_URL: This is the URL used to call edge functions, should have the formathttps://[project_id].supabase.co
2. Run migrations:
Once modified, run the migrations in your project with the command:
supabase db pushThis will create the tables you had locally from the migrations folder.
3. Set secrets for Edge Functions:
You can do this in 2 ways:
- Set manually in the Dashboard
- Run the command:
supabase secrets set --env-file ./supabase/functions/.env
supabase secrets listMake sure you have the .env file in the functions folder with your correct credentials.
4. Deploy functions:
Once ready, deploy the functions with:
supabase functions deploy5. Set up the webhook:
When everything is ready, we need to properly set the MUX_WEBHOOK_SECRET. Once the mux-webhook is deployed in Supabase, the URL will appear in Dashboard -> Edge Functions.
Similar to the "Running the Webhook locally" section, create the webhook in Mux with that URL and set the MUX_WEBHOOK_SECRET in the Supabase Dashboard with the new value.
