@remotion/studio-shared 4.0.477 → 4.0.479

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.
@@ -1,6 +1,6 @@
1
1
  import type { AudioCodec, ChromeMode, Codec, ColorSpace, LogLevel, PixelFormat, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
2
2
  import type { HardwareAccelerationOption } from '@remotion/renderer/client';
3
- import type { _InternalTypes, CannotUpdateSequenceReason, CanUpdateEffectPropsResponse, CanUpdateSequencePropsResponseFalse, CanUpdateSequencePropsResponseTrue, CanUpdateSequencePropStatus, ExtrapolateType, JsxComponentIdentity, SequenceNodePath, SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
3
+ import type { _InternalTypes, CannotUpdateSequenceReason, CanUpdateEffectPropsResponse, CanUpdateSequencePropsResponseFalse, CanUpdateSequencePropsResponseTrue, CanUpdateSequencePropStatus, ExtrapolateType, JsxComponentIdentity, SequenceNodePath, SequencePropsSubscriptionKey, InteractivitySchema } from 'remotion';
4
4
  import type { RecastCodemod, VisualControlChange } from './codemods';
5
5
  import type { ComponentProp } from './component-drag-data';
6
6
  import type { EffectClipboardParam, EffectClipboardPasteType, EffectClipboardSnapshot } from './effect-clipboard-data';
@@ -227,7 +227,7 @@ export type SaveSequencePropEdit = {
227
227
  key: string;
228
228
  value: string;
229
229
  defaultValue: string | null;
230
- schema: SequenceSchema;
230
+ schema: InteractivitySchema;
231
231
  };
232
232
  export type SaveSequencePropsRequest = {
233
233
  edits: SaveSequencePropEdit[];
@@ -254,7 +254,7 @@ type SaveEffectPropsRequestBase = {
254
254
  effectIndex: number;
255
255
  key: string;
256
256
  defaultValue: string | null;
257
- schema: SequenceSchema;
257
+ schema: InteractivitySchema;
258
258
  clientId: string;
259
259
  };
260
260
  export type SaveEffectPropsRequest = (SaveEffectPropsRequestBase & {
@@ -294,6 +294,19 @@ export type ReorderEffectResponse = {
294
294
  reason: string;
295
295
  stack: string;
296
296
  };
297
+ export type DuplicateEffectRequestItem = {
298
+ fileName: string;
299
+ sequenceNodePath: SequencePropsSubscriptionKey;
300
+ effectIndex: number;
301
+ };
302
+ export type DuplicateEffectRequest = DuplicateEffectRequestItem[];
303
+ export type DuplicateEffectResponse = {
304
+ success: true;
305
+ } | {
306
+ success: false;
307
+ reason: string;
308
+ stack: string;
309
+ };
297
310
  export type ReorderSequencePosition = 'before' | 'after';
298
311
  export type ReorderSequenceRequest = {
299
312
  fileName: string;
@@ -314,7 +327,7 @@ export type DeleteSequenceKeyframe = {
314
327
  nodePath: SequencePropsSubscriptionKey;
315
328
  key: string;
316
329
  frame: number;
317
- schema: SequenceSchema;
330
+ schema: InteractivitySchema;
318
331
  };
319
332
  export type MoveSequenceKeyframe = {
320
333
  fileName: string;
@@ -322,7 +335,7 @@ export type MoveSequenceKeyframe = {
322
335
  key: string;
323
336
  fromFrame: number;
324
337
  toFrame: number;
325
- schema: SequenceSchema;
338
+ schema: InteractivitySchema;
326
339
  };
327
340
  export type AddSequenceKeyframeRequest = {
328
341
  fileName: string;
@@ -330,7 +343,7 @@ export type AddSequenceKeyframeRequest = {
330
343
  key: string;
331
344
  frame: number;
332
345
  value: string;
333
- schema: SequenceSchema;
346
+ schema: InteractivitySchema;
334
347
  clientId: string;
335
348
  };
336
349
  export type AddSequenceKeyframeResponse = SaveSequencePropsResponse;
@@ -341,7 +354,7 @@ export type DeleteEffectKeyframe = {
341
354
  effectIndex: number;
342
355
  key: string;
343
356
  frame: number;
344
- schema: SequenceSchema;
357
+ schema: InteractivitySchema;
345
358
  };
346
359
  export type MoveEffectKeyframe = {
347
360
  fileName: string;
@@ -350,7 +363,7 @@ export type MoveEffectKeyframe = {
350
363
  key: string;
351
364
  fromFrame: number;
352
365
  toFrame: number;
353
- schema: SequenceSchema;
366
+ schema: InteractivitySchema;
354
367
  };
355
368
  export type DeleteKeyframesRequest = {
356
369
  sequenceKeyframes: DeleteSequenceKeyframe[];
@@ -375,7 +388,7 @@ export type AddEffectKeyframeRequest = {
375
388
  key: string;
376
389
  frame: number;
377
390
  value: string;
378
- schema: SequenceSchema;
391
+ schema: InteractivitySchema;
379
392
  clientId: string;
380
393
  };
381
394
  export type AddEffectKeyframeResponse = SaveEffectPropsResponse;
@@ -405,7 +418,7 @@ export type UpdateSequenceKeyframeSettingsRequest = {
405
418
  nodePath: SequencePropsSubscriptionKey;
406
419
  key: string;
407
420
  settings: KeyframeSettings;
408
- schema: SequenceSchema;
421
+ schema: InteractivitySchema;
409
422
  clientId: string;
410
423
  };
411
424
  export type UpdateSequenceKeyframeSettingsResponse = SaveSequencePropsResponse;
@@ -415,7 +428,7 @@ export type UpdateEffectKeyframeSettingsRequest = {
415
428
  effectIndex: number;
416
429
  key: string;
417
430
  settings: KeyframeSettings;
418
- schema: SequenceSchema;
431
+ schema: InteractivitySchema;
419
432
  clientId: string;
420
433
  };
421
434
  export type UpdateEffectKeyframeSettingsResponse = SaveEffectPropsResponse;
@@ -490,7 +503,7 @@ export type InsertableCompositionElement = {
490
503
  position: InsertableCompositionElementPosition | null;
491
504
  } | {
492
505
  type: 'asset';
493
- assetType: 'image' | 'video' | 'gif' | 'audio';
506
+ assetType: 'image' | 'video' | 'gif' | 'animated-image' | 'audio';
494
507
  src: string;
495
508
  srcType: 'static' | 'remote';
496
509
  dimensions: {
@@ -586,6 +599,7 @@ export type ApiRoutes = {
586
599
  '/api/save-effect-props': ReqAndRes<SaveEffectPropsRequest, SaveEffectPropsResponse>;
587
600
  '/api/add-effect': ReqAndRes<AddEffectRequest, AddEffectResponse>;
588
601
  '/api/reorder-effect': ReqAndRes<ReorderEffectRequest, ReorderEffectResponse>;
602
+ '/api/duplicate-effect': ReqAndRes<DuplicateEffectRequest, DuplicateEffectResponse>;
589
603
  '/api/reorder-sequence': ReqAndRes<ReorderSequenceRequest, ReorderSequenceResponse>;
590
604
  '/api/delete-keyframes': ReqAndRes<DeleteKeyframesRequest, DeleteKeyframesResponse>;
591
605
  '/api/move-keyframes': ReqAndRes<MoveKeyframesRequest, MoveKeyframesResponse>;
@@ -3,11 +3,16 @@ export type ComponentProp = {
3
3
  name: string;
4
4
  value: string | number | boolean;
5
5
  };
6
+ export type ComponentDimensions = {
7
+ height: number;
8
+ width: number;
9
+ };
6
10
  export type ComponentDragData = {
7
11
  type: 'remotion-component';
8
12
  version: 1;
9
13
  component: {
10
14
  componentName: string;
15
+ dimensions?: ComponentDimensions;
11
16
  importName: string;
12
17
  importPath: string;
13
18
  props: ComponentProp[];
@@ -18,8 +23,9 @@ export declare const isComponentImportPath: (value: unknown) => value is string;
18
23
  export declare const isComponentPropName: (value: unknown) => value is string;
19
24
  export declare const isComponentProp: (value: unknown) => value is ComponentProp;
20
25
  export declare const areComponentProps: (value: unknown) => value is ComponentProp[];
21
- export declare const makeComponentDragData: ({ componentName, importName, importPath, props, }: {
26
+ export declare const makeComponentDragData: ({ componentName, dimensions, importName, importPath, props, }: {
22
27
  componentName: string;
28
+ dimensions?: ComponentDimensions | null | undefined;
23
29
  importName: string;
24
30
  importPath: string;
25
31
  props: ComponentProp[];
@@ -51,12 +51,24 @@ const areComponentProps = (value) => {
51
51
  return true;
52
52
  };
53
53
  exports.areComponentProps = areComponentProps;
54
- const makeComponentDragData = ({ componentName, importName, importPath, props, }) => {
54
+ const isComponentDimensions = (value) => {
55
+ if (!isRecord(value)) {
56
+ return false;
57
+ }
58
+ return (typeof value.width === 'number' &&
59
+ Number.isFinite(value.width) &&
60
+ value.width >= 0 &&
61
+ typeof value.height === 'number' &&
62
+ Number.isFinite(value.height) &&
63
+ value.height >= 0);
64
+ };
65
+ const makeComponentDragData = ({ componentName, dimensions, importName, importPath, props, }) => {
55
66
  return {
56
67
  type: 'remotion-component',
57
68
  version: 1,
58
69
  component: {
59
70
  componentName,
71
+ ...(dimensions ? { dimensions } : {}),
60
72
  importName,
61
73
  importPath,
62
74
  props,
@@ -76,11 +88,12 @@ const parseComponentDragData = (value) => {
76
88
  if (!isRecord(parsed.component)) {
77
89
  return null;
78
90
  }
79
- const { componentName, importName, importPath, props } = parsed.component;
91
+ const { componentName, dimensions, importName, importPath, props } = parsed.component;
80
92
  if (!(0, exports.isComponentIdentifier)(componentName) ||
81
93
  !(0, exports.isComponentIdentifier)(importName) ||
82
94
  !(0, exports.isComponentImportPath)(importPath) ||
83
- !(0, exports.areComponentProps)(props)) {
95
+ !(0, exports.areComponentProps)(props) ||
96
+ (typeof dimensions !== 'undefined' && !isComponentDimensions(dimensions))) {
84
97
  return null;
85
98
  }
86
99
  return {
@@ -88,6 +101,7 @@ const parseComponentDragData = (value) => {
88
101
  version: 1,
89
102
  component: {
90
103
  componentName,
104
+ ...(dimensions ? { dimensions } : {}),
91
105
  importName,
92
106
  importPath,
93
107
  props,
@@ -47,6 +47,10 @@ export type PngType = {
47
47
  type: 'png';
48
48
  dimensions: FileDimensions | null;
49
49
  };
50
+ export type ApngType = {
51
+ type: 'apng';
52
+ dimensions: FileDimensions | null;
53
+ };
50
54
  export type JpegType = {
51
55
  type: 'jpeg';
52
56
  dimensions: FileDimensions | null;
@@ -65,7 +69,7 @@ export type PdfType = {
65
69
  export type UnknownType = {
66
70
  type: 'unknown';
67
71
  };
68
- export type FileType = JpegType | WebpType | RiffType | WebmType | WavType | PdfType | AacType | IsoBaseMediaType | TransportStreamType | Mp3Type | GifType | PngType | BmpType | AacType | FlacType | M3uType | UnknownType;
69
- export type ImageFileType = JpegType | WebpType | GifType | PngType | BmpType;
72
+ export type FileType = JpegType | WebpType | RiffType | WebmType | WavType | PdfType | AacType | IsoBaseMediaType | TransportStreamType | Mp3Type | GifType | PngType | ApngType | BmpType | AacType | FlacType | M3uType | UnknownType;
73
+ export type ImageFileType = JpegType | WebpType | GifType | PngType | ApngType | BmpType;
70
74
  export declare const isImageFileType: (fileType: FileType) => fileType is ImageFileType;
71
75
  export declare const detectFileType: (data: Uint8Array<ArrayBufferLike>) => FileType;
@@ -69,12 +69,15 @@ const isM3u = (data) => {
69
69
  return new TextDecoder('utf-8').decode(data.slice(0, 7)) === '#EXTM3U';
70
70
  };
71
71
  exports.isM3u = isM3u;
72
+ const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
73
+ const acTLChunkType = new Uint8Array([0x61, 0x63, 0x54, 0x4c]);
74
+ const idatChunkType = new Uint8Array([0x49, 0x44, 0x41, 0x54]);
75
+ const iendChunkType = new Uint8Array([0x49, 0x45, 0x4e, 0x44]);
72
76
  const getPngDimensions = (pngData) => {
73
77
  if (pngData.length < 24) {
74
78
  return null;
75
79
  }
76
80
  const view = new DataView(pngData.buffer, pngData.byteOffset);
77
- const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
78
81
  for (let i = 0; i < 8; i++) {
79
82
  if (pngData[i] !== pngSignature[i]) {
80
83
  return null;
@@ -85,11 +88,38 @@ const getPngDimensions = (pngData) => {
85
88
  height: view.getUint32(20, false),
86
89
  };
87
90
  };
91
+ const hasApngAnimationControlChunk = (pngData) => {
92
+ if (pngData.length < 16) {
93
+ return false;
94
+ }
95
+ const view = new DataView(pngData.buffer, pngData.byteOffset, pngData.byteLength);
96
+ let offset = 8;
97
+ while (offset + 8 <= pngData.length) {
98
+ const chunkLength = view.getUint32(offset, false);
99
+ const chunkType = pngData.subarray(offset + 4, offset + 8);
100
+ if ((0, exports.matchesPattern)(acTLChunkType)(chunkType)) {
101
+ return true;
102
+ }
103
+ if ((0, exports.matchesPattern)(idatChunkType)(chunkType) ||
104
+ (0, exports.matchesPattern)(iendChunkType)(chunkType)) {
105
+ return false;
106
+ }
107
+ const nextOffset = offset + 12 + chunkLength;
108
+ if (nextOffset <= offset) {
109
+ return false;
110
+ }
111
+ offset = nextOffset;
112
+ }
113
+ return false;
114
+ };
88
115
  const isPng = (data) => {
89
116
  const pngPattern = new Uint8Array([0x89, 0x50, 0x4e, 0x47]);
90
117
  if ((0, exports.matchesPattern)(pngPattern)(data.subarray(0, 4))) {
91
118
  const png = getPngDimensions(data);
92
- return { dimensions: png, type: 'png' };
119
+ return {
120
+ dimensions: png,
121
+ type: hasApngAnimationControlChunk(data) ? 'apng' : 'png',
122
+ };
93
123
  }
94
124
  return null;
95
125
  };
@@ -235,6 +265,7 @@ const isImageFileType = (fileType) => {
235
265
  fileType.type === 'webp' ||
236
266
  fileType.type === 'gif' ||
237
267
  fileType.type === 'png' ||
268
+ fileType.type === 'apng' ||
238
269
  fileType.type === 'bmp');
239
270
  };
240
271
  exports.isImageFileType = isImageFileType;
@@ -0,0 +1,18 @@
1
+ import type { KeyframeEasing } from './keyframe-easing-presets';
2
+ export type EasingClipboardData = {
3
+ readonly type: 'easing';
4
+ readonly version: 1;
5
+ readonly remotionClipboard: 'easing';
6
+ readonly easing: KeyframeEasing;
7
+ };
8
+ export type EasingClipboardDataParseResult = {
9
+ readonly status: 'valid';
10
+ readonly data: EasingClipboardData;
11
+ } | {
12
+ readonly status: 'unsupported-version';
13
+ readonly version: unknown;
14
+ } | {
15
+ readonly status: 'invalid';
16
+ };
17
+ export declare const parseEasingClipboardDataResult: (value: string) => EasingClipboardDataParseResult;
18
+ export declare const parseEasingClipboardData: (value: string) => EasingClipboardData | null;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseEasingClipboardData = exports.parseEasingClipboardDataResult = void 0;
4
+ const isRecord = (value) => {
5
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
6
+ };
7
+ const isFiniteNumber = (value) => {
8
+ return typeof value === 'number' && Number.isFinite(value);
9
+ };
10
+ const isEasing = (value) => {
11
+ return (isRecord(value) &&
12
+ (value.type === 'linear' ||
13
+ (value.type === 'bezier' &&
14
+ isFiniteNumber(value.x1) &&
15
+ isFiniteNumber(value.y1) &&
16
+ isFiniteNumber(value.x2) &&
17
+ isFiniteNumber(value.y2)) ||
18
+ (value.type === 'spring' &&
19
+ isFiniteNumber(value.damping) &&
20
+ isFiniteNumber(value.mass) &&
21
+ isFiniteNumber(value.stiffness) &&
22
+ typeof value.overshootClamping === 'boolean')));
23
+ };
24
+ const parseEasingClipboardDataResult = (value) => {
25
+ try {
26
+ const parsed = JSON.parse(value);
27
+ if (!isRecord(parsed)) {
28
+ return { status: 'invalid' };
29
+ }
30
+ if (parsed.remotionClipboard !== 'easing') {
31
+ return { status: 'invalid' };
32
+ }
33
+ if (parsed.version !== 1) {
34
+ return {
35
+ status: 'unsupported-version',
36
+ version: parsed.version,
37
+ };
38
+ }
39
+ if (parsed.type !== 'easing' || !isEasing(parsed.easing)) {
40
+ return { status: 'invalid' };
41
+ }
42
+ return {
43
+ status: 'valid',
44
+ data: {
45
+ type: 'easing',
46
+ version: 1,
47
+ remotionClipboard: 'easing',
48
+ easing: parsed.easing,
49
+ },
50
+ };
51
+ }
52
+ catch (_a) {
53
+ return { status: 'invalid' };
54
+ }
55
+ };
56
+ exports.parseEasingClipboardDataResult = parseEasingClipboardDataResult;
57
+ const parseEasingClipboardData = (value) => {
58
+ const result = (0, exports.parseEasingClipboardDataResult)(value);
59
+ if (result.status !== 'valid') {
60
+ return null;
61
+ }
62
+ return result.data;
63
+ };
64
+ exports.parseEasingClipboardData = parseEasingClipboardData;
@@ -0,0 +1,19 @@
1
+ import type { EffectDragData } from './effect-drag-data';
2
+ export type EffectCatalogItem = {
3
+ readonly id: string;
4
+ readonly category: string;
5
+ readonly label: string;
6
+ readonly description: string;
7
+ readonly effect: EffectDragData['effect'];
8
+ };
9
+ export type EffectCatalogCategory = {
10
+ readonly title: string;
11
+ readonly effects: readonly EffectCatalogItem[];
12
+ };
13
+ export declare const getEffectDocumentationPath: (item: EffectCatalogItem) => string;
14
+ export declare const getEffectDocumentationLink: (item: EffectCatalogItem) => string;
15
+ export declare const getEffectPreviewSource: (item: EffectCatalogItem) => string;
16
+ export declare const getEffectPreviewAlt: (item: EffectCatalogItem) => string;
17
+ export declare const makeEffectDragDataFromCatalogItem: (item: EffectCatalogItem) => EffectDragData;
18
+ export declare const getEffectCatalogCategories: (items: readonly EffectCatalogItem[]) => readonly EffectCatalogCategory[];
19
+ export declare const EFFECT_CATALOG: readonly EffectCatalogItem[];