You need to enable JavaScript to run this app.
Lake AI Service

Lake AI Service

Copy page
Download PDF
Video processing
Video frame sampling
Copy page
Download PDF
Video frame sampling

The Video Frame Extraction operator supports extracting frames from the input video at a specified frame rate and uploading the extracted image frames to a designated TOS storage path. After the task is completed, you can obtain the video metadata and the TOS storage path for each frame. Supports configurable frame extraction frequency, maximum frame count limit, output image format, and scaling strategy. Suitable for scenarios such as video understanding, detection, moderation, summarization, and cover generation.

Operator introduction

Operator ID: las_video_frame_extract

Core capabilities

  • Frame extraction by frame rate: Uniformly extracts frames from the video starting at 0 seconds according to the specified FPS (0.1 ~ 10.0).
  • Maximum frame count limit: You can set the max_frames parameter to control the upper limit of output frames. If the limit is exceeded, the first N frames are retained in chronological order to avoid generating too many frames from long videos.
  • Multi-format output: Supports output in both jpg and png image formats.
  • Flexible scaling: Supports scaling by short side (resize_short_side) or specifying the target resolution (resize_hw) to meet different scenario requirements.
  • Custom output path: Customize the storage path of extracted frames on TOS through the output path template.
  • Long video support: Suitable for processing long-duration videos, with output scale controlled by max_frames.

Supported regions

  • Beijing: cn-beijing
  • Shanghai: cn-shanghai
  • Guangzhou: cn-guangzhou

Operator performance

Sub-items
Performance impact explanation

Maximum RPM

600

Maximum concurrency

10

Input and output requirements

Input requirements

Category
Detailed description

Supported input data modalities

  • Video

Input format: Video

  • Format: Common video formats such as mp4, mov, avi, mkv are supported

Input path requirements

Provide input data to the operator via the request parameter video_url. Currently, two methods are supported: public URL and TOS path.

  • Public URL: A video URL accessible via the public network, format is http/https.
  • TOS path: After uploading the data to be processed to a TOS Bucket under the same primary account and region as the current LAS service, you can provide a TOS path in the format tos://bucket_name/demo.

Output requirements

Category
Detailed description

Output data modality

  • Image

Output format: Image

  • Format: Supports jpg and png

Output path and naming: TOS

Set the output TOS path and naming rules via the request parameter output_path_template.

  • Caution: Must point to a specific file, not just set as a TOS path (directory). That is, it must start with tos:// and must include the {index} placeholder to specify the naming rule for the output result. For example, tos://bucket/frames/frame_{index}.{autoext}.
  • TOS path: A TOS Bucket directory under the same primary account and region as the LAS service, with write permissions.

Billing description
  • Billing standards

    Item breakdown
    Billing standards description

    Billing item

    The usage is calculated based on the number of images sampled from the input video, and billed accordingly.

    Billing type

    Usage-based billing, unit: CNY per 1,000 images, billed hourly based on actual usage.

    Unit price

    0.1 CNY per 1,000 images

  • Billing details
    Billing formula: Total cost = unit price * usage

Notes and prerequisites

Details

Caution and prerequisites

Costs

Before calling an operator, you need to understand the model invocation costs associated with using the operator. For details, see Large model invocation billing.

Authentication (API Key)

Before calling an operator, you need to generate an API Key for operator invocation. It is recommended to configure the API Key as an environment variable to ensure safer operator calls. For details, see Obtain and configure API Key.

BaseURL

Before calling an operator, you need to determine the BaseURL for operator invocation based on the region where your current LAS service is deployed. This is used to configure the path parameter values for operator calls.
For details, see Obtain the Base URL. The Examples below are for reference only; when making actual calls, replace the path values with those corresponding to your region.

Rest API invocation

When calling las_video_frame_extract, you must first submit an asynchronous task using Submit. Once the task reaches the completed state, use Poll to retrieve the frame extraction results.

API usage instructions

  • The API of this operator is an asynchronous task interface. You need to submit a task via the Submit interface to obtain the task_id of the task, then use the Poll interface to get the running status of the corresponding task (task_id) and obtain the operator processing result.
  • Caution: After the task is submitted, the task_id is valid for 3 days. After 3 days, the operator processing result cannot be obtained using this task_id.

Submit

Interface description

Call the Video Frame Extraction operator to submit an asynchronous task, extract frames from the input video at the specified frame rate, and upload the extracted image frames to the specified TOS path. After successful submission, the task ID is returned. You can obtain the processing result (including video metadata and the TOS storage path for each frame) through the task query interface.

Request parameters

const properties = ({
  "columns": [
{ "title": "参数", "dataIndex": "column_0", "key": "column_0", "width": 300 },
{ "title": "类型", "dataIndex": "column_1", "key": "column_1", "width": 150 },
{ "title": "Required", "dataIndex": "column_2", "key": "column_2", "width": 80 },
{ "title": "Example", "dataIndex": "column_3", "key": "column_3", "width": 150 },
{ "title": "Description", "dataIndex": "column_4", "key": "column_4" }
  ],
  "data": [
    {
      "key": "1",
      "column_0": "operator_id",
      "column_1": "string",
"column_2": "YES",
      "column_3": "las_video_frame_extract",
"column_4": "Operator ID."
    },
    {
      "key": "2",
      "column_0": "operator_version",
      "column_1": "string",
"column_2": "YES",
      "column_3": "v1",
"column_4": "Operator version."
    },
    {
      "key": "3",
      "column_0": "data",
      "column_1": "VideoFrameExtractData",
"column_2": "YES",
      "column_3": "",
"column_4": "Video frame extraction request parameters.",
      "children": [
        {
          "key": "3-1",
          "column_0": "video_url",
          "column_1": "string",
"column_2": "YES",
          "column_3": "tos://bucket/path/video.mp4",
"column_4": < div> Input video address. Supports < code> http/https</ code> and < code> tos://bucket/key</ code>. The address must be accessible by the service; if the video cannot be downloaded, parsed, or the format is unsupported, the following will be returned respectively: < code> Video.DownloadFailed</ code>, < code> Video.Invalid</ code>, or < code> Video.FormatUnsupported</ code>. </div>
        },
        {
          "key": "3-2",
          "column_0": "output_path_template",
          "column_1": "string",
"column_2": "YES",
          "column_3": "tos://bucket/frames/frame_{index:06d}.{autoext}",
"column_4": < div> Output path template. The target bucket must have write permissions; it must point to a specific file in the form of < code> tos://bucket/path/file</ code>, cannot be rendered as a directory, and must include the < code>{ index}</ code> placeholder. Only < code>{ index}</ code> and < code>{ autoext}</ code> placeholders are supported;< ul>< li>< code>{ index}</ code> is the frame index starting from 0, supports formatted output (for example, < code>{ index:06d}</ code> outputs < code> 000000</ code>, < code> 000001</ code>); if no format is specified, outputs < code> 0</ code>, < code> 1</ code>. </ li>< li>< code>{ autoext}</ code> will be replaced with the actual output format suffix < code> jpg</ code> or < code> png</ code>. </ li></ ul> When writing the output object, the same-named TOS object will be overwritten. </div>
        },
        {
          "key": "3-3",
          "column_0": "fps",
          "column_1": "float",
"column_2": "No",
          "column_3": "1.0",
"column_4": < div> Frame extraction rate, measured in frames per second. Value range < code>[ 0.1, 10.0]</ code>, default < code> 1.0</ code>. The operator starts from < code> 0</ code> seconds, constructs sampling time points at intervals of < code> 1/fps</ code> seconds, until the video duration or the < code> max_frames</ code> limit is reached; actual frames are extracted by ffmpeg at the corresponding time points. Invalid values return < code> Parameter.Invalid</ code>. </div>
        },
        {
          "key": "3-4",
          "column_0": "max_frames",
          "column_1": "integer",
"column_2": "No",
          "column_3": "200",
"column_4": < div> Maximum number of frames to extract. Greater than 0; if not specified, there is no limit. If the sampling points calculated by < code> fps</ code> exceed < code> max_frames</ code>, the first < code> max_frames</ code> frames are retained in chronological order and extraction stops. Invalid values return < code> Parameter.Invalid</ code>; unlimited duration videos may generate a large number of images and TOS writes. </div>
        },
        {
          "key": "3-5",
          "column_0": "image_format",
          "column_1": "string",
"column_2": "No",
          "column_3": "jpg",
"column_4": < div> Output image format. Optional values: < code> jpg</ code>, < code> png</ code>, default < code> jpg</ code>. When < code> output_path_template</ code> contains < code>{ autoext}</ code>, the system uses this format as the output file suffix. </div>
        },
        {
          "key": "3-6",
          "column_0": "resize_short_side",
          "column_1": "integer",
"column_2": "No",
          "column_3": "720",
"column_4": < div> Scale the short side to the specified pixel value while maintaining the aspect ratio. Must be greater than 0; the actual upper limit for the short side is < code> 1080</ code>. If a larger value is provided, it will be processed as < code> 1080</ code>; the output width and height will be adjusted to even numbers. The original video frame may be enlarged or reduced. Mutually exclusive with < code> resize_hw</ code>; cannot be set simultaneously. </div>
        },
        {
          "key": "3-7",
          "column_0": "resize_hw",
          "column_1": "array",
"column_2": "No",
          "column_3": "&#91;720, 1080&#93;",
"column_4": < div> Specify the output resolution < code>&#91; width, height&#93;</ code>; element type is integer or null. The array length must be 2, and at least one element must be an integer greater than 0. It cannot be < code>&#91; null, null&#93;</ code>. If only one side is specified, the original aspect ratio is maintained during scaling; if both width and height are specified, the output will use the specified dimensions, which may change the original aspect ratio; the output width and height will be adjusted to even numbers. Mutually exclusive with < code> resize_short_side</ code>; cannot be set simultaneously. </div>
        }
      ]
    }
  ]
}); 
return <Table border={{ cell: true, wrapper: true }} pagination={false} {...properties} />;

Response parameters

参数
类型
示例值
描述
metadata
metadata
Request metadata.
task_id
string
task-xxx
Task ID in asynchronous mode, used for job status queries.
task_status
string
PENDING
Task status in asynchronous mode.
  • PENDING, request received
  • RUNNING, running
  • COMPLETED, completed
  • FAILED, failed
  • TIMEOUT, timed out
business_code
string
0
Business code.
error_msg
string
If an exception occurs, detailed error information will be returned.

Examples

Request example

curl --location "https://operator.las.ap-southeast-1.volces.com/api/v1/submit" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $LAS_API_KEY" \
--data '{
  "operator_id": "las_video_frame_extract",
  "operator_version": "v1",
  "data": {
    "video_url": "tos://my-bucket/videos/sample.mp4",
    "output_path_template": "tos://my-bucket/frames/frame_{index:06d}.{autoext}",
    "fps": 1.0,
    "max_frames": 200,
    "image_format": "jpg",
    "resize_short_side": 720
  }
}'

Response example

{
  "metadata": {
    "task_id": "task-20260420120000-abc123",
    "task_status": "PENDING",
    "business_code": "0",
    "error_msg": ""
  }
}

Error code

HttpStatusCode

Error code

Error message

Description

400

Parameter.Invalid

invalid parameter

The request parameter is invalid.

400

Parameter.Missing

Missing required parameter

Required parameter is missing.

400

Url.Invalid

invalid url

The input video URL is invalid.

400

Video.Invalid

invalid video file

The video file is invalid or cannot be parsed.

400

Video.DownloadFailed

Video download failed

Video download failed.

400

Video.FormatUnsupported

Video format not supported

Video format is not supported.

400

Video.Timeout

Video processing timeout

Video processing timed out.

400

Video.FrameExtractionFailed

Video frame extraction failed

Video frame extraction failed.

400

Tos.AccessFailed

Failed to access TOS path with provided credentials

TOS access failed. Please check credentials, Endpoint, and path write permissions.

401

Authorization.Missing

Missing Authorization

Authorization information is missing.

401

ApiKey.InValid

The api key is invalid

API Key is invalid.

Poll

Interface description

Query the execution status and result of the Video Frame Extraction task. When the task status is COMPLETED and business_code=0, video metadata and the list of extracted frames are returned. In the PENDING, RUNNING, FAILED, or TIMEOUT states, data is usually not returned. The failure reason is returned via metadata.business_code and metadata.error_msg.

Request parameters

Name

Type

Required

Example value

Description

operator_id

string

Yes

las_video_frame_extract

Operator ID.

operator_version

string

Yes

v1

Operator version.

task_id

string

Yes

task-xxx

The task ID returned after submitting the task.

Response parameters

Parameter
Type
Example value
Description
metadata
metadata
Request metadata.
data
VideoFrameExtractResponse
Data returned only when the task is completed and successful.

Examples

Request example

curl --location "https://operator.las.ap-southeast-1.volces.com/api/v1/poll" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $LAS_API_KEY" \
--data '{
  "operator_id": "las_video_frame_extract",
  "operator_version": "v1",
  "task_id": "task-20260420120000-abc123"
}'

Response example

{
    "metadata": {
        "task_id": "task-20260420120000-abc123",
        "task_status": "COMPLETED",
        "submit_time": "2026-07-21T16:04:06+08:00",
        "end_time": "2026-07-21T16:04:06+08:00",
        "business_code": "0",
        "error_msg": ""
    },
    "data": {
        "video_duration": 11.234,
        "video_resolution": "1920x1080",
        "frame_count": 3,
        "frames": [
            {
                "index": 0,
                "timestamp_seconds": 0.00,
                "width": 720,
                "height": 405,
                "tos_path": "tos://my-bucket/frames/frame_000000.jpg"
            },
            {
                "index": 1,
                "timestamp_seconds": 1.00,
                "width": 720,
                "height": 405,
                "tos_path": "tos://my-bucket/frames/frame_000001.jpg"
            },
            {
                "index": 2,
                "timestamp_seconds": 2.00,
                "width": 720,
                "height": 405,
                "tos_path": "tos://my-bucket/frames/frame_000002.jpg"
            }
        ]
    }
}

Error code

HttpCode

Error code

Error message

Description

400

Parameter.Invalid

invalid parameter

The request parameter is invalid.

400

Parameter.Missing

Missing required parameter

Required parameter is missing.

400

Url.Invalid

invalid url

The input video URL is invalid.

400

Video.Invalid

invalid video file

The video file is invalid or cannot be parsed.

400

Video.DownloadFailed

Video download failed

Video download failed.

400

Video.FormatUnsupported

Video format not supported

Video format is not supported.

400

Video.Timeout

Video processing timeout

Video processing timed out.

400

Video.FrameExtractionFailed

Video frame extraction failed

Video frame extraction failed.

400

Tos.AccessFailed

Failed to access TOS path with provided credentials

TOS access failed. Please check credentials, Endpoint, and path write permissions.

400

Task.NotFound

Task not found

Task does not exist.

401

Authorization.Missing

Missing Authorization

Authorization information is missing.

401

ApiKey.InValid

The api key is invalid

API Key is invalid.

500

Internal.ServerError

Internal server error

Internal server error.

Daft invocation

Operator parameters

Input

Input column name

Description

video_paths

Input video path column (local or remote URI), type string, default None

video_binaries

Input video binary column, type binary, default None

video_formats

The format corresponding to the binary input (such as "mp4", "mov"), type string, default None

video_durations

Video duration column (seconds), type float, default None

Output

Struct array. Fields include:

  • frames: Array of sampled frame images (H x W x C), configurable for output
  • base64: Base64 encoding of sampled frames (format specified by img_type), configurable for output
  • timestamps: Timestamps of sampled frames (seconds)
  • frame_indices: Frame indices of sampled frames in the decoding sequence
  • tos_paths: Storage paths of sampled frames on TOS (if output_tos_dir is configured)

Parameters

If a parameter does not have a default value, it is required.

Parameter name

Type

Default value

Description

sample_mode

str

by_count_uniform

Sampling mode. Optional values: ["by_count_uniform", "by_interval_time", "by_interval_frames", "by_fps", "by_timestamps"]

start_time_sec

float

0.0

Start time (seconds)

end_time_sec

float or None

End time (seconds). None indicates the end of the video

count_k

int or None

Number of frames for uniform/random sampling (used by by_count_uniform)

interval_sec

float or None

Time interval Δt (seconds, used by by_interval_time)

interval_frames

int or None

Decoded frame interval N (used by by_interval_frames)

target_fps

float or None

Target FPS (used by by_fps)

timestamps_sec

list or None

Target timestamp list (seconds, used by by_timestamps)

img_type

str

.jpg

Output image format (for base64 and optional saving to TOS), options: [".jpg", ".png", ".webp"], default is ".jpg"

output_tos_dir

str

If not empty, sampled frames will be saved locally and uploaded to the target directory in TOS (each video in a separate subdirectory)

max_frames

int or None

Maximum number of frames returned (defensive limit). None means no limit

seed

int

42

When the total duration of the video cannot be determined in advance, the operator uses the reservoir sampling algorithm to uniformly randomly sample the specified number of frames from the video stream. This parameter is used to set the random seed to ensure the sampling results are reproducible. The default value is 42.

output_frames

bool

True

Whether to output the original frame array (which can be large, default is True). Caution: Even if set to False, the returned result still contains the frames field, but its content is an empty list.

output_base64

bool

True

Whether to output base64 encoding (which can be large, default is True). Caution: Even if set to False, the returned result still contains the base64 field, but its content is an empty list.

Examples

The following code demonstrates how to use Daft (for distributed scenarios) to sample several image frames from a video at frame intervals. In this example, interval_frames=100 is set, and 6 images are actually produced.

from __future__ import annotations

import os

import daft
from daft import col
from daft.las.functions.udf import las_udf
from daft.las.functions.video.video_frame_sampler import VideoFrameSampler

if __name__ == "__main__":

    # After sampling, the frames will be saved to the specified TOS path. Therefore, you need to set the environment variables to ensure you have permission to write to TOS, including: ACCESS_KEY, SECRET_KEY, TOS_ENDPOINT, TOS_REGION, TOS_TEST_DIR
    TOS_DIR = os.getenv("TOS_TEST_DIR", "tos_bucket")
    output_tos_dir = f"tos://{TOS_DIR}/video/video_frame_sampler"
    
    if os.getenv("DAFT_RUNNER", "native") == "ray":
        import logging

        import ray

        def configure_logging():
            logging.basicConfig(
                level=logging.INFO,
                format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
                datefmt="%Y-%m-%d %H:%M:%S.%s".format(),
            )
            logging.getLogger("tracing.span").setLevel(logging.WARNING)
            logging.getLogger("daft_io.stats").setLevel(logging.WARNING)
            logging.getLogger("DaftStatisticsManager").setLevel(logging.WARNING)
            logging.getLogger("DaftFlotillaScheduler").setLevel(logging.WARNING)
            logging.getLogger("DaftFlotillaDispatcher").setLevel(logging.WARNING)

        ray.init(dashboard_host="0.0.0.0", runtime_env={"worker_process_setup_hook": configure_logging})
        daft.set_runner_ray()
    daft.set_execution_config(actor_udf_ready_timeout=600)
    daft.set_execution_config(min_cpu_per_task=0)

    # Construct the URL using environment variables
    tos_dir_url = os.getenv("TOS_DIR_URL", "las-cn-beijing-public-online.tos-cn-beijing.volces.com")
    samples = {
        "video_path": [
            f"https://{tos_dir_url}/public/shared_video_dataset/sample.mp4"
        ]
    }

    ds = daft.from_pydict(samples)

    sampler = las_udf(
        VideoFrameSampler,
        construct_args={
            "sample_mode": "by_interval_frames",
            "interval_frames": 100,
            "output_tos_dir": output_tos_dir,
            "img_type": ".jpg",
        },
    )

    # Use Daft for distributed processing
    ds = ds.with_column("results", sampler(col("video_path")))

    ds = ds.select(
        "video_path",
        col("results")["frames"].alias("frames"),
        col("results")["base64"].alias("base64"),
        col("results")["timestamps"].alias("timestamps"),
        col("results")["frame_indices"].alias("frame_indices"),
        col("results")["tos_paths"].alias("tos_paths"),
    )

    ds.show()
    # ╭────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
    # │ video_path                     ┆ results                                                                                                                          │
    # │ ---                            ┆ ---                                                                                                                                      │
    # │ Utf8                           ┆ Struct[frames: List[Binary], base64: List[Utf8], timestamps: List[Float64], frame_indices: List[Int64], tos_paths: List[Utf8]] │
    # ╞════════════════════════════════╪══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
    # │ https://las-cn-beijing-publi-… ┆ {frames: […], base64: […], timestamps: […], frame_indices: […], tos_paths: ["tos://tos_bucket/video/video_frame_sampler/frame_0.jpg", …]} │
    # ╰────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Last updated: 2026.08.18 15:00:37