Skip to content

Ultra-low Latency with WebRTC

Last updated View as MarkdownAgent setup

WebRTC allows ultra-low latency (sub-second) live streaming (using WHIP) and playback (using WHEP) to thousands of concurrent viewers. WebRTC is ideally suited for one-to-many broadcasts with a real-time experience, for example:

  • When the outcome of a live event is time-sensitive: gaming, live sports, financial news
  • When viewers interact with the content: e-learning, live Q&A, auctions

WebRTC is also ideally suited to creator platforms or in-browser experiences because your users can go live without special broadcast applications or dedicated hardware encoders.

Step 1: Create a live input

Create a live input using one of the two options:

API response from a POST request to /live_inputsjson
{
  "uid": "1a553f11a88915d093d45eda660d2f8c",
 ...
  "webRTC": {
    "url": "https://customer-<CODE>.cloudflarestream.com/<SECRET>/webRTC/publish"
  },
  "webRTCPlayback": {
    "url": "https://customer-<CODE>.cloudflarestream.com/<INPUT_UID>/webRTC/play"
  },
...
}

Step 2: Go live using WHIP

Broadcasting from the browser

Every live input has a unique URL that one creator can be stream to. This is a credential and should only be shared with the creator — anyone with this URL can stream live video to this input.

Retrieve the WHIP endpoint URL:

  • The Live inputs page of the Cloudflare dashboard.

    Go to Live inputs ↗
  • The webRTC.url property in the API response when the input is created.

For a complete, no-dependency example of going live from a browser, see the First WebRTC broadcast in the browser tutorial.

You can also use this URL with any client that supports the WebRTC-HTTP Ingestion Protocol (WHIP). See supported WHIP clients for a list of clients we have tested and confirmed compatibility with Cloudflare Stream.

Broadcasting from other software (OBS, FFmpeg)

Using OBS 31.0 or higher: Recommended settings to broadcast WebRTC/WHIP. In Settings:

  • In the Stream tab
    • Service: WHIP
    • Server: Paste the entire WebRTC (WHIP) URL from Cloudflare Stream
      • The broadcast secret is part of this URL, leave "Bearer Token" blank
  • In the Output tab
    • Audio Encoder: FFmpeg Opus (or another Opus encoder, if available)
    • Video Encoder: x264 (or a hardware accelerated H.264 encoder like QuickSync or NVENC)
    • Rate Control: CBR or VBR
    • Bitrate: between 3000 Kbps and 7000 Kpbs
    • Profile: main or baseline
    • B Frames: 0
  • In the Video tab
    • Framerate: field may be called "Common FPS Values" or "Integer FPS Value", set to 30

Using FFmpeg 8.1 or higher: This sample command outputs a clock and a constant tone. Revise the input criteria with your content.

ffmpeg -hide_banner -y \
  -re -f lavfi -i testsrc=size=1920x1080:rate=30 \
  -re -f lavfi -i "sine=frequency=200" \
  -vf "drawtext=fontsize=120:text='%{gmtime}.%{eif\:1M*t-1K*trunc(t\*1K)\:d}':x=0:y=0:fontcolor=WhiteSmoke:box=1:boxcolor=black@0.6" \
  -c:v libx264 -flags +global_header -maxrate 4000k -bufsize 1500k \
  -tune zerolatency -g 30 -profile:v baseline -pix_fmt yuv420p \
  -acodec libopus -b:a 128k -ar 48000 -ac 2 \
  -ts_buffer_size 16777216 \
  -f whip https://customer-igynxd2rwhmuoxw8.cloudflarestream.com/71adb6d1676e2aa8d42ddce2271a2aedk5b6efd743b78487c095b2911e08345d8/webRTC/publish

If using Windows/PowerShell:

  • Add :fontfile='C\:/Windows/Fonts/consola.ttf' to the vf string; a font must be specified in Windows environments
  • Use backticks \`` instead of backslashes ` to segment a multiline command

FFmpeg's WHIP support currently requires the use of libx264 at baseline. The ts_buffer_size is a memory allocation strategy, not a buffer that increases latency.

Step 3: Play live video using WHEP

Using the Stream Player: Stream's built-in player already supports playing WebRTC broadcasts by automatically upgrading to WHEP when available. Refer to "Use the Stream Player" for more information. The player embed code can be generated on the live input's settings page in the Dashboard.

Using the WHEP endpoint in a custom player:

Copy the URL from either:

  • The Live inputs page of the Cloudflare dashboard.

    Go to Live inputs ↗
  • The webRTCPlayback.url property in the API response when the input is created.

While the creator is actively streaming, viewers can watch the broadcast in their browsers with less than 500 milliseconds of latency. There are no fixed limits on the number of concurrent viewers.

For a complete, no-dependency example of playing WebRTC in a browser, see the First WebRTC broadcast in the browser tutorial.

This URL can also be used with any client that supports the WebRTC-HTTP Egress Protocol (WHEP). See supported WHEP clients for a list of clients we have tested and confirmed compatibility with Cloudflare Stream.

Debugging WebRTC

  • Chrome: Navigate to chrome://webrtc-internals to view detailed logs and graphs.
  • Firefox: Navigate to about:webrtc to view information about WebRTC sessions, similar to Chrome.
  • Safari: To enable WebRTC logs, from the inspector, open the settings tab (cogwheel icon), and set WebRTC logging to "Verbose" in the dropdown menu.

Supported WHIP and WHEP clients

You can write your own broadcast and publishing apps using the browser's native WebRTC APIs — see the First WebRTC broadcast in the browser tutorial. Beyond native code, we have tested and confirmed that the following clients are compatible with Cloudflare Stream:

WHIP for Broadcasting

Dedicated applications:

Development libraries:

WHEP for Playback

Using WebRTC in native apps

If you are building a native app, the browser example from the First WebRTC broadcast in the browser tutorial can run within a WkWebView (iOS), WebView (Android) or using react-native-webrtc. If you need to use WebRTC without a webview, you can use Google's Java and Objective-C native implementations of WebRTC APIs.

Supported broadcast codecs

  • VP9
  • VP8
  • h264 (Constrained Baseline Profile Level 3.1, referred to as 42e01f in the SDP offer's profile-level-id parameter.)

Conformance with WHIP and WHEP specifications

Cloudflare Stream supports the WHIP and WHEP specifications, including:

You can find the specific version of WHIP and WHEP being used in the protocol-version header in WHIP and WHEP API responses. The value of this header references the IETF draft slug for each protocol. Currently, Stream uses draft-ietf-wish-whip-06 (expected to be the final WHIP draft revision) and draft-murillo-whep-01 (the most current WHEP draft).

Limitations

WHIP and WHEP must be used together: we do not yet support inputs using RTMP/SRT to be played using WHEP, or inputs using WHIP to be recorded and played played using HLS/DASH.

  • Broadcast metrics and player experience metrics are not supported
  • Recording and live HLS playback are not yet supported
  • Simulcasting (restreaming via RTMP/SRT) is not supported
  • Live viewer counts are not supported

Pricing

Stream Live WebRTC follows standard Stream pricing: $1 per 1,000 minutes of video delivered. WebRTC is not currently eligible for recording, thus no storage is consumed.

Was this helpful?