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

@mario9/wasm-player

v0.1.2

Published

基于 Vue 3 + mediabunny 的媒体播放器,支持 H.264、H.265/HEVC 视频和 MP3 音频

Readme

@mario9/wasm-player

基于 Vue 3 + TypeScript + mediabunny 的媒体播放器,支持 H.264、H.265/HEVC 视频和 MP3 等音频格式。

特性

  • H.264 视频原生播放(<video> 标签)
  • H.265/HEVC 视频通过 mediabunny CanvasSink 直接解码渲染到 Canvas(无需转码,无 MSE 复杂度)
  • MP3 等音频格式原生播放,独立音频播放器 UI
  • 用 mediabunny Input 在主线程直接 probe,识别 MP4 容器内的编解码器(h264 vs h265),无需 Worker 往返
  • 智能预取与 LRU 缓存,自动处理 B-frame 排序和 RASL 帧跳过
  • URL 入口做协议白名单(http/https/blob/data)
  • 按格式分层的架构,易于扩展新格式

技术栈

  • Vue 3 — 前端框架
  • Vite — 构建工具
  • TypeScript — 类型安全
  • mediabunny — 纯 TypeScript 媒体处理库(MP4 demux + WebCodecs 解码管线)
  • WebCodecs API — 浏览器原生硬件加速编解码

安装

npm install @mario9/wasm-player

快速开始

<template>
  <WasmPlayer src="/videos/demo.mp4" :width="800" :height="450" />
  <WasmPlayer src="/audio/track.mp3" />
</template>

<script setup>
import { WasmPlayer } from '@mario9/wasm-player'
import '@mario9/wasm-player/dist/player.css'
</script>

注意: 消费者项目需配置服务端 COOP/COEP 头,详见服务端配置

使用组件

推荐直接使用 WasmPlayer,它会自动识别格式并路由到对应播放器:

<!-- 视频(自动识别 H.264 / H.265) -->
<WasmPlayer src="/videos/demo.mp4" :width="800" :height="450" />

<!-- 音频 -->
<WasmPlayer src="/audio/track.mp3" />

也可以直接使用底层组件:

<VideoPlayer src="/videos/h264.mp4" />
<StreamingPlayer src="/videos/h265.mp4" />
<AudioPlayer src="/audio/track.mp3" />

WasmPlayer Props

| Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | src | string | 必填 | 媒体 URL(支持 http/https/blob/data) | | autoplay | boolean | false | 自动播放 | | width | number | 800 | 宽度(px) | | height | number | 450 | 高度(px,仅视频) | | poster | string | — | 封面图 URL(仅视频) |

VideoPlayer / StreamingPlayer Props

| Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | src | string | 必填 | 视频 URL | | autoplay | boolean | false | 自动播放 | | width | number | 800 | 宽度(px) | | height | number | 450 | 高度(px) | | poster | string | — | 封面图 URL |

AudioPlayer Props

| Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | src | string | 必填 | 音频 URL | | autoplay | boolean | false | 自动播放 |

工作原理

WasmPlayer.vue(智能路由)
  → detectMediaType()        扩展名快判(音频直接路由)
  → probeMediaBySrc()        mediabunny Input 主线程 probe
  → resolveCodecPlayback()   按 codec feature 决策
      h264  → VideoPlayer.vue(<video> 原生播放)
      h265  → StreamingPlayer.vue(Canvas 渲染)
      audio → AudioPlayer.vue(<audio> 原生播放)

H.265/HEVC 播放流程

StreamingPlayer.vue
  ↓ useMediabunnyPlayer
  ↓ Input + UrlSource(获取视频轨道)
  ↓ CanvasSink(poolSize: 2, fit: 'contain')
  ↓ for await (const { canvas, timestamp } of videoSink.canvases())
  ↓ RAF 循环:检查 nextFrame.timestamp <= currentTime,绘制到 Canvas
<canvas> 渲染

音频通过 extractAudioToNative 将编码包重封装为 ADTS 容器,生成 blob URL 挂载到原生 <audio> 元素,以 audioRef.currentTime 作为视频帧渲染的时钟源,保证音视频同步。

扩展新格式

src/shared/index.tsresolveCodecPlayback 中添加分支:

if (result.videoCodec === 'vp9') {
  return { routeTarget: 'video', mode: 'native', reason: 'vp9 native' }
}

性能说明

  • probe 无 Worker 往返:mediabunny Input 直接在主线程解析 MP4 元数据
  • 无 WASM 开销:mediabunny 是纯 TypeScript,WebCodecs 使用浏览器原生硬件加速编解码
  • 智能预取:mediabunny 内置网络优化预取策略和 LRU 缓存
  • Canvas 池复用:零拷贝,减少内存分配
  • 解码在独立线程:WebCodecs 的 VideoDecoder 在浏览器独立线程运行,不阻塞主线程

浏览器兼容性

WebCodecs API 要求:

| 浏览器 | 最低版本 | |--------|---------| | Chrome / Edge | 94+ | | Safari | 16.4+ | | Firefox | 不支持 H.264/HEVC(WebCodecs 部分实现) |

本地开发

npm install
npm run dev        # 开发服务器 http://localhost:5173
npm run build      # 类型检查 + 生产构建
npm run build:lib  # 构建 npm 包到 dist/
npm run test       # 运行 vitest 单元测试
npm run lint       # ESLint 检查
npm run format     # Prettier 格式化 src/

测试

npm run test

覆盖范围:src/shared/ 的决策函数与兜底逻辑。mediabunny 解码能力只能在真实浏览器中回归,建议搭配 Playwright 做冒烟测试。

服务端配置

本库依赖 SharedArrayBuffer(通过 mediabunny),浏览器要求页面处于 cross-origin isolated 环境。消费者项目需配置以下响应头:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Vite 开发服务器配置示例:

// vite.config.ts
export default defineConfig({
  server: {
    headers: {
      'Cross-Origin-Opener-Policy': 'same-origin',
      'Cross-Origin-Embedder-Policy': 'require-corp',
    },
  },
})

Nginx 配置示例:

add_header Cross-Origin-Opener-Policy "same-origin";
add_header Cross-Origin-Embedder-Policy "require-corp";

许可证

MIT