Multi-CDN Setup
Lunar Stream provides multiple CDN endpoints for redundancy and optimal global performance.
Why Multi-CDN?
- High Availability: If one CDN has issues, viewers automatically switch to another
- Global Performance: Different CDNs may perform better in different regions
- Load Distribution: Spread traffic across multiple providers
CDN Failover Flow
Available CDN Endpoints
Each livestream is available through multiple CDN providers:
| CDN | URL Pattern | Coverage |
|---|---|---|
| Primary | https://stream.lunarstream.kozow.com/live/{streamKey}/hls.m3u8 | Global |
| BunnyCDN | https://zlmediakit-cdn.b-cdn.net/live/{streamKey}/hls.m3u8 | Global |
| Gcore | https://gcore-zlmediakit.lunarstream.kozow.com/live/{streamKey}/hls.m3u8 | Global |
Getting CDN URLs
When you retrieve a livestream, the response includes all available CDN URLs:
bash
curl -X GET "https://api.xxxxxx.xxx/api/v1/livestream/LIVESTREAM_ID?projectId=PROJECT_ID" \
-H "ls-api-key: YOUR_API_KEY"Response:
json
{
"data": {
"id": "d926da37-56ae-4212-83bc-f20d9de64d6b",
"streamKey": "ee04affe2a669854052102fe762bd715",
"hlsSources": [
{
"name": "origin",
"url": "https://stream.lunarstream.kozow.com/hls/ee04affe2a669854052102fe762bd715/master.m3u8"
},
{
"name": "bunny",
"url": "https://bunny.lunarstream.kozow.com/hls/ee04affe2a669854052102fe762bd715/master.m3u8"
},
{
"name": "gcore",
"url": "https://gcore.lunarstream.kozow.com/hls/ee04affe2a669854052102fe762bd715/master.m3u8"
}
]
}
}Implementing CDN Failover
JavaScript Implementation
javascript
class MultiCDNPlayer {
constructor(hlsSources) {
this.cdnUrls = hlsSources.map(s => s.url);
this.currentIndex = 0;
}
getCurrentUrl() {
return this.cdnUrls[this.currentIndex];
}
switchToNextCDN() {
if (this.currentIndex < this.cdnUrls.length - 1) {
this.currentIndex++;
console.log(`Switching to CDN: ${this.getCurrentUrl()}`);
return true;
}
return false;
}
reset() {
this.currentIndex = 0;
}
}
// Usage with Video.js
const cdnPlayer = new MultiCDNPlayer(hlsSources);
const player = videojs('video-player');
player.src({ src: cdnPlayer.getCurrentUrl(), type: 'application/x-mpegURL' });
player.on('error', () => {
if (cdnPlayer.switchToNextCDN()) {
player.src({ src: cdnPlayer.getCurrentUrl(), type: 'application/x-mpegURL' });
player.play();
} else {
console.error('All CDNs failed');
}
});React Hook Implementation
javascript
import { useState, useCallback } from 'react';
function useMultiCDN(hlsSources) {
const urls = hlsSources.map(s => s.url);
const [currentIndex, setCurrentIndex] = useState(0);
const currentUrl = urls[currentIndex];
const hasMoreCDNs = currentIndex < urls.length - 1;
const switchToNextCDN = useCallback(() => {
if (hasMoreCDNs) {
setCurrentIndex(prev => prev + 1);
return true;
}
return false;
}, [hasMoreCDNs]);
const reset = useCallback(() => {
setCurrentIndex(0);
}, []);
return { currentUrl, switchToNextCDN, reset, hasMoreCDNs };
}
// Usage
const StreamPlayer = ({ hlsSources }) => {
const { currentUrl, switchToNextCDN } = useMultiCDN(hlsSources);
const handleError = () => {
if (!switchToNextCDN()) {
console.error('All CDNs failed');
}
};
return (
<video src={currentUrl} onError={handleError} controls />
);
};Best Practices
1. Region-Based CDN Selection
Prioritize CDNs based on viewer location for optimal performance:
javascript
function selectOptimalCDN(hlsSources, userRegion) {
const cdnPriority = {
'asia': ['gcore', 'bunny', 'origin'],
'europe': ['bunny', 'gcore', 'origin'],
'americas': ['bunny', 'origin', 'gcore'],
'default': ['origin', 'bunny', 'gcore']
};
const priority = cdnPriority[userRegion] || cdnPriority['default'];
return hlsSources.sort((a, b) => {
const aIndex = priority.findIndex(cdn => a.name.includes(cdn));
const bIndex = priority.findIndex(cdn => b.name.includes(cdn));
return aIndex - bIndex;
});
}2. Health Checking
Pre-check CDN availability before playback:
javascript
async function checkCDNHealth(url) {
try {
const response = await fetch(url, { method: 'HEAD' });
return response.ok;
} catch {
return false;
}
}
async function findHealthyCDN(hlsSources) {
for (const source of hlsSources) {
if (await checkCDNHealth(source.url)) {
return source.url;
}
}
return null;
}3. Performance Monitoring
Track CDN performance for analytics:
javascript
function trackCDNPerformance(cdnUrl, loadTime, errors) {
analytics.track('cdn_performance', {
cdn: new URL(cdnUrl).hostname,
loadTime,
errors
});
}Troubleshooting
| Issue | Possible Cause | Solution |
|---|---|---|
| All CDNs failing | Stream not active | Check stream status via API |
| Slow switching | No error handling | Implement proper error listeners |
| Region mismatch | Wrong CDN priority | Use region detection |
Next Steps
- HLS Playback - Video player integration
- API Reference - Get stream details
- Webhooks - Monitor stream events