Webhooks & Stream Events
Learn how to monitor stream status and handle stream events in your application.
Stream Status Flow
Stream States
| State | Description | When it happens |
|---|---|---|
READY_FOR_USE | Stream created, waiting for broadcaster | After calling Create Livestream API |
STARTED | Broadcaster connected, stream is live | When broadcaster starts pushing RTMP |
ENDED | Broadcaster disconnected | When broadcaster stops streaming |
TOKEN_EXPIRED | Push token expired | When token lifetime exceeded |
Monitoring Stream Status
Polling Method
Poll the API to check stream status changes:
javascript
async function monitorStreamStatus(streamKey, onStatusChange) {
let lastStatus = null;
const checkStatus = async () => {
try {
const response = await fetch(
`https://api.xxxxxx.xxx/api/v1/livestreams/stream-info/${streamKey}`
);
const { data } = await response.json();
if (data.status !== lastStatus) {
onStatusChange(data.status, lastStatus);
lastStatus = data.status;
}
} catch (error) {
console.error('Failed to check stream status:', error);
}
};
// Poll every 5 seconds
setInterval(checkStatus, 5000);
// Initial check
checkStatus();
}
// Usage
monitorStreamStatus('ee04affe2a669854052102fe762bd715', (newStatus, oldStatus) => {
console.log(`Stream status changed: ${oldStatus} -> ${newStatus}`);
switch (newStatus) {
case 'STARTED':
notifyViewers('Stream is now live!');
break;
case 'ENDED':
notifyViewers('Stream has ended');
break;
case 'TOKEN_EXPIRED':
refreshPushToken();
break;
}
});Get Stream Info API
bash
curl -X GET "https://api.xxxxxx.xxx/api/v1/livestreams/stream-info/YOUR_STREAM_KEY"Response:
json
{
"data": {
"streamKey": "ee04affe2a669854052102fe762bd715",
"status": "STARTED",
"hlsSources": [
{
"name": "origin",
"url": "https://stream.lunarstream.kozow.com/hls/ee04affe2a669854052102fe762bd715/master.m3u8"
}
]
}
}Handling Status Changes
React Example
javascript
import { useState, useEffect, useCallback } from 'react';
function useStreamStatus(streamKey) {
const [status, setStatus] = useState(null);
const [loading, setLoading] = useState(true);
const checkStatus = useCallback(async () => {
try {
const response = await fetch(
`https://api.xxxxxx.xxx/api/v1/livestreams/stream-info/${streamKey}`
);
const { data } = await response.json();
setStatus(data.status);
} catch (error) {
console.error('Status check failed:', error);
} finally {
setLoading(false);
}
}, [streamKey]);
useEffect(() => {
checkStatus();
const interval = setInterval(checkStatus, 5000);
return () => clearInterval(interval);
}, [checkStatus]);
return { status, loading };
}
// Usage in component
const StreamViewer = ({ streamKey }) => {
const { status, loading } = useStreamStatus(streamKey);
if (loading) return <div>Loading...</div>;
switch (status) {
case 'STARTED':
return <VideoPlayer streamKey={streamKey} />;
case 'READY_FOR_USE':
return <div>Waiting for stream to start...</div>;
case 'ENDED':
return <div>Stream has ended</div>;
default:
return <div>Stream unavailable</div>;
}
};Best Practices
1. Polling Frequency
- Recommended: Poll every 5-10 seconds
- Minimum: Don't poll more than once per second
- Stop polling: When stream status is
ENDED
2. Error Handling
javascript
async function safeStatusCheck(streamKey) {
const maxRetries = 3;
let retries = 0;
while (retries < maxRetries) {
try {
const response = await fetch(
`https://api.xxxxxx.xxx/api/v1/livestreams/stream-info/${streamKey}`
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
retries++;
if (retries >= maxRetries) {
throw error;
}
// Wait before retry
await new Promise(resolve => setTimeout(resolve, 1000 * retries));
}
}
}3. Caching
Cache stream status to reduce API calls:
javascript
const statusCache = new Map();
const CACHE_TTL = 3000; // 3 seconds
async function getCachedStatus(streamKey) {
const cached = statusCache.get(streamKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.status;
}
const { data } = await fetchStreamStatus(streamKey);
statusCache.set(streamKey, {
status: data.status,
timestamp: Date.now()
});
return data.status;
}Troubleshooting
| Issue | Possible Cause | Solution |
|---|---|---|
| Status not updating | Polling too slow | Reduce polling interval |
| Rate limit errors | Polling too fast | Increase polling interval |
| Stream stuck in READY | Broadcaster not connected | Check RTMP credentials |
| Unexpected ENDED | Network issues | Check broadcaster connection |
Next Steps
- RTMP Streaming - Configure broadcaster
- HLS Playback - Video player integration
- API Reference - Complete API documentation