# h265web.js: a browser HEVC player built around the problem browsers did not solve

> Since 2017 one JavaScript SDK has been decoding H.265 in browsers that ship no hardware path for it, across live and on-demand protocols, with the README now pointing at a paid Pro edition alongside the free one.

**numberwolf/h265web.js** — https://h265web.com - A HEVC/H.265 web player by Chang Yanlong, supporting hardware decoding for live and VOD streams, with H.265 codec support for HttpFLV/HLS/MP4/TS/FLV/M3U8/WebSocket/WebRTC playback.

- Repository: https://github.com/numberwolf/h265web.js
- Website: https://h265web.com
- Stars: 2,351 · Forks: 382
- Language: JavaScript
- License: NOASSERTION
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/numberwolf-h265web-js

## The gap this project exists to fill

HEVC is a better codec than H.264 and browsers mostly do not play it. Safari has supported HEVC natively for years, Chrome added it on some platforms, and everywhere else you get a blank player. For a streaming product that means your encode choice and your audience's browser support pull in opposite directions, and the usual workarounds are all compromises: transcode to H.264 and throw away the bandwidth you were trying to save, or ship a software decoder and hope the CPU keeps up.

h265web.js takes the second option seriously and does it properly. It is a JavaScript SDK that assembles a decode path in the browser for HEVC/H.265, AVC/H.264 and AV1, spanning live and on-demand streams. The listed use cases are the ones a real integration needs rather than a demo needs: MP4, MOV, MKV, FLV, MPEG-TS, MPEG-PS, M3U8, HLS, HTTP-FLV, WS-FLV, HTTP-TS, WS-TS, WebRTC and raw HEVC elementary streams.

The project's own framing is continuity rather than novelty. The README says h265web.js has been built and refined continuously since 2017, and the repository reflects that, with 2,348 stars, 383 forks, 65 open issues and a push on 2026-09-27. Author ChangYanlong runs it as a long-lived product with a website, a public demo, a QQ group, a Discord server and a WeChat account, which is a different operating model from a library that lands one release and goes quiet.

## What the protocol matrix actually claims

The feature matrix is the most useful part of the README because it is a list of formats rather than adjectives. Live coverage runs through HLS, HTTP-FLV, HTTP-TS, WS-FLV and WS-TS. On-demand coverage runs through M3U8, MP4, FLV, MPEG-TS and MPEG-PS, plus MOV with H.265 and MKV with HEVC. Codec coverage includes AV1 on Chrome, AAC in main and LC profiles, G.711A and G.711U over HTTP-FLV, and raw HEVC over both HTTP and WebSocket.

Read the caveats in the matrix as carefully as the rows. The multi-thread decode entry is annotated in red as available only over https with a suitable nginx configuration, which tells you it depends on serving rather than on the library, and that single-thread decode is the general case. If your deployment is plain http or a CDN that will not set the headers multi-thread wants, you are on the slower path.

The matrix also has a small inconsistency worth mentioning because it shows how the page is maintained: the G.711A and G.711U cells both point at the same `resource/icon-pcm.png` asset. Neither capability is in doubt, but the icons are hand-maintained HTML tables, and that is the sort of thing that drifts.

The media server recommendation is stated directly rather than implied. The README points at ZLMediaKit as the recommended server for live and VOD delivery, which is a coherent pairing: a C++ streaming server that speaks HTTP-FLV, WebSocket-FLV, HLS and WebRTC is exactly the transport surface this SDK consumes.

## The HLS routing rewrite is the real story of 2026

The August 2026 release is where the engineering shows. The change: HLS gained a mainline routing layer that picks a decode chain among native HLS, MSE, WebCodec and WASM based on browser capability, an explicitly requested kernel, and which callbacks the caller has bound. Everything after that is the cost of making that decision honest.

The default `hls_strategy: "auto"` now uses only the mainline kernels and no longer silently falls back to the historical `past-core/ext*` implementations. You can force the new behaviour with `hls_strategy: "mainline"`, and you have to ask for `hls_strategy: "legacy"` explicitly to get the old path. The older `hls_legacy_fallback: true` parameter no longer enables automatic fallback, which means a config file carrying that flag has quietly changed meaning. When every mainline candidate fails, the player returns a specific error instead of switching kernels on its own.

Callback handling got the same treatment, and this is the part integrators should read twice. The player now chooses a kernel that can satisfy the callbacks you registered, and an explicitly named kernel that cannot support them produces an error rather than silently dropping callbacks. Time units are defined: playback time, seek and media duration in seconds; NAL units, frames, rendering, SEI and cache timestamps in milliseconds. `on_release_done_callback` fires exactly once, after player resources and workers are actually released. Audio control is separated too, where `ignore_audio` means skip the audio pipeline entirely and `set_mute()` is the reversible option.

Underneath that is a long list of fixes in the same release: master and media playlists, relative paths, redirects, live sliding windows and discontinuity handling; format detection for H.264, H.265, AAC, PCM, G.711A and G.711U; HEVC sample description, keyframe detection, Annex-B conversion and decoder reconfiguration; DTS and PTS regressions on H.265 B-frame TS content that caused dropped frames and audio-video drift; and hardening of the build, load, play, seek, release and rebuild lifecycle, including worker cleanup, timeout termination and multi-instance isolation.

## WebRTC arrived as a demo before it arrived as a release

The 2026-08-24 release adds WebRTC, and the repository root carries the two HTML pages that make it inspectable: `webrtc-publish.html` for WHIP publishing and `webrtc-play.html` for WHEP playback. Those two files sit next to `index.html`, `index-cn.html`, `index.js` and `index.css`, which is the repository's actual shape, and worth being blunt about.

There is no `src` directory, no `package.json` and no build config in the tree. What the repository holds is the README in two languages, a `DOCS` folder, a `static` directory, an image folder, the demo pages and one small test asset named `hevc_test_moov_set_head_16s_hvc1.mp4` whose name describes exactly what it is, a 16 second H.265 clip. This is a documentation and demo repository attached to a commercial product, not a mirror of the SDK source. The practical consequence is that you integrate against the SDK the project hands out through its website and docs, and you read the repository for the release history, the capability matrix and the behaviour changes.

That is a legitimate arrangement, and the docs are substantial enough to compensate, with a get-started guide online and a local copy at `DOCS/README-HowToUse.MD`, plus a separate QA wiki for frequently asked questions. But it does mean the usual GitHub read, clone, run the tests, read the source, does not apply here. Budget an hour with the demo player and the QA wiki before you plan the integration.

## Who is using it, and what the version numbers mean

The README lists integration references under a partial table, and the names are a reasonable proxy for the kind of traffic involved: Temu, Kwai, iQiYi, Baidu, Baidu Cloud, Shandong World, Shanghai Unicom, Xi'an Sihua, Beijing Shutong Mofang, Hangzhou Chengzhi Tianyang and Nanjing Yiyi. A mix of consumer platforms, cloud providers and regional carriers, which is what you would expect for a codec gap that mainly bites outside North America and Western Europe.

Version numbers are dates rather than semantic versions. The three releases are `v20260926`, `v20260824` and `v20260810`, and the two most recent bodies are short: VR 360 media playback, and WebRTC support. Calendar versioning tells you the cadence without reading anything, which is useful for a component where upstream browser behaviour is the main source of churn. It also means there is no minor-version compatibility promise to lean on, so pin the version you tested.

The licensing picture needs reading carefully. GitHub reports the license as NOASSERTION, and the tree contains two license files, `LICENSE-Free_CN.MD` and `LICENSE-Free_EN.MD`. Neither the name nor the repository metadata gives you the terms at a glance, so open both files before shipping anything commercial. The README also positions a paid Pro edition as the mature version with broader coverage and stronger performance, covering HEVC, AVC, AV1, WebRTC, live, VOD, WebCodec, WASM decoding, MediaInfo, snapshot, fullscreen, seek and multi-instance playback. The open source repository is the free half of that product.

## Where to start and what to test first

The shortest useful path runs through the public demo at `h265web.com/player.php`, which is linked from the README badges along with the get-started guide. Both WebRTC demo pages can be opened directly from the repository if you want to see the publish and playback flows before wiring your own server.

For an integration, three things decide whether this SDK fits, and all three are testable before you write the player UI. First, browser support for your actual traffic: check whether your viewers' browsers decode HEVC natively, because on Safari or a recent Chrome with hardware support the native path is both faster and less work. Second, the HLS strategy decision, since the routing layer now surfaces an error where it used to switch kernels quietly, which means a configuration that relied on silent fallback needs to be revisited. Third, the callback set you need, because the new kernel selection is callback-aware and a kernel that cannot deliver what you registered will now tell you instead of quietly omitting it.

On the server side, the recommended ZLMediaKit pairing is worth trying first because it keeps the transport layer conventional and lets you isolate the player from the streaming stack. If you need multi-thread decoding, sort out the https and nginx configuration early, since the feature matrix ties it to serving rather than to the SDK, and a change of CDN later can take it away.

Support is reachable through a QQ group at 925466059, Discord, WeChat, email and the QA wiki. For a component this old and this widely deployed, the accumulated answers in that wiki are arguably the most valuable part of the offering.

## Conclusion

h265web.js earns its place when your content is H.265 and your users' browsers do not decode it, which is still the normal case outside Safari and the latest Chrome on supported hardware. It is a JavaScript SDK with a real engineering record behind it: a date-versioned release history that documents its own breaking changes, a protocol matrix that names its limits, and integration references from streaming platforms and carriers. Two things deserve your attention before committing. The repository root is documentation and demo pages rather than the library source, so what you install comes from the project's website rather than a clone. And the README's headline paragraph is about Pro, a paid edition, with the free SDK described as the open source half of the same work. Read the DOCS folder and the release notes, feed it one real stream from your own server, and check the HLS routing decision for your browser before you build a timeline around it.

## FAQ

### Can h265web.js play HEVC video in any browser?

That is the point of the project. Browsers that lack native HEVC support get a decode path assembled in JavaScript, and the same SDK covers AVC/H.264 and AV1. On browsers that do decode HEVC natively, including Safari and recent Chrome builds on supported hardware, the native path is available and is usually the cheaper option.

### Which streaming protocols does h265web.js support?

The feature matrix covers HLS and M3U8, MP4, MOV with H.265, MKV with HEVC, FLV, MPEG-TS, MPEG-PS, HTTP-FLV, HTTP-TS, WS-FLV, WS-TS, raw HEVC over HTTP and WebSocket, and WebRTC. Audio formats include AAC main and LC plus G.711A and G.711U over HTTP-FLV. The README recommends ZLMediaKit as the server side.

### What changed in the 2026 HLS update, and how do I pick a strategy?

HLS gained a mainline routing layer that chooses between native HLS, MSE, WebCodec and WASM. The default `hls_strategy: "auto"` no longer falls back to the old `past-core/ext*` kernels, `"mainline"` forces the new path, and `"legacy"` is the only way to get the old one. The old `hls_legacy_fallback: true` flag no longer triggers automatic fallback, and a failed candidate returns an explicit error instead of switching quietly.

## Sources

- [Issues](https://github.com/numberwolf/h265web.js/issues)
- [numberwolf/h265web.js on GitHub](https://github.com/numberwolf/h265web.js)
- [Project website](https://h265web.com)
- [README](https://github.com/numberwolf/h265web.js/blob/master/README.md)
- [Releases](https://github.com/numberwolf/h265web.js/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/numberwolf-h265web-js
