# Video

Nominal stores a video as a channel on a dataset and plays it back in step with your other data. It reads MP4, MKV, AVI and MPEG-TS files with H.264 or H.265 video. To convert other video, see [Convert the video](https://dev.nominal.io/python/guides/video/video-ingest.md#convert-the-video) in the Python client’s guides. For video recorded in an MCAP file, see [MCAP video ingest](https://dev.nominal.io/python/guides/video/mcap-video-ingest.md).

## Upload a file

**Nominal app**

1. In the sidebar, click **+** (**New**), then **Upload data**. Drop the video onto **Upload files**, or click **SELECT FILES**.
2. Click **SELECT A DESTINATION** and choose **Standalone dataset**. Pick a dataset, or click **NEW DATASET**, enter a name and click **CREATE DATASET**.
3. In the video’s settings, choose or type a **Channel**, such as `camera`, and check the **Start time**. Nominal fills in the start time when the file records one.
4. Click **CONFIRM & INGEST**.

**Python**

```python
from datetime import datetime, timezone

from nominal.core import NominalClient

client = NominalClient.from_profile("default")
dataset = client.create_dataset("Flight 42 video")
file = dataset.add_video(
    "flight.mp4",
    channel="camera",
    start=datetime(2026, 1, 1, 14, 0, tzinfo=timezone.utc),  # when the first frame was recorded
)
file.poll_until_ingestion_completed()  # raises if ingestion fails
```

For LabVIEW, Rust and Go, see [Video upload](https://dev.nominal.io/quickstart/quick/quick-video.md).

## Options

| Setting | Nominal app | Python |
| --- | --- | --- |
| The channel the video plays on | **Channel** | `channel` |
| When the first frame was recorded | **Start time** | `start` |
| Each frame’s time, as epoch nanoseconds, in place of a start time | — | `frame_timestamps` |
| Delete video already on the channel that overlaps this file | **Overwrite segments** | `overwrite_overlapping` |
| A tag on the video | **Tags** | `tags` |
