daily-video-editor 0.0.4 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,138 +1,138 @@
1
- # video-clips
2
-
3
- 视频合成编辑器。打包后宿主只需 Vue,不必再装 Pinia、全局 Element Plus 或 Tailwind。
4
-
5
- ## 接入
6
-
7
- ```ts
8
- import { createApp, ref } from "vue";
9
- import {
10
- createDefaultVideoComposeEditorModel,
11
- VideoComposeEditor,
12
- type VideoComposeEditorExpose,
13
- type VideoComposeEditorModel,
14
- } from "video-clips";
15
- import "video-clips/style.css";
16
-
17
- const model = ref<VideoComposeEditorModel>(
18
- createDefaultVideoComposeEditorModel({
19
- bizType: "source_video",
20
- bizId: "local",
21
- }),
22
- );
23
- const editorRef = ref<VideoComposeEditorExpose | null>(null);
24
-
25
- createApp(App).mount("#app");
26
- ```
27
-
28
- ```vue
29
- <VideoComposeEditor ref="editorRef" v-model="model" />
30
- ```
31
-
32
- `peerDependencies` 只有 `vue`。`pinia`、`element-plus` 随包安装,并在编辑器内部使用:每个时间轴自建一份 Pinia,同页多个编辑器不会抢轨。
33
-
34
- 换稿必须调用 `editorRef.reload(model)`。只改 `v-model` 引用不会回灌时间轴。
35
-
36
- ## 组件 Ref(`VideoComposeEditorExpose`)
37
-
38
- | 方法 | 说明 |
39
- | --- | --- |
40
- | `validate(): string \| null` | 导出前校验。`null` 表示通过,否则为错误文案 |
41
- | `flush(): void` | 立刻把当前轨道、喜欢态、缩放写入 `update:modelValue` |
42
- | `reload(model): Promise<void>` | 用指定工程整页重置时间轴。换稿只走这个方法 |
43
- | `exportComposePayload()` | 先 `flush`,再返回 `{ id, bizType, bizId, tracks }` |
44
- | `getMainVideoClips()` | 主轨视频片段。优先读时间轴,否则用派生列表 |
45
- | `requestUploadClip()` | 触发上传视频:有 `onRequestUploadClip` 则交给宿主,否则走内置上传 |
46
-
47
- ## 公共类型
48
-
49
- 声明在 `dist/index.d.ts`。包根导出:
50
-
51
- - 组件与工厂:`VideoComposeEditor`、`createDefaultVideoComposeEditorModel`
52
- - 工程:`VideoComposeEditorModel`、`ComposeExportPayload`、`ComposeTrack`、`ComposeClip`、`MediaBizType`、`MediaRef`、`ComposeSegmentClipAssets`
53
- - 侧栏种子:`BgmItem`、`TextTemplateItem`、`VideoClipItem`
54
- - 入参与上传:`ComposeEditorProps`、`ComposeUploadAdapter`、`ComposeBgmUploadResult`、`ComposeCatalogUploadPayload`
55
- - Ref:`VideoComposeEditorExpose`
56
- - 轨道片段:`MediaClip`、`SubtitleClip`、`TextClip`、`TrackType`
57
- - 媒体地址:`createComposeMediaResolver`、`isPassthroughMediaUrl`、`mediaCorsMessage`、`ComposeMediaResolver`、`ResolveMediaUrl`
58
-
59
- 字段含义以声明文件为准。
60
-
61
- ## 发包
62
-
63
- `package.json` 保持 `"private": true`。本包默认不发到公共 npm。
64
-
65
- 安装方式:monorepo workspace、`file:` 依赖,或私有 registry。类型入口是 `dist/index.d.ts`(`files` 含整个 `dist`)。要公开发到 npm 时,须先去掉 `private`,再按公开发布流程处理,不走上述私有安装约定。
66
-
67
- 构建:
68
-
69
- ```bash
70
- npm run build
71
- ```
72
-
73
- 库产物:
74
-
75
- - `dist/index.js`
76
- - `dist/index.d.ts`
77
- - `dist/style.css`
78
- - `dist/algorithm/`
79
-
80
- ## 产物部署
81
-
82
- 宿主必须引入样式,否则编辑器没有皮肤:
83
-
84
- ```ts
85
- import "video-clips/style.css";
86
- ```
87
-
88
- 美颜预览 Worker 在 `npm run build` 时内联进 `dist/index.js`。不要单独部署 worker 文件,也不要再准备 `/assets/beautyPreview.worker-*.js`。
89
-
90
- `dist/algorithm/` 仍须挂到宿主静态目录。默认从站点根路径 `/algorithm/` 读取:
91
-
92
- - `/algorithm/face_landmarker.task`
93
- - `/algorithm/mediapipe/`
94
-
95
- 本地 demo 使用 `public/algorithm/`。库构建只拷贝这两项到 `dist/algorithm/`。挂好后可用 `algorithmBaseUrl` 改根路径(须是目录,并能拼出上述两个相对路径)。
96
-
97
- ## 侧栏素材(不进工程 JSON)
98
-
99
- 视频 / 音频 / 音效 / 花字列表由 **Editor 内部数组**维护,**不写入** `v-model`(`model` 只有 tracks、likedMedia、scale 等)。
100
-
101
- 可用 props 作种子;上传成功事件载荷为:
102
-
103
- ```ts
104
- { file: File; item: T; items: T[] }
105
- ```
106
-
107
- 宿主可把 `items` 回写到自己的状态。纯 `onRequestUpload*` 由宿主自管 UX,不走该 emit。
108
-
109
- ## 跨域媒体
110
-
111
- 预览、缩略图和美颜抽帧都要能读取像素。编辑器会:
112
-
113
- - 给 `video` / `audio` 设置 `crossorigin="anonymous"`
114
- - 对跨域地址默认 `fetch`(`mode: "cors"`)并转成 `blob:`
115
- - 同源、`blob:`、`data:` 原样使用
116
-
117
- 源站需要:
118
-
119
- ```
120
- Access-Control-Allow-Origin: <页面源> 或 *
121
- Access-Control-Allow-Methods: GET
122
- ```
123
-
124
- 没有 CORS 头时,默认 fetch 会失败,界面提示配置 `resolveMediaUrl`。宿主把地址换成同源代理或 blob:
125
-
126
- ```ts
127
- async function proxyToBlob(url: string): Promise<string> {
128
- const response = await fetch(`/api/media-proxy?url=${encodeURIComponent(url)}`);
129
- if (!response.ok) throw new Error("媒体代理失败");
130
- return URL.createObjectURL(await response.blob());
131
- }
132
- ```
133
-
134
- ```vue
135
- <VideoComposeEditor v-model="model" :resolve-media-url="proxyToBlob" />
136
- ```
137
-
138
- 本仓库不实现代理服务。
1
+ # daily-video-clips
2
+
3
+ 视频合成编辑器。打包后宿主只需 Vue,不必再装 Pinia、全局 Element Plus 或 Tailwind。
4
+
5
+ ## 接入
6
+
7
+ ```ts
8
+ import { createApp, ref } from "vue";
9
+ import {
10
+ createDefaultVideoComposeEditorModel,
11
+ VideoComposeEditor,
12
+ type VideoComposeEditorExpose,
13
+ type VideoComposeEditorModel,
14
+ } from "video-clips";
15
+ import "video-clips/style.css";
16
+
17
+ const model = ref<VideoComposeEditorModel>(
18
+ createDefaultVideoComposeEditorModel({
19
+ bizType: "source_video",
20
+ bizId: "local",
21
+ }),
22
+ );
23
+ const editorRef = ref<VideoComposeEditorExpose | null>(null);
24
+
25
+ createApp(App).mount("#app");
26
+ ```
27
+
28
+ ```vue
29
+ <VideoComposeEditor ref="editorRef" v-model="model" />
30
+ ```
31
+
32
+ `peerDependencies` 只有 `vue`。`pinia`、`element-plus` 随包安装,并在编辑器内部使用:每个时间轴自建一份 Pinia,同页多个编辑器不会抢轨。
33
+
34
+ 换稿必须调用 `editorRef.reload(model)`。只改 `v-model` 引用不会回灌时间轴。
35
+
36
+ ## 组件 Ref(`VideoComposeEditorExpose`)
37
+
38
+ | 方法 | 说明 |
39
+ | --- | --- |
40
+ | `validate(): string \| null` | 导出前校验。`null` 表示通过,否则为错误文案 |
41
+ | `flush(): void` | 立刻把当前轨道、喜欢态、缩放写入 `update:modelValue` |
42
+ | `reload(model): Promise<void>` | 用指定工程整页重置时间轴。换稿只走这个方法 |
43
+ | `exportComposePayload()` | 先 `flush`,再返回 `{ id, bizType, bizId, tracks }` |
44
+ | `getMainVideoClips()` | 主轨视频片段。优先读时间轴,否则用派生列表 |
45
+ | `requestUploadClip()` | 触发上传视频:有 `onRequestUploadClip` 则交给宿主,否则走内置上传 |
46
+
47
+ ## 公共类型
48
+
49
+ 声明在 `dist/index.d.ts`。包根导出:
50
+
51
+ - 组件与工厂:`VideoComposeEditor`、`createDefaultVideoComposeEditorModel`
52
+ - 工程:`VideoComposeEditorModel`、`ComposeExportPayload`、`ComposeTrack`、`ComposeClip`、`MediaBizType`、`MediaRef`、`ComposeSegmentClipAssets`
53
+ - 侧栏种子:`BgmItem`、`TextTemplateItem`、`VideoClipItem`
54
+ - 入参与上传:`ComposeEditorProps`、`ComposeUploadAdapter`、`ComposeBgmUploadResult`、`ComposeCatalogUploadPayload`
55
+ - Ref:`VideoComposeEditorExpose`
56
+ - 轨道片段:`MediaClip`、`SubtitleClip`、`TextClip`、`TrackType`
57
+ - 媒体地址:`createComposeMediaResolver`、`isPassthroughMediaUrl`、`mediaCorsMessage`、`ComposeMediaResolver`、`ResolveMediaUrl`
58
+
59
+ 字段含义以声明文件为准。
60
+
61
+ ## 发包
62
+
63
+ `package.json` 保持 `"private": true`。本包默认不发到公共 npm。
64
+
65
+ 安装方式:monorepo workspace、`file:` 依赖,或私有 registry。类型入口是 `dist/index.d.ts`(`files` 含整个 `dist`)。要公开发到 npm 时,须先去掉 `private`,再按公开发布流程处理,不走上述私有安装约定。
66
+
67
+ 构建:
68
+
69
+ ```bash
70
+ npm run build
71
+ ```
72
+
73
+ 库产物:
74
+
75
+ - `dist/index.js`
76
+ - `dist/index.d.ts`
77
+ - `dist/style.css`
78
+ - `dist/algorithm/`
79
+
80
+ ## 产物部署
81
+
82
+ 宿主必须引入样式,否则编辑器没有皮肤:
83
+
84
+ ```ts
85
+ import "video-clips/style.css";
86
+ ```
87
+
88
+ 美颜预览 Worker 在 `npm run build` 时内联进 `dist/index.js`。不要单独部署 worker 文件,也不要再准备 `/assets/beautyPreview.worker-*.js`。
89
+
90
+ `dist/algorithm/` 仍须挂到宿主静态目录。默认从站点根路径 `/algorithm/` 读取:
91
+
92
+ - `/algorithm/face_landmarker.task`
93
+ - `/algorithm/mediapipe/`
94
+
95
+ 本地 demo 使用 `public/algorithm/`。库构建只拷贝这两项到 `dist/algorithm/`。挂好后可用 `algorithmBaseUrl` 改根路径(须是目录,并能拼出上述两个相对路径)。
96
+
97
+ ## 侧栏素材(不进工程 JSON)
98
+
99
+ 视频 / 音频 / 音效 / 花字列表由 **Editor 内部数组**维护,**不写入** `v-model`(`model` 只有 tracks、likedMedia、scale 等)。
100
+
101
+ 可用 props 作种子;上传成功事件载荷为:
102
+
103
+ ```ts
104
+ { file: File; item: T; items: T[] }
105
+ ```
106
+
107
+ 宿主可把 `items` 回写到自己的状态。纯 `onRequestUpload*` 由宿主自管 UX,不走该 emit。
108
+
109
+ ## 跨域媒体
110
+
111
+ 预览、缩略图和美颜抽帧都要能读取像素。编辑器会:
112
+
113
+ - 给 `video` / `audio` 设置 `crossorigin="anonymous"`
114
+ - 对跨域地址默认 `fetch`(`mode: "cors"`)并转成 `blob:`
115
+ - 同源、`blob:`、`data:` 原样使用
116
+
117
+ 源站需要:
118
+
119
+ ```
120
+ Access-Control-Allow-Origin: <页面源> 或 *
121
+ Access-Control-Allow-Methods: GET
122
+ ```
123
+
124
+ 没有 CORS 头时,默认 fetch 会失败,界面提示配置 `resolveMediaUrl`。宿主把地址换成同源代理或 blob:
125
+
126
+ ```ts
127
+ async function proxyToBlob(url: string): Promise<string> {
128
+ const response = await fetch(`/api/media-proxy?url=${encodeURIComponent(url)}`);
129
+ if (!response.ok) throw new Error("媒体代理失败");
130
+ return URL.createObjectURL(await response.blob());
131
+ }
132
+ ```
133
+
134
+ ```vue
135
+ <VideoComposeEditor v-model="model" :resolve-media-url="proxyToBlob" />
136
+ ```
137
+
138
+ 本仓库不实现代理服务。
@@ -0,0 +1,2 @@
1
+ declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
2
+ export default _default;
@@ -1,6 +1,6 @@
1
1
  import { Component, FunctionalComponent } from 'vue';
2
2
  export interface CustomButton {
3
- type: 'custom';
3
+ type: "custom";
4
4
  key: string;
5
5
  }
6
6
  export interface OperationButtonConfig {
@@ -19,7 +19,7 @@ export interface OperationButtonConfig {
19
19
  /** 自定义CSS类名 */
20
20
  className?: string;
21
21
  }
22
- export type OperationButton = 'reset' | 'undo' | 'redo' | 'split' | 'delete' | CustomButton | OperationButtonConfig;
22
+ export type OperationButton = "reset" | "undo" | "redo" | "split" | "trimLeft" | "trimRight" | "delete" | CustomButton | OperationButtonConfig;
23
23
  export interface ScaleConfigButtonConfig {
24
24
  /** 按钮标识 */
25
25
  key: string;
@@ -36,7 +36,14 @@ export interface ScaleConfigButtonConfig {
36
36
  /** 自定义CSS类名 */
37
37
  className?: string;
38
38
  }
39
- export type ScaleConfigButton = 'snap' | CustomButton | ScaleConfigButtonConfig;
39
+ export type ScaleConfigButton = "snap" | CustomButton | ScaleConfigButtonConfig;
40
+ /**
41
+ * {
42
+ video: { max: 5 },
43
+ audio: { max: 3 },
44
+ subtitle: { max: 2 },
45
+ }
46
+ */
40
47
  export interface TrackTypeConfig {
41
48
  [key: string]: {
42
49
  max: number;
@@ -82,7 +89,7 @@ export interface TrackContextMenuConfig {
82
89
  enabled?: boolean;
83
90
  }
84
91
  export interface ClipContextMenuConfig {
85
- commonItems?: Array<'copy' | 'cut' | 'delete' | ContextMenuItem>;
92
+ commonItems?: Array<"copy" | "cut" | "delete" | ContextMenuItem>;
86
93
  showCommonItems?: boolean;
87
94
  byType?: {
88
95
  [clipType: string]: ContextMenuItem[];
@@ -131,6 +138,9 @@ export interface LocaleConfig {
131
138
  reset?: string;
132
139
  undo?: string;
133
140
  redo?: string;
141
+ split?: string;
142
+ trimLeft?: string;
143
+ trimRight?: string;
134
144
  delete?: string;
135
145
  play?: string;
136
146
  pause?: string;
@@ -32,13 +32,13 @@ export declare function parseSvgAspect(raw: string): number;
32
32
  export declare function getCachedTextTemplateSvg(sourceUrl: string): string;
33
33
  /** 按本地缓存读取模板 SVG,不发网络请求 */
34
34
  export declare function loadTextTemplateSvg(sourceUrl: string): Promise<string>;
35
- /** 解析 SVG 并写入原文缓存,供拖入贴图轨 / 宿主 mock 组装 */
35
+ /** 解析 SVG 并写入原文缓存,供拖入贴图轨 / 宿主组装 */
36
36
  export declare function createTextTemplateItem(id: string, name: string, raw: string, url: string): TextTemplateItem;
37
37
  /** 从本地 SVG 构建花字项(不写入会话目录,供宿主 props 维护) */
38
38
  export declare function createTextTemplateFromFile(file: File): Promise<TextTemplateItem>;
39
39
  /** 把本地 SVG 追加进当前会话的花字列表。刷新页面后消失 */
40
40
  export declare function appendUploadedTextTemplate(file: File): Promise<TextTemplateItem>;
41
- /** 返回当前会话花字目录(不再自动灌 mock;mock 由宿主经 props.textTemplates 传入) */
41
+ /** 返回当前会话花字目录(宿主经 props.textTemplates 注入) */
42
42
  export declare function loadTextTemplateCatalog(): Promise<TextTemplateItem[]>;
43
43
  /** 同步宿主花字进查找缓存,供拖入贴图轨 / 预览按 id 解析 */
44
44
  export declare function setHostTextTemplates(items: TextTemplateItem[] | undefined): void;