Skip to content

WebRTC Protocol

WebRTC is the standard technology for ultra-low latency audio/video communication in browsers. Monibuca V6 implements publishing and subscribing based on the WHIP (WebRTC-HTTP Ingestion Protocol) and WHEP (WebRTC-HTTP Egress Protocol) standards, powered by the rustrtc engine for full ICE/DTLS/SRTP support.

PropertyValue
Signaling TransportHTTP (WHIP/WHEP)
Media TransportUDP (ICE/DTLS/SRTP)
Publish✅ Supported (WHIP)
Subscribe✅ Supported (WHEP)
Latency< 500ms
Feature Flagwebrtc
Cargo.toml
[features]
webrtc = ["dep:plugin-webrtc"]
webrtc:
enable: true
port_range: "udp:9000-9100"
pli_interval: 2
public_ip: ""
enable_cors: true
cors_origins:
- "*"
ice_servers:
- urls:
- "stun:stun.l.google.com:19302"
OptionTypeDefaultDescription
enablebooltrueWhether to enable the WebRTC plugin
port_rangestring"udp:9000-9100"UDP port range
pli_intervalu642PLI (keyframe request) interval (seconds)
public_ipstring""Public IP (used for NAT traversal)
enable_corsbooltrueWhether to enable CORS
cors_originsVec["*"]Allowed cross-origin sources
ice_serversVec[]ICE server list
ice_servers:
# STUN server (for NAT traversal)
- urls:
- "stun:stun.l.google.com:19302"
# TURN server (for relay)
- urls:
- "turn:turn.example.com:3478"
username: "user"
credential: "pass"
TypeCodecDescription
VideoH.264Widely supported
VideoH.265Supported by some browsers
AudioOpusWebRTC standard audio codec
POST /webrtc/whip/{streamPath}
Content-Type: application/sdp

The request body is an SDP Offer, and the response returns an SDP Answer.

FFmpeg 6.1+ supports WHIP publishing:

Terminal window
ffmpeg -re -i input.mp4 \
-c:v libx264 -preset ultrafast -tune zerolatency \
-c:a libopus \
-f whip "http://localhost:8080/webrtc/whip/live/test"

OBS 30+ has built-in WHIP support:

  1. Go to SettingsStream
  2. Select WHIP for the service
  3. Enter the server URL: http://your-server:8080/webrtc/whip/live/test
  4. Click Start Streaming
POST /webrtc/whep/{streamPath}
Content-Type: application/sdp

The request body is an SDP Offer, and the response returns an SDP Answer.

async function play(streamPath) {
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.addTransceiver('video', { direction: 'recvonly' });
pc.addTransceiver('audio', { direction: 'recvonly' });
pc.ontrack = (event) => {
document.getElementById('player').srcObject = event.streams[0];
};
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const response = await fetch(`/webrtc/whep/${streamPath}`, {
method: 'POST',
headers: { 'Content-Type': 'application/sdp' },
body: offer.sdp,
});
const answer = await response.text();
await pc.setRemoteDescription({ type: 'answer', sdp: answer });
}
play('live/test');

Monibuca provides built-in WebRTC test pages for quick feature verification:

PageURLDescription
Publish Test/webrtc/test/publishPublish using camera/screen
Subscribe Test/webrtc/test/subscribePlay an existing WebRTC stream

Simply access the URLs in your browser to use them.

In network environments with NAT, proper configuration is required to ensure WebRTC connectivity:

webrtc:
public_ip: "203.0.113.1" # Server's public IP
webrtc:
ice_servers:
- urls:
- "stun:stun.l.google.com:19302"
- urls:
- "turn:turn.example.com:3478"
username: "user"
credential: "pass"

Ensure the UDP port range configured in port_range is open in your firewall:

Terminal window
# Open UDP port range
sudo ufw allow 9000:9100/udp

After publishing via WebRTC, you can subscribe through other protocols:

Terminal window
# After WebRTC WHIP publishing...
# Subscribe via RTMP (Opus automatically transcoded to AAC)
ffplay rtmp://localhost:1935/live/test
# Subscribe via HTTP-FLV
ffplay http://localhost:8080/flv/live/test.flv
# Subscribe via HLS
ffplay http://localhost:8080/hls/live/test/index.m3u8