@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) => voidvideoExportUrl 应传入绝对且带尾斜杠的接口地址。不要使用 /api/editor/video/ 这类相对地址,否则请求会发送到当前应用自身。
如果需要接入自定义鉴权或上传网关,可以传入 client 覆盖默认请求行为。
