@effectnode/media 0.9.0 → 0.10.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.
Files changed (31) hide show
  1. package/dist/backend/movie-backend/agent/prompt/script.md +111 -1
  2. package/dist/backend/movie-backend/core.js +33 -0
  3. package/dist/backend/movie-backend/generation-queue.d.ts +1 -1
  4. package/dist/backend/movie-backend/generation-queue.js +75 -8
  5. package/dist/backend/movie-backend/render-media.d.ts +79 -2
  6. package/dist/backend/movie-backend/render-media.js +722 -418
  7. package/frontend/src/movie-app/components/EditorTabs/AdvancedVoiceCloneTab.tsx +366 -0
  8. package/frontend/src/movie-app/components/EditorTabs/AudioToVideoTab.tsx +406 -0
  9. package/frontend/src/movie-app/components/EditorTabs/FastImageEditTab.tsx +47 -0
  10. package/frontend/src/movie-app/components/EditorTabs/GenerateVideoTab.tsx +155 -1
  11. package/frontend/src/movie-app/components/EditorTabs/MovieStudioTab.tsx +33 -13
  12. package/frontend/src/movie-app/components/EditorTabs/SetupAiModelTab.tsx +26 -5
  13. package/frontend/src/movie-app/components/EditorTabs/UpscaleTab.tsx +342 -0
  14. package/frontend/src/movie-app/components/EditorTabs/VoiceCloneTab.tsx +365 -0
  15. package/frontend/src/movie-app/components/ProjectEditorPage.tsx +130 -125
  16. package/frontend/src/movie-app/stores/advancedVoiceCloneStore.ts +207 -0
  17. package/frontend/src/movie-app/stores/aiModelStore.ts +25 -2
  18. package/frontend/src/movie-app/stores/audioToVideoStore.ts +274 -0
  19. package/frontend/src/movie-app/stores/generationStore.ts +156 -255
  20. package/frontend/src/movie-app/stores/movieStudioStore.ts +10 -3
  21. package/frontend/src/movie-app/stores/queueStore.ts +47 -1
  22. package/frontend/src/movie-app/stores/upscaleStore.ts +118 -0
  23. package/frontend/src/movie-app/stores/voiceCloneStore.ts +227 -0
  24. package/package.json +1 -1
  25. package/frontend/src/movie-app/components/EditorTabs/BatchVoiceVideoTab.tsx +0 -913
  26. package/frontend/src/movie-app/components/EditorTabs/ExtendVideoTab.tsx +0 -305
  27. package/frontend/src/movie-app/components/EditorTabs/ExtractImageTab.tsx +0 -249
  28. package/frontend/src/movie-app/components/EditorTabs/SceneVisualTab.tsx +0 -267
  29. package/frontend/src/movie-app/lib/batchVoiceStorage.ts +0 -75
  30. package/frontend/src/movie-app/stores/batchVoiceStore.ts +0 -990
  31. package/frontend/src/movie-app/stores/sceneVisualStore.ts +0 -251
@@ -1,251 +0,0 @@
1
- import { create } from "zustand";
2
-
3
- const API_BASE = `http://localhost:${(window as any).PORT}`;
4
-
5
- export interface SceneVisualItem {
6
- id: string;
7
- prompt: string;
8
- generating: boolean;
9
- uploading: boolean;
10
- result: string | null;
11
- error: string | null;
12
- logs: string[];
13
- }
14
-
15
- interface SceneVisualStore {
16
- projectId: string | null;
17
- items: SceneVisualItem[];
18
- ensureProject: (projectId: string) => void;
19
- addItem: () => void;
20
- removeItem: (id: string) => void;
21
- setPrompt: (id: string, prompt: string) => void;
22
- generateItem: (projectId: string, id: string) => Promise<void>;
23
- uploadItemImage: (
24
- projectId: string,
25
- id: string,
26
- base64: string,
27
- filename: string,
28
- ) => Promise<void>;
29
- haltAll: () => void;
30
- }
31
-
32
- function makeId(): string {
33
- return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
34
- }
35
-
36
- async function readSSEStream(
37
- response: Response,
38
- onEvent: (event: string, data: any) => void,
39
- ): Promise<void> {
40
- const reader = response.body?.getReader();
41
- if (!reader) return;
42
-
43
- const decoder = new TextDecoder();
44
- let buffer = "";
45
-
46
- try {
47
- while (true) {
48
- const { done, value } = await reader.read();
49
- if (done) break;
50
-
51
- buffer += decoder.decode(value, { stream: true });
52
- const lines = buffer.split("\n");
53
- buffer = lines.pop() || "";
54
-
55
- let eventType = "message";
56
- for (const line of lines) {
57
- if (line.startsWith("event: ")) {
58
- eventType = line.slice(7).trim();
59
- } else if (line.startsWith("data: ")) {
60
- try {
61
- onEvent(eventType, JSON.parse(line.slice(6)));
62
- } catch {
63
- // skip malformed lines
64
- }
65
- eventType = "message";
66
- }
67
- }
68
- }
69
- } finally {
70
- reader.releaseLock();
71
- }
72
- }
73
-
74
- export const useSceneVisualStore = create<SceneVisualStore>((set, get) => ({
75
- projectId: null,
76
- items: [],
77
-
78
- ensureProject: (projectId) => {
79
- if (get().projectId !== projectId) {
80
- set({ projectId, items: [] });
81
- }
82
- },
83
-
84
- addItem: () =>
85
- set((s) => ({
86
- items: [
87
- ...s.items,
88
- {
89
- id: makeId(),
90
- prompt: "",
91
- generating: false,
92
- uploading: false,
93
- result: null,
94
- error: null,
95
- logs: [],
96
- },
97
- ],
98
- })),
99
-
100
- removeItem: (id) =>
101
- set((s) => ({ items: s.items.filter((i) => i.id !== id) })),
102
-
103
- setPrompt: (id, prompt) =>
104
- set((s) => ({
105
- items: s.items.map((i) =>
106
- i.id === id ? { ...i, prompt, error: null } : i,
107
- ),
108
- })),
109
-
110
- generateItem: async (projectId, id) => {
111
- const item = get().items.find((i) => i.id === id);
112
- if (!item || item.generating || !item.prompt.trim()) return;
113
-
114
- set((s) => ({
115
- items: s.items.map((i) =>
116
- i.id === id
117
- ? { ...i, generating: true, error: null, result: null, logs: [] }
118
- : i,
119
- ),
120
- }));
121
-
122
- try {
123
- const res = await fetch(`${API_BASE}/api/render/text-to-image`, {
124
- method: "POST",
125
- headers: { "Content-Type": "application/json" },
126
- body: JSON.stringify({
127
- prompt: item.prompt.trim(),
128
- projectId,
129
- aspect: "1:1",
130
- width: 1080,
131
- height: 1080,
132
- device: "mps",
133
- }),
134
- });
135
-
136
- if (!res.ok) {
137
- const err = await res.text();
138
- set((s) => ({
139
- items: s.items.map((i) =>
140
- i.id === id ? { ...i, generating: false, error: err } : i,
141
- ),
142
- }));
143
- return;
144
- }
145
-
146
- await readSSEStream(res, (event, data) => {
147
- switch (event) {
148
- case "log":
149
- set((s) => ({
150
- items: s.items.map((i) =>
151
- i.id === id
152
- ? { ...i, logs: [...i.logs, data.text as string] }
153
- : i,
154
- ),
155
- }));
156
- break;
157
- case "complete":
158
- set((s) => ({
159
- items: s.items.map((i) =>
160
- i.id === id
161
- ? {
162
- ...i,
163
- generating: false,
164
- result: `http://localhost:${(window as any).PORT}/api/files?path=${encodeURIComponent(data.path)}`,
165
- }
166
- : i,
167
- ),
168
- }));
169
- break;
170
- case "error":
171
- set((s) => ({
172
- items: s.items.map((i) =>
173
- i.id === id
174
- ? {
175
- ...i,
176
- generating: false,
177
- error: data.error || "Image generation failed",
178
- }
179
- : i,
180
- ),
181
- }));
182
- break;
183
- }
184
- });
185
- } catch (e) {
186
- set((s) => ({
187
- items: s.items.map((i) =>
188
- i.id === id ? { ...i, generating: false, error: String(e) } : i,
189
- ),
190
- }));
191
- }
192
- },
193
-
194
- uploadItemImage: async (projectId, id, base64, filename) => {
195
- set((s) => ({
196
- items: s.items.map((i) =>
197
- i.id === id ? { ...i, uploading: true, error: null } : i,
198
- ),
199
- }));
200
-
201
- try {
202
- const res = await fetch(`${API_BASE}/api/upload/image`, {
203
- method: "POST",
204
- headers: { "Content-Type": "application/json" },
205
- body: JSON.stringify({
206
- image: base64,
207
- filename: filename || `scene-${Date.now()}.png`,
208
- projectId,
209
- }),
210
- });
211
-
212
- if (!res.ok) {
213
- const err = await res.text();
214
- set((s) => ({
215
- items: s.items.map((i) =>
216
- i.id === id ? { ...i, uploading: false, error: err } : i,
217
- ),
218
- }));
219
- return;
220
- }
221
-
222
- const data = await res.json();
223
- set((s) => ({
224
- items: s.items.map((i) =>
225
- i.id === id
226
- ? {
227
- ...i,
228
- uploading: false,
229
- result: `http://localhost:${(window as any).PORT}/api/files?path=${encodeURIComponent(data.path)}`,
230
- }
231
- : i,
232
- ),
233
- }));
234
- } catch (e) {
235
- set((s) => ({
236
- items: s.items.map((i) =>
237
- i.id === id ? { ...i, uploading: false, error: String(e) } : i,
238
- ),
239
- }));
240
- }
241
- },
242
-
243
- haltAll: () => {
244
- set((s) => ({
245
- items: s.items.map((i) =>
246
- i.generating ? { ...i, generating: false } : i,
247
- ),
248
- }));
249
- fetch(`${API_BASE}/api/render/cancel`, { method: "POST" }).catch(() => {});
250
- },
251
- }));