---
title: Make a memorial slideshow that loops and plays offline at the venue
description: A memorial or funeral slideshow, a celebration of life video, that loops for the whole service and plays from a file with no internet at the venue.
---
You get a memorial slideshow, also called a funeral slideshow or a celebration of life video, from your photos and clips. It runs with soft music and the person's name and dates, loops for the whole visitation or reception, and plays from an MP4 file on a USB stick or a laptop, with no internet at the venue.

Use invideo for this when you need it right the first time and on the day: every photo stays editable until the last minute, your agent makes one long looped file, and you download it to play offline.

## Quickest path

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

```text
Make a memorial slideshow for my father, James Okafor, 1948 to 2026,
from the photos in ./dad, oldest first. Six seconds a photo, slow
fades, gentle piano, "In loving memory" at the start. Make it loop for
two hours, export it as an MP4 and save it to ./usb. Show me frames
before you export.
```

In a chat app, you drag the photos into the project's Media panel in invideo, then name them in the chat. Then you download the file from the export card. In a terminal, you name the folder, and the agent saves the file for you.

## What you need

Ask family for photos early. Scans of old prints work well.

- **Photos and clips.** JPG, PNG, HEIC, MP4 or MOV. Name them `01.jpg`, `02.jpg` to keep the order.
- **The words.** The full name, the dates, a short line or a verse, and captions if you want them.
- **The music.** A gentle mood from stock music, or a favorite song you have the rights to play.
- **The venue's screen.** A TV with a USB port, a projector with a laptop, or a media player. Ask the venue which.
- **How long it must play.** The length of the visitation or the reception.
- **The shape.** 16:9 for almost every TV and projector.

## Steps

Your agent edits on a branch, so the family can review before anything is final.

<Steps>
<Step title="Make the slideshow">
The agent makes a project with `new_project` and a 16:9 timeline with `new_timeline`, then creates a branch with `timeline_history`. It uploads the photos with `start_upload` and `add_media`, places them in order with `insert_media`, and sets each one's length with `trim_clip`. Expected result: one clip per photo, in order.
</Step>
<Step title="Sharpen a small scan, if you need to">
For a small or soft scan, the agent runs `find_models` with the job in words, like "upscale an old photo scan", and `get_model` on its pick. A good pick is `crystal_upscaler`. Your agent can search for others with `find_models`. It calls `generate` with `source_image` set to the scan's sequence URL, `scale_factor` 2 and `dry_run: true`, and tells you the price. 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`, and swaps the new image in on the timeline. The original stays. Expected result: a sequence URL for the sharper image, which the agent reads with `read`, never with a second `generate`.
</Step>
<Step title="Add the words, fades and music">
The agent adds the name, the dates and the opening line with `add_text`, and a `fade` between photos with `add_transition`. It adds a track from `stock_music` with `search_library` and `add_media`, and fades it out with `set_audio_fades`. Portrait photos get the `fit_with_blur` effect. Expected result: a slideshow that runs once from start to end.
</Step>
<Step title="Check it with the family">
The agent runs `capture` at the title, at faces, and at the end, and `check_timeline`. It gives you the timeline URL to share for review. Expected result: frames you and the family approve.
</Step>
<Step title="Export one pass">
The agent runs `export` with `format` video, `quality` 1080 and an `idempotency_key`. It reads the export card until its status is `completed`. Expected result: a 1080p MP4 of one pass.
</Step>
<Step title="Make the long loop">
The export card is a sequence, so the agent runs `media` `video.loop` on the card's URL as it is, with `target_duration` set to the event length in seconds and an `idempotency_key`. The dry run shows its price before anything starts. Expected result: one long MP4 sequence that repeats the slideshow.
</Step>
<Step title="Download the file and test it at the venue">
In a terminal, the agent saves the looped file with `invideo notebook show` and `--out`, then renames `export.mp4` to a name like `james-memorial.mp4`. In a chat app, you download it from the sequence, whose `file` link `read` returns. You copy it to a USB stick or the laptop, play it on the venue's TV or player from start to end, and turn on the player's repeat setting as a backup. Expected result: the file plays, the sound is right, and the text fits the screen.
</Step>
</Steps>

The same job from a terminal:

```bash
invideo project new --title "James Okafor memorial"
invideo agent register <project-url> --name <name>
export INVIDEO_AS=<name>
invideo edit new <project-url> --name "Memorial"
invideo asset upload <edit-url> ./dad/*
invideo gen models <project-url> --query "upscale an old photo scan"
invideo gen model <project-url> --model crystal_upscaler
invideo gen run <page-url> --model crystal_upscaler --dry-run \
  -i source_image=<scan-sequence-url> -i scale_factor=2
invideo gen run <page-url> --model crystal_upscaler \
  --max-credits <price> --idempotency-key scan-1 \
  -i source_image=<scan-sequence-url> -i scale_factor=2
invideo edit show <edit-url>
invideo edit change <edit-url> --timeline T1 --token <state_token> \
  --operations @ops.json
invideo edit capture <edit-url> --at 0,30,90,300 --out ./frames
invideo edit export <edit-url> --format video --quality 1080 \
  --idempotency-key james-1 --json
invideo status <card-url> --wait
invideo notebook show <card-url> --out ./usb
invideo media video.loop <card-url> --target-duration 7200 --dry-run
invideo media video.loop <card-url> --target-duration 7200 \
  --max-credits <price> --idempotency-key james-loop-1
invideo status <loop-sequence-url> --wait
invideo notebook show <loop-sequence-url> --out ./usb/loop
```

Where each value comes from:

- `<name>` is the name you choose in `invideo agent register`. `INVIDEO_AS` passes it to every later command.
- `<project-url>` comes from `invideo project new`, and `<edit-url>` from `invideo edit new`. `<state_token>` comes from `invideo edit show`.
- The `crystal_upscaler` lines are only for a small scan. `<scan-sequence-url>` is the URL `invideo asset upload` returns for that photo. `<page-url>` is a notebook page; `invideo notebook show <project-url>` lists them. `<price>` is the dry run's `.estimated_credits`, or `credits` on the `video.loop` dry run.
- `ops.json` holds a bare list of operations, such as `insert_media`, `trim_clip`, `add_text` and `add_transition`.
- `<card-url>` is `.sequences[0]` of the export result. `<loop-sequence-url>` is the URL the paid `video.loop` run returns.
- `invideo notebook show` saves the export as `./usb/export.mp4`, whatever `--file-name` says. Rename each file after it lands.

The key MCP call is the full `media` call that makes the long loop from the exported video. `<card-url>` is the export card's URL, from the `export` result.

```json
{
  "url": "<card-url>",
  "op": "video.loop",
  "target_duration": 7200,
  "idempotency_key": "james-loop-1"
}
```

To loop on the timeline instead, the agent nests the slideshow with `nest_clips`, copies it with `duplicate_clip`, and adds a `fade` at each seam with `add_transition`. Then one export has the whole loop.

## 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:** uploads, the slideshow, the export and the download.
- **Tool ops:** `video.loop`. The dry run shows its price before anything starts.
- **Costs credits:** paid stock music, and a sharper scan with `crystal_upscaler`. Your own music file costs nothing.

The slideshow takes the agent a few minutes. A long export and loop take longer, so make the file well before the service. See [Credits and what they cost](/account/credits) for prices.

## If something goes wrong

Most problems happen at the venue, so test the file there before the day.

| 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. |
| 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. |
| The venue TV does not open the file | Try the laptop with a video player app, or ask the venue for a media player. Keep a second copy on the laptop. |
| The file is too big for the USB stick | Use a larger stick, or loop for less time and turn on the player's repeat setting. |
| The download link stopped working | Download links expire. `read` the export card or the sequence again for a new one. |
| The music is too loud in the room | Export again with a lower `target_lufs`, or turn the venue volume down. |
| A jump where the loop repeats | Add a fade to black at the start and the end with `add_edge_transition`, then export and loop again. |
| Status `failed` on the export | The agent reads the card for the reason, fixes it, and exports once more with a new `idempotency_key`. |
| Avoid: playing from the export page at the venue | Instead: play the downloaded file. Venue internet is often weak. |
| Avoid: making the file on the morning of the service | Instead: make and test it well before the day. |
| A photo in the review frames is wrong | The agent removes it with `delete_clip`, places the right photo with `insert_media`, then runs `capture` again. |

## Prompts to try

Each prompt is a real variation of the job.

```text
Make a celebration of life video for Aunt Maria from ./maria. Bright,
warm music, her favorite quote at the start, and a caption with the
year on each photo. One hour loop.
```

```text
Make a short funeral slideshow, about five minutes, to play once during
the service. Include the two video clips in ./clips with their sound,
and "Forever loved" at the end.
```

```text
Make two versions on two branches: a 16:9 loop for the venue TV, and a
vertical one minute version to share with family on WhatsApp.
```

## When to use something else

invideo does not burn DVDs. If the venue only has a DVD player, use a DVD burning app with the MP4 file.

For a livestream of the service, use a streaming service. invideo makes files, not live broadcasts.

## Related

- [Make a photo slideshow for any occasion: anniversary, graduation, retirement, baby's first year, family recap](/how-to/personal/occasion-slideshow)
- [Animate a photo, or make a pet memorial from one picture](/how-to/personal/animate-a-photo)
- [Make a video with ChatGPT, Claude or Gemini](/how-to/personal/with-chatgpt-claude-gemini)
- [Check your video before you say it is done](/how-to/check-your-video)
- [Add music and sound effects that clear rights](/how-to/creators/music-and-sound-effects)