

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用存储视频分析操作
<a name="video"></a>

Amazon Rekognition Video 是可用于分析视频的 API。利用 Amazon Rekognition Video，您可以检测存储于 Amazon Simple Storage Service (Amazon S3) 存储桶的视频中的标签、人脸、人员、名人和成人（暗示性和明显的）内容。您可以在公共安全等类别中使用亚马逊 Rekognition Video。 media/entertainment 以前，扫描视频中的物体或人员可能需要人进行数小时的查看，并且这种方式容易出错。Amazon Rekognition Video 将自动检测视频中的项目和它们出现的时间。

本节介绍 Amazon Rekognition Video 可执行的分析类型、API 的概述以及使用 Amazon Rekognition Video 的示例。

**Topics**
+ [分析类型](#video-recognition-types)
+ [Amazon Rekognition Video API 概述](#video-api-overview)
+ [调用 Amazon Rekognition Video 操作](api-video.md)
+ [配置 Amazon Rekognition Video](api-video-roles.md)
+ [使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)](video-analyzing-with-sqs.md)
+ [使用分析视频 AWS Command Line Interface](video-cli-commands.md)
+ [参考：视频分析结果通知](video-notification-payload.md)
+ [Amazon Rekognition Video 故障排除](video-troubleshooting.md)

## 分析类型
<a name="video-recognition-types"></a>

您可以使用 Amazon Rekognition Video 分析视频中的以下信息：
+ [视频分段](segments.md)
+ [标签](labels.md)
+ [暗示性和明显的成人内容](moderation.md)
+ [文本](text-detection.md)
+ [名人](celebrities.md)
+ [人脸](faces.md)
+ [人员](persons.md)

有关更多信息，请参阅 [Amazon Rekognition 的工作原理](how-it-works.md)。

## Amazon Rekognition Video API 概述
<a name="video-api-overview"></a>

Amazon Rekognition Video 处理存储在 Amazon S3 存储桶中的视频。设计模式是异步操作集。您可通过调用 `Start` 操作 (如 [StartLabelDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartLabelDetection.html)) 来启动视频分析。将请求完成状态发布到Amazon Simple Notification Service (Amazon SNS) 主题。要从亚马逊 SNS 主题中获取完成状态，您可以使用亚马逊简单队列服务 (Amazon SQS) Simple Queue 队列或函数。 AWS Lambda 在获得完成状态之后，请调用 `Get` 操作 (如 [GetLabelDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetLabelDetection.html)) 以获取请求的结果。

下图显示了检测存储于 Amazon S3 存储桶的视频中的标签的过程。在此图中，Amazon SQS 队列将从 Amazon SNS 主题获取完成状态。或者，你可以使用一个 AWS Lambda 函数。

![\[流程图描述了使用 Amazon Rekognition Video、Amazon SNS 和 Amazon SQS 进行视频分析的步骤，以及任务和向相应 StartLabelDetection队列发布 GetLabelDetection 完成状态等组件。\]](http://docs.aws.amazon.com/zh_cn/rekognition/latest/dg/images/VideoRekognition.png)


其他 Amazon Rekognition Video 操作的过程相同。下表列出了每个非存储 Amazon Rekognition 操作的 `Start` 和 `Get` 操作。


| 检测 | Start 操作 | Get 操作 | 
| --- | --- | --- | 
|  视频分段  |  [StartSegmentDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartSegmentDetection.html)  |  [GetSegmentDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetSegmentDetection.html)  | 
|  标签  |  [StartLabelDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartLabelDetection.html)  |  [GetLabelDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetLabelDetection.html)  | 
|  明显的或暗示性成人内容  |  [StartContentModeration](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartContentModeration.html)  |  [GetContentModeration](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetContentModeration.html)  | 
|  文本  |  [StartTextDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartTextDetection.html)  |  [GetTextDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetTextDetection.html)  | 
|  名人  |  [StartCelebrityRecognition](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartCelebrityRecognition.html)  |  [GetCelebrityRecognition](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetCelebrityRecognition.html)  | 
|  人脸  |  [StartFaceDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartFaceDetection.html)  |  [GetFaceDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetFaceDetection.html)  | 
|  People  |  [StartPersonTracking](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartPersonTracking.html)  |  [GetPersonTracking](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetPersonTracking.html)  | 

对于 `Get` 之外的 `GetCelebrityRecognition` 操作，Amazon Rekognition Video 将返回有关何时在整个输入视频中检测到实体的跟踪信息。

有关使用 Amazon Rekognition Video 的更多信息，请参阅[调用 Amazon Rekognition Video 操作](api-video.md)。有关使用 Amazon SQS 执行视频分析的示例，请参阅[使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)](video-analyzing-with-sqs.md)。有关 AWS CLI 示例，请参阅[使用分析视频 AWS Command Line Interface](video-cli-commands.md)。

### 视频格式和存储
<a name="video-storage-formats"></a>

Amazon Rekognition 操作可以分析存储在 Amazon S3 存储桶中的视频。有关对视频分析操作的所有限制的列表，请参阅[Amazon Rekognition 中的准则和配额](limits.md)。

视频必须使用 H.264 编解码器进行编码。支持的文件格式为 MPEG-4 和 MOV。

编解码器是一种软件或硬件，用于压缩数据以提高传输速度以及将收到的数据解压为其原始形式。H.264 编解码器通常用于录制、压缩和分发视频内容。视频文件格式可包含一个或多个编解码器。如果您的 MOV 或 MPEG-4 格式的视频文件不适用于 Amazon Rekognition Video，请检查用于对该视频进行编码的编解码器是否为 H.264。

任何分析音频数据的 Amazon Rekognition Video API 仅支持 AAC 音频编解码器。

存储视频的最大文件大小为 10GB。

### 搜索人员
<a name="video-searching-persons-overview"></a>

您可以使用存储在集合中的面部元数据来搜索视频中的人员。例如，您可以在已存档视频中搜索某个特定人员或搜索多个人员。您使用 [IndexFaces](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_IndexFaces.html) 操作将源图像中的面部元数据存储在集合中。然后，您可以使用 [StartFaceSearch](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartFaceSearch.html) 在集合中开始异步搜索人脸。您使用 [GetFaceSearch](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GeFaceSearch.html) 获取搜索结果。有关更多信息，请参阅 [搜索存储视频中的人脸](procedure-person-search-videos.md)。搜索人员是基于存储的 Amazon Rekognition 操作的一个示例。有关更多信息，请参阅 [基于存储的 API 操作](how-it-works-storage-non-storage.md#how-it-works-storage-based)。

您还可以在流视频中搜索人员。有关更多信息，请参阅 [使用流视频事件](streaming-video.md)。

# 调用 Amazon Rekognition Video 操作
<a name="api-video"></a>

Amazon Rekognition Video 是一个异步 API，可用于分析存储在 Amazon Simple Storage Service (Amazon S3) 存储桶的视频。您可以通过调用 Amazon Rekognit `Start` ion Video 操作开始分析视频，例如。[StartPersonTracking](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartPersonTracking.html)Amazon Rekognition Video 将分析请求的结果发布到 Amazon Simple Notification Service (Amazon SNS) 主题。您可以使用亚马逊简单队列服务 (Amazon SQS) Simple Queue 队列或 AWS Lambda 函数来获取来自亚马逊 SNS 主题的视频分析请求的完成状态。最后，您可以通过调用 Amazon Rekognit `Get` ion 操作来获取视频分析请求结果，例如。[GetPersonTracking](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetPersonTracking.html)

以下各节中的信息使用标签检测操作来展示 Amazon Rekognition Video 如何在存储于 Amazon S3 存储桶的视频中检测标签（对象、事件、概念和活动）。同样的方法也适用于其他 Amazon Rekognition Video 操作——例如，和。[StartFaceDetection[StartPersonTracking](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartPersonTracking.html)](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartFaceDetection.html)示例 [使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)](video-analyzing-with-sqs.md) 说明了如何通过使用 Amazon SQS 队列从 Amazon SNS 主题获取完成状态来分析视频。它还用作其他 Amazon Rekognition Video 示例（如[人物的轨迹](persons.md)）的基础。有关 AWS CLI 示例，请参阅[使用分析视频 AWS Command Line Interface](video-cli-commands.md)。

**Topics**
+ [启动视频分析](#api-video-start)
+ [获取 Amazon Rekognition Video 分析请求的完成状态](#api-video-get-status)
+ [获取 Amazon Rekognition Video 分析结果](#api-video-get)

## 启动视频分析
<a name="api-video-start"></a>

您可以通过致电来启动亚马逊 Rekognition Video 标签检测请求。[StartLabelDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartLabelDetection.html)下面是由 `StartLabelDetection` 传递的 JSON 请求的示例。

```
{
    "Video": {
        "S3Object": {
            "Bucket": "amzn-s3-demo-bucket",
            "Name": "video.mp4"
        }
    },
    "ClientRequestToken": "LabelDetectionToken",
    "MinConfidence": 50,
    "NotificationChannel": {
        "SNSTopicArn": "arn:aws:sns:us-east-1:nnnnnnnnnn:topic",
        "RoleArn": "arn:aws:iam::nnnnnnnnnn:role/roleopic"
    },
    "JobTag": "DetectingLabels"
}
```

输入参数 `Video` 提供视频文件名以及从中检索此文件的 Amazon S3 存储桶。`NotificationChannel` 包含 Amazon Rekognition Video 在视频分析请求完成时通知的 Amazon SNS 主题的 Amazon 资源名称 (ARN)。Amazon SNS 主题必须与您调用的 Amazon Rekognition Video 端点位于同一 AWS 区域。`NotificationChannel` 还包含允许 Amazon Rekognition Video 向 Amazon SNS 主题进行发布的角色的 ARN。您通过创建 IAM 服务角色为 Amazon Rekognition 提供向您的 Amazon SNS 主题进行发布的权限。有关更多信息，请参阅 [配置 Amazon Rekognition Video](api-video-roles.md)。

您也可以指定一个可选输入参数 `JobTag`，该参数使您能够标识处于已发布到 Amazon SNS 主题的完成状态的任务。

为防止分析任务意外重复，您可以选择性地提供幂等令牌 `ClientRequestToken`。如果您为 `ClientRequestToken` 提供了一个值，`Start` 操作将为对 start 操作的多个相同调用（如 `StartLabelDetection`）返回相同的 `JobId`。`ClientRequestToken` 令牌的使用期限为 7 天。7 天后，您可以重复使用它。如果您在令牌使用期限内重复使用令牌，则会出现以下情况：
+ 如果您通过相同的 `Start` 操作和相同的输入参数重复使用此令牌，则将返回相同的 `JobId`。此任务不会再次执行，Amazon Rekognition Video 不会向注册的 Amazon SNS 主题发送完成状态。
+ 如果您对相同的 `Start` 操作重复使用此令牌，并且只进行了细微的输入参数更改，则会引发 `IdempotentParameterMismatchException`（HTTP 状态代码：400）异常。
+ 您不应该通过其他 `Start` 操作重复使用令牌，因为从 Amazon Rekognition 会得到不可预测的结果。

对 `StartLabelDetection` 操作的响应是作业标识符 (`JobId`)。使用 `JobId` 可跟踪请求并在 Amazon Rekognition Video 将完成状态发布到 Amazon SNS 主题之后获取分析结果。例如：

```
{"JobId":"270c1cc5e1d0ea2fbc59d97cb69a72a5495da75851976b14a1784ca90fc180e3"}
```

如果您以并发方式启动的作业过多，则调用 `StartLabelDetection` 会引发 `LimitExceededException`（HTTP 状态代码：400），直到并发运行的作业数量低于 Amazon Rekognition 服务限制。

如果您发现活动量陡增时会引发 `LimitExceededException` 异常，请考虑使用 Amazon SQS 队列管理传入请求。如果您发现 Amazon SQS 队列无法管理您的平均并发请求数，并且仍然收到`LimitExceededException`异常，请联系 AWS 支持人员。

## 获取 Amazon Rekognition Video 分析请求的完成状态
<a name="api-video-get-status"></a>

Amazon Rekognition Video 会将分析完成通知发送到注册的 Amazon SNS 主题。通知将在 JSON 字符串中包含操作的任务标识符和完成状态。成功的视频分析请求具有 `SUCCEEDED` 状态。例如，以下结果展示了标签检测任务的成功处理。

```
{
    "JobId": "270c1cc5e1d0ea2fbc59d97cb69a72a5495da75851976b14a1nnnnnnnnnnnn",
    "Status": "SUCCEEDED",
    "API": "StartLabelDetection",
    "JobTag": "DetectingLabels",
    "Timestamp": 1510865364756,
    "Video": {
        "S3ObjectName": "video.mp4",
        "S3Bucket": "amzn-s3-demo-bucket"
    }
}
```

有关更多信息，请参阅 [参考：视频分析结果通知](video-notification-payload.md)。

要获取由 Amazon Rekognition Video 发布到 Amazon SNS 主题的状态信息，请使用以下选项之一：
+ **AWS Lambda** – 您可订阅写入到 Amazon SNS 主题的 AWS Lambda 函数。此函数在 Amazon Rekognition 通知 Amazon SNS 主题请求已完成时调用。如果您希望服务器端代码处理视频分析请求的结果，请使用 Lambda 函数。例如，在将信息返回到客户端应用程序之前，您可能希望使用服务器端代码来注释视频或创建有关视频内容的报告。我们还建议对大型视频进行服务器端处理，因为 Amazon Rekognition API 可能返回大量数据。
+ **Amazon Simple Queue Service** – 您可以为 Amazon SQS 队列订阅 Amazon SNS 主题。您随后将轮询 Amazon SQS 队列以检索 Amazon Rekognition 在视频分析请求完成后发布的完成状态。有关更多信息，请参阅 [使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)](video-analyzing-with-sqs.md)。如果您希望仅从客户端应用程序调用 Amazon Rekognition Video 操作，请使用 Amazon SQS 队列。

**重要**  
我们建议不要通过反复调用 Amazon Rekognition Video `Get` 操作来获取请求完成状态。这是因为 Amazon Rekognition Video 会在发出的请求过多时限制 `Get` 操作。如果您同时处理多个视频，那么监控一个 SQS 队列中的完成通知比为每个视频的状态分别轮询 Amazon Rekognition Video 更加简单有效。

## 获取 Amazon Rekognition Video 分析结果
<a name="api-video-get"></a>

 要获取视频分析请求的结果，请先确保从 Amazon SNS 主题检索的完成状态为 `SUCCEEDED`。然后调用 `GetLabelDetection`，它将传递从 `StartLabelDetection` 返回的 `JobId` 值。请求 JSON 类似于以下示例：

```
{
    "JobId": "270c1cc5e1d0ea2fbc59d97cb69a72a5495da75851976b14a1784ca90fc180e3",
    "MaxResults": 10,
    "SortBy": "TIMESTAMP"
}
```

JobId 是视频分析操作的标识符。由于视频分析会生成大量数据，请使用 `MaxResults` 指定要在单个 Get 操作中返回的结果的最大数量。`MaxResults` 的默认值为 1000。如果您指定的值大于 1000，则返回最多 1000 个结果。如果该操作未返回整个结果集，下一页的分页令牌将在操作响应中返回。如果您来自上一个 Get 请求的分页令牌，请将它与 `NextToken` 结合使用以获取下一页结果。

**注意**  
Amazon Rekognition 将保留视频分析操作的结果 7 天。此时间过后，您将无法检索分析结果。

`GetLabelDetection` 操作响应 JSON 与以下内容类似：

```
{
    "Labels": [
        {
            "Timestamp": 0,
            "Label": {
                "Instances": [],
                "Confidence": 60.51791763305664,
                "Parents": [],
                "Name": "Electronics"
            }
        },
        {
            "Timestamp": 0,
            "Label": {
                "Instances": [],
                "Confidence": 99.53411102294922,
                "Parents": [],
                "Name": "Human"
            }
        },
        {
            "Timestamp": 0,
            "Label": {
                "Instances": [
                    {
                        "BoundingBox": {
                            "Width": 0.11109819263219833,
                            "Top": 0.08098889887332916,
                            "Left": 0.8881205320358276,
                            "Height": 0.9073750972747803
                        },
                        "Confidence": 99.5831298828125
                    },
                    {
                        "BoundingBox": {
                            "Width": 0.1268676072359085,
                            "Top": 0.14018426835536957,
                            "Left": 0.0003282368124928324,
                            "Height": 0.7993982434272766
                        },
                        "Confidence": 99.46029663085938
                    }
                ],
                "Confidence": 99.53411102294922,
                "Parents": [],
                "Name": "Person"
            }
        },
        .
        .   
        .

        {
            "Timestamp": 166,
            "Label": {
                "Instances": [],
                "Confidence": 73.6471176147461,
                "Parents": [
                    {
                        "Name": "Clothing"
                    }
                ],
                "Name": "Sleeve"
            }
        }
        
    ],
    "LabelModelVersion": "2.0",
    "JobStatus": "SUCCEEDED",
    "VideoMetadata": {
        "Format": "QuickTime / MOV",
        "FrameRate": 23.976024627685547,
        "Codec": "h264",
        "DurationMillis": 5005,
        "FrameHeight": 674,
        "FrameWidth": 1280
    }
}
```

`GetLabelDetection` 和 `GetContentModeration` 操作允许您按时间戳或标签名称对分析结果进行分类。您还可以按视频片段或时间戳汇总结果。

您可按检测时间 (视频开始的时间 (毫秒)) 或检测到的实体 (物体、人脸、名人、审阅标签或人员) 的字母顺序为结果排序。要按时间排序，请将 `SortBy` 输入参数的值设置为 `TIMESTAMP`。如果未指定 `SortBy`，则默认行为是按时间排序。上述示例是按时间排序的。要按实体排序，请将 `SortBy` 输入参数与适用于您执行的操作的值结合使用。例如，要按在对 `GetLabelDetection` 的调用中检测到的标签排序，请使用值 `NAME`。

要按时间戳汇总结果，请将 `AggregateBy` 参数的值设置为 `TIMESTAMPS`。要按视频片段进行汇总，请将 `AggregateBy` 的值设置为 `SEGMENTS`。`SEGMENTS` 汇总模式将随着时间的推移汇总标签，同时`TIMESTAMPS`给出检测到标签的时间戳，使用 2 FPS 采样和每帧输出（注意：当前采样率可能会发生变化，不应假设当前的采样率）。如果未指定值，则默认汇总方法为 `TIMESTAMPS`。

# 配置 Amazon Rekognition Video
<a name="api-video-roles"></a>

要将 Amazon Rekognition Video API 用于所存储视频，您必须配置用户和 IAM 服务角色以访问您的 Amazon SNS 主题。您还必须为您的 Amazon SNS 主题订阅 Amazon SQS 队列。

**注意**  
如果使用这些说明来设置 [使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)](video-analyzing-with-sqs.md) 示例，则无需执行步骤 3、4、5 和 6。此示例包括用于创建和配置 Amazon SNS 主题和 Amazon SQS 队列的代码。

本节中的示例通过使用向 Amazon Rekognition Video 提供对多个主题的访问权限的指令，创建新的 Amazon SNS 主题。如果您想要使用现有的 Amazon SNS 主题，请对步骤 3 使用[授予访问现有 Amazon SNS 主题的权限](#api-video-roles-single-topics)。<a name="configure-rekvid-procedure"></a>

**配置 Amazon Rekognition Video**

1. 设置 AWS 账户以访问亚马逊 Rekognition Video。有关更多信息，请参阅 [步骤 1：设置 AWS 账户并创建用户](setting-up.md)。

1. 安装和配置所需的 AWS SDK。有关更多信息，请参阅 [第 2 步：设置 AWS CLI 和 AWS SDKs](setup-awscli-sdk.md)。

1. 要运行本开发人员指南中的代码示例，请确保您选择的用户具有编程访问权限。请参阅[授予编程式访问权限](sdk-programmatic-access.md)了解更多信息。

   您的用户还需要至少以下权限：
   + 亚马逊SQSFull访问权限
   + AmazonRekognitionFullAccess
   + 亚马逊 3 FullAccess
   + 亚马逊SNSFull访问权限

   如果您使用 IAM Identity Center 进行身份验证，请将权限添加到角色的权限集中，否则将权限添加到您的 IAM 角色中。

1. 通过使用 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/v2/home)[创建 Amazon SNS 主题](https://docs.aws.amazon.com/sns/latest/dg/CreateTopic.html)。在主题名称前面加上。*AmazonRekognition*记下主题的 Amazon 资源名称 (ARN)。确保该主题与您使用的 AWS 端点位于同一区域。

1. 使用 [Amazon SQS 控制台](https://console.aws.amazon.com/sqs/)[创建 Amazon SQS 标准队列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-create-queue.html)。记录队列 ARN。

1. [为队列订阅主题](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-subscribe-queue-sns-topic.html)（您在步骤 3 中创建）。

1. [为向 Amazon SQS 队列发送消息的 Amazon SNS 主题授予权限](https://docs.aws.amazon.com/sns/latest/dg/SendMessageToSQS.html#SendMessageToSQS.sqs.permissions)。

1. 创建 IAM 服务角色来为 Amazon Rekognition Video 提供对 Amazon SNS 主题的访问权限。记下服务角色的 Amazon 资源名称 (ARN)。有关更多信息，请参阅 [提供对多个 Amazon SNS 主题的访问权限](#api-video-roles-all-topics)。

1. 为确保您的账户安全，您需要将 Rekognition 的访问范围限制为仅限于您正在使用的资源。这可以通过将信任策略附加到您的 IAM 服务角色来完成。有关如何执行此操作的信息，请参阅 [防止跨服务混淆代理](cross-service-confused-deputy-prevention.md)。

1. 向您在步骤 1 中创建的用户[添加以下内联策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html#embed-inline-policy-console)：

   为该内联策略提供您选择的名称。

1. 如果您使用客户托管 AWS Key Management Service 密钥对 Amazon S3 存储桶中的视频进行加密，请向密钥[添加](https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-modifying.html#key-policy-modifying-how-to-console-policy-view)权限，允许您在步骤 7 中创建的服务角色解密视频。服务角色至少需要权限才能执行 `kms:GenerateDataKey` 和 `kms:Decrypt` 操作。例如：

   ```
   {
       "Sid": "Decrypt only",
       "Effect": "Allow",
       "Principal": {
           "AWS": "arn:aws:iam::111122223333:user/user from step 1"
       },
       "Action": [
           "kms:Decrypt",
           "kms:GenerateDataKey"
       ],
       "Resource": "*"
   }
   ```

   有关更多信息，请参阅[我的 Amazon S3 存储桶使用自定义 AWS KMS 密钥进行默认加密。如何允许用户从存储桶下载并上传到存储桶？](https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-access-default-encryption/)以及[使用服务器端加密和存储在 AWS Key Management Service 中的 KMS 密钥 (SSE-KMS) 保护数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html)。

1. 现在您就可以运行[使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)](video-analyzing-with-sqs.md)和[使用分析视频 AWS Command Line Interface](video-cli-commands.md)中的示例了。

## 提供对多个 Amazon SNS 主题的访问权限
<a name="api-video-roles-all-topics"></a>

您可使用 IAM 服务角色为 Amazon Rekognition Video 提供对您创建的 Amazon SNS 主题的访问权限。IAM 提供了用于创建 Amazon Rekognition Video 服务角色的 *Rekognition* 使用案例。

您可以使用权限策略并在主题名称前加上——例如，，来授予亚马逊 Rekognition Video 访问多个亚马逊 SNS 主题`AmazonRekognitionServiceRole`的权限。*AmazonRekognition*`AmazonRekognitionMyTopicName`

**让 Amazon Rekognition Video 访问多个 Amazon SNS 主题**

1. [创建 IAM 服务角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html?icmpid=docs_iam_console)。使用以下信息创建 IAM 服务角色：

   1. 对于服务名称，选择 **Rekognition**。

   1. 对于服务角色使用案例，选择 **Rekognition**。您应该会看到列出的**AmazonRekognitionServiceRole**权限策略。 **AmazonRekognitionServiceRole**允许亚马逊 Rekognition Video 访问前缀为的亚马逊 SNS 主题。*AmazonRekognition*

   1. 为该服务角色指定您选择的名称。

1. 记下服务角色的 ARN。您需要它才能开始视频分析操作。

## 授予访问现有 Amazon SNS 主题的权限
<a name="api-video-roles-single-topics"></a>

您可以创建一个权限策略，允许 Amazon Rekognition Video 访问现有的 Amazon SNS 主题。

**让 Amazon Rekognition Video 访问现有 Amazon SNS 话题**

1. [ 使用 IAM JSON 策略编辑器创建新的权限策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-json-editor)，然后使用以下策略。将 `topicarn` 替换为所需 Amazon SNS 主题的 Amazon 资源名称 (ARN)。

1. [创建 IAM 服务角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html?icmpid=docs_iam_console)，或者更新现有 IAM 服务角色。使用以下信息创建 IAM 服务角色：

   1. 对于服务名称，选择 **Rekognition**。

   1. 对于服务角色使用案例，选择 **Rekognition**。

   1. 附加您在步骤 1 中创建的权限策略。

1. 记下服务角色的 ARN。您需要它才能开始视频分析操作。

# 使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)
<a name="video-analyzing-with-sqs"></a>

本过程展示如何使用 Amazon Rekognition Video 标签检测操作、存储在 Amazon S3 存储桶内的视频和 Amazon SNS 主题来检测视频中的标签。本过程还说明如何使用 Amazon SQS 队列从 Amazon SNS 主题获取完成状态。有关更多信息，请参阅 [调用 Amazon Rekognition Video 操作](api-video.md)。您不必局限于使用 Amazon SQS 队列。例如，您可以使用 AWS Lambda 函数来获取完成状态。有关更多信息，请参阅[使用 Amazon SNS 通知调用 Lambda 函数](https://docs.aws.amazon.com/sns/latest/dg/sns-lambda.html)。

本过程中的示例代码展示如何执行以下操作：

1. 创建 Amazon SNS 主题。

1. 创建 Amazon SQS 队列。

1. 为 Amazon Rekognition Video 提供将视频分析操作的完成状态发布到 Amazon SNS 主题的权限。

1. 为 Amazon SQS 队列订阅 Amazon SNS 主题。

1. 通过调用 [StartLabelDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartLabelDetection.html) 启动视频分析请求。

1. 从 Amazon SQS 队列获取完成状态。示例将跟踪 `StartLabelDetection` 中返回的任务标识符 (`JobId`) 并且仅获取与从完成状态读取的任务标识符匹配的结果。如果其他应用程序使用的是同一队列和主题，那么这是一个重要的考量。为简便起见，该示例会删除不匹配的任务。请考虑将它们添加到 Amazon SQS 死信队列以进行进一步调查。

1. 通过调用 [GetLabelDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_GetLabelDetection.html) 来获取和显示视频分析结果。

## 先决条件
<a name="video-prerequisites"></a>

Java 和 Python 提供了此过程的示例代码。您需要安装相应的 AWS SDK。有关更多信息，请参阅 [Amazon Rekognition 入门](getting-started.md)。您使用的 AWS 账户必须具有对 Amazon Rekognition API 的访问权限。有关更多信息，请参阅 [Amazon Rekognition 定义的操作](https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonrekognition.html#amazonrekognition-actions-as-permissions)。

**检测视频中的标签**

1. 配置用户对 Amazon Rekognition Video 的访问权限并配置 Amazon Rekognition Video 对 Amazon SNS 的访问权限。有关更多信息，请参阅 [配置 Amazon Rekognition Video](api-video-roles.md)。您无需执行步骤 3、4、5 和 6，因为示例代码将创建并配置 Amazon SNS 主题和 Amazon SQS 队列。

1. 将 MOV 或 MPEG-4 格式的视频文件上传到 Amazon S3 存储桶。对于测试，请上传时长不超过 30 秒的视频。

   有关说明，请参阅**《Amazon Simple Storage Service 用户指南》中的[将对象上传到 Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UploadingObjectsintoAmazonS3.html)。

   

1. 使用以下代码示例检测视频中的标签。

------
#### [ Java ]

   在函数 `main` 中：
   + 将 `roleArn` 替换为您在[配置 Amazon Rekognition Video](api-video-roles.md#configure-rekvid-procedure)的步骤 7 中创建的 IAM 服务角色的 ARN。
   + 将 `amzn-s3-demo-bucket` 和 `video` 的值替换为您在步骤 2 中指定的存储桶和视频文件名。

   ```
   //Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
   //PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-developer-guide/blob/master/LICENSE-SAMPLECODE.)
   
   package com.amazonaws.samples;
   import com.amazonaws.auth.policy.Policy;
   import com.amazonaws.auth.policy.Condition;
   import com.amazonaws.auth.policy.Principal;
   import com.amazonaws.auth.policy.Resource;
   import com.amazonaws.auth.policy.Statement;
   import com.amazonaws.auth.policy.Statement.Effect;
   import com.amazonaws.auth.policy.actions.SQSActions;
   import com.amazonaws.services.rekognition.AmazonRekognition;
   import com.amazonaws.services.rekognition.AmazonRekognitionClientBuilder;
   import com.amazonaws.services.rekognition.model.CelebrityDetail;
   import com.amazonaws.services.rekognition.model.CelebrityRecognition;
   import com.amazonaws.services.rekognition.model.CelebrityRecognitionSortBy;
   import com.amazonaws.services.rekognition.model.ContentModerationDetection;
   import com.amazonaws.services.rekognition.model.ContentModerationSortBy;
   import com.amazonaws.services.rekognition.model.Face;
   import com.amazonaws.services.rekognition.model.FaceDetection;
   import com.amazonaws.services.rekognition.model.FaceMatch;
   import com.amazonaws.services.rekognition.model.FaceSearchSortBy;
   import com.amazonaws.services.rekognition.model.GetCelebrityRecognitionRequest;
   import com.amazonaws.services.rekognition.model.GetCelebrityRecognitionResult;
   import com.amazonaws.services.rekognition.model.GetContentModerationRequest;
   import com.amazonaws.services.rekognition.model.GetContentModerationResult;
   import com.amazonaws.services.rekognition.model.GetFaceDetectionRequest;
   import com.amazonaws.services.rekognition.model.GetFaceDetectionResult;
   import com.amazonaws.services.rekognition.model.GetFaceSearchRequest;
   import com.amazonaws.services.rekognition.model.GetFaceSearchResult;
   import com.amazonaws.services.rekognition.model.GetLabelDetectionRequest;
   import com.amazonaws.services.rekognition.model.GetLabelDetectionResult;
   import com.amazonaws.services.rekognition.model.GetPersonTrackingRequest;
   import com.amazonaws.services.rekognition.model.GetPersonTrackingResult;
   import com.amazonaws.services.rekognition.model.Instance;
   import com.amazonaws.services.rekognition.model.Label;
   import com.amazonaws.services.rekognition.model.LabelDetection;
   import com.amazonaws.services.rekognition.model.LabelDetectionSortBy;
   import com.amazonaws.services.rekognition.model.NotificationChannel;
   import com.amazonaws.services.rekognition.model.Parent;
   import com.amazonaws.services.rekognition.model.PersonDetection;
   import com.amazonaws.services.rekognition.model.PersonMatch;
   import com.amazonaws.services.rekognition.model.PersonTrackingSortBy;
   import com.amazonaws.services.rekognition.model.S3Object;
   import com.amazonaws.services.rekognition.model.StartCelebrityRecognitionRequest;
   import com.amazonaws.services.rekognition.model.StartCelebrityRecognitionResult;
   import com.amazonaws.services.rekognition.model.StartContentModerationRequest;
   import com.amazonaws.services.rekognition.model.StartContentModerationResult;
   import com.amazonaws.services.rekognition.model.StartFaceDetectionRequest;
   import com.amazonaws.services.rekognition.model.StartFaceDetectionResult;
   import com.amazonaws.services.rekognition.model.StartFaceSearchRequest;
   import com.amazonaws.services.rekognition.model.StartFaceSearchResult;
   import com.amazonaws.services.rekognition.model.StartLabelDetectionRequest;
   import com.amazonaws.services.rekognition.model.StartLabelDetectionResult;
   import com.amazonaws.services.rekognition.model.StartPersonTrackingRequest;
   import com.amazonaws.services.rekognition.model.StartPersonTrackingResult;
   import com.amazonaws.services.rekognition.model.Video;
   import com.amazonaws.services.rekognition.model.VideoMetadata;
   import com.amazonaws.services.sns.AmazonSNS;
   import com.amazonaws.services.sns.AmazonSNSClientBuilder;
   import com.amazonaws.services.sns.model.CreateTopicRequest;
   import com.amazonaws.services.sns.model.CreateTopicResult;
   import com.amazonaws.services.sqs.AmazonSQS;
   import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
   import com.amazonaws.services.sqs.model.CreateQueueRequest;
   import com.amazonaws.services.sqs.model.Message;
   import com.amazonaws.services.sqs.model.QueueAttributeName;
   import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
   import com.fasterxml.jackson.databind.JsonNode;
   import com.fasterxml.jackson.databind.ObjectMapper;
   import java.util.*;
   
   public class VideoDetect {
    
       
       private static String sqsQueueName=null;
       private static String snsTopicName=null;
       private static String snsTopicArn = null;
       private static String roleArn= null;
       private static String sqsQueueUrl = null;
       private static String sqsQueueArn = null;
       private static String startJobId = null;
       private static String bucket = null;
       private static String video = null; 
       private static AmazonSQS sqs=null;
       private static AmazonSNS sns=null;
       private static AmazonRekognition rek = null;
       
       private static NotificationChannel channel= new NotificationChannel()
               .withSNSTopicArn(snsTopicArn)
               .withRoleArn(roleArn);
   
   
       public static void main(String[] args) throws Exception {
           
           video = "";
           bucket = "";
           roleArn= "";
   
           sns = AmazonSNSClientBuilder.defaultClient();
           sqs= AmazonSQSClientBuilder.defaultClient();
           rek = AmazonRekognitionClientBuilder.defaultClient();
     
           CreateTopicandQueue();
           
           //=================================================
           
           StartLabelDetection(bucket, video);
   
           if (GetSQSMessageSuccess()==true)
           	GetLabelDetectionResults();
           
          //=================================================  
           
   
           DeleteTopicandQueue();
           System.out.println("Done!");
          
       }
   
       
       static boolean GetSQSMessageSuccess() throws Exception
       {
       	boolean success=false;
   
      
           System.out.println("Waiting for job: " + startJobId);
           //Poll queue for messages
           List<Message> messages=null;
           int dotLine=0;
           boolean jobFound=false;
   
           //loop until the job status is published. Ignore other messages in queue.
           do{
               messages = sqs.receiveMessage(sqsQueueUrl).getMessages();
               if (dotLine++<40){
                   System.out.print(".");
               }else{
                   System.out.println();
                   dotLine=0;
               }
   
               if (!messages.isEmpty()) {
                   //Loop through messages received.
                   for (Message message: messages) {
                       String notification = message.getBody();
   
                       // Get status and job id from notification.
                       ObjectMapper mapper = new ObjectMapper();
                       JsonNode jsonMessageTree = mapper.readTree(notification);
                       JsonNode messageBodyText = jsonMessageTree.get("Message");
                       ObjectMapper operationResultMapper = new ObjectMapper();
                       JsonNode jsonResultTree = operationResultMapper.readTree(messageBodyText.textValue());
                       JsonNode operationJobId = jsonResultTree.get("JobId");
                       JsonNode operationStatus = jsonResultTree.get("Status");
                       System.out.println("Job found was " + operationJobId);
                       // Found job. Get the results and display.
                       if(operationJobId.asText().equals(startJobId)){
                           jobFound=true;
                           System.out.println("Job id: " + operationJobId );
                           System.out.println("Status : " + operationStatus.toString());
                           if (operationStatus.asText().equals("SUCCEEDED")){
                           	success=true;
                           }
                           else{
                               System.out.println("Video analysis failed");
                           }
   
                           sqs.deleteMessage(sqsQueueUrl,message.getReceiptHandle());
                       }
   
                       else{
                           System.out.println("Job received was not job " +  startJobId);
                           //Delete unknown message. Consider moving message to dead letter queue
                           sqs.deleteMessage(sqsQueueUrl,message.getReceiptHandle());
                       }
                   }
               }
               else {
                   Thread.sleep(5000);
               }
           } while (!jobFound);
   
           System.out.println("Finished processing video");
           return success;
       }
     
   
       private static void StartLabelDetection(String bucket, String video) throws Exception{
       	
           NotificationChannel channel= new NotificationChannel()
                   .withSNSTopicArn(snsTopicArn)
                   .withRoleArn(roleArn);
   
   
           StartLabelDetectionRequest req = new StartLabelDetectionRequest()
                   .withVideo(new Video()
                           .withS3Object(new S3Object()
                                   .withBucket(bucket)
                                   .withName(video)))
                   .withMinConfidence(50F)
                   .withJobTag("DetectingLabels")
                   .withNotificationChannel(channel);
   
           StartLabelDetectionResult startLabelDetectionResult = rek.startLabelDetection(req);
           startJobId=startLabelDetectionResult.getJobId();
           
       }
     
       private static void GetLabelDetectionResults() throws Exception{
   
           int maxResults=10;
           String paginationToken=null;
           GetLabelDetectionResult labelDetectionResult=null;
   
           do {
               if (labelDetectionResult !=null){
                   paginationToken = labelDetectionResult.getNextToken();
               }
   
               GetLabelDetectionRequest labelDetectionRequest= new GetLabelDetectionRequest()
                       .withJobId(startJobId)
                       .withSortBy(LabelDetectionSortBy.TIMESTAMP)
                       .withMaxResults(maxResults)
                       .withNextToken(paginationToken);
   
   
               labelDetectionResult = rek.getLabelDetection(labelDetectionRequest);
   
               VideoMetadata videoMetaData=labelDetectionResult.getVideoMetadata();
   
               System.out.println("Format: " + videoMetaData.getFormat());
               System.out.println("Codec: " + videoMetaData.getCodec());
               System.out.println("Duration: " + videoMetaData.getDurationMillis());
               System.out.println("FrameRate: " + videoMetaData.getFrameRate());
   
   
               //Show labels, confidence and detection times
               List<LabelDetection> detectedLabels= labelDetectionResult.getLabels();
   
               for (LabelDetection detectedLabel: detectedLabels) {
                   long seconds=detectedLabel.getTimestamp();
                   Label label=detectedLabel.getLabel();
                   System.out.println("Millisecond: " + Long.toString(seconds) + " ");
                   
                   System.out.println("   Label:" + label.getName()); 
                   System.out.println("   Confidence:" + detectedLabel.getLabel().getConfidence().toString());
         
                   List<Instance> instances = label.getInstances();
                   System.out.println("   Instances of " + label.getName());
                   if (instances.isEmpty()) {
                       System.out.println("        " + "None");
                   } else {
                       for (Instance instance : instances) {
                           System.out.println("        Confidence: " + instance.getConfidence().toString());
                           System.out.println("        Bounding box: " + instance.getBoundingBox().toString());
                       }
                   }
                   System.out.println("   Parent labels for " + label.getName() + ":");
                   List<Parent> parents = label.getParents();
                   if (parents.isEmpty()) {
                       System.out.println("        None");
                   } else {
                       for (Parent parent : parents) {
                           System.out.println("        " + parent.getName());
                       }
                   }
                   System.out.println();
               }
           } while (labelDetectionResult !=null && labelDetectionResult.getNextToken() != null);
   
       } 
   
       // Creates an SNS topic and SQS queue. The queue is subscribed to the topic. 
       static void CreateTopicandQueue()
       {
           //create a new SNS topic
           snsTopicName="AmazonRekognitionTopic" + Long.toString(System.currentTimeMillis());
           CreateTopicRequest createTopicRequest = new CreateTopicRequest(snsTopicName);
           CreateTopicResult createTopicResult = sns.createTopic(createTopicRequest);
           snsTopicArn=createTopicResult.getTopicArn();
           
           //Create a new SQS Queue
           sqsQueueName="AmazonRekognitionQueue" + Long.toString(System.currentTimeMillis());
           final CreateQueueRequest createQueueRequest = new CreateQueueRequest(sqsQueueName);
           sqsQueueUrl = sqs.createQueue(createQueueRequest).getQueueUrl();
           sqsQueueArn = sqs.getQueueAttributes(sqsQueueUrl, Arrays.asList("QueueArn")).getAttributes().get("QueueArn");
           
           //Subscribe SQS queue to SNS topic
           String sqsSubscriptionArn = sns.subscribe(snsTopicArn, "sqs", sqsQueueArn).getSubscriptionArn();
           
           // Authorize queue
             Policy policy = new Policy().withStatements(
                     new Statement(Effect.Allow)
                     .withPrincipals(Principal.AllUsers)
                     .withActions(SQSActions.SendMessage)
                     .withResources(new Resource(sqsQueueArn))
                     .withConditions(new Condition().withType("ArnEquals").withConditionKey("aws:SourceArn").withValues(snsTopicArn))
                     );
                     
   
             Map queueAttributes = new HashMap();
             queueAttributes.put(QueueAttributeName.Policy.toString(), policy.toJson());
             sqs.setQueueAttributes(new SetQueueAttributesRequest(sqsQueueUrl, queueAttributes)); 
           
   
            System.out.println("Topic arn: " + snsTopicArn);
            System.out.println("Queue arn: " + sqsQueueArn);
            System.out.println("Queue url: " + sqsQueueUrl);
            System.out.println("Queue sub arn: " + sqsSubscriptionArn );
        }
       static void DeleteTopicandQueue()
       {
           if (sqs !=null) {
               sqs.deleteQueue(sqsQueueUrl);
               System.out.println("SQS queue deleted");
           }
           
           if (sns!=null) {
               sns.deleteTopic(snsTopicArn);
               System.out.println("SNS topic deleted");
           }
       }
   }
   ```

------
#### [ Python ]

   在函数 `main` 中：
   + 将 `roleArn` 替换为您在[配置 Amazon Rekognition Video](api-video-roles.md#configure-rekvid-procedure)的步骤 7 中创建的 IAM 服务角色的 ARN。
   + 将 `amzn-s3-demo-bucket` 和 `video` 的值替换为您在步骤 2 中指定的存储桶和视频文件名。
   + 将创建 Rekognition 会话的行中的`profile_name`值替换为您的开发人员资料的名称。
   + 您还可以在设置参数中包含过滤条件。例如，可以在所需值列表旁边使用 `LabelsInclusionFilter` 或 `LabelsExclusionFilter`。在下面的代码中，您可以取消对`Features`和`Settings`部分的注释，并提供自己的值，将返回的结果限制在您感兴趣的标签上。
   + 在对 `GetLabelDetection` 的调用中，您可以为 `SortBy` 和 `AggregateBy` 参数提供值。要按时间排序，请将 `SortBy` 输入参数的值设置为 `TIMESTAMP`。要按实体排序，请将 `SortBy` 输入参数与适用于您执行的操作的值结合使用。要按时间戳汇总结果，请将 `AggregateBy` 参数的值设置为 `TIMESTAMPS`。要按视频片段进行汇总，请使用`SEGMENTS`。

   在代码示例中，将以下 IAM 策略放置到行 `policy = """""".format(sqsQueueArn, self.snsTopicArn)` 的引号内。

   ```
   ## Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-developer-guide/blob/master/LICENSE-SAMPLECODE.)
   
   import boto3
   import json
   import sys
   import time
   
   class VideoDetect:
   
       jobId = ''
   
       roleArn = ''
       bucket = ''
       video = ''
       startJobId = ''
   
       sqsQueueUrl = ''
       snsTopicArn = ''
       processType = ''
   
       def __init__(self, role, bucket, video, client, rek, sqs, sns):
           self.roleArn = role
           self.bucket = bucket
           self.video = video
           self.client = client
           self.rek = rek
           self.sqs = sqs
           self.sns = sns
   
       def GetSQSMessageSuccess(self):
   
           jobFound = False
           succeeded = False
   
           dotLine = 0
           while jobFound == False:
               sqsResponse = self.sqs.receive_message(QueueUrl=self.sqsQueueUrl, MessageAttributeNames=['ALL'],
                                                      MaxNumberOfMessages=10)
   
               if sqsResponse:
   
                   if 'Messages' not in sqsResponse:
                       if dotLine < 40:
                           print('.', end='')
                           dotLine = dotLine + 1
                       else:
                           print()
                           dotLine = 0
                       sys.stdout.flush()
                       time.sleep(5)
                       continue
   
                   for message in sqsResponse['Messages']:
                       notification = json.loads(message['Body'])
                       rekMessage = json.loads(notification['Message'])
                       print(rekMessage['JobId'])
                       print(rekMessage['Status'])
                       if rekMessage['JobId'] == self.startJobId:
                           print('Matching Job Found:' + rekMessage['JobId'])
                           jobFound = True
                           if (rekMessage['Status'] == 'SUCCEEDED'):
                               succeeded = True
   
                           self.sqs.delete_message(QueueUrl=self.sqsQueueUrl,
                                                   ReceiptHandle=message['ReceiptHandle'])
                       else:
                           print("Job didn't match:" +
                                 str(rekMessage['JobId']) + ' : ' + self.startJobId)
                       # Delete the unknown message. Consider sending to dead letter queue
                       self.sqs.delete_message(QueueUrl=self.sqsQueueUrl,
                                               ReceiptHandle=message['ReceiptHandle'])
   
           return succeeded
   
       def StartLabelDetection(self):
           response = self.rek.start_label_detection(Video={'S3Object': {'Bucket': self.bucket, 'Name': self.video}},
                                                     NotificationChannel={'RoleArn': self.roleArn,
                                                                          'SNSTopicArn': self.snsTopicArn},
                                                     MinConfidence=90,
                                                     # Filtration options, uncomment and add desired labels to filter returned labels
                                                     # Features=['GENERAL_LABELS'],
                                                     # Settings={
                                                     # 'GeneralLabels': {
                                                     # 'LabelInclusionFilters': ['Clothing']
                                                     # }}
                                                      )
   
           self.startJobId = response['JobId']
           print('Start Job Id: ' + self.startJobId)
   
       def GetLabelDetectionResults(self):
           maxResults = 10
           paginationToken = ''
           finished = False
   
           while finished == False:
               response = self.rek.get_label_detection(JobId=self.startJobId,
                                                       MaxResults=maxResults,
                                                       NextToken=paginationToken,
                                                       SortBy='TIMESTAMP',
                                                       AggregateBy="TIMESTAMPS")
   
               print('Codec: ' + response['VideoMetadata']['Codec'])
               print('Duration: ' + str(response['VideoMetadata']['DurationMillis']))
               print('Format: ' + response['VideoMetadata']['Format'])
               print('Frame rate: ' + str(response['VideoMetadata']['FrameRate']))
               print()
   
               for labelDetection in response['Labels']:
                   label = labelDetection['Label']
   
                   print("Timestamp: " + str(labelDetection['Timestamp']))
                   print("   Label: " + label['Name'])
                   print("   Confidence: " + str(label['Confidence']))
                   print("   Instances:")
                   for instance in label['Instances']:
                       print("      Confidence: " + str(instance['Confidence']))
                       print("      Bounding box")
                       print("        Top: " + str(instance['BoundingBox']['Top']))
                       print("        Left: " + str(instance['BoundingBox']['Left']))
                       print("        Width: " + str(instance['BoundingBox']['Width']))
                       print("        Height: " + str(instance['BoundingBox']['Height']))
                       print()
                   print()
   
                   print("Parents:")
                   for parent in label['Parents']:
                       print("   " + parent['Name'])
   
                   print("Aliases:")
                   for alias in label['Aliases']:
                       print("   " + alias['Name'])
   
                   print("Categories:")
                   for category in label['Categories']:
                       print("   " + category['Name'])
                   print("----------")
                   print()
   
                   if 'NextToken' in response:
                       paginationToken = response['NextToken']
                   else:
                       finished = True
   
       def CreateTopicandQueue(self):
   
           millis = str(int(round(time.time() * 1000)))
   
           # Create SNS topic
   
           snsTopicName = "AmazonRekognitionExample" + millis
   
           topicResponse = self.sns.create_topic(Name=snsTopicName)
           self.snsTopicArn = topicResponse['TopicArn']
   
           # create SQS queue
           sqsQueueName = "AmazonRekognitionQueue" + millis
           self.sqs.create_queue(QueueName=sqsQueueName)
           self.sqsQueueUrl = self.sqs.get_queue_url(QueueName=sqsQueueName)['QueueUrl']
   
           attribs = self.sqs.get_queue_attributes(QueueUrl=self.sqsQueueUrl,
                                                   AttributeNames=['QueueArn'])['Attributes']
   
           sqsQueueArn = attribs['QueueArn']
   
           # Subscribe SQS queue to SNS topic
           self.sns.subscribe(
               TopicArn=self.snsTopicArn,
               Protocol='sqs',
               Endpoint=sqsQueueArn)
   
           # Authorize SNS to write SQS queue 
           # Insert the policy from the documentation from 
           policy = """
           {{
              "Version":"2012-10-17",              
              "Statement":[
               {{
                   "Sid":"MyPolicy",
                   "Effect":"Allow",
                   "Principal" : {{"AWS" : "*"}},
                   "Action":"SQS:SendMessage",
                   "Resource": "{}",
                   "Condition":{{
                       "ArnEquals":{{
                           "aws:SourceArn": "{}"
                        }}
                   }}
               }}
               ]
           }}""".format(sqsQueueArn, self.snsTopicArn)
   
           response = self.sqs.set_queue_attributes(
               QueueUrl=self.sqsQueueUrl,
               Attributes={
                   'Policy': policy
               })
   
       def DeleteTopicandQueue(self):
           self.sqs.delete_queue(QueueUrl=self.sqsQueueUrl)
           self.sns.delete_topic(TopicArn=self.snsTopicArn)
   
   def main():
       
       roleArn = 'role-arn'
       bucket = 'bucket-name'
       video = 'video-name'
   
       session = boto3.Session(profile_name='profile-name')
       client = session.client('rekognition')
       rek = boto3.client('rekognition')
       sqs = boto3.client('sqs')
       sns = boto3.client('sns')
   
       analyzer = VideoDetect(roleArn, bucket, video, client, rek, sqs, sns)
       analyzer.CreateTopicandQueue()
   
       analyzer.StartLabelDetection()
       if analyzer.GetSQSMessageSuccess() == True:
           analyzer.GetLabelDetectionResults()
   
       analyzer.DeleteTopicandQueue()
   
   if __name__ == "__main__":
       main()
   ```

------
#### [ Node.Js ]

   请看下面的示例代码：
   + 将`REGION`的值替换为您账户的运营区域名称。
   + 将`amzn-s3-demo-bucket`的值替换为包含您的视频文件的 Amazon S3 存储桶的名称。
   + 使用您 Amazon S3 存储桶的视频文件名称替换 `videoName` 的值。
   +  将创建 Rekognition 会话的行中的`profile_name`值替换为您的开发人员资料的名称。
   + 将 `roleArn` 替换为您在[配置 Amazon Rekognition Video](api-video-roles.md#configure-rekvid-procedure)的步骤 7 中创建的 IAM 服务角色的 ARN。

   ```
   import { CreateQueueCommand, GetQueueAttributesCommand, GetQueueUrlCommand, 
     SetQueueAttributesCommand, DeleteQueueCommand, ReceiveMessageCommand, DeleteMessageCommand } from  "@aws-sdk/client-sqs";
   import {CreateTopicCommand, SubscribeCommand, DeleteTopicCommand } from "@aws-sdk/client-sns";
   import  { SQSClient } from "@aws-sdk/client-sqs";
   import  { SNSClient } from "@aws-sdk/client-sns";
   import  { RekognitionClient, StartLabelDetectionCommand, GetLabelDetectionCommand } from "@aws-sdk/client-rekognition";
   import { stdout } from "process";
   import {fromIni} from '@aws-sdk/credential-providers';
   
   // Set the AWS Region.
   const REGION = "region-name"; //e.g. "us-east-1"
   const profileName = "profile-name"
   // Create SNS service object.
   const sqsClient = new SQSClient({ region: REGION, 
     credentials: fromIni({profile: profileName,}), });
   const snsClient = new SNSClient({ region: REGION, 
     credentials: fromIni({profile: profileName,}), });
   const rekClient = new RekognitionClient({region: REGION, 
     credentials: fromIni({profile: profileName,}), 
   });
   
   // Set bucket and video variables
   const bucket = "bucket-name";
   const videoName = "video-name";
   const roleArn = "role-arn"
   var startJobId = ""
   
   var ts = Date.now();
   const snsTopicName = "AmazonRekognitionExample" + ts;
   const snsTopicParams = {Name: snsTopicName}
   const sqsQueueName = "AmazonRekognitionQueue-" + ts;
   
   // Set the parameters
   const sqsParams = {
     QueueName: sqsQueueName, //SQS_QUEUE_URL
     Attributes: {
       DelaySeconds: "60", // Number of seconds delay.
       MessageRetentionPeriod: "86400", // Number of seconds delay.
     },
   };
   
   const createTopicandQueue = async () => {
     try {
       // Create SNS topic
       const topicResponse = await snsClient.send(new CreateTopicCommand(snsTopicParams));
       const topicArn = topicResponse.TopicArn
       console.log("Success", topicResponse);
       // Create SQS Queue
       const sqsResponse = await sqsClient.send(new CreateQueueCommand(sqsParams));
       console.log("Success", sqsResponse);
       const sqsQueueCommand = await sqsClient.send(new GetQueueUrlCommand({QueueName: sqsQueueName}))
       const sqsQueueUrl = sqsQueueCommand.QueueUrl
       const attribsResponse = await sqsClient.send(new GetQueueAttributesCommand({QueueUrl: sqsQueueUrl, AttributeNames: ['QueueArn']}))
       const attribs = attribsResponse.Attributes
       console.log(attribs)
       const queueArn = attribs.QueueArn
       // subscribe SQS queue to SNS topic
       const subscribed = await snsClient.send(new SubscribeCommand({TopicArn: topicArn, Protocol:'sqs', Endpoint: queueArn}))
       const policy = {
         Version: "2012-10-17",&TCX5-2025-waiver;                
         Statement: [
           {
             Sid: "MyPolicy",
             Effect: "Allow",
             Principal: {AWS: "*"},
             Action: "SQS:SendMessage",
             Resource: queueArn,
             Condition: {
               ArnEquals: {
                 'aws:SourceArn': topicArn
               }
             }
           }
         ]
       };
   
       const response = sqsClient.send(new SetQueueAttributesCommand({QueueUrl: sqsQueueUrl, Attributes: {Policy: JSON.stringify(policy)}}))
       console.log(response)
       console.log(sqsQueueUrl, topicArn)
       return [sqsQueueUrl, topicArn]
   
     } catch (err) {
       console.log("Error", err);
     }
   };
   
   const startLabelDetection = async (roleArn, snsTopicArn) => {
     try {
       //Initiate label detection and update value of startJobId with returned Job ID
      const labelDetectionResponse = await rekClient.send(new StartLabelDetectionCommand({Video:{S3Object:{Bucket:bucket, Name:videoName}}, 
         NotificationChannel:{RoleArn: roleArn, SNSTopicArn: snsTopicArn}}));
         startJobId = labelDetectionResponse.JobId
         console.log(`JobID: ${startJobId}`)
         return startJobId
     } catch (err) {
       console.log("Error", err);
     }
   };
   
   const getLabelDetectionResults = async(startJobId) => {
     console.log("Retrieving Label Detection results")
     // Set max results, paginationToken and finished will be updated depending on response values
     var maxResults = 10
     var paginationToken = ''
     var finished = false
   
     // Begin retrieving label detection results
     while (finished == false){
       var response = await rekClient.send(new GetLabelDetectionCommand({JobId: startJobId, MaxResults: maxResults, 
         NextToken: paginationToken, SortBy:'TIMESTAMP'}))
         // Log metadata
         console.log(`Codec: ${response.VideoMetadata.Codec}`)
         console.log(`Duration: ${response.VideoMetadata.DurationMillis}`)
         console.log(`Format: ${response.VideoMetadata.Format}`)
         console.log(`Frame Rate: ${response.VideoMetadata.FrameRate}`)
         console.log()
         // For every detected label, log label, confidence, bounding box, and timestamp
         response.Labels.forEach(labelDetection => {
           var label = labelDetection.Label
           console.log(`Timestamp: ${labelDetection.Timestamp}`)
           console.log(`Label: ${label.Name}`)
           console.log(`Confidence: ${label.Confidence}`)
           console.log("Instances:")
           label.Instances.forEach(instance =>{
             console.log(`Confidence: ${instance.Confidence}`)
             console.log("Bounding Box:")
             console.log(`Top: ${instance.Confidence}`)
             console.log(`Left: ${instance.Confidence}`)
             console.log(`Width: ${instance.Confidence}`)
             console.log(`Height: ${instance.Confidence}`)
             console.log()
           })
         console.log()
         // Log parent if found
         console.log("   Parents:")
         label.Parents.forEach(parent =>{
           console.log(`    ${parent.Name}`)
         })
         console.log()
         // Searh for pagination token, if found, set variable to next token
         if (String(response).includes("NextToken")){
           paginationToken = response.NextToken
   
         }else{
           finished = true
         }
   
         })
     }
   }
   
   // Checks for status of job completion
   const getSQSMessageSuccess = async(sqsQueueUrl, startJobId) => {
     try {
       // Set job found and success status to false initially
       var jobFound = false
       var succeeded = false
       var dotLine = 0
       // while not found, continue to poll for response
       while (jobFound == false){
         var sqsReceivedResponse = await sqsClient.send(new ReceiveMessageCommand({QueueUrl:sqsQueueUrl, 
           MaxNumberOfMessages:'ALL', MaxNumberOfMessages:10}));
         if (sqsReceivedResponse){
           var responseString = JSON.stringify(sqsReceivedResponse)
           if (!responseString.includes('Body')){
             if (dotLine < 40) {
               console.log('.')
               dotLine = dotLine + 1
             }else {
               console.log('')
               dotLine = 0 
             };
             stdout.write('', () => {
               console.log('');
             });
             await new Promise(resolve => setTimeout(resolve, 5000));
             continue
           }
         }
   
         // Once job found, log Job ID and return true if status is succeeded
         for (var message of sqsReceivedResponse.Messages){
           console.log("Retrieved messages:")
           var notification = JSON.parse(message.Body)
           var rekMessage = JSON.parse(notification.Message)
           var messageJobId = rekMessage.JobId
           if (String(rekMessage.JobId).includes(String(startJobId))){
             console.log('Matching job found:')
             console.log(rekMessage.JobId)
             jobFound = true
             console.log(rekMessage.Status)
             if (String(rekMessage.Status).includes(String("SUCCEEDED"))){
               succeeded = true
               console.log("Job processing succeeded.")
               var sqsDeleteMessage = await sqsClient.send(new DeleteMessageCommand({QueueUrl:sqsQueueUrl, ReceiptHandle:message.ReceiptHandle}));
             }
           }else{
             console.log("Provided Job ID did not match returned ID.")
             var sqsDeleteMessage = await sqsClient.send(new DeleteMessageCommand({QueueUrl:sqsQueueUrl, ReceiptHandle:message.ReceiptHandle}));
           }
         }
       }
     return succeeded
     } catch(err) {
       console.log("Error", err);
     }
   };
   
   // Start label detection job, sent status notification, check for success status
   // Retrieve results if status is "SUCEEDED", delete notification queue and topic
   const runLabelDetectionAndGetResults = async () => {
     try {
       const sqsAndTopic = await createTopicandQueue();
       const startLabelDetectionRes = await startLabelDetection(roleArn, sqsAndTopic[1]);
       const getSQSMessageStatus = await getSQSMessageSuccess(sqsAndTopic[0], startLabelDetectionRes)
       console.log(getSQSMessageSuccess)
       if (getSQSMessageSuccess){
         console.log("Retrieving results:")
         const results = await getLabelDetectionResults(startLabelDetectionRes)
       }
       const deleteQueue = await sqsClient.send(new DeleteQueueCommand({QueueUrl: sqsAndTopic[0]}));
       const deleteTopic = await snsClient.send(new DeleteTopicCommand({TopicArn: sqsAndTopic[1]}));
       console.log("Successfully deleted.")
     } catch (err) {
       console.log("Error", err);
     }
   };
   
   runLabelDetectionAndGetResults()
   ```

------
#### [ Java V2 ]

   此代码取自 AWS 文档 SDK 示例 GitHub 存储库。请在[此处](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/javav2/example_code/rekognition/src/main/java/com/example/rekognition/VideoDetect.java)查看完整示例。

   ```
   import com.fasterxml.jackson.core.JsonProcessingException;
   import com.fasterxml.jackson.databind.JsonMappingException;
   import com.fasterxml.jackson.databind.JsonNode;
   import com.fasterxml.jackson.databind.ObjectMapper;
   import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
   import software.amazon.awssdk.regions.Region;
   import software.amazon.awssdk.services.rekognition.RekognitionClient;
   import software.amazon.awssdk.services.rekognition.model.StartLabelDetectionResponse;
   import software.amazon.awssdk.services.rekognition.model.NotificationChannel;
   import software.amazon.awssdk.services.rekognition.model.S3Object;
   import software.amazon.awssdk.services.rekognition.model.Video;
   import software.amazon.awssdk.services.rekognition.model.StartLabelDetectionRequest;
   import software.amazon.awssdk.services.rekognition.model.GetLabelDetectionRequest;
   import software.amazon.awssdk.services.rekognition.model.GetLabelDetectionResponse;
   import software.amazon.awssdk.services.rekognition.model.RekognitionException;
   import software.amazon.awssdk.services.rekognition.model.LabelDetectionSortBy;
   import software.amazon.awssdk.services.rekognition.model.VideoMetadata;
   import software.amazon.awssdk.services.rekognition.model.LabelDetection;
   import software.amazon.awssdk.services.rekognition.model.Label;
   import software.amazon.awssdk.services.rekognition.model.Instance;
   import software.amazon.awssdk.services.rekognition.model.Parent;
   import software.amazon.awssdk.services.sqs.SqsClient;
   import software.amazon.awssdk.services.sqs.model.Message;
   import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
   import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest;
   import java.util.List;
   //snippet-end:[rekognition.java2.recognize_video_detect.import]
   
   /**
   * Before running this Java V2 code example, set up your development environment, including your credentials.
   *
   * For more information, see the following documentation topic:
   *
   * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
   */
   public class VideoDetect {
   
    private static String startJobId ="";
    public static void main(String[] args) {
   
        final String usage = "\n" +
            "Usage: " +
            "   <bucket> <video> <queueUrl> <topicArn> <roleArn>\n\n" +
            "Where:\n" +
            "   bucket - The name of the bucket in which the video is located (for example, (for example, amzn-s3-demo-bucket). \n\n"+
            "   video - The name of the video (for example, people.mp4). \n\n" +
            "   queueUrl- The URL of a SQS queue. \n\n" +
            "   topicArn - The ARN of the Amazon Simple Notification Service (Amazon SNS) topic. \n\n" +
            "   roleArn - The ARN of the AWS Identity and Access Management (IAM) role to use. \n\n" ;
   
        if (args.length != 5) {
            System.out.println(usage);
            System.exit(1);
        }
   
        String bucket = args[0];
        String video = args[1];
        String queueUrl = args[2];
        String topicArn = args[3];
        String roleArn = args[4];
        Region region = Region.US_WEST_2;
        RekognitionClient rekClient = RekognitionClient.builder()
            .region(region)
            .credentialsProvider(ProfileCredentialsProvider.create("profile-name"))
            .build();
   
        SqsClient sqs = SqsClient.builder()
            .region(Region.US_WEST_2)
            .credentialsProvider(ProfileCredentialsProvider.create("profile-name"))
            .build();
   
        NotificationChannel channel = NotificationChannel.builder()
            .snsTopicArn(topicArn)
            .roleArn(roleArn)
            .build();
   
        startLabels(rekClient, channel, bucket, video);
        getLabelJob(rekClient, sqs,  queueUrl);
        System.out.println("This example is done!");
        sqs.close();
        rekClient.close();
    }
   
    // snippet-start:[rekognition.java2.recognize_video_detect.main]
    public static void startLabels(RekognitionClient rekClient,
                                   NotificationChannel channel,
                                   String bucket,
                                   String video) {
        try {
            S3Object s3Obj = S3Object.builder()
                .bucket(bucket)
                .name(video)
                .build();
   
            Video vidOb = Video.builder()
                .s3Object(s3Obj)
                .build();
   
            StartLabelDetectionRequest labelDetectionRequest = StartLabelDetectionRequest.builder()
                .jobTag("DetectingLabels")
                .notificationChannel(channel)
                .video(vidOb)
                .minConfidence(50F)
                .build();
   
            StartLabelDetectionResponse labelDetectionResponse = rekClient.startLabelDetection(labelDetectionRequest);
            startJobId = labelDetectionResponse.jobId();
   
            boolean ans = true;
            String status = "";
            int yy = 0;
            while (ans) {
   
                GetLabelDetectionRequest detectionRequest = GetLabelDetectionRequest.builder()
                    .jobId(startJobId)
                    .maxResults(10)
                    .build();
   
                GetLabelDetectionResponse result = rekClient.getLabelDetection(detectionRequest);
                status = result.jobStatusAsString();
   
                if (status.compareTo("SUCCEEDED") == 0)
                    ans = false;
                else
                    System.out.println(yy +" status is: "+status);
   
                Thread.sleep(1000);
                yy++;
            }
   
            System.out.println(startJobId +" status is: "+status);
   
        } catch(RekognitionException | InterruptedException e) {
            e.getMessage();
            System.exit(1);
        }
    }
   
    public static void getLabelJob(RekognitionClient rekClient, SqsClient sqs, String queueUrl) {
   
        List<Message> messages;
        ReceiveMessageRequest messageRequest = ReceiveMessageRequest.builder()
            .queueUrl(queueUrl)
            .build();
   
        try {
            messages = sqs.receiveMessage(messageRequest).messages();
   
            if (!messages.isEmpty()) {
                for (Message message: messages) {
                    String notification = message.body();
   
                    // Get the status and job id from the notification
                    ObjectMapper mapper = new ObjectMapper();
                    JsonNode jsonMessageTree = mapper.readTree(notification);
                    JsonNode messageBodyText = jsonMessageTree.get("Message");
                    ObjectMapper operationResultMapper = new ObjectMapper();
                    JsonNode jsonResultTree = operationResultMapper.readTree(messageBodyText.textValue());
                    JsonNode operationJobId = jsonResultTree.get("JobId");
                    JsonNode operationStatus = jsonResultTree.get("Status");
                    System.out.println("Job found in JSON is " + operationJobId);
   
                    DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder()
                        .queueUrl(queueUrl)
                        .build();
   
                    String jobId = operationJobId.textValue();
                    if (startJobId.compareTo(jobId)==0) {
                        System.out.println("Job id: " + operationJobId );
                        System.out.println("Status : " + operationStatus.toString());
   
                        if (operationStatus.asText().equals("SUCCEEDED"))
                            GetResultsLabels(rekClient);
                        else
                            System.out.println("Video analysis failed");
   
                        sqs.deleteMessage(deleteMessageRequest);
                    }
   
                    else{
                        System.out.println("Job received was not job " +  startJobId);
                        sqs.deleteMessage(deleteMessageRequest);
                    }
                }
            }
   
        } catch(RekognitionException e) {
            e.getMessage();
            System.exit(1);
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
   
    // Gets the job results by calling GetLabelDetection
    private static void GetResultsLabels(RekognitionClient rekClient) {
   
        int maxResults=10;
        String paginationToken=null;
        GetLabelDetectionResponse labelDetectionResult=null;
   
        try {
            do {
                if (labelDetectionResult !=null)
                    paginationToken = labelDetectionResult.nextToken();
   
   
                GetLabelDetectionRequest labelDetectionRequest= GetLabelDetectionRequest.builder()
                    .jobId(startJobId)
                    .sortBy(LabelDetectionSortBy.TIMESTAMP)
                    .maxResults(maxResults)
                    .nextToken(paginationToken)
                    .build();
   
                labelDetectionResult = rekClient.getLabelDetection(labelDetectionRequest);
                VideoMetadata videoMetaData=labelDetectionResult.videoMetadata();
                System.out.println("Format: " + videoMetaData.format());
                System.out.println("Codec: " + videoMetaData.codec());
                System.out.println("Duration: " + videoMetaData.durationMillis());
                System.out.println("FrameRate: " + videoMetaData.frameRate());
   
                List<LabelDetection> detectedLabels= labelDetectionResult.labels();
                for (LabelDetection detectedLabel: detectedLabels) {
                    long seconds=detectedLabel.timestamp();
                    Label label=detectedLabel.label();
                    System.out.println("Millisecond: " + seconds + " ");
   
                    System.out.println("   Label:" + label.name());
                    System.out.println("   Confidence:" + detectedLabel.label().confidence().toString());
   
                    List<Instance> instances = label.instances();
                    System.out.println("   Instances of " + label.name());
   
                    if (instances.isEmpty()) {
                        System.out.println("        " + "None");
                    } else {
                        for (Instance instance : instances) {
                            System.out.println("        Confidence: " + instance.confidence().toString());
                            System.out.println("        Bounding box: " + instance.boundingBox().toString());
                        }
                    }
                    System.out.println("   Parent labels for " + label.name() + ":");
                    List<Parent> parents = label.parents();
   
                    if (parents.isEmpty()) {
                        System.out.println("        None");
                    } else {
                        for (Parent parent : parents) {
                            System.out.println("   " + parent.name());
                        }
                    }
                    System.out.println();
                }
            } while (labelDetectionResult !=null && labelDetectionResult.nextToken() != null);
   
        } catch(RekognitionException e) {
            e.getMessage();
            System.exit(1);
        }
    }
    // snippet-end:[rekognition.java2.recognize_video_detect.main]
   }
   ```

------

1. 构建并运行代码。此操作可能需要一段时间才能完成。完成后，将显示在视频中检测到的标签的列表。有关更多信息，请参阅 [检测视频中的标签](labels-detecting-labels-video.md)。

# 使用分析视频 AWS Command Line Interface
<a name="video-cli-commands"></a>

你可以使用 AWS Command Line Interface (AWS CLI) 调用 Amazon Rekognition Video 操作。设计模式与在或其他 AWS 上使用亚马逊 Rekognition Video API 相同。 适用于 Java 的 AWS SDK SDKs有关更多信息，请参阅 [Amazon Rekognition Video API 概述](video.md#video-api-overview)。以下过程说明如何使用 AWS CLI 来检测视频中的标签。

您可通过调用 `start-label-detection` 开始检测视频中的标签。当 Amazon Rekognition 分析完视频后，完成状态将发送到在 `start-label-detection` 的 `--notification-channel` 参数中指定的 Amazon SNS 主题。您可通过为 Amazon Simple Queue Service (Amazon SQS) 队列订阅 Amazon SNS 主题来获取完成状态。然后轮询 [receive-message](https://docs.aws.amazon.com/cli/latest/reference/sqs/receive-message.html) 以从 Amazon SQS 队列获取完成状态。

调用 `StartLabelDetection` 时，您可以通过向 `LabelsInclusionFilter` 和/或 `LabelsExclusionFilter` 参数提供过滤参数来筛选结果。有关更多信息，请参阅 [检测视频中的标签](labels-detecting-labels-video.md)。

完成状态通知是 `receive-message` 响应内的 JSON 结构。您需要从响应中提取 JSON。有关完成状态 JSON 的信息，请参阅[参考：视频分析结果通知](video-notification-payload.md)。如果已完成状态 JSON 的 `Status` 字段的值为 `SUCCEEDED`，您可通过调用 `get-label-detection` 来获取视频分析请求的结果。调用 `GetLabelDetection` 时，您可以使用 `SortBy` 和 `AggregateBy` 参数对返回的结果进行排序和汇总。

以下过程不包含用于轮询 Amazon SQS 队列的代码。此外，它们也不包含用于分析从 Amazon SQS 队列返回的 JSON 的代码。有关 Java 示例，请参阅[使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)](video-analyzing-with-sqs.md)。

## 先决条件
<a name="video-prerequisites"></a>

要运行此过程，你需要 AWS CLI 安装。有关更多信息，请参阅 [Amazon Rekognition 入门](getting-started.md)。您使用的 AWS 账户必须具有对 Amazon Rekognition API 的访问权限。有关更多信息，请参阅 [Amazon Rekognition 定义的操作](https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonrekognition.html#amazonrekognition-actions-as-permissions)。

**配置 Amazon Rekognition Video 并上传视频**

1. 配置用户对 Amazon Rekognition Video 的访问权限并配置 Amazon Rekognition Video 对 Amazon SNS 的访问权限。有关更多信息，请参阅 [配置 Amazon Rekognition Video](api-video-roles.md)。

1. 将 MOV 或 MPEG-4 格式的视频文件上传到您的 S3 存储桶。在开发和测试时，我们建议使用时长不超过 30 秒的小视频。

   有关说明，请参阅**《Amazon Simple Storage Service 用户指南》中的[将对象上传到 Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UploadingObjectsintoAmazonS3.html)。

**检测视频中的标签**

1. 运行以下 AWS CLI 命令开始检测视频中的标签。

   ```
   aws rekognition start-label-detection --video '{"S3Object":{"Bucket":"amzn-s3-demo-bucket","Name":"video-name"}}' \
    --notification-channel '{"SNSTopicArn":"TopicARN","RoleArn":"RoleARN"}' \
   --region region-name  \ 
   --features GENERAL_LABELS \
   --profile profile-name \
   --settings "{"GeneralLabels":{"LabelInclusionFilters":["Car"]}}
   ```

   更新以下值：
   + 将`amzn-s3-demo-bucket`和`videofile`更改为您在步骤 2 中指定的 Amazon S3 存储桶名称和文件名。
   + 将 `us-east-1` 更改为您使用的 AWS 区域。
   + 将创建 Rekognition 会话的行中的`profile_name`值替换为您的开发人员资料的名称。
   + 将 `TopicARN` 更改为您在 [配置 Amazon Rekognition Video](api-video-roles.md) 的步骤 3 中创建的 Amazon SNS 主题的 ARN。
   + 将 `RoleARN` 更改为您在 [配置 Amazon Rekognition Video](api-video-roles.md) 的步骤 7 中创建的 IAM 服务角色的 ARN。
   + 如果需要，您可以指定 `endpoint-url`。AWS CLI 应根据提供的区域自动确定正确的端点 URL。但是，如果您使用的是[私有 VPC 中的](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html#what-is-privatelink)端点，则可能需要指定`endpoint-url`。[AWS 服务端点](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints)资源列出了用于指定端点网址的语法以及每个区域的名称和代码。
   + 您还可以在设置参数中包含过滤条件。例如，可以在所需值列表旁边使用 `LabelsInclusionFilter` 或 `LabelsExclusionFilter`。

    如果您在 Windows 设备上访问 CLI，请使用双引号代替单引号，并用反斜杠（即 \$1）对内部双引号进行转义，以解决可能遇到的任何解析器错误。有关示例，请参阅以下内容：

   ```
   aws rekognition start-label-detection --video "{\"S3Object\":{\"Bucket\":\"amzn-s3-demo-bucket",\"Name\":\"video-name\"}}" --notification-channel "{\"SNSTopicArn\":\"TopicARN\",\"RoleArn\":\"RoleARN\"}" \
   --region us-east-1 --features GENERAL_LABELS --settings "{\"GeneralLabels\":{\"LabelInclusionFilters\":[\"Car\"]}}" --profile profile-name
   ```

1. 记下响应中 `JobId` 的值。该响应看上去与以下 JSON 示例类似。

   ```
   {
       "JobId": "547089ce5b9a8a0e7831afa655f42e5d7b5c838553f1a584bf350ennnnnnnnnn"
   }
   ```

1. 编写代码以轮询完成状态 JSON 的 Amazon SQS 队列（通过使用 [receive-message](https://docs.aws.amazon.com/cli/latest/reference/sqs/receive-message.html)）。

1. 编写代码以从完成状态 JSON 提取 `Status` 字段。

1. 如果的值`Status`为`SUCCEEDED`，则运行以下 AWS CLI 命令以显示标签检测结果。

   ```
   aws rekognition get-label-detection  --job-id JobId \
   --region us-east-1 --sort-by TIMESTAMP aggregate-by TIMESTAMPS
   ```

   更新以下值：
   + 将 `JobId` 更改得与您在步骤 2 中记下的任务标识符匹配。
   + 将 `Endpoint` 和 `us-east-1` 更改为您使用的 AWS 端点和区域。

   结果看上去与以下示例 JSON 类似：

   ```
   {
       "Labels": [
           {
               "Timestamp": 0,
               "Label": {
                   "Confidence": 99.03720092773438,
                   "Name": "Speech"
               }
           },
           {
               "Timestamp": 0,
               "Label": {
                   "Confidence": 71.6698989868164,
                   "Name": "Pumpkin"
               }
           },
           {
               "Timestamp": 0,
               "Label": {
                   "Confidence": 71.6698989868164,
                   "Name": "Squash"
               }
           },
           {
               "Timestamp": 0,
               "Label": {
                   "Confidence": 71.6698989868164,
                   "Name": "Vegetable"
               }
           }, .......
   ```

# 参考：视频分析结果通知
<a name="video-notification-payload"></a>

Amazon Rekognition 将Amazon Rekognition Video 分析请求的结果（包括完成状态）发布到 Amazon Simple Notification Service (Amazon SNS) 主题。要从 Amazon SNS 主题中获取通知，请使用亚马逊简单队列服务队列或函数。 AWS Lambda 有关更多信息，请参阅 [调用 Amazon Rekognition Video 操作](api-video.md)。有关示例，请参阅[使用 Java 或 Python 分析存储在 Amazon S3 存储桶中的视频 (SDK)](video-analyzing-with-sqs.md)。

负载采用以下 JSON 格式：

```
{
  "JobId": "String",
  "Status": "String",
  "API": "String",
  "JobTag": "String",
  "Timestamp": Number,
  "Video": {
    "S3ObjectName": "String",
    "S3Bucket": "String"
  }
}
```


| Name | 说明 | 
| --- | --- | 
|  JobId  |  任务标识符。匹配从 `Start` 操作返回的任务标识符，如 [StartPersonTracking](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartPersonTracking.html)。  | 
|  Status  |  任务的状态。有效值为 SUCCEEDED、FAILED 或 ERROR。  | 
|  API  |  用于分析输入视频的 Amazon Rekognition Video 操作。  | 
|  JobTag  |  任务的标识符。您在对 Start 操作的调用中指定 `JobTag`，如 [StartLabelDetection](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_StartLabelDetection.html)。  | 
|  Timestamp  |  任务完成的 Unix 时间戳。  | 
|  视频  |  有关已处理的视频的详细信息。包含文件名和将文件存储到的 Amazon S3 存储桶。  | 

以下是已发送到 Amazon SNS 主题的成功通知的示例。

```
{
  "JobId": "6de014b0-2121-4bf0-9e31-856a18719e22",
  "Status": "SUCCEEDED",
  "API": "LABEL_DETECTION",
  "Message": "",
  "Timestamp": 1502230160926,
  "Video": {
    "S3ObjectName": "video.mpg",
    "S3Bucket": "amzn-s3-demo-bucket"
  }
}
```

# Amazon Rekognition Video 故障排除
<a name="video-troubleshooting"></a>

以下内容介绍了有关使用 Amazon Rekognition Video 和所存储视频的问题排查信息。

## 我从未收到发送到 Amazon SNS 主题的完成状态
<a name="video-no-sns-topic"></a>

 在视频分析完成时，Amazon Rekognition Video 会将状态信息发布到 Amazon SNS 主题。通常，您通过订阅带 Amazon SQS 队列或 Lambda 函数的主题来获取完成状态消息。要帮助进行调查，请通过电子邮件订阅 Amazon SNS 主题，以便您的电子邮件收件箱接收发送到 Amazon SNS 主题的消息。有关更多信息，请参阅[订阅 Amazon SNS 主题](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html)。

如果您的应用程序未收到消息，请考虑：
+ 验证分析是否已完成。检查 Get 操作响应中的 `JobStatus` 值（例如 `GetLabelDetection`）。如果该值为 `IN_PROGRESS`，则表示分析未完成，并且尚未将完成状态发布到 Amazon SNS 主题。
+ 验证您是否有一个 IAM 服务角色向 Amazon Rekognition Video 授予发布到 Amazon SNS 主题的权限。有关更多信息，请参阅 [配置 Amazon Rekognition Video](api-video-roles.md)。
+ 确认您使用的 IAM 服务角色可以使用角色凭证发布到 Amazon SNS 主题，并且您的服务角色的权限已安全地扩展到您使用的资源。执行以下步骤：
  + 获取用户的 Amazon 资源名称 (ARN)：

    ```
    aws sts get-caller-identity --profile RekognitionUser 
    ```
  + 将用户 ARN 添加到角色信任关系中。有关更多信息，请参阅[修改角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_manage_modify.html)。以下示例信任策略指定了用户的角色凭证，并将服务角色的权限限制在您正在使用的资源范围内（有关安全限制服务角色权限范围的更多信息，请参阅[防止跨服务混淆代理](cross-service-confused-deputy-prevention.md)）：
  + 代入角色：`aws sts assume-role --role-arn arn:Role ARN --role-session-name SessionName --profile RekognitionUser`
  + 发布到 Amazon SNS 主题：`aws sns publish --topic-arn arn:Topic ARN --message "Hello World!" --region us-east-1 --profile RekognitionUser`

  如果 AWS CLI 命令起作用，则会收到消息（如果您通过电子邮件订阅了主题，则在电子邮件收件箱中）。如果您没有收到消息：
  + 检查您是否配置了 Amazon Rekognition Video。有关更多信息，请参阅 [配置 Amazon Rekognition Video](api-video-roles.md)。
  + 查看此排查问题的其他提示。
+ 检查您使用了正确的 Amazon SNS 主题：
  + 如果您使用 IAM 服务角色向 Amazon Rekognition Video 提供对单个 Amazon SNS 主题的访问权限，请确保已向您授予对正确的 Amazon SNS 主题的权限。有关更多信息，请参阅 [授予访问现有 Amazon SNS 主题的权限](api-video-roles.md#api-video-roles-single-topics)。
  + 如果您使用 IAM 服务角色向 Amazon Rekognition Video 授予对多个 SNS 主题的访问权限，请验证您使用的主题是否正确，并且主题名称前面是否带有。*AmazonRekognition*有关更多信息，请参阅 [提供对多个 Amazon SNS 主题的访问权限](api-video-roles.md#api-video-roles-all-topics)。
  + 如果您使用 AWS Lambda 函数，请确认您的 Lambda 函数已订阅正确的亚马逊 SNS 主题。有关更多信息，请参阅[扇出到 Lambda 函数](https://docs.aws.amazon.com/sns/latest/dg/sns-lambda.html)。
+ 如果您使用 Amazon SQS 队列订阅 Amazon SNS 主题，请确认 Amazon SNS 主题有权将消息发送到 Amazon SQS 队列。有关更多信息，请参阅[为向 Amazon SQS 队列发送消息的 Amazon SNS 主题授予权限](https://docs.aws.amazon.com/sns/latest/dg/subscribe-sqs-queue-to-sns-topic.html#SendMessageToSQS.sqs.permissions)。

## 我需要更多帮助来排除 Amazon SNS 主题的故障
<a name="video-troubleshoot-sns"></a>

您可以 AWS X-Ray 与 Amazon SNS 配合使用来跟踪和分析通过您的应用程序传输的消息。有关更多信息，请参阅 [Amazon SNS 和。 AWS X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-services-sns.html)

如需更多帮助，您可以将问题发布到 [Amazon Rekognition 论坛](https://forums.aws.amazon.com/forum.jspa?forumID=234) 或考虑注册获取 [AWS 技术支持](https://aws.amazon.com/premiumsupport/)。