visualfries 0.1.10120 → 0.3.2

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 (133) hide show
  1. package/README.md +97 -0
  2. package/bin/visualfries.js +1570 -0
  3. package/dist/DIContainer.d.ts +2 -1
  4. package/dist/DIContainer.js +16 -5
  5. package/dist/SceneBuilder.svelte.d.ts +70 -1
  6. package/dist/SceneBuilder.svelte.js +96 -29
  7. package/dist/agent/audioMixer.d.ts +34 -0
  8. package/dist/agent/audioMixer.js +308 -0
  9. package/dist/agent/broll.d.ts +35 -0
  10. package/dist/agent/broll.js +226 -0
  11. package/dist/agent/capabilities.d.ts +34 -0
  12. package/dist/agent/capabilities.js +246 -0
  13. package/dist/agent/captionScene.d.ts +23 -0
  14. package/dist/agent/captionScene.js +204 -0
  15. package/dist/agent/catalog.d.ts +24 -0
  16. package/dist/agent/catalog.js +67 -0
  17. package/dist/agent/cueFiles.d.ts +54 -0
  18. package/dist/agent/cueFiles.js +219 -0
  19. package/dist/agent/cuePresets.d.ts +7 -0
  20. package/dist/agent/cuePresets.js +50 -0
  21. package/dist/agent/deterministicMedia.d.ts +61 -0
  22. package/dist/agent/deterministicMedia.js +303 -0
  23. package/dist/agent/index.d.ts +18 -0
  24. package/dist/agent/index.js +18 -0
  25. package/dist/agent/inspectScene.d.ts +36 -0
  26. package/dist/agent/inspectScene.js +139 -0
  27. package/dist/agent/localRender.d.ts +82 -0
  28. package/dist/agent/localRender.js +702 -0
  29. package/dist/agent/overlays.d.ts +40 -0
  30. package/dist/agent/overlays.js +325 -0
  31. package/dist/agent/productionPlan.d.ts +131 -0
  32. package/dist/agent/productionPlan.js +322 -0
  33. package/dist/agent/renderPlan.d.ts +27 -0
  34. package/dist/agent/renderPlan.js +68 -0
  35. package/dist/agent/renderRanges.d.ts +24 -0
  36. package/dist/agent/renderRanges.js +73 -0
  37. package/dist/agent/runtimeSupport.d.ts +19 -0
  38. package/dist/agent/runtimeSupport.js +192 -0
  39. package/dist/agent/streamingEncoder.d.ts +31 -0
  40. package/dist/agent/streamingEncoder.js +208 -0
  41. package/dist/agent/transcripts.d.ts +29 -0
  42. package/dist/agent/transcripts.js +146 -0
  43. package/dist/agent/transitions.d.ts +20 -0
  44. package/dist/agent/transitions.js +169 -0
  45. package/dist/animations/PixiAnimationTarget.d.ts +29 -0
  46. package/dist/animations/PixiAnimationTarget.js +63 -0
  47. package/dist/animations/builders/LineHighlighterAnimationBuilder.js +20 -3
  48. package/dist/animations/builders/WordHighlighterAnimationBuilder.js +15 -2
  49. package/dist/browser/browserExport.d.ts +73 -0
  50. package/dist/browser/browserExport.js +180 -0
  51. package/dist/browser/glTransitions.d.ts +37 -0
  52. package/dist/browser/glTransitions.js +261 -0
  53. package/dist/browser/index.d.ts +3 -0
  54. package/dist/browser/index.js +3 -0
  55. package/dist/browser/mediaDecode.d.ts +31 -0
  56. package/dist/browser/mediaDecode.js +152 -0
  57. package/dist/builders/PixiComponentBuilder.d.ts +6 -0
  58. package/dist/builders/PixiComponentBuilder.js +12 -0
  59. package/dist/builders/_ComponentState.svelte.d.ts +7 -5
  60. package/dist/builders/_ComponentState.svelte.js +29 -15
  61. package/dist/builders/html/StyleBuilder.js +9 -8
  62. package/dist/builders/html/TextComponentHtmlBuilder.js +4 -2
  63. package/dist/builders/html/processors/AppearanceStyleProcessor.js +1 -1
  64. package/dist/builders/html/processors/TextAppearanceStyleProcessor.js +7 -0
  65. package/dist/builders/html/processors/TextEffectsStyleProcessor.js +32 -13
  66. package/dist/commands/ReplaceSourceOnTimeCommand.js +9 -1
  67. package/dist/commands/SeekCommand.js +19 -6
  68. package/dist/components/AnimatedGIF.d.ts +3 -0
  69. package/dist/components/AnimatedGIF.js +28 -1
  70. package/dist/components/Component.svelte.d.ts +5 -5
  71. package/dist/components/Component.svelte.js +29 -13
  72. package/dist/components/ComponentContext.svelte.js +68 -23
  73. package/dist/components/hooks/AnimationHook.js +1 -1
  74. package/dist/components/hooks/CanvasFillHook.d.ts +12 -0
  75. package/dist/components/hooks/CanvasFillHook.js +75 -0
  76. package/dist/components/hooks/DeterministicMediaFrameHook.js +3 -0
  77. package/dist/components/hooks/HtmlTextHook.js +11 -3
  78. package/dist/components/hooks/HtmlToCanvasHook.js +8 -25
  79. package/dist/components/hooks/MediaHook.js +172 -47
  80. package/dist/components/hooks/MediaSeekingHook.js +138 -88
  81. package/dist/components/hooks/PixiGifHook.js +4 -4
  82. package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.js +73 -6
  83. package/dist/components/hooks/PixiVideoTextureHook.js +10 -4
  84. package/dist/components/hooks/PixiVisualTransformHook.d.ts +16 -0
  85. package/dist/components/hooks/PixiVisualTransformHook.js +102 -0
  86. package/dist/components/hooks/SubtitlesHook.js +48 -24
  87. package/dist/components/hooks/VerifyMediaHook.js +2 -2
  88. package/dist/directors/ComponentDirector.d.ts +1 -0
  89. package/dist/directors/ComponentDirector.js +41 -8
  90. package/dist/fonts/fontDiscovery.js +12 -1
  91. package/dist/layers/Layer.svelte.d.ts +54 -0
  92. package/dist/layers/Layer.svelte.js +2 -25
  93. package/dist/managers/AppManager.svelte.js +8 -5
  94. package/dist/managers/ComponentsManager.svelte.d.ts +7 -7
  95. package/dist/managers/ComponentsManager.svelte.js +29 -15
  96. package/dist/managers/DeterministicMediaManager.js +38 -3
  97. package/dist/managers/EventManager.js +3 -1
  98. package/dist/managers/LayersManager.svelte.d.ts +54 -0
  99. package/dist/managers/RenderManager.d.ts +5 -0
  100. package/dist/managers/RenderManager.js +67 -21
  101. package/dist/managers/StateManager.svelte.d.ts +56 -0
  102. package/dist/managers/StateManager.svelte.js +60 -58
  103. package/dist/managers/SubtitlesManager.svelte.js +1 -3
  104. package/dist/managers/TimeManager.svelte.d.ts +4 -0
  105. package/dist/managers/TimeManager.svelte.js +23 -7
  106. package/dist/schemas/runtime/deterministic.js +5 -1
  107. package/dist/schemas/runtime/types.d.ts +36 -15
  108. package/dist/schemas/scene/components.d.ts +126 -0
  109. package/dist/schemas/scene/components.js +11 -0
  110. package/dist/schemas/scene/core.d.ts +109 -10
  111. package/dist/schemas/scene/core.js +1 -1
  112. package/dist/utils/mediaWindow.d.ts +13 -0
  113. package/dist/utils/mediaWindow.js +25 -0
  114. package/dist/utils/svgGenerator.js +1 -1
  115. package/dist/utils/timelineWindow.d.ts +2 -0
  116. package/dist/utils/timelineWindow.js +7 -0
  117. package/dist/utils/utils.js +2 -4
  118. package/docs/AGENT_PATTERNS.md +243 -0
  119. package/docs/AGENT_WORKFLOW.md +364 -0
  120. package/docs/AUTHORING_BEST_PRACTICES.md +188 -0
  121. package/docs/AUTHORING_SYSTEM_AUDIT.md +98 -0
  122. package/docs/BROWSER_EXPORT_SPIKE.md +55 -0
  123. package/docs/DETERMINISTIC_RENDERER.md +83 -0
  124. package/docs/NEXT_RELEASE.md +28 -0
  125. package/docs/PROPOSED_VISUALFRIES_SKILL.md +68 -0
  126. package/docs/examples/agent-cues.json +49 -0
  127. package/docs/examples/agent-transcript.json +23 -0
  128. package/docs/examples/agent-transcript.srt +7 -0
  129. package/docs/examples/agent-transcript.vtt +7 -0
  130. package/docs/examples/image-animation.json +87 -0
  131. package/docs/examples/native-text-metric-badge.json +109 -0
  132. package/package.json +133 -100
  133. package/skills/visualfries/SKILL.md +328 -0
@@ -1347,6 +1347,12 @@ export declare const SceneLayerShape: z.ZodObject<{
1347
1347
  lowercase: "lowercase";
1348
1348
  capitalize: "capitalize";
1349
1349
  }>>;
1350
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
1351
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
1352
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
1353
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
1354
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
1355
+ }, z.core.$strip>]>>;
1350
1356
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
1351
1357
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
1352
1358
  preset: z.ZodOptional<z.ZodString>;
@@ -2494,6 +2500,12 @@ export declare const SceneLayerShape: z.ZodObject<{
2494
2500
  lowercase: "lowercase";
2495
2501
  capitalize: "capitalize";
2496
2502
  }>>;
2503
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
2504
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
2505
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
2506
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
2507
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
2508
+ }, z.core.$strip>]>>;
2497
2509
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2498
2510
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
2499
2511
  preset: z.ZodOptional<z.ZodString>;
@@ -3648,6 +3660,12 @@ export declare const SceneLayerShape: z.ZodObject<{
3648
3660
  lowercase: "lowercase";
3649
3661
  capitalize: "capitalize";
3650
3662
  }>>;
3663
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
3664
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
3665
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
3666
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
3667
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
3668
+ }, z.core.$strip>]>>;
3651
3669
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
3652
3670
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
3653
3671
  preset: z.ZodOptional<z.ZodString>;
@@ -4800,6 +4818,12 @@ export declare const SceneLayerShape: z.ZodObject<{
4800
4818
  lowercase: "lowercase";
4801
4819
  capitalize: "capitalize";
4802
4820
  }>>;
4821
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
4822
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
4823
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
4824
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
4825
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
4826
+ }, z.core.$strip>]>>;
4803
4827
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
4804
4828
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
4805
4829
  preset: z.ZodOptional<z.ZodString>;
@@ -6022,6 +6046,12 @@ export declare const SceneLayerShape: z.ZodObject<{
6022
6046
  lowercase: "lowercase";
6023
6047
  capitalize: "capitalize";
6024
6048
  }>>;
6049
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
6050
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
6051
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
6052
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
6053
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
6054
+ }, z.core.$strip>]>>;
6025
6055
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
6026
6056
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
6027
6057
  preset: z.ZodOptional<z.ZodString>;
@@ -7184,6 +7214,12 @@ export declare const SceneLayerShape: z.ZodObject<{
7184
7214
  lowercase: "lowercase";
7185
7215
  capitalize: "capitalize";
7186
7216
  }>>;
7217
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
7218
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
7219
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
7220
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
7221
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
7222
+ }, z.core.$strip>]>>;
7187
7223
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
7188
7224
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
7189
7225
  preset: z.ZodOptional<z.ZodString>;
@@ -8237,6 +8273,12 @@ export declare const SceneLayerShape: z.ZodObject<{
8237
8273
  lowercase: "lowercase";
8238
8274
  capitalize: "capitalize";
8239
8275
  }>>;
8276
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
8277
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
8278
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
8279
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
8280
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
8281
+ }, z.core.$strip>]>>;
8240
8282
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
8241
8283
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
8242
8284
  preset: z.ZodOptional<z.ZodString>;
@@ -9289,6 +9331,12 @@ export declare const SceneLayerShape: z.ZodObject<{
9289
9331
  lowercase: "lowercase";
9290
9332
  capitalize: "capitalize";
9291
9333
  }>>;
9334
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
9335
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
9336
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
9337
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
9338
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
9339
+ }, z.core.$strip>]>>;
9292
9340
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
9293
9341
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
9294
9342
  preset: z.ZodOptional<z.ZodString>;
@@ -10463,6 +10511,12 @@ export declare const SceneLayerShape: z.ZodObject<{
10463
10511
  lowercase: "lowercase";
10464
10512
  capitalize: "capitalize";
10465
10513
  }>>;
10514
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
10515
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
10516
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
10517
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
10518
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
10519
+ }, z.core.$strip>]>>;
10466
10520
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
10467
10521
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
10468
10522
  preset: z.ZodOptional<z.ZodString>;
@@ -10698,13 +10752,9 @@ export declare const SceneTransitionShape: z.ZodObject<{
10698
10752
  * Schema for the main scene structure in v2.0
10699
10753
  */
10700
10754
  export declare const SceneShape: z.ZodObject<{
10701
- /** Unique identifier for the scene */
10702
10755
  id: z.ZodString;
10703
- /** Schema version */
10704
10756
  version: z.ZodOptional<z.ZodCoercedString<unknown>>;
10705
- /** Optional name for the scene */
10706
10757
  name: z.ZodOptional<z.ZodString>;
10707
- /** Scene settings */
10708
10758
  settings: z.ZodObject<{
10709
10759
  width: z.ZodNumber;
10710
10760
  height: z.ZodNumber;
@@ -10816,7 +10866,6 @@ export declare const SceneShape: z.ZodObject<{
10816
10866
  }, z.core.$strip>]>>>>>;
10817
10867
  }, z.core.$strip>>;
10818
10868
  }, z.core.$strip>;
10819
- /** Assets registry */
10820
10869
  assets: z.ZodPrefault<z.ZodArray<z.ZodObject<{
10821
10870
  id: z.ZodString;
10822
10871
  type: z.ZodEnum<{
@@ -10902,7 +10951,6 @@ export declare const SceneShape: z.ZodObject<{
10902
10951
  }, z.core.$strip>>>;
10903
10952
  }, z.core.$strip>>>;
10904
10953
  }, z.core.$strip>>>;
10905
- /** Layers in the scene */
10906
10954
  layers: z.ZodPrefault<z.ZodArray<z.ZodObject<{
10907
10955
  id: z.ZodString;
10908
10956
  name: z.ZodOptional<z.ZodString>;
@@ -11891,6 +11939,12 @@ export declare const SceneShape: z.ZodObject<{
11891
11939
  lowercase: "lowercase";
11892
11940
  capitalize: "capitalize";
11893
11941
  }>>;
11942
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
11943
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
11944
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
11945
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
11946
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
11947
+ }, z.core.$strip>]>>;
11894
11948
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
11895
11949
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
11896
11950
  preset: z.ZodOptional<z.ZodString>;
@@ -13038,6 +13092,12 @@ export declare const SceneShape: z.ZodObject<{
13038
13092
  lowercase: "lowercase";
13039
13093
  capitalize: "capitalize";
13040
13094
  }>>;
13095
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
13096
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
13097
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
13098
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
13099
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
13100
+ }, z.core.$strip>]>>;
13041
13101
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
13042
13102
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
13043
13103
  preset: z.ZodOptional<z.ZodString>;
@@ -14192,6 +14252,12 @@ export declare const SceneShape: z.ZodObject<{
14192
14252
  lowercase: "lowercase";
14193
14253
  capitalize: "capitalize";
14194
14254
  }>>;
14255
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
14256
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
14257
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
14258
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
14259
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
14260
+ }, z.core.$strip>]>>;
14195
14261
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
14196
14262
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
14197
14263
  preset: z.ZodOptional<z.ZodString>;
@@ -15344,6 +15410,12 @@ export declare const SceneShape: z.ZodObject<{
15344
15410
  lowercase: "lowercase";
15345
15411
  capitalize: "capitalize";
15346
15412
  }>>;
15413
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
15414
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
15415
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
15416
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
15417
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
15418
+ }, z.core.$strip>]>>;
15347
15419
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
15348
15420
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
15349
15421
  preset: z.ZodOptional<z.ZodString>;
@@ -16566,6 +16638,12 @@ export declare const SceneShape: z.ZodObject<{
16566
16638
  lowercase: "lowercase";
16567
16639
  capitalize: "capitalize";
16568
16640
  }>>;
16641
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
16642
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
16643
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
16644
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
16645
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
16646
+ }, z.core.$strip>]>>;
16569
16647
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
16570
16648
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
16571
16649
  preset: z.ZodOptional<z.ZodString>;
@@ -17728,6 +17806,12 @@ export declare const SceneShape: z.ZodObject<{
17728
17806
  lowercase: "lowercase";
17729
17807
  capitalize: "capitalize";
17730
17808
  }>>;
17809
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
17810
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
17811
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
17812
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
17813
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
17814
+ }, z.core.$strip>]>>;
17731
17815
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
17732
17816
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
17733
17817
  preset: z.ZodOptional<z.ZodString>;
@@ -18781,6 +18865,12 @@ export declare const SceneShape: z.ZodObject<{
18781
18865
  lowercase: "lowercase";
18782
18866
  capitalize: "capitalize";
18783
18867
  }>>;
18868
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
18869
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
18870
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
18871
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
18872
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
18873
+ }, z.core.$strip>]>>;
18784
18874
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
18785
18875
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
18786
18876
  preset: z.ZodOptional<z.ZodString>;
@@ -19833,6 +19923,12 @@ export declare const SceneShape: z.ZodObject<{
19833
19923
  lowercase: "lowercase";
19834
19924
  capitalize: "capitalize";
19835
19925
  }>>;
19926
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
19927
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
19928
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
19929
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
19930
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
19931
+ }, z.core.$strip>]>>;
19836
19932
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
19837
19933
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
19838
19934
  preset: z.ZodOptional<z.ZodString>;
@@ -21007,6 +21103,12 @@ export declare const SceneShape: z.ZodObject<{
21007
21103
  lowercase: "lowercase";
21008
21104
  capitalize: "capitalize";
21009
21105
  }>>;
21106
+ padding: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>, z.ZodObject<{
21107
+ top: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
21108
+ right: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
21109
+ bottom: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
21110
+ left: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodCoercedNumber<unknown>>;
21111
+ }, z.core.$strip>]>>;
21010
21112
  shadow: z.ZodOptional<z.ZodNullable<z.ZodObject<{
21011
21113
  enabled: z.ZodOptional<z.ZodPrefault<z.ZodBoolean>>;
21012
21114
  preset: z.ZodOptional<z.ZodString>;
@@ -21213,7 +21315,6 @@ export declare const SceneShape: z.ZodObject<{
21213
21315
  }, z.core.$strip>;
21214
21316
  }, z.core.$strict>], "type">>>;
21215
21317
  }, z.core.$strip>>>;
21216
- /** Scene transitions */
21217
21318
  transitions: z.ZodPrefault<z.ZodArray<z.ZodObject<{
21218
21319
  id: z.ZodString;
21219
21320
  name: z.ZodOptional<z.ZodString>;
@@ -21224,7 +21325,6 @@ export declare const SceneShape: z.ZodObject<{
21224
21325
  duration: z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>;
21225
21326
  parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
21226
21327
  }, z.core.$strip>>>;
21227
- /** Audio tracks */
21228
21328
  audioTracks: z.ZodPrefault<z.ZodArray<z.ZodObject<{
21229
21329
  id: z.ZodString;
21230
21330
  name: z.ZodOptional<z.ZodString>;
@@ -21234,9 +21334,8 @@ export declare const SceneShape: z.ZodObject<{
21234
21334
  endAt: z.ZodPipe<z.ZodOptional<z.ZodNumber>, z.ZodTransform<number | undefined, number | undefined>>;
21235
21335
  muted: z.ZodPrefault<z.ZodBoolean>;
21236
21336
  }, z.core.$strip>>>;
21237
- /** Optional checksum */
21238
21337
  checksum: z.ZodOptional<z.ZodString>;
21239
- }, z.core.$strict>;
21338
+ }, z.core.$strip>;
21240
21339
  export type SceneAssetMetadata = z.infer<typeof SceneAssetMetadataShape>;
21241
21340
  export type SceneAsset = z.infer<typeof SceneAssetShape>;
21242
21341
  export type SceneSettings = z.infer<typeof SceneSettingsShape>;
@@ -140,7 +140,7 @@ export const SceneTransitionShape = z.object({
140
140
  /**
141
141
  * Schema for the main scene structure in v2.0
142
142
  */
143
- export const SceneShape = z.strictObject({
143
+ export const SceneShape = z.object({
144
144
  /** Unique identifier for the scene */
145
145
  id: z.string(),
146
146
  /** Schema version */
@@ -0,0 +1,13 @@
1
+ import type { ComponentData } from '..';
2
+ export declare const DEFAULT_MEDIA_PREROLL_SECONDS = 0.75;
3
+ export declare const STREAMING_MEDIA_PREROLL_SECONDS = 2;
4
+ export declare const DEFAULT_MEDIA_POSTROLL_SECONDS = 0.25;
5
+ type MediaWindowComponent = Pick<ComponentData, 'type' | 'visible' | 'timeline'> & {
6
+ source?: {
7
+ url?: string | null;
8
+ };
9
+ };
10
+ export declare function isMediaWindowComponent(data: MediaWindowComponent | undefined): data is MediaWindowComponent;
11
+ export declare function getMediaPrerollSeconds(data: MediaWindowComponent | undefined): number;
12
+ export declare function shouldPrepareMediaAtTime(data: MediaWindowComponent | undefined, currentTime: number): boolean;
13
+ export {};
@@ -0,0 +1,25 @@
1
+ export const DEFAULT_MEDIA_PREROLL_SECONDS = 0.75;
2
+ export const STREAMING_MEDIA_PREROLL_SECONDS = 2;
3
+ export const DEFAULT_MEDIA_POSTROLL_SECONDS = 0.25;
4
+ export function isMediaWindowComponent(data) {
5
+ return data?.type === 'VIDEO' || data?.type === 'AUDIO';
6
+ }
7
+ export function getMediaPrerollSeconds(data) {
8
+ if (!isMediaWindowComponent(data)) {
9
+ return 0;
10
+ }
11
+ const url = data.source?.url ?? '';
12
+ return /\.m3u8(?:$|[?#])/i.test(url)
13
+ ? STREAMING_MEDIA_PREROLL_SECONDS
14
+ : DEFAULT_MEDIA_PREROLL_SECONDS;
15
+ }
16
+ export function shouldPrepareMediaAtTime(data, currentTime) {
17
+ if (!isMediaWindowComponent(data) || data.visible === false) {
18
+ return false;
19
+ }
20
+ const startAt = data.timeline.startAt ?? 0;
21
+ const endAt = data.timeline.endAt ?? startAt;
22
+ const prerollSeconds = getMediaPrerollSeconds(data);
23
+ return (currentTime >= startAt - prerollSeconds &&
24
+ currentTime <= endAt + DEFAULT_MEDIA_POSTROLL_SECONDS);
25
+ }
@@ -26,7 +26,7 @@ export class SVGGenerator {
26
26
  const isEmoji = /^(\p{Emoji_Presentation}|\p{Emoji}\uFE0F|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\s)+$/u.test(el.textContent || '');
27
27
  const getFontText = isEmoji ? 'a' : fontText || el.textContent;
28
28
  let fontData = null;
29
- if (fontFamily && !isEmoji) {
29
+ if (fontFamily && !isEmoji && config.fontSource?.source === 'google') {
30
30
  const cacheKey = `${fontFamily + weightAppend}_${getFontText}`;
31
31
  if (cacheKey in this.fontDataBase64Cache) {
32
32
  fontData = this.fontDataBase64Cache[cacheKey];
@@ -0,0 +1,2 @@
1
+ export declare const TIMELINE_BOUNDARY_EPSILON = 1e-7;
2
+ export declare function isTimeWithinTimeline(currentTime: number, startAt: number, endAt: number, epsilon?: number): boolean;
@@ -0,0 +1,7 @@
1
+ export const TIMELINE_BOUNDARY_EPSILON = 1e-7;
2
+ export function isTimeWithinTimeline(currentTime, startAt, endAt, epsilon = TIMELINE_BOUNDARY_EPSILON) {
3
+ if (endAt - startAt <= epsilon) {
4
+ return currentTime >= startAt - epsilon && currentTime <= endAt + epsilon;
5
+ }
6
+ return currentTime >= startAt - epsilon && currentTime < endAt - epsilon;
7
+ }
@@ -41,9 +41,7 @@ export const buildCharactersListFromComponentsAndSubtitles = function (layers, s
41
41
  const c = component;
42
42
  const text = c.text;
43
43
  if (text) {
44
- // Use Array.from to properly handle multi-codepoint characters (emojis, etc.)
45
- // This prevents splitting emojis into unpaired surrogates
46
- const textList = Array.from(text);
44
+ const textList = text.split('');
47
45
  const missingChars = textList.filter((char) => {
48
46
  // Check if the character is not whitespace, not in the characters list,
49
47
  // is a Unicode letter or number, and is NOT an emoji
@@ -108,7 +106,7 @@ export const setPlacementAndOpacity = function (obj, c) {
108
106
  obj.y = config.y;
109
107
  obj.width = config.width;
110
108
  obj.height = config.height;
111
- obj.alpha = config.opacity || 1;
109
+ obj.alpha = config.opacity ?? 1;
112
110
  if (config.rotation) {
113
111
  obj.angle = config.rotation;
114
112
  }
@@ -0,0 +1,243 @@
1
+ # VisualFries Agent Patterns
2
+
3
+ Reusable building blocks for agents that need short-form videos without writing raw scene JSON from scratch.
4
+
5
+ ## New Agent Package
6
+
7
+ Use when starting a self-contained work folder:
8
+
9
+ ```bash
10
+ visualfries init ./video-package \
11
+ --video ./input.mp4 \
12
+ --transcript ./transcript.srt \
13
+ --preset hidden-engine-center \
14
+ --cue-preset hidden-engine-dynamic
15
+ ```
16
+
17
+ Generated structure:
18
+
19
+ ```text
20
+ video-package/
21
+ scene.json
22
+ cues.json
23
+ assets/
24
+ qa/
25
+ inspect.json
26
+ frames/
27
+ notes.md
28
+ transcript.example.json
29
+ ```
30
+
31
+ `cues.json` is generated from the selected cue preset and should be treated as the visual timeline map for the video.
32
+
33
+ ## Captioned Video
34
+
35
+ Use when the base asset already contains the main story or voiceover.
36
+
37
+ Fastest preview path:
38
+
39
+ ```bash
40
+ visualfries compose \
41
+ --video ./input.mp4 \
42
+ --transcript ./transcript.srt \
43
+ --cue-preset hidden-engine-dynamic \
44
+ --cues ./cues.json \
45
+ --scene-output ./scene.json \
46
+ --qa-output ./qa/frames \
47
+ --render-mode preview \
48
+ --output ./out.mp4
49
+ ```
50
+
51
+ Use `compose` for routine agent previews. Use the step-by-step commands when debugging a scene. Final output for scenes with `VIDEO` or `GIF` components uses the local deterministic renderer path, which predecodes media into exact frame images before the browser compositor sees the scene. Browser media rendering is intentionally treated as preview-only.
52
+
53
+ ```bash
54
+ visualfries caption-scene \
55
+ --video ./input.mp4 \
56
+ --transcript ./transcript.srt \
57
+ --preset hidden-engine-center \
58
+ --output ./scene.json
59
+ ```
60
+
61
+ `--transcript` accepts JSON, SRT, or VTT. Prefer SRT/VTT when the agent already has timed subtitles from another tool.
62
+
63
+ Then QA:
64
+
65
+ ```bash
66
+ visualfries inspect ./scene.json --screenshots --samples 3 --output ./qa/frames --json
67
+ ```
68
+
69
+ ## Cue File Application
70
+
71
+ Use when an agent has a timeline map and should not write custom JavaScript.
72
+
73
+ ```bash
74
+ visualfries preset-cues --duration 45 \
75
+ --preset hidden-engine-dynamic \
76
+ --output ./cues.json
77
+
78
+ visualfries apply-cues ./scene.json \
79
+ --cues ./cues.json \
80
+ --output ./scene.with-cues.json
81
+ ```
82
+
83
+ Cue file:
84
+
85
+ ```json
86
+ {
87
+ "broll": [
88
+ { "url": "./assets/profile-scroll.mp4", "start": 2, "end": 5, "type": "VIDEO" }
89
+ ],
90
+ "overlays": [
91
+ { "text": "LOVE THIS 😍", "start": 0.4, "end": 1.1, "style": "hook-punch" },
92
+ { "text": "your move", "start": 41.5, "end": 43, "style": "cta-card" }
93
+ ],
94
+ "transitions": [
95
+ { "time": 2, "style": "dip-to-black" }
96
+ ]
97
+ }
98
+ ```
99
+
100
+ Use this as the normal agent path:
101
+
102
+ ```text
103
+ compose
104
+ ```
105
+
106
+ For debugging:
107
+
108
+ ```text
109
+ caption-scene -> preset-cues -> edit cues -> apply-cues -> inspect --screenshots -> render
110
+ ```
111
+
112
+ Available starter presets:
113
+
114
+ - `hidden-engine-dynamic`: cue skeleton for 40-60s story-driven shorts with hook/proof/mechanism/choice/CTA overlay beats.
115
+ - `captioned-clean`: minimal transition cues for caption-first videos.
116
+
117
+ ## Timed Text Overlays
118
+
119
+ Use for quick reaction beats, keyword shocks, proof callouts, and hook emphasis.
120
+
121
+ ```ts
122
+ import { addAgentTextOverlays } from 'visualfries/agent';
123
+
124
+ const withOverlays = addAgentTextOverlays({
125
+ scene,
126
+ overlays: [
127
+ { text: 'LOVE THIS 😍', start: 0.4, end: 1.1, style: 'pop-label' },
128
+ { text: 'NECK 🤯', start: 1.1, end: 1.7, style: 'shock-word' },
129
+ { text: '1M PROFIT', start: 2.0, end: 3.0, style: 'metric-badge' }
130
+ ]
131
+ });
132
+ ```
133
+
134
+ Overlay styles:
135
+
136
+ - `hook-punch`: loud yellow hook label for the first second.
137
+ - `shock-word`: large keyword reveal.
138
+ - `metric-badge`: big number/proof badge.
139
+ - `proof-pill`: smaller credibility/proof pill.
140
+ - `danger-crossout`: negative beat / wrong path callout.
141
+ - `cta-card`: final question or choice card.
142
+ - `pop-label`: generic fast reaction label.
143
+ - `soft-card`: calmer context card.
144
+
145
+ Rules:
146
+
147
+ - one overlay idea per beat,
148
+ - 0.4-1.4 seconds per overlay,
149
+ - keep captions readable,
150
+ - render sampled screenshots before final MP4.
151
+
152
+ ## B-roll Sequence
153
+
154
+ Use when an agent has portrait stock footage, generated images, screen recordings, or proof visuals.
155
+
156
+ ```ts
157
+ import { addAgentBrollSequence } from 'visualfries/agent';
158
+
159
+ const withBroll = addAgentBrollSequence({
160
+ scene,
161
+ cues: [
162
+ { url: './broll/profile.mp4', start: 2.0, end: 5.0, type: 'VIDEO' },
163
+ { url: './broll/chart.png', start: 5.0, end: 7.0, type: 'IMAGE', motion: 'slow-zoom-in' }
164
+ ]
165
+ });
166
+ ```
167
+
168
+ Layer defaults:
169
+
170
+ - b-roll layer order: `5`
171
+ - captions layer from `caption-scene`: `10`
172
+ - text overlay layer: `90`
173
+
174
+ This means b-roll naturally replaces/augments the base media while captions and overlays stay visible.
175
+
176
+ Image motion:
177
+
178
+ - `slow-zoom-in` default for images,
179
+ - `slow-zoom-out`,
180
+ - `drift-up`,
181
+ - `none`.
182
+
183
+ ## Beat Transitions
184
+
185
+ Use when a hard cut between b-roll/avatar/proof visuals needs a small cover at an exact beat.
186
+
187
+ ```ts
188
+ import { addAgentTransitions } from 'visualfries/agent';
189
+
190
+ const withTransitions = addAgentTransitions({
191
+ scene,
192
+ transitions: [
193
+ { time: 2.0, style: 'dip-to-black' },
194
+ { time: 5.0, style: 'swipe-left', color: '#04483D' }
195
+ ]
196
+ });
197
+ ```
198
+
199
+ Available styles:
200
+
201
+ - `dip-to-black` for invisible cuts,
202
+ - `flash` for punchy hook beats,
203
+ - `swipe-left` for editorial movement,
204
+ - `swipe-up` for vertical short-form movement.
205
+
206
+ Keep transition durations short, usually `0.18-0.32s`. Overusing them makes the edit feel templated.
207
+
208
+ ## Agent QA Loop
209
+
210
+ For every non-trivial scene:
211
+
212
+ ```bash
213
+ visualfries doctor --json
214
+ visualfries catalog --json
215
+ visualfries validate-cues ./cues.json --duration 45 --json
216
+ visualfries validate ./scene.json
217
+ visualfries qa ./scene.json --output ./qa
218
+ visualfries render ./scene.json --render-mode preview --output ./preview.mp4
219
+ ffprobe -v error -show_entries stream=codec_type,width,height -of json ./preview.mp4
220
+ ```
221
+
222
+ If `visualfries render` blocks a final VIDEO/GIF scene, that is expected. Do not bypass it for shipped output. The scene needs deterministic predecoded media frames before final encode.
223
+
224
+ For final contiguous MP4 renders, prefer streaming encode after QA:
225
+
226
+ ```bash
227
+ visualfries render ./scene.with-cues.json \
228
+ --stream-encode \
229
+ --image-format jpg \
230
+ --output ./out.mp4
231
+ ```
232
+
233
+ This avoids writing every final frame to disk before encode.
234
+
235
+ For static-heavy agent videos, add `--skip-duplicates` after QA:
236
+
237
+ ```bash
238
+ visualfries render ./scene.json --output ./out.mp4 --skip-duplicates
239
+ ```
240
+
241
+ The CLI uses VisualFries `renderFrameRange()` for contiguous frame ranges. Sparse QA screenshots still use direct sampled frame renders.
242
+
243
+ If screenshot samples show overlap, fix the scene JSON or cue timing before encoding the full video.