cloudflare
references/stream/api-live.md
.md 196 lines
Content
# Stream Live Streaming API
Live input creation, status checking, simulcast, and WebRTC streaming.
## Create Live Input
### Using Cloudflare SDK
```typescript
import Cloudflare from 'cloudflare';
const client = new Cloudflare({ apiToken: env.CF_API_TOKEN });
const liveInput = await client.stream.liveInputs.create({
account_id: env.CF_ACCOUNT_ID,
recording: { mode: 'automatic', timeoutSeconds: 30 },
deleteRecordingAfterDays: 30
});
// Returns: { uid, rtmps, srt, webRTC }
```
### Raw fetch API
```typescript
async function createLiveInput(accountId: string, apiToken: string) {
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${accountId}/stream/live_inputs`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
recording: { mode: 'automatic', timeoutSeconds: 30 },
deleteRecordingAfterDays: 30
})
}
);
const { result } = await response.json();
return {
uid: result.uid,
rtmps: { url: result.rtmps.url, streamKey: result.rtmps.streamKey },
srt: { url: result.srt.url, streamId: result.srt.streamId, passphrase: result.srt.passphrase },
webRTC: result.webRTC
};
}
```
## Check Live Status
```typescript
async function getLiveStatus(accountId: string, liveInputId: string, apiToken: string) {
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${accountId}/stream/live_inputs/${liveInputId}`,
{ headers: { 'Authorization': `Bearer ${apiToken}` } }
);
const { result } = await response.json();
return {
isLive: result.status?.current?.state === 'connected',
recording: result.recording,
status: result.status
};
}
```
## Simulcast (Live Outputs)
### Create Output
```typescript
async function createLiveOutput(
accountId: string, liveInputId: string, apiToken: string,
outputUrl: string, streamKey: string
) {
return fetch(
`https://api.cloudflare.com/client/v4/accounts/${accountId}/stream/live_inputs/${liveInputId}/outputs`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
url: `${outputUrl}/${streamKey}`,
enabled: true,
streamKey // For platforms like YouTube, Twitch
})
}
).then(r => r.json());
}
```
### Example: Simulcast to YouTube + Twitch
```typescript
const liveInput = await createLiveInput(accountId, apiToken);
// Add YouTube output
await createLiveOutput(
accountId, liveInput.uid, apiToken,
'rtmp://a.rtmp.youtube.com/live2',
'your-youtube-stream-key'
);
// Add Twitch output
await createLiveOutput(
accountId, liveInput.uid, apiToken,
'rtmp://live.twitch.tv/app',
'your-twitch-stream-key'
);
```
## WebRTC Streaming (WHIP/WHEP)
### Browser to Stream (WHIP)
```typescript
async function startWebRTCBroadcast(liveInputId: string) {
const pc = new RTCPeerConnection();
// Add local media tracks
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
stream.getTracks().forEach(track => pc.addTrack(track, stream));
// Create offer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// Send to Stream via WHIP
const response = await fetch(
`https://customer-<CODE>.cloudflarestream.com/${liveInputId}/webRTC/publish`,
{
method: 'POST',
headers: { 'Content-Type': 'application/sdp' },
body: offer.sdp
}
);
const answer = await response.text();
await pc.setRemoteDescription({ type: 'answer', sdp: answer });
}
```
### Stream to Browser (WHEP)
```typescript
async function playWebRTCStream(videoId: string) {
const pc = new RTCPeerConnection();
pc.addTransceiver('video', { direction: 'recvonly' });
pc.addTransceiver('audio', { direction: 'recvonly' });
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const response = await fetch(
`https://customer-<CODE>.cloudflarestream.com/${videoId}/webRTC/play`,
{
method: 'POST',
headers: { 'Content-Type': 'application/sdp' },
body: offer.sdp
}
);
const answer = await response.text();
await pc.setRemoteDescription({ type: 'answer', sdp: answer });
return pc;
}
```
## Recording Settings
| Mode | Behavior |
|------|----------|
| `automatic` | Record all live streams |
| `off` | No recording |
| `timeoutSeconds` | Stop recording after N seconds of inactivity |
```typescript
const recordingConfig = {
mode: 'automatic',
timeoutSeconds: 30, // Auto-stop 30s after stream ends
requireSignedURLs: true, // Require token for VOD playback
allowedOrigins: ['https://yourdomain.com']
};
```
## In This Reference
- [README.md](./README.md) - Overview and quick start
- [api.md](./api.md) - On-demand video APIs
- [configuration.md](./configuration.md) - Setup and config
- [patterns.md](./patterns.md) - Full-stack flows, best practices
- [gotchas.md](./gotchas.md) - Error codes, troubleshooting
## See Also
- [workers](../workers/) - Deploy live APIs in Workers