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

react-video-capture-lib

v0.0.2

Published

A React library for video capture and preview

Downloads

170

Readme

react-video-capture

用于在线视频关键帧提取与预览进度条展示的 React 组件库。

当前项目包含两部分能力:

  • utils:从远程 .mp4 URL 渐进式提取预览帧,或按指定 time / percent 获取单帧。
  • VideoCapture:一个可控/非可控的预览进度条组件,内置底部多帧预览、悬浮预览、拖拽选中与原图回传。

安装

pnpm add react-video-capture

要求:

  • react >= 18
  • react-dom >= 18

快速开始

import { useState } from "react";
import { VideoCapture } from "react-video-capture";
import "react-video-capture/lib/styles.css";

export function Demo() {
  const [percent, setPercent] = useState(0);
  const [frame, setFrame] = useState<Blob | null>(null);

  return (
    <VideoCapture
      src="https://example.com/demo.mp4"
      mode="percent"
      value={percent}
      onChange={(nextPercent, nextFrame) => {
        setPercent(nextPercent);
        setFrame(nextFrame);
      }}
    />
  );
}

导出

export {
  VideoCapture,
  createVideoCapture,
  captureVideoFrames,
  // 以及对应的类型导出
}

当前包根已同时导出组件和 utils,完整导出见 src/index.ts

工具能力

createVideoCapture

创建一个可复用的视频预览提取器。

适用场景:

  • 首次加载时根据已缓冲进度,逐步产出多张底部预览图
  • 鼠标悬浮到任意位置时请求单张预览图
  • 拖拽/点击选中后获取对应帧
import { createVideoCapture } from "react-video-capture";

const captureSession = await createVideoCapture(videoUrl, {
  maxWidth: 352,
  maxHeight: 264,
  quality: 0.72,
  cacheTimeStep: 100,
});

参数

CreateVideoCaptureOptions

| 参数 | 类型 | 说明 | | --- | --- | --- | | imageType | "image/jpeg" \| "image/png" \| "image/webp" | 输出图片格式 | | quality | number | 图片质量,范围 0 ~ 1 | | crossOrigin | "anonymous" \| "use-credentials" | 视频跨域模式 | | maxWidth | number | 预览尺寸最大宽度,等比缩小,不会放大 | | maxHeight | number | 预览尺寸最大高度,等比缩小,不会放大 | | cacheTimeStep | number | 预览近似缓存吸附步长,单位毫秒 |

元数据

const metadata = captureSession.getMetadata();

返回:

| 字段 | 说明 | | --- | --- | | durationTime | 视频总时长,单位毫秒 | | width | 预览输出宽度 | | height | 预览输出高度 | | sourceWidth | 视频原始宽度 | | sourceHeight | 视频原始高度 |

captureFrames

根据当前已加载到本地的缓冲区,渐进式产出多张预览图。

支持两种策略。 当前统一使用 VideoCaptureStrategy 语义:

  • 固定时间间隔:interval
  • 固定分段数量:segments
const result = await captureSession.captureFrames({
  strategy: {
    type: "segments",
    count: 10,
  },
  onFrame(frame) {
    console.log("new frame", frame);
  },
  onProgress(progress) {
    console.log(progress.bufferedRanges);
  },
});

行为说明

  • 只会消费“已经缓冲到本地”的片段。
  • 如果某些目标位置还没加载到,本轮不会强制继续拉取视频。
  • 当浏览器判断缓冲基本停止增长后,会结束本轮提取,并通过 missingSlots 返回未命中的位置。

CaptureFramesOptions

| 参数 | 类型 | 说明 | | --- | --- | --- | | strategy | VideoCaptureStrategy | 预览图生成策略 | | startTime | number | 起始时间,毫秒 | | endTime | number | 结束时间,毫秒 | | onFrame | (frame) => void | 每抓到一帧时回调 | | onProgress | (progress) => void | 进度变化时回调 | | signal | AbortSignal | 中止任务 |

CapturedFrame

| 字段 | 说明 | | --- | --- | | slotIndex | 当前帧对应的槽位索引 | | requestedTime | 请求时间,毫秒 | | actualTime | 实际截取时间,毫秒 | | percent | 对应视频进度百分比 | | blob | 图片二进制数据 |

captureFrameAt

获取指定时间点的一帧。

支持两种输入:

  • { time }
  • { percent }
const frameByTime = await captureSession.captureFrameAt(
  { time: 5_000 },
  { cacheMode: "exact", outputSize: "preview" },
);

const frameByPercent = await captureSession.captureFrameAt(
  { percent: 50 },
  { cacheMode: "exact", outputSize: "source" },
);

行为说明

  • 如果指定位置尚未缓冲到本地,直接返回 null
  • outputSize: "preview" 返回缩略图尺寸
  • outputSize: "source" 返回视频原始尺寸
  • cacheMode: "approximate" 会按 cacheTimeStep 吸附时间,用于减少高频 seek
  • cacheMode: "exact" 一定按目标时间请求

CaptureFrameAtOptions

| 参数 | 类型 | 说明 | | --- | --- | --- | | cacheMode | "approximate" \| "exact" | 近似缓存或精确时间 | | outputSize | "preview" \| "source" | 返回预览尺寸或原始尺寸 | | signal | AbortSignal | 中止本次获取 |

captureVideoFrames

一次性抽取多张分段帧的便捷方法。

import { captureVideoFrames } from "react-video-capture";

const result = await captureVideoFrames(videoUrl, {
  count: 8,
});

说明:

  • 内部使用 segments
  • 要求目标帧已经全部缓冲完成
  • 如果仍有未加载位置,会直接抛错
  • 更适合“视频本地可快速加载完成”的简单场景

VideoCapture 组件

用于展示视频底部预览进度条。

能力:

  • 默认外层 block
  • 类似 iOS 视频预览的底部轨道样式
  • 支持拖动、点击、悬浮预览
  • 支持受控 / 非受控
  • mode="time" 时,valueonChange 使用毫秒
  • mode="percent" 时,valueonChange 使用百分比
  • onChange 返回的 frame 为原始尺寸 Blob
import { useState } from "react";
import { VideoCapture } from "react-video-capture";

export function TimeModeDemo() {
  const [time, setTime] = useState(0);
  const [frame, setFrame] = useState<Blob | null>(null);

  return (
    <VideoCapture
      src="https://example.com/demo.mp4"
      mode="time"
      value={time}
      onChange={(nextTime, nextFrame) => {
        setTime(nextTime);
        setFrame(nextFrame);
      }}
      captureStrategy={{ type: "segments", count: 10 }}
    />
  );
}

Props

| 参数 | 类型 | 说明 | | --- | --- | --- | | src | string | 视频 URL | | mode | "time" \| "percent" | 值模式 | | value | number | 受控值 | | defaultValue | number | 非受控初始值 | | onChange | (value, frame) => void | 值变化回调,frame 为原始尺寸 Blob \| null | | captureStrategy | VideoCaptureStrategy | 底部预览图生成策略 | | captureOptions | CreateVideoCaptureOptions | 提取器配置 | | disabled | boolean | 是否禁用 |

继承原生 div 属性。

交互说明

  • 初次加载时,组件会根据 captureStrategy 渐进式填充底部预览图
  • hover 时会先显示最近邻预加载图,再异步补精确预览
  • hover 精确图请求带短延迟,并且鼠标移走后会被中止
  • drag 时会更新位置值,并在短延迟后请求选中帧
  • 选中帧请求与 hover 预览分开缓存
  • onChange 会先回调最新 valuenull,等原始帧完成后再回调一次真实 Blob

受控与非受控

受控:

<VideoCapture
  src={videoUrl}
  mode="percent"
  value={percent}
  onChange={(nextPercent) => setPercent(nextPercent)}
/>

非受控:

<VideoCapture
  src={videoUrl}
  mode="percent"
  defaultValue={0}
  onChange={(nextPercent, frame) => {
    console.log(nextPercent, frame);
  }}
/>

性能设计

当前实现做了这些优化:

  • 预加载缩略图与选中原图分开缓存
  • hoverselected 使用独立任务通道
  • 所有 seek / drawImage / toBlob 串行执行,避免同一 video/canvas 被并发污染
  • approximate 模式通过 cacheTimeStep 吸附时间,减少相近点频繁截图
  • hover 优先显示最近邻预加载图,降低首次等待感

限制说明

  • 依赖浏览器 HTMLVideoElementcanvasbuffered 能力,不支持 SSR 直接执行
  • 远程视频必须满足可播放与正确的 CORS 配置,否则无法截图
  • 如果目标时间点尚未缓冲,captureFrameAt 会返回 null
  • 目前工具层只处理截图提取,不包含你业务侧的视频播放器联动逻辑

本地开发

pnpm install
pnpm dev

库构建:

pnpm build

Playground 构建:

pnpm build:web

Lint:

pnpm lint

目录结构

.
├── src/
│   ├── components/        # VideoCapture 组件
│   ├── utils/             # 视频帧提取工具
│   ├── index.ts           # 对外导出
│   └── styles.less
├── example/               # 本地示例
├── public/                # 示例静态资源
└── README.md

License

MIT