mux-video
npx skills add https://github.com/joelhooks/joelclaw --skill mux-video
Agent 安装分布
Skill 文档
Mux Video
Upload, manage, and embed videos through Mux’s API and CLI. Integrates with joelclaw’s webhook infrastructure and Inngest event pipeline.
When to Use
Triggers on: “upload video to mux”, “create mux asset”, “embed mux video”, “check video status”, “mux playback”, “direct upload”, “video encoding”, “mux webhook”, or any task involving video hosting via Mux.
Credentials
Stored in agent-secrets:
mux_token_idâ API token IDmux_token_secretâ API token secretmux_signing_key_idâ URL signing key IDmux_signing_secretâ webhook signing secret (per-endpoint, HMAC)
Lease credentials:
secrets lease mux_token_id
secrets lease mux_token_secret
Or use env vars MUX_TOKEN_ID and MUX_TOKEN_SECRET.
Core Operations
Create Asset from URL
Ingest a video from a public URL:
curl https://api.mux.com/video/v1/assets \
-X POST \
-H "Content-Type: application/json" \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET} \
-d '{
"input": [{"url": "https://example.com/video.mp4"}],
"playback_policy": ["public"],
"video_quality": "plus"
}'
Video quality tiers: basic (fastest/cheapest), plus (default, good quality), premium (highest).
Direct Upload (browser/client-side)
Two-step process:
Step 1: Create authenticated upload URL (server-side)
curl https://api.mux.com/video/v1/uploads \
-X POST \
-H "Content-Type: application/json" \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET} \
-d '{
"new_asset_settings": {
"playback_policies": ["public"],
"video_quality": "plus"
},
"cors_origin": "*"
}'
Response includes data.url (resumable upload endpoint) and data.id (upload ID).
Step 2: PUT the file to the URL (client-side)
curl -X PUT "${UPLOAD_URL}" \
-H "Content-Type: video/mp4" \
--data-binary @video.mp4
The URL is resumable â large files can be uploaded in chunks. Use UpChunk for browser uploads.
List Assets
curl https://api.mux.com/video/v1/assets \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET}
Get Asset Details
curl https://api.mux.com/video/v1/assets/${ASSET_ID} \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET}
Delete Asset
curl -X DELETE https://api.mux.com/video/v1/assets/${ASSET_ID} \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET}
Auto-Generated Captions
curl https://api.mux.com/video/v1/assets \
-X POST \
-H "Content-Type: application/json" \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET} \
-d '{
"input": [{"url": "https://example.com/video.mp4"}],
"playback_policy": ["public"],
"auto_generated_captions": [{"language": "en"}]
}'
Playback
Embed URL
Once an asset is ready and has a playback ID:
https://stream.mux.com/${PLAYBACK_ID}.m3u8
Thumbnail/Poster
https://image.mux.com/${PLAYBACK_ID}/thumbnail.jpg
https://image.mux.com/${PLAYBACK_ID}/thumbnail.jpg?time=10
https://image.mux.com/${PLAYBACK_ID}/animated.gif?start=5&end=10
Mux Player (Web Component)
<mux-player
playback-id="${PLAYBACK_ID}"
metadata-video-title="My Video"
accent-color="#FF0000"
></mux-player>
Install: npm install @mux/mux-player-react for React, or use the web component directly.
React Component
import MuxPlayer from "@mux/mux-player-react";
<MuxPlayer
playbackId={playbackId}
metadata={{ video_title: "My Video" }}
accentColor="#FF0000"
/>
Webhook Events
Mux webhooks are registered at: https://panda.tail7af24.ts.net/webhooks/mux
The webhook provider (packages/system-bus/src/webhooks/providers/mux.ts) handles HMAC-SHA256 verification and normalizes events into the Inngest pipeline.
Key Events
| Mux Event | Inngest Event | When |
|---|---|---|
video.asset.created |
mux/asset.created |
Asset record created |
video.asset.ready |
mux/asset.ready |
Encoding complete, playable |
video.asset.errored |
mux/asset.errored |
Encoding failed |
video.upload.created |
mux/upload.created |
Direct upload URL created |
video.upload.asset_created |
mux/upload.asset_created |
Upload completed, asset created |
video.upload.cancelled |
mux/upload.cancelled |
Upload cancelled or timed out |
video.asset.live_stream_completed |
mux/asset.live_stream_completed |
Live stream recording ready |
Event Payload Structure
{
"type": "video.asset.ready",
"data": {
"id": "asset_id",
"playback_ids": [{"id": "playback_id", "policy": "public"}],
"status": "ready",
"duration": 120.5,
"passthrough": "your_custom_id",
"tracks": [...]
}
}
The passthrough field carries your custom identifier through the entire pipeline â use it to correlate uploads with your application records.
Building Inngest Functions for Mux Events
// Example: Notify when video is ready
const onVideoReady = inngest.createFunction(
{ id: "mux-video-ready", name: "Mux Video Ready" },
{ event: "mux/asset.ready" },
async ({ event, step }) => {
const { data } = event;
const playbackId = data.playback_ids?.[0]?.id;
const duration = data.duration;
// Your logic here â update DB, notify user, etc.
await step.run("notify", async () => {
// ...
});
}
);
passthrough Pattern
Always set passthrough when creating assets or uploads. This is your correlation ID that flows through all webhook events:
curl https://api.mux.com/video/v1/assets \
-X POST \
-H "Content-Type: application/json" \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET} \
-d '{
"input": [{"url": "https://example.com/video.mp4"}],
"playback_policy": ["public"],
"passthrough": "my-unique-correlation-id"
}'
Rules
- Always use
passthroughfor tracking â it’s your only way to correlate webhooks back to your records. - Don’t poll for status in production â use webhooks. Mux has rate limits.
- Webhook signing secret is per-endpoint â it’s the secret you get when registering the webhook URL in the Mux dashboard, NOT the API token secret or signing key.
- Video quality tiers affect cost â
basicfor drafts/previews,plusfor production,premiumonly when needed. - Direct upload URLs expire â default 1 hour timeout. Create them on-demand, not ahead of time.
- Playback IDs are stable â once an asset is ready, the playback ID doesn’t change. Safe to cache/store.