Wowza Streaming Engine can ingest and deliver audio and video over WebRTC, and can transmux or transcode WebRTC to HLS, MPEG-DASH, RTMP, or RTSP. It can also ingest a non-WebRTC source and play it back over WebRTC (alone or alongside HTTP-based protocols like HLS). This article covers publishing and playing a stream over WebRTC with all major desktop and mobile browsers that support the WebRTC APIs. Encryption is mandatory for WebRTC, so you must configure SSL/TLS before streaming.
Starting with Wowza Streaming Engine 4.11.0, WebRTC runs on an updated stack that is the default for new installations. The previous (legacy) implementation continues to work unchanged and remains available — see Use the legacy WebRTC implementation. It adds the following new capabilities:
- WHIP and WHEP support — standard HTTP signaling for publishing (WHIP) and playback (WHEP), interoperable with tools such as OBS Studio, FFmpeg, and GStreamer.
- Configurable STUN and TURN servers (with TURN authentication) per application, to improve connectivity across restrictive NATs and firewalls.
- Improved ICE — full candidate gathering and connectivity checks, trickle ICE, and TCP candidate support where UDP is blocked.
- Expanded codecs — adds HEVC (H.265) and VP9 alongside H.264 and VP8, with automatic negotiation.
- Multiple IP / NIC support — works on secondary public IPs and additional host ports.
Before you start
You should complete the following tasks:
- Create a live application according to Create applications.
- Review the supported codecs and browsers. The current stack supports H.264, HEVC (H.265), VP8, and VP9 video with automatic negotiation.
- Configure SSL/TLS in Wowza Streaming Engine. We recommend the free Wowza StreamLock service, but you can use your own certificate. (If it's self-signed, configure your test browser to trust it.) Certificates must be in Java KeyStore (JKS) format.
Upgrading from an earlier version
New installations of Wowza Streaming Engine 4.11.0 and later already include the configuration the current WebRTC stack needs. If you're upgrading from an earlier version, you must manually update VHost.xml and Application.xml before you can use WHIP, WHEP, or trickle ICE. Complete the steps below first, then continue with the configuration sections that follow.
Update VHost.xml
Both updates are in [install-dir]/conf/VHost.xml. Save the file and restart Wowza Streaming Engine after you finish.
WebRTC HTTP provider
Point the WebRTC signaling provider at the updated signaling router. In the <HTTPProviders> element of your SSL/TLS host port, find the <HTTPProvider> whose <BaseClass> is the deprecated class:
<!-- Deprecated WebRTC HTTP provider -->
<HTTPProvider>
<BaseClass>com.wowza.wms.webrtc.http.HTTPWebRTCExchangeSessionInfo</BaseClass>
<RequestFilters>*webrtc-session.json</RequestFilters>
<AuthenticationMethod>none</AuthenticationMethod>
</HTTPProvider>Update the <BaseClass> value to the updated class:
<!-- Updated WebRTC HTTP provider -->
<HTTPProvider>
<BaseClass>com.wowza.wms.webrtc2.http.HTTPWebRTCSignalingRouter</BaseClass>
<RequestFilters>*webrtc-session.json</RequestFilters>
<AuthenticationMethod>none</AuthenticationMethod>
</HTTPProvider>WebRTC HTTP streamer adapter
- In the
<HTTPStreamerAdapters>element, add awebrtcadapter:<HTTPStreamerAdapter> <ID>webrtc</ID> <Name>webrtc</Name> <Properties></Properties> </HTTPStreamerAdapter> - Add
webrtcto the<HTTPStreamerAdapterIDs>list. For example:<HTTPStreamerAdapterIDs>cupertinostreaming,smoothstreaming,sanjosestreaming,dvrchunkstreaming,mpegdashstreaming,webrtc</HTTPStreamerAdapterIDs>
Update Application.xml
For each WebRTC application, open [install-dir]/conf/[application-name]/Application.xml and add webrtc to the <HTTPStreamers> list. For example:
<HTTPStreamers>cupertinostreaming,mpegdashstreaming,webrtc</HTTPStreamers>
Save the file and restart Wowza Streaming Engine.
Note: After upgrading, the WebRTC implementation defaults to dynamic until you set it explicitly. To use the current WebRTC implementation exclusively, set the implementation to WebRTC (v2) — see Configure SSL/TLS encryption for WebRTC.
1. Configure SSL/TLS encryption for WebRTC
Because of cross-domain restrictions, you must secure the browser-to-server SDP exchange with an SSL/TLS certificate and enable WebRTC WebSocket signaling on the SSL/TLS host port. Use either Wowza Streaming Engine Manager or XML.
Wowza Streaming Engine Manager
- Click the Server tab, then Virtual Host Setup, then Edit.
- Under Host Ports, click the edit icon for your SSL/TLS port and select Use WebRTC WebSocket Signaling. Click Apply.
- Under WebRTC WebSocket Implementation, select the implementation the virtual host uses (see the table below). For the current implementation, select WebRTC.
- Click Save, then restart the virtual host.
XML
- Open
[install-dir]/conf/VHost.xmlin a text editor. - In the
<HTTPProviders>container of your SSL/TLS<HostPort>, add the WebRTC signaling provider (this is what enables WebRTC on the port) as the second-to-last entry:<HTTPProvider> <BaseClass>com.wowza.wms.webrtc2.http.HTTPWebRTCSignalingRouter</BaseClass> <RequestFilters>*webrtc-session.json</RequestFilters> <AuthenticationMethod>none</AuthenticationMethod> </HTTPProvider>If you upgraded from an earlier version and an older WebRTC provider is already present, update it instead of adding a new one — see Upgrading from an earlier version.
- Add a
<WebRTC>element to select the implementation. Set<SelectedVersion>tov2(current),legacy, ordynamic:<!-- WebRTC signaling implementation: legacy | v2 | dynamic --> <WebRTC> <SelectedVersion>v2</SelectedVersion> </WebRTC> - The 443 SSL/TLS host port is commented out by default. If needed, comment it back in by removing the surrounding
<!-- 443 with SSL -->,<!--, and-->lines. - Save and restart Wowza Streaming Engine.
| Implementation | Manager option | VHost.xml value | Behavior |
|---|---|---|---|
| WebRTC (current, default) | WebRTC | v2 | All WebRTC signaling uses the current implementation. |
| Legacy | Legacy WebRTC | legacy | All WebRTC signaling uses the legacy implementation. |
| Both (client-selectable) | Dynamic | dynamic | Selectable per client via ?webrtcImplementation=v2 in the signaling URL. If absent or not v2, defaults to legacy. |
Note: When you upgrade from a version earlier than 4.11.0, VHost.xml has no <SelectedVersion> element and Wowza Streaming Engine defaults to dynamic, so existing workflows keep working. Set <SelectedVersion> to v2 to use the current WebRTC implementation exclusively.
2. Enable WebRTC for your application
After enabling SSL/TLS signaling, enable and configure WebRTC for your live application using either Wowza Streaming Engine Manager or XML.
Wowza Streaming Engine Manager
On the Applications tab, select your live application, click WebRTC, and on the Setup tab click Edit. Configure the following, then Save and restart the application.
WebRTC Enabled Features
- Publish WebRTC to Wowza Streaming Engine — ingest WebRTC source streams to this application.
- Play WebRTC from Wowza Streaming Engine — deliver WebRTC playback from this application.
- Query published stream names — allow querying the names of published WebRTC streams.
- Enable WHIP/WHEP — enable the standards-based HTTP endpoints: WHIP (publish) at
/<application>/<stream>/whipand WHEP (play) at/<application>/<stream>/whep, so standard clients can publish and play without WebSocket signaling. See section 3. - Enable Debug Logging — detailed logging of the DTLS handshake, SDP negotiation, UDP port assignment, and session lifecycle. Takes effect at the next application start.
ICE Candidate Setup — ICE candidates specify the network connections WebRTC can use, listed in order of preference. To add one, click Add ICE Candidate, select UDP (recommended) or TCP, enter the publicly accessible server IP address, and (for TCP) a streaming port — the default is 1935; UDP ports are assigned dynamically. Use the Priority arrows to order candidates.
Note: TCP candidates are uncommon and used mainly when UDP is unavailable or restricted; not all browsers support ICE over TCP. IPv6 isn't supported, and port 554 isn't supported for TCP candidates.
STUN Server and TURN Relay — optionally specify external STUN and TURN servers to establish connectivity when clients and the server can't reach each other directly. TURN Username and TURN Password authenticate with the TURN relay. Leave empty if unused.
A STUN (Session Traversal Utilities for NAT) server lets each WebRTC peer discover the public IP address and port it appears as on the internet, so peers behind NATs and firewalls can advertise reachable candidate addresses and attempt a direct media connection. When a direct path isn't possible — for example, across symmetric NATs or strict firewalls — a TURN (Traversal Using Relays around NAT) server relays the media between the peers instead.
Wowza doesn't host STUN or TURN servers; you supply your own. The example stun.l.google.com:19302 shown in this article is a public STUN service operated by Google — convenient for quick testing, but not intended or guaranteed for production use. TURN in particular requires a server you run and authenticate against, since it relays your media. Common open-source options you can self-host include coturn, eturnal, and Pion TURN.
WHIP/WHEP Authentication — optionally require bearer tokens on the WHIP and/or WHEP endpoints (WHIP Bearer Token (Publish) and WHEP Bearer Token (Play)). See Publish and play with WHIP and WHEP.
Publish Audio Codecs — Opus is the primary supported audio codec; PCMU and PCMA can be used in some cases. The list and order can't be changed.
Publish Video Codecs — H.264, H.265, VP8, and VP9 are supported; at least one is required. Click Add Codec to add one and use the Priority arrows to set the preferred order.
XML
Open [install-dir]/conf/[application-name]/Application.xml and configure the <WebRTC> container element. A complete example:
<WebRTC>
<!-- Enable WebRTC publishing to this application -->
<EnablePublish>true</EnablePublish>
<!-- Enable WebRTC playback from this application -->
<EnablePlay>true</EnablePlay>
<!-- Enable query of published stream names for this application -->
<EnableQuery>true</EnableQuery>
<!-- IP address, transport, and port used for WebRTC streaming. -->
<!-- TCP format: [external-ip-address],tcp,[port] UDP format: [external-ip-address],udp -->
<IceCandidateIpAddresses>13.218.92.124,udp|13.218.92.124,tcp,1935</IceCandidateIpAddresses>
<!-- Local IP of the network card to use for WebRTC UDP traffic -->
<UDPBindAddress/>
<!-- Audio codecs, in order of preference, for ingestion -->
<PreferredCodecsAudio>opus,pcmu,pcma</PreferredCodecsAudio>
<!-- Video codecs, in order of preference, for ingestion -->
<PreferredCodecsVideo>vp8,h264</PreferredCodecsVideo>
<!-- Enable WebRTC debug logging -->
<DebugLog>false</DebugLog>
<Properties>
<Property>
<Name>harvestStunServer</Name>
<Value>stun.l.google.com:19302</Value>
<Type>String</Type>
</Property>
<Property>
<Name>harvestTurnRelay</Name>
<Value>turn.example.com:3478</Value>
<Type>String</Type>
</Property>
<Property>
<Name>harvestTurnRelayUsername</Name>
<Value>turnuser</Value>
<Type>String</Type>
</Property>
<Property>
<Name>harvestTurnRelayPassword</Name>
<Value>turnpassword</Value>
<Type>String</Type>
</Property>
<Property>
<Name>webrtcWhipBearerToken</Name>
<Value>79273a6f03772d162eec9ff2f1218dde</Value>
<Type>String</Type>
</Property>
<Property>
<Name>webrtcWhepBearerToken</Name>
<Value>5c1f0b9a8d4e47a2b6c3f9e1d7a2b8c4</Value>
<Type>String</Type>
</Property>
</Properties>
</WebRTC>Property reference:
| Name | Type | Description |
|---|---|---|
| EnablePublish / EnablePlay / EnableQuery | Boolean | Enable WebRTC publishing, playback, and stream-name querying for this application. |
| IceCandidateIpAddresses | String | IP, transport, and port for WebRTC. UDP: [external-ip],udp (port auto-assigned). TCP: [external-ip],tcp,[port], using a non-SSL streaming HostPort from VHost.xml (for example, 1935). Separate multiple entries with a pipe (|). IPv6 and TCP port 554 aren't supported. |
| UDPBindAddress | String | Local NIC IP for WebRTC UDP traffic. Leave blank for typical UDP; set only with multiple NICs. On cloud instances, 0.0.0.0 often works best. |
| PreferredCodecsAudio | String | Audio codecs in order of preference. Default opus,pcmu,pcma. |
| PreferredCodecsVideo | String | Video codecs in order of preference. Valid: vp8, vp9, h264, h265. Default vp8,h264. At least one required. |
| DebugLog | Boolean | Enable WebRTC debug logging. |
| harvestStunServer | String | STUN server host:port (for example, stun.l.google.com:19302). |
| harvestTurnRelay | String | TURN relay server host:port. |
| harvestTurnRelayUsername / harvestTurnRelayPassword | String | Credentials used to authenticate with the TURN relay. |
| webrtcWhipBearerToken / webrtcWhepBearerToken | String | Bearer tokens required on WHIP (publish) and WHEP (play) requests. Independent of each other; leave unset to keep that direction open. See section 3. |
Save and restart Wowza Streaming Engine.
Note: We recommend disabling B-frames for WebRTC streams. With Wowza Streaming Engine 4.8.14 and later, the Transcoder adds B-frames by default — see Configure B-frame generation in Wowza Streaming Engine.
3. Publish and play with WHIP and WHEP
The current WebRTC stack supports standard WHIP (ingest) and WHEP (egress) HTTP signaling, so clients such as OBS Studio, FFmpeg, and GStreamer can publish and play directly without a custom integration. After you select Enable WHIP/WHEP for the application (section 2), the endpoints are:
- WHIP (publish):
https://[ssl-domain]:[ssl-port]/<application>/<stream>/whip - WHEP (play):
https://[ssl-domain]:[ssl-port]/<application>/<stream>/whep
Point a WHIP-capable encoder at the WHIP endpoint to publish, and a WHEP-capable player at the WHEP endpoint to play the same application and stream.
Bearer token authentication (optional). Authentication is disabled by default; an endpoint with no token stays open. When a token is set, clients must send Authorization: Bearer <token> on every request, and missing or incorrect tokens are rejected with 401 Unauthorized (standard clients support this — for example, the Bearer Token field in OBS Studio). WHIP and WHEP tokens are independent, so a playback token can't be used to publish. Set tokens either way:
- Manager: on the application's WebRTC Setup page, under WHIP/WHEP Authentication, enter or generate WHIP Bearer Token (Publish) and/or WHEP Bearer Token (Play), then Save.
- XML: set
webrtcWhipBearerTokenand/orwebrtcWhepBearerTokenin the<WebRTC>/<Properties>container (see section 2), then restart.
4. (Optional) Configure custom WebRTC properties
You can optionally tune FIR/NACK messaging, out-of-order and retransmitted packet handling, packet loss, and SDP playback compatibility.
5. Test the WebRTC workflow
In production, WebRTC pages must be hosted on a server using SSL/TLS. For testing, use the Wowza-hosted test pages (also reachable from the application's WebRTC Setup page via Wowza Hosted Test Pages).
Publish a test stream
By default, the hosted WebRTC publish test page connects using WebSocket (WSS) signaling. To publish with WHIP instead, select WHIP. Fill in the matching fields, optionally add STUN/TURN details (trickle ICE speeds up setup), then click Publish.
WebSocket (WSS) signaling — default
- Signaling URL:
wss://[ssl-certificate-domain-name]:[SSL-port-number]/webrtc-session.json(include a non-default port if you aren't using 443). With StreamLock on 443:wss://5ab4321c0d123.streamlock.net/webrtc-session.json. - Enter the Application Name matching your WebRTC application and a unique Stream Name.
WHIP (HTTP ingest)
- Select WHIP as the publishing method.
- Signaling URL:
https://[ssl-certificate-domain-name]:[SSL-port-number]— the HTTPS form of the WSS URL above. - Enter the Application Name matching your WebRTC application and a unique Stream Name.
- If the application requires a bearer token, enter it in the token field. Set tokens up in Manager — see Publish and play with WHIP and WHEP.
Note: WHIP also lets external clients publish directly to Wowza Streaming Engine without the test page. In OBS Studio, choose WHIP as the service and set the server to the WHIP endpoint for your application and stream — https://[ssl-domain]:[ssl-port]/<application>/<stream>/whip — then enter the application's WHIP token in the Bearer Token field if one is required.
Tips: The frame rate/size settings constrain the camera input and aren't in the SDP; the browser may adjust the frame rate for network conditions. After publishing, use the arrow next to the camera icon to share your screen. Click Copy config to share settings with another browser or device.
Play a test stream
In a new tab, open the hosted WebRTC play test page and use the same Application Name and Stream Name you published. By default the page connects using WebSocket (WSS) signaling; to play with WHEP instead, select WHEP. Then click Play.
WebSocket (WSS) signaling — default
- Signaling URL:
wss://[ssl-certificate-domain-name]:[SSL-port-number]/webrtc-session.json— the same one used to publish. - Enter the same Application Name and Stream Name used to publish.
- If you use SecureToken playback security, complete the Secure Token Data fields: Shared Secret (required; matches the Playback Security page), Token Timeout (optional, UTC seconds), Hash Query Parameter Prefix (defaults to
wowzatoken), and Include Client IP Address with Client IP Address (required when that option is selected). Note: SecureToken playback is not yet functional in the current stack — see Known issues.
WHEP (HTTP egress)
- Select WHEP as the playback method.
- Signaling URL:
https://[ssl-certificate-domain-name]:[SSL-port-number]— the HTTPS form of the WSS URL. - Enter the same Application Name and Stream Name used to publish.
- If the application requires a bearer token, enter it in the token field (see Publish and play with WHIP and WHEP).
Note: External WHEP players connect directly to the WHEP endpoint for your application and stream: https://[ssl-domain]:[ssl-port]/<application>/<stream>/whep.
Tip: For production playback, consider the Wowza Flowplayer Real-Time Streaming (WebRTC) plugin. To test other protocols, enable them under Playback Types on the application's Setup tab and use that protocol's playback URL.
Use the legacy WebRTC implementation
The legacy implementation continues to work unchanged in 4.11.0. To use it, set WebRTC WebSocket Implementation to Legacy WebRTC in Manager, or <SelectedVersion>legacy</SelectedVersion> in VHost.xml. To run both and choose per client, use Dynamic and include ?webrtcImplementation=v2 in the signaling URL for clients that should use the current implementation.
Legacy limitations that don't apply to the current implementation:
- No full STUN negotiation — only symmetric NAT traversal via a single STUN transport supplied in
IceCandidateIpAddresses; TURN isn't supported. - Firefox requires UDP; TCP isn't supported.
- With UDP ICE candidates, enabling NACK is recommended for retransmission of lost packets.
More resources
- Check out our GitHub WebRTC examples. They demonstrate how to publish and play WebRTC streams with Wowza Streaming Engine.
- Ingest RTSP, SRT, or RTMP streams into Wowza Streaming Engine for playback with WebRTC
- Control access to WebRTC publishing and playback
- Record WebRTC streams with Wowza Streaming Engine
- Tune Wowza Streaming Engine for WebRTC optimal performance
- Protect streaming using SecureToken in Wowza Streaming Engine
Known issues
- SecureToken playback protection is not yet functional in the current WebRTC stack. To protect streams with SecureToken, run the application on the legacy stack until this is resolved.




