Skip to content

Live Playback Demo (HTTP-FLV / HLS) ​

This is a minimal player for an ordinary live URL. Start a real stream before opening the page; entering a URL does not create a stream. For WebRTC live playback, use the separate WebRTC Playback Demo.

1. Prepare a live stream and URL ​

For example, run ZLMediaKit and publish a file to live/test with FFmpeg. Replace ./media/live.mp4 with your test file, or download the self-generated ordinary H.264 + AAC sample under that name. For direct stream-copy publishing and VR360 live URLs, see Test Media and FFmpeg:

bash
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/test

Typical playback URLs are:

text
HTTP-FLV: http://127.0.0.1/live/test.live.flv
HLS:      http://127.0.0.1/live/test/hls.m3u8

127.0.0.1 means the browser's own machine. If the media server is elsewhere, use its real address and configure CORS when origins differ. HLS segment delay is not a measure of low-latency live performance.

2. Copy index.html ​

Place matching-build output/h265web.js, h265web_wasm.js and h265web_wasm.wasm beside the page and serve it over HTTP.

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Live 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">Connecting to live stream…</p>

  <script>
    // Confirm this URL is reachable from the browser and a stream is live.
    const mediaUrl = 'http://127.0.0.1/live/test.live.flv';
    // For HLS, replace the line above with:
    // const mediaUrl = 'http://127.0.0.1/live/test/hls.m3u8';
    const status = document.getElementById('status');
    const playButton = document.getElementById('play');
    const player = H265webjsPlayer();

    // Bind callbacks first. Caching can mean waiting for the next live segment.
    player.on_ready_show_done_callback = () => {
      playButton.disabled = false;
      status.textContent = 'Live first frame ready. Press Play.';
    };
    player.on_load_caching_callback = () => { status.textContent = 'Waiting for live data…'; };
    player.on_error_callback = (error) => {
      status.textContent = `Live 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,
      hls_strategy: 'auto' // Use current HLS routing, not the historical legacy core.
    });
    if (ok) {
      player.set_voice(0); // Start muted; enable audio from a user click.
      player.load_media(mediaUrl);
    } 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 ​

  • If there is no live stream at the URL, the player can only wait or report an error. Check live/test on the media server first.
  • With auto_play: false, press Play after the first frame is ready.
  • Ordinary live streams are not generally seekable; seek only within a range offered by the server.
  • Keep HLS on hls_strategy: 'auto' or 'mainline'; for failures, check Network, CORS and QA WIKI.