---
title: Turn a webinar replay into an evergreen video with a CTA and chapters
description: Turn a long webinar recording into an evergreen replay with the dead air and waiting room cut, a call-to-action card, chapters and captions.
---
Turn a webinar recording, or a live session replay, into an evergreen video people watch on demand. Your agent cuts the dead air: the waiting room, "can you hear me", long pauses and the tech fumbles. It adds a call-to-action (CTA) card, chapter markers with a chapter list, and captions, which some people call subtitles.

Use invideo for this when the recording is long and every cut must stay reversible: the cuts are timeline edits on a branch, so you can put a section back in the editor.

The agent never publishes the replay or emails your list. You do that.

## Quickest path

Set up your agent first with [invideo for AI agents](/agents). Then give it this prompt.

```text
Turn webinar.mp4 into an evergreen replay. Cut the waiting room, the
sound checks and every pause longer than two seconds. Add a CTA card
for the demo link at the end and after the offer, chapter markers,
a chapter list for YouTube, and captions. Price the transcript first.
```

In a chat app, you drag the recording into the project. In a terminal, the agent names the file and uploads it.

## What you need

These are the inputs the agent asks for.

- The recording as an MP4 or MOV file, from Zoom, Teams, Webex or your webinar tool.
- The CTA: the words and the link to show, like "Book a demo at acme.com/demo".
- Where the CTA goes: at the end, after the offer, or both.
- What to keep from the Q and A, or all of it.
- The shape. Webinars are 16:9.

## Steps

The agent works on a branch, so the main timeline stays clean until you approve.

<Steps>
<Step title="Upload the recording">
A webinar file is large, so the agent calls `start_upload` with the file name, PUTs the bytes to the `upload_url`, then calls `add_media` with the `upload_id`. Expected result: a sequence URL for the recording.
</Step>
<Step title="Transcribe it">
The agent prices `audio.transcript` on the recording's sequence URL with `dry_run` and tells you the price. Then it starts it with `max_credits` set to that price, and calls again after `retry_after_s` for the words. It pages through the words with `offset`. Expected result: every word with its time and speaker.
</Step>
<Step title="Find the dead air">
The agent runs `media` `audio.content` for the silence spans. It reads the transcript for the waiting room, the sound checks and the "give everyone a minute" lines. It lists the spans to cut with their times and shows you the list. Expected result: your yes, or your changes.
</Step>
<Step title="Cut on a branch">
The agent makes a 16:9 timeline with `new_timeline`, creates a branch with `timeline_history`, and places the recording with `place_media` and `linked_audio` true. It cuts each span with `edit_time_range` and mode `close_gap`, from the last span to the first, so the earlier times stay true. Expected result: a new `state_token` and a shorter timeline.
</Step>
<Step title="Add chapters and the CTA">
The agent adds a marker at each topic change with `add_marker`, with a `name` for the chapter. It adds the CTA as a text card with `add_text`, with a background color and your brand colors in its `style`. Expected result: markers on the timeline and a CTA clip on its own track.
</Step>
<Step title="Add captions">
The agent moves each transcript word earlier by the time cut before it, then adds the words with `add_captions`. Expected result: a caption clip that matches the speech after the cuts.
</Step>
<Step title="Check, then export">
The agent runs `capture` at each cut, each CTA and each chapter start, and `check_timeline`. It checks every cut edge against the transcript's word times, so no cut lands inside a word. Then it runs `export` with `format` video and `target_lufs`, and runs `audio.waveform` on the export card to see that no gap or click is left. Expected result: an export card with status `completed`, and the chapter list in the chat.
</Step>
</Steps>

The terminal version of the same job:

```bash
invideo project new --title "Webinar replay"
invideo agent register <project-url> --name <name>
export INVIDEO_AS=<name>
invideo asset upload <project-url> ./webinar.mp4
invideo media audio.transcript <sequence-url> --dry-run
invideo media audio.transcript <sequence-url> --max-credits <price>
invideo media audio.content <sequence-url>
invideo edit new <project-url> --name "Replay v1"
invideo edit show <edit-url> --json
invideo branch new <edit-url> --name evergreen --token <state_token>
invideo edit show <branch-url> --json
invideo edit change <branch-url> --timeline T1 --token <state_token> \
  --operations @cut-list.json
invideo edit show <branch-url> --mode collection --collection marker
invideo edit capture <branch-url> --at 0,300,1200,2400 --out ./frames
invideo edit export <branch-url> --format video --quality 1080 \
  --target-lufs -14 --json
invideo status <card-url> --wait
invideo notebook show <card-url> --out ./out
```

Where the values come from: `<project-url>` from `invideo project new`, and `<edit-url>` from `invideo edit new`. `<name>` is the name you choose in `invideo agent register`. `<sequence-url>` is the `url` that `invideo asset upload` returns for the recording. `<price>` is the dry run's `estimated_credits`. `<state_token>` comes from `invideo edit show` on the edit, and on the branch from `invideo edit show <branch-url>`. The main token is stale there. `<branch-url>` is the `branch_url` that `invideo branch new` returns. `<card-url>` is `.sequences[0]` of what the export returns. `invideo status` does not download; `invideo notebook show` saves the file as `export.mp4`.

The key edit is the ops file `cut-list.json`, a bare list. It cuts one span, marks a chapter and adds the CTA card. At 30 fps, frame 1800 is one minute.

```json
[
  { "op": "edit_time_range", "timeline": "T1",
    "start_f": 0, "end_f": 5400, "mode": "close_gap" },
  { "op": "add_marker", "at_f": 9000, "name": "Pricing",
    "color": "#ffaa00" },
  { "op": "add_text", "track": "V3", "start_f": 54000,
    "end_f": 54450, "text": "Book a demo: acme.com/demo",
    "style": { "font_size": 64, "color": "#ffffff",
      "background_color": "#1a56dbcc", "align": "center" } }
]
```

The agent sends the cuts in one `edit_timeline` call. They land all together, or none do.

### The chapter list

The agent reads the markers with `get_timeline` mode `collection` and `collection` `marker`. It writes one line per marker: the time as minutes and seconds, then the name. YouTube reads chapters from a list like this in the description. The list starts at 00:00 and goes in order, and each chapter has a minimum length. See <a href="https://support.google.com/youtube/answer/9884579" target="_blank">YouTube's video chapters help</a>.

```text
00:00 Welcome and agenda
03:10 Why most onboarding fails
11:45 The three-step fix
24:30 Pricing
31:05 Q and A
```

## Cost and time

Edits and exports are free. Generation and transcripts cost credits. Paid stock costs a small credit charge, or one of your workspace's iStock licenses. Your agent runs a dry run first and tells you the price before it spends anything.

- Free: the upload, every cut, marker, CTA and caption edit, `capture` and `export`.
- `audio.content` and `audio.waveform`: the dry run shows the price before anything starts.
- Costs credits: `audio.transcript`, once per file. Later calls to follow it cost nothing.

The upload and transcript of a long webinar take a while. The cuts take a few minutes. See [Credits](/account/credits) for prices.

## If something goes wrong

Most problems are times that moved after a cut.

| Symptom | Fix |
| --- | --- |
| A later cut lands in the wrong place | The cuts went first to last, so times moved. Read the timeline again and cut from the last span to the first. |
| Captions run ahead of the speech | The word times were not moved for the cuts before them. Recompute and replace the caption clip. |
| A word is cut in half | Move the span's edge to the gap between words from the transcript, then cut again. |
| `audio.transcript` returns a status, not words | It is still running. Call again with the same file after `retry_after_s`. |
| The upload PUT fails | Call `start_upload` again for a new `upload_url`, and PUT once more. |
| `unavailable` | The timeline is starting. Retry the same request in a few seconds. |
| CLI exit 3 | The edit changed since your read, or the token is the main timeline's. Run `invideo edit show <branch-url>` and rebuild. |
| The download folder is empty | `invideo status` does not download. Run `invideo notebook show <card-url> --out ./out`. |
| CLI exit 7 | Nothing ran. Run the same command again. |
| Exit code 6, or `status` is `held` | A safety review, not a refusal. Wait, then run `invideo status <url> --wait` again. Do not resend. If it ends `failed`, change the input the review flagged. |
| Avoid: cutting on main | Instead: create a branch, so the full recording stays one click away. |

## Prompts to try

Each prompt is a real variation of this job.

```text
Cut this webinar to the 20-minute core talk only. Drop the Q and A.
Add a CTA card every ten minutes and at the end.
```

```text
Keep the Q and A, but cut any question nobody answered and every pause
over three seconds. Give me the chapter list for YouTube.
```

```text
Make the evergreen replay, then a second branch with only the demo
section and the CTA, for a short follow-up.
```

## When to use something else

invideo does not run the webinar, host the replay page, or send the follow-up emails. Use your webinar tool for the live session, and your video host or email tool to publish and send. A clickable button inside the player comes from your video host. In invideo, the CTA is text on screen.

## Related

- [Cut ums, pauses and retakes, as reversible timeline edits](/how-to/creators/cut-ums-and-retakes)
- [Edit a long YouTube video: cut the dead parts, add b-roll, music and captions](/how-to/creators/edit-a-long-youtube-video)
- [Add word-by-word captions](/how-to/creators/word-by-word-captions)
- [Edit a podcast episode and pull clips from it](/how-to/creators/podcast-edit-and-clips)
- [Check your video before you say it is done](/how-to/check-your-video)
- [Know the cost before you spend](/how-to/cost-before-you-spend)