@aicut/core 0.1.0 → 0.1.1

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 (2) hide show
  1. package/README.md +68 -80
  2. package/package.json +35 -2
package/README.md CHANGED
@@ -1,9 +1,17 @@
1
1
  # @aicut/core
2
2
 
3
- Framework-agnostic video editor engine. Owns the project data model, the HTML5 playback engine, the canvas timeline (ruler, tracks, clips, thumbnails, playhead, snap, in-canvas scrollbars), and a vanilla DOM toolbar.
3
+ > Framework-agnostic engine for the AiCut video editor canvas timeline, plain-JSON projects, zero runtime deps.
4
+
5
+ [![npm](https://img.shields.io/npm/v/@aicut/core.svg)](https://www.npmjs.com/package/@aicut/core)
6
+ [![License](https://img.shields.io/npm/l/@aicut/core.svg)](./LICENSE)
7
+ [![GitHub](https://img.shields.io/badge/repo-ziqiangai/AiCut-181717?logo=github)](https://github.com/ziqiangai/AiCut)
8
+
9
+ ![AiCut editor](https://raw.githubusercontent.com/ziqiangai/AiCut/main/docs/screenshots/editor-dark.png)
4
10
 
5
11
  For React or Vue apps, prefer **[@aicut/react](https://www.npmjs.com/package/@aicut/react)** or **[@aicut/vue](https://www.npmjs.com/package/@aicut/vue)** — they wrap this same engine.
6
12
 
13
+ ## Install
14
+
7
15
  ```bash
8
16
  pnpm add @aicut/core
9
17
  ```
@@ -21,91 +29,79 @@ const editor = Editor.create({
21
29
  sources: [
22
30
  { id: "s1", url: "/media/a.mp4", kind: "video", name: "a.mp4" },
23
31
  ],
24
- tracks: [
25
- {
26
- id: "t1",
27
- kind: "video",
28
- clips: [{ id: "c1", sourceId: "s1", in: 0, out: 5000, start: 0 }],
29
- },
30
- ],
32
+ tracks: [{
33
+ id: "t1",
34
+ kind: "video",
35
+ clips: [{ id: "c1", sourceId: "s1", in: 0, out: 5000, start: 0 }],
36
+ }],
31
37
  },
32
38
  });
33
39
 
34
- editor.on("change", ({ project }) => localStorage.setItem("aicut", JSON.stringify(project)));
35
- editor.on("export", ({ project }) => fetch("/api/export", {
36
- method: "POST",
37
- headers: { "content-type": "application/json" },
38
- body: JSON.stringify({ project }),
39
- }));
40
- ```
41
-
42
- The editor renders into your `container`. Call methods on the returned `editor` instance to drive it imperatively.
40
+ editor.on("change", ({ project }) => {
41
+ localStorage.setItem("aicut", JSON.stringify(project));
42
+ });
43
43
 
44
- ## API surface
44
+ editor.on("export", ({ project }) => {
45
+ fetch("/api/export", {
46
+ method: "POST",
47
+ headers: { "content-type": "application/json" },
48
+ body: JSON.stringify({ project }),
49
+ });
50
+ });
51
+ ```
45
52
 
46
- ### Playback & editing
53
+ ## API at a glance
47
54
 
48
55
  ```ts
49
- editor.play(); editor.pause(); editor.togglePlay(); editor.seek(timeMs);
50
- editor.split(); // split at playhead
51
- editor.trimLeft(); // trim selected clip's left edge to playhead
56
+ // Playback
57
+ editor.play(); editor.pause(); editor.togglePlay();
58
+ editor.seek(timeMs);
59
+
60
+ // Editing
61
+ editor.split(); // at playhead
62
+ editor.trimLeft();
52
63
  editor.trimRight();
53
64
  editor.removeClip(clipId);
54
65
  editor.setClipSpeed(clipId, 2);
55
-
56
66
  editor.undo(); editor.redo();
57
- editor.canUndo(); editor.canRedo();
58
- ```
59
-
60
- ### Project, sources, tracks
61
67
 
62
- ```ts
63
- editor.getProject(); // deep clone of current state
64
- editor.setProject(p); // replace, preserves auto-fit etc.
65
- editor.reset(); // empty single-track project
68
+ // Project state
69
+ editor.getProject();
70
+ editor.setProject(project);
71
+ editor.reset();
66
72
  editor.addSource({ id, url, kind: "video" });
67
73
  editor.addTrack("video");
68
- editor.removeTrack(trackId);
69
74
  editor.moveClip(clipId, { start, trackId, newTrack });
70
- editor.resizeClip(clipId, { in, out, start });
71
- ```
72
75
 
73
- ### Viewport
76
+ // Viewport
77
+ editor.setScale(80); // px per second
78
+ editor.setSnap(false);
79
+ editor.setSelection(clipId);
74
80
 
75
- ```ts
76
- editor.getScale(); editor.setScale(80); // px per second
77
- editor.getSnap(); editor.setSnap(false);
78
- editor.getSelection(); editor.setSelection(clipId);
79
- editor.enterFullscreen(); editor.exitFullscreen();
81
+ // UI
82
+ editor.setTheme({ controlsBg: "#fff" });
83
+ editor.setLocale({ undo: "Annuler" });
84
+ editor.requestExport(); // → fires "export" event
80
85
  ```
81
86
 
82
- ### Events
87
+ ## Events
83
88
 
84
89
  ```ts
85
- const off = editor.on("change", ({ project }) => /* … */);
86
- editor.on("time", ({ timeMs }) => /* playback tick */);
87
- editor.on("export", ({ project }) => /* host-triggered export */);
90
+ editor.on("change", ({ project }) => /* … */);
91
+ editor.on("time", ({ timeMs }) => /* */);
92
+ editor.on("export", ({ project }) => /* */);
88
93
  editor.on("selectionChange", ({ clipId }) => /* … */);
89
- editor.on("historyChange", ({ canUndo, canRedo }) => /* … */);
90
- editor.on("ready", ({ sourceId }) => /* per-source metadata loaded */);
91
- editor.on("scaleChange", ({ pxPerSec }) => /* … */);
92
- editor.on("snapChange", ({ snap }) => /* … */);
93
- editor.on("error", ({ error }) => /* … */);
94
- off(); // unsubscribe
94
+ editor.on("historyChange", ({ canUndo, canRedo }) => /* … */);
95
+ editor.on("ready", ({ sourceId }) => /* */);
96
+ editor.on("scaleChange", ({ pxPerSec }) => /* … */);
97
+ editor.on("snapChange", ({ snap }) => /* … */);
98
+ editor.on("error", ({ error }) => /* … */);
95
99
  ```
96
100
 
97
- ### Triggering export
98
-
99
- The library never calls a backend on its own — `requestExport()` fires the `export` event with the current project JSON; your handler decides what to do.
100
-
101
- ```ts
102
- editor.requestExport(); // → emits "export" with project
103
- ```
101
+ Each `on` returns an unsubscribe function.
104
102
 
105
103
  ## Theming
106
104
 
107
- CSS variables; pass any subset via `theme` and the rest fall back to the defaults.
108
-
109
105
  ```ts
110
106
  Editor.create({
111
107
  container,
@@ -116,16 +112,14 @@ Editor.create({
116
112
  controlsBorder: "rgba(255, 255, 255, 0.08)",
117
113
  controlsHover: "rgba(255, 255, 255, 0.08)",
118
114
  controlsActive: "rgba(255, 255, 255, 0.12)",
119
- previewBg: "#000", // letterbox colour
115
+ previewBg: "#000", // letterbox colour
120
116
  },
121
117
  });
122
-
123
- editor.setTheme({ controlsBg: "#f6f6f8", previewBg: "#e4e4e7" }); // runtime swap
124
118
  ```
125
119
 
126
- Every variable is also a plain CSS custom property — `.aicut-root { --aicut-controls-bg: …; }` works too.
120
+ Every key is also a plain CSS custom property — `.aicut-root { --aicut-controls-bg: …; }` works too. Call `editor.setTheme(…)` to swap at runtime.
127
121
 
128
- ## Internationalisation
122
+ ## i18n
129
123
 
130
124
  English by default. Bundled `localeZh` covers the whole editor (toolbar tooltips, exit-fullscreen overlay, canvas track headers).
131
125
 
@@ -134,42 +128,36 @@ import { Editor, localeZh } from "@aicut/core";
134
128
 
135
129
  Editor.create({ container, project, locale: localeZh });
136
130
 
137
- // Partial override + runtime swap
138
- editor.setLocale({ undo: "Annuler", redo: "Refaire" });
131
+ editor.setLocale({ undo: "Annuler" }); // partial override
139
132
  ```
140
133
 
141
- `Locale` is exported as a type if you need to typecheck a custom pack.
142
-
143
134
  ## Toolbar slots
144
135
 
145
- Both the editor's built-in toolbar and the standalone `Timeline`'s optional toolbar reserve `toolbarLeft` / `toolbarRight` slot DOM elements for host-supplied controls.
136
+ Both the editor's toolbar and the standalone `Timeline`'s optional toolbar expose `toolbarLeft` / `toolbarRight` slot DOM elements. The library renders nothing into them — append your own buttons.
146
137
 
147
138
  ```ts
148
- const editor = Editor.create({ container, project });
149
139
  const exportBtn = document.createElement("button");
150
140
  exportBtn.textContent = "Export";
151
141
  exportBtn.onclick = () => editor.requestExport();
152
142
  editor.toolbarRight.appendChild(exportBtn);
153
143
  ```
154
144
 
155
- The library paints nothing into either slot and renders no separator until they're populated.
156
-
157
145
  ## Standalone Timeline
158
146
 
159
- Use the canvas timeline without the rest of the editor — useful for a frame-picker, thumbnail strip, or a read-only preview.
160
-
161
147
  ```ts
162
148
  import { Timeline } from "@aicut/core";
163
149
 
164
150
  const tl = Timeline.create({
165
151
  container: document.getElementById("strip")!,
166
- project: { /* one-clip project */ },
152
+ project: singleClipProject,
167
153
  showHeader: false,
168
154
  readOnly: true,
169
155
  onSeek: (ms) => console.log("picked", ms),
170
156
  });
171
157
  ```
172
158
 
159
+ Useful for a frame-picker, thumbnail strip, or read-only preview.
160
+
173
161
  ## Data model
174
162
 
175
163
  ```ts
@@ -188,14 +176,14 @@ interface Track { id: string; kind: "video" | "audio"; clips: Clip[]; }
188
176
 
189
177
  interface Clip {
190
178
  id: string; sourceId: string;
191
- in: Ms; out: Ms; // window into the source (exclusive at `out`)
192
- start: Ms; // position on the timeline
179
+ in: Ms; out: Ms; // window into the source (exclusive at `out`)
180
+ start: Ms; // position on the timeline
193
181
  speed?: number;
194
182
  }
195
183
 
196
- type Ms = number; // integer milliseconds; no frame-rate coupling
184
+ type Ms = number; // integer milliseconds; no frame-rate coupling
197
185
  ```
198
186
 
199
- ## License
187
+ ---
200
188
 
201
- MIT
189
+ [Full docs & demo](https://github.com/ziqiangai/AiCut) · [@aicut/react](https://www.npmjs.com/package/@aicut/react) · [@aicut/vue](https://www.npmjs.com/package/@aicut/vue)
package/package.json CHANGED
@@ -1,8 +1,41 @@
1
1
  {
2
2
  "name": "@aicut/core",
3
- "version": "0.1.0",
4
- "description": "Framework-agnostic core for the AiCut video editor — data model, editor instance, playback engine, vanilla DOM renderer.",
3
+ "version": "0.1.1",
4
+ "description": "Framework-agnostic core for the AiCut video editor — canvas timeline, data model, HTML5 playback engine.",
5
5
  "license": "MIT",
6
+ "author": "ziqiang <ziqiangytu@gmail.com>",
7
+ "homepage": "https://github.com/ziqiangai/AiCut#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/ziqiangai/AiCut.git",
11
+ "directory": "packages/core"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/ziqiangai/AiCut/issues"
15
+ },
16
+ "keywords": [
17
+ "video-editor",
18
+ "video-editing",
19
+ "timeline",
20
+ "timeline-editor",
21
+ "nle",
22
+ "video-cutter",
23
+ "video-clip",
24
+ "canvas",
25
+ "ffmpeg",
26
+ "video",
27
+ "editor",
28
+ "mp4",
29
+ "component",
30
+ "framework-agnostic",
31
+ "capcut",
32
+ "premiere",
33
+ "final-cut",
34
+ "davinci",
35
+ "imovie",
36
+ "veed",
37
+ "filmora"
38
+ ],
6
39
  "type": "module",
7
40
  "sideEffects": [
8
41
  "./styles/*.css"