@volcengine/amk-editor 0.0.1-beta.4

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.
Files changed (49) hide show
  1. package/LICENSE +11 -0
  2. package/README.md +139 -0
  3. package/dist/amk-editor.d.ts +182 -0
  4. package/dist/api/client.d.ts +30 -0
  5. package/dist/api/preset-library.d.ts +11 -0
  6. package/dist/api/project.d.ts +30 -0
  7. package/dist/asr-progress-modal-view.d.ts +8 -0
  8. package/dist/asr-progress-modal.d.ts +11 -0
  9. package/dist/asr-text-layout.d.ts +4 -0
  10. package/dist/assets/export-modal-ai.png +0 -0
  11. package/dist/assets/export-modal-close.png +0 -0
  12. package/dist/assets/export-modal-info.png +0 -0
  13. package/dist/assets/export-modal-question.png +0 -0
  14. package/dist/assets/export-modal-select.png +0 -0
  15. package/dist/assets/header-back.png +0 -0
  16. package/dist/assets/header-close.png +0 -0
  17. package/dist/assets/header-edit.png +0 -0
  18. package/dist/assets/header-export.png +0 -0
  19. package/dist/assets/import-local.svg +3 -0
  20. package/dist/assets/import-url.svg +10 -0
  21. package/dist/confirm-modal-view.d.ts +15 -0
  22. package/dist/confirm-modal.d.ts +14 -0
  23. package/dist/export-modal-view.d.ts +11 -0
  24. package/dist/export-modal.d.ts +46 -0
  25. package/dist/export-project-adapter.d.ts +14 -0
  26. package/dist/header.d.ts +29 -0
  27. package/dist/i18n/index.d.ts +17 -0
  28. package/dist/i18n/keys.d.ts +83 -0
  29. package/dist/i18n/locales/en-US.d.ts +2 -0
  30. package/dist/i18n/locales/zh-CN.d.ts +2 -0
  31. package/dist/import-actions.d.ts +14 -0
  32. package/dist/index.d.ts +7 -0
  33. package/dist/index.js +128072 -0
  34. package/dist/local-upload-modal-view.d.ts +12 -0
  35. package/dist/local-upload-modal.d.ts +13 -0
  36. package/dist/project-bootstrap.d.ts +11 -0
  37. package/dist/public-types.d.ts +120 -0
  38. package/dist/react-mount.d.ts +10 -0
  39. package/dist/refresh-play-info.d.ts +17 -0
  40. package/dist/runtime/veveditor.d.ts +6 -0
  41. package/dist/task-polling.d.ts +9 -0
  42. package/dist/toast.d.ts +24 -0
  43. package/dist/types.d.ts +138 -0
  44. package/dist/url-upload-modal-view.d.ts +12 -0
  45. package/dist/url-upload-modal.d.ts +12 -0
  46. package/dist/utils/material-extract.d.ts +43 -0
  47. package/dist/veveditor.css +2563 -0
  48. package/package.json +52 -0
  49. package/third_party_notice.txt +1182 -0
package/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates. All Rights Reserved.
2
+
3
+ The AMK Editor SDK was developed by Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates (hereinafter “Volcano Engine”). Any rights, including but not limited to any copyrights or patent rights, are owned by and proprietary material of the Volcano Engine.
4
+
5
+ The AMK Editor SDK is licensed solely for integration within AI MediaKit which shall be used under a valid commercial license. Customers can contact service@volcengine.com for such commercial license. Here is also a link to AI MediaKit: https://www.volcengine.com/docs/6448/69e744e0d6af160501b2d70b?lang=zh.
6
+
7
+ Without Volcano Engine's prior written permission, any use of the AMK Editor SDK beyond its incorporation into AI MediaKit, in particular any use for commercial purposes, is strictly prohibited. This includes, without limitation, incorporation in a commercial product, use in a commercial service, or production of other artefacts for commercial purposes.
8
+
9
+ Without Volcano Engine's prior written permission, you shall not reproduce, modify, decompile, disassemble, reverse-engineer, or create derivative works of the AMK Editor SDK, nor access, extract, or obtain its source code by any means, or make it available in any form to any third party in any form. Any unauthorized modifications, derivative works, or adaptations of the AMK Editor SDK, along with all associated intellectual property rights, shall automatically and exclusively vest in Volcano Engine.
10
+
11
+ Except otherwise provided by Volcano Engine, the AMK Editor SDK is provided “AS IS” without any warranties. Volcano Engine disclaims all liability for damages arising from its use.
package/README.md ADDED
@@ -0,0 +1,139 @@
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
+
11
+ ```ts
12
+ import { AmkEditor } from '@volcengine/amk-editor';
13
+
14
+ const editor = new AmkEditor({
15
+ container,
16
+ projectId: 'xxx',
17
+ endpoint: 'https://your-proxy.example.com',
18
+ getLicenseUrl: 'https://license.example.com',
19
+ material: {
20
+ // 本地上传:入参 File[],返回 MaterialItem[];每项必须带 source_material_id,不必传 material_id
21
+ onUploadMaterial: async files => [],
22
+ // URL 上传:入参 string[](弹窗内逗号/换行分隔),返回契约同上
23
+ onUploadUrlMaterial: async urls => [],
24
+ onRefreshPlayInfo: async materials =>
25
+ materials.map(item => ({
26
+ 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,
33
+ })),
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
+ },
47
+ });
48
+
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
+ },
80
+ });
81
+ ```
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
+
137
+ ```ts
138
+ editor.destroy();
139
+ ```
@@ -0,0 +1,182 @@
1
+ import './veveditor.css';
2
+ import type { AmkEditorOptions, AmkProjectSnapshot, MaterialItem, VeVeditorInstance } from './types';
3
+ import { type AmkI18nInstance } from './i18n';
4
+ import { type AmkInvokeToolParams } from './api/client';
5
+ export declare class AmkEditor {
6
+ private readonly options;
7
+ private config;
8
+ private readonly i18n;
9
+ private editor?;
10
+ private layout?;
11
+ private exportModal?;
12
+ private asrProgressModal?;
13
+ private confirmModal?;
14
+ private emptyTrackConfirmInFlight?;
15
+ private readonly apiClient;
16
+ private readonly ready;
17
+ private projectName?;
18
+ private editorRevision;
19
+ private projectHydrated;
20
+ private lastKnownTrack;
21
+ private intentionalEmptyTrackChange;
22
+ private emptyTrackSaveNeedsConfirmation;
23
+ private emptyTrackSaveBlocked;
24
+ private savedMaterials;
25
+ private saveQueue;
26
+ private pendingSaveCount;
27
+ private readonly asrPollingControllers;
28
+ /** 当前前台 ASR 会话;取消、关闭或销毁后直接丢弃,不写入工程 JSON。 */
29
+ private activeAsrElementId?;
30
+ /** 提交 ASR 前的同步锁,防止连点在任务创建前重复提交 */
31
+ private readonly asrStartingElementIds;
32
+ /** sprite 抽帧任务轮询:key = material_id / source */
33
+ private readonly spritePollingControllers;
34
+ /** 同一素材的封面/雪碧图转存结果串行写回,避免自定义字段互相覆盖。 */
35
+ private readonly materialPatchQueues;
36
+ /** 同一素材的 sprite 失败只处理一次,避免多个缩略图同时 403 重复建任务。 */
37
+ private readonly thumbnailErrorInFlight;
38
+ /** 前端抽帧封面缓存(不落盘):key = materialKey,value = dataURL */
39
+ private readonly posterCache;
40
+ /** 同一 URL 的封面抽帧只执行一次,避免初始化与上传回调重复请求。 */
41
+ private readonly posterCaptureInFlight;
42
+ /** 销毁编辑器时中断尚未完成的前端抽帧或 AMK 首帧轮询。 */
43
+ private readonly posterCaptureControllers;
44
+ /** 启动时加载的内置预设资源,供编辑器面板和 ASR 字幕复用。 */
45
+ private presetLibrary;
46
+ private readonly handleTrackChanged;
47
+ private readonly handleEditParamChanged;
48
+ constructor(options: AmkEditorOptions);
49
+ /** 等待工程拉取 / canvas 校正 / 挂载完成 */
50
+ whenReady(): Promise<this>;
51
+ getEditor(): VeVeditorInstance | undefined;
52
+ getI18n(): AmkI18nInstance;
53
+ /** 通用工具调用:POST /api/v1/tools/{toolName} */
54
+ invokeTool<T = unknown>(options: AmkInvokeToolParams): Promise<T>;
55
+ /**
56
+ * 获取工程全量参数(materials + editParam + projectName)。
57
+ * 从 VeVeditor 当前素材/草稿快照读取;未挂载时回落内置拉取到的快照。
58
+ */
59
+ getProject(): AmkProjectSnapshot;
60
+ /**
61
+ * 刷新素材播放信息(按需触发,如播放前 / 初始化)。
62
+ * - 未配置 `material.onRefreshPlayInfo`:直接从当前素材库返回匹配项,不发请求
63
+ * - 配置后:把完整素材列表传给业务方,业务方返回要覆盖的字段(url / sprite / poster 等)
64
+ * @param materialIdOrIds 单个 material_id、material_id 列表;省略则刷新当前全部有 material_id 的素材
65
+ */
66
+ refreshPlayInfo(materialIdOrIds?: string | string[]): Promise<MaterialItem | MaterialItem[] | undefined>;
67
+ private bootstrap;
68
+ /** 内置拉取工程:project + materials + editor → 归一化 → 组装 initialData。 */
69
+ private resolveAndApplyProject;
70
+ /**
71
+ * 初始化时批量 refresh 素材(完整素材列表交给业务方),
72
+ * 再把轨道元素里的 URL 回填到最新值,完成后回写 editor 文档。
73
+ */
74
+ private refreshProjectOnInit;
75
+ private resolveAndApplyPresetLibrary;
76
+ mount(): VeVeditorInstance;
77
+ destroy(): void;
78
+ private resolveConfig;
79
+ /** 与 VeVeditor 同一套顶层扁平资源字段:boolean 面板开关 + 内部 xgplayer 组装 */
80
+ private resolveVeVeditorOptions;
81
+ private resolveInternalConfig;
82
+ private enqueueSave;
83
+ private queueProjectNameSave;
84
+ /**
85
+ * VeVeditor 删除前置钩子:远端删除成功后返回 true,底层才清理本地素材和轨道;
86
+ * 请求失败返回 false,保留当前素材。
87
+ */
88
+ private deleteMaterial;
89
+ private queueEditorSave;
90
+ private confirmAbnormalEmptyTrackSave;
91
+ private enqueueEditorSaveWithCurrentEditParam;
92
+ /**
93
+ * AMK 内部导出入口。
94
+ * 适配只作用于即将提交给导出接口的 editParam 副本,不写回工程或当前预览。
95
+ */
96
+ private submitExport;
97
+ private attach;
98
+ private detach;
99
+ private clearAsrPollingTimers;
100
+ private isAsrMediaElement;
101
+ /** 前台 ASR 弹窗打开期间,只允许当前素材对应的一个任务运行。 */
102
+ private isAsrBusy;
103
+ private cancelActiveAsrTask;
104
+ private completeAsrTask;
105
+ private createId;
106
+ private getTrackSnapshot;
107
+ private setTrackSnapshot;
108
+ private findTrackElementIndexById;
109
+ private resolveAsrMediaUrl;
110
+ private extractTaskId;
111
+ private submitAsrTask;
112
+ private queryAsrTask;
113
+ private isTaskCompleted;
114
+ private isTaskFailed;
115
+ private extractUtterances;
116
+ private normalizeAsrRange;
117
+ private resolveAsrTimelineMapping;
118
+ private createAsrTextElement;
119
+ private finishAsrAndCreateTextTrack;
120
+ private startAsrPolling;
121
+ private startAsrTask;
122
+ /**
123
+ * 本地 / URL 上传入库后的统一收口:
124
+ * POST 远端素材库 → 按 sprite/poster 判断发起抽帧并 PUT 更新。
125
+ */
126
+ private ingestImportedMaterials;
127
+ /**
128
+ * 本地上传 / URL 上传完成后,将新素材 POST 到 Editing API。
129
+ * addSketchItems 已写入面板;此处确保远端持久化,并把 Editing API
130
+ * 返回的 material_id 记到面板(业务不用传这个字段;不覆盖本地 source / kid / 预览字段)。
131
+ */
132
+ private persistUploadedMaterials;
133
+ private isHttpUrl;
134
+ private resolveDisplayPoster;
135
+ private withDisplayPosters;
136
+ private blobToDataUrl;
137
+ /** AMK 视频抽帧:指定第 0 帧并轮询任务结果。 */
138
+ private captureVideoPosterFromAmk;
139
+ /** 前端 Range + WebCodecs 解第一张同步帧。 */
140
+ private captureVideoPosterFromFrontend;
141
+ private isThumbnailFrontendDecodeEnabled;
142
+ /**
143
+ * 封面只做运行时刷新,不写素材/工程:
144
+ * - enableThumbnailDecode=true:优先前端 Range + WebCodecs,失败再 AMK 第 0 帧兜底
145
+ * - 默认 false:只走 AMK SpecifiedFrames 第 0 帧接口
146
+ */
147
+ private captureVideoPosterFromUrl;
148
+ /**
149
+ * 抽帧临时 http 转存;失败回落临时链。
150
+ * 调用方应先上屏临时链,再后台调用本方法换链。
151
+ */
152
+ private persistExtractUrls;
153
+ /**
154
+ * 后台转存:临时链已上屏/落盘后,换成长效地址再 PUT + 刷新面板。
155
+ * 未配置回调、转存失败或结果未变时不二次写盘。
156
+ */
157
+ private schedulePersistExtractUrlsAndSwap;
158
+ /**
159
+ * 统一入口:初始化 / 本地上传 / URL 上传拿到素材后,按 sprite/poster 判断是否抽帧。
160
+ * - sprite / poster 缺失或 auth_key 过期:重新抽帧
161
+ * - http 结果:先临时链上屏/PUT;若配置 onPersistExtractUrls 则后台转存换链
162
+ * - 前端 dataURL 不落盘
163
+ * - enableThumbnailDecode=true:跳过 sprite 接口,封面优先前端解码
164
+ */
165
+ private ensureMaterialExtractTasks;
166
+ private createExtractFramesTask;
167
+ private startSpritePolling;
168
+ private buildSpriteFromExtractResult;
169
+ private extractFirstSnapshotUrl;
170
+ /**
171
+ * 时间轴 sprite 真实请求失败后的兜底:不解析 URL 的签名格式,直接以 Image.onerror 为准。
172
+ * 先让业务通过 onRefreshPlayInfo 更新素材;刷新后仍没有新的 sprite,再重新抽帧。
173
+ */
174
+ private handleThumbnailError;
175
+ private findMaterialByKey;
176
+ private applyMaterialToPanel;
177
+ private enqueueMaterialPatch;
178
+ private patchMaterialRemote;
179
+ private clearSpriteTimer;
180
+ private clearSpritePollingTimers;
181
+ }
182
+ export declare function createAmkEditor(options: AmkEditorOptions): AmkEditor;
@@ -0,0 +1,30 @@
1
+ export type AmkApiClientOptions = {
2
+ endpoint: string;
3
+ };
4
+ export type AmkInvokeToolParams = {
5
+ toolName: string;
6
+ params?: Record<string, unknown>;
7
+ headers?: Record<string, string>;
8
+ signal?: AbortSignal;
9
+ };
10
+ export declare class AmkApiClient {
11
+ private readonly baseUrl;
12
+ constructor(options: AmkApiClientOptions);
13
+ getBaseUrl(): string;
14
+ invokeTool<T = unknown>(options: AmkInvokeToolParams): Promise<T>;
15
+ /**
16
+ * 查询异步任务:GET /api/v1/tasks/{task_id}
17
+ * @see https://docs.volcengine.com/docs/6448/2278532
18
+ */
19
+ getTask<T = unknown>(taskId: string, options?: {
20
+ headers?: Record<string, string>;
21
+ signal?: AbortSignal;
22
+ }): Promise<T>;
23
+ requestJson<T = unknown>(path: string, options?: {
24
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
25
+ headers?: Record<string, string>;
26
+ body?: unknown;
27
+ signal?: AbortSignal;
28
+ }): Promise<T>;
29
+ }
30
+ export declare function createAmkApiClient(options: AmkApiClientOptions): AmkApiClient;
@@ -0,0 +1,11 @@
1
+ import type { AmkApiClient } from './client';
2
+ export type PresetLibraryResourceKey = 'effects' | 'fonts' | 'word_arts' | 'filters' | 'transitions' | 'text_enter_animations' | 'text_out_animations' | 'text_loop_animations';
3
+ export type PresetLibraryItem = {
4
+ id: string;
5
+ name: string;
6
+ icon_url: string;
7
+ package_url: string;
8
+ default?: boolean;
9
+ };
10
+ export type PresetLibrary = Partial<Record<PresetLibraryResourceKey, PresetLibraryItem[]>>;
11
+ export declare function fetchPresetLibrary(client: Pick<AmkApiClient, 'requestJson'>, resources: PresetLibraryResourceKey[]): Promise<PresetLibrary>;
@@ -0,0 +1,30 @@
1
+ import type { AmkApiClient } from './client';
2
+ import type { AmkProjectSnapshot, MaterialItem } from '../types';
3
+ type EditingApiClient = Pick<AmkApiClient, 'requestJson'>;
4
+ export type LoadedAmkProject = AmkProjectSnapshot & {
5
+ editorRevision: number;
6
+ };
7
+ export type SavedAmkEditor = {
8
+ revision: number;
9
+ editParam: Record<string, unknown>;
10
+ };
11
+ export declare function fetchAmkProject(client: EditingApiClient, projectId: string): Promise<LoadedAmkProject>;
12
+ export declare function updateAmkProjectName(client: EditingApiClient, projectId: string, projectName: string): Promise<void>;
13
+ /**
14
+ * POST 一批新素材到 AMK 工程。
15
+ * POST 语义:已存在报错,不存在新增;用于上传新素材入库。
16
+ * 请求只带业务 source_material_id;返回值里的 material_id 由 Editing API 生成。
17
+ */
18
+ export declare function createAmkMaterials(client: EditingApiClient, projectId: string, materials: MaterialItem[]): Promise<MaterialItem[]>;
19
+ /**
20
+ * Upsert(PUT)一批素材到 AMK 工程。
21
+ * PUT 语义:已存在覆盖,不存在新增;适合本地上传/URL上传完成后写回。
22
+ */
23
+ export declare function upsertAmkMaterials(client: EditingApiClient, projectId: string, materials: MaterialItem[]): Promise<void>;
24
+ /**
25
+ * 删除 AMK 工程素材。Editing API DELETE body 为 source_material_ids,
26
+ * 值为业务 source_material_id;这里统一按 100 条分批。
27
+ */
28
+ export declare function deleteAmkMaterials(client: EditingApiClient, projectId: string, materials: MaterialItem | MaterialItem[]): Promise<void>;
29
+ export declare function saveAmkEditor(client: EditingApiClient, projectId: string, editParam: Record<string, unknown>, revision: number): Promise<SavedAmkEditor>;
30
+ export {};
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { AmkI18nInstance } from './i18n';
3
+ export interface AsrProgressModalViewProps {
4
+ visible: boolean;
5
+ t: AmkI18nInstance['t'];
6
+ onCancel: () => void;
7
+ }
8
+ export declare function AsrProgressModalView({ visible, t, onCancel, }: AsrProgressModalViewProps): React.ReactElement;
@@ -0,0 +1,11 @@
1
+ import type { AmkI18nInstance } from './i18n';
2
+ export interface AsrProgressModalController {
3
+ open: () => void;
4
+ close: () => void;
5
+ destroy: () => void;
6
+ }
7
+ export declare function createAsrProgressModal(options: {
8
+ container: HTMLElement;
9
+ t: AmkI18nInstance['t'];
10
+ onCancel: () => void;
11
+ }): AsrProgressModalController;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * ASR 字幕字号随画布宽度等比缩放:1080px 画布对应 80px 字号,上限 100。
3
+ */
4
+ export declare function resolveAsrFontSize(canvasWidth: number): number;
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,3 @@
1
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M1.5 7.93855V7.38461C1.5 7.19344 1.65498 7.03846 1.84615 7.03846C2.03733 7.03846 2.19231 7.19344 2.19231 7.38461V7.93855C2.19231 8.33194 2.19244 8.6062 2.20989 8.81971C2.227 9.02917 2.259 9.14953 2.30544 9.24068C2.405 9.43608 2.56392 9.595 2.75932 9.69456C2.85047 9.741 2.97083 9.773 3.18029 9.79011C3.39379 9.80756 3.66806 9.80769 4.06145 9.80769H7.93855C8.33194 9.80769 8.60621 9.80756 8.81971 9.79011C9.02917 9.773 9.14953 9.741 9.24068 9.69456C9.43608 9.595 9.595 9.43608 9.69456 9.24068C9.741 9.14953 9.773 9.02917 9.79011 8.81971C9.80756 8.6062 9.80769 8.33194 9.80769 7.93855V7.38461C9.80769 7.19344 9.96267 7.03846 10.1538 7.03846C10.345 7.03846 10.5 7.19344 10.5 7.38461V7.93855C10.5 8.32051 10.5004 8.62782 10.4802 8.87605C10.4596 9.12833 10.4156 9.34982 10.3111 9.55484C10.1452 9.8805 9.8805 10.1452 9.55484 10.3111C9.34982 10.4156 9.12833 10.4596 8.87605 10.4802C8.62782 10.5004 8.32051 10.5 7.93855 10.5H4.06145C3.67949 10.5 3.37218 10.5004 3.12395 10.4802C2.87167 10.4596 2.65018 10.4156 2.44516 10.3111C2.1195 10.1452 1.85479 9.8805 1.68885 9.55484C1.5844 9.34982 1.54044 9.12833 1.51983 8.87605C1.49955 8.62782 1.5 8.32051 1.5 7.93855ZM5.65385 7.38461V2.68179L3.93705 4.39859C3.80187 4.53377 3.58275 4.53377 3.44757 4.39859C3.31239 4.26341 3.31239 4.04429 3.44757 3.9091L5.75526 1.60141L5.80799 1.55814C5.86444 1.52051 5.93116 1.5 6 1.5C6.09181 1.5 6.17983 1.5365 6.24474 1.60141L8.55243 3.9091C8.68761 4.04429 8.68761 4.26341 8.55243 4.39859C8.41725 4.53377 8.19813 4.53377 8.06295 4.39859L6.34615 2.68179V7.38461C6.34615 7.57579 6.19117 7.73077 6 7.73077C5.80882 7.73077 5.65385 7.57579 5.65385 7.38461Z" fill="#595863" stroke="#595863" stroke-width="0.2" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_0_10)">
3
+ <path d="M6.35378 9.18196L5.64667 9.88907C4.67036 10.8654 3.08745 10.8654 2.11114 9.88907C1.13483 8.91276 1.13483 7.32985 2.11114 6.35354L2.81825 5.64643M9.18221 6.35354L9.88931 5.64643C10.8656 4.67012 10.8656 3.08721 9.88931 2.1109C8.913 1.13458 7.33009 1.13458 6.35378 2.1109L5.64667 2.818M4.25023 7.74997L7.75023 4.24997" stroke="#595863" stroke-linecap="round" stroke-linejoin="round"/>
4
+ </g>
5
+ <defs>
6
+ <clipPath id="clip0_0_10">
7
+ <rect width="12" height="12" fill="white"/>
8
+ </clipPath>
9
+ </defs>
10
+ </svg>
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import type { AmkI18nInstance } from './i18n';
3
+ export interface ConfirmModalViewProps {
4
+ visible: boolean;
5
+ title: string;
6
+ desc: string;
7
+ theme?: 'light' | 'dark';
8
+ t: AmkI18nInstance['t'];
9
+ onConfirm: () => void;
10
+ onCancel: () => void;
11
+ }
12
+ /**
13
+ * 对齐 VeVeditor 节点报错弹窗(EditorErrorDialog)的居中 Modal 结构与按钮层级。
14
+ */
15
+ export declare function ConfirmModalView({ visible, title, desc, theme, t, onConfirm, onCancel, }: ConfirmModalViewProps): React.ReactElement;
@@ -0,0 +1,14 @@
1
+ import type { AmkI18nInstance } from './i18n';
2
+ export interface ConfirmModalAskOptions {
3
+ title: string;
4
+ desc: string;
5
+ theme?: 'light' | 'dark';
6
+ }
7
+ export interface ConfirmModalController {
8
+ ask: (options: ConfirmModalAskOptions) => Promise<boolean>;
9
+ destroy: () => void;
10
+ }
11
+ export declare function createConfirmModal(options: {
12
+ container: HTMLElement;
13
+ t: AmkI18nInstance['t'];
14
+ }): ConfirmModalController;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import type { ExportVideoParams } from './types';
3
+ import type { AmkI18nInstance } from './i18n';
4
+ export interface ExportModalViewProps {
5
+ videoName: string;
6
+ visible: boolean;
7
+ t: AmkI18nInstance['t'];
8
+ onConfirm: (params: ExportVideoParams) => Promise<void> | void;
9
+ onClose: () => void;
10
+ }
11
+ export declare function ExportModalView({ videoName, visible, t, onConfirm, onClose, }: ExportModalViewProps): React.ReactElement;
@@ -0,0 +1,46 @@
1
+ import type { ExportVideoParams } from './types';
2
+ import type { AmkI18nInstance } from './i18n';
3
+ export interface CreateExportModalOptions {
4
+ container: HTMLElement;
5
+ videoName: string;
6
+ onConfirm: (params: ExportVideoParams) => Promise<void> | void;
7
+ t?: AmkI18nInstance['t'];
8
+ }
9
+ export interface ExportModalController {
10
+ open: () => void;
11
+ close: () => void;
12
+ destroy: () => void;
13
+ }
14
+ type SelectOption<T extends string> = {
15
+ label: string;
16
+ value: T;
17
+ };
18
+ /** @deprecated 使用 AMK_I18N_KEYS.export.qualityTooltip + t() */
19
+ export declare const QUALITY_TOOLTIP = "AI MediaKit \u753B\u8D28\u589E\u5F3A\u96C6\u6210\u667A\u80FD\u8D85\u5206\u3001\u63D2\u5E27\u3001\u753B\u9762\u589E\u5F3A\u3001\u81EA\u9002\u5E94\u9510\u5316\u3001\u8272\u5F69\u589E\u5F3A\u7B49 30+ \u9AD8\u8D28\u91CF\u7B97\u6CD5\uFF0C\u7ED3\u5408\u81EA\u7814\u89C6\u9891\u5185\u5BB9\u7406\u89E3\u4E0E\u667A\u80FD\u8C03\u5EA6\uFF0C\u6309\u573A\u666F\u81EA\u52A8\u62E9\u4F18\u8C03\u7528\uFF0C\u5168\u9762\u63D0\u5347\u89C6\u9891\u753B\u8D28\u3002";
20
+ export declare function getBaseResolutions(t: AmkI18nInstance['t']): SelectOption<ExportVideoParams['resolution']>[];
21
+ /** 画质增强开启后的分辨率:不含原画;大模型版不含 4K */
22
+ export declare function getEnhancedResolutions(t: AmkI18nInstance['t'], enhancementVersion?: ExportVideoParams['enhancementVersion']): SelectOption<ExportVideoParams['resolution']>[];
23
+ /** 当前模式下合法分辨率;非法时回落到默认项 */
24
+ export declare function normalizeExportResolution(params: Pick<ExportVideoParams, 'qualityEnhancement' | 'enhancementVersion' | 'resolution'>, t?: AmkI18nInstance['t']): ExportVideoParams['resolution'];
25
+ export declare function getEnhancementVersions(t: AmkI18nInstance['t']): SelectOption<ExportVideoParams['enhancementVersion']>[];
26
+ export declare const BASE_FORMATS: SelectOption<ExportVideoParams['format']>[];
27
+ export declare const BASE_CODECS: SelectOption<ExportVideoParams['codec']>[];
28
+ export declare const AUDIO_CODECS: SelectOption<ExportVideoParams['codec']>[];
29
+ /** 按导出格式返回编码下拉选项;画质增强开启时仅保留 H264。 */
30
+ export declare function getCodecOptions(format: ExportVideoParams['format'], enhanced: boolean): SelectOption<ExportVideoParams['codec']>[];
31
+ /** 保证 codec 与 format 一致:MP3 固定 mp3,MP4 回落到合法视频编码。 */
32
+ export declare function normalizeExportCodec(params: Pick<ExportVideoParams, 'format' | 'codec'>): ExportVideoParams['codec'];
33
+ export declare function applyExportFormatChange(current: ExportVideoParams, format: ExportVideoParams['format']): ExportVideoParams;
34
+ /** 兼容旧测试/调用方:中文默认标签 */
35
+ export declare const BASE_RESOLUTIONS: SelectOption<"original" | "720p" | "1080p" | "2k" | "4k">[];
36
+ export declare const ENHANCED_RESOLUTIONS: SelectOption<"original" | "720p" | "1080p" | "2k" | "4k">[];
37
+ export declare const ENHANCEMENT_VERSIONS: SelectOption<"standard" | "professional" | "large-model">[];
38
+ export declare function createDefaultExportVideoParams(videoName: string): ExportVideoParams;
39
+ /** 导出帧率合法区间(含端点) */
40
+ export declare const EXPORT_FRAME_RATE_MIN = 15;
41
+ export declare const EXPORT_FRAME_RATE_MAX = 120;
42
+ /** 将导出帧率钳制到 15~120;非法输入回落 30 */
43
+ export declare function normalizeExportFrameRate(frameRate: unknown): number;
44
+ export declare function toggleQualityEnhancement(params: ExportVideoParams, enabled: boolean): ExportVideoParams;
45
+ export declare function createExportModal(options: CreateExportModalOptions): ExportModalController;
46
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { ExportVideoParams } from './types';
2
+ /**
3
+ * 开启画质增强时,把增强任务参数交给代理层(callback_args,JSON 字符串)。
4
+ * - large-model → POST .../tools/enhance-video-generative
5
+ * - standard / professional → POST .../tools/enhance-video,带 tool_version
6
+ * video_url 由代理在导出完成后再填;关闭增强时返回 undefined。
7
+ */
8
+ export declare function buildExportCallbackArgs(params: Pick<ExportVideoParams, 'qualityEnhancement' | 'enhancementVersion' | 'resolution' | 'frameRate'>): string | undefined;
9
+ /**
10
+ * 临时导出兜底:
11
+ * 根据目标分辨率短边等比缩放 Canvas、Track 元素和 Extra。
12
+ * 只返回导出副本,不修改编辑器内部工程;服务端支持后可整文件删除。
13
+ */
14
+ export declare function adaptEditParamForExport(editParam: Record<string, unknown>, params: Pick<ExportVideoParams, 'resolution' | 'format' | 'frameRate' | 'codec'>): Record<string, unknown>;
@@ -0,0 +1,29 @@
1
+ import type { AmkI18nInstance } from './i18n';
2
+ export interface ResolveHeaderTitleOptions {
3
+ /** initialData.projectName / getProject.projectName */
4
+ projectName?: string;
5
+ t?: AmkI18nInstance['t'];
6
+ }
7
+ export interface CreateAmkEditorLayoutOptions {
8
+ container: HTMLElement;
9
+ title: string;
10
+ theme?: 'light' | 'dark';
11
+ showHeader: boolean;
12
+ onExport: () => void;
13
+ /** 传入则展示返回按钮 */
14
+ onBack?: () => void;
15
+ /** 传入则展示关闭按钮 */
16
+ onClose?: () => void;
17
+ onTitleSubmit?: (title: string) => void;
18
+ t?: AmkI18nInstance['t'];
19
+ }
20
+ export type AmkSaveStatus = 'saving' | 'saved';
21
+ export interface AmkEditorLayout {
22
+ root: HTMLDivElement;
23
+ workspace: HTMLDivElement;
24
+ setSaveStatus: (status: AmkSaveStatus) => void;
25
+ destroy: () => void;
26
+ }
27
+ export declare function resolveHeaderTitle(options: ResolveHeaderTitleOptions): string;
28
+ export declare function validateHeaderTitle(title: string, t?: AmkI18nInstance['t']): string | undefined;
29
+ export declare function createAmkEditorLayout(options: CreateAmkEditorLayoutOptions): AmkEditorLayout;
@@ -0,0 +1,17 @@
1
+ export type Locale = string;
2
+ export type Messages = Record<string, string>;
3
+ export type LocaleMessages = Record<Locale, Messages>;
4
+ export interface AmkI18nOptions {
5
+ locale?: Locale;
6
+ messages?: LocaleMessages;
7
+ messageOverrides?: Messages;
8
+ }
9
+ export interface AmkI18nInstance {
10
+ t: (key: string, params?: Record<string, any>, fallback?: string) => string;
11
+ getLocale: () => Locale;
12
+ }
13
+ export declare function createAmkI18n(options?: AmkI18nOptions): AmkI18nInstance;
14
+ export declare function setGlobalAmkI18n(i18n: AmkI18nInstance): void;
15
+ export declare function getGlobalAmkI18n(): AmkI18nInstance | null;
16
+ export declare function tAmk(key: string, params?: Record<string, any>, fallback?: string): string;
17
+ export { AMK_I18N_KEYS } from './keys';