Migrating from Mux
Migrating from Mux to AntCDN
This guide helps you migrate your video infrastructure from Mux to AntCDN with minimal disruption to your service.
Tip
Most migrations can be completed in phases over 2-4 weeks, allowing you to test thoroughly before switching completely.
Migration Overview
Compare APIs: Map Mux endpoints to AntCDN equivalents
Update authentication: Switch from Mux API tokens to AntCDN API keys
Modify upload flow: Adapt your upload process
Update players: Point to new playback URLs
Migrate analytics: Transition tracking and reporting
API Comparison
Core Endpoints
| Mux Endpoint | AntCDN Equivalent | Notes |
|---|---|---|
POST /video/v1/assets | Two-step process: 1. POST /{orgID}/environments/{envID}/videos/upload-url2. POST /{orgID}/environments/{envID}/videos/process | AntCDN separates upload and processing |
POST /video/v1/uploads | POST /{orgID}/environments/{envID}/videos/upload-url | Direct upload to storage |
GET /video/v1/assets/{id} | GET /{orgID}/videos/{publicID}/details | Similar response structure |
DELETE /video/v1/assets/{id} | DELETE /{orgID}/videos/{videoID} | Soft delete with cleanup |
GET /data/v1/metrics | GET /{orgID}/analytics/* | Multiple specialized endpoints |
Playback URLs
Mux:
https://stream.mux.com/{PLAYBACK_ID}.m3u8AntCDN:
https://worker.antcdn.net/{publicID}/master.m3u8Mux:
// Generate JWT with signing keyconst token = Mux.JWT.sign(playbackId, { keyId: SIGNING_KEY_ID, keySecret: SIGNING_KEY_PRIVATE});const url = `https://stream.mux.com/${playbackId}.m3u8?token=${token}`;AntCDN:
// Request signed URL from APIconst response = await fetch( `https://api.antcdn.net/v1/api/${orgId}/videos/${publicId}/signed-url`, { headers: { 'X-Api-Key': `${apiKey}` } });const { signed_url } = await response.json();Code Migration Examples
Upload Flow
Mux Implementation:
// Create direct uploadconst upload = await mux.video.uploads.create({ cors_origin: 'https://example.com', new_asset_settings: { playback_policy: ['public'], encoding_tier: 'baseline' }});
// Upload file using tusconst uppy = new Uppy() .use(Tus, { endpoint: upload.data.url });AntCDN Implementation:
// Get upload URLconst { body } = await fetch(`${API}/videos/upload-url`, { method: 'POST', headers: { 'X-Api-Key': `${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ filename: 'video.mp4', fileSize: file.size })}).then(r => r.json());
// Upload directlyawait fetch(body.signedURL, { method: 'PUT', body: file, headers: { 'Content-Type': 'video/mp4' }});
// Start processingconst { videoID } = await fetch(`${API}/videos/process`, { method: 'POST', headers: { 'X-Api-Key': `${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ gcsPath: body.bucketPath, videoQuality: 'high', allowPublicAccess: true })}).then(r => r.json());Mux Implementation:
const asset = await mux.video.assets.create({ input: 'https://example.com/video.mp4', playback_policy: ['public'], encoding_tier: 'baseline'});AntCDN Implementation:
// First download to our storageconst { body: downloadResult } = await fetch(`${API}/videos/download`, { method: 'POST', headers: { 'X-Api-Key': `${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ sourceUrl: 'https://example.com/video.mp4' })}).then(r => r.json());
// Then processconst { videoID } = await fetch(`${API}/videos/process`, { method: 'POST', headers: { 'X-Api-Key': `${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ gcsPath: downloadResult.bucketPath, videoQuality: 'high', allowPublicAccess: true })}).then(r => r.json());Status Polling
Both platforms require polling for processing status:
async function waitForReady(assetId) { while (true) { const asset = await mux.video.assets.retrieve(assetId); if (asset.data.status === 'ready') { return asset.data; } if (asset.data.status === 'errored') { throw new Error('Asset failed to process'); } await new Promise(r => setTimeout(r, 5000)); }}async function waitForReady(publicId) { while (true) { const { body } = await fetch( `${API}/videos/${publicId}/details`, { headers: { 'X-Api-Key': `${apiKey}` } } ).then(r => r.json());
if (body.status.ready) { return body; } if (body.status.failed) { throw new Error('Video failed to process'); } await new Promise(r => setTimeout(r, 5000)); }}Feature Mapping
Video Processing
| Mux Feature | AntCDN Equivalent | Configuration |
|---|---|---|
| Encoding Tiers | Video Quality | standard, high, ultra |
| MP4 Support | Coming Soon | HLS-only currently |
| Thumbnails | Custom Thumbnails | Generate at any timestamp |
| Captions | Coming Soon | Q2 2024 |
| Clipping | Coming Soon | Q3 2024 |
| Live Streaming | Not Available | Focus on VOD |
Analytics
| Mux Data | AntCDN Analytics | Endpoint |
|---|---|---|
| Views | Segments Served | GET /analytics/usage |
| View Duration | Segments × 6s | Calculate from segments |
| Unique Viewers | Not Available | Privacy-focused |
| Quality Distribution | Resolution Analytics | GET /analytics/resolution |
| Errors | Not Available | Client-side only |
Migration Checklist
Set up AntCDN account
- Create organization
- Generate API keys
- Configure billing
Update backend code
- Replace Mux SDK with AntCDN API calls
- Update webhook handlers
- Modify upload flow
Update frontend
- Switch playback URLs
- Update player configuration
- Test on all platforms
Migrate content (optional)
- Export video list from Mux
- Re-upload to AntCDN
- Update video IDs in database
Monitor and optimize
- Compare analytics
- Adjust encoding settings
- Monitor costs
Cost Comparison
Tip
AntCDN typically costs 70-80% less than Mux for similar usage patterns.
Pricing Example (10,000 minutes/month)
| Service | Encoding | Storage | Delivery | Total |
|---|---|---|---|---|
| Mux | $50 | $25 | $125 | $200 |
| AntCDN | Included | Included | $0.15/min | $150 |
Savings: $50/month (25%)
Common Issues
CORS Errors
AntCDN has permissive CORS by default. No configuration needed.
Webhook Differences
Mux sends many granular events. AntCDN focuses on key events:
// Webhook handlerapp.post('/webhooks/antcdn', (req, res) => { const { event, videoId, status } = req.body;
switch(event) { case 'video.processing.completed': // Video ready break; case 'video.processing.failed': // Handle error break; }});Player Compatibility
AntCDN uses standard HLS. Any HLS player works:
- HLS.js
- Video.js
- Native Safari
- ExoPlayer (Android)
- AVPlayer (iOS)
Support
Need help migrating?
- Documentation: docs.antcdn.net
- Email: [email protected]
- Migration Assistance: Contact us for hands-on help
Note
Enterprise customers get free migration assistance including code review and implementation support.