@lalalic/markcut 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/.env.example +27 -0
  2. package/.github/user-steer.md +9 -0
  3. package/.vscode/settings.json +3 -0
  4. package/AGENTS.md +271 -0
  5. package/README.md +219 -0
  6. package/SKILL.md +209 -0
  7. package/docs/dynamic-components.md +191 -0
  8. package/docs/edit-mode.md +220 -0
  9. package/docs/json-descriptive.md +539 -0
  10. package/docs/label-mode.md +110 -0
  11. package/docs/markdown-descriptive.md +751 -0
  12. package/docs/templates.md +52 -0
  13. package/package.json +64 -0
  14. package/remotion.config.ts +5 -0
  15. package/scripts/artlist-dl.mjs +190 -0
  16. package/scripts/build-pipeline.sh +19 -0
  17. package/scripts/build-player.sh +20 -0
  18. package/src/Root.tsx +55 -0
  19. package/src/config.mjs +88 -0
  20. package/src/context/EventContext.tsx +168 -0
  21. package/src/context/index.tsx +42 -0
  22. package/src/descriptive/compiler.test.ts +1135 -0
  23. package/src/descriptive/compiler.ts +1230 -0
  24. package/src/descriptive/dsl.ts +455 -0
  25. package/src/descriptive/markdown.test.ts +866 -0
  26. package/src/descriptive/markdown.ts +674 -0
  27. package/src/descriptive/resolve.test.ts +951 -0
  28. package/src/descriptive/resolve.ts +891 -0
  29. package/src/entry.tsx +163 -0
  30. package/src/index.ts +4 -0
  31. package/src/player/browser.tsx +356 -0
  32. package/src/player/bundle/player.js +60259 -0
  33. package/src/player/bundler.mjs +269 -0
  34. package/src/player/label-server.mjs +599 -0
  35. package/src/player/pipeline.mjs +11123 -0
  36. package/src/player/pipeline.ts +117 -0
  37. package/src/player/server-shared.mjs +144 -0
  38. package/src/player/server.mjs +1006 -0
  39. package/src/render/cli-tools.ts +177 -0
  40. package/src/render/cli.mjs +628 -0
  41. package/src/schema/index.ts +259 -0
  42. package/src/types/Audio.tsx +56 -0
  43. package/src/types/Component.tsx +135 -0
  44. package/src/types/Effect.tsx +88 -0
  45. package/src/types/Folder.tsx +180 -0
  46. package/src/types/FrameSyncStyle.tsx +51 -0
  47. package/src/types/Image.tsx +51 -0
  48. package/src/types/Include.tsx +394 -0
  49. package/src/types/Map.tsx +252 -0
  50. package/src/types/Rhythm.tsx +58 -0
  51. package/src/types/Scene.tsx +42 -0
  52. package/src/types/Subtitle.tsx +218 -0
  53. package/src/types/Video.tsx +70 -0
  54. package/src/types/keyframes.ts +454 -0
  55. package/src/utils/__tests__/vtt.test.ts +129 -0
  56. package/src/utils/index.ts +168 -0
  57. package/src/utils/tween.ts +118 -0
  58. package/src/vision/cli.mjs +1187 -0
  59. package/src/vision/vision_prompts.md +67 -0
  60. package/tests/dsl.test.ts +317 -0
  61. package/tests/fixtures/audio.json +25 -0
  62. package/tests/fixtures/basic.json +27 -0
  63. package/tests/fixtures/component-all.json +38 -0
  64. package/tests/fixtures/components.json +38 -0
  65. package/tests/fixtures/effects.json +64 -0
  66. package/tests/fixtures/full.json +51 -0
  67. package/tests/fixtures/map.json +23 -0
  68. package/tests/fixtures/md/all-nodes.md +28 -0
  69. package/tests/fixtures/md/basic.md +6 -0
  70. package/tests/fixtures/md/component-imports.md +20 -0
  71. package/tests/fixtures/md/edge-cases.md +33 -0
  72. package/tests/fixtures/md/effects.md +17 -0
  73. package/tests/fixtures/md/frontmatter.md +20 -0
  74. package/tests/fixtures/md/full-feature.md +58 -0
  75. package/tests/fixtures/md/imports-block.md +19 -0
  76. package/tests/fixtures/md/include-main.md +11 -0
  77. package/tests/fixtures/md/include-sub.md +25 -0
  78. package/tests/fixtures/md/jsx-code-fence.md +21 -0
  79. package/tests/fixtures/md/map.md +11 -0
  80. package/tests/fixtures/md/nested-scenes.md +25 -0
  81. package/tests/fixtures/md/rhythm.md +17 -0
  82. package/tests/fixtures/md/scenes.md +16 -0
  83. package/tests/fixtures/md/tween.md +11 -0
  84. package/tests/fixtures/md/vars-test.md +6 -0
  85. package/tests/fixtures/scenes.json +40 -0
  86. package/tests/fixtures/subtitle.json +59 -0
  87. package/tests/fixtures/subvideo.json +59 -0
  88. package/tests/fixtures/templates/courseware.md +351 -0
  89. package/tests/fixtures/tween-visual.json +28 -0
  90. package/tests/fixtures/video-series.json +54 -0
  91. package/tests/md-descriptive.test.ts +742 -0
  92. package/tests/render.test.ts +985 -0
  93. package/tests/schema.test.ts +68 -0
  94. package/tests/server.test.ts +308 -0
  95. package/tests/utils.ts +391 -0
  96. package/tests/vitest.config.ts +18 -0
  97. package/tests/vitest.integration.config.ts +16 -0
  98. package/tsconfig.json +20 -0
@@ -0,0 +1,6 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## Intro
4
+ layout:parallel
5
+ - image src:cover.jpg duration:2
6
+ - video src:clip.mp4 volume:0.8
@@ -0,0 +1,20 @@
1
+ ---
2
+ width: 640
3
+ height: 480
4
+ fps: 30
5
+ ---
6
+ # video
7
+ layout:series
8
+ ## Demo
9
+ layout:parallel
10
+ - component duration:2 jsx:"<Hello name='World' />"
11
+ - component duration:3 jsx:"<PieChart data={[{value:40,color:'#E38627'},{value:30,color:'#C13C37'},{value:20,color:'#6A2135'}]} lineWidth={20} />"
12
+
13
+ ```js imports
14
+ import { PieChart } from "npm:react-minimal-pie-chart"
15
+ import { Hello } from "git:user/repo/path/to/Hello.tsx"
16
+
17
+ export function Hello({ name }) {
18
+ return <div style={{color: '#fff', fontSize: 24, textAlign: 'center'}}>Hello {name}!</div>
19
+ }
20
+ ```
@@ -0,0 +1,33 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## Empty
4
+ layout:parallel
5
+ - include
6
+ ## SpecialChars
7
+ layout:parallel
8
+ - image src:"my photo.jpg" duration:2
9
+ - audio src:"bgm (copy).mp3" duration:3 volume:0.5
10
+ ## QuotedScripts
11
+ layout:parallel
12
+ - image src:a.jpg duration:2
13
+ - script "Special chars: #hash, $dollar, %percent, &ampersand"
14
+ - video src:b.mp4 duration:3
15
+ - script "Path with spaces: /Users/me/my video.mp4"
16
+ ## LongDuration
17
+ layout:parallel
18
+ - image src:long.jpg duration:60
19
+ ## ZeroDuration
20
+ layout:parallel
21
+ - component duration:0 jsx:"<Test />"
22
+ ## VisibleFalse
23
+ layout:parallel
24
+ - image src:hidden.jpg duration:2 visible:false
25
+ - image src:shown.jpg duration:2
26
+ ## BackgroundAudio
27
+ layout:parallel
28
+ - audio src:bgm.mp3 duration:10 volume:0.2 isBackground:true
29
+ ## StartOffsets
30
+ layout:parallel
31
+ - image src:a.jpg duration:3 start:1
32
+ - image src:b.jpg duration:2 start:0
33
+ - image src:c.jpg duration:4 start:2
@@ -0,0 +1,17 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## Fades
4
+ layout:parallel
5
+ - image src:card1.jpg duration:2 effects:[fadeIn(3)]
6
+ - image src:card2.jpg duration:2 effects:[fadeOut(3)]
7
+ ## Slides
8
+ layout:parallel
9
+ - image src:card3.jpg duration:2 effects:[slideInLeft(3)]
10
+ - image src:card4.jpg duration:2 effects:[slideInRight(3)]
11
+ ## Attention
12
+ layout:parallel
13
+ - image src:card5.jpg duration:2 effects:[bounceIn(,ease-out,2)]
14
+ - image src:card6.jpg duration:2 effects:[pulse(,ease-in-out)]
15
+ ## CustomKeyframes
16
+ layout:parallel
17
+ - image src:card7.jpg duration:2 effects:[{"animation":"custom","duration":3,"customKeyframes":{"0":{"opacity":"0","transform":"scale(0.5)"},"50":{"opacity":"0.5","transform":"scale(1.2)"},"100":{"opacity":"1","transform":"scale(1)"}}}]
@@ -0,0 +1,20 @@
1
+ ---
2
+ # (frontmatter is metadata only — video config comes from root key-value line)
3
+ ---
4
+ # video
5
+ width:640 height:480 fps:30 layout:series tts:"edge-tts --voice 'en-US-GuyNeural' --text '{input}' --write-media '{output}'" stt:"whisper '{input}' --output_format vtt --output_dir '{output}' --model whisper-1 --language zh"
6
+ ## Demo
7
+ layout:parallel
8
+ - component duration:2 jsx:"<StatCounter value={42} label='Test' />"
9
+ - component duration:2 jsx:"<Banner text='Hello' />"
10
+ - component duration:1 jsx:"<InlineBadge text='Hot' />"
11
+
12
+ ```js imports
13
+ import { StatCounter } from "npm:stat-counter"
14
+ import { Logo } from "github:foo/bar/src/Logo.tsx"
15
+ import { Banner } from "https://cdn.example.com/banner.js"
16
+
17
+ export function InlineBadge({ text }) {
18
+ return <span style={{color:"#fff",background:"#333",padding:"4px 8px",borderRadius:"4px"}}>{text}</span>
19
+ }
20
+ ```
@@ -0,0 +1,58 @@
1
+ ---
2
+ ---
3
+ # video
4
+ width:1080 height:1920 fps:30 layout:series instruction:"Full feature demo video" metadata:"v2.0-feature-test" tts:"edge-tts --voice 'zh-CN-XiaoxiaoNeural' --text '{input}' --write-media '{output}'"
5
+ ## OpeningHook
6
+ layout:parallel instruction:"Start with animated headline and BGM"
7
+ - script "Welcome to this demo video"
8
+ - component duration:3 jsx:"<AnimatedHeadline text='Welcome!' gradient='#667eea→#764ba2' />"
9
+ - audio src:bgm/intro.mp3 duration:3 volume:0.3 isBackground:true
10
+ ## StatShowcase
11
+ layout:series
12
+ ### Counter1
13
+ layout:parallel
14
+ - component duration:3 jsx:"<StatCounter value={100} label='Performance' />"
15
+ ### Counter2
16
+ layout:parallel
17
+ - component duration:3 jsx:"<StatCounter value={99} label='Quality' suffix='%' />"
18
+ ## MediaMontage
19
+ layout:transitionSeries transition:fade transitionTime:0.5
20
+ - script "Here are some highlights"
21
+ - image src:photos/highlight1.jpg duration:2 fit:cover
22
+ - video src:clips/moment1.mp4 duration:3 volume:0.8
23
+ - image src:photos/highlight2.jpg duration:2 fit:cover
24
+ - video src:clips/moment2.mp4 startFrom:0.5 endAt:4.5 volume:0.9
25
+ ## AnimatedEffects
26
+ layout:parallel
27
+ - image src:cards/card1.png duration:1.5 fit:contain effects:[fadeInUp(2)]
28
+ - image src:cards/card2.png duration:1.5 fit:contain effects:[zoomIn(2,ease-out)]
29
+ - image src:cards/card3.png duration:1.5 fit:contain effects:[flipInX(2,,1)]
30
+ ## InteractiveMap
31
+ layout:parallel
32
+ - script "Our journey across the continent"
33
+ - map duration:6 travelMode:DRIVING waypoints:[37.77,-122.41,"San Francisco";40.7128,-74.006,"New York City"] routeColor:"#FF6B6B" routeWeight:5 zoom:4 mapType:roadmap routeMarker:"🚗"
34
+ - audio src:bgm/map-music.mp3 duration:6 volume:0.25 isBackground:true
35
+ ## BeatSync
36
+ layout:parallel
37
+ - rhythm src:audio/drop.mp3 spots:[0.0,0.6,1.2,1.8,2.4,3.0] volume:0.8
38
+ - image src:flash/f1.jpg
39
+ - image src:flash/f2.jpg
40
+ - image src:flash/f3.jpg
41
+ - image src:flash/f4.jpg
42
+ - image src:flash/f5.jpg
43
+ - image src:flash/f6.jpg
44
+ ## Closing
45
+ layout:parallel
46
+ - script "Thanks for watching! Don't forget to subscribe"
47
+ - image src:photos/ending.jpg duration:4 fit:cover
48
+ - component duration:4 jsx:"<Logo variant='white' />"
49
+
50
+ ```js imports
51
+ import { AnimatedHeadline } from "npm:@remotion-engine/headline"
52
+ import { StatCounter } from "npm:stat-counter@2.1.0"
53
+
54
+ export function Logo({ variant = 'white' }) {
55
+ const color = variant === 'white' ? '#ffffff' : '#667eea';
56
+ return <div style={{color, fontSize: 48, fontWeight: 'bold'}}>MyBrand</div>
57
+ }
58
+ ```
@@ -0,0 +1,19 @@
1
+ ---
2
+ width: 640
3
+ height: 480
4
+ fps: 30
5
+ ---
6
+ # video
7
+ layout:series
8
+ ## Charts
9
+ layout:parallel
10
+ - component duration:2 jsx:"<PieChart data={[{name:'A',value:50},{name:'B',value:50}]} />"
11
+ - component duration:2 jsx:"<Hello name='World' />"
12
+
13
+ ```js imports
14
+ import { PieChart } from "npm:recharts"
15
+
16
+ export function Hello({ name }) {
17
+ return <div style={{color: '#fff', fontSize: 24}}>Hello {name}</div>
18
+ }
19
+ ```
@@ -0,0 +1,11 @@
1
+ # main-video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## Intro
4
+ layout:parallel
5
+ - component duration:2 jsx:"<div style={{background:'#1a1a2e',width:'100%',height:'100%',display:'flex',alignItems:'center',justifyContent:'center'}}><h1 style={{color:'#e94560',fontSize:36}}>Main Video</h1></div>"
6
+ ## EmbeddedContent
7
+ layout:parallel
8
+ - include src:./include-sub.md
9
+ ## Outro
10
+ layout:parallel
11
+ - component duration:2 jsx:"<div style={{background:'#16213e',width:'100%',height:'100%',display:'flex',alignItems:'center',justifyContent:'center'}}><h1 style={{color:'#0f3460',fontSize:36}}>The End</h1></div>"
@@ -0,0 +1,25 @@
1
+ # sub-video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## SubScene1
4
+ layout:parallel
5
+ - component duration:3 jsx:"<SubSlide bg='#667eea' scene='1' />"
6
+ ## SubScene2
7
+ layout:parallel
8
+ - component duration:3 jsx:"<SubSlide bg='#764ba2' scene='2' />"
9
+
10
+ ```js imports
11
+ export function SubSlide({ bg, scene }) {
12
+ return <div style={{
13
+ background: bg,
14
+ width: '100%',
15
+ height: '100%',
16
+ display: 'flex',
17
+ alignItems: 'center',
18
+ justifyContent: 'center',
19
+ flexDirection: 'column'
20
+ }}>
21
+ <h1 style={{color:'white', fontSize:48, margin:0}}>Sub Video</h1>
22
+ <p style={{color:'rgba(255,255,255,0.8)', fontSize:24}}>Scene {scene}</p>
23
+ </div>;
24
+ }
25
+ ```
@@ -0,0 +1,21 @@
1
+ ---
2
+ width: 640
3
+ height: 480
4
+ fps: 30
5
+ ---
6
+ # video
7
+ layout:series
8
+ ## Demo
9
+ layout:parallel
10
+ - component duration:2 jsx:"<Greeting name='World' />"
11
+ - component duration:3 jsx:"<Counter value={100} />"
12
+
13
+ ```js imports
14
+ export function Greeting({ name }) {
15
+ return <div style={{color: '#fff', fontSize: 28, textAlign: 'center'}}>Hello {name}!</div>
16
+ }
17
+
18
+ export function Counter({ value }) {
19
+ return <div style={{color: '#667eea', fontSize: 64, fontWeight: 'bold', textAlign: 'center'}}>{value}</div>
20
+ }
21
+ ```
@@ -0,0 +1,11 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## RoadTrip
4
+ layout:parallel
5
+ - map duration:5 travelMode:DRIVING waypoints:[37.77,-122.41,"San Francisco";34.05,-118.24,"Los Angeles";36.16,-115.15,"Las Vegas"] routeColor:"#FF5733" routeWeight:6 zoom:8 mapType:roadmap routeMarker:"🚗"
6
+ ## WalkingTour
7
+ layout:parallel
8
+ - map duration:4 travelMode:WALKING waypoints:[48.8566,2.3522,"Paris";48.8575,2.3644,"Louvre"] mapType:hybrid zoom:15 routeMarker:"🚶" routeColor:"#33FF57" routeWeight:3
9
+ ## DetailedWaypoints
10
+ layout:parallel
11
+ - map duration:3 waypoints:[35.6762,139.6503,"Tokyo";35.7146,139.7967,"Asakusa";35.7101,139.8107,"Skytree"] travelMode:TRANSIT mapType:satellite zoom:12 routeMarker:"🗼"
@@ -0,0 +1,25 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## Chapter1
4
+ layout:series instruction:"Opening chapter" title:"The Beginning"
5
+ ### Shot1
6
+ layout:parallel
7
+ - image src:dawn.jpg duration:2
8
+ - audio src:ambient.mp3 duration:2 volume:0.3
9
+ ### Shot2
10
+ layout:parallel
11
+ - image src:road.jpg duration:3
12
+ - component duration:2 jsx:"<Narration text='A journey begins' />"
13
+ ## Chapter2
14
+ layout:series
15
+ ### Shot3
16
+ layout:parallel
17
+ - image src:mountain.jpg duration:2
18
+ ### Shot4
19
+ layout:transitionSeries transition:fade transitionTime:0.3
20
+ - image src:peak1.jpg duration:2
21
+ - image src:peak2.jpg duration:2
22
+ - image src:peak3.jpg duration:2
23
+ ## Chapter3
24
+ layout:parallel
25
+ - image src:sunset.jpg duration:3
@@ -0,0 +1,17 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## MusicDrop
4
+ layout:parallel
5
+ - rhythm src:beat.mp3 spots:[0.0,0.5,1.0,1.5] volume:0.9
6
+ - image src:flash1.jpg
7
+ - image src:flash2.jpg
8
+ - image src:flash3.jpg
9
+ - image src:flash4.jpg
10
+ ## SlowRhythm
11
+ layout:parallel
12
+ - rhythm src:ambient.mp3 spots:[0.0,1.2,2.5,3.8,5.0] volume:0.6
13
+ - image src:scene1.jpg
14
+ - image src:scene2.jpg
15
+ - image src:scene3.jpg
16
+ - image src:scene4.jpg
17
+ - image src:scene5.jpg
@@ -0,0 +1,16 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## Hook
4
+ layout:parallel instruction:"Grab attention fast"
5
+ - image src:opener.jpg duration:2 fit:cover
6
+ - component duration:2 jsx:"<BigText text='Wow!' />"
7
+ ## Journey
8
+ layout:transitionSeries transition:fade transitionTime:0.5
9
+ - script "Follow along on this adventure"
10
+ - image src:scene1.jpg duration:2
11
+ - image src:scene2.jpg duration:2
12
+ - image src:scene3.jpg duration:3
13
+ ## WrapUp
14
+ layout:parallel
15
+ - script "Thanks for watching"
16
+ - image src:final.jpg duration:3 fit:cover
@@ -0,0 +1,11 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## BarChartAnim
4
+ layout:parallel
5
+ - component duration:4 jsx:"<svg viewBox='0 0 400 300'><rect y={260-tween(0,200)} width={80} height={tween(0,200)} fill='#E38627' /><rect x={100} y={260-tween(0,160)} width={80} height={tween(0,160)} fill='#C13C37' /><rect x={200} y={260-tween(0,240)} width={80} height={tween(0,240)} fill='#6A2135' /></svg>"
6
+ ## NivoBarChart
7
+ layout:parallel
8
+ - component duration:4 jsx:"<BarChart data={[{name:'A',value:tween(0,80)},{name:'B',value:tween(0,60)},{name:'C',value:tween(0,100)}]} keys={['value']} indexBy='name' />"
9
+ ## ColorTween
10
+ layout:parallel
11
+ - component duration:3 jsx:"<div style={{background:tween('#000','#FFF'), width:200, height:200, borderRadius: tween(0,100)}} />"
@@ -0,0 +1,6 @@
1
+ # video
2
+ width:640 height:480 fps:30 layout:series
3
+ ## Test
4
+ layout:parallel
5
+ - image src:photo_${width}x${height}.jpg duration:2
6
+ - component duration:3 jsx:"<div style={{width:'100%',height:'100%',background:'#333',display:'flex',alignItems:'center',justifyContent:'center'}}><h1 style={{color:'white',fontSize:32}}>Size: ${width}x${height}</h1></div>"
@@ -0,0 +1,40 @@
1
+ {
2
+ "id": "root",
3
+ "type": "root",
4
+ "width": 640,
5
+ "height": 480,
6
+ "fps": 30,
7
+ "isSeries": true,
8
+ "transition": "fade",
9
+ "transitionTime": 0.3,
10
+ "children": [
11
+ {
12
+ "id": "scene-1",
13
+ "type": "scene",
14
+ "name": "Intro",
15
+ "description": "Opening hook with headline animation",
16
+ "children": [
17
+ {
18
+ "id": "scene-1-headline",
19
+ "type": "component",
20
+ "jsx": "<div style={{background:'linear-gradient(135deg,#667eea,#764ba2)',padding:'30px',borderRadius:'12px',textAlign:'center'}}><h2 style={{color:'white',fontSize:'28px',margin:0}}>Scene Rendering Works</h2><p style={{color:'rgba(255,255,255,0.7)',fontSize:'14px',marginTop:'8px'}}>Testing the scene type in stream tree</p></div>",
21
+ "actions": [{ "start": 0, "end": 3 }]
22
+ }
23
+ ]
24
+ },
25
+ {
26
+ "id": "scene-2",
27
+ "type": "scene",
28
+ "name": "Conclusion",
29
+ "description": "Final message",
30
+ "children": [
31
+ {
32
+ "id": "scene-2-headline",
33
+ "type": "component",
34
+ "jsx": "<div style={{background:'linear-gradient(135deg,#764ba2,#667eea)',padding:'30px',borderRadius:'12px',textAlign:'center'}}><h2 style={{color:'white',fontSize:'28px',margin:0}}>Test Complete</h2><p style={{color:'rgba(255,255,255,0.7)',fontSize:'14px',marginTop:'8px'}}>All scene types render correctly</p></div>",
35
+ "actions": [{ "start": 0, "end": 2 }]
36
+ }
37
+ ]
38
+ }
39
+ ]
40
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "id": "root",
3
+ "type": "root",
4
+ "width": 640,
5
+ "height": 480,
6
+ "fps": 30,
7
+ "isSeries": true,
8
+ "transition": "fade",
9
+ "transitionTime": 0.3,
10
+ "stylesheet": ".caption { background: rgba(0,0,0,0.4); padding: 12px 24px; border-radius: 12px; }",
11
+ "subtitle": {
12
+ "src": "WEBVTT\n\n00:00:00.500 --> 00:00:03.500\nRoot-level subtitle overlay\n\n00:00:04.500 --> 00:00:07.500\nSecond scene caption\n\n00:00:08.500 --> 00:00:12.000\nThird scene caption",
13
+ "fontSize": 48
14
+ },
15
+ "children": [
16
+ {
17
+ "id": "scene-1",
18
+ "type": "folder",
19
+ "isSeries": false,
20
+ "children": [
21
+ {
22
+ "id": "bg1",
23
+ "type": "image",
24
+ "src": "https://picsum.photos/seed/sub1/640/480",
25
+ "fit": "cover",
26
+ "actions": [{ "start": 0, "end": 4 }]
27
+ }
28
+ ]
29
+ },
30
+ {
31
+ "id": "scene-2",
32
+ "type": "folder",
33
+ "isSeries": false,
34
+ "children": [
35
+ {
36
+ "id": "bg2",
37
+ "type": "image",
38
+ "src": "https://picsum.photos/seed/sub2/640/480",
39
+ "fit": "cover",
40
+ "actions": [{ "start": 0, "end": 4 }]
41
+ }
42
+ ]
43
+ },
44
+ {
45
+ "id": "scene-3",
46
+ "type": "folder",
47
+ "isSeries": false,
48
+ "children": [
49
+ {
50
+ "id": "bg3",
51
+ "type": "image",
52
+ "src": "https://picsum.photos/seed/sub3/640/480",
53
+ "fit": "cover",
54
+ "actions": [{ "start": 0, "end": 5 }]
55
+ }
56
+ ]
57
+ }
58
+ ]
59
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "id": "root",
3
+ "type": "root",
4
+ "width": 640,
5
+ "height": 480,
6
+ "fps": 30,
7
+ "isSeries": true,
8
+ "transition": "fade",
9
+ "transitionTime": 0.3,
10
+ "children": [
11
+ {
12
+ "id": "intro",
13
+ "type": "folder",
14
+ "isSeries": false,
15
+ "children": [
16
+ {
17
+ "id": "bg-intro",
18
+ "type": "image",
19
+ "src": "https://picsum.photos/seed/subv-intro/640/480",
20
+ "fit": "cover",
21
+ "actions": [{ "start": 0, "end": 2 }]
22
+ },
23
+ {
24
+ "id": "title-intro",
25
+ "type": "component",
26
+ "jsx": "<div style={{background:'#667eea',color:'white',padding:'30px',borderRadius:'12px',textAlign:'center'}}><h2 style={{margin:0,fontSize:'28px'}}>Main Video</h2></div>",
27
+ "actions": [{ "start": 0, "end": 2 }]
28
+ }
29
+ ]
30
+ },
31
+ {
32
+ "id": "subvideo-chapter",
33
+ "type": "include",
34
+ "name": "Embedded-Reel",
35
+ "src": "data:application/json;base64,eyJpZCI6InJvb3QiLCJ0eXBlIjoicm9vdCIsIndpZHRoIjo2NDAsImhlaWdodCI6NDgwLCJmcHMiOjMwLCJpc1NlcmllcyI6dHJ1ZSwidHJhbnNpdGlvbiI6ImZhZGUiLCJ0cmFuc2l0aW9uVGltZSI6MC4zLCJjaGlsZHJlbiI6W3siaWQiOiJzdWItc2NlbmUtMSIsInR5cGUiOiJmb2xkZXIiLCJpc1NlcmllcyI6ZmFsc2UsImNoaWxkcmVuIjpbeyJpZCI6InN1Yi1iZy0xIiwidHlwZSI6ImltYWdlIiwic3JjIjoiaHR0cHM6Ly9waWNzdW0ucGhvdG9zL3NlZWQvc3Vidi1pbm5lcjEvNjQwLzQ4MCIsImZpdCI6ImNvdmVyIiwiYWN0aW9ucyI6W3sic3RhcnQiOjAsImVuZCI6Mn1dfV19LHsiaWQiOiJzdWItc2NlbmUtMiIsInR5cGUiOiJmb2xkZXIiLCJpc1NlcmllcyI6ZmFsc2UsImNoaWxkcmVuIjpbeyJpZCI6InN1Yi1iZy0yIiwidHlwZSI6ImltYWdlIiwic3JjIjoiaHR0cHM6Ly9waWNzdW0ucGhvdG9zL3NlZWQvc3Vidi1pbm5lcjIvNjQwLzQ4MCIsImZpdCI6ImNvdmVyIiwiYWN0aW9ucyI6W3sic3RhcnQiOjAsImVuZCI6Mn1dfV19XX0=",
36
+ "actions": [{ "start": 0, "end": 4 }]
37
+ },
38
+ {
39
+ "id": "outro",
40
+ "type": "folder",
41
+ "isSeries": false,
42
+ "children": [
43
+ {
44
+ "id": "bg-outro",
45
+ "type": "image",
46
+ "src": "https://picsum.photos/seed/subv-outro/640/480",
47
+ "fit": "cover",
48
+ "actions": [{ "start": 0, "end": 2 }]
49
+ },
50
+ {
51
+ "id": "title-outro",
52
+ "type": "component",
53
+ "jsx": "<div style={{background:'#764ba2',color:'white',padding:'30px',borderRadius:'12px',textAlign:'center'}}><h2 style={{margin:0,fontSize:'28px'}}>Back to Main</h2></div>",
54
+ "actions": [{ "start": 0, "end": 2 }]
55
+ }
56
+ ]
57
+ }
58
+ ]
59
+ }