npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kongliu/libde265-web

v0.1.4

Published

Browser HEVC player with transparent WebCodecs/libde265 WASM fallback

Readme

libde265-web

English | 简体中文

浏览器端 HEVC/H.265 实时播放器:优先使用 WebCodecs,浏览器或具体 HEVC 配置不支持时透明回退到 libde265 WebAssembly。两种后端共享同一个播放器、输入、 帧和事件接口。

特性

  • auto、webcodecs、wasm 三种解码模式
  • WebSocket 二进制 Annex-B 字节流,可跨消息任意分片
  • 内置 HEVC NAL/Access Unit 拆分和 VPS/SPS/PPS 缓存
  • 有界输入队列、WebCodecs 背压、关键帧安全恢复和渲染丢帧
  • 统一 UnifiedVideoFrame,可自动渲染到 Canvas
  • WASM 可自动移入 Dedicated Worker,并把 HTMLCanvasElement 转移为 OffscreenCanvas
  • WebGL2 I420/Main10 shader 渲染,失败时自动回退 Canvas2D
  • baseline、WASM SIMD、WASM threads+SIMD 三种构建
  • TypeScript 源码和自动生成的类型声明,不依赖前端框架
  • ES Module 可直接使用,无运行时 npm 依赖

libde265 本身采用 LGPL-3.0-or-later;本项目的 TypeScript/C++ 胶水采用 MIT。 发布产品前请阅读许可说明和第三方声明,并单独评估 HEVC 专利许可义务。

快速开始

安装开发依赖、编译 TypeScript,并生成 WASM:

npm install
npm run build
git submodule update --init --recursive
npm run build:wasm
npm run serve

浏览器打开 http://localhost:8080。serve 会发送 COOP/COEP 响应头,因此 threads+SIMD 变体可以运行。

多路不同视频的简单示例见 examples/multi-view.html,本地访问 http://localhost:8080/examples/multi-view.html。

最小调用代码:

<canvas id="video"></canvas>
<script type="module">
  import { createHevcPlayer } from "@kongliu/libde265-web";

  const player = await createHevcPlayer({
    canvas: document.querySelector("#video"),
    mode: "auto",
    codec: "hev1.1.6.L93.B0",
    wasmBaseUrl: "/assets/libde265/",
    wasmWorker: "auto",
    renderer: "auto"
  });

  player.on("error", console.error);
  await player.connect("wss://example.com/hevc-stream");
  console.log(player.backend); // "webcodecs" 或 "wasm"
</script>

调用方需要把 dist/wasm/ 下的文件原样部署到 wasmBaseUrl。完整说明见:

手动推流

不使用内置 WebSocket 时,可以接入任意传输层:

const player = await createHevcPlayer({
  canvas,
  mode: "auto",
  wasmBaseUrl: "/wasm/",
  lowLatency: {
    maxInputFrames: 12,
    maxDecodeQueue: 4,
    maxQueueAgeMs: 250,
    dropPolicy: "until-key"
  }
});

transport.onData((bytes) => {
  player.push(bytes); // Uint8Array、DataView 或 ArrayBuffer
});

transport.onEnd(async () => {
  await player.flush();
});

push() 接收原始 Annex-B HEVC,不接收 MP4、MPEG-TS、FLV 等容器。容器数据必须 先 demux。

自定义协议已经解析出完整帧、PTS 和关键帧标志时,直接调用:

player.pushAccessUnit(packet.payload, {
  timestamp: packet.ptsUs,
  duration: packet.durationUs,
  key: packet.key,
  sequence: packet.sequence
});

包入口会自动加载 dist/esm/,类型声明由 TypeScript 输出到 dist/types/。调用方无需 引用本项目的 src/ 目录。

浏览器策略

auto 不会仅凭 window.VideoDecoder 存在就选择 WebCodecs。它会调用 VideoDecoder.isConfigSupported() 探测指定的完整 codec string。HEVC 支持与 操作系统、浏览器、硬件和媒体扩展有关,因此应始终保留 WASM 文件。

多线程 WASM 需要:

  • HTTPS 或 localhost
  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp
  • 浏览器具备 SharedArrayBuffer

wasmVariant: "auto" 会按 SIMD → baseline 自动选择,不会自动启用多线程。 需要 threads+SIMD 时必须显式指定 wasmVariant: "threads-simd"。

WASM 后端默认在浏览器支持时使用 Dedicated Worker。renderer: "auto" 会优先使用 WebGL2,无法创建 WebGL2 context 时回退 Canvas2D;支持 transferControlToOffscreen() 时,解码和渲染都在 Worker 内完成。需要保持所有 frame.planes 时使用默认的 workerFrameOutput: "planes";纯播放且不读取平面时可设为 "metadata",避免把 Y/U/V 平面复制到主线程:

const player = await createHevcPlayer({
  canvas,
  mode: "auto",
  wasmWorker: "auto",
  renderer: "auto",
  workerFrameOutput: "metadata"
});

console.log(player.wasmExecution); // "worker"、"main" 或 null
console.log(player.rendererKind);  // "webgl2"、"canvas2d" 或 null

性能预期

auto 优先选择浏览器原生 WebCodecs;在系统提供 HEVC 硬件解码时,这是低延迟和低 CPU 占用的首选。WASM 是兼容性回退:SIMD 和 threads+SIMD 能明显改善纯软件解码,但实际 能否实时取决于分辨率、位深、码率、设备 CPU 和码流特性,不能用一个固定 FPS 概括。

内置 WASM Canvas 渲染目前会在 CPU 上把 I420 转成 RGBA,高分辨率时可能先成为瓶颈。 对延迟敏感的调用方可以设置 render: false,在 onFrame 中读取统一帧的 nativeFrame 或 planes,接入自己的 WebGL/WebGPU 渲染器。建议用目标设备和真实码流 执行 npm run benchmark:wasm -- baseline <stream.h265> 做验收。

组件默认启用有界低延迟模式。轻度渲染积压时,只丢弃尚未交给调用方的旧解码帧;编码 输入严重积压时会重置解码器、丢弃到下一个 IRAP 关键帧,并触发 keyframerequest。 调用方可监听 backpressure 向自定义服务器发送暂停、降码率或请求 IDR 的控制消息:

player.on("backpressure", ({ level, stats }) => {
  transport.setPressure(level, stats);
});

player.on("keyframerequest", () => {
  transport.requestIdr();
});

验证

npm run check
npm test
npm run build
npm run build:wasm
npm run test:wasm

正式生成 npm 安装包时只需执行:

npm run pack

prepack 会自动依次执行类型检查、单元测试、TypeScript 构建和全部 WASM 构建;任何 一步失败都会中止打包,最终的 .tgz 输出到 build/packages/。不要跳过 prepack, 否则可能把旧版本 libde265 的 WASM 产物装入新包。

上游 libde265 v1.1.1 固定在 Git submodule 中,升级时应重新运行测试和实际码流验证。

参与贡献与安全问题

提交改动前请阅读贡献指南。安全问题请按 安全政策私下报告,不要先创建公开 issue。