All Products
Search
Document Center

ApsaraVideo VOD:Generate Animated Images from Videos

Last Updated:Mar 19, 2026

Extract GIF or WebP animated images from videos to create previews, social media content, or thumbnails.

Use cases

  • Social media: Create clips for Twitter, Facebook, Instagram.

  • E-commerce: Show product features without full videos.

  • Marketing: Extract highlights from promotional videos.

  • News: Showcase key moments from events.

Supported formats

Format

File Size

Browser Support

When to Use

GIF

Larger

Universal

Maximum compatibility

WebP

30-70% smaller

Modern browsers (not IE, iOS Safari <14)

Mobile apps, bandwidth-sensitive sites

Note

WebP is not supported in IE, iOS Safari 3.2-13.7, and KaiOS Browser.

Prerequisites

Before you begin, ensure that you have:

  • An ApsaraVideo VOD account.

  • At least one video uploaded to VOD.

  • (Optional) Event notifications configured.

Workflow

  1. Create a template (format, frame rate, dimensions, time range).

  2. Submit a task via workflow or API.

  3. Receive an event notification.

  4. Retrieve the animated image URL.

Step 1: Create a template

Console

  1. Log in to the ApsaraVideo VOD console.

  2. In the left-side navigation pane, go to Configuration Management > Media Processing > Frame Animation Template.

  3. Click Create Frame Animation Template.

  4. Configure the template:

    Parameter

    Description

    Example

    Template Name

    Unique identifier (4-64 characters)

    social-media-preview

    Output Format

    gif or webp

    webp

    Frame Rate

    Frames per second (1-60)

    15

    Dimensions

    Width × Height (optional)

    640×360

    Time Range

    Duration: Start + length
    Trim End: Start to (length - trim)

    Duration

    Start Time

    Extraction start (seconds)

    5.0

    Duration

    Length (seconds, for Duration mode)

    3.0

    Trim from End

    Exclude from end (seconds, for Trim mode)

    N/A

    Set as Cover

    Use as video thumbnail

    Disabled

    Example: 3-second WebP, 15 fps, 640×360, starts at 5 seconds.

  5. Click OK.

Note the Template ID for Step 3.

API

Call AddVodTemplate with TemplateType=DynamicImage:

{
  "TemplateType": "DynamicImage",
  "Name": "social-media-preview",
  "TemplateConfig": {
    "Format": "webp",
    "Fps": "15",
    "Width": "640",
    "Height": "360",
    "TimeSpan": {
      "Seek": "5",
      "Duration": "3"
    }
  }
}

Response includes VodTemplateId.

Step 2 (Optional): Configure event notifications

  1. Set up callbacks: Configure event notifications.

  2. Subscribe to DynamicImageComplete.

Callback includes: URL, format, file size, dimensions, status, errors (if failed).

Step 3: Submit a task

Console (workflow)

Create workflow

  1. Create a workflow that includes the Frame Animation Template node.

  2. In the workflow, add the Frame Animation Template node and set the animated image template to the one created in Step 1.

  3. For more information about how to create workflows, see Workflows.

Submit during upload

  1. Go to Media Files > Audio/Video.

  2. Click Upload Audio/Video.

  3. Select Use Workflow > Workflow > your workflow.

  4. Click Upload.

Submit for existing videos

  1. Go to Media Files > Audio/Video.

  2. Find video, click Processing.

  3. Select workflow.

  4. Click OK.

API

During upload: Set WorkflowId when calling:

For existing videos: Call SubmitDynamicImageJob:

{
  "VideoId": "ca570defc72f4057b54ea7fc41a****",
  "DynamicImageTemplateId": "5d0d68xxx****"
}

Step 4: Retrieve the result

Method 1: Event notification (Recommended)

{
  "EventType": "DynamicImageComplete",
  "VideoId": "ca570defc72f4057b54ea7fc41a****",
  "JobId": "d7d1a82a51f44a0b9c2e2a7e3a****",
  "DynamicImageUrl": "https://example.oss-cn-hangzhou.aliyuncs.com/animated/preview.webp",
  "Width": 640,
  "Height": 360,
  "FileSize": 1048576,
  "Format": "webp",
  "Status": "success"
}

Method 2: API

Call ListDynamicImage. Response includes DynamicImageList.

Method 3: Console

  1. Go to Media Files > Audio/Video.

  2. Find video, click Manage.

  3. Check Animated Images tab.

Method 4: Cover image

If Set as Cover enabled, call GetVideoInfo and check CoverURL.

Best practices

Optimize file size

Practice

Impact

Use WebP vs GIF

30-70% smaller

Set 10-15 fps

Sufficient, smaller file

Limit to 3-5 seconds

Balance quality/size

Match display size

Don't use source resolution

Extraction time ranges

Content

Recommendation

Product demos

Show features in action

Highlights

Capture engaging moments

Static

Avoid credits, black screens

Format selection

Use Case

Format

Why

Max compatibility

GIF

All browsers

Min file size

WebP

30-70% smaller

Mobile apps

WebP

Check iOS Safari ≥14

Social media

GIF

Cross-platform

Modern web

WebP + fallback

Browser detection

Code examples

Python

from aliyunsdkcore.client import AcsClient
from aliyunsdkvod.request.v20170321 import SubmitDynamicImageJobRequest
import os

client = AcsClient(
    os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),
    os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
    'cn-shanghai'
)

request = SubmitDynamicImageJobRequest.SubmitDynamicImageJobRequest()
request.set_VideoId('ca570defc72f4057b54ea7fc41a****')
request.set_DynamicImageTemplateId('5d0d68xxx****')

print(client.do_action_with_exception(request))

Java

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.*;
import com.aliyuncs.profile.DefaultProfile;

public class AnimatedImage {
    public static void main(String[] args) throws Exception {
        DefaultProfile profile = DefaultProfile.getProfile(
            "cn-shanghai",
            System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
            System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
        );
        DefaultAcsClient client = new DefaultAcsClient(profile);

        SubmitDynamicImageJobRequest request = new SubmitDynamicImageJobRequest();
        request.setVideoId("ca570defc72f4057b54ea7fc41a****");
        request.setDynamicImageTemplateId("5d0d68xxx****");

        SubmitDynamicImageJobResponse response = client.getAcsResponse(request);
        System.out.println("Job ID: " + response.getDynamicImageJob().getJobId());
    }
}

Node.js

const Core = require('@alicloud/pop-core');

const client = new Core({
  accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
  accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
  endpoint: 'https://vod.cn-shanghai.aliyuncs.com',
  apiVersion: '2017-03-21'
});

client.request('SubmitDynamicImageJob', {
  VideoId: 'ca570defc72f4057b54ea7fc41a****',
  DynamicImageTemplateId: '5d0d68xxx****'
}, { method: 'POST' })
  .then(result => console.log('Job ID:', result.DynamicImageJob.JobId))
  .catch(error => console.error('Error:', error));

Troubleshooting

"InvalidVideoFormat" error

Cause: No video stream or corrupted container.

Fix:

  1. Verify file contains video stream.

  2. Check corruption (play locally).

  3. Re-upload if needed.

  4. Inspect: ffmpeg -i video.mp4.

Blank/corrupted image

Cause: Invalid time range.

Fix:

  1. Check duration: ListDynamicImage.

  2. Ensure StartTime < duration.

  3. Verify StartTime + Duration ≤ duration.

  4. For Trim: verify StartTime + (duration - TrimEnd) is valid.

File too large

Cause: High fps, long duration, large dimensions.

Fix:

  • Lower to 10-15 fps.

  • Limit to 3-5 seconds.

  • Resize to display size (e.g., 640×360).

  • Use WebP vs GIF.

WebP not displaying

Cause: Browser doesn't support WebP.

Fix: Implement fallback:

function supportsWebP() {
  const canvas = document.createElement('canvas');
  return canvas.getContext && canvas.getContext('2d') &&
    canvas.toDataURL('image/webp').indexOf('data:image/webp') === 0;
}

const format = supportsWebP() ? 'webp' : 'gif';
document.getElementById('preview').src = `https://example.com/preview.${format}`;

Pricing

Billed as video transcoding by resolution and duration. See Billing for basic services.

Limitations

  • Audio-only or corrupted files cannot generate images.

  • Processing time varies by video size, duration, extraction length.

  • Tasks run asynchronously—use events or ListDynamicImage.