← Files FrameoARCHIVED FILE

skills/subtitles-and-cut/SKILL.md

3.89 KB · Oct 10, 2026 · 06:03 UTC

↓ Download file

---
name: subtitles-and-cut
description: "Trim, resize to 9:16 or 16:9, join clips, add a music bed, and burn captions from timings, a script, or a transcription of the footage — on footage the user already has. Free, except a transcription."
---

Needs: the user's video(s), uploaded through show_upload, imported from a web link with import_media_url, or already in Frameo; the caption text with timings, a script to fit, or nothing (the speech is transcribed)
Credits: 0 (ffmpeg is free; a music bed is ~1 per 50 characters of its prompt; transcribing the footage is a few credits per minute, charged after the run)
Time: 5–10 minutes

## When

Editing, not generating: cut a long take, make a vertical from a horizontal, join
takes, burn subtitles. Not for generating scenes.

## Ask first

1. **The footage** — links (uploaded or from `read_project`), each clip's length in
   seconds (`extract_frames` needs it; `read_project` reports `seconds` only for items the app has
   placed and saved, a generated clip's `wait_task` result has it as `duration_seconds`, and
   uploads carry none), and
   the target frame.
2. **Captions** — text with timings (SRT-like), a script to spread evenly, the footage's own
   speech (transcribed, a few credits per minute), or none.
3. **Sound** — keep the original, add a bed, or both.

## Steps

**Before anything.** `list_projects` (or `create_project`) for the `project_id` and, when the
project has several modules, the `module_id` — `extract_frames` and `run_ffmpeg` take that
pair. Nothing below spends credits. The one exception is a music bed the user wants
generated: one `generate_music` under the usual quote (`estimate_cost` with the same
project, told to the user, then the call with that `quote_id` and `confirmed_by_user=true`,
and `wait_task` for the link); a bed is at most 120 s (the tool's cap) and is looped at the
cut (`-stream_loop -1` on the bed input, `-shortest`) for longer footage.

**1. Look first (free).** `extract_frames(video_url, duration=<that clip's length>,
at_seconds=[…])` at a few timestamps to see what is in the footage before cutting; confirm the trim points with the user.

**2. Captions.** Write the `.ass` sidecar: one dialogue line per cue with start/end from
the user's timings. When only a script is given, spread the lines across the trimmed
length in proportion to their character counts and say the timing is approximate. When the
user wants the footage's own speech captioned, `analyze_media(media_url, question="Transcribe
the speech with start and end timestamps for every line", confirmed_by_user=true)` — the one
paid call with no quote: it is charged by clip length, a few credits per minute, the user is
told that and agrees first, and the finished run (`wait_task`) reports `credits_charged_estimate`.
Cues come from those timestamps, offset by the trim start.
Style: bottom-anchored, white with a dark outline, 15% of the height from the bottom
so phone UI does not cover it.

**3. The cut (free).** `run_ffmpeg` takes at most 10 inputs and 4 outputs: with more than
nine clips (plus the bed) concatenate in groups of at most 10 first — each input scaled, cropped,
`setsar=1` and set to one frame rate in that group call, since clips of different sizes do not join —
`wait_task`, and feed
those to the final call, repeating until the final call fits. That call: `-ss`/`-t` for the trim, `scale`+`crop` for 9:16
(centre crop unless the user points at a subject), `concat` for joins, `ass=subs.ass` for
captions, the bed mixed under with `amix`. Output `final.mp4`. `wait_task`, return the
link and `open_in_frameo`.

## Done

The cut on the Frameo project's canvas, shown with `show_generations` and `final: true`
where the chat app displays Frameo cards.
`open_in_frameo` on the result opens the project in the Frameo app, where every take sits on
the canvas, ready for retakes and edits.

## Files

- `ass-skeleton.md` — a minimal `.ass` file to fill in.

SHA-256: bde41eee8a1653fb74653a7e50dd61531bc4fc5e62a2ef9432ba28ab8f079f17