Skip to content

h265web.js PRO Get Started ​

h265web.js PRO is the current official release line and it is free to use.

This page keeps the player creation flow as small and practical as possible.

If a sample does not load or stays black, use QA WIKI · Frequently Asked Questions for MP4 moov/Range, autoplay, CORS and WASM checks.

1. Files You Need ​

The browser runtime usually needs these files:

  • h265web.js
  • h265web_wasm.js
  • h265web_wasm.wasm

A common layout looks like this:

text
root/
├── index.html
├── index.js
├── resource/
│   └── demo.mp4
└── output/
    ├── h265web.js
    ├── h265web_wasm.js
    └── h265web_wasm.wasm

2. Import The SDK ​

html
<head>
  <meta charset="utf-8" />
  <script src="./output/h265web.js"></script>
</head>

After this script loads, the console prints [h265web.js] SDK script loaded: https://github.com/numberwolf/h265web.js through console.info. This confirms the SDK JavaScript loaded; WASM initialization and its output happen only when the selected playback path needs WASM.

3. Create A Player Container ​

html
<div id="canvas111"></div>

4. Set Resource Paths ​

SDK resource paths support all of these styles:

  • Full URL: https://cdn.example.com/output/h265web_wasm.js
  • Site-absolute path: /output/h265web_wasm.js
  • Relative path: ./output/h265web_wasm.js

If you want one common base directory for SDK resources, use base_url.

js
const playerConfig = {
  player_id: 'canvas111',
  base_url: './output/',
  wasm_js_uri: 'h265web_wasm.js',
  wasm_wasm_uri: 'h265web_wasm.wasm',
  width: '100%',
  height: 480,
  color: '#101318',
  auto_play: true,
  readframe_multi_times: -1,
  ignore_audio: false
};

5. Create The Player ​

js
const ylplayer = H265webjsPlayer();
ylplayer.build(playerConfig);

6. Minimum Required Callbacks ​

These are the two callbacks you should wire first.

js
ylplayer.on_ready_show_done_callback = function () {
  console.log('on_ready_show_done_callback');
};

ylplayer.video_probe_callback = function (mediaInfo) {
  console.log('video_probe_callback', mediaInfo);
};

ylplayer.on_error_callback = function (error) {
  console.error('player error', error);
};

WebRTC does not add a second callback API. Bind the same probe, ready, play-time, loading, release, render and error callbacks before build().

Useful Additional Callbacks ​

Keep these when you need playback progress, cache state, or seek state.

js
ylplayer.on_cache_process_callback = function (timestamp) {
  console.log('on_cache_process_callback', timestamp);
};

ylplayer.on_load_caching_callback = function () {
  console.log('on_load_caching_callback');
};

ylplayer.on_finish_cache_callback = function (data) {
  console.log('on_finish_cache_callback', data);
};

ylplayer.on_play_finished = function () {
  console.log('on_play_finished');
};

ylplayer.on_play_time = function (pts) {
  console.log('on_play_time', pts);
};

ylplayer.on_seek_start_callback = function (seekTarget) {
  console.log('on_seek_start_callback', seekTarget);
};

ylplayer.on_seek_done_callback = function (seekTarget) {
  console.log('on_seek_done_callback', seekTarget);
};

Feature callbacks such as SEI can be wired separately when your stream carries extra metadata.

js
ylplayer.video_sei_raw_callback = function (rawSei, pts, dts, codec) {
  console.log('video_sei_raw_callback', rawSei, pts, dts, codec);
};

ylplayer.video_sei_text_callback = function (text, pts, dts, codec) {
  console.log('video_sei_text_callback', text, pts, dts, codec);
};

7. Load Media ​

Media URLs support the same three styles:

  • Full URL: https://example.com/media/demo.mp4
  • Site-absolute path: /resource/demo.mp4
  • Relative path: ./resource/demo.mp4
js
const mediaUrl = './resource/demo.mp4';
ylplayer.load_media(mediaUrl);

8. WebRTC Live Playback ​

WHIP is the standard HTTP signaling protocol for WebRTC publishing. WHEP is the corresponding standard for playback, so a player should normally receive a WHEP endpoint.

The SDK recognizes these three playback URL forms:

text
http://127.0.0.1/index/api/whep?app=live&stream=test
webrtc://127.0.0.1/live/test
http://127.0.0.1/index/api/webrtc?app=live&stream=test&type=play

The first URL is standard WHEP and is recommended. webrtc:// is an SDK compatibility URL converted to WHEP. The third URL is the ZLMediaKit private signaling API. The HTTP(S) endpoint exchanges SDP; the negotiated media still uses WebRTC ICE/DTLS/SRTP.

Auto routing needs no additional configuration:

js
ylplayer.load_media('http://127.0.0.1/index/api/whep?app=live&stream=test');

To require WebRTC explicitly, keep the existing API and add the normal core field:

js
playerConfig.core = 'webrtc';
ylplayer.build(playerConfig);
ylplayer.load_media('http://127.0.0.1/index/api/whep?app=live&stream=test');

When ZLMediaKit converts RTMP to WebRTC, use the tested timestamp policy:

ini
[protocol]
modify_stamp=1
paced_sender_ms=0

modify_stamp=1 rebuilds and smooths timestamps from the ZLMediaKit receive clock. With modify_stamp=2, an RTMP input can keep decoding at the expected frame rate while Chrome treats frames on the resulting native WebRTC timeline as late and drops them, producing visible jumps. This setting aligns the server-side RTMP-to-RTP timeline; it is not a browser-side decode option.

Native WebRTC live playback runs at 1x and does not support seek. It supports negotiated AV, video-only and audio-only results. Standard WebRTC can only receive codecs accepted by the browser's WebRTC stack. A non-negotiated codec requires the media server to implement the optional h265web-rtc-encoded/v1 encoded-media transport before the WebCodecs/WASM route can be used.

9. Start Playback ​

If auto_play is false, call play() after the first frame is ready.

js
ylplayer.on_ready_show_done_callback = function () {
  ylplayer.play();
};

10. Small Working Example ​

js
const ylplayer = H265webjsPlayer();

ylplayer.on_ready_show_done_callback = function () {
  console.log('first frame ready');
};

ylplayer.video_probe_callback = function (mediaInfo) {
  console.log('mediaInfo', mediaInfo);
};

ylplayer.build({
  player_id: 'canvas111',
  base_url: './output/',
  wasm_js_uri: 'h265web_wasm.js',
  wasm_wasm_uri: 'h265web_wasm.wasm',
  width: '100%',
  height: 480,
  auto_play: true,
  ignore_audio: false
});

ylplayer.load_media('./resource/demo.mp4');