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

# Why isn't the video duration shown during first playback of a transformed video?



## Why this happens

When you apply a transformation to a video on the fly (for example, format conversion, cropping, resizing, or adding overlays), Cloudinary generates the transformed video in real time. The server streams the output progressively as it processes, rather than waiting for the entire video to be generated first.

Because the video is being created on the fly, the total file size and duration aren't known in advance. Without this metadata, the video player can't display the total duration or render an accurate seek bar. Instead, the elapsed time increments without a total length indicator.

This behavior occurs when a specific transformation is requested before Cloudinary has finished generating and caching that derived asset. Once the transformed video has been fully generated and cached, later requests for that same transformation usually include the full metadata and the duration displays normally.

> **NOTE**: This is expected behavior for progressive playback of on-the-fly transformed videos and isn't a bug. You'll typically see it when the player relies on metadata from the delivered file, including direct playback in the Cloudinary Video Player, standard HTML5 `<video>` elements, and similar players.

## How to fix it

If displaying the video duration from the start of playback is important for your use case, pre-generate the transformation instead of relying on on-the-fly processing.

### Use eager transformations on upload

You can specify transformations to generate immediately when the video is uploaded, using [eager transformations](eager_and_incoming_transformations#eager_transformations). This ensures the transformed version is fully processed and cached before anyone requests it.

For large videos, use the `eager_async` parameter to process the transformation in the background without blocking the upload response. For example:

```multi
|nodejs
cloudinary.v2.uploader.upload("my_video.mp4", {
  resource_type: "video",
  eager_async: true,
  eager: [{ width: 640, height: 360, crop: "fill", format: "mp4" }]
})

|ruby 
Cloudinary::Uploader.upload("my_video.mp4",
  resource_type: "video",
  eager_async: true,
  eager: [{ width: 640, height: 360, crop: "fill", format: "mp4" }])

|python
cloudinary.uploader.upload("my_video.mp4",
  resource_type = "video",
  eager_async = True,
  eager = [{"width": 640, "height": 360, "crop": "fill", "format": "mp4"}])

|php_2
use Cloudinary\Api\Upload\UploadApi;

(new UploadApi())->upload('my_video.mp4', [
  'resource_type' => 'video',
  'eager_async' => true,
  'eager' => [['width' => 640, 'height' => 360, 'crop' => 'fill', 'format' => 'mp4']]]);

|java
Map params = ObjectUtils.asMap(
    "resource_type", "video",
    "eager_async", true,
    "eager", Arrays.asList(
        new Transformation().width(640).height(360).crop("fill").fetchFormat("mp4")));
cloudinary.uploader().upload("my_video.mp4", params);

|csharp
var uploadParams = new VideoUploadParams()
{
    File = new FileDescription(@"my_video.mp4"),
    EagerAsync = true,
    EagerTransforms = new List<Transformation>()
    {
        new Transformation().Width(640).Height(360).Crop("fill").FetchFormat("mp4")
    }
};
var uploadResult = cloudinary.Upload(uploadParams);
```

See [Eager asynchronous transformations](eager_and_incoming_transformations#eager_asynchronous_transformations) for details.

### Use the explicit method for existing assets

For videos that are already uploaded, use the [explicit method](image_upload_api_reference#explicit) to trigger transformation generation asynchronously:

```multi
|nodejs
cloudinary.v2.uploader.explicit("my_video", {
  type: "upload",
  resource_type: "video",
  eager: [{ width: 640, height: 360, crop: "fill", format: "mp4" }],
  eager_async: true
})

|ruby 
Cloudinary::Uploader.explicit("my_video",
  type: "upload",
  resource_type: "video",
  eager: [{ width: 640, height: 360, crop: "fill", format: "mp4" }],
  eager_async: true)

|python
cloudinary.uploader.explicit("my_video",
  type = "upload",
  resource_type = "video",
  eager = [{"width": 640, "height": 360, "crop": "fill", "format": "mp4"}],
  eager_async = True)

|php_2
use Cloudinary\Api\Upload\UploadApi;

(new UploadApi())->explicit('my_video', [
  'type' => 'upload',
  'resource_type' => 'video',
  'eager' => [['width' => 640, 'height' => 360, 'crop' => 'fill', 'format' => 'mp4']],
  'eager_async' => true]);

|java
Map params = ObjectUtils.asMap(
    "type", "upload",
    "resource_type", "video",
    "eager", Arrays.asList(
        new Transformation().width(640).height(360).crop("fill").fetchFormat("mp4")),
    "eager_async", true);
cloudinary.uploader().explicit("my_video", params);

|csharp
var explicitParams = new ExplicitParams("my_video")
{
    Type = "upload",
    ResourceType = ResourceType.Video,
    EagerAsync = true,
    EagerTransforms = new List<Transformation>()
    {
        new Transformation().Width(640).Height(360).Crop("fill").FetchFormat("mp4")
    }
};
var explicitResult = cloudinary.Explicit(explicitParams);
```

Once the eager transformation completes, subsequent requests for that transformation URL serve the fully processed video with duration metadata.

### Use notifications to know when processing is complete

You can use [eager notification URLs](eager_and_incoming_transformations#eager_asynchronous_transformations) to receive a webhook when the transformation finishes generating. This lets your application know exactly when the transformed video is ready to be served with full metadata.

## When to expect this behavior

This issue occurs specifically when **all** of the following conditions are met:

* The video has a transformation applied in the delivery URL (e.g., format conversion, resize, crop, overlay).
* The specific transformation has **not been generated before** (it's not cached).
* The video is being delivered as an on-the-fly generated progressive file.

It doesn't occur when:

* The video is delivered without transformations (the original upload).
* The transformation has already been generated and cached (second play onward, or after using eager transformations).
* The video is delivered using [adaptive bitrate streaming](adaptive_bitrate_streaming) (HLS/MPEG-DASH). These protocols use manifest files that contain duration metadata, so the player doesn't depend on the video file being fully generated.

> **READING**:
>
> * [Eager and incoming transformations](eager_and_incoming_transformations): Pre-generate transformations on upload or for existing assets.

> * [Video best practices](video_best_practices): Optimization strategies for video delivery.

> * [Adaptive bitrate streaming](adaptive_bitrate_streaming): Pre-generate streaming profiles for seamless video playback.
