> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trainy.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Video

> Log and view video data in Pluto

## Logging

You can log video in the following formats:

* [**MP4**](https://en.wikipedia.org/wiki/MP4_file_format) - MPEG-4 Part 14 container format
* [**GIF**](https://en.wikipedia.org/wiki/GIF) - Graphics Interchange Format
* [**WebM**](https://en.wikipedia.org/wiki/WebM) - Open web media format
* [**M4A**](https://en.wikipedia.org/wiki/MPEG-4_Part_14#.m4a) - MPEG-4 Audio format
* [**OGG**](https://en.wikipedia.org/wiki/Ogg) - Free, open container format

To log a video, instantiate the `pluto.Video` class:

```python theme={null}
video = pluto.Video(
    data: Union[str, np.ndarray],
    rate: int | None = 30,
    caption: str | None = None,
    format: str | None = None,
)
pluto.log({"video/file/0-0": video}, step=step)
```

| **Parameter** | **Type**                 | **Description**                                                        |
| ------------- | ------------------------ | ---------------------------------------------------------------------- |
| `data`        | `Union[str, np.ndarray]` | The video data to log. Can be a path to a video file or a NumPy array. |
| `rate`        | `int`                    | The frame rate of the video. Defaults to 30.                           |
| `caption`     | `str`                    | A caption for the video.                                               |
| `format`      | `str`                    | The format of the video. Defaults to `mp4`.                            |

### Examples

#### Logging Videos from File Paths

```python theme={null}
path = "video.mp4"
pluto.log({"video": pluto.Video(path)}, step=step)
```

#### Logging Videos from NumPy Arrays

```python theme={null}
data = np.random.randint(low=0, high=256, size=(10, 3, 112, 112), dtype=np.uint8)
pluto.log({"video": pluto.Video(data)}, step=step)
```

## Viewing

Logged videos appear as playable widgets. Each video card includes standard playback controls (play/pause, seek) and displays the filename and associated run.

<Frame caption="Comparing multi-sample video logs across runs.">
  <video autoPlay loop muted playsInline controls className="w-full rounded-xl" src="https://mintcdn.com/trainy/RSBzmM6c9FBJXx6L/images/pluto/videos-multisample-pinning.mp4?fit=max&auto=format&n=RSBzmM6c9FBJXx6L&q=85&s=f4b11478c6538fcb9cbf005c9b148874" data-path="images/pluto/videos-multisample-pinning.mp4" />
</Frame>

When comparing multiple runs, video widgets from each run are shown together, making it easy to visually compare generated outputs or training episodes across experiments.

### Adding to a dashboard

Videos show up automatically in the Compare view. To place a video gallery on a [custom dashboard](/pluto/dashboards), open **Add Widget**, choose the **Files** tab, and search for your video log name.

<img src="https://mintcdn.com/trainy/ck7WI5896eYTYADa/images/pluto/add-widget-files-video.png?fit=max&auto=format&n=ck7WI5896eYTYADa&q=85&s=ed99d4bdf64dded6d6bc546396c6b199" alt="Adding a Files widget from the Add Widget modal" width="1352" height="1656" data-path="images/pluto/add-widget-files-video.png" />

### Step Navigation

If you log videos at multiple training steps, use the step slider below the players to browse through different steps. When multiple video groups are displayed in the same section, their step sliders can be **linked** so that changing the step on one group changes all of them simultaneously. Click the **lock icon** on the step navigator to toggle sync on or off.

### Multi-Sample Logging

Log **several videos at the same step under one log name** by passing a list. Every video renders inside the same card with a per-cell `◀  i / N  ▶` nav row below the player:

```python theme={null}
pluto.log({
    "rollouts": [pluto.Video(a), pluto.Video(b)],
}, step=10)
```

<img src="https://mintcdn.com/trainy/RSBzmM6c9FBJXx6L/images/pluto/multi-index-nav-video.png?fit=max&auto=format&n=RSBzmM6c9FBJXx6L&q=85&s=98b9132bffb611ba4ebfb0a593a387b5" alt="Two runs' video cards showing 2/3 and 1/4 multi-sample nav" style={{ maxWidth: '85%' }} width="1098" height="814" data-path="images/pluto/multi-index-nav-video.png" />

#### Sync Sample Indices

A **Sync Sample Indices** selector in the media settings popover controls how the sample index is shared:

* **Off** — each run steps through its samples independently.
* **Across runs** — every run in the same widget shares the sample index.
* **Across widgets** (default) — every run on every media widget (image, video, and audio) advances the sample index in tandem.

The selector is always available, so you can opt a single widget out of cross-widget sync. Where a card has fewer samples than the shared index, it clamps to its own last sample, and single-sample cards show no nav row.

### Pinning Runs at a Step

The global step slider forces every run to be viewed at the same step, which makes it hard to compare runs at their respective best checkpoints — different runs converge at different steps. Pinning lets you freeze individual runs at a specific step while the global slider keeps driving everything else.

Each pinned card shows a colored badge with the pinned step. Click the pin button on a video card to choose the pin scope:

| Symbol | Scope                     | Effect                                                                                                                                |
| ------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| ◇      | **Pin in this panel**     | Freezes only this card's run inside this video widget. Other widgets for the same run still follow the global stepper.                |
| ◈      | **Pin across all panels** | Freezes this run at the chosen step in every video widget on the page that shows it.                                                  |
| ★      | **Pin to best step**      | Pinned by a column-header action (see [Best-Step Pinning](#best-step-pinning) below), computed per run from a metric's argmin/argmax. |

<img src="https://mintcdn.com/trainy/RSBzmM6c9FBJXx6L/images/pluto/pin-menu-video.png?fit=max&auto=format&n=RSBzmM6c9FBJXx6L&q=85&s=8103556dc0bc1dbee8291bb696a3a5db" alt="Pin scope menu on a video card" width="810" height="420" data-path="images/pluto/pin-menu-video.png" />

#### Unpinning

Cross-panel and best-step pins offer two unpin options: **Unpin this video** removes the pin from this widget only, while **Unpin across all panels** removes it everywhere. Local single-panel pins keep the simpler one-click unpin.

<img src="https://mintcdn.com/trainy/RSBzmM6c9FBJXx6L/images/pluto/unpin-menu-video.png?fit=max&auto=format&n=RSBzmM6c9FBJXx6L&q=85&s=5a0ef41d072d745be0a547c0cc78b0fd" alt="Unpin menu on a pinned video card" width="724" height="420" data-path="images/pluto/unpin-menu-video.png" />

#### Clear All Pins

Click **Clear All Pins** to remove every pin (local, cross-panel, and best-step) at once for the current page.

### Best-Step Pinning

For metric-driven exploration (e.g. "show each run at its best loss"), pin every run on the page to its own argmin/argmax step in one click. Open a metric column's header menu in the runs table, then choose **Find best step** → one of:

| Action                               | What it pins to                                                        |
| ------------------------------------ | ---------------------------------------------------------------------- |
| **Pin steppers at min value**        | Each run pinned at the step where the metric is lowest                 |
| **Pin steppers at max value**        | Each run pinned at the step where the metric is highest                |
| **Pin steppers at min (with media)** | Lowest metric value among steps that *also* have a video for that run  |
| **Pin steppers at max (with media)** | Highest metric value among steps that *also* have a video for that run |

The **(with media)** variants (grouped under *Pin to nearest media step*) are useful when your metric and video cadences don't perfectly overlap — without them, the chosen step might land on a step that has no video, so the card falls back to the **No video at step N** placeholder.

<img src="https://mintcdn.com/trainy/ck7WI5896eYTYADa/images/pluto/find-best-step-video.png?fit=max&auto=format&n=ck7WI5896eYTYADa&q=85&s=998a499f7482fee0d0911f68832848e4" alt="Find best step menu" width="974" height="794" data-path="images/pluto/find-best-step-video.png" />

#### Tolerance Window

Even with the **(with media)** variants, your metric and video cadences may not align exactly. The best-step picker handles this with a **nearest-snap with tolerance**: each metric step snaps to its closest video step within a step-distance limit `K` (default `K = 20`).

You can edit `K` directly in the **Find best step** submenu — type a value, press Enter or click any of the four pin buttons.

**Widen the window if pins come up empty.** In the `tol-demo-gap` run below, the metric is logged at steps 0/50/100/150/200 and videos only at 25/75/125/175, so every metric step sits exactly 25 steps from the nearest video. At the default `K = 20` nothing is within tolerance and the run stays **unpinned** (plain pin icon, no step badge); raise `K` to 25 and the min-loss step (100) snaps to video step 125 — the provenance even notes the tie with step 75, broken toward the later step.

<div style={{ display: 'flex', gap: '1rem', flexWrap: 'wrap', alignItems: 'flex-start' }}>
  <img src="https://mintcdn.com/trainy/RSBzmM6c9FBJXx6L/images/pluto/tolerance-video-nopin.png?fit=max&auto=format&n=RSBzmM6c9FBJXx6L&q=85&s=e90afd49e7d38cf4a5a7696c1a042f75" alt="tol-demo-gap unpinned at K=20" style={{ width: '48%', minWidth: '260px', borderRadius: '8px' }} width="350" height="368" data-path="images/pluto/tolerance-video-nopin.png" />

  <img src="https://mintcdn.com/trainy/RSBzmM6c9FBJXx6L/images/pluto/tolerance-video-pinned.png?fit=max&auto=format&n=RSBzmM6c9FBJXx6L&q=85&s=3e62b9b25a438d7ed280b3aee1bc9546" alt="tol-demo-gap pinned at K=25" style={{ width: '48%', minWidth: '260px', borderRadius: '8px' }} width="838" height="540" data-path="images/pluto/tolerance-video-pinned.png" />
</div>

**A wider window can also find a *better* step.** When the metric keeps improving past the nearest media step, a tight window snaps to a worse value. In `tol-demo-sparse` below, `K = 10` only reaches metric step 40 (loss 0.85), while `K = 25` reaches metric step 55 — the true minimum (loss 0.1). The pinned video is the same in both (step 30); only the provenance popover reveals which metric step drove the pick.

<div style={{ display: 'flex', gap: '1rem', flexWrap: 'wrap', alignItems: 'flex-start' }}>
  <img src="https://mintcdn.com/trainy/RSBzmM6c9FBJXx6L/images/pluto/tolerance-video-bad.png?fit=max&auto=format&n=RSBzmM6c9FBJXx6L&q=85&s=acbfba82cec5c2b5c7ae4fd2f67f8bce" alt="tol-demo-sparse at K=10 reaching loss 0.85" style={{ width: '48%', minWidth: '260px', borderRadius: '8px' }} width="512" height="504" data-path="images/pluto/tolerance-video-bad.png" />

  <img src="https://mintcdn.com/trainy/RSBzmM6c9FBJXx6L/images/pluto/tolerance-video-good.png?fit=max&auto=format&n=RSBzmM6c9FBJXx6L&q=85&s=55b99b3fa24bab44ac8cb4fe5e2d37d9" alt="tol-demo-sparse at K=25 reaching loss 0.1" style={{ width: '48%', minWidth: '260px', borderRadius: '8px' }} width="512" height="504" data-path="images/pluto/tolerance-video-good.png" />
</div>

#### Pin Provenance

Every best-step pinned card shows an **info icon (ⓘ)** next to the run name. Hover for a popover that explains why this step was chosen:

* A headline with the metric and extreme that drove the pick (e.g. *Pinned at min train/loss = 0.006667*)
* The metric step that drove the pick
* How far the chosen video is from that metric step (or that it matches exactly)

<img src="https://mintcdn.com/trainy/ck7WI5896eYTYADa/images/pluto/best-step-example-video.png?fit=max&auto=format&n=ck7WI5896eYTYADa&q=85&s=5a92c5b6702cb536e89ba867967c37c9" alt="A best-step pinned video card with its provenance popover" width="572" height="556" data-path="images/pluto/best-step-example-video.png" />
