Appearance
Cloudflare Stream setup
On the shared plane, Vabu runs this setup for you. Use this page when you want Streams to use your own Cloudflare account, so the video, the bill and the signing keys are yours. We create the configuration from the values you prepare here.
You need a Cloudflare account with a Stream subscription (or a Pro or Business zone plan, or an enterprise contract with Stream). Every call below uses your account id and an API token, shown as $ACCOUNT_ID and $CLOUDFLARE_API_TOKEN.
1. Get the account id and the customer code
Your account id is in the Cloudflare dashboard. The customer code is the <code> in customer-<code>.cloudflarestream.com, the host that serves your video. It appears in every playback url Cloudflare returns.
2. Create an API token
Create an API token on the Account API tokens page with these permissions:
- Stream Write, to create and delete live inputs, videos, outputs and signing keys, and to read storage.
- Notifications Write, to create the live input destination in step 5. You can leave this off and create the destination in the dashboard instead.
3. Create a signing key
A signing key lets Vabu sign playback tokens without calling Cloudflare for each one. Create it once.
bash
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/stream/keys" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"The response holds id, pem and jwk. Cloudflare shows them once, so store them straight away. Keep the id and the pem (it is base64 encoded, and we accept it as it is). You can have up to 1,000 keys, and deleting a key revokes every token signed with it.
4. Set the account webhook
The account webhook tells Vabu when an upload, a URL import or a clip is ready or has failed. Cloudflare allows one webhook per account. Use the url we give you, which looks like https://api.vabu.live/api/v1/providers/cloudflare_stream/webhooks/mpc_....
bash
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/stream/webhook" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"notificationUrl": "https://api.vabu.live/api/v1/providers/cloudflare_stream/webhooks/mpc_..."}'The response has a secret. Cloudflare signs every webhook with it, and we check the signature. Requests older than five minutes are refused.
5. Send live input events to Vabu
Connect and disconnect events of live inputs do not use the account webhook. They come through Notifications, which sends a secret of your choice in the cf-webhook-auth header. Make a destination, then a policy that sends Stream live input events to it.
bash
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/alerting/v3/destinations/webhooks" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"name": "Vabu live inputs", "url": "https://api.vabu.live/api/v1/providers/cloudflare_stream/webhooks/mpc_...", "secret": "<a long random secret>"}'The response has the destination id. Use it in the policy:
bash
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/alerting/v3/policies" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"name": "Vabu live inputs", "alert_type": "stream_live_notifications", "enabled": true, "mechanisms": {"webhooks": [{"id": "<destination id>"}]}}'By default the policy covers every live input. Cloudflare never returns the secret again, so keep a copy. Notifications reach a public address on port 80 or 443 only.
6. Give us the values
For the configuration we need the account id, the customer code, the API token, the signing key id and pem, the account webhook secret and the notification secret. They are encrypted at rest and never shown again, in the API or in events.
Encoder settings for venues
Cloudflare Stream accepts one kind of feed. Set the encoder at the venue to:
- Video H.264 and audio AAC (ADTS, not LATM).
- A total bitrate between 2 and 14 Mbps, constant bitrate where you can. Under 10 Mbps suits most shows.
- A keyframe interval between 2 and 10 seconds, with closed GOPs. Use 4 to 8 seconds for the best balance of latency and quality.
- Automatic reconnect, so a dropped feed returns inside the
reconnect_window.
A live recording is cut at 7 days. When a feed breaks these limits, Cloudflare reports it and the stream shows as disconnected.
A browser or phone that goes live over WHIP sends VP8, VP9 or H.264 Constrained Baseline instead. That feed plays back over WebRTC only.
Keep the cost down
Cloudflare Stream bills two things: minutes stored and minutes delivered.
- Minutes stored are prepaid, at $5 a month for each 1,000 minutes. Every broadcast is recorded and counts until its recording is deleted. A live recording is deleted 30 days after the broadcast and nothing removes it sooner yet, so a stream that is always on holds its minutes for the full 30 days. Deleting an asset made from an upload or a copy releases its minutes at once. An upload also reserves its longest allowed length until it finishes or its link expires.
- Minutes delivered are billed at $1 for each 1,000 minutes watched. They include preloading in the player and every simulcast target while the stream is live.
Encoding and sending video to Cloudflare are free, and a live input that nobody connects to costs nothing. If the account runs low on storage, Vabu refuses to start a stream with 409 provider_storage_exhausted instead of letting a show stop halfway. Buy more storage in the Cloudflare dashboard to clear it.