> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://uploadcare.com/docs/llms.txt.

# Videoframe

> Videoframe gets a still image from any video at a given timestamp on the fly, with a single CDN URL.

Videoframe returns a single still image taken from a video at the timestamp you
specify. It works on the fly, like other CDN operations: there is no processing
job to start, nothing to poll, and no new file added to your project.

The workflow is the same as with other CDN operations. The only difference is
the `videoframe` URL directive should be included after the `/` separator, not
`/-/`, and it takes the timestamp as a path segment:

```cdn
https://:subdomain.ucarecd.net/:uuid/videoframe/:timestamp/
```

`:subdomain` is your project's subdomain — find it in [Delivery](https://app.uploadcare.com/projects/-/settings/#delivery).

[`/:uuid/videoframe/00:00:01/`](https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/00:00:01/)

[`/:uuid/videoframe/5s/`](https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/5s/)

This feature works for video files only. A file counts as a video when its file
information has the `content_info.video` key (see the
[file info example](https://uploadcare.com/docs/api/rest/file/info)). For any
other file you'll get an HTTP 400 error.

## Timestamp \[#timestamp]

`/videoframe/:timestamp/`

Sets the position in the video the frame is taken from. Two forms are
supported.

* **Clock form** — `HH:MM:SS` with optional fractional seconds,
  `HH:MM:SS.mmm`.\

  Hours range from `00` to `99`, minutes and seconds from `00` to `59`. All
  parts are zero-padded to two digits.\

  Examples: `00:00:05`, `00:01:23.500`, `01:00:00`.
* **Seconds form** — a number of seconds followed by `s`.\

  Takes a non-negative integer or a decimal value.\

  Examples: `30s`, `30.5s`.

A timestamp that doesn't match either form returns an HTTP 400 error. Notably,
the clock form has to be fully padded and can't be shortened: `0:00:05`,
`00:05`, and `00:60:00` are all invalid.

The timestamp also has to fall within the video. You can read the video length
from the `content_info.video.duration` field of the
[file information object](/docs/api/rest/file/info) — it's given in
milliseconds.

[`/:uuid/videoframe/00:00:01/`](https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/00:00:01/)

[`/:uuid/videoframe/00:00:02.500/`](https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/00:00:02.500/)

[`/:uuid/videoframe/3.5s/`](https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/3.5s/)

## Output \[#output]

The extracted frame is always a **PNG** image at the video's native resolution.
There is no size argument — use [image operations](#operations) to scale or
convert it.

The frame is served with `Content-Type: image/png` and shown in the browser
rather than downloaded:

```text
content-type: image/png
content-disposition: inline; filename=frame-00-00-02.png
```

The default filename is built from the timestamp, with `:` replaced by `-`. You
can set your own filename the same way as
[for any other file](/docs/cdn-operations/#cdn-filename), by adding it after
the trailing slash:

```cdn
https://:subdomain.ucarecd.net/:uuid/videoframe/00:00:02/poster.png
```

## Transform the extracted frame \[#operations]

The frame goes through the regular image pipeline, so you can append any
[image operations](/docs/transformations/image/) after it — resize, crop,
format conversion, quality, effects, overlays, and the
[JSON](/docs/cdn-operations/#operation-json) request:

[`/:uuid/videoframe/00:00:01/-/resize/300x/`](https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/00:00:01/-/resize/300x/)

[`/:uuid/videoframe/00:00:01/-/resize/300x/-/format/jpeg/`](https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/00:00:01/-/resize/300x/-/format/jpeg/)

[`/:uuid/videoframe/00:00:01/-/scale_crop/300x300/smart/`](https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/00:00:01/-/scale_crop/300x300/smart/)

This is how you get a poster image in the format and size you need, in one
request:

```html
<video poster="https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/videoframe/00:00:01/-/resize/1280x/-/format/jpeg/poster.jpg" controls>
  <source src="https://examples.ucarecd.net/e879b607-e881-4f2e-8788-9c3297f28db6/" type="video/mp4"/>
</video>
```

The `-/json/` operation describes the extracted frame, not the source video:

```json
{
  "id": "e879b607-e881-4f2e-8788-9c3297f28db6",
  "format": "PNG",
  "width": 1920,
  "height": 1080,
  "sequence": false,
  "hash": "cbc9c9cbc0373634"
}
```

Operation permissions and project-level transformation settings apply the same
way as for image URLs.

## Caching \[#caching]

The extracted frame is cached per timestamp: the first request for a given
timestamp extracts the frame and takes longer, while all following requests for
the same timestamp are served from the cache. Different timestamps are
extracted and cached independently.

Any image operations you append are applied on top of that cached frame, so
switching from `-/resize/300x/` to `-/resize/600x/` doesn't re-extract
anything. Every complete URL gets its own CDN cache entry and is served as an
immutable response.

## Videoframe vs. video thumbnails \[#vs-thumbnails]

[Video processing](/docs/transformations/video-encoding/) can also produce
thumbnails with the [`thumbs`](/docs/transformations/video-encoding/#operation-thumbs)
operation. The two features solve different problems:

|                     | **Videoframe**                                    | **Video thumbnails**                          |
| ------------------- | ------------------------------------------------- | --------------------------------------------- |
| API                 | CDN URL, on the fly                               | [REST API](/docs/api/rest/) conversion job    |
| Selecting the frame | An exact timestamp you specify                    | `N` evenly spaced frames, or the middle frame |
| Result              | A cached CDN response, no new file                | Files in your project, in a thumbnails group  |
| Best for            | Posters, previews, and stills at a known position | A set of thumbnails to pick from or store     |

## Errors \[#errors]

| **Code** | **Reason**                                                                                                                     |
| -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| 400      | The timestamp doesn't match a supported format, the timestamp is past the end of the video, or the source file is not a video. |
| 403      | Transformations are disabled for the project, or one of the appended operations is not allowed.                                |
| 404      | There is no file with the requested UUID.                                                                                      |