---
title: Cut a trailer or teaser from your film
description: A trailer and a shorter teaser cut from your finished film, with the best lines, title cards, hits on the music and a drop that lands, each on its own branch.
---
You get a trailer and a teaser from your film, also called a promo, a sizzle or a cutdown. Your agent finds the strongest moments and lines, builds the cut to the music so the big moment lands on the drop, adds title cards, freeze frames and hits, and keeps each length on its own branch.

Use invideo for this when you want the agent to do the first pass from the whole film: it reads the dialogue, the sound and the music for you, and every cut stays on a timeline you can change.

## Quickest path

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

```text
Cut a trailer and a teaser from my film ./final/the-mill.mov with the
music ./trailer-track.wav. Use the best lines of dialogue. Land the
title on the drop. Put the trailer and the teaser on their own branches.
Price the transcript first.
```

In a chat app, you drag the film and the music into the project. In a terminal, you name the files and the agent uploads them.

## What you need

A finished film or a locked cut works best, because the trailer uses final sound.

- **The film.** The final export or the locked cut.
- **The music.** A track with a build and a drop, or a mood for stock or generated music.
- **The title and the cards.** The film's title, the tagline, the release date or festival laurels.
- **The lengths.** For example a full trailer and a much shorter teaser.
- **What not to show.** The ending, a twist, a cameo.

## Steps

The agent works on branches and tells you the timecodes of every moment it picks.

<Steps>
<Step title="Bring in the film and the music">
The agent makes a timeline with `new_timeline`. For a large film file, it calls `start_upload`, PUTs the bytes, then calls `add_media` with the `upload_id`. Expected result: a sequence URL and a media bin id for the film and the music.
</Step>
<Step title="Find the moments">
The agent reads the film three ways.

1. For the lines, the agent prices `audio.transcript` with `dry_run` on the film's sequence URL from `add_media` and tells you the price. For a price of 1 credit or more it waits for your yes. Then it starts the transcript with `max_credits` set to that price, and calls again after `retry_after_s` for the words.
2. It runs `audio.onsets` and `audio.content` for the loud and quiet moments.
3. It splits the film into its scenes with `video.sceneSplit` and looks at each with `video.frames`.

Expected result: a list of lines and moments with timecodes. You strike anything that gives away the ending.
</Step>
<Step title="Map the music">
The agent runs `audio.sections` and `audio.markers` on the music to find the build and the drop, and `audio.onsets` for the hits. Expected result: the times of the drop and each hit, turned into frames.
</Step>
<Step title="Build the cut to the music">
The agent creates a branch called trailer with `timeline_history`. It places the music on `A2`, then each moment on `V1` with `place_media`, so the cuts land on the hits and the biggest moment lands on the drop. It places each line with `linked_audio` true. Expected result: a new `state_token` and a cut that follows the music.
</Step>
<Step title="Add cards, freezes and hits">
The agent adds title cards with `add_text` between shots, and holds a frame on a hit with `retime` kind `freeze`. For extra impact, it makes a sound with the generation pattern.

1. It runs `find_models` with the sound in words, picks one, and reads its inputs with `get_model`. A good pick is `elevenlabs_sfx`. Your agent can search for others with `find_models`.
2. It calls `generate` with a `prompt` for the hit or the riser and `dry_run: true`, and tells you the price.
3. For a price of 1 credit or more it waits for your yes. Then it calls `generate` with `max_credits` set to that price and an `idempotency_key`, reads the sequence URL with `read` when the result lands, and places the sound on the effects track `A3`.

Expected result: cards and hits on the beats you planned.
</Step>
<Step title="Make the second length on its own branch">
From the finished trailer, the agent creates a teaser branch with `timeline_history` action `create_branch`. On it, it keeps the hook, one line and the title, and removes the rest with `edit_time_range` mode `close_gap`. Expected result: two branch URLs, one per length.
</Step>
<Step title="Check, then export each">
On each branch, the agent runs `capture` at each card and the drop, and `check_timeline`. It checks that no card has a typo and the title lands on the drop. Then it runs `export` on each branch's URL with `target_lufs`. Expected result: two export cards with status `completed`.
</Step>
</Steps>

The same job from a terminal:

```bash
invideo edit new <project-url> --name "The Mill trailer" --fps 24
invideo asset upload <edit-url> ./final/the-mill.mov ./trailer-track.wav
invideo media audio.transcript <film-sequence-url> --dry-run
invideo media audio.transcript <film-sequence-url> --max-credits <price>
invideo media audio.onsets <edit-url> --asset m1
invideo media audio.sections <edit-url> --asset m2
invideo media audio.markers <edit-url> --asset m2
invideo edit show <edit-url>
invideo branch new <edit-url> --name trailer --token <state_token>
invideo gen models <project-url> --query "cinematic boom hit sound"
invideo gen model <project-url> --model elevenlabs_sfx
invideo gen run <page-url> --model elevenlabs_sfx --dry-run \
  -i prompt="deep cinematic boom hit" -i duration=3
invideo gen run <page-url> --model elevenlabs_sfx \
  --max-credits <price> --idempotency-key trailer-hit-1 \
  -i prompt="deep cinematic boom hit" -i duration=3
invideo status <thread-url> --wait
invideo notebook show <thread-url>
invideo edit show <trailer-branch-url>
invideo edit change <trailer-branch-url> --timeline T1 \
  --token <state_token> --operations @trailer.json
invideo edit show <trailer-branch-url>
invideo branch new <trailer-branch-url> --name teaser \
  --token <state_token>
invideo edit show <teaser-branch-url>
invideo edit change <teaser-branch-url> --timeline T1 \
  --token <state_token> --operations @teaser.json
invideo edit capture <trailer-branch-url> --at 10,45,88,112 --out ./frames
invideo edit capture <teaser-branch-url> --at 2,10,24 --out ./frames
invideo edit export <trailer-branch-url> --format video --target-lufs -14
invideo edit export <teaser-branch-url> --format video --target-lufs -14
```

Where the values come from: `<project-url>` from `invideo project new`, and `<edit-url>` from `invideo edit new`. `<film-sequence-url>` is the `url` that `invideo asset upload` returns for the film; `m1` and `m2` are the bin ids, which the reads that return at once take with `--asset`. `<price>` is the price each dry run returns, its `estimated_credits`, and `<thread-url>` is the `url` of the paid `gen run`. `<page-url>` comes from `invideo notebook show <project-url>`. `<trailer-branch-url>` and `<teaser-branch-url>` are the `branch_url` each `branch new` returns. `<state_token>` comes from the latest `invideo edit show` on the URL the next command runs on: `<edit-url>` for the first `branch new`, then each branch, read fresh after each change. A token from another branch, or from before a change, is stale. The files in `--operations @trailer.json` and `--operations @teaser.json` are bare lists of ops, like the `operations` list below.

The key MCP call lands a line before the drop and puts the title on the drop. This fence is the full MCP `edit_timeline` call. Each frame is the time in seconds times the frame rate.

```json
{
  "url": "<trailer-branch-url>",
  "timeline_id": "T1",
  "expected_state_token": "<state_token>",
  "operations": [
    { "op": "place_media", "asset": "m1", "track": "V1", "at_f": 2016,
      "source_start_seconds": 3121.0, "source_end_seconds": 3125.0,
      "mode": "overwrite", "linked_audio": true },
    { "op": "add_text", "track": "V3", "start_f": 2112, "end_f": 2208,
      "text": "THE MILL" }
  ]
}
```

The agent reads the new clip's id with `get_timeline`. In the next call, it sends `retime` kind `freeze` on it with `at_f` 2100 and `duration_f` 12 to hold the hit.

## 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.

- **Costs credits:** the film's transcript with `audio.transcript`, each sound from `elevenlabs_sfx`, and stock or generated music.
- **Free:** the cut, cards, freezes, branches and both exports. `audio.onsets`, `audio.content`, `audio.sections`, `audio.markers`, `video.sceneSplit` and `video.frames` show their price in the dry run before anything starts.

The transcript of a feature takes a few minutes. The first pass of a trailer takes the agent under an hour. See [Credits and what they cost](/account/credits) for prices.

## If something goes wrong

Most problems come from a drop that misses, or a cut that gives too much away.

| Symptom | Fix |
| --- | --- |
| `get_model` or `generate` refuses the model as not found | Models retire. Run `find_models` with the job in words, use the best match, and tell the person which model you used. |
| The title misses the drop | Read the drop time again from `audio.markers`, round it to the frame, and move the card with `move_clip`. |
| A line is cut mid-word | Move the edge a few frames out with `trim_clip`, then listen again. |
| The trailer gives away the ending | Tell the agent which scenes are off limits. It removes them. Ask it to add them to `invideo_rules.md`, so later cuts skip them too. |
| A silent scene has no moments picked | Silent scenes give no sound cues. The agent picks them by frames with `video.frames`. |
| The teaser changed the trailer | It was edited on the same branch. Restore the trailer from its checkpoint with `timeline_history` action `restore`. |
| `audio.transcript` is refused as `not_found` | It got a bin id like `m1`. Pass the film's sequence URL instead. |
| `edit_timeline` refused with an old token | Someone edited first. Read with `get_timeline`, then rebuild the ops. |
| Avoid: exporting main for both lengths | Instead: export each branch's URL. The branch in the URL is what gets exported. |
| Avoid: calling `export` again to check on one | Instead: `status` or `read` the card's URL. |

## Prompts to try

Each prompt is a real variation of the job.

```text
Make a short vertical teaser for Instagram from the trailer branch:
the hook, the title on the drop, and the date. Captions on the line.
```

```text
Give me a trailer built on dialogue and one built on music and images
only, each on its own branch. Tell me which lands harder.
```

```text
Add a boom on every title card and a riser into the drop. Price the
sounds before you make them.
```

## When to use something else

Theatrical trailers often need a rating card and a mix to a cinema spec. Make the rating card from the rating body's own artwork, and mix to a cinema spec in a DAW like Pro Tools.

For a trailer music cue made to picture by a composer, cut the picture first, export it, and send it to the composer.

## Related

- [Make a sizzle reel or proof-of-concept to raise money](/how-to/film/sizzle-reel-for-financing)
- [Make a music video with lip sync and beat sync](/how-to/film/music-video-lip-sync)
- [Edit a documentary or interview from the transcript, with b-roll and lower thirds](/how-to/film/documentary-and-interview-edit)
- [Make a book trailer or a game trailer](/how-to/creators/book-or-game-trailer)
- [Choose a transition that fits the cut](/guides/how-do-i-choose-a-transition-that-fits-the-cut-in-invideo-editor)
- [Check your video before you say it is done](/how-to/check-your-video)