WebRTC Playback Demo
This example is for receiving a WebRTC stream, not publishing one. WHEP is the recommended playback URL; WHIP is for publishing and cannot be used as the player's URL. The normal H265webjsPlayer() API is enough.
1. Publish a real test stream first
Start ZLMediaKit, then publish a file to live/test. Install FFmpeg and replace ./media/live.mp4 with a real file. You can download our ordinary H.264 + AAC test video as ./media/live.mp4; the test-media guide also has a no-re-encode publishing command:
ffmpeg -stream_loop -1 -re -i ./media/live.mp4 \
-vf scale=640:360,format=yuv420p \
-c:v libx264 -preset veryfast -tune zerolatency -bf 0 -g 30 \
-c:a aac -ar 44100 -ac 2 -f flv \
rtmp://127.0.0.1/live/testCheck that ZLMediaKit's WHEP endpoint is reachable. If the server runs on another machine, replace 127.0.0.1 in the code below with its address. For RTMP-to-WebRTC delivery, use the tested modify_stamp=1 setting in Get Started. The browser can only play codecs it successfully negotiates.
2. Copy index.html
Also place matching-build output/h265web.js, h265web_wasm.js and h265web_wasm.wasm beside the page. Serve the page over HTTP, not file://.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>WebRTC playback demo</title>
<script src="./output/h265web.js"></script>
</head>
<body>
<div id="player"></div>
<button id="play" disabled>Play</button>
<button id="pause">Pause</button>
<button id="sound">Enable sound</button>
<p id="status">Waiting for WebRTC video…</p>
<script>
// WHEP receives media. Confirm live/test exists on ZLMediaKit first.
const whepUrl = 'http://127.0.0.1/index/api/whep?app=live&stream=test';
const status = document.getElementById('status');
const playButton = document.getElementById('play');
const player = H265webjsPlayer();
// Bind callbacks before build() so first-frame and error events are visible.
player.on_ready_show_done_callback = () => {
playButton.disabled = false;
status.textContent = 'WebRTC first frame ready. Press Play.';
};
player.video_probe_callback = (info) => console.log('Media info', info);
player.on_error_callback = (error) => {
status.textContent = `WebRTC error: ${error.message || error.code}`;
};
const ok = player.build({
player_id: 'player',
base_url: './output/',
wasm_js_uri: 'h265web_wasm.js',
wasm_wasm_uri: 'h265web_wasm.wasm',
width: '100%', height: 480,
auto_play: false, ignore_audio: false,
// No core field: the SDK recognizes WHEP URLs automatically.
// Add core: 'webrtc' only when you explicitly want to require WebRTC.
});
if (ok) {
player.set_voice(0); // Start muted; the sound button restores audio.
player.load_media(whepUrl);
} else {
status.textContent = 'Player build failed: check SDK file paths.';
}
playButton.onclick = () => player.play();
document.getElementById('pause').onclick = () => player.pause();
document.getElementById('sound').onclick = () => player.set_voice(1);
window.addEventListener('beforeunload', () => player.release());
</script>
</body>
</html>3. Common mistakes
- WHEP is for playback, WHIP for publishing.
webrtc://is a compatibility form; test WHEP first. - Native WebRTC live playback stays at 1x and does not support normal VOD seeking.
127.0.0.1means the machine opening the webpage. For remote browsers, replace it and check signaling CORS/HTTPS/ICE.- If video jumps, check ZLMediaKit timestamp settings and the source stream before QA WIKI.