By following the steps described in this document, you can fully experience the end-to-end process from video data ingestion, video dataset processing, to text-to-image and image-to-image search. Through this process, you will master the following skills:
Large visual models can interpret visual information in videos, completing tasks such as describing objects within them and analyzing action logic. These models can be used for automated video content review, intelligent monitoring analysis, and more, significantly reducing labor costs. They are suitable for fields such as intelligent security, sports event analysis, and media content management.
The common approaches to constructing business systems based on VLM are as follows.
Audio and video content can be stored in Volcano Engine TOS. After ingesting audio and video data into the lake via LAS (converting to Lance format data), you can call LAS data processing operators to process the audio and video data, and perform content understanding/vectorization on the audio and video content, facilitating subsequent consumption of the audio and video content.
This practice uses key frame extraction from video files as an example to introduce the operational process of video data ingestion and processing. Prepare a test video file in a common format such as MP4, AVI, or MOV, and follow the steps in this practice to complete the process.
You need to enable Volcano Engine Object Storage TOS and create a TOS bucket to store the test video data during this experiment.
Preparation | Key operational points | Reference documentation | Configuration example |
|---|---|---|---|
Create Bucket |
| Bucket name: las-doctest |
You need to log in to the Access Control (IAM) console and prepare an AK and SK for subsequent API access to TOS and LAS.
Preparation | Key operational points | Reference documentation | Configuration example |
|---|---|---|---|
Obtain AK and SK | To ensure the security of access to TOS/LAS services, you must provide valid access keys (AK/SK) for subsequent authentication.
|
You need to enable the LAS service and create the queue resources and development machine environment required for this experiment.
Preparations | Operation key points | Reference documents | Configuration example |
|---|---|---|---|
Queue resources |
| See operation key points | |
LAS API Key | Before you call the LAS online function, you need to first generate an API Key for authentication.
warning LAS provides you with two types of data processing operators: offline and online. Only online operators require LAS API Key authentication.
| See operation key points | |
Development machine | Before you call the LAS offline function, you need to prepare the development environment for calling the offline function.
|
warning
The main purpose of this practice step is to upload videos to the TOS Bucket and create a video dataset in LAS. Subsequently, you can directly preview, process, and perform other operations on videos in the LAS video dataset.
After logging in to the TOS product console, upload the video to be processed to the TOS bucket.
Operation steps | Operation key points | Reference documentation | Configuration example |
|---|---|---|---|
Upload video | Upload the video to be processed to the prepared TOS Bucket. You can create folders as needed and upload videos to the folders. | The TOS path is: |
Log in to the LAS console, click Datasets > Common dataset in the left navigation bar, and after entering the dataset page, click "Create dataset". Refer to the following configuration points to set the dataset parameters. After completing the configuration, click "Create" to finish creating the video dataset.
Operation steps | Operation key points | Reference documentation | Configuration example |
|---|---|---|---|
Create video dataset |
|
|
After the dataset is created, you can view the basic information of the dataset on the dataset details page. For video datasets, previewing the first ten videos is supported.
warning
The main purpose of this practice step is to convert the video dataset to a Lance dataset, enabling video data lake ingestion and facilitating subsequent data processing operations such as video frame extraction.
You need to first log in to the TOS console and prepare a TOS path for storing the converted Lance dataset data. The TOS path for the Lance dataset in this example is: tos://las-doctest/video2lance/.
This step is mainly performed on the development machine, where VeDaft is used to call the SDK for reading and writing operations on the dataset. Since this involves accessing the TOS Bucket, it is recommended to configure certain authentication parameters and fixed path parameters as environment variables in the development environment for easier reference in subsequent code execution.
You can refer to the following content to prepare the environment variable configuration.
# Region settings. This example uses the North China 2 - Beijing region export REGION="cn-beijing" # Authentication AK-related environment variables # Authentication sk and ak for accessing TOS and LAS export LAS_TOS_SECRET_KEY="<your_sk>" export LAS_TOS_ACCESS_KEY="<your_ak>" # TOS access-related environment variables # TOS access endpoint export LAS_TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com" # TOS endpoint (for TOSConfig) export TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com"
In the development machine environment, run the source env.sh command to activate the environment variables.
# Please execute the following code on the LAS development machine import os """ Convert to Lance Dataset """ import daft from daft.io import CreateLasDatasetOptions, IOConfig, LanceWriteOptions from daft.las.io import TOSConfig # You can customize the path for your new dataset dataset_name = "las_dataset_video" lance_tos_dir = f"tos://las-doctest/video2lance/{dataset_name}.lance" LANCE_DATASET_FORMAT = "lance" # Create the relevant configuration io_config = IOConfig(s3=TOSConfig.from_env().to_s3_config()) write_options = LanceWriteOptions(io_config=io_config, uri=lance_tos_dir) create_ds_options = CreateLasDatasetOptions( nick_name="daft_test_lance_write", privacy="public", description="This is my dataset", ) # Read the raw data df = daft.read_las_dataset(name=dataset_name) # Create here new_dataset_name = dataset_name + "_lance" df.write_las_dataset( name=new_dataset_name, format=LANCE_DATASET_FORMAT, write_options=write_options, create_ds_options=create_ds_options, ) # Read the newly converted dataset df = daft.read_las_dataset(name=new_dataset_name) print("\n\nnew dataset:") df.show()
You need to modify the following parameters.
las_dataset_videoOther parameters can be kept as the example values.
new dataset: ╭────────────────────────────────┬───────────┬──────────╮ │ video ┆ size ┆ num_rows │ │ --- ┆ --- ┆ --- │ │ String ┆ Int64 ┆ Int64 │ ╞════════════════════════════════╪═══════════╪══════════╡ │ s3://las-doctest/video/LAS AI… ┆ 225602609 ┆ None │ ╰────────────────────────────────┴───────────┴──────────╯
The converted Lance dataset contains the fields "video", "size", and "num_rows". Details:
If an ERROR message appears in the output but the dataset data is returned normally, the ERROR message can be ignored.
After completing the operation to convert to a Lance dataset, you can log in to the LAS console and view the newly created Lance dataset on the dataset list page.
warning
The main purpose of this step is to perform simple processing on the videos, writing the binary video data into the Lance dataset ingested into the lake. This allows video content to be previewed directly in the Lance dataset and prepares for subsequent operations such as video content understanding and vectorization.
The main purpose of this step is to invoke LAS data processing operators to enhance the video data:
Invoke the multimodal vectorization operator: Use a large model to vectorize the video, write the vectorization results into the Lance dataset, and facilitate subsequent application scenarios for consuming video data, such as image-to-image retrieval.
# Region settings. In this example, North China 2 - Beijing region is used export REGION="cn-beijing" # Authentication AK-related environment variables # Authentication sk and ak for accessing TOS and LAS export LAS_TOS_SECRET_KEY="<your_sk>" export LAS_TOS_ACCESS_KEY="<your_ak>" # TOS access-related environment variables # TOS access endpoint export LAS_TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com" # TOS endpoint (for TOSConfig) export TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com" # DAFT executor type, set to local mode export DAFT_RUNNER="native"
This step adds:
source env.sh command to activate the environment variables.The following uses Video keyframe extraction as an example to demonstrate how to process video. During processing, a new Lance dataset will be created, and key parameters such as the TOS path of the original video, the binary result and TOS path after video frame extraction, and so on will be written into the newly created Lance dataset.
Run the following script on the development machine.
# Import features from future versions to ensure compatibility from __future__ import annotations # Import necessary libraries import base64 # For Base64 encoding and decoding import hashlib # For generating SHA256 hashes import os # For operating system interactions, such as obtaining environment variables import pyarrow as pa # For processing columnar data import daft # Import the daft data processing framework from daft import DataType, col # Import data types and column operation tools from daft.io import ( CreateLasDatasetOptions, # Configuration options for creating LAS datasets IOConfig, # IO configuration class LanceWriteOptions, # Lance format write options ) from daft.io.object_store_options import io_config_to_storage_options # Convert IO configuration to storage options from daft.daft import IOConfig # Import IOConfig again (possibly to ensure correctness) from daft.las.functions.udf import las_udf # Import the LAS user-defined function decorator from daft.las.functions.video import VideoKeyframes # Import the video key frame processing function from daft.las.io.tos import TOSConfig # Import the TOS storage configuration # Set the TOS path where the video source file is located TOS_TEST_DIR = "tos://las-doctest/video/LAS AI Product Introduction.mp4" # Set the TOS path for storing the resulting images after video frame extraction TOS_TEST_OUTPUT_DIR = "tos://las-doctest/video/result/" # Create a new Lance dataset from the video frame extraction results; the following parameters are used to configure the new Lance dataset # Customize the name of the new Lance dataset DATASET_NAME = "las_dataset_video_lance_kf" # Set the TOS path for the new Lance dataset TOS_TEST_LANCE_DIR = "tos://las-doctest/video2lance/las_dataset_video_kf.lance" # After frame extraction, customize the video path column name when writing to the Lance dataset VIDEO_COLUMN = os.getenv("VIDEO_COLUMN", "video") # After frame extraction, customize the video key frame column name when writing to the Lance dataset VIDEO_KEYFRAMES_COLUMN = os.getenv("VIDEO_KEYFRAMES_COLUMN", "video_keyframes") # After frame extraction, customize the TOS path column name for the video key frames when writing to the Lance dataset VIDEO_KEYFRAMES_TOS_COLUMN = os.getenv("VIDEO_KEYFRAMES_TOS_COLUMN", "video_keyframes_tos") # If the DAFT executor is ray, initialize ray if os.environ['DAFT_RUNNER'] == 'ray': import ray # Import the ray distributed computing framework ray.init(address='auto') # Automatically connect to the ray cluster # Define a DAFT UDF: convert a Base64 string to binary data # ✅ New syntax: use @daft.func instead of @daft.udf (stateless function) @daft.func def base64_to_binary(base64_str: DataType.string()) -> DataType.binary(): import base64 as b64 return b64.b64decode(base64_str) # Define a DAFT UDF: generate a SHA256 hash value @daft.func def generate_sha256_hash(s: DataType.string()) -> DataType.string(): import hashlib return hashlib.sha256(str(s).encode()).hexdigest() # Main function entry point if __name__ == "__main__": # Create IO configuration from environment variable settings (adapted for TOS storage) io_config = IOConfig(s3=TOSConfig.from_env().to_s3_config()) # Create sample data containing video paths samples = {VIDEO_COLUMN: [f"{TOS_TEST_DIR}"]} # Create a daft dataset from a dictionary ds = daft.from_pydict(samples) # Create a video key frame extractor UDF extractor = las_udf( VideoKeyframes, # Use the video key frame extraction function construct_args={ "method": "I_frame", # Extraction method: I-frame "keyframes_cnt": 50, # Number of extracted key frames "output_tos_dir": f"{TOS_TEST_OUTPUT_DIR}", # Output directory in TOS }, ) # Apply the extractor to add a key frame column to the dataset ds = ds.with_column(VIDEO_KEYFRAMES_COLUMN, extractor(col(VIDEO_COLUMN))) # Extract the TOS path column from the key frame results ds = ds.with_column(VIDEO_KEYFRAMES_TOS_COLUMN, col(VIDEO_KEYFRAMES_COLUMN)["tos_paths"]) # Extract the base64-encoded image data from the key frame results ds = ds.with_column(VIDEO_KEYFRAMES_COLUMN, col(VIDEO_KEYFRAMES_COLUMN)["base64"]) # Expand the key frame data and corresponding TOS paths (one row becomes multiple rows) ds = ds.explode(col(VIDEO_KEYFRAMES_COLUMN), col(VIDEO_KEYFRAMES_TOS_COLUMN)) # Convert the base64-encoded image data to binary ds = ds.with_column(VIDEO_KEYFRAMES_COLUMN, base64_to_binary(col(VIDEO_KEYFRAMES_COLUMN))) # Generate a data item ID (SHA256 hash) based on the TOS path ds = ds.with_column("__data_item_id", generate_sha256_hash(col(VIDEO_KEYFRAMES_TOS_COLUMN))) # Set the data storage format to lance format = "lance" # Configure Lance write options write_options = LanceWriteOptions(uri=TOS_TEST_LANCE_DIR, io_config=io_config) # Print the IO configuration (for debugging) print(io_config) # Configure options for creating the LAS dataset create_ds_options = CreateLasDatasetOptions( nick_name=DATASET_NAME, # Dataset nickname privacy="public", # Privacy setting: public description="This is test dataset" # Dataset description ) # Write the dataset to LAS ds.write_las_dataset( name=DATASET_NAME, # Dataset name format=format, # Storage format write_options=write_options, # Write options create_ds_options=create_ds_options, # Create dataset options ) # Read the dataset df = daft.read_las_dataset(name=DATASET_NAME) df.show()
You need to modify some parameters as needed:
You can also modify the relevant parameters of the video keyframe extraction operator as needed:
In the LAS dataset, you can see the created video keyframe extraction result dataset. Click "Data Details" to view the extracted video result images stored in the data lake in Lance format.