@twick/studio 0.14.11 → 0.14.13
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/dist/components/container/properties-panel-container.d.ts +6 -2
- package/dist/components/properties/generate-subtitles.d.ts +13 -0
- package/dist/helpers/generate-subtitles.service.d.ts +21 -0
- package/dist/hooks/use-generate-subtitles.d.ts +9 -0
- package/dist/hooks/use-studio-operation.d.ts +5 -1
- package/dist/index.d.ts +22 -13
- package/dist/index.js +445 -86
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +445 -86
- package/dist/index.mjs.map +1 -1
- package/dist/studio.css +60 -0
- package/dist/types/index.d.ts +54 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -110,15 +110,49 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
110
110
|
* This source code is licensed under the ISC license.
|
|
111
111
|
* See the LICENSE file in the root directory of this source tree.
|
|
112
112
|
*/
|
|
113
|
-
const __iconNode$
|
|
114
|
-
|
|
113
|
+
const __iconNode$s = [
|
|
114
|
+
["rect", { width: "18", height: "14", x: "3", y: "5", rx: "2", ry: "2", key: "12ruh7" }],
|
|
115
|
+
["path", { d: "M7 15h4M15 15h2M7 11h2M13 11h4", key: "1ueiar" }]
|
|
116
|
+
];
|
|
117
|
+
const Captions = createLucideIcon("captions", __iconNode$s);
|
|
115
118
|
/**
|
|
116
119
|
* @license lucide-react v0.511.0 - ISC
|
|
117
120
|
*
|
|
118
121
|
* This source code is licensed under the ISC license.
|
|
119
122
|
* See the LICENSE file in the root directory of this source tree.
|
|
120
123
|
*/
|
|
121
|
-
const __iconNode$
|
|
124
|
+
const __iconNode$r = [
|
|
125
|
+
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
126
|
+
["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
|
|
127
|
+
];
|
|
128
|
+
const CircleCheck = createLucideIcon("circle-check", __iconNode$r);
|
|
129
|
+
/**
|
|
130
|
+
* @license lucide-react v0.511.0 - ISC
|
|
131
|
+
*
|
|
132
|
+
* This source code is licensed under the ISC license.
|
|
133
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
134
|
+
*/
|
|
135
|
+
const __iconNode$q = [
|
|
136
|
+
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
137
|
+
["path", { d: "m15 9-6 6", key: "1uzhvr" }],
|
|
138
|
+
["path", { d: "m9 9 6 6", key: "z0biqf" }]
|
|
139
|
+
];
|
|
140
|
+
const CircleX = createLucideIcon("circle-x", __iconNode$q);
|
|
141
|
+
/**
|
|
142
|
+
* @license lucide-react v0.511.0 - ISC
|
|
143
|
+
*
|
|
144
|
+
* This source code is licensed under the ISC license.
|
|
145
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
146
|
+
*/
|
|
147
|
+
const __iconNode$p = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
|
|
148
|
+
const Circle = createLucideIcon("circle", __iconNode$p);
|
|
149
|
+
/**
|
|
150
|
+
* @license lucide-react v0.511.0 - ISC
|
|
151
|
+
*
|
|
152
|
+
* This source code is licensed under the ISC license.
|
|
153
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
154
|
+
*/
|
|
155
|
+
const __iconNode$o = [
|
|
122
156
|
[
|
|
123
157
|
"path",
|
|
124
158
|
{ d: "M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3Z", key: "1tn4o7" }
|
|
@@ -127,119 +161,119 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
127
161
|
["path", { d: "m12.4 3.4 3.1 4", key: "6hsd6n" }],
|
|
128
162
|
["path", { d: "M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z", key: "ltgou9" }]
|
|
129
163
|
];
|
|
130
|
-
const Clapperboard = createLucideIcon("clapperboard", __iconNode$
|
|
164
|
+
const Clapperboard = createLucideIcon("clapperboard", __iconNode$o);
|
|
131
165
|
/**
|
|
132
166
|
* @license lucide-react v0.511.0 - ISC
|
|
133
167
|
*
|
|
134
168
|
* This source code is licensed under the ISC license.
|
|
135
169
|
* See the LICENSE file in the root directory of this source tree.
|
|
136
170
|
*/
|
|
137
|
-
const __iconNode$
|
|
171
|
+
const __iconNode$n = [
|
|
138
172
|
["path", { d: "M12 15V3", key: "m9g1x1" }],
|
|
139
173
|
["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
|
|
140
174
|
["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
|
|
141
175
|
];
|
|
142
|
-
const Download = createLucideIcon("download", __iconNode$
|
|
176
|
+
const Download = createLucideIcon("download", __iconNode$n);
|
|
143
177
|
/**
|
|
144
178
|
* @license lucide-react v0.511.0 - ISC
|
|
145
179
|
*
|
|
146
180
|
* This source code is licensed under the ISC license.
|
|
147
181
|
* See the LICENSE file in the root directory of this source tree.
|
|
148
182
|
*/
|
|
149
|
-
const __iconNode$
|
|
183
|
+
const __iconNode$m = [
|
|
150
184
|
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
151
185
|
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }]
|
|
152
186
|
];
|
|
153
|
-
const File = createLucideIcon("file", __iconNode$
|
|
187
|
+
const File = createLucideIcon("file", __iconNode$m);
|
|
154
188
|
/**
|
|
155
189
|
* @license lucide-react v0.511.0 - ISC
|
|
156
190
|
*
|
|
157
191
|
* This source code is licensed under the ISC license.
|
|
158
192
|
* See the LICENSE file in the root directory of this source tree.
|
|
159
193
|
*/
|
|
160
|
-
const __iconNode$
|
|
194
|
+
const __iconNode$l = [
|
|
161
195
|
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
|
|
162
196
|
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
|
|
163
197
|
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
|
|
164
198
|
];
|
|
165
|
-
const Image = createLucideIcon("image", __iconNode$
|
|
199
|
+
const Image = createLucideIcon("image", __iconNode$l);
|
|
166
200
|
/**
|
|
167
201
|
* @license lucide-react v0.511.0 - ISC
|
|
168
202
|
*
|
|
169
203
|
* This source code is licensed under the ISC license.
|
|
170
204
|
* See the LICENSE file in the root directory of this source tree.
|
|
171
205
|
*/
|
|
172
|
-
const __iconNode$
|
|
206
|
+
const __iconNode$k = [
|
|
173
207
|
["path", { d: "M6 16c5 0 7-8 12-8a4 4 0 0 1 0 8c-5 0-7-8-12-8a4 4 0 1 0 0 8", key: "18ogeb" }]
|
|
174
208
|
];
|
|
175
|
-
const Infinity = createLucideIcon("infinity", __iconNode$
|
|
209
|
+
const Infinity = createLucideIcon("infinity", __iconNode$k);
|
|
176
210
|
/**
|
|
177
211
|
* @license lucide-react v0.511.0 - ISC
|
|
178
212
|
*
|
|
179
213
|
* This source code is licensed under the ISC license.
|
|
180
214
|
* See the LICENSE file in the root directory of this source tree.
|
|
181
215
|
*/
|
|
182
|
-
const __iconNode$
|
|
183
|
-
const LoaderCircle = createLucideIcon("loader-circle", __iconNode$
|
|
216
|
+
const __iconNode$j = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
|
|
217
|
+
const LoaderCircle = createLucideIcon("loader-circle", __iconNode$j);
|
|
184
218
|
/**
|
|
185
219
|
* @license lucide-react v0.511.0 - ISC
|
|
186
220
|
*
|
|
187
221
|
* This source code is licensed under the ISC license.
|
|
188
222
|
* See the LICENSE file in the root directory of this source tree.
|
|
189
223
|
*/
|
|
190
|
-
const __iconNode$
|
|
224
|
+
const __iconNode$i = [
|
|
191
225
|
["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z", key: "1lielz" }]
|
|
192
226
|
];
|
|
193
|
-
const MessageSquare = createLucideIcon("message-square", __iconNode$
|
|
227
|
+
const MessageSquare = createLucideIcon("message-square", __iconNode$i);
|
|
194
228
|
/**
|
|
195
229
|
* @license lucide-react v0.511.0 - ISC
|
|
196
230
|
*
|
|
197
231
|
* This source code is licensed under the ISC license.
|
|
198
232
|
* See the LICENSE file in the root directory of this source tree.
|
|
199
233
|
*/
|
|
200
|
-
const __iconNode$
|
|
234
|
+
const __iconNode$h = [
|
|
201
235
|
["path", { d: "M9 18V5l12-2v13", key: "1jmyc2" }],
|
|
202
236
|
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
|
|
203
237
|
["circle", { cx: "18", cy: "16", r: "3", key: "1hluhg" }]
|
|
204
238
|
];
|
|
205
|
-
const Music = createLucideIcon("music", __iconNode$
|
|
239
|
+
const Music = createLucideIcon("music", __iconNode$h);
|
|
206
240
|
/**
|
|
207
241
|
* @license lucide-react v0.511.0 - ISC
|
|
208
242
|
*
|
|
209
243
|
* This source code is licensed under the ISC license.
|
|
210
244
|
* See the LICENSE file in the root directory of this source tree.
|
|
211
245
|
*/
|
|
212
|
-
const __iconNode$
|
|
246
|
+
const __iconNode$g = [
|
|
213
247
|
["rect", { x: "14", y: "4", width: "4", height: "16", rx: "1", key: "zuxfzm" }],
|
|
214
248
|
["rect", { x: "6", y: "4", width: "4", height: "16", rx: "1", key: "1okwgv" }]
|
|
215
249
|
];
|
|
216
|
-
const Pause = createLucideIcon("pause", __iconNode$
|
|
250
|
+
const Pause = createLucideIcon("pause", __iconNode$g);
|
|
217
251
|
/**
|
|
218
252
|
* @license lucide-react v0.511.0 - ISC
|
|
219
253
|
*
|
|
220
254
|
* This source code is licensed under the ISC license.
|
|
221
255
|
* See the LICENSE file in the root directory of this source tree.
|
|
222
256
|
*/
|
|
223
|
-
const __iconNode$
|
|
224
|
-
const Play = createLucideIcon("play", __iconNode$
|
|
257
|
+
const __iconNode$f = [["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]];
|
|
258
|
+
const Play = createLucideIcon("play", __iconNode$f);
|
|
225
259
|
/**
|
|
226
260
|
* @license lucide-react v0.511.0 - ISC
|
|
227
261
|
*
|
|
228
262
|
* This source code is licensed under the ISC license.
|
|
229
263
|
* See the LICENSE file in the root directory of this source tree.
|
|
230
264
|
*/
|
|
231
|
-
const __iconNode$
|
|
265
|
+
const __iconNode$e = [
|
|
232
266
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
233
267
|
["path", { d: "M12 5v14", key: "s699le" }]
|
|
234
268
|
];
|
|
235
|
-
const Plus = createLucideIcon("plus", __iconNode$
|
|
269
|
+
const Plus = createLucideIcon("plus", __iconNode$e);
|
|
236
270
|
/**
|
|
237
271
|
* @license lucide-react v0.511.0 - ISC
|
|
238
272
|
*
|
|
239
273
|
* This source code is licensed under the ISC license.
|
|
240
274
|
* See the LICENSE file in the root directory of this source tree.
|
|
241
275
|
*/
|
|
242
|
-
const __iconNode$
|
|
276
|
+
const __iconNode$d = [
|
|
243
277
|
[
|
|
244
278
|
"path",
|
|
245
279
|
{
|
|
@@ -250,39 +284,39 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
250
284
|
["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
|
|
251
285
|
["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
|
|
252
286
|
];
|
|
253
|
-
const Save = createLucideIcon("save", __iconNode$
|
|
287
|
+
const Save = createLucideIcon("save", __iconNode$d);
|
|
254
288
|
/**
|
|
255
289
|
* @license lucide-react v0.511.0 - ISC
|
|
256
290
|
*
|
|
257
291
|
* This source code is licensed under the ISC license.
|
|
258
292
|
* See the LICENSE file in the root directory of this source tree.
|
|
259
293
|
*/
|
|
260
|
-
const __iconNode$
|
|
294
|
+
const __iconNode$c = [
|
|
261
295
|
["circle", { cx: "6", cy: "6", r: "3", key: "1lh9wr" }],
|
|
262
296
|
["path", { d: "M8.12 8.12 12 12", key: "1alkpv" }],
|
|
263
297
|
["path", { d: "M20 4 8.12 15.88", key: "xgtan2" }],
|
|
264
298
|
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
|
|
265
299
|
["path", { d: "M14.8 14.8 20 20", key: "ptml3r" }]
|
|
266
300
|
];
|
|
267
|
-
const Scissors = createLucideIcon("scissors", __iconNode$
|
|
301
|
+
const Scissors = createLucideIcon("scissors", __iconNode$c);
|
|
268
302
|
/**
|
|
269
303
|
* @license lucide-react v0.511.0 - ISC
|
|
270
304
|
*
|
|
271
305
|
* This source code is licensed under the ISC license.
|
|
272
306
|
* See the LICENSE file in the root directory of this source tree.
|
|
273
307
|
*/
|
|
274
|
-
const __iconNode$
|
|
308
|
+
const __iconNode$b = [
|
|
275
309
|
["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
|
|
276
310
|
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
|
|
277
311
|
];
|
|
278
|
-
const Search = createLucideIcon("search", __iconNode$
|
|
312
|
+
const Search = createLucideIcon("search", __iconNode$b);
|
|
279
313
|
/**
|
|
280
314
|
* @license lucide-react v0.511.0 - ISC
|
|
281
315
|
*
|
|
282
316
|
* This source code is licensed under the ISC license.
|
|
283
317
|
* See the LICENSE file in the root directory of this source tree.
|
|
284
318
|
*/
|
|
285
|
-
const __iconNode$
|
|
319
|
+
const __iconNode$a = [
|
|
286
320
|
[
|
|
287
321
|
"path",
|
|
288
322
|
{
|
|
@@ -292,14 +326,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
292
326
|
],
|
|
293
327
|
["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
|
|
294
328
|
];
|
|
295
|
-
const Settings = createLucideIcon("settings", __iconNode$
|
|
329
|
+
const Settings = createLucideIcon("settings", __iconNode$a);
|
|
296
330
|
/**
|
|
297
331
|
* @license lucide-react v0.511.0 - ISC
|
|
298
332
|
*
|
|
299
333
|
* This source code is licensed under the ISC license.
|
|
300
334
|
* See the LICENSE file in the root directory of this source tree.
|
|
301
335
|
*/
|
|
302
|
-
const __iconNode$
|
|
336
|
+
const __iconNode$9 = [
|
|
303
337
|
[
|
|
304
338
|
"path",
|
|
305
339
|
{
|
|
@@ -312,62 +346,62 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
312
346
|
["path", { d: "M4 17v2", key: "vumght" }],
|
|
313
347
|
["path", { d: "M5 18H3", key: "zchphs" }]
|
|
314
348
|
];
|
|
315
|
-
const Sparkles = createLucideIcon("sparkles", __iconNode$
|
|
349
|
+
const Sparkles = createLucideIcon("sparkles", __iconNode$9);
|
|
316
350
|
/**
|
|
317
351
|
* @license lucide-react v0.511.0 - ISC
|
|
318
352
|
*
|
|
319
353
|
* This source code is licensed under the ISC license.
|
|
320
354
|
* See the LICENSE file in the root directory of this source tree.
|
|
321
355
|
*/
|
|
322
|
-
const __iconNode$
|
|
356
|
+
const __iconNode$8 = [
|
|
323
357
|
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }]
|
|
324
358
|
];
|
|
325
|
-
const Square = createLucideIcon("square", __iconNode$
|
|
359
|
+
const Square = createLucideIcon("square", __iconNode$8);
|
|
326
360
|
/**
|
|
327
361
|
* @license lucide-react v0.511.0 - ISC
|
|
328
362
|
*
|
|
329
363
|
* This source code is licensed under the ISC license.
|
|
330
364
|
* See the LICENSE file in the root directory of this source tree.
|
|
331
365
|
*/
|
|
332
|
-
const __iconNode$
|
|
366
|
+
const __iconNode$7 = [
|
|
333
367
|
["path", { d: "M3 6h18", key: "d0wm0j" }],
|
|
334
368
|
["path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6", key: "4alrt4" }],
|
|
335
369
|
["path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2", key: "v07s0e" }],
|
|
336
370
|
["line", { x1: "10", x2: "10", y1: "11", y2: "17", key: "1uufr5" }],
|
|
337
371
|
["line", { x1: "14", x2: "14", y1: "11", y2: "17", key: "xtxkd" }]
|
|
338
372
|
];
|
|
339
|
-
const Trash2 = createLucideIcon("trash-2", __iconNode$
|
|
373
|
+
const Trash2 = createLucideIcon("trash-2", __iconNode$7);
|
|
340
374
|
/**
|
|
341
375
|
* @license lucide-react v0.511.0 - ISC
|
|
342
376
|
*
|
|
343
377
|
* This source code is licensed under the ISC license.
|
|
344
378
|
* See the LICENSE file in the root directory of this source tree.
|
|
345
379
|
*/
|
|
346
|
-
const __iconNode$
|
|
380
|
+
const __iconNode$6 = [
|
|
347
381
|
["path", { d: "M12 4v16", key: "1654pz" }],
|
|
348
382
|
["path", { d: "M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2", key: "e0r10z" }],
|
|
349
383
|
["path", { d: "M9 20h6", key: "s66wpe" }]
|
|
350
384
|
];
|
|
351
|
-
const Type = createLucideIcon("type", __iconNode$
|
|
385
|
+
const Type = createLucideIcon("type", __iconNode$6);
|
|
352
386
|
/**
|
|
353
387
|
* @license lucide-react v0.511.0 - ISC
|
|
354
388
|
*
|
|
355
389
|
* This source code is licensed under the ISC license.
|
|
356
390
|
* See the LICENSE file in the root directory of this source tree.
|
|
357
391
|
*/
|
|
358
|
-
const __iconNode$
|
|
392
|
+
const __iconNode$5 = [
|
|
359
393
|
["path", { d: "M12 3v12", key: "1x0j5s" }],
|
|
360
394
|
["path", { d: "m17 8-5-5-5 5", key: "7q97r8" }],
|
|
361
395
|
["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }]
|
|
362
396
|
];
|
|
363
|
-
const Upload = createLucideIcon("upload", __iconNode$
|
|
397
|
+
const Upload = createLucideIcon("upload", __iconNode$5);
|
|
364
398
|
/**
|
|
365
399
|
* @license lucide-react v0.511.0 - ISC
|
|
366
400
|
*
|
|
367
401
|
* This source code is licensed under the ISC license.
|
|
368
402
|
* See the LICENSE file in the root directory of this source tree.
|
|
369
403
|
*/
|
|
370
|
-
const __iconNode$
|
|
404
|
+
const __iconNode$4 = [
|
|
371
405
|
[
|
|
372
406
|
"path",
|
|
373
407
|
{
|
|
@@ -377,14 +411,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
377
411
|
],
|
|
378
412
|
["rect", { x: "2", y: "6", width: "14", height: "12", rx: "2", key: "158x01" }]
|
|
379
413
|
];
|
|
380
|
-
const Video = createLucideIcon("video", __iconNode$
|
|
414
|
+
const Video = createLucideIcon("video", __iconNode$4);
|
|
381
415
|
/**
|
|
382
416
|
* @license lucide-react v0.511.0 - ISC
|
|
383
417
|
*
|
|
384
418
|
* This source code is licensed under the ISC license.
|
|
385
419
|
* See the LICENSE file in the root directory of this source tree.
|
|
386
420
|
*/
|
|
387
|
-
const __iconNode$
|
|
421
|
+
const __iconNode$3 = [
|
|
388
422
|
[
|
|
389
423
|
"path",
|
|
390
424
|
{
|
|
@@ -395,7 +429,25 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
395
429
|
["path", { d: "M16 9a5 5 0 0 1 0 6", key: "1q6k2b" }],
|
|
396
430
|
["path", { d: "M19.364 18.364a9 9 0 0 0 0-12.728", key: "ijwkga" }]
|
|
397
431
|
];
|
|
398
|
-
const Volume2 = createLucideIcon("volume-2", __iconNode$
|
|
432
|
+
const Volume2 = createLucideIcon("volume-2", __iconNode$3);
|
|
433
|
+
/**
|
|
434
|
+
* @license lucide-react v0.511.0 - ISC
|
|
435
|
+
*
|
|
436
|
+
* This source code is licensed under the ISC license.
|
|
437
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
438
|
+
*/
|
|
439
|
+
const __iconNode$2 = [
|
|
440
|
+
[
|
|
441
|
+
"path",
|
|
442
|
+
{
|
|
443
|
+
d: "M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",
|
|
444
|
+
key: "uqj9uw"
|
|
445
|
+
}
|
|
446
|
+
],
|
|
447
|
+
["line", { x1: "22", x2: "16", y1: "9", y2: "15", key: "1ewh16" }],
|
|
448
|
+
["line", { x1: "16", x2: "22", y1: "9", y2: "15", key: "5ykzw1" }]
|
|
449
|
+
];
|
|
450
|
+
const VolumeX = createLucideIcon("volume-x", __iconNode$2);
|
|
399
451
|
/**
|
|
400
452
|
* @license lucide-react v0.511.0 - ISC
|
|
401
453
|
*
|
|
@@ -2664,6 +2716,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2664
2716
|
icon: "MessageSquare",
|
|
2665
2717
|
description: "Subtitle Style"
|
|
2666
2718
|
}
|
|
2719
|
+
],
|
|
2720
|
+
[
|
|
2721
|
+
"generate-subtitles",
|
|
2722
|
+
{
|
|
2723
|
+
id: "generate-subtitles",
|
|
2724
|
+
name: "Generate Subtitles",
|
|
2725
|
+
icon: "Subtitles",
|
|
2726
|
+
description: "Generate Subtitles"
|
|
2727
|
+
}
|
|
2667
2728
|
]
|
|
2668
2729
|
]);
|
|
2669
2730
|
const getIcon = (iconName) => {
|
|
@@ -2676,6 +2737,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2676
2737
|
return Image;
|
|
2677
2738
|
case "Music":
|
|
2678
2739
|
return Music;
|
|
2740
|
+
case "Subtitles":
|
|
2741
|
+
return Captions;
|
|
2679
2742
|
case "MessageSquare":
|
|
2680
2743
|
return MessageSquare;
|
|
2681
2744
|
case "Settings":
|
|
@@ -2708,6 +2771,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2708
2771
|
sections.push(propsCategories.get("animations"));
|
|
2709
2772
|
sections.push(propsCategories.get("color-effects"));
|
|
2710
2773
|
sections.push(propsCategories.get("playback-props"));
|
|
2774
|
+
sections.push(propsCategories.get("generate-subtitles"));
|
|
2711
2775
|
} else if (selectedElement instanceof timeline.AudioElement) {
|
|
2712
2776
|
sections.push(propsCategories.get("element-props"));
|
|
2713
2777
|
sections.push(propsCategories.get("playback-props"));
|
|
@@ -3145,10 +3209,250 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3145
3209
|
] })
|
|
3146
3210
|
] });
|
|
3147
3211
|
}
|
|
3212
|
+
const hasAudio = async (src) => {
|
|
3213
|
+
if (!src) return false;
|
|
3214
|
+
const isSafeUrl = /^(https?:|blob:|data:)/i.test(src);
|
|
3215
|
+
if (!isSafeUrl) return false;
|
|
3216
|
+
try {
|
|
3217
|
+
const audioBuffer = await fetchAndDecodeAudio(src);
|
|
3218
|
+
if (audioBuffer.duration === 0 || audioBuffer.length === 0) {
|
|
3219
|
+
return false;
|
|
3220
|
+
}
|
|
3221
|
+
if (isAudioSilent(audioBuffer)) {
|
|
3222
|
+
return false;
|
|
3223
|
+
}
|
|
3224
|
+
return true;
|
|
3225
|
+
} catch (error) {
|
|
3226
|
+
return false;
|
|
3227
|
+
}
|
|
3228
|
+
};
|
|
3229
|
+
const fetchAndDecodeAudio = async (src) => {
|
|
3230
|
+
const response = await fetch(src);
|
|
3231
|
+
if (!response.ok) throw new Error(`Failed to fetch source: ${response.status}`);
|
|
3232
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
3233
|
+
return decodeAudioData(arrayBuffer);
|
|
3234
|
+
};
|
|
3235
|
+
const decodeAudioData = async (arrayBuffer) => {
|
|
3236
|
+
const AudioContextCtor = window.AudioContext || window.webkitAudioContext;
|
|
3237
|
+
if (!AudioContextCtor) throw new Error("Web Audio API not supported");
|
|
3238
|
+
const audioContext = new AudioContextCtor();
|
|
3239
|
+
try {
|
|
3240
|
+
return await new Promise((resolve, reject) => {
|
|
3241
|
+
audioContext.decodeAudioData(
|
|
3242
|
+
arrayBuffer.slice(0),
|
|
3243
|
+
(buf) => resolve(buf),
|
|
3244
|
+
(err) => reject(err || new Error("Failed to decode audio: no audio track found or unsupported format"))
|
|
3245
|
+
);
|
|
3246
|
+
});
|
|
3247
|
+
} finally {
|
|
3248
|
+
audioContext.close();
|
|
3249
|
+
}
|
|
3250
|
+
};
|
|
3251
|
+
const isAudioSilent = (buffer, threshold = 1e-3) => {
|
|
3252
|
+
for (let channel = 0; channel < buffer.numberOfChannels; channel++) {
|
|
3253
|
+
const channelData = buffer.getChannelData(channel);
|
|
3254
|
+
for (let i = 0; i < channelData.length; i += 100) {
|
|
3255
|
+
if (Math.abs(channelData[i]) > threshold) {
|
|
3256
|
+
return false;
|
|
3257
|
+
}
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3260
|
+
return true;
|
|
3261
|
+
};
|
|
3262
|
+
const loadFile = (accept) => {
|
|
3263
|
+
return new Promise((resolve, reject) => {
|
|
3264
|
+
try {
|
|
3265
|
+
const input = document.createElement("input");
|
|
3266
|
+
input.type = "file";
|
|
3267
|
+
input.accept = accept;
|
|
3268
|
+
input.style.display = "none";
|
|
3269
|
+
document.body.appendChild(input);
|
|
3270
|
+
const cleanup = () => {
|
|
3271
|
+
input.value = "";
|
|
3272
|
+
document.body.removeChild(input);
|
|
3273
|
+
};
|
|
3274
|
+
input.onchange = () => {
|
|
3275
|
+
const file = input.files && input.files[0];
|
|
3276
|
+
cleanup();
|
|
3277
|
+
if (!file) {
|
|
3278
|
+
reject(new Error("No file selected"));
|
|
3279
|
+
return;
|
|
3280
|
+
}
|
|
3281
|
+
resolve(file);
|
|
3282
|
+
};
|
|
3283
|
+
input.click();
|
|
3284
|
+
} catch (error) {
|
|
3285
|
+
reject(error);
|
|
3286
|
+
}
|
|
3287
|
+
});
|
|
3288
|
+
};
|
|
3289
|
+
const saveAsFile = (content, type, name) => {
|
|
3290
|
+
const blob = typeof content === "string" ? new Blob([content], { type }) : content;
|
|
3291
|
+
const url = URL.createObjectURL(blob);
|
|
3292
|
+
const a = document.createElement("a");
|
|
3293
|
+
a.href = url;
|
|
3294
|
+
a.download = name;
|
|
3295
|
+
a.click();
|
|
3296
|
+
URL.revokeObjectURL(url);
|
|
3297
|
+
};
|
|
3298
|
+
function GenerateSubtitlesPanel({
|
|
3299
|
+
selectedElement,
|
|
3300
|
+
addSubtitlesToTimeline,
|
|
3301
|
+
onGenerateSubtitles,
|
|
3302
|
+
getSubtitleStatus
|
|
3303
|
+
}) {
|
|
3304
|
+
const [containsAudio, setContainsAudio] = react.useState(null);
|
|
3305
|
+
const [isLoading, setIsLoading] = react.useState(true);
|
|
3306
|
+
const [isGenerating, setIsGenerating] = react.useState(false);
|
|
3307
|
+
const [pollingStatus, setPollingStatus] = react.useState("idle");
|
|
3308
|
+
const [errorMessage, setErrorMessage] = react.useState(null);
|
|
3309
|
+
const pollingIntervalRef = react.useRef(null);
|
|
3310
|
+
const currentReqIdRef = react.useRef(null);
|
|
3311
|
+
react.useEffect(() => {
|
|
3312
|
+
return () => {
|
|
3313
|
+
if (pollingIntervalRef.current) {
|
|
3314
|
+
clearInterval(pollingIntervalRef.current);
|
|
3315
|
+
}
|
|
3316
|
+
};
|
|
3317
|
+
}, []);
|
|
3318
|
+
const stopPolling = () => {
|
|
3319
|
+
if (pollingIntervalRef.current) {
|
|
3320
|
+
clearInterval(pollingIntervalRef.current);
|
|
3321
|
+
pollingIntervalRef.current = null;
|
|
3322
|
+
}
|
|
3323
|
+
};
|
|
3324
|
+
const startPolling = async (reqId) => {
|
|
3325
|
+
if (!getSubtitleStatus) {
|
|
3326
|
+
return;
|
|
3327
|
+
}
|
|
3328
|
+
setPollingStatus("polling");
|
|
3329
|
+
setIsGenerating(true);
|
|
3330
|
+
setErrorMessage(null);
|
|
3331
|
+
const poll = async () => {
|
|
3332
|
+
try {
|
|
3333
|
+
const response = await getSubtitleStatus(reqId);
|
|
3334
|
+
if (response.status === "completed") {
|
|
3335
|
+
stopPolling();
|
|
3336
|
+
setPollingStatus("success");
|
|
3337
|
+
setIsGenerating(false);
|
|
3338
|
+
addSubtitlesToTimeline(response.subtitles || []);
|
|
3339
|
+
setTimeout(() => {
|
|
3340
|
+
setPollingStatus("idle");
|
|
3341
|
+
}, 3e3);
|
|
3342
|
+
} else if (response.status === "pending") {
|
|
3343
|
+
} else if (response.status === "failed") {
|
|
3344
|
+
stopPolling();
|
|
3345
|
+
setPollingStatus("error");
|
|
3346
|
+
setIsGenerating(false);
|
|
3347
|
+
setErrorMessage(response.error || "Failed to generate subtitles");
|
|
3348
|
+
console.error("Error generating subtitles:", response.error);
|
|
3349
|
+
}
|
|
3350
|
+
} catch (error) {
|
|
3351
|
+
stopPolling();
|
|
3352
|
+
setPollingStatus("error");
|
|
3353
|
+
setIsGenerating(false);
|
|
3354
|
+
setErrorMessage(error instanceof Error ? error.message : "Failed to get subtitle status");
|
|
3355
|
+
console.error("Error polling for subtitles:", error);
|
|
3356
|
+
}
|
|
3357
|
+
};
|
|
3358
|
+
await poll();
|
|
3359
|
+
pollingIntervalRef.current = setInterval(poll, 2e3);
|
|
3360
|
+
};
|
|
3361
|
+
const handleGenerateSubtitles = async () => {
|
|
3362
|
+
if (!(selectedElement instanceof timeline.VideoElement)) {
|
|
3363
|
+
return;
|
|
3364
|
+
}
|
|
3365
|
+
const videoElement = selectedElement;
|
|
3366
|
+
try {
|
|
3367
|
+
const reqId = await onGenerateSubtitles(videoElement);
|
|
3368
|
+
if (!reqId) {
|
|
3369
|
+
setPollingStatus("error");
|
|
3370
|
+
setIsGenerating(false);
|
|
3371
|
+
setErrorMessage("Failed to start subtitle generation");
|
|
3372
|
+
console.error("Error generating subtitles: Failed to start subtitle generation");
|
|
3373
|
+
return;
|
|
3374
|
+
}
|
|
3375
|
+
currentReqIdRef.current = reqId;
|
|
3376
|
+
await startPolling(reqId);
|
|
3377
|
+
} catch (error) {
|
|
3378
|
+
setPollingStatus("error");
|
|
3379
|
+
setIsGenerating(false);
|
|
3380
|
+
setErrorMessage(error instanceof Error ? error.message : "Failed to start subtitle generation");
|
|
3381
|
+
console.error("Error generating subtitles:", error);
|
|
3382
|
+
}
|
|
3383
|
+
};
|
|
3384
|
+
const checkAudio = async () => {
|
|
3385
|
+
setIsLoading(true);
|
|
3386
|
+
if (selectedElement instanceof timeline.VideoElement) {
|
|
3387
|
+
const videoElement = selectedElement;
|
|
3388
|
+
const videoUrl = videoElement.getSrc();
|
|
3389
|
+
if (videoUrl) {
|
|
3390
|
+
try {
|
|
3391
|
+
const hasAudioTrack = await hasAudio(videoUrl);
|
|
3392
|
+
setContainsAudio(hasAudioTrack);
|
|
3393
|
+
} catch (error) {
|
|
3394
|
+
console.error("Error checking audio:", error);
|
|
3395
|
+
setContainsAudio(false);
|
|
3396
|
+
}
|
|
3397
|
+
} else {
|
|
3398
|
+
setContainsAudio(false);
|
|
3399
|
+
}
|
|
3400
|
+
} else {
|
|
3401
|
+
setContainsAudio(false);
|
|
3402
|
+
}
|
|
3403
|
+
setIsLoading(false);
|
|
3404
|
+
};
|
|
3405
|
+
react.useEffect(() => {
|
|
3406
|
+
checkAudio();
|
|
3407
|
+
stopPolling();
|
|
3408
|
+
setPollingStatus("idle");
|
|
3409
|
+
setIsGenerating(false);
|
|
3410
|
+
setErrorMessage(null);
|
|
3411
|
+
}, [selectedElement]);
|
|
3412
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-container", children: [
|
|
3413
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-title", children: "Generate Subtitles Panel" }),
|
|
3414
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-state-content", children: [
|
|
3415
|
+
/* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { className: "empty-state-icon animate-spin" }),
|
|
3416
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-text", children: "Checking for audio..." })
|
|
3417
|
+
] }) }) }),
|
|
3418
|
+
!isLoading && containsAudio === false && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-state-content", children: [
|
|
3419
|
+
/* @__PURE__ */ jsxRuntime.jsx(VolumeX, { className: "empty-state-icon" }),
|
|
3420
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-text", children: "No audio track found in this video" })
|
|
3421
|
+
] }) }) }),
|
|
3422
|
+
!isLoading && containsAudio === true && pollingStatus === "idle" && !isGenerating && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-state-content", children: [
|
|
3423
|
+
/* @__PURE__ */ jsxRuntime.jsx(Volume2, { className: "empty-state-icon" }),
|
|
3424
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-text", children: "Audio detected! You can now generate subtitles" })
|
|
3425
|
+
] }) }) }),
|
|
3426
|
+
!isLoading && isGenerating && pollingStatus === "polling" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-state-content", children: [
|
|
3427
|
+
/* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { className: "empty-state-icon animate-spin" }),
|
|
3428
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-text", children: "Generating subtitles... Please wait" })
|
|
3429
|
+
] }) }) }),
|
|
3430
|
+
!isLoading && pollingStatus === "success" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-state-content", children: [
|
|
3431
|
+
/* @__PURE__ */ jsxRuntime.jsx(CircleCheck, { className: "empty-state-icon", color: "var(--color-green-500)" }),
|
|
3432
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-text", children: "Subtitles generated successfully!" })
|
|
3433
|
+
] }) }) }),
|
|
3434
|
+
!isLoading && pollingStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-state-content", children: [
|
|
3435
|
+
/* @__PURE__ */ jsxRuntime.jsx(CircleX, { className: "empty-state-icon", color: "var(--color-red-500)" }),
|
|
3436
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-text", children: errorMessage || "Failed to generate subtitles" })
|
|
3437
|
+
] }) }) }),
|
|
3438
|
+
!isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex panel-section", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3439
|
+
"button",
|
|
3440
|
+
{
|
|
3441
|
+
onClick: handleGenerateSubtitles,
|
|
3442
|
+
disabled: !containsAudio || isGenerating,
|
|
3443
|
+
className: "btn-primary w-full",
|
|
3444
|
+
children: isGenerating ? "Generating..." : "Generate Subtitles"
|
|
3445
|
+
}
|
|
3446
|
+
) })
|
|
3447
|
+
] });
|
|
3448
|
+
}
|
|
3148
3449
|
function PropertiesPanelContainer({
|
|
3149
3450
|
selectedProp,
|
|
3150
3451
|
selectedElement,
|
|
3151
|
-
updateElement
|
|
3452
|
+
updateElement,
|
|
3453
|
+
addSubtitlesToTimeline,
|
|
3454
|
+
onGenerateSubtitles,
|
|
3455
|
+
getSubtitleStatus
|
|
3152
3456
|
}) {
|
|
3153
3457
|
if (!selectedElement) {
|
|
3154
3458
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-container", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "properties-header", children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "properties-title", children: "Select Element to see properties" }) }) });
|
|
@@ -3184,45 +3488,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3184
3488
|
selectedElement,
|
|
3185
3489
|
updateElement
|
|
3186
3490
|
}
|
|
3491
|
+
),
|
|
3492
|
+
selectedProp === "generate-subtitles" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3493
|
+
GenerateSubtitlesPanel,
|
|
3494
|
+
{
|
|
3495
|
+
selectedElement,
|
|
3496
|
+
addSubtitlesToTimeline,
|
|
3497
|
+
onGenerateSubtitles,
|
|
3498
|
+
getSubtitleStatus
|
|
3499
|
+
}
|
|
3187
3500
|
)
|
|
3188
3501
|
] });
|
|
3189
3502
|
}
|
|
3190
|
-
const loadFile = (accept) => {
|
|
3191
|
-
return new Promise((resolve, reject) => {
|
|
3192
|
-
try {
|
|
3193
|
-
const input = document.createElement("input");
|
|
3194
|
-
input.type = "file";
|
|
3195
|
-
input.accept = accept;
|
|
3196
|
-
input.style.display = "none";
|
|
3197
|
-
document.body.appendChild(input);
|
|
3198
|
-
const cleanup = () => {
|
|
3199
|
-
input.value = "";
|
|
3200
|
-
document.body.removeChild(input);
|
|
3201
|
-
};
|
|
3202
|
-
input.onchange = () => {
|
|
3203
|
-
const file = input.files && input.files[0];
|
|
3204
|
-
cleanup();
|
|
3205
|
-
if (!file) {
|
|
3206
|
-
reject(new Error("No file selected"));
|
|
3207
|
-
return;
|
|
3208
|
-
}
|
|
3209
|
-
resolve(file);
|
|
3210
|
-
};
|
|
3211
|
-
input.click();
|
|
3212
|
-
} catch (error) {
|
|
3213
|
-
reject(error);
|
|
3214
|
-
}
|
|
3215
|
-
});
|
|
3216
|
-
};
|
|
3217
|
-
const saveAsFile = (content, type, name) => {
|
|
3218
|
-
const blob = typeof content === "string" ? new Blob([content], { type }) : content;
|
|
3219
|
-
const url = URL.createObjectURL(blob);
|
|
3220
|
-
const a = document.createElement("a");
|
|
3221
|
-
a.href = url;
|
|
3222
|
-
a.download = name;
|
|
3223
|
-
a.click();
|
|
3224
|
-
URL.revokeObjectURL(url);
|
|
3225
|
-
};
|
|
3226
3503
|
const useStudioOperation = (studioConfig) => {
|
|
3227
3504
|
const { editor, present } = timeline.useTimelineContext();
|
|
3228
3505
|
const [projectName, setProjectName] = react.useState("");
|
|
@@ -3276,7 +3553,79 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3276
3553
|
alert("Export video not supported in demo mode");
|
|
3277
3554
|
}
|
|
3278
3555
|
};
|
|
3279
|
-
|
|
3556
|
+
const onGenerateSubtitles = async (videoElement) => {
|
|
3557
|
+
if (studioConfig == null ? void 0 : studioConfig.subtitleGenerationService) {
|
|
3558
|
+
const service = studioConfig.subtitleGenerationService;
|
|
3559
|
+
const reqId = await service.generateSubtitles(videoElement, present);
|
|
3560
|
+
return reqId;
|
|
3561
|
+
}
|
|
3562
|
+
alert("Generate subtitles not supported in demo mode");
|
|
3563
|
+
return null;
|
|
3564
|
+
};
|
|
3565
|
+
const addSubtitlesToTimeline = (subtitles) => {
|
|
3566
|
+
var _a;
|
|
3567
|
+
const updatedProjectJSON = (_a = studioConfig == null ? void 0 : studioConfig.subtitleGenerationService) == null ? void 0 : _a.updateProjectWithSubtitles(subtitles);
|
|
3568
|
+
if (updatedProjectJSON) {
|
|
3569
|
+
editor.loadProject(updatedProjectJSON);
|
|
3570
|
+
}
|
|
3571
|
+
};
|
|
3572
|
+
const getSubtitleStatus = async (reqId) => {
|
|
3573
|
+
if (studioConfig == null ? void 0 : studioConfig.subtitleGenerationService) {
|
|
3574
|
+
const service = studioConfig.subtitleGenerationService;
|
|
3575
|
+
return await service.getRequestStatus(reqId);
|
|
3576
|
+
}
|
|
3577
|
+
return {
|
|
3578
|
+
status: "failed",
|
|
3579
|
+
error: "Subtitle generation service not found"
|
|
3580
|
+
};
|
|
3581
|
+
};
|
|
3582
|
+
return {
|
|
3583
|
+
onLoadProject,
|
|
3584
|
+
onSaveProject,
|
|
3585
|
+
onExportVideo,
|
|
3586
|
+
onGenerateSubtitles,
|
|
3587
|
+
addSubtitlesToTimeline,
|
|
3588
|
+
getSubtitleStatus
|
|
3589
|
+
};
|
|
3590
|
+
};
|
|
3591
|
+
const useGenerateSubtitles = (studioConfig) => {
|
|
3592
|
+
const { editor, present } = timeline.useTimelineContext();
|
|
3593
|
+
const onGenerateSubtitles = async (videoElement) => {
|
|
3594
|
+
if (studioConfig == null ? void 0 : studioConfig.subtitleGenerationService) {
|
|
3595
|
+
const service = studioConfig.subtitleGenerationService;
|
|
3596
|
+
const reqId = await service.generateSubtitles(
|
|
3597
|
+
videoElement,
|
|
3598
|
+
present
|
|
3599
|
+
);
|
|
3600
|
+
return reqId;
|
|
3601
|
+
}
|
|
3602
|
+
alert("Generate subtitles not supported in demo mode");
|
|
3603
|
+
return null;
|
|
3604
|
+
};
|
|
3605
|
+
const addSubtitlesToTimeline = (subtitles) => {
|
|
3606
|
+
var _a;
|
|
3607
|
+
const updatedProjectJSON = (_a = studioConfig == null ? void 0 : studioConfig.subtitleGenerationService) == null ? void 0 : _a.updateProjectWithSubtitles(
|
|
3608
|
+
subtitles
|
|
3609
|
+
);
|
|
3610
|
+
if (updatedProjectJSON) {
|
|
3611
|
+
editor.loadProject(updatedProjectJSON);
|
|
3612
|
+
}
|
|
3613
|
+
};
|
|
3614
|
+
const getSubtitleStatus = async (reqId) => {
|
|
3615
|
+
if (studioConfig == null ? void 0 : studioConfig.subtitleGenerationService) {
|
|
3616
|
+
const service = studioConfig.subtitleGenerationService;
|
|
3617
|
+
return await service.getRequestStatus(reqId);
|
|
3618
|
+
}
|
|
3619
|
+
return {
|
|
3620
|
+
status: "failed",
|
|
3621
|
+
error: "Subtitle generation service not found"
|
|
3622
|
+
};
|
|
3623
|
+
};
|
|
3624
|
+
return {
|
|
3625
|
+
onGenerateSubtitles,
|
|
3626
|
+
addSubtitlesToTimeline,
|
|
3627
|
+
getSubtitleStatus
|
|
3628
|
+
};
|
|
3280
3629
|
};
|
|
3281
3630
|
function TwickStudio({ studioConfig }) {
|
|
3282
3631
|
var _a;
|
|
@@ -3290,7 +3639,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3290
3639
|
updateElement
|
|
3291
3640
|
} = useStudioManager();
|
|
3292
3641
|
const { videoResolution, setVideoResolution } = timeline.useTimelineContext();
|
|
3293
|
-
const {
|
|
3642
|
+
const {
|
|
3643
|
+
onLoadProject,
|
|
3644
|
+
onSaveProject,
|
|
3645
|
+
onExportVideo
|
|
3646
|
+
} = useStudioOperation(studioConfig);
|
|
3647
|
+
const { onGenerateSubtitles, addSubtitlesToTimeline, getSubtitleStatus } = useGenerateSubtitles(studioConfig);
|
|
3294
3648
|
const twickStudiConfig = react.useMemo(
|
|
3295
3649
|
() => ({
|
|
3296
3650
|
canvasMode: true,
|
|
@@ -3347,7 +3701,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3347
3701
|
{
|
|
3348
3702
|
selectedProp,
|
|
3349
3703
|
selectedElement,
|
|
3350
|
-
updateElement
|
|
3704
|
+
updateElement,
|
|
3705
|
+
addSubtitlesToTimeline,
|
|
3706
|
+
onGenerateSubtitles,
|
|
3707
|
+
getSubtitleStatus
|
|
3351
3708
|
}
|
|
3352
3709
|
),
|
|
3353
3710
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3362,6 +3719,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3362
3719
|
] }) });
|
|
3363
3720
|
}
|
|
3364
3721
|
exports2.AudioPanel = AudioPanel;
|
|
3722
|
+
exports2.CAPTION_PROPS = CAPTION_PROPS;
|
|
3365
3723
|
exports2.CirclePanel = CirclePanel;
|
|
3366
3724
|
exports2.IconPanel = IconPanel;
|
|
3367
3725
|
exports2.ImagePanel = ImagePanel;
|
|
@@ -3373,6 +3731,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3373
3731
|
exports2.TwickStudio = TwickStudio;
|
|
3374
3732
|
exports2.VideoPanel = VideoPanel;
|
|
3375
3733
|
exports2.default = TwickStudio;
|
|
3734
|
+
exports2.useGenerateSubtitles = useGenerateSubtitles;
|
|
3376
3735
|
exports2.useStudioManager = useStudioManager;
|
|
3377
3736
|
Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3378
3737
|
});
|