@volcengine/amk-editor 0.0.1-beta.4 → 0.0.2-beta.0

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,139 +1,62 @@
1
1
  # @volcengine/amk-editor
2
-
3
- AMK 场景官方接入包:发布构建会内联底层编辑器运行时 UMD 与样式。公网业务方/demo **只需安装本包**,无需安装或访问内部编辑器包。弹层挂载使用 React 18/19 的 `createRoot`(兼容 React 19,不再使用已弃用的 `ReactDOM.render`)。
4
-
5
- ## License
6
-
7
- AMK Editor SDK 是火山引擎 AI MediaKit 的商业配套软件。使用本 SDK 需要获得有效的火山引擎商业授权,具体条款参见 [LICENSE](./LICENSE)。商业授权咨询请联系 `service@volcengine.com`。
8
-
9
- SDK 使用的第三方开源组件仍分别适用其各自的许可证,第三方许可证不因本商业许可证而被替代。
10
-
2
+ 火山引擎 AI MediaKit 官方 Web 视频编辑器 SDK。
3
+ ## 安装
4
+ ```bash
5
+ npm install @volcengine/amk-editor
6
+ ```
7
+ 需要 React 18 19。使用本 SDK 须获得有效的火山引擎商业授权,条款见 [LICENSE](./LICENSE)
8
+ 本 SDK 使用的第三方开源组件仍分别适用其各自的许可证。
9
+ ## 快速开始
11
10
  ```ts
12
11
  import { AmkEditor } from '@volcengine/amk-editor';
13
-
14
12
  const editor = new AmkEditor({
15
13
  container,
16
- projectId: 'xxx',
17
- endpoint: 'https://your-proxy.example.com',
18
- getLicenseUrl: 'https://license.example.com',
14
+ projectId: 'your-project-id',
15
+ endpoint: 'https://your-backend.example.com',
16
+ // 可选:自定义客户代理服务所需的请求头,SDK 不约定鉴权格式并会原样透传。
17
+ auth: {
18
+ getHeaders: async () => {
19
+ const response = await fetch('/api/session-token');
20
+ const { token } = await response.json();
21
+ return {
22
+ Authorization: `Bearer ${token}`,
23
+ 'X-Customer-Id': 'your-customer-id',
24
+ };
25
+ },
26
+ },
19
27
  material: {
20
- // 本地上传:入参 File[],返回 MaterialItem[];每项必须带 source_material_id,不必传 material_id
21
- onUploadMaterial: async files => [],
22
- // URL 上传:入参 string[](弹窗内逗号/换行分隔),返回契约同上
23
- onUploadUrlMaterial: async urls => [],
28
+ onUploadMaterial: async files => {
29
+ // 上传到业务存储后返回素材列表,每项必须带 source_material_id
30
+ return [];
31
+ },
32
+ onUploadUrlMaterial: async urls => {
33
+ return [];
34
+ },
24
35
  onRefreshPlayInfo: async materials =>
25
36
  materials.map(item => ({
26
37
  material_id: item.material_id, // 仅用于匹配,不要改写
27
- url: '...', // 业务方按自己字段映射
28
- // 以下 key 名只是推荐示例;使用自定义字段时读取自己的字段即可。
29
- poster: item.poster_storage_key ? 'https://signed-poster-url' : item.poster,
30
- sprite: item.sprite_storage_keys
31
- ? { ...item.sprite, storeurls: ['https://signed-sprite-url'] }
32
- : item.sprite,
38
+ url: '...',
39
+ poster: item.poster,
40
+ sprite: item.sprite,
33
41
  })),
34
- // 抽帧临时链转存成长效地址(可选);URL 和 key 会一起写回素材
35
- onPersistExtractUrls: async ({ kind, urls, material }) => {
36
- const result = await persistToBusinessStorage({ kind, urls, material });
37
- return {
38
- urls: result.urls,
39
- // SDK 会把 materialPatch 原样合并并写回素材;字段名由业务决定。
40
- materialPatch:
41
- kind === 'poster'
42
- ? { poster_storage_key: result.storageKeys[0] }
43
- : { sprite_storage_keys: result.storageKeys },
44
- };
45
- },
46
42
  },
47
43
  });
48
44
 
49
- // 两种上传返回素材后,SDK 统一:
50
- // 1. addSketchItems → 素材面板
51
- // 2. createAmkMaterials POST 远端仓库,并把服务端返回的 material_id 记到面板
52
- // 3. ensureMaterialExtractTasks → 缺/过期 poster/sprite 时抽帧;临时链上屏后可后台转存再 PUT
53
-
54
- // 转存完成后素材会保存:
55
- // - poster + poster_storage_key(推荐字段,可自定义)
56
- // - sprite.storeurls + sprite_storage_keys(推荐字段,可自定义)
57
- // 下一次 onRefreshPlayInfo 会收到这些 key,业务可据此重新生成有时效的访问 URL。
58
- // SDK 不读取上述两个 key,也不把它们当作固定 Schema。业务也可以返回:
59
- // materialPatch: {
60
- // biz_storage: { poster_key: '...', sprite_keys: ['...'] },
61
- // }
62
- // 只需在 onRefreshPlayInfo 中按同一套自定义结构读取即可。
63
-
64
- // 导出:invokeTool('vibe-editing-common', { edit_param, callback_args? })
65
- // 开启画质增强时附带 callback_args(JSON 字符串),供代理后续调增强:
66
- // - standard/professional → { tool:"enhance-video", tool_version, resolution, fps }
67
- // - large-model → { tool:"enhance-video-generative", resolution, fps }
68
- // SDK 不负责增强任务本身。
69
-
70
- // 工程会从 {endpoint}/api/v1/editing/projects/{projectId} 加载并自动保存。
71
- // 通用 MediaKit 工具仍通过 POST {endpoint}/api/v1/tools/{toolName} 调用。
72
- await editor.invokeTool({
73
- toolName: 'asr-subtitles',
74
- params: {
75
- input: {
76
- type: 'video',
77
- url: 'https://example.com/demo.mp4',
78
- },
79
- },
45
+ // 运行时替换鉴权逻辑,后续所有 AMK 请求立即使用新的 Header。
46
+ editor.setAuth({
47
+ getHeaders: () => ({ Authorization: 'Custom new-token' }),
80
48
  });
49
+ // 清除鉴权 Header。
50
+ editor.setAuth(null);
81
51
  ```
82
-
83
- ## 构建
84
-
85
- 先构建 SDK,再构建本包:
86
-
87
- ```bash
88
- pnpm build-veveditor
89
- pnpm --filter @volcengine/amk-editor run build
90
- ```
91
-
92
- 产物位于 `dist/index.js`(含 veveditor 运行时)与 `dist/veveditor.css`(样式 side-effect)。
93
-
94
- - `projectId` / `endpoint` 均为必传;鉴权密钥留在业务服务端,由 `endpoint` 代理注入
95
- - 发布包不声明底层编辑器为运行时依赖;底层编辑器和 `video-editor` 已在构建阶段内联到 `dist/index.js`,类型声明也不依赖内部包。
96
- - 发布前必须使用 `npm pack --dry-run` 检查 tarball;公网用户只需要能访问 npm 公网源和业务方提供的 `endpoint`。
97
-
98
- ## Editing API 对接
99
-
100
- 初始化时,AMK Editor 会组合以下接口:
101
-
102
- - `GET /api/v1/editing/projects/:project_id`
103
- - `GET /api/v1/editing/projects/:project_id/materials`
104
- - `GET /api/v1/editing/projects/:project_id/editor`
105
-
106
- 编辑过程中按资源分别写回:
107
-
108
- - 标题变更:`PATCH /projects/:project_id`
109
- - 素材变更:`PUT/DELETE /projects/:project_id/materials`
110
- - 剪辑参数变更:`PUT /projects/:project_id/editor`
111
-
112
- Editor 保存携带服务端 `revision`,SDK 内部串行提交保存请求,避免同一页面内的并发保存互相覆盖。素材身份字段分工:
113
-
114
- - `source_material_id`:业务必填主键。POST / PUT 请求体、DELETE 都用它;DELETE body 为 `{ source_material_ids: string[] }`
115
- - `material_id`:Editing API 自己生成的服务端 id。业务方不用传,传了也不会入库;SDK 只在 POST 成功后把返回值记到面板,供轨道内部关联
116
- - `source`:VeVEditor 轨道 `Source` / 加密 vid 等资源标识。Editing API 请求体里的 `source` 是 origin url,与面板 `source` 不是同一语义
117
-
118
- 服务端响应缺少 `source` 时,加载工程仅使用 `material_id` 作为 `source` fallback。
119
-
120
- 浏览器不应持有 AMK API Key。`endpoint` 应指向业务代理,由代理向 Editing API 注入:
121
-
122
- ```http
123
- Authorization: Bearer <AMK_API_KEY>
124
- ```
125
-
126
- `amkeditordemo` 默认使用与 Editing API 契约一致的内存 mock。联调真实服务时,在启动 demo 的服务端环境设置:
127
-
128
- ```bash
129
- EDITING_API_UPSTREAM='https://your-editing-api.example.com' \
130
- AMK_API_KEY='<your-api-key>' \
131
- VITE_AMK_PROJECT_ID='<existing-project-id>' \
132
- pnpm --dir packages/amkeditordemo/fe dev
133
- ```
134
-
135
- 卸载时销毁:
136
-
52
+ 页面卸载时销毁:
137
53
  ```ts
138
54
  editor.destroy();
139
55
  ```
56
+ ## 接入说明
57
+ - `projectId`、`endpoint` 必填。`endpoint` 指向你的业务代理。
58
+ - `auth` 可选,用于浏览器访问客户代理时附加自定义请求头。SDK 不约定 Token 格式或 Header 名称,只会将 `getHeaders` 返回的内容原样合并到工程、素材、tools、tasks、导出等全部 AMK 请求中。运行期间可通过 `setAuth()` 替换,传入 `null` 或 `undefined` 可清除。
59
+ - 本地上传、URL 导入由业务回调完成。返回的素材必须带业务主键 `source_material_id`,不必填写 `material_id`。
60
+ - 播放地址、封面、雪碧图可能有时效。通过 `onRefreshPlayInfo` 返回新的访问地址。
61
+ - 可选实现 `onPersistExtractUrls`:把抽帧得到的临时地址转存为业务长期地址,并随 `materialPatch` 写回自定义存储字段。
62
+ - 可选配置 `export.qualityEnhancement: true` 以在导出弹窗展示「视频画质增强」;默认不展示。
@@ -1,5 +1,5 @@
1
1
  import './veveditor.css';
2
- import type { AmkEditorOptions, AmkProjectSnapshot, MaterialItem, VeVeditorInstance } from './types';
2
+ import type { AmkEditorAuthConfig, AmkEditorOptions, AmkExportRequestResult, AmkProjectSnapshot, MaterialItem, VeVeditorInstance } from './types';
3
3
  import { type AmkI18nInstance } from './i18n';
4
4
  import { type AmkInvokeToolParams } from './api/client';
5
5
  export declare class AmkEditor {
@@ -9,6 +9,7 @@ export declare class AmkEditor {
9
9
  private editor?;
10
10
  private layout?;
11
11
  private exportModal?;
12
+ private exportRequestInFlight?;
12
13
  private asrProgressModal?;
13
14
  private confirmModal?;
14
15
  private emptyTrackConfirmInFlight?;
@@ -31,8 +32,18 @@ export declare class AmkEditor {
31
32
  private readonly asrStartingElementIds;
32
33
  /** sprite 抽帧任务轮询:key = material_id / source */
33
34
  private readonly spritePollingControllers;
35
+ private readonly posterPollingControllers;
36
+ /** TOS 上传完成前的素材面板占位:key = source_material_id。 */
37
+ private readonly tosUploadPlaceholders;
34
38
  /** 同一素材的封面/雪碧图转存结果串行写回,避免自定义字段互相覆盖。 */
35
39
  private readonly materialPatchQueues;
40
+ /** 等待批量落盘的素材;同一素材在窗口内只保留合并后的最新状态。 */
41
+ private readonly pendingMaterialPatches;
42
+ /** 包含等待中和提交中的最新本地状态,用于合并跨批次的并发字段。 */
43
+ private readonly latestMaterialPatches;
44
+ private materialPatchBatchTimer?;
45
+ /** 批次串行提交,避免先发批次晚返回后覆盖更新批次。 */
46
+ private materialPatchFlushQueue;
36
47
  /** 同一素材的 sprite 失败只处理一次,避免多个缩略图同时 403 重复建任务。 */
37
48
  private readonly thumbnailErrorInFlight;
38
49
  /** 前端抽帧封面缓存(不落盘):key = materialKey,value = dataURL */
@@ -43,6 +54,10 @@ export declare class AmkEditor {
43
54
  private readonly posterCaptureControllers;
44
55
  /** 启动时加载的内置预设资源,供编辑器面板和 ASR 字幕复用。 */
45
56
  private presetLibrary;
57
+ /** 所有 TOS 素材共用一个刷新定时器,避免按素材创建大量 timer。 */
58
+ private tosSignedUrlRefreshTimer?;
59
+ private tosSignedUrlRefreshInFlight?;
60
+ private readonly handleVisibilityChange;
46
61
  private readonly handleTrackChanged;
47
62
  private readonly handleEditParamChanged;
48
63
  constructor(options: AmkEditorOptions);
@@ -50,8 +65,16 @@ export declare class AmkEditor {
50
65
  whenReady(): Promise<this>;
51
66
  getEditor(): VeVeditorInstance | undefined;
52
67
  getI18n(): AmkI18nInstance;
68
+ /** 替换后续 AMK 请求使用的鉴权 Header 提供器;传入 null/undefined 可清除。 */
69
+ setAuth(auth?: AmkEditorAuthConfig | null): void;
53
70
  /** 通用工具调用:POST /api/v1/tools/{toolName} */
54
71
  invokeTool<T = unknown>(options: AmkInvokeToolParams): Promise<T>;
72
+ /**
73
+ * Opens the existing export modal and resolves after the user confirms or cancels.
74
+ * Intended for Agent frontend tools (`request_export_task`). Header export still
75
+ * uses `open()` + direct submit and is unchanged.
76
+ */
77
+ requestExport(): Promise<AmkExportRequestResult>;
55
78
  /**
56
79
  * 获取工程全量参数(materials + editParam + projectName)。
57
80
  * 从 VeVeditor 当前素材/草稿快照读取;未挂载时回落内置拉取到的快照。
@@ -59,11 +82,13 @@ export declare class AmkEditor {
59
82
  getProject(): AmkProjectSnapshot;
60
83
  /**
61
84
  * 刷新素材播放信息(按需触发,如播放前 / 初始化)。
62
- * - 未配置 `material.onRefreshPlayInfo`:直接从当前素材库返回匹配项,不发请求
63
- * - 配置后:把完整素材列表传给业务方,业务方返回要覆盖的字段(url / sprite / poster 等)
85
+ * - TOS 直传素材会先使用临时 STS 重签私有对象 URL
86
+ * - 配置 `material.onRefreshPlayInfo` 后,宿主可继续覆盖播放字段
87
+ * - 两者都未配置时直接返回当前素材,不发请求
64
88
  * @param materialIdOrIds 单个 material_id、material_id 列表;省略则刷新当前全部有 material_id 的素材
65
89
  */
66
90
  refreshPlayInfo(materialIdOrIds?: string | string[]): Promise<MaterialItem | MaterialItem[] | undefined>;
91
+ private refreshPlayInfoInternal;
67
92
  private bootstrap;
68
93
  /** 内置拉取工程:project + materials + editor → 归一化 → 组装 initialData。 */
69
94
  private resolveAndApplyProject;
@@ -72,8 +97,20 @@ export declare class AmkEditor {
72
97
  * 再把轨道元素里的 URL 回填到最新值,完成后回写 editor 文档。
73
98
  */
74
99
  private refreshProjectOnInit;
100
+ /** TOS 私有桶签名刷新优先,宿主刷新回调随后可继续覆盖播放信息。 */
101
+ private refreshMaterialTargets;
102
+ /**
103
+ * 将重签后的素材 URL 按 material_id 同步到轨道节点并重建媒体节点。
104
+ * URL 是运行时数据:保存工程,但不产生撤销步骤。
105
+ */
106
+ private applyTrackMaterialUrls;
107
+ private getExpiringTosMaterialIds;
108
+ private scheduleTosSignedUrlRefresh;
109
+ private refreshExpiringTosUrls;
110
+ private readonly handlePreviewNodeRefresh;
75
111
  private resolveAndApplyPresetLibrary;
76
- mount(): VeVeditorInstance;
112
+ mount(): VeVeditorInstance | undefined;
113
+ private mountVeVeditor;
77
114
  destroy(): void;
78
115
  private resolveConfig;
79
116
  /** 与 VeVeditor 同一套顶层扁平资源字段:boolean 面板开关 + 内部 xgplayer 组装 */
@@ -119,6 +156,26 @@ export declare class AmkEditor {
119
156
  private finishAsrAndCreateTextTrack;
120
157
  private startAsrPolling;
121
158
  private startAsrTask;
159
+ private resolveLocalFileType;
160
+ private createTosUploadPlaceholder;
161
+ /** 资产库选中后立即展示 0% 上传占位卡片,写入素材库成功后再切换为完成态。 */
162
+ private addSystemTosImportPlaceholders;
163
+ private removeTosUploadPlaceholders;
164
+ private hasTosUploadPlaceholders;
165
+ private uploadTosMaterials;
166
+ private extractToolResult;
167
+ private requirePositiveNumber;
168
+ private waitForToolTask;
169
+ private probeAsyncMetadata;
170
+ private prepareTosMaterial;
171
+ /** 将业务资产库的原始条目归一化为 SDK 素材;TOS 地址随后由 SDK 自行签发。 */
172
+ private normalizeSystemMaterial;
173
+ /**
174
+ * 资产库选择的 TOS 条目:同步签发播放 URL 并补齐基础元信息。
175
+ * 入参应为已 normalize 的素材;poster/sprite 在正式素材入库后后台处理。
176
+ */
177
+ private prepareSystemTosMaterials;
178
+ private ingestTosImportedMaterials;
122
179
  /**
123
180
  * 本地 / URL 上传入库后的统一收口:
124
181
  * POST 远端素材库 → 按 sprite/poster 判断发起抽帧并 PUT 更新。
@@ -132,6 +189,11 @@ export declare class AmkEditor {
132
189
  private persistUploadedMaterials;
133
190
  private isHttpUrl;
134
191
  private resolveDisplayPoster;
192
+ /**
193
+ * DataURL 已上屏时保留到本次会话结束,HTTP poster 只负责落库。
194
+ * 没有前端预览或当前缓存也是 HTTP 时,才切换到新的 HTTP 地址。
195
+ */
196
+ private cachePersistedPosterForDisplay;
135
197
  private withDisplayPosters;
136
198
  private blobToDataUrl;
137
199
  /** AMK 视频抽帧:指定第 0 帧并轮询任务结果。 */
@@ -140,9 +202,13 @@ export declare class AmkEditor {
140
202
  private captureVideoPosterFromFrontend;
141
203
  private isThumbnailFrontendDecodeEnabled;
142
204
  /**
143
- * 封面只做运行时刷新,不写素材/工程:
144
- * - enableThumbnailDecode=true:优先前端 Range + WebCodecs,失败再 AMK 第 0 帧兜底
145
- * - 默认 false:只走 AMK SpecifiedFrames 第 0 帧接口
205
+ * 浏览器先解一帧仅作会话展示(DataURL 不落库)。
206
+ * 正式封面仍由 AMK 接口返回的 HTTP URL 负责持久化。
207
+ */
208
+ private previewPosterFromFrontend;
209
+ /**
210
+ * 正式封面只走 AMK 抽帧接口;返回可落库的 HTTP URL。
211
+ * 前端预览由 {@link previewPosterFromFrontend} 并行触发。
146
212
  */
147
213
  private captureVideoPosterFromUrl;
148
214
  /**
@@ -159,24 +225,30 @@ export declare class AmkEditor {
159
225
  * 统一入口:初始化 / 本地上传 / URL 上传拿到素材后,按 sprite/poster 判断是否抽帧。
160
226
  * - sprite / poster 缺失或 auth_key 过期:重新抽帧
161
227
  * - http 结果:先临时链上屏/PUT;若配置 onPersistExtractUrls 则后台转存换链
162
- * - 前端 dataURL 不落盘
163
- * - enableThumbnailDecode=true:跳过 sprite 接口,封面优先前端解码
228
+ * - 封面:浏览器可并行解一帧作会话预览(DataURL 不落盘);正式封面始终走 AMK 接口 URL 落库
229
+ * - enableThumbnailDecode=true:跳过 sprite 接口,轨道缩略图走前端解码
164
230
  */
165
231
  private ensureMaterialExtractTasks;
166
232
  private createExtractFramesTask;
167
233
  private startSpritePolling;
234
+ private startPosterPolling;
168
235
  private buildSpriteFromExtractResult;
169
236
  private extractFirstSnapshotUrl;
170
237
  /**
171
- * 时间轴 sprite 真实请求失败后的兜底:不解析 URL 的签名格式,直接以 Image.onerror 为准。
172
- * 先让业务通过 onRefreshPlayInfo 更新素材;刷新后仍没有新的 sprite,再重新抽帧。
238
+ * 时间轴 sprite / 素材库 poster 真实请求失败后的兜底:不解析 URL 的签名格式,直接以 Image.onerror 为准。
239
+ * 先让业务通过 onRefreshPlayInfo 更新素材;刷新后仍没有新地址,再重新抽帧。
173
240
  */
174
241
  private handleThumbnailError;
242
+ /** 兼容时间轴元素与素材库 sketch 项,定位失败资源所属素材。 */
243
+ private resolveMaterialFromThumbnailError;
175
244
  private findMaterialByKey;
176
245
  private applyMaterialToPanel;
177
246
  private enqueueMaterialPatch;
178
247
  private patchMaterialRemote;
248
+ private flushPendingMaterialPatches;
179
249
  private clearSpriteTimer;
180
250
  private clearSpritePollingTimers;
251
+ private clearPosterTimer;
252
+ private clearPosterPollingTimers;
181
253
  }
182
254
  export declare function createAmkEditor(options: AmkEditorOptions): AmkEditor;
@@ -1,17 +1,30 @@
1
+ import type { AmkEditorAuthConfig } from '../types';
1
2
  export type AmkApiClientOptions = {
2
3
  endpoint: string;
4
+ /** 客户业务代理鉴权;返回的自定义请求头会随每次请求动态获取。 */
5
+ auth?: AmkEditorAuthConfig;
6
+ /** 调用 tools 接口时写入请求体的产物存储目标,例如 `tos://bucket`。 */
7
+ mediaOutputDestination?: string;
3
8
  };
4
9
  export type AmkInvokeToolParams = {
5
10
  toolName: string;
6
11
  params?: Record<string, unknown>;
12
+ /** 默认注入配置的产物存储目标;纯探测类工具应设为 false。 */
13
+ includeMediaOutputDestination?: boolean;
7
14
  headers?: Record<string, string>;
8
15
  signal?: AbortSignal;
9
16
  };
10
17
  export declare class AmkApiClient {
11
18
  private readonly baseUrl;
19
+ private auth?;
20
+ private readonly mediaOutputDestination?;
12
21
  constructor(options: AmkApiClientOptions);
13
22
  getBaseUrl(): string;
23
+ /** 替换后续请求使用的鉴权 Header 提供器;传入 null/undefined 可清除。 */
24
+ setAuth(auth?: AmkEditorAuthConfig | null): void;
14
25
  invokeTool<T = unknown>(options: AmkInvokeToolParams): Promise<T>;
26
+ invokeSyncTool<T = unknown>(options: AmkInvokeToolParams): Promise<T>;
27
+ private mergeToolParams;
15
28
  /**
16
29
  * 查询异步任务:GET /api/v1/tasks/{task_id}
17
30
  * @see https://docs.volcengine.com/docs/6448/2278532
@@ -26,5 +39,6 @@ export declare class AmkApiClient {
26
39
  body?: unknown;
27
40
  signal?: AbortSignal;
28
41
  }): Promise<T>;
42
+ private resolveAuthHeaders;
29
43
  }
30
44
  export declare function createAmkApiClient(options: AmkApiClientOptions): AmkApiClient;
@@ -0,0 +1,3 @@
1
+ <svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="7.74994" height="4.24997" viewBox="0 0 7.74994 4.24997" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path id="Vector (Stroke)" d="M7.10984 0.109835C7.25628 -0.0366117 7.49366 -0.0366116 7.64011 0.109835C7.78656 0.256282 7.78656 0.493662 7.64011 0.640108L4.14011 4.14011C4.06978 4.21043 3.97443 4.24997 3.87497 4.24997C3.77552 4.24997 3.68016 4.21043 3.60983 4.14011L0.109835 0.640108C-0.0366116 0.493662 -0.0366117 0.256282 0.109835 0.109835C0.256282 -0.0366116 0.493662 -0.0366117 0.640108 0.109835L3.87497 3.3447L7.10984 0.109835Z" fill="#101013"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path id="Vector (Stroke)" d="M1.07402e-06 8.58474V7.84615C1.07402e-06 7.59125 0.206639 7.38461 0.461539 7.38461C0.71644 7.38461 0.923078 7.59125 0.923078 7.84615V8.58474C0.923078 9.10926 0.923257 9.47494 0.946515 9.75961C0.969334 10.0389 1.012 10.1994 1.07392 10.3209C1.20667 10.5814 1.41856 10.7933 1.67909 10.9261C1.80063 10.988 1.96111 11.0307 2.24039 11.0535C2.52506 11.0767 2.89074 11.0769 3.41527 11.0769H8.58474C9.10926 11.0769 9.47494 11.0767 9.75962 11.0535C10.0389 11.0307 10.1994 10.988 10.3209 10.9261C10.5814 10.7933 10.7933 10.5814 10.9261 10.3209C10.988 10.1994 11.0307 10.0389 11.0535 9.75961C11.0767 9.47494 11.0769 9.10926 11.0769 8.58474V7.84615C11.0769 7.59125 11.2836 7.38461 11.5385 7.38461C11.7934 7.38461 12 7.59125 12 7.84615V8.58474C12 9.09402 12.0006 9.50376 11.9736 9.83473C11.9461 10.1711 11.8875 10.4664 11.7482 10.7398C11.5269 11.174 11.174 11.5269 10.7398 11.7482C10.4664 11.8875 10.1711 11.9461 9.83474 11.9736C9.50376 12.0006 9.09402 12 8.58474 12H3.41527C2.90598 12 2.49624 12.0006 2.16527 11.9736C1.82889 11.9461 1.53357 11.8875 1.26022 11.7482C0.825997 11.5269 0.47305 11.174 0.251804 10.7398C0.112532 10.4664 0.0539263 10.1711 0.0264434 9.83473C-0.000595874 9.50376 1.01767e-06 9.09402 1.07402e-06 8.58474ZM5.53846 7.84615V1.57572L3.2494 3.86478C3.06916 4.04503 2.777 4.04503 2.59676 3.86478C2.41651 3.68454 2.41651 3.39238 2.59676 3.21214L5.67368 0.135216L5.74399 0.077524C5.81925 0.0273516 5.90821 1.16544e-07 6 0C6.12241 0 6.23977 0.0486612 6.32632 0.135216L9.40324 3.21214C9.58349 3.39238 9.58349 3.68454 9.40324 3.86478C9.223 4.04503 8.93084 4.04503 8.7506 3.86478L6.46154 1.57572V7.84615C6.46154 8.10105 6.2549 8.30769 6 8.30769C5.7451 8.30769 5.53846 8.10105 5.53846 7.84615Z" fill="#101013"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="4.41019" height="5.64103" viewBox="0 0 4.41019 5.64103" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path id="Vector (Stroke)" d="M1.74355 1.57572V5.17949C1.74355 5.43439 1.95019 5.64103 2.20509 5.64103C2.45999 5.64102 2.66663 5.43439 2.66663 5.17949V1.57572L3.62236 2.53145C3.8026 2.71169 4.09476 2.71169 4.275 2.53145C4.45525 2.35121 4.45525 2.05905 4.275 1.87881L2.53141 0.135216C2.44486 0.0486612 2.3275 0 2.20509 0C2.11331 0 2.02434 0.0273516 1.94908 0.077524L1.87877 0.135216L0.135181 1.87881C-0.0450605 2.05905 -0.0450605 2.35121 0.135181 2.53145C0.315423 2.71169 0.607583 2.71169 0.787825 2.53145L1.74355 1.57572Z" fill="#101013"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="13.0093" height="9.54572" viewBox="0 0 13.0093 9.54572" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path id="Vector" d="M0.721682 6.03213C0.52041 5.42761 0.459347 4.78521 0.54312 4.15359C0.626893 3.52197 0.853304 2.9177 1.2052 2.38655C1.5571 1.85539 2.02527 1.41128 2.57422 1.08786C3.12318 0.764439 3.73855 0.570185 4.3737 0.519811C5.00886 0.469438 5.64715 0.564267 6.24022 0.797115C6.8333 1.02996 7.36561 1.39472 7.79684 1.86377C8.22806 2.33282 8.54689 2.89384 8.72918 3.50436H9.80292C10.3821 3.5043 10.9459 3.69051 11.4111 4.0355C11.8763 4.38049 12.2183 4.86596 12.3864 5.42019C12.5545 5.97443 12.5399 6.56804 12.3447 7.11334C12.1496 7.65863 11.9344 8.0263 11.119 8.57093C10.3036 9.11555 7.8181 9.03484 7.8181 9.03484" stroke="black" stroke-width="1.01333" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="12.9997" height="12.9998" viewBox="0 0 12.9997 12.9998" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path id="Vector (Stroke)" d="M2.2056 5.58315C2.40085 5.38809 2.71742 5.38803 2.91263 5.58315C3.10783 5.77836 3.10772 6.09491 2.91263 6.29018L1.78633 7.41649C0.737757 8.46506 0.737873 10.165 1.78633 11.2134C2.8348 12.2618 4.53519 12.2618 5.58385 11.2134L6.70885 10.0877C6.90402 9.89237 7.22053 9.89192 7.41589 10.0871C7.61124 10.2822 7.61106 10.5987 7.41589 10.7941L6.29154 11.9204H6.29089C4.85194 13.3591 2.51846 13.3598 1.0793 11.921C-0.359868 10.482 -0.359663 8.14842 1.0793 6.70946L2.2056 5.58315ZM8.39896 3.89435C8.59424 3.69931 8.91081 3.69916 9.10599 3.89435C9.30115 4.08954 9.30101 4.40611 9.10599 4.60138L4.60143 9.10594C4.40622 9.30104 4.08964 9.301 3.8944 9.10594C3.69918 8.91071 3.69925 8.59417 3.8944 8.39891L8.39896 3.89435ZM6.70951 1.07925C8.14865 -0.359805 10.4814 -0.359693 11.9204 1.07925C13.3595 2.51826 13.3595 4.85116 11.9204 6.29018L10.7948 7.41649C10.5996 7.61156 10.283 7.61163 10.0878 7.41649C9.89259 7.22128 9.89266 6.90473 10.0878 6.70946L11.2134 5.58315L11.3085 5.48289C12.2608 4.42893 12.2292 2.80199 11.2134 1.78628C10.1648 0.737765 8.46506 0.73782 7.41654 1.78628L6.29024 2.91193C6.09497 3.10719 5.77846 3.1072 5.5832 2.91193C5.38805 2.71665 5.38797 2.40012 5.5832 2.2049L6.70951 1.07925Z" fill="#101013"/>
3
+ </svg>
@@ -5,7 +5,8 @@ export interface ExportModalViewProps {
5
5
  videoName: string;
6
6
  visible: boolean;
7
7
  t: AmkI18nInstance['t'];
8
+ showQualityEnhancement?: boolean;
8
9
  onConfirm: (params: ExportVideoParams) => Promise<void> | void;
9
10
  onClose: () => void;
10
11
  }
11
- export declare function ExportModalView({ videoName, visible, t, onConfirm, onClose, }: ExportModalViewProps): React.ReactElement;
12
+ export declare function ExportModalView({ videoName, visible, t, showQualityEnhancement, onConfirm, onClose, }: ExportModalViewProps): React.ReactElement;
@@ -5,12 +5,27 @@ export interface CreateExportModalOptions {
5
5
  videoName: string;
6
6
  onConfirm: (params: ExportVideoParams) => Promise<void> | void;
7
7
  t?: AmkI18nInstance['t'];
8
+ /** 是否展示「视频画质增强」。默认不展示。 */
9
+ showQualityEnhancement?: boolean;
8
10
  }
9
11
  export interface ExportModalController {
10
12
  open: () => void;
11
13
  close: () => void;
12
14
  destroy: () => void;
15
+ /**
16
+ * Opens the modal and waits for the user to confirm or cancel.
17
+ * Confirmed results are returned to the caller and do not invoke `onConfirm`
18
+ * (callers such as Agent tools own the submit path). Header `open()` still
19
+ * uses `onConfirm` for the direct-export path.
20
+ */
21
+ request: () => Promise<ExportModalRequestResult>;
13
22
  }
23
+ export type ExportModalRequestResult = {
24
+ status: 'confirmed';
25
+ params: ExportVideoParams;
26
+ } | {
27
+ status: 'cancel';
28
+ };
14
29
  type SelectOption<T extends string> = {
15
30
  label: string;
16
31
  value: T;
@@ -23,6 +23,8 @@ export declare const AMK_I18N_KEYS: {
23
23
  readonly import: {
24
24
  readonly local: "amk.import.local";
25
25
  readonly url: "amk.import.url";
26
+ readonly system: "amk.import.system";
27
+ readonly action: "amk.import.action";
26
28
  };
27
29
  readonly localUpload: {
28
30
  readonly title: "amk.localUpload.title";
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export interface ImportDropdownAction {
3
+ key: string;
4
+ label: string;
5
+ onSelect: () => void;
6
+ }
7
+ export interface ImportActionsDropdownViewProps {
8
+ actions: ImportDropdownAction[];
9
+ label: string;
10
+ }
11
+ /**
12
+ * “导入”是固定的操作入口,而非表单选择值:菜单项点击后只触发对应回调。
13
+ * selection="none" 同时确保组件不会维护选中态或展示勾选图标。
14
+ */
15
+ export declare function ImportActionsDropdownView({ actions, label, }: ImportActionsDropdownViewProps): React.ReactElement;
@@ -1,4 +1,4 @@
1
- import type { MaterialItem } from './types';
1
+ import type { MaterialItem, SystemMaterialItem } from './types';
2
2
  import type { AmkI18nInstance } from './i18n';
3
3
  interface MountImportActionsOptions {
4
4
  /** AMKEditor 自己的浮层容器;按钮仍挂在 VeVeditor 提供的工具栏插槽中。 */
@@ -6,7 +6,8 @@ interface MountImportActionsOptions {
6
6
  uploadAccept?: string;
7
7
  onUploadMaterial?: (files: File[]) => Promise<MaterialItem[]> | MaterialItem[];
8
8
  onUploadUrlMaterial?: (urls: string[]) => Promise<MaterialItem[]> | MaterialItem[];
9
- onMaterialsImported: (materials: MaterialItem[]) => void;
9
+ onUploadFromSystem?: () => Promise<SystemMaterialItem[] | undefined | null> | SystemMaterialItem[] | undefined | null;
10
+ onMaterialsImported: (materials: SystemMaterialItem[]) => void | Promise<void>;
10
11
  t?: AmkI18nInstance['t'];
11
12
  }
12
13
  /** AMK 独立拥有素材导入 UI 与业务回调,VeVeditor 仅提供挂载容器和标准数据写入 API。 */
package/dist/index.d.ts CHANGED
@@ -4,4 +4,4 @@ export type { AmkApiClientOptions, AmkInvokeToolParams } from './api/client';
4
4
  export type { PresetLibrary, PresetLibraryItem, PresetLibraryResourceKey, } from './api/preset-library';
5
5
  export { AMK_I18N_KEYS, createAmkI18n, tAmk, getGlobalAmkI18n, setGlobalAmkI18n, } from './i18n';
6
6
  export type { AmkI18nInstance, AmkI18nOptions, Locale, LocaleMessages, Messages, } from './i18n';
7
- export type { AmkEditorOptions, AmkEditorConfig, AmkEditorDecodeOptions, AmkEditorHeaderConfig, AmkEditorInternalConfig, AmkProjectSnapshot, ExportVideoParams, MaterialConfig, MaterialItem, PersistExtractUrlsResult, RecommendedExtractStorageFields, Theme, VeVeditorInstance, } from './types';
7
+ export type { AmkEditorOptions, AmkEditorAuthConfig, AmkEditorStorageConfig, AmkEditorUploadSTSCredentials, AmkEditorConfig, AmkEditorDecodeOptions, AmkEditorExportConfig, AmkEditorHeaderConfig, AmkEditorInternalConfig, AmkExportRequestResult, AmkProjectSnapshot, ExportVideoParams, MaterialConfig, MaterialItem, PersistExtractUrlsResult, RecommendedExtractStorageFields, SystemMaterialItem, Theme, VeVeditorInstance, } from './types';