remotion-composition

安装量: 55
排名: #13412

安装

npx skills add https://github.com/ncklrs/startup-os-skills --skill remotion-composition

Remotion Composition

Generates composition structure documents that define how scenes are ordered, timed, and transitioned in a Remotion video. This skill focuses exclusively on Sequence layout and timing orchestration.

What This Skill Does

Generates composition structure for:

Sequence layout — Ordering and positioning of scene Sequences Timing calculations — Start frames, end frames, duration for each scene Scene transitions — Overlap and crossfade timing between scenes Duration mapping — Converting seconds to frames for all scenes Timing constants — Structured timing object for constants.ts Scope Boundaries

IN SCOPE:

Sequence component organization Frame calculations for scene timing Scene overlap and transition timing Duration constant generation Scene ordering logic

OUT OF SCOPE:

Scene component implementation (use /remotion-component-gen) Animation parameters (use /remotion-animation) Visual styling (colors, layouts) Asset management (use /remotion-asset-coordinator) Input/Output Formats Input Format: Scene List with Durations

Accepts scene timing specifications:

Natural Language:

Scene 1 (Intro): 0-5 seconds Scene 2 (Features): 5-15 seconds Scene 3 (Demo): 15-25 seconds Scene 4 (CTA): 25-30 seconds

Structured Format:

Scene Timing

Total Duration: 30 seconds Frame Rate: 30 fps Total Frames: 900

Scenes: 1. Scene 1 - Intro: 5 seconds (0s - 5s) 2. Scene 2 - Features: 10 seconds (5s - 15s) 3. Scene 3 - Demo: 10 seconds (15s - 25s) 4. Scene 4 - CTA: 5 seconds (25s - 30s)

Transitions: - Fade transition between scenes: 0.5 seconds (15 frames)

Output Format: COMPOSITION_STRUCTURE.md

Generates composition structure document:

Composition Structure: ProductDemo

Status

✅ Sequence layout defined ✅ Timing calculations complete ⏳ Ready for scene implementation

Composition Overview

Total Duration: 30 seconds (900 frames @ 30fps) Scenes: 4 Transitions: Crossfade (15 frames)

Scene Timing Constants

```typescript const FPS = 30;

export const SCENE_TIMING = { intro: { start: 0, end: 150, duration: 150, // 0s - 5s }, features: { start: 150, end: 450, duration: 300, // 5s - 15s }, demo: { start: 450, end: 750, duration: 300, // 15s - 25s }, cta: { start: 750, end: 900, duration: 150, // 25s - 30s }, } as const;

// Transition timing export const TRANSITIONS = { crossfadeDuration: 15, // frames (0.5 seconds) } as const;

Composition Layout

Main composition with Sequence structure:

import { AbsoluteFill, Sequence } from "remotion"; import { SCENE_TIMING } from "./constants"; import { Scene1Intro } from "./scenes/Scene1Intro"; import { Scene2Features } from "./scenes/Scene2Features"; import { Scene3Demo } from "./scenes/Scene3Demo"; import { Scene4CTA } from "./scenes/Scene4CTA";

export function ProductDemo() { return ( {/ Scene 1: Intro (0s - 5s) /}

  {/* Scene 2: Features (5s - 15s) */}
  <Sequence
    from={SCENE_TIMING.features.start}
    durationInFrames={SCENE_TIMING.features.duration}
  >
    <Scene2Features />
  </Sequence>

  {/* Scene 3: Demo (15s - 25s) */}
  <Sequence
    from={SCENE_TIMING.demo.start}
    durationInFrames={SCENE_TIMING.demo.duration}
  >
    <Scene3Demo />
  </Sequence>

  {/* Scene 4: CTA (25s - 30s) */}
  <Sequence
    from={SCENE_TIMING.cta.start}
    durationInFrames={SCENE_TIMING.cta.duration}
  >
    <Scene4CTA />
  </Sequence>
</AbsoluteFill>

); }

Scene Timing Breakdown Scene Name Duration Frames Start Frame End Frame 1 Intro 5s 150 0 150 2 Features 10s 300 150 450 3 Demo 10s 300 450 750 4 CTA 5s 150 750 900

Total: 30 seconds (900 frames)

Timeline Visualization Frame: 0 150 450 750 900 Time: 0s 5s 15s 25s 30s |---------|---------|---------|---------| Scene: | Intro | Features| Demo | CTA | |---------|---------|---------|---------|

Next Steps Implement scenes via /remotion-component-gen Add transitions if needed (crossfades, wipes) Integrate constants into composition constants.ts Test timing in Remotion preview Adjust durations if scenes feel too fast/slow Checklist Scene timing calculated Sequence layout defined Constants generated Timing constants structured Scene components implemented (next step) Transitions added (if needed) Timing tested in preview

Composition Patterns

Pattern 1: Sequential Scenes (No Overlap)

Standard sequential layout where scenes don't overlap:

```typescript

Pattern 2: Overlapping Scenes (Crossfade)

Scenes overlap for smooth transitions:

const CROSSFADE = 15; // frames

// Scene 1: Full duration

// Scene 2: Starts before Scene 1 ends

// Scene 3: Starts before Scene 2 ends

Pattern 3: Layered Composition

Background + foreground scenes running simultaneously:

{/ Background layer - runs full duration /}

{/ Foreground scenes - sequential /}

Pattern 4: Nested Sequences

Sub-scenes within main scenes:

{/ Sub-scene 1 /}

{/* Sub-scene 2 */}
<Sequence from={100} durationInFrames={200}>
  <MainContent />
</Sequence>

Timing Calculation Helpers

Common frame calculations:

// Convert seconds to frames const secondsToFrames = (seconds: number, fps: number = 30): number => Math.round(seconds * fps);

// Calculate scene timing interface SceneTiming { start: number; end: number; duration: number; }

const calculateSceneTiming = ( startSeconds: number, durationSeconds: number, fps: number = 30 ): SceneTiming => { const start = secondsToFrames(startSeconds, fps); const duration = secondsToFrames(durationSeconds, fps); const end = start + duration;

return { start, end, duration }; };

// Calculate crossfade overlap const calculateCrossfade = ( scene1Start: number, scene1Duration: number, crossfadeDuration: number ) => ({ scene1: { from: scene1Start, durationInFrames: scene1Duration, }, scene2: { from: scene1Start + scene1Duration - crossfadeDuration, durationInFrames: crossfadeDuration, // or more if scene is longer }, });

// Validate total duration const validateDuration = ( scenes: SceneTiming[], expectedTotal: number ): boolean => { const lastScene = scenes[scenes.length - 1]; return lastScene.end === expectedTotal; };

Scene Timing Generation

Automated timing generation from scene list:

interface SceneSpec { name: string; durationSeconds: number; }

const generateSceneTiming = ( scenes: SceneSpec[], fps: number = 30 ) => { let currentFrame = 0; const timing: Record = {};

for (const scene of scenes) { const duration = secondsToFrames(scene.durationSeconds, fps);

timing[scene.name] = {
  start: currentFrame,
  end: currentFrame + duration,
  duration,
};

currentFrame += duration;

}

return { timing, totalFrames: currentFrame, totalSeconds: currentFrame / fps, }; };

// Usage: const scenes = [ { name: 'intro', durationSeconds: 5 }, { name: 'features', durationSeconds: 10 }, { name: 'demo', durationSeconds: 10 }, { name: 'cta', durationSeconds: 5 }, ];

const result = generateSceneTiming(scenes, 30); // Result: // { // timing: { // intro: { start: 0, end: 150, duration: 150 }, // features: { start: 150, end: 450, duration: 300 }, // ... // }, // totalFrames: 900, // totalSeconds: 30, // }

Transition Patterns Crossfade Transition

Smooth opacity crossfade between scenes:

const CROSSFADE = 15;

// Scene 1 - fades out at end

// Scene 2 - fades in at start

// In Scene component: function Scene1({ crossfadeOut = 0 }) { const frame = useCurrentFrame(); const { durationInFrames } = useVideoConfig();

const opacity = crossfadeOut > 0 ? interpolate( frame, [durationInFrames - crossfadeOut, durationInFrames], [1, 0], { extrapolateRight: 'clamp' } ) : 1;

return ...; }

Hard Cut Transition

No transition, instant scene change:

Slide Transition

One scene slides out while next slides in:

const TRANSITION_DURATION = 20;

Duration Validation

Ensuring timing adds up correctly:

// Validation helper const validateCompositionTiming = ( scenes: Record, expectedDuration: number, fps: number ): { valid: boolean; issues: string[] } => { const issues: string[] = [];

// Check for gaps const sceneList = Object.entries(scenes).sort((a, b) => a[1].start - b[1].start);

for (let i = 0; i < sceneList.length - 1; i++) { const currentEnd = sceneList[i][1].end; const nextStart = sceneList[i + 1][1].start;

if (nextStart > currentEnd) {
  issues.push(`Gap detected: ${currentEnd} to ${nextStart} (${(nextStart - currentEnd) / fps}s)`);
}
if (nextStart < currentEnd) {
  issues.push(`Overlap detected: ${sceneList[i][0]} and ${sceneList[i + 1][0]}`);
}

}

// Check total duration const lastScene = sceneList[sceneList.length - 1][1]; if (lastScene.end !== expectedDuration) { issues.push( Total duration mismatch: expected ${expectedDuration}, got ${lastScene.end} (${lastScene.end / fps}s) ); }

return { valid: issues.length === 0, issues, }; };

Timeline Visualization Helper

Generate ASCII timeline:

const generateTimeline = ( scenes: Record, fps: number, width: number = 60 ) => { const lastScene = Object.values(scenes).reduce((max, scene) => scene.end > max ? scene.end : max, 0 );

const timeline: string[] = [];

// Frame markers const frameMarkers = Array.from({ length: width + 1 }, (_, i) => { const frame = Math.round((i / width) * lastScene); return frame.toString().padStart(4); }).join(''); timeline.push('Frame: ' + frameMarkers);

// Time markers const timeMarkers = Array.from({ length: width + 1 }, (_, i) => { const time = ((i / width) * lastScene) / fps; return time.toFixed(1) + 's'; }).join(' '); timeline.push('Time: ' + timeMarkers);

// Scene bars for (const [name, timing] of Object.entries(scenes)) { const startPos = Math.round((timing.start / lastScene) * width); const endPos = Math.round((timing.end / lastScene) * width); const bar = ' '.repeat(startPos) + '|' + '='.repeat(endPos - startPos - 1) + '|'; timeline.push(${name.padEnd(8)}: ${bar}); }

return timeline.join('\n'); };

Best Practices Timing Guidelines // Minimum scene duration for readability const MIN_SCENE_DURATION = 30; // 1 second at 30fps

// Standard transition duration const STANDARD_TRANSITION = 15; // 0.5 seconds

// Maximum scene duration before pacing feels slow const MAX_SCENE_DURATION = 600; // 20 seconds

// Recommended scene duration range const IDEAL_SCENE_DURATION = { min: 60, // 2 seconds max: 300, // 10 seconds };

Composition Organization // Group related Sequences // Good: <> {/ Background layer /}

{/ Content scenes /} </>

// Bad: Mixed layers without organization

Integration Workflow Define scene durations → Input to this skill Generate composition structure → COMPOSITION_STRUCTURE.md Add to composition file (index.tsx) Add timing to constants (constants.ts) Implement scenes via /remotion-component-gen Test timing in preview Adjust if needed and regenerate Integration with Other Skills

This skill coordinates with:

remotion-composition (this skill) ↓ outputs: COMPOSITION_STRUCTURE.md remotion-component-gen ↓ implements scenes with timing awareness remotion-animation ↓ animation timing works within scene durations

Works with:

/motion-designer — Scene timing from design specs /remotion-scaffold — Structure added to composition file /remotion-animation — Timing coordinates with animation configs /remotion-component-gen — Scenes fit within calculated durations /remotion-spec-translator — Orchestrates this skill in pipeline

This skill provides precise composition structure and timing calculations that ensure smooth, well-paced Remotion videos.

返回排行榜