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

Lake AI Service

Copy page
Download PDF
Video processing
Video segment splitting (keyframe)
Copy page
Download PDF
Video segment splitting (keyframe)

Operator introduction

Description

Video keyframe segmentation processor, supports intelligent segment splitting.

Key features

  • Multi-algorithm keyframe detection:
    • I_frame: Detection based on I-frame (recommended)
    • difference: Pixel difference detection
    • histogram: Histogram difference detection
  • Supports segment binary output or TOS storage
  • Provides timestamp positioning functionality

Format support

  • MP4 (.mp4)
  • AVI (.avi)
  • MOV (.mov)
  • MKV (.mkv)
  • Other common video formats

Daft invocation

Operator parameters

Input

Input column name

Note

video_paths

Array containing input video paths Default value: None

video_binaries

Array containing video binary data Default value: None

video_formats

Array containing input video formats (such as 'mp4', 'avi', and more); format information can be provided when specifying video_binaries Default value: None

output_basenames

Optional, array of output subdirectory names (file names)

Output

The processed struct fields include:

  • segments: list[str], list of paths to video segments after splitting
  • segments_binary: list[bytes], list of binary data for video segments after splitting
  • video_format: list[str], list of formats for video segments after splitting

Parameters

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

Parameter name

Type

Default value

Description

method

str

I_frame

Method for extracting keyframes, supports "difference" (pixel difference method), "histogram" (histogram method), and "I_frame" (I-frame keyframe identification). Caution: Non-I-frame methods may require longer processing time for videos. Optional values: ["difference", "histogram", "I_frame"] Default value: "I_frame"

threshold

float

0

Threshold for determining keyframes. Recommended value for difference: 2000000; recommended value for histogram: 0.01. Default value: 0

keyframes_cnt

int

10

Specifies the number of video keyframes to extract. -1 means using all detected keyframes; 0 means invalid parameter (video will not be split); if the specified number is greater than the actual number of keyframes, all keyframes will be used; otherwise, the specified number of keyframes will be evenly selected from all detected keyframes to avoid concentration of keyframes in a single time period. Default value: 10

seconds_per_frame

int

-1

Frame extraction interval, in seconds; -1 means no interval specified. Default value: -1

output_tos_dir

str

TOS path for saving video segments; if an empty string, segments will not be uploaded. Default value: ""

output_segments_binary

bool

False

Whether to output the binary data of video segments. Default value: False

output_video_format

str or None

Globally specify the output video format (such as "mp4", "avi", and so on). This setting takes precedence over the input file extension and the video_format column.

Examples

The following code demonstrates how to use Daft (for distributed scenarios) to run the operator to split videos by keyframe.

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 import VideoSplitByKeyframes

if __name__ == "__main__":

    # After modification, the split videos will be saved to the specified TOS path. Therefore, you need to set environment variables to ensure write access 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_split_by_keyframes"
    
    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)

    splitter = las_udf(
        VideoSplitByKeyframes,
        construct_args={
            "method": "I_frame",
            "keyframes_cnt": 2,
            "output_tos_dir": output_tos_dir,
        },
    )

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

    ds.show()
    # ╭──────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
    # │ video_path                               ┆ results                                                                                                                          │
    # │ ---                                      ┆ ---                                                                                                                              │
    # │ Utf8                                     ┆ Struct[segments: List[Utf8], segments_binary: List[Binary], video_format: List[Utf8]]                                            │
    # ╞══════════════════════════════════════════╪══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
    # │ https://las-cn-beijing-publi-…           ┆ {segments: ["tos://tos_bucket/video/video_split_by_keyframes/sample/segment_1.mp4", "tos://tos_bucket/video/video_split_by_keyf… │
    # ╰──────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Last updated: 2026.05.12 19:06:36