Combine recordings
Join several storyboards into one video with sequence.json, and insert a new feature clip into the middle of an existing demo without re-recording it.
A sequence.json joins several storyboards, each with its own recording, into one MP4. The AI app can write it for you, or you write it yourself. The main use is to add a new feature to a demo you already made: you record only the new part, and the old recording stays untouched.
Insert a feature clip into a demo#
Say demo.json is a finished demo, and the feature you want to show belongs after second 42 of its recording. You do not re-record the demo and you do not edit its storyboard. You do three things.
- Record the feature on its own and write a storyboard for it,
feature/feature.json. Start it with"extends": "../demo.json"so it takes the demo's look: theme, voice, output size and music. See Share a look with extends. - Write
sequence.jsonnext todemo.json. List the demo twice, split at second 42, and put the feature between the two halves. - Validate and render.
The feature storyboard only needs what is different:
{
"extends": "../demo.json",
"source": "rec.mp4",
"segments": [{ "in": 0, "out": 12 }],
"captions": [{ "at": 1, "text": "New: recurring invoices", "style": "title" }],
"narration": [{ "at": 1, "text": "Invoices can now repeat on a schedule." }]
}
And the sequence:
{
"version": 1,
"parts": [
{ "storyboard": "demo.json", "to": 42 },
{ "storyboard": "feature/feature.json", "transition": { "type": "crossfade", "dur": 0.5 } },
{ "storyboard": "demo.json", "from": 42, "transition": { "type": "crossfade" } }
]
}
screenpilot sequence-validate sequence.json
screenpilot sequence sequence.json -q draft
screenpilot check sequence.mp4 --at 5,40,50
screenpilot sequence sequence.json -q delivery -o demo-with-feature.mp4
The result plays the demo up to second 42, crossfades into the feature clip, then crossfades back and plays the rest of the demo. The demo's intro plays once at the start and its outro once at the end.
from and to are source seconds of that storyboard, the same seconds you use for zooms and captions. Pick the split from a frame: screenpilot frames demo.mp4 --at 42 --grid.The sequence file#
Paths in sequence.json are relative to the sequence file. screenpilot sequence-schema (or the sequence_schema tool) prints the authoritative JSON Schema.
| Field | Default | Meaning |
|---|---|---|
version | 1 | Format version. Always 1. |
parts | required | Storyboards in playing order. At least one. The same storyboard can appear more than once. |
output | first part's output | width, height and fps for the whole video. Fields you give here override the first part's output. |
Part fields#
| Field | Default | Meaning |
|---|---|---|
storyboard | required | Path to a storyboard, relative to the sequence file. |
from | the start | Source second this part starts at. |
to | the end | Source second this part ends at. |
transition | cut | How this part enters from the previous one. See Transitions. Ignored on the first part. |
What every part shares#
- One output size. All parts are rendered at the same width, height and frame rate, even if their storyboards say different things.
- One intro, one outro.
introplays only on the first part andoutroonly on the last. The other parts' cards are left out. - Your files stay as they are. ScreenPilot writes a derived storyboard for each part into a build folder.
Source ranges: from and to#
from and to keep only the range [from, to) of a storyboard's source time. The range is half-open: something at exactly to belongs to the part that starts there. That is why {"to": 42} followed by {"from": 42} keeps every item of the demo exactly once.
| Item | What happens at the edges |
|---|---|
| Segments | Cut to the range. If nothing is left, the sequence is invalid. |
| Narration | Kept when it starts inside the range. A line that started before from is dropped, because a line cannot resume in the middle of a word. |
| Zooms, captions, highlights | Cut to the range. One that straddles an edge is shortened. If less than 0.5 seconds is left, it is dropped. |
| Holds, chapter cards | Kept when their at is inside the range. |
| Overlays | An overlay with at is cut to the range like a zoom. An overlay without at (a logo for the whole video) is kept in every part. |
| Camera view | The view in force at from carries in, so the second half does not start on the wrong window or monitor. |
sequence-validate warns when to is past the end of the source.
Transitions#
transition on a part says how it enters from the previous part. It has a type and an optional dur.
| Type | What the viewer sees |
|---|---|
cut | A plain cut. This is the default. |
crossfade | The previous part fades into this one. |
fade-black | The previous part fades to black, then this one fades in. |
wipe-left, wipe-right | This part is revealed by a wipe in that direction. |
slide-left, slide-right | This part slides in over the previous one in that direction. |
dur is the number of seconds the two parts overlap. It defaults to 0.5 and is clamped to half the length of either neighbouring part, so a short clip never disappears into a long transition. Audio crossfades together with the picture.
Render a sequence#
| Command | What it does |
|---|---|
screenpilot sequence-validate <sequence> | Checks the sequence and every storyboard it uses. It fails with the schema issues, or prints valid: true with the warnings of each part. |
screenpilot sequence <sequence> | Renders every part and joins them. Flags: -o, --output (default <sequence>.mp4), -q, --quality (draft, looks, delivery), --png-frames, --workers, --build-dir. |
screenpilot sequence-schema | Prints the JSON Schema of sequence.json. |
The same steps are the tools sequence_validate, sequence_render (inputs sequence, output, quality) and sequence_schema. See MCP tools.
- Unchanged parts are reused. Each part is rendered like a storyboard into
<sequence>.build/part-N/. On the next run, a part whose storyboard, recording, events, music, overlays and quality are the same is not rendered again. Editing the feature clip does not re-render the demo. - The join. When every part is cut to the next and they are encoded the same way, the parts are joined by stream copy, with no quality loss. With a transition, or when the encodings differ, the video is re-encoded. The result tells you which one happened in
join(copyorencode). - The result. The command prints the output path, the duration,
joinand each part with its duration, whether it was reused and its warnings.
-q draft first, then look at frames with screenpilot check around each join. Use -q delivery only for the final file.Limits#
sequencehas no--from,--toor--formats. To review one part quickly, render its storyboard withscreenpilot render --from --to. For another size, setoutputin the sequence.- A part keeps its own recording and its own narration. Nothing is shared between parts except the output size, the intro on the first part and the outro on the last.
- A storyboard that fails validation fails the sequence. The error names the part, for example
parts[1] (feature/feature.json).