@suemor/libav-hevc
v0.1.1
Published
HEVC software decoder for WebAssembly, based on libav.js and FFmpeg
Readme
@suemor/libav-hevc
基于 libav.js 的 HEVC 专用 WASM 解码包。包含普通版、多线程版、CJS/ESM 加载器和类型声明;不包含播放器、音频解码或自动 HEVC 硬解选择。上游作者为 Yahweasel,本 fork 由 suemor 维护 Emscripten 6 兼容修复。
npm install @suemor/libav-hevcimport LibAV from '@suemor/libav-hevc'
const av = await LibAV.LibAV({
yesthreads: true,
// 浏览器部署时指向完整复制的 dist 资源目录,文件名保持不变。
base: new URL('/wasm/libav', location.href).href,
})
// 是否实际启用多线程应检查 av.libavjsMode,不能只看 yesthreads。
const [, context, packet, frame] = await av.ff_init_decoder('hevc', {
threads: 4,
// codecpar、time_base 按实际输入填写。
})
// 通过 ff_decode_multi 喂入 HEVC 包并读取帧;使用结束先释放解码资源。
await av.ff_free_decoder(context, packet, frame)
av.terminate()这是低层 API 用法示意,不是可直接播放文件的完整例子。JS/WASM 文件必须来自同一个包版本。运行在浏览器时推荐在专用 Worker 中解码;多线程需要安全上下文和 SharedArrayBuffer,通常配置 COOP: same-origin / COEP: require-corp。SIMD 不在本包的功能承诺中。
Vite / Electron 静态资源
WASM 和线程胶水不应被改名或混用版本。使用 Node 构建脚本复制整个 dist 目录:
import { createRequire } from 'node:module'
import { dirname, join } from 'node:path'
import { cp, mkdir } from 'node:fs/promises'
const require = createRequire(import.meta.url)
const packageRoot = dirname(require.resolve('@suemor/libav-hevc/package.json'))
await mkdir('public/wasm/libav', { recursive: true })
await cp(join(packageRoot, 'dist'), 'public/wasm/libav', { recursive: true })Electron 生产环境需把 base 配成实际静态资源协议地址。加载器 base / wasmurl / toImport 的细节见上游 libav.js 文档。运行时由调用方负责关闭与取消,不保证每台设备实时解码。
来源与许可证
manifest.json 记录源码、构建参数及产物 SHA-256。sources/ 提供本 fork 对应源码、FFmpeg 源码和 emfiberthreads 源码。保留所有许可证头及第三方声明。修改并再分发时继续提供对应源码与重建材料;HEVC 专利许可与开源许可证是独立问题。
0.1.1 内存与线程预算
初始线性内存 24 MiB,增长上限 768 MiB。线程版固定预创建 5 个 pthread Worker(包含调度线程),池耗尽时不额外扩池;推荐每个实例最多配置 4 个解码线程。预算按实例计算,不是整个播放器的总内存限制。
在专用 Worker 中使用 noworker: true,可同步调用 av.libavjsMemoryStats?.(),返回 linearMemoryBytes、activePthreads、idlePthreads。线程数包含运行时调度线程,线性内存不等于进程 RSS。默认代理 Worker 模式不提供这个同步接口。超过内存预算可能分配失败,由调用方结束当前解码并提示;释放不会承诺立刻归还 RSS。
