自定义事件侦测

更新时间:
复制 MD 格式

传统的视频检索依赖人工打标或事后翻看录像,难以从海量视频中快速定位「有人摔倒」「有人撒网」「违规广告」这类特定事件。自定义事件侦测让您用一句话描述业务关心的事件,视频入库时由 AI 自动识别并打上事件标签、写入文件元数据;之后通过元数据查询接口即可直接检索命中事件的视频,无需自建视频理解链路。

重要

本功能基于新版 MetaQuery,当前处于邀测阶段,仅支持华东1(杭州)、新加坡地域。使用前请确保目标 Bucket 位于上述地域,并联系技术支持申请开通新版 MetaQuery 邀测能力。

应用场景

  • 安防监控:从海量监控视频中自动识别「有人摔倒」「有人翻越围栏」等安全事件,便于事后检索与告警联动。

  • 内容审核:对 UGC 视频自动标记「违规广告」「违规手势」等业务自定义违规事件,辅助人工复核。

  • 行业巡检:对生产、渔业、交通等场景的视频自动标记业务关注的特定行为,沉淀为可检索的结构化标签。

工作原理

  1. 定义事件标签:在目标 Dataset 的 DatasetConfig 中开启用户自定义标签,为每个事件配置名称(Name)和触发条件描述(Description)。

  2. 入库自动识别:视频上传并路由到该 Dataset 后,OSS 异步对视频做内容理解,按标签的描述匹配画面中发生的事件。

  3. 写入元数据:匹配到的事件标签写入该文件在 Dataset 中的元数据(Labels)。

  4. 按标签检索:通过 SimpleQueryLabels.LabelName 检索命中事件的文件;也可通过 MNS 通知获取命中的标签。

说明

视频内容理解为异步执行,上传后需要等待一段时间事件标签才会生成;在此之前文件可能查询不到。

使用限制

  • 调用方需具备 oss:MetaQueryoss:PutObject 等权限。

  • 如需接收文件索引完成通知,请提前创建 MNS 队列,并确保 OpenMetaQuery 使用的 RAM 角色拥有向该队列发送消息的权限。

  • 如需将不同对象路由到不同 Dataset,需要在开启 MetaQuery 时配置 RouteRule

1. 开启 MetaQuery

semantic 模式为 Bucket 开启元数据管理功能。以下示例基于 OSS Java SDK V2(com.aliyun:alibabacloud-oss-v2)与 OSS Go SDK V2(github.com/aliyun/alibabacloud-oss-go-sdk-v2),并从环境变量 OSS_ACCESS_KEY_IDOSS_ACCESS_KEY_SECRET 读取访问凭证。

Java SDK

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.dataprocess.OSSDataProcessClient;
import com.aliyun.sdk.service.oss2.dataprocess.models.*;
import java.util.Arrays;
import java.util.Collections;

public class OpenMetaQuerySample {
    public static void main(String[] args) throws Exception {
        try (OSSDataProcessClient client = OSSDataProcessClient.newBuilder()
                .region("cn-hangzhou")
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .build()) {
            MetaQueryOpenBody body = MetaQueryOpenBody.newBuilder()
                    .routeRule(RouteRule.newBuilder()
                            .type("OSSTag")
                            .autoCreateDataset("True")
                            .ossTagKey("routing-dataset")
                            .build())
                    .notificationAttributes(NotificationAttributes.newBuilder()
                            .notifications(MetaQueryNotifications.newBuilder()
                                    .notifications(Collections.singletonList(
                                            MetaQueryNotification.newBuilder()
                                                    .mns("metaquery-index-notification")
                                                    .build()))
                                    .build())
                            .withFields(Arrays.asList("Labels", "Insights"))
                            .build())
                    .build();

            client.openMetaQuery(OpenMetaQueryRequest.newBuilder()
                    .bucket("examplebucket")
                    .mode("semantic")
                    .role("AliyunMetaQueryDefaultRole")
                    .metaQueryBody(body)
                    .build());
            System.out.println("open meta query success");
        }
    }
}
说明

多 Dataset 路由(RouteRule)、索引完成 MNS 通知(NotificationAttributes)以及 Bucket 级默认 DatasetConfig,需在 OpenMetaQuery 请求体中一并配置,字段说明请参见 OpenMetaQuery;如需在通知消息中返回事件标签,请在 WithFields 中加入 Labels

2. 创建 Dataset 并配置事件标签

调用 CreateDataset 创建 Dataset,并通过 DatasetConfig 配置自定义事件标签:将 Insights.Video.Label.UserDefined.Enable 设置为 true,并在 Labels 中配置标签清单。各字段含义如下。

字段

说明

Name

标签名称,查询时按该名称检索。例如 有人摔倒

Description

标签的触发条件描述,作为 AI 匹配的语义提示。建议写清动作、场景和关键细节,例如 画面中有人由站立或行走变为倒在地面的动作

Java SDK

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.dataprocess.OSSDataProcessClient;
import com.aliyun.sdk.service.oss2.dataprocess.models.*;
import java.util.Arrays;

public class CreateDatasetSample {
    public static void main(String[] args) throws Exception {
        try (OSSDataProcessClient client = OSSDataProcessClient.newBuilder()
                .region("cn-hangzhou")
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .build()) {
            DatasetConfig config = DatasetConfig.newBuilder()
                    .insights(InsightsConfig.newBuilder()
                            .video(InsightsVideoConfig.newBuilder()
                                    .label(InsightsVideoLabelConfig.newBuilder()
                                            .userDefined(InsightsLabelUserDefinedConfig.newBuilder()
                                                    .enable("true")
                                                    .labels(Arrays.asList(
                                                            InsightsLabelItem.newBuilder()
                                                                    .name("有人摔倒")
                                                                    .description("画面中有人由站立或行走变为倒在地面的动作")
                                                                    .build(),
                                                            InsightsLabelItem.newBuilder()
                                                                    .name("有人撒网")
                                                                    .description("有人在水边或船上进行撒网捞鱼的动作")
                                                                    .build()))
                                                    .build())
                                            .build())
                                    .build())
                            .build())
                    .build();

            client.createDataset(CreateDatasetRequest.newBuilder()
                    .bucket("examplebucket")
                    .datasetName("security-events")
                    .datasetConfig(config)
                    .build());
            System.out.println("create dataset success");
        }
    }
}
说明

兼容旧版本的基础自定义标签开关也可通过 WorkflowParameters 配置,该方式仅用于存量配置,后续新功能不再通过 WorkflowParameters 演进。新接入建议统一使用 DatasetConfig

3. 上传视频并路由到 Dataset

上传视频时,通过 OSS Object Tag 设置 routing-dataset=security-events,将文件路由到目标 Dataset。文件索引完成后,会按照 Dataset 中配置的标签清单进行事件匹配。

Java SDK

import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.models.PutObjectRequest;
import com.aliyun.sdk.service.oss2.transport.BinaryData;
import java.nio.file.Files;
import java.nio.file.Paths;

public class PutObjectSample {
    public static void main(String[] args) throws Exception {
        try (OSSClient client = OSSClient.newBuilder()
                .region("cn-hangzhou")
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .build()) {
            client.putObject(PutObjectRequest.newBuilder()
                    .bucket("examplebucket")
                    .key("security/event-a.mp4")
                    .tagging("routing-dataset=security-events")
                    .body(BinaryData.fromStream(Files.newInputStream(Paths.get("/local/path/event-a.mp4"))))
                    .build());
            System.out.println("put object success");
        }
    }
}

(可选)为单个文件附加临时标签

如果某个文件需要使用 Dataset 标签清单之外的临时标签,可以在上传时通过自定义元数据头携带 URL 编码后的标签清单。HTTP 头名称为 x-oss-meta-metaquery-user-defined-labels;使用 SDK 时,metadata 的 key 填写 metaquery-user-defined-labels

Java SDK

import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.models.PutObjectRequest;
import com.aliyun.sdk.service.oss2.transport.BinaryData;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;

public class PutObjectWithLabelsSample {
    public static void main(String[] args) throws Exception {
        String labels = URLEncoder.encode(
                "[{\"Name\":\"有人摔倒\",\"Description\":\"画面中有人由站立或行走变为倒在地面的动作\"}]",
                StandardCharsets.UTF_8);
        try (OSSClient client = OSSClient.newBuilder()
                .region("cn-hangzhou")
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .build()) {
            client.putObject(PutObjectRequest.newBuilder()
                    .bucket("examplebucket")
                    .key("security/event-x.mp4")
                    .tagging("routing-dataset=security-events")
                    .metadata(Collections.singletonMap("metaquery-user-defined-labels", labels))
                    .body(BinaryData.fromStream(Files.newInputStream(Paths.get("/local/path/event-x.mp4"))))
                    .build());
            System.out.println("put object success");
        }
    }
}

4. 查询命中文件

文件索引完成后,调用 SimpleQuery 在指定 Dataset 内按 Labels.LabelName 精确查询命中文件。如果在开启 MetaQuery 时配置了 MNS 通知,您也可以通过消费 MNS 消息判断文件是否索引完成,并从通知消息中读取命中的 Labels

Java SDK

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.dataprocess.OSSDataProcessClient;
import com.aliyun.sdk.service.oss2.dataprocess.models.*;
import java.util.Arrays;

public class SimpleQueryLabelSample {
    public static void main(String[] args) throws Exception {
        try (OSSDataProcessClient client = OSSDataProcessClient.newBuilder()
                .region("cn-hangzhou")
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .build()) {
            SimpleQueryResult result = client.simpleQuery(SimpleQueryRequest.newBuilder()
                    .bucket("examplebucket")
                    .datasetName("security-events")
                    .query(SimpleQuery.newBuilder()
                            .field("Labels.LabelName")
                            .operation("eq")
                            .value("有人摔倒")
                            .build())
                    .withFields(Arrays.asList("Filename", "URI", "Labels"))
                    .maxResults(20)
                    .build());
            for (File file : result.files()) {
                System.out.println(file.filename() + " " + file.labels());
            }
        }
    }
}

响应中每个命中文件的 Labels.Label.LabelName 字段即为匹配的业务标签。例如:

<File>
  <Filename>security/event-a.mp4</Filename>
  <Labels>
    <Label>
      <LabelName>有人摔倒</LabelName>
    </Label>
  </Labels>
</File>

相关 API