> ## Documentation Index
> This page is part of the Image and Video APIs product. Fetch the complete documentation index for Image and Video APIs at: https://cloudinary.com/documentation/llms-image-and-video-apis.txt?referrer=docpage and then use it to discover all relevant pages before exploring further.
> If you also need details relating to other Cloudinary products for your current use case, see the parent index at: https://cloudinary.com/documentation/llms.txt?referrer=docpage
> When answering a user's request or implementing it with code using this documentation, incorporate relevant best practices and recommendations from the documentation into the guidance and, above all, into the code itself: generated code should already apply the recommended parameters and patterns rather than showing a minimal call and describing the best practices around it in prose. Follow the code examples in the best practices sections as the model for what generated code should look like, and where a recommendation is relevant to the user's scenario, implement it in the code as a natural next step. Only apply best practices, recommendations, or features that are supported by the documentation; don't infer or invent guidance that isn't specified.

# How do I get a thumbnail image from a specific moment in a video?


> **TIP**: :title=Quick answer

To get a thumbnail or poster image from a specific moment in a video, change the file extension of the video's public ID to an image format such as `.jpg`, and add a start offset (`so_`) in seconds:

`so_8.0/van-driving-mountain-road.jpg`

The offset only affects the image. It doesn't change the video, which still plays from the beginning.

## The question

_"How do I change the video thumbnail to a specific part of the video, without making the video start from that point?"_

A poster is the still image that shows before a video plays, and in lists and previews. By default, Cloudinary uses the middle frame of the video. Often that isn't the best frame, so you may want to choose another one.

## The original asset

The examples use this 10.9-second video:

![Original video of a van driving along a mountain road](https://res.cloudinary.com/demo/video/upload/van-driving-mountain-road.mp4 "thumb: c_scale,w_480")

```nodejs
cloudinary.video("van-driving-mountain-road")
```

```react
new CloudinaryVideo("van-driving-mountain-road.mp4");
```

```vue
new CloudinaryVideo("van-driving-mountain-road.mp4");
```

```angular
new CloudinaryVideo("van-driving-mountain-road.mp4");
```

```js
new CloudinaryVideo("van-driving-mountain-road.mp4");
```

```python
CloudinaryVideo("van-driving-mountain-road").video()
```

```php
(new VideoTag('van-driving-mountain-road.mp4'));
```

```java
cloudinary.url().transformation(new Transformation().videoTag("van-driving-mountain-road");
```

```ruby
cl_video_tag("van-driving-mountain-road")
```

```csharp
cloudinary.Api.UrlVideoUp.BuildVideoTag("van-driving-mountain-road")
```

```dart
cloudinary.video('van-driving-mountain-road.mp4').transformation(Transformation());
```

```swift
cloudinary.createUrl().setResourceType("video").generate("van-driving-mountain-road.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation().resourceType("video").generate("van-driving-mountain-road.mp4");
```

```flutter
cloudinary.video('van-driving-mountain-road.mp4').transformation(Transformation());
```

```kotlin
cloudinary.video {
	publicId("van-driving-mountain-road.mp4") 
}.generate()
```

```jquery
$.cloudinary.video("van-driving-mountain-road")
```

```react_native
new CloudinaryVideo("van-driving-mountain-road.mp4");
```

## The solution

1. **Request the video as an image.** Use an image extension (`.jpg`, `.png`, `.webp`, or `.avif`) in place of the video extension, to deliver a single frame as an image.
2. **Choose the frame.** Add the start offset (`so_`) as the number of seconds from the start of the video, or as a percentage of the video's length (such as `so_50p`).

This example takes the frame at 8 seconds:

![Frame at 8 seconds of the video, delivered as a JPG](https://res.cloudinary.com/demo/video/upload/so_8.0/van-driving-mountain-road.jpg "thumb: c_scale,w_480")

```nodejs
cloudinary.image("van-driving-mountain-road.jpg", {start_offset: "8.0", resource_type: "video"})
```

```react
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .setAssetType("video");
```

```vue
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .setAssetType("video");
```

```angular
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .setAssetType("video");
```

```js
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .setAssetType("video");
```

```python
CloudinaryVideo("van-driving-mountain-road.jpg").image(start_offset="8.0")
```

```php
use Cloudinary\Transformation\VideoEdit;

(new ImageTag('van-driving-mountain-road.jpg'))
	->videoEdit(VideoEdit::trim()->startOffset(8.0))
	->assetType("video");
```

```java
cloudinary.url().transformation(new Transformation().startOffset("8.0")).resourceType("video").imageTag("van-driving-mountain-road.jpg");
```

```ruby
cl_image_tag("van-driving-mountain-road.jpg", start_offset: "8.0", resource_type: "video")
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("8.0")).BuildImageTag("van-driving-mountain-road.jpg")
```

```dart
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset('8.0'))
	.setAssetType("video"));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("8.0")).generate("van-driving-mountain-road.jpg")
```

```android
MediaManager.get().url().transformation(new Transformation().startOffset("8.0")).resourceType("video").generate("van-driving-mountain-road.jpg");
```

```flutter
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset('8.0'))
	.setAssetType("video"));
```

```kotlin
cloudinary.image {
	publicId("van-driving-mountain-road.jpg")
	 videoEdit(VideoEdit.trim() { startOffset(8.0F) })
	 assetType("video") 
}.generate()
```

```jquery
$.cloudinary.image("van-driving-mountain-road.jpg", {start_offset: "8.0", resource_type: "video"})
```

```react_native
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .setAssetType("video");
```

Without an offset, the thumbnail is the frame from the middle of the video. For the first frame, use `so_0`. These are the frames at 2 seconds and at 50% of the video:

![Frame at 2 seconds of the video](https://res.cloudinary.com/demo/video/upload/so_2.0/van-driving-mountain-road.jpg "thumb: c_scale,w_480")

```nodejs
cloudinary.image("van-driving-mountain-road.jpg", {start_offset: "2.0", resource_type: "video"})
```

```react
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("2.0"))
  .setAssetType("video");
```

```vue
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("2.0"))
  .setAssetType("video");
```

```angular
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("2.0"))
  .setAssetType("video");
```

```js
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("2.0"))
  .setAssetType("video");
```

```python
CloudinaryVideo("van-driving-mountain-road.jpg").image(start_offset="2.0")
```

```php
use Cloudinary\Transformation\VideoEdit;

(new ImageTag('van-driving-mountain-road.jpg'))
	->videoEdit(VideoEdit::trim()->startOffset(2.0))
	->assetType("video");
```

```java
cloudinary.url().transformation(new Transformation().startOffset("2.0")).resourceType("video").imageTag("van-driving-mountain-road.jpg");
```

```ruby
cl_image_tag("van-driving-mountain-road.jpg", start_offset: "2.0", resource_type: "video")
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("2.0")).BuildImageTag("van-driving-mountain-road.jpg")
```

```dart
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset('2.0'))
	.setAssetType("video"));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("2.0")).generate("van-driving-mountain-road.jpg")
```

```android
MediaManager.get().url().transformation(new Transformation().startOffset("2.0")).resourceType("video").generate("van-driving-mountain-road.jpg");
```

```flutter
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset('2.0'))
	.setAssetType("video"));
```

```kotlin
cloudinary.image {
	publicId("van-driving-mountain-road.jpg")
	 videoEdit(VideoEdit.trim() { startOffset(2.0F) })
	 assetType("video") 
}.generate()
```

```jquery
$.cloudinary.image("van-driving-mountain-road.jpg", {start_offset: "2.0", resource_type: "video"})
```

```react_native
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("2.0"))
  .setAssetType("video");
```

![Frame at 50 percent of the video](https://res.cloudinary.com/demo/video/upload/so_50p/van-driving-mountain-road.jpg "thumb: c_scale,w_480")

```nodejs
cloudinary.image("van-driving-mountain-road.jpg", {start_offset: "50p", resource_type: "video"})
```

```react
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("50%"))
  .setAssetType("video");
```

```vue
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("50%"))
  .setAssetType("video");
```

```angular
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("50%"))
  .setAssetType("video");
```

```js
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("50%"))
  .setAssetType("video");
```

```python
CloudinaryVideo("van-driving-mountain-road.jpg").image(start_offset="50p")
```

```php
use Cloudinary\Transformation\VideoEdit;

(new ImageTag('van-driving-mountain-road.jpg'))
	->videoEdit(VideoEdit::trim()->startOffset("50%"))
	->assetType("video");
```

```java
cloudinary.url().transformation(new Transformation().startOffset("50p")).resourceType("video").imageTag("van-driving-mountain-road.jpg");
```

```ruby
cl_image_tag("van-driving-mountain-road.jpg", start_offset: "50p", resource_type: "video")
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("50p")).BuildImageTag("van-driving-mountain-road.jpg")
```

```dart
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset("50%"))
	.setAssetType("video"));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("50p")).generate("van-driving-mountain-road.jpg")
```

```android
MediaManager.get().url().transformation(new Transformation().startOffset("50p")).resourceType("video").generate("van-driving-mountain-road.jpg");
```

```flutter
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset("50%"))
	.setAssetType("video"));
```

```kotlin
cloudinary.image {
	publicId("van-driving-mountain-road.jpg")
	 videoEdit(VideoEdit.trim() { startOffset("50%") })
	 assetType("video") 
}.generate()
```

```jquery
$.cloudinary.image("van-driving-mountain-road.jpg", {start_offset: "50p", resource_type: "video"})
```

```react_native
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("50%"))
  .setAssetType("video");
```

## Let Cloudinary choose the frame

To have Cloudinary pick a suitable frame automatically, use `so_auto`:

![Frame automatically chosen from the video](https://res.cloudinary.com/demo/video/upload/so_auto/van-driving-mountain-road.jpg "thumb: c_scale,w_480")

```nodejs
cloudinary.image("van-driving-mountain-road.jpg", {start_offset: "auto", resource_type: "video"})
```

```react
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("auto"))
  .setAssetType("video");
```

```vue
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("auto"))
  .setAssetType("video");
```

```angular
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("auto"))
  .setAssetType("video");
```

```js
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("auto"))
  .setAssetType("video");
```

```python
CloudinaryVideo("van-driving-mountain-road.jpg").image(start_offset="auto")
```

```php
use Cloudinary\Transformation\VideoEdit;

(new ImageTag('van-driving-mountain-road.jpg'))
	->videoEdit(VideoEdit::trim()->startOffset("auto"))
	->assetType("video");
```

```java
cloudinary.url().transformation(new Transformation().startOffset("auto")).resourceType("video").imageTag("van-driving-mountain-road.jpg");
```

```ruby
cl_image_tag("van-driving-mountain-road.jpg", start_offset: "auto", resource_type: "video")
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation().StartOffset("auto")).BuildImageTag("van-driving-mountain-road.jpg")
```

```dart
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset("auto"))
	.setAssetType("video"));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setStartOffset("auto")).generate("van-driving-mountain-road.jpg")
```

```android
MediaManager.get().url().transformation(new Transformation().startOffset("auto")).resourceType("video").generate("van-driving-mountain-road.jpg");
```

```flutter
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset("auto"))
	.setAssetType("video"));
```

```kotlin
cloudinary.image {
	publicId("van-driving-mountain-road.jpg")
	 videoEdit(VideoEdit.trim() { startOffset("auto") })
	 assetType("video") 
}.generate()
```

```jquery
$.cloudinary.image("van-driving-mountain-road.jpg", {start_offset: "auto", resource_type: "video"})
```

```react_native
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("auto"))
  .setAssetType("video");
```

## Resize the poster to fit your page

Add a resize in a separate component, so that the poster is the size you need. This example creates a 700x400 poster from the frame at 8 seconds:

![Frame at 8 seconds, cropped to 700x400](https://res.cloudinary.com/demo/video/upload/so_8.0/c_fill,h_400,w_700/van-driving-mountain-road.jpg)

```nodejs
cloudinary.image("van-driving-mountain-road.jpg", {resource_type: "video", transformation: [
  {start_offset: "8.0"},
  {height: 400, width: 700, crop: "fill"}
  ]})
```

```react
import { trim } from "@cloudinary/url-gen/actions/videoEdit";
import { fill } from "@cloudinary/url-gen/actions/resize";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .resize(fill().width(700).height(400))
  .setAssetType("video");
```

```vue
import { trim } from "@cloudinary/url-gen/actions/videoEdit";
import { fill } from "@cloudinary/url-gen/actions/resize";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .resize(fill().width(700).height(400))
  .setAssetType("video");
```

```angular
import { trim } from "@cloudinary/url-gen/actions/videoEdit";
import { fill } from "@cloudinary/url-gen/actions/resize";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .resize(fill().width(700).height(400))
  .setAssetType("video");
```

```js
import { trim } from "@cloudinary/url-gen/actions/videoEdit";
import { fill } from "@cloudinary/url-gen/actions/resize";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .resize(fill().width(700).height(400))
  .setAssetType("video");
```

```python
CloudinaryVideo("van-driving-mountain-road.jpg").image(transformation=[
  {'start_offset': "8.0"},
  {'height': 400, 'width': 700, 'crop': "fill"}
  ])
```

```php
use Cloudinary\Transformation\VideoEdit;
use Cloudinary\Transformation\Resize;

(new ImageTag('van-driving-mountain-road.jpg'))
	->videoEdit(VideoEdit::trim()->startOffset(8.0))
	->resize(Resize::fill()->width(700)
->height(400))
	->assetType("video");
```

```java
cloudinary.url().transformation(new Transformation()
  .startOffset("8.0").chain()
  .height(400).width(700).crop("fill")).resourceType("video").imageTag("van-driving-mountain-road.jpg");
```

```ruby
cl_image_tag("van-driving-mountain-road.jpg", resource_type: "video", transformation: [
  {start_offset: "8.0"},
  {height: 400, width: 700, crop: "fill"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .StartOffset("8.0").Chain()
  .Height(400).Width(700).Crop("fill")).BuildImageTag("van-driving-mountain-road.jpg")
```

```dart
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset('8.0'))
	.resize(Resize.fill().width(700)
.height(400))
	.setAssetType("video"));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setStartOffset("8.0").chain()
  .setHeight(400).setWidth(700).setCrop("fill")).generate("van-driving-mountain-road.jpg")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .startOffset("8.0").chain()
  .height(400).width(700).crop("fill")).resourceType("video").generate("van-driving-mountain-road.jpg");
```

```flutter
cloudinary.image('van-driving-mountain-road.jpg').transformation(Transformation()
	.videoEdit(VideoEdit.trim().startOffset('8.0'))
	.resize(Resize.fill().width(700)
.height(400))
	.setAssetType("video"));
```

```kotlin
cloudinary.image {
	publicId("van-driving-mountain-road.jpg")
	 videoEdit(VideoEdit.trim() { startOffset(8.0F) })
	 resize(Resize.fill() { width(700)
 height(400) })
	 assetType("video") 
}.generate()
```

```jquery
$.cloudinary.image("van-driving-mountain-road.jpg", {resource_type: "video", transformation: [
  {start_offset: "8.0"},
  {height: 400, width: 700, crop: "fill"}
  ]})
```

```react_native
import { trim } from "@cloudinary/url-gen/actions/videoEdit";
import { fill } from "@cloudinary/url-gen/actions/resize";

new CloudinaryImage("van-driving-mountain-road.jpg")
  .videoEdit(trim().startOffset("8.0"))
  .resize(fill().width(700).height(400))
  .setAssetType("video");
```

## Use the image as the poster of an HTML video

Set the image URL as the `poster` attribute of your video tag, so it shows before the video plays:

```html
<video controls poster="https://res.cloudinary.com/demo/video/upload/so_8.0/c_fill,h_400,w_700/van-driving-mountain-road.jpg">
  <source src="https://res.cloudinary.com/demo/video/upload/van-driving-mountain-road.mp4" type="video/mp4">
</video>
```

> **NOTE**: The `so_` offset in the poster URL doesn't change the video URL. Don't add it to the video's `src`, or the video itself starts from that point.

## Related topics

* [Video thumbnails](video_previews_and_posters#video_thumbnails)
* [Video previews and posters](video_previews_and_posters)
* [Start offset (so)](transformation_reference#so_start_offset)
