← FrameoCONTENT HISTORY

Update to Frameo

Snapshot Oct 8, 2026 · 18:02 UTC · version 1.2.1

Collection source: downloaded plugin package.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "One person on camera delivers a script: a face (photo or designed), a fixed voice, lipsynced delivery, optional title card, cut to length.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 372
    },
    {
      "relative_path": "assets/icon.svg",
      "size_in_bytes": 405
    }
  ],
  "name": "talking-presenter",
  "skill_md_contents": "---\nname: talking-presenter\ndescription: \"One person on camera delivers a script: a face (photo or designed), a fixed voice, lipsynced delivery, optional title card, cut to length.\"\n---\n\nNeeds: a script; a photo of the presenter or a description; optionally a brand colour or logo\nCredits: about 1,000–2,100 for a 30–60 second piece (lipsync is the main cost: ~20 credits per second of clip)\nTime: 10–20 minutes\n\n## When\n\nUse for one person speaking to camera: an explainer, a founder message, a course intro, an\nannouncement, a customer-support answer. Any language the voice catalog covers.\n\nNot for: several characters in scenes (`script-to-video`), or narration over other footage\n(`faceless-story-video`).\n\n## Ask first\n\n1. **Who** — a photo (`show_upload` for files on the user's device, `import_media_url` for a web link; images attached to the chat do not reach Frameo, and `create_upload_url` is for clients that send the file themselves) or a description to design from.\n2. **Voice** — the user's preference in words (warm, brisk, older, Hindi, British…); pick 3\n   with `search_voices` and show their names.\n3. **Frame** — 9:16 or 16:9, and whether a title card opens the piece.\n\nSay the rough cost (the script's length decides it) in the same turn as the questions; the user's yes comes with the plan (Steps, **The plan first.**).\n\n## Steps\n\n**Before any paid step.** The project: `list_projects` (or `create_project`) gives the `project_id`\nand, when the project has several modules, the `module_id`; every call below that takes a project —\n`estimate_cost` included — gets that same pair; without it those tools answer `project_needed`. The\nquote: one `estimate_cost(items=[…])` prices a stage in one call, with the same project, model,\nsize and number of `image_urls` or `reference_image_urls` (`reference_count`) as each generate call, and returns a `quote_id` per item plus the total. Each generate call\nthen passes its own item's `quote_id` and `confirmed_by_user=true`. A quote is single-use and lasts\n15 minutes, so a long plan is priced stage by stage, right before each stage runs; a stage that\ncomes to more than the user approved is asked about again first. Generate calls return\n`generation_ids`; `wait_task` returns the links, and `show_generations` shows each stage's running\nand finished work in one card where the chat app displays Frameo cards: all the stage's ids at\nonce, before its first `wait_task`, and the finished result with `final: true`.\n\n**The plan first.** Before the first paid call, the plan goes to the user in the chat as plain\ntext: what will be made, in order, one line per generation (for a script, the shot list; for a\nset, each shot), with each line's credits and the total. The credits come from\n`estimate_cost(items=[…])`, up to 10 items a call, so a long plan takes several calls; those\nquotes may expire unused, since each stage is quoted again right before it runs. Nothing is\ngenerated until the user says yes. The user can drop or change lines; a changed line is priced\nagain.\n\n**Canvas rows.** Pass `shot_number` on every `generate_image` and `generate_video` of a shot (1, 2, 3… in story order; the same number for a retake and for that shot's video), so each shot gets its own row on the Frameo canvas. Cast, prop and location references take `placement_kind` (`character`, `prop` or `location`) and the subject's name as `placement_group` instead: they sit on their own board, and the shots built from them do not pile into their row.\n\n**1. The presenter still (~18 credits).** `generate_image`: a mid-shot of the presenter facing\ncamera, neutral background unless the user wants one, `image_urls=[photo]` when there is a\nphoto. `wait_task`, show it; adjust once if asked.\n\n**2. The voice (~1 credit per 50 characters).** `generate_speech(text=script, voice_id)` in one\ncall when the whole script fits one clip (15 s, the lipsync's cap, or the video model's max from\n`list_models(kind=\"video\")` when that is lower); otherwise split at sentence breaks — and at clause breaks (commas, dashes) when one\nsentence alone is still too long — so each file fits one clip. `wait_task` gives the link; play it back to the user before spending on video. The result's\n`duration_seconds`, the file's measured spoken length, is its raw estimate, kept as is for the\nlipsync; a result without one is estimated at 2.8 words per second (2.5 for Hindi) plus one\nsecond of headroom, and that estimate is approximate. When the user picks a presenter\n`list_characters` already has in the project, its first image is the still and its `voice_id` the\nvoice. A new\npresenter is saved with `save_character` under a name not already in the cast (the same name\nreplaces that character's voice), with `image_urls=[presenter still]` and the `voice_id`, so later\nvideos in this project reuse the same face and voice.\n\n**3. The clip (~65 credits per 5 s + ~20 per second of lipsync).** For each speech file:\n`generate_video` from the still (`first_frame_url`) with a prompt like \"presenter speaking\nto camera, subtle natural head movement, steady framing\", `duration` = that file's raw\nestimate rounded up to whole seconds, kept inside the video model's range\n(`list_models(kind=\"video\")`; 4–30 s on the default) and at most 15 s — step 2 sized the files to\nthat, and a file that measures a little longer still goes in whole as `audio_duration`,\n`wait_task`, then `generate_lipsync(video_url, audio_url, duration, audio_duration=the raw\nestimate, aspect_ratio, resolution)` — the raw one, so a clamped clip is still extended to\nthe speech; the size the clip was made at; and `duration` never above 15 s, the lipsync's\nown cap, whatever the video model allows — and\n`wait_task`. Test the first clip\nbefore the rest.\n\n**4. Title card (free).** If wanted: `render_motion_graphics` with `template=\"title_card\"`, the title\n(and a `subtitle`), the piece's `size` and a `duration` of 2 to 3 s; `wait_task` returns the card's clip,\njoined in front in the cut. It counts against the 30 runs per clock hour.\n\n**5. Cut (free).** With a title card, one pass of its own first: the card comes at full HD in its\n`size`, so it is scaled to the clips' size (`scale`, then `setsar=1`) and given a bounded silent\ntrack (`-f lavfi -t <card seconds> -i anullsrc=r=<the clips' sample rate>:cl=stereo`); an\nunbounded `anullsrc` never ends and stalls the join. Then `run_ffmpeg` takes at most 10 inputs and 4 outputs:\nconcatenate the lipsynced clips in\norder, in groups of at most 10 — the card counts as an input, so nine clips per group when\none is joined in front — and repeat until the final call fits (`wait_task` after each pass;\nits outputs are the next pass's inputs). Output `final.mp4`. `wait_task`,\nreturn the link and `open_in_frameo`.\n\n## Done\n\nThe finished clip, the presenter still, and every clip in the Frameo project (chat and\ncanvas) for edits in the app.\n\n## Files\n\nNone.\n"
}

SHA-256 of public snapshot: 2a1a603099f49a7a11e83767551cfe0a7af62a72ce58443b2667c216a2dac634