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

@bylqwjc/media-editor-video

v1.0.46

Published

媒体编辑器框架无关视频运行时:内部打包 React + 完整视频编辑富 UI(时间轴/裁剪/标注/贴纸/滤镜/封面),暴露 mountVideoEditor(el, opts);消费方无需自带 React

Readme

@media-editor/video

框架无关视频编辑器运行时。内部封装 React 和完整视频编辑 UI,支持时间轴、剪辑、裁剪、调色、滤镜、标注、贴纸、比例、封面和导出。

安装

pnpm add @media-editor/video @media-editor/styles

视频导出需要后端接口,通常配合 @media-editor/server。

使用

import { mountVideoEditor } from '@media-editor/video';
import '@media-editor/styles/theme.css';

const handle = mountVideoEditor(el, {
  source: videoFile,
  videoExportUrl: 'https://www.socialecho.net/api/editor/video/',
  locale: 'zh',
  theme: 'dark',
  // 自定义“导出至”说明;传 false 或空字符串可隐藏该字段
  exportDestination: '保存到项目素材库',
  onExported: async (blob, filename) => {
    await saveVideoToYourApp(blob, filename);
  },
  onError: console.error,
});

handle.update({ locale: 'en' });
handle.destroy();

locale 支持 zh、en、es 和 zh-Hant。

exportDestination 支持自定义导出位置说明;传 false 或空字符串会隐藏整行“导出至”。

source 可以传 File 或远程 URL 对象。远程视频会先按 metadata 加载,浏览器在播放和拖动时会自行发起 HTTP Range 请求,不会因为文件很大而预先下载整段视频;网络暂时无响应时会自动重试,失败后仍保留 URL 并可再次重试。

远程 URL 的源站/CDN 需要满足:允许页面跨域访问(Access-Control-Allow-Origin)、支持字节范围请求(Accept-Ranges: bytes,通常返回 206),并返回正确的 Content-Type。MP4 建议将 moov 索引移到文件开头(fast start),否则首次读取元数据可能需要等待完整文件。若源站不支持 CORS/Range,优先改用 CDN 或由业务侧下载成 File 后传入;前端不手工拼接视频分片,因为这会破坏容器索引和随机 seek。

父组件传入字幕

父组件可以直接传入带时间戳的文本数组。编辑器会把每一项转换成现有的文字 overlay,并显示在对应的时间轴区间;不解析 SRT/ASS、不做 OCR,也不负责烧录字幕。

const handle = mountVideoEditor(el, {
  source: videoFile,
  subtitles: [
    { id: 's1', text: '第一句字幕', startAt: 0, endAt: 2.5 },
    { id: 's2', text: '第二句字幕', startAt: 2.5, endAt: 5.8 },
  ],
});

时间单位是秒,id 用于去重和父组件更新时同步。可选的 style 支持 fontSize、color、backgroundColor、position(top/center/bottom)、align、fontFamily、fontWeight、fontStyle(normal/italic)、italic、lineHeight、width、paddingX 和 paddingY。fontStyle 和 italic 都可以表示斜体,优先使用显式传入的 italic。

字幕文本支持使用 \n 换行,字体大小单位为输出画布像素,fontWeight 可以传 '400'、'600'、'700' 或数字 400、600、700。

subtitles: [
  {
    id: 's1',
    text: '第一行字幕\n第二行字幕',
    startAt: 0,
    endAt: 2.5,
    style: {
      fontSize: 42,
      fontWeight: 700,
      fontFamily: 'Microsoft YaHei',
      fontStyle: 'italic',
      lineHeight: 1.2,
      color: '#ffffff',
      position: 'bottom',
      align: 'center',
    },
  },
]

父组件打开封面弹窗并上传

原生运行时可以通过句柄打开封面弹窗。用户点击“设为封面”或上传封面后,onPosterSaved 会收到可直接提交到业务接口的 Blob、文件名和输出时间。

const handle = mountVideoEditor(el, {
  source: videoFile,
  onPosterSaved: async (blob, name, time) => {
    await uploadCover(blob, name, time);
  },
});

coverButton.onclick = () => handle.openPosterPicker();

也可以传 openPosterPicker: true 让父组件通过参数调起;React 的 <VideoEditor> 支持 ref.current.openPosterPicker(),Vue 的 <VideoEditor> 支持模板 ref 暴露的 openPosterPicker()。Vue 组件通过 poster-saved 事件返回同样的三个参数。

Lazy

import { mountVideoEditorLazy, preloadVideoEditor } from '@media-editor/video/lazy';

preloadVideoEditor();
await mountVideoEditorLazy(el, options);

导出回调

导出过程中编辑器会显示 loading。导出成功后触发:

onExported: (blob: Blob, filename: string) => void

videoExportUrl 应传入绝对且带尾斜杠的接口地址。不要使用 /api/editor/video/ 这类相对地址,否则请求会发送到当前应用自身。

如果需要接入自定义鉴权或上传网关,可以传入 client 覆盖默认请求行为。