{"value":"### **1. 前言**\n基于云端实时视频智能检测的功能,在居家安防监控领域有着较高的价值。这一场景的实现通常如下图所示分为如下几个阶段:视频流产生(Producer)、视频流存储(Storage)、视频流处理(Consumer)。\n\n![image.png](https://dev-media.amazoncloud.cn/04a9676e35d047a88ce39ea913b41e82_image.png)\n\n当前使用低成本的网络摄像头(硬件资源有限,不支持边缘推理计算)+云端存储推理实现家用及中小商户安防监控成为一个流行的方式。在实际的应用过程中往往需要根据AI场景的复杂性、多样性、成本的考量、技术难度差异选择适合当前现状的方案。例如基于成本优化的考虑,我们希望采用图片作为智能检测的数据输入,发送用户告警通知的媒体信息通常也是图片格式,因此通常需要从视频流中提取图片,但从视频流中抽取图片往往需要维护可扩展的计算资源来将视频转码为图片格式,这对没有的专业领域技术积累的团队来说是个不小的挑战。本文将详细介绍如何使用 Amazon 新推出的 Amazon Kinesis Video Streams Images 来简化云端抽图。\n#### **1.1 相关产品介绍**\n- **Amazon Kinesis Video Streams** 是一项完全托管的 Amazon 服务,您可以使用 Kinesis Video Streams 捕获来自数百万种源 (包括智能手机、安全摄像头、网络摄像头、车载摄像头、无人机及其他源) 的海量实时视频数据传输到 Amazon 云,或者构建应用程序以进行实时视频处理或进行面向批处理的视频。\n- **Amazon Kinesis Video Stream Images** 是 KVS 上一组完全托管的 API ,它提供了如下的功能特性:\n1. 以完全托管的方式从 KVS 视频流中抽取图片并保存到S3。\n2. 使用 KVS Consumer 侧提供的 GetImages API 按需从 KVS 视频流中抽取图片。\n3. 基于标签 KVS Producer 端的标签,自动触发 Amazon SNS 的通知。\n\n借助上述功能,您可以构建视频流检测的通知,基于视频流中的抽取的图片构建智能视频检测应用。\n\n- **Amazon Rekognition** 提供预先训练和可定制的计算机视觉 (CV) 功能,可从您的图像和视频中提取信息和获得洞察力。提供高精度的人脸分析检测、人脸比较和人脸搜索、标签文本检测等功能。Amazon Rekognition 基于同样由 Amazon 计算机视觉科学家开发的成熟且高度可扩展的深度学习技术,每天能够分析数十亿图像和视频。它不需要机器学习专业知识即可使用。Amazon Rekognition 包含一个简单易用的API,该API 可快速分析存储在 Amazon S3 中的任何图像或视频文件。\n### **2.Amazon Kinesis Video Stream Images 方案分析**\n#### **2.1 方案概述**\nKinesis Video Stream Images 方案整体架构分为:设备端、Amazon云端、用户应用端。\n\n- **设备端**\n\n为带有一定视频检测能力的摄像头设备、通过集成 KVS SDK 作为 KVS 的 Producer 向云端 KVS Stream 推送视频流,并基于摄像头设备的检测能力给 KVS MKV 数据打 Tag ,这些 Tag 的用途一是作为 KVS Image API 的触发标志,二是作为业务逻辑处理的依据。\n\n- **Amazon 云端**\n\n\t- Amazon Kinesis Video Stream :提供设备视频持久化存储、视频检索、视频在线查看、视频下载等能力,并向 Rekognition 提供用于视频检测的数据。\n\t- Amazon Rekognition:提供自动执行视频和图像分析的能力,包括基于视频或图像的内容审核、人脸检测、人脸比较、标签检测等完全托管的能力,并且可以方便的与 KVS、S3、SNS 等服务集成。\n\t- Amazon S3:提供视频检测结果的存储。\n\t- Amazon SNS:完全托管的发布/订阅消息收发、SMS、电子邮件和移动推送通知在本方案中提供通知发送的能力。\n\n该方案的整体架构图如下\n\n![image.png](https://dev-media.amazoncloud.cn/a9179242b28b4974a97f70d35837522b_image.png)\n#### **2.2方案说明**\n- 视频流 Producer(设备)\n\n设备端通常是带有一定检测能力的摄像头设备,集成 KVS Prouder SDK 。借助自身的视频检测能力给视频帧打标签,并使用 KVS prouder SDK 将视频流推送到云端。\n\n- 视频流 Processor(云端)\n\n云端视频流 Processor 通过 Amazon Service 提供如下处理能力:\n\n**视频云存**:KVS Video Streams 是 Amazon 在云端的视频流存储资源,它可以提供视频数据的持久化存储,并提供视频检测和回放的API以实现复杂的需求场景。\n\n**抽图**:通过 KVS 您可以使用 KVS GetMedia 或 GetImages API 从视频流中抽取图片、发送告警通知、智能视频检测处理。\n\n**通知告警**:采用 SNS 与 KVS images 无缝集成的方式,您只需调用 API 进行一些简单的配置就可以构建视频通知告警的方案。\n\n**智能视频检测**:云端的视频检测实现方式有三种:基于 Sagemaker、基于 Rekognition、基于 EC2 自建模型。\n\n- 视频流 Consumer(应用端):\n\n应用端通常是 APP,集成 KVS Consumer SDK 和消息推送服务,可以从 KVS 中按需回看视频或者查看存储在S3中的图片。\n### **3. 方案集成验证**\n#### **3.1 实验准备工作**\n##### **3.1.1 准备 Amazon 资源**\n- **准备 Amazon 账户并配置用户权限**\n\n1、本次实验需要用到的 Amazon 资源都在 Ireland Region 中创建,您需要提前准备好一个 Amazon account。\n2、在 Amazon IAM 中创建一个 Admin User,赋予arn:aws:iam::aws:policy/AdministratorAccess 策略,后续的资源创建都使用这个用户来操作。\n\n3、在 Amazon IAM 的 Admin User 创建一个 AKSK,并记录下来,后面的实验环境需要用到。创建 IAM User AKSK 的方法请参考如下的文档:[https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)\n\n- **创建 Cloud9 用于模拟 KVS Producer 和 Consumer**\n\n创建 Amazon Cloud9 的方法请参考如下的文档:\n\n[https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9](https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9)\n\n注意:由于默认创建的 Cloud9 的存储空间有限,建议在执行后面的操作之前先扩展 Cloud9 的空间,如何扩展 Cloud9 的存储空间请参照如下链接中的 Disk Space Expansion 章节。\n\n[https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9](https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9)\n\n- **在 Cloud9 中配置 profile **\n\n在 Cloud9 的终端中执行如下命令配置 profile\n```\n$ aws configure --profile your-profile-name\nAWS Access Key ID [None]:your AWS Access Key ID \nAWS Secret Access Key [None]:your AWS Secret Access Key\nDefault region name [None]: eu-west-1\nDefault output format [None]: json \n```\n- **创建 Amazon S3 Bucket 用于保存从 KVS 中抽取的图片**\n```\naws s3 mb s3://sample-bucket-name --region eu-west-1\n```\n- **创建 SNS 用于 KVS 将抽帧结果通知到相关服务**\n\n注意上面创建的 Cloud9、S3 Bucket 和 SNS 需要位于同一个 Amazon 的 Region 。如下图所示:\n\n![image.png](https://dev-media.amazoncloud.cn/d0c11017f7714b4794c1408a2b0c792c_image.png)\n- **创建云端的 Kinesis Video Stream **\n\n![image.png](https://dev-media.amazoncloud.cn/9fd22e3ffab14d2fb11196f3de49f27e_image.png)\n##### **3.1.2 模拟 KVS Producer 设备端环境准备**\n- **安装工程依赖**\n```\nsudo apt-get update\nsudo apt-get install -y cmake git gcc g++ autoconf\nsudo apt-get install -y libssl-dev libcurl4-openssl-dev liblog4cplus-dev pkg-config\n```\n- **样例工程编译**\n**1.下载工程代码**\n```\ngit clone --recursive https://github.com/awslabs/amazon-kinesis-video-streams-producer-c.git\n```\n**2.工程代码**\n```\nmkdir -p amazon-kinesis-video-streams-producer-c/build\ncd amazon-kinesis-video-streams-producer-c/build\ncmake .. -DBUILD_TEST=TRUE\nmake\n```\n##### **3.1.2 模拟 KVS Consumer 端环境准备**\n- **安装工程依赖**\n```\nsudo apt update\nsudo apt install software-properties-common\nsudo add-apt-repository ppa:deadsnakes/ppa\n```\n- **将 Python 版本更新到3.7**\n\nConsumer 端的代码依赖于 Python3.7 您需要按如下操作将 Python 的版本升级到3.7\n```\n执行如下命令查看 Python 的版本,如果版本是 python3.6 需要将 Python 版本更新到3.7\npython3 —version\n如果您的 Python 版本已经是 python3.7 可以跳过下面的步骤,如果是 python3.6 执行如下的操作\n\nsudo apt install python3.7\nsudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1\nsudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2\n\nsudo update-alternatives --config python3\n Selection Path Priority Status\n------------------------------------------------------------\n* 0 /usr/bin/python3.7 2 auto mode\n 1 /usr/bin/python3.6 1 manual mode\n 2 /usr/bin/python3.7 2 manual mode\nPress <enter> to keep the current choice[*], or type selection number:0\n选择0\n再次执行python3 —version\nPython 3.7.13\n```\n- **安装样例工程代码的依赖**\n```\n1.下载工程代码\ngit clone https://github.com/arch-team/amazon-kinesis-video-streams-time-lapse-video-main.git\n2.更新 pip 工具\nsudo python3 -m pip install -U pip\nsudo python3 -m pip install -U setuptools\nsudo apt-get update\nsudo apt-get install ffmpeg libsm6 libxext6 -y \n```\n- **在 Cloud9 中配置 profile**\n\n在 Cloud9 的终端中执行如下命令配置 profile\n```\nexport AWS_SESSION_TOKEN=your-SessionToken\nexport AWS_DEFAULT_REGION=eu-west-1\nexport AWS_ACCESS_KEY_ID=your AccessKeyId\nexport AWS_SECRET_ACCESS_KEY=your SecretAccessKey\n```\n- **执行 KVS Consumer 样例代码**\n```\npython3 main.py —stream-name your-stream-name\n—start-time 2022-05-31T09:40:33 # 开始时间\n—end-time 2022-05-31T09:42:19 # 结束时间\n—duration 3 # 采用周期\n—width 1920 —height 1080 # 图片分辨率\n—output-path result1.mp4\n```\n#### **3.2 自动从 KVS 中抽图流程说明**\n基于 KVS Image 功能之 Auto Image Generation 的处理流程如下图所示\n\n![image.png](https://dev-media.amazoncloud.cn/0bbccf3c8af24c6b8f9940b80bacf8f4_image.png)\n\n##### 3.2.1 执行 UpdateImageGenerationConfiguration 配置 KVS 自动抽图\n UpdateImageGenerationConfiguration 是配置 KVS 图片抽取参数的 API,通过该 API 您可以配置 KVS 自动抽图的采样周期、图片保存的 S3 存储桶、图片格式、图片像素等信息。\n\n- **准备 update-image-generation-input.json 文件**\n```\n{\n \"StreamName\": \"TestStream\", # 为您在3.1.1中创建的KVS Stream的名称\n \"ImageGenerationConfiguration\": {\n \"Status\": \"ENABLED\", # ENABLED或DISABLE 控制该项功能的启用或禁止\n \"DestinationConfig\": {\n \"DestinationRegion\": \"us-east-1\", # 为您在3.1.1中创建的S3所在的Region,本实验使用eu-west-1\n \"Uri\": \"s3://bucket-name\" # bucket-name为您在3.1.1中创建的S3的Bucket名称\n },\n \"SamplingInterval\": 3000, # 抽取图片的间隔时间\n \"ImageSelectorType\": \"PRODUCER_TIMESTAMP\", # 时间类型\n \"Format\": \"JPEG\", # 图片格式\n \"FormatConfig\": {\n \"JPEGQuality\": \"80\"\n },\n \"WidthPixels\": 320, # 图片像素\n \"HeightPixels\": 240 # 图片像素\n }\n}\n```\n- **执行 UpdateImageGenerationConfiguration API**\n```\naws kinesisvideo update-image-generation-configuration \\\n--cli-input-json file://./update-image-generation-input.json \\\n```\n##### **3.2.2 执行 UpdateNotificationConfiguration 配置 KVS 基于 SNS 通知下发**\nUpdateNotificationConfiguration 是配置基于 SNS 自动化通知下发的 API,通过该 API 配置 KVS Stream 之后,当 KVS 接受到 producer 发送到带有 AWS_KINESISVIDEO_NOTIFICATION 标签的帧后,会触发 SNS 通知。\n\n- 准备 update-notification-configuration.json 文件\n\n```\n{\n \"NotificationConfiguration\": { \n \"DestinationConfig\": { \n \"Uri\": \"string\" # SNS ARN\n },\n \"Status\": \"string\" # ENABLED或DISABLE 控制该项功能的启用或禁止\n },\n \"StreamARN\": \"string\", # StreamARN 与 StreamName二者选填一个,用于标识KVS\n \"StreamName\": \"string\"\n}\n```\n该命令执行如果报权限错误,您需要在该命令中指定 profile, 在上面的命令后加上–profile your profile name\n\n- **执行UpdateNotificationConfiguration API**\n```\naws kinesisvideo update-notification-configuration —cli-input-json file://./updateNotificationConfiguration.json\n```\n注意:\n\n1、执行 UpdateImageGenerationConfiguration 或 UpdateNotificationConfiguration 后,KVS Stream 的自动图片抽取和基于 SNS 需要1分钟之后才能生效。\n\n2、UpdateImageGenerationConfiguration 采样的时间间隔最小是3秒钟,如果您想要提高采样频率可以联系 Amazon support 来提升。\n\n##### **3.2.3 Cloud9 模拟 KVS Producer 推送视频流**\n- 获取临时token\n\n执行如下命令:aws sts get-session-token —profile your profile name 获取临时 token\n```\n\"Credentials\": {\n\"AccessKeyId\": \"your AccessKeyId\",\n\"SecretAccessKey\": \"your SecretAccessKey\",\n\"SessionToken\": \"your SessionToken\",\n\"Expiration\": \"2022-05-30T21:03:10Z\"\n}\n```\n- 配置环境变量\n```\nexport AWS_SESSION_TOKEN=your SessionToken\nexport AWS_DEFAULT_REGION=eu-west-1\nexport AWS_ACCESS_KEY_ID=your AccessKeyId\nexport AWS_SECRET_ACCESS_KEY=your SecretAccessKey\n```\n- 执行 Producer Sample 推送视频流\n```\nstatus = putKinesisVideoFrame(data->streamHandle, &frame);\n if (data->firstFrame) {\n startUpLatency = (DOUBLE)(GETTIME() - data->startTime) / (DOUBLE) HUNDREDS_OF_NANOS_IN_A_MILLISECOND;\n DLOGD(\"Start up latency: %lf ms\", startUpLatency);\n data->firstFrame = FALSE;\n }\n else if (frame.flags == FRAME_FLAG_KEY_FRAME) {\n if(gKeyFrameCount%KEYFRAME_EVENT_INTERVAL == 0)\n {\n //reset to 0 to avoid overflow in long running applications\n gKeyFrameCount = 0;\n switch (gEventsEnabled) {\n // NOTIFICATION标签\n case 1:\n putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_NOTIFICATION, NULL);\n break;\n // IMAGE_GENERATION标签\n case 2:\n putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_IMAGE_GENERATION, NULL);\n break;\n // NOTIFICATION和IMAGE_GENERATION标签\n case 3:\n putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_NOTIFICATION | STREAM_EVENT_TYPE_IMAGE_GENERATION, NULL);\n break;\n default:\n break;\n }\n }\n gKeyFrameCount++;\n }\n```\nProducer 端视频帧无标签,这时不会触发自动抽图和 Notification\n```\n./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac\n```\nProducer 端给视频帧打上 STREAM_EVENT_TYPE_IMAGE_GENERATION,仅自动抽图\n```\n./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac image\n```\nProducer 端给视频帧打上 STREAM_EVENT_TYPE_NOTIFICATION,仅 notification\n```\n./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac notification\n```\nProducer端给视频帧打上STREAM_EVENT_TYPE_IMAGE_GENERATION 和STREAM_EVENT_TYPE_IMAGE_GENERATION两种标签,自动抽图并发送notification\n```\n./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac both\n```\n##### **3.2.4 KVS Stream 自动抽图结果**\n- **s3 object key 说明如下图所示:由如下字段组成:file-extension**\t\n```\n1.ImagePrefix - Value of AWS_KINESISVIDEO_IMAGE_PREFIX.\n2.AccountID - Account ID under which the stream is created.\n3.StreamName - Name of the stream for which the image is generated.\n4.ImageTimecode - Epoch timecode in the fragment at which the image is generated.\n5.RandomID - Random GUID.\n6.file-extension - JPG or PNG based on the Image format requested.\n```\n![image.png](https://dev-media.amazoncloud.cn/c9f174f9c73c4066ae19a4e1b030e6b3_image.png)\n\n- **s3 object Metadata**\n```\n{ \n // KVS S3 object metadata \n x-amz-meta-aws_kinesisvideo_fragment_number : 'string', \n x-amz-meta-aws_kinesisvideo_producer_timestamp: 'number', \n x-amz-meta-aws_kinesisvideo_server_timestamp: 'number', \n // Optional key value pair sent as part of the MKV tags \n custom_key_1: custom_value_1, \n custom_key_2: custom_value_2, \n }\n```\n![image.png](https://dev-media.amazoncloud.cn/f8033a1de6164d1c9d85daede9ae1ad5_image.png)\n\n您可以基于其中的aws_kinesisvideo_fragment_number、timestamp和Producer自定义tag来满足具体的业务场景,比如使用aws_kinesisvideo_fragment_number对kvs视频流进行定位回放等。\n\n##### 3.2.5 KVS Stream 基于 SNS 的通知结果\n```\n{\n \"StreamArn\": \"your kvs stream arn\",\n \"FragmentNumber\": \"91343852333182293998949405270547347888495435985\",\n \"FragmentStartProducerTimestamp\": 1653905243571,\n \"FragmentStartServerTimestamp\": 1653905243687,\n \"NotificationType\": \"PERSISTED\"\n}\n```\n#### **3.3 基于 KVS GetImage 抽图流程**\nGetImages 是 KVS 最新推出的一个 API ,使用该 API 您可以采用完成托管的方式从存储在 KVS Stream 视频流中按照您期望的方式抽取图片。您可以将该图片用于机器学习推理,如对视频流进行人形、宠物、车辆等物体检测或者推送给最终用户进行预览。\n\n![image.png](https://dev-media.amazoncloud.cn/993391a80a4047798412e7a265476db8_image.png)\n##### **3.3.1 KVS GetImages API说明**\n- KVS GetImages Request参数\n```\n{\n \"StreamARN\": \"string\", # KVS stream标识\n \"StreamName\": \"string\",\n \"Format\": \"string\", # 返回图片的格式 JPEG|PNG\n \"FormatConfig\": {\n \"string\": \"string\"\n },\n \"HeightPixels\": number, # 图片像素\n \"WidthPixels\": number # 图片像素\n \"ImageSelectorType\": \"string\", # PRODUCER_TIMESTAMP | SERVER_TIMESTAMP\n \"MaxResults\": number, # 返回图片最大数量\n \"NextToken\": \"string\",\n \"SamplingInterval\": number, # 采样的时间间隔\n \"StartTimestamp\": number, # 抽图的开始时间\n \"EndTimestamp\": number, # 抽图的结束时间\n}\n```\n- KVS GetImages Response参数\n```\n{\n \"Images\": [ # GetImages API 返回的图片集合\n {\n \"Error\": \"string\",\n \"ImageContent\": \"string\", # 图片数据采用BASE64编码后的内容\n \"TimeStamp\": number\n }\n ],\n \"NextToken\": \"string\"\n}\n```\n##### 3.3.1 KVS GetImages 实验步骤\n- **按照2.3 Cloud9 模拟 KVS Producer 推送视频流到对应的 KVS Stream**\n- **记录下上一步骤中 KVS Producer 推流中 terminal 中打印的时间**\n```\n2022-05-31 14:00:33 DEBUG logStreamMetric(): Total elementary frame rate (fps): 25.000000 \n2022-05-31 14:00:33 DEBUG logStreamMetric(): Average API call retry count for client: 0.000000\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 65524 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 39363 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 25886 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {\"EventType\":\"RECEIVED\",\"FragmentTimecode\":0,\"FragmentNumber\":\"91343852333182358371831448110348590349566628324\"}\n\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 20922 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {\"EventType\":\"BUFFERING\",\"FragmentTimecode\":1800,\"FragmentNumber\":\"91343852333182358376783208267490111901301663845\"}\n\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 17251 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 20494 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 709 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {\"EventType\":\"PERSISTED\",\"FragmentTimecode\":0,\"FragmentNumber\":\"91343852333182358371831448110348590349566628324\"}\n```\n- **如下图所示执行1.2 模拟 KVS Consumer 端环境准备的样例代码**\n核心代码说明:如下图是基于 Python 代码\n```\ndef get_and_write_frame(args, kvs_am_client, timestamp, writer):\n \"\"\" Fetch a frame at the timestamp and write it to the video writer \"\"\"\n try:\n res = kvs_am_client.get_images(\n StreamName=args.stream_name,\n ImageSelectorType='SERVER_TIMESTAMP',\n StartTimestamp=timestamp,\n EndTimestamp=timestamp + datetime.timedelta(seconds=3),\n SamplingInterval=3000,\n Format='JPEG',\n WidthPixels=args.width,\n HeightPixels=args.height,\n MaxResults=3,\n )\n except kvs_am_client.exceptions.ResourceNotFoundException as e:\n print(f\"{e} at {timestamp}\")\n return\n for image in res[\"Images\"]:\n if \"Error\" not in image:\n content = image[\"ImageContent\"]\n path = \"/tmp/image.jpg\"\n print(f\"Write a frame at {timestamp}\")\n with open(path, \"wb\") as fw:\n fw.write(base64.b64decode(content))\n\n cv2_image = cv2.imread(path)\n writer.write(cv2_image)\n return\n print(f\"Couldn't find a valid image frame at {timestamp}\") \n```\n运行 main.py,并传入封装好的参数\n```\npython3 main.py —stream-name your stream name\n—start-time 2022-05-31T09:40:33 # 开始时间\n—end-time 2022-05-31T09:42:19 # 结束时间\n—duration 3 # 采用周期\n—width 1920 —height 1080 # 图片分辨率\n—output-path result1.mp4\n```\n- **观测 KVS Images GetImages 抽取图片,如下图所示 Consumer端抽取图片成功**\n```\nCouldn't find a valid image frame at 2022-05-31 09:40:33\nWrite a frame at 2022-05-31 09:40:35\nWrite a frame at 2022-05-31 09:40:37\nWrite a frame at 2022-05-31 09:40:39\nWrite a frame at 2022-05-31 09:40:41\nWrite a frame at 2022-05-31 09:40:43\nWrite a frame at 2022-05-31 09:40:45\nWrite a frame at 2022-05-31 09:40:47\nWrite a frame at 2022-05-31 09:40:49\n```\n### 4.结束语\n在端到端的处理流程中,按照检测数据输入来源、输入数据格式、数据处理方案、智能检测方式这几个维度的可选的组合有如下几种技术方案可供选择。Amazon 提供的云服务能力可以很好的支持这些方案的实现。\n\n![image.png](https://dev-media.amazoncloud.cn/df3a929a22c24ee780c07f6681411c41_image.png)\n- 智能检测部署位置对比分析\n\n![image.png](https://dev-media.amazoncloud.cn/4914b084d8674ce699ee0b3244a2579d_image.png)\n- 智能检测输入数据格式对比分析\n\n![image.png](https://dev-media.amazoncloud.cn/d8ec4a73447245a38dfcd9b3899eee30_image.png)\n- 智能检测输入数据处理对比分析\n\n![image.png](https://dev-media.amazoncloud.cn/be93cd6002104a53a8b4b5b08f5c1096_image.png)\n- 智能检测方案对比分析\n\n![image.png](https://dev-media.amazoncloud.cn/1a39dfefb33b4d79912f2317060e2986_image.png)\n\n实际应用中您可以根据AI场景的复杂度、团队的技术储备、成本、项目交付周期这几个维度选择适合当前状况的方案。\n### **5. 参考资料**\nKinesis Video Streams Images 官方文档\n\n[https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/images.html](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/images.html)\n\nC语言版本的 KVS Producer 包含了 KVS Images 功能的样例代码\n\n[https://github.com/awslabs/amazon-kinesis-video-streams-producer-c](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c)\n\nCPP 语言版本的 KVS Producer 包含了 KVS Images 功能的样例代码\n\n[https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp)\n\nPython 语言版本的 KVS 包含了 KVS Images 功能的样例代码\n\n[https://github.com/arch-team/amazon-kinesis-video-streams-time-lapse-video-main](https://github.com/arch-team/amazon-kinesis-video-streams-time-lapse-video-main)\n\nPython 升级到 Python3.7 版本说明\n\n[https://www.itbulu.com/up-ubuntu-python37.html](https://www.itbulu.com/up-ubuntu-python37.html)\n\n### 本篇作者\n![image.png](https://dev-media.amazoncloud.cn/ae2397ea6b774957b8eae38320efc091_image.png)\n**孙进华**\n亚马逊云科技资深解决方案架构师,负责帮助客户进行上云架构的设计和咨询。加入 Amazon 前自主创业负责电商平台搭建和车企电商平台整体架构设计。曾就职于全球领先的通讯设备公司,担任高级工程师,负责 LTE 设备系统的多个子系统的开发与架构设计。在高并发、高可用系统架构设计、微服务架构设计、数据库、中间件、IOT 等方面有着丰富的经验。\n\n![image.png](https://dev-media.amazoncloud.cn/80fee0f8653844f993c08bf0bf5a93a1_image.png)\n**徐开**\nAmazon 物联网实验室 解决方案架构师,主要负责物联网解决方案,致力于 Amazon IoT 相关技术的推广与应用","render":"<h3><a id=\"1__0\"></a><strong>1. 前言</strong></h3>\n<p>基于云端实时视频智能检测的功能,在居家安防监控领域有着较高的价值。这一场景的实现通常如下图所示分为如下几个阶段:视频流产生(Producer)、视频流存储(Storage)、视频流处理(Consumer)。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/04a9676e35d047a88ce39ea913b41e82_image.png\" alt=\"image.png\" /></p>\n<p>当前使用低成本的网络摄像头(硬件资源有限,不支持边缘推理计算)+云端存储推理实现家用及中小商户安防监控成为一个流行的方式。在实际的应用过程中往往需要根据AI场景的复杂性、多样性、成本的考量、技术难度差异选择适合当前现状的方案。例如基于成本优化的考虑,我们希望采用图片作为智能检测的数据输入,发送用户告警通知的媒体信息通常也是图片格式,因此通常需要从视频流中提取图片,但从视频流中抽取图片往往需要维护可扩展的计算资源来将视频转码为图片格式,这对没有的专业领域技术积累的团队来说是个不小的挑战。本文将详细介绍如何使用 Amazon 新推出的 Amazon Kinesis Video Streams Images 来简化云端抽图。</p>\n<h4><a id=\"11___6\"></a><strong>1.1 相关产品介绍</strong></h4>\n<ul>\n<li><strong>Amazon Kinesis Video Streams</strong> 是一项完全托管的 Amazon 服务,您可以使用 Kinesis Video Streams 捕获来自数百万种源 (包括智能手机、安全摄像头、网络摄像头、车载摄像头、无人机及其他源) 的海量实时视频数据传输到 Amazon 云,或者构建应用程序以进行实时视频处理或进行面向批处理的视频。</li>\n<li><strong>Amazon Kinesis Video Stream Images</strong> 是 KVS 上一组完全托管的 API ,它提供了如下的功能特性:</li>\n</ul>\n<ol>\n<li>以完全托管的方式从 KVS 视频流中抽取图片并保存到S3。</li>\n<li>使用 KVS Consumer 侧提供的 GetImages API 按需从 KVS 视频流中抽取图片。</li>\n<li>基于标签 KVS Producer 端的标签,自动触发 Amazon SNS 的通知。</li>\n</ol>\n<p>借助上述功能,您可以构建视频流检测的通知,基于视频流中的抽取的图片构建智能视频检测应用。</p>\n<ul>\n<li><strong>Amazon Rekognition</strong> 提供预先训练和可定制的计算机视觉 (CV) 功能,可从您的图像和视频中提取信息和获得洞察力。提供高精度的人脸分析检测、人脸比较和人脸搜索、标签文本检测等功能。Amazon Rekognition 基于同样由 Amazon 计算机视觉科学家开发的成熟且高度可扩展的深度学习技术,每天能够分析数十亿图像和视频。它不需要机器学习专业知识即可使用。Amazon Rekognition 包含一个简单易用的API,该API 可快速分析存储在 Amazon S3 中的任何图像或视频文件。</li>\n</ul>\n<h3><a id=\"2Amazon_Kinesis_Video_Stream_Images__16\"></a><strong>2.Amazon Kinesis Video Stream Images 方案分析</strong></h3>\n<h4><a id=\"21__17\"></a><strong>2.1 方案概述</strong></h4>\n<p>Kinesis Video Stream Images 方案整体架构分为:设备端、Amazon云端、用户应用端。</p>\n<ul>\n<li><strong>设备端</strong></li>\n</ul>\n<p>为带有一定视频检测能力的摄像头设备、通过集成 KVS SDK 作为 KVS 的 Producer 向云端 KVS Stream 推送视频流,并基于摄像头设备的检测能力给 KVS MKV 数据打 Tag ,这些 Tag 的用途一是作为 KVS Image API 的触发标志,二是作为业务逻辑处理的依据。</p>\n<ul>\n<li>\n<p><strong>Amazon 云端</strong></p>\n<ul>\n<li>Amazon Kinesis Video Stream :提供设备视频持久化存储、视频检索、视频在线查看、视频下载等能力,并向 Rekognition 提供用于视频检测的数据。</li>\n<li>Amazon Rekognition:提供自动执行视频和图像分析的能力,包括基于视频或图像的内容审核、人脸检测、人脸比较、标签检测等完全托管的能力,并且可以方便的与 KVS、S3、SNS 等服务集成。</li>\n<li>Amazon S3:提供视频检测结果的存储。</li>\n<li>Amazon SNS:完全托管的发布/订阅消息收发、SMS、电子邮件和移动推送通知在本方案中提供通知发送的能力。</li>\n</ul>\n</li>\n</ul>\n<p>该方案的整体架构图如下</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/a9179242b28b4974a97f70d35837522b_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"22_34\"></a><strong>2.2方案说明</strong></h4>\n<ul>\n<li>视频流 Producer(设备)</li>\n</ul>\n<p>设备端通常是带有一定检测能力的摄像头设备,集成 KVS Prouder SDK 。借助自身的视频检测能力给视频帧打标签,并使用 KVS prouder SDK 将视频流推送到云端。</p>\n<ul>\n<li>视频流 Processor(云端)</li>\n</ul>\n<p>云端视频流 Processor 通过 Amazon Service 提供如下处理能力:</p>\n<p><strong>视频云存</strong>:KVS Video Streams 是 Amazon 在云端的视频流存储资源,它可以提供视频数据的持久化存储,并提供视频检测和回放的API以实现复杂的需求场景。</p>\n<p><strong>抽图</strong>:通过 KVS 您可以使用 KVS GetMedia 或 GetImages API 从视频流中抽取图片、发送告警通知、智能视频检测处理。</p>\n<p><strong>通知告警</strong>:采用 SNS 与 KVS images 无缝集成的方式,您只需调用 API 进行一些简单的配置就可以构建视频通知告警的方案。</p>\n<p><strong>智能视频检测</strong>:云端的视频检测实现方式有三种:基于 Sagemaker、基于 Rekognition、基于 EC2 自建模型。</p>\n<ul>\n<li>视频流 Consumer(应用端):</li>\n</ul>\n<p>应用端通常是 APP,集成 KVS Consumer SDK 和消息推送服务,可以从 KVS 中按需回看视频或者查看存储在S3中的图片。</p>\n<h3><a id=\"3__54\"></a><strong>3. 方案集成验证</strong></h3>\n<h4><a id=\"31__55\"></a><strong>3.1 实验准备工作</strong></h4>\n<h5><a id=\"311__Amazon__56\"></a><strong>3.1.1 准备 Amazon 资源</strong></h5>\n<ul>\n<li><strong>准备 Amazon 账户并配置用户权限</strong></li>\n</ul>\n<p>1、本次实验需要用到的 Amazon 资源都在 Ireland Region 中创建,您需要提前准备好一个 Amazon account。<br />\n2、在 Amazon IAM 中创建一个 Admin User,赋予arn:aws:iam::aws:policy/AdministratorAccess 策略,后续的资源创建都使用这个用户来操作。</p>\n<p>3、在 Amazon IAM 的 Admin User 创建一个 AKSK,并记录下来,后面的实验环境需要用到。创建 IAM User AKSK 的方法请参考如下的文档:<a href=\"https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html\" target=\"_blank\">https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html</a></p>\n<ul>\n<li><strong>创建 Cloud9 用于模拟 KVS Producer 和 Consumer</strong></li>\n</ul>\n<p>创建 Amazon Cloud9 的方法请参考如下的文档:</p>\n<p><a href=\"https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9\" target=\"_blank\">https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9</a></p>\n<p>注意:由于默认创建的 Cloud9 的存储空间有限,建议在执行后面的操作之前先扩展 Cloud9 的空间,如何扩展 Cloud9 的存储空间请参照如下链接中的 Disk Space Expansion 章节。</p>\n<p><a href=\"https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9\" target=\"_blank\">https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9</a></p>\n<ul>\n<li>**在 Cloud9 中配置 profile **</li>\n</ul>\n<p>在 Cloud9 的终端中执行如下命令配置 profile</p>\n<pre><code class=\"lang-\">$ aws configure --profile your-profile-name\nAWS Access Key ID [None]:your AWS Access Key ID \nAWS Secret Access Key [None]:your AWS Secret Access Key\nDefault region name [None]: eu-west-1\nDefault output format [None]: json \n</code></pre>\n<ul>\n<li><strong>创建 Amazon S3 Bucket 用于保存从 KVS 中抽取的图片</strong></li>\n</ul>\n<pre><code class=\"lang-\">aws s3 mb s3://sample-bucket-name --region eu-west-1\n</code></pre>\n<ul>\n<li><strong>创建 SNS 用于 KVS 将抽帧结果通知到相关服务</strong></li>\n</ul>\n<p>注意上面创建的 Cloud9、S3 Bucket 和 SNS 需要位于同一个 Amazon 的 Region 。如下图所示:</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/d0c11017f7714b4794c1408a2b0c792c_image.png\" alt=\"image.png\" /></p>\n<ul>\n<li>**创建云端的 Kinesis Video Stream **</li>\n</ul>\n<p><img src=\"https://dev-media.amazoncloud.cn/9fd22e3ffab14d2fb11196f3de49f27e_image.png\" alt=\"image.png\" /></p>\n<h5><a id=\"312__KVS_Producer__96\"></a><strong>3.1.2 模拟 KVS Producer 设备端环境准备</strong></h5>\n<ul>\n<li><strong>安装工程依赖</strong></li>\n</ul>\n<pre><code class=\"lang-\">sudo apt-get update\nsudo apt-get install -y cmake git gcc g++ autoconf\nsudo apt-get install -y libssl-dev libcurl4-openssl-dev liblog4cplus-dev pkg-config\n</code></pre>\n<ul>\n<li><strong>样例工程编译</strong><br />\n<strong>1.下载工程代码</strong></li>\n</ul>\n<pre><code class=\"lang-\">git clone --recursive https://github.com/awslabs/amazon-kinesis-video-streams-producer-c.git\n</code></pre>\n<p><strong>2.工程代码</strong></p>\n<pre><code class=\"lang-\">mkdir -p amazon-kinesis-video-streams-producer-c/build\ncd amazon-kinesis-video-streams-producer-c/build\ncmake .. -DBUILD_TEST=TRUE\nmake\n</code></pre>\n<h5><a id=\"312__KVS_Consumer__115\"></a><strong>3.1.2 模拟 KVS Consumer 端环境准备</strong></h5>\n<ul>\n<li><strong>安装工程依赖</strong></li>\n</ul>\n<pre><code class=\"lang-\">sudo apt update\nsudo apt install software-properties-common\nsudo add-apt-repository ppa:deadsnakes/ppa\n</code></pre>\n<ul>\n<li><strong>将 Python 版本更新到3.7</strong></li>\n</ul>\n<p>Consumer 端的代码依赖于 Python3.7 您需要按如下操作将 Python 的版本升级到3.7</p>\n<pre><code class=\"lang-\">执行如下命令查看 Python 的版本,如果版本是 python3.6 需要将 Python 版本更新到3.7\npython3 —version\n如果您的 Python 版本已经是 python3.7 可以跳过下面的步骤,如果是 python3.6 执行如下的操作\n\nsudo apt install python3.7\nsudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1\nsudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2\n\nsudo update-alternatives --config python3\n Selection Path Priority Status\n------------------------------------------------------------\n* 0 /usr/bin/python3.7 2 auto mode\n 1 /usr/bin/python3.6 1 manual mode\n 2 /usr/bin/python3.7 2 manual mode\nPress <enter> to keep the current choice[*], or type selection number:0\n选择0\n再次执行python3 —version\nPython 3.7.13\n</code></pre>\n<ul>\n<li><strong>安装样例工程代码的依赖</strong></li>\n</ul>\n<pre><code class=\"lang-\">1.下载工程代码\ngit clone https://github.com/arch-team/amazon-kinesis-video-streams-time-lapse-video-main.git\n2.更新 pip 工具\nsudo python3 -m pip install -U pip\nsudo python3 -m pip install -U setuptools\nsudo apt-get update\nsudo apt-get install ffmpeg libsm6 libxext6 -y \n</code></pre>\n<ul>\n<li><strong>在 Cloud9 中配置 profile</strong></li>\n</ul>\n<p>在 Cloud9 的终端中执行如下命令配置 profile</p>\n<pre><code class=\"lang-\">export AWS_SESSION_TOKEN=your-SessionToken\nexport AWS_DEFAULT_REGION=eu-west-1\nexport AWS_ACCESS_KEY_ID=your AccessKeyId\nexport AWS_SECRET_ACCESS_KEY=your SecretAccessKey\n</code></pre>\n<ul>\n<li><strong>执行 KVS Consumer 样例代码</strong></li>\n</ul>\n<pre><code class=\"lang-\">python3 main.py —stream-name your-stream-name\n—start-time 2022-05-31T09:40:33 # 开始时间\n—end-time 2022-05-31T09:42:19 # 结束时间\n—duration 3 # 采用周期\n—width 1920 —height 1080 # 图片分辨率\n—output-path result1.mp4\n</code></pre>\n<h4><a id=\"32__KVS__173\"></a><strong>3.2 自动从 KVS 中抽图流程说明</strong></h4>\n<p>基于 KVS Image 功能之 Auto Image Generation 的处理流程如下图所示</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/0bbccf3c8af24c6b8f9940b80bacf8f4_image.png\" alt=\"image.png\" /></p>\n<h5><a id=\"321___UpdateImageGenerationConfiguration__KVS__178\"></a>3.2.1 执行 UpdateImageGenerationConfiguration 配置 KVS 自动抽图</h5>\n<p>UpdateImageGenerationConfiguration 是配置 KVS 图片抽取参数的 API,通过该 API 您可以配置 KVS 自动抽图的采样周期、图片保存的 S3 存储桶、图片格式、图片像素等信息。</p>\n<ul>\n<li><strong>准备 update-image-generation-input.json 文件</strong></li>\n</ul>\n<pre><code class=\"lang-\">{\n "StreamName": "TestStream", # 为您在3.1.1中创建的KVS Stream的名称\n "ImageGenerationConfiguration": {\n "Status": "ENABLED", # ENABLED或DISABLE 控制该项功能的启用或禁止\n "DestinationConfig": {\n "DestinationRegion": "us-east-1", # 为您在3.1.1中创建的S3所在的Region,本实验使用eu-west-1\n "Uri": "s3://bucket-name" # bucket-name为您在3.1.1中创建的S3的Bucket名称\n },\n "SamplingInterval": 3000, # 抽取图片的间隔时间\n "ImageSelectorType": "PRODUCER_TIMESTAMP", # 时间类型\n "Format": "JPEG", # 图片格式\n "FormatConfig": {\n "JPEGQuality": "80"\n },\n "WidthPixels": 320, # 图片像素\n "HeightPixels": 240 # 图片像素\n }\n}\n</code></pre>\n<ul>\n<li><strong>执行 UpdateImageGenerationConfiguration API</strong></li>\n</ul>\n<pre><code class=\"lang-\">aws kinesisvideo update-image-generation-configuration \\\n--cli-input-json file://./update-image-generation-input.json \\\n</code></pre>\n<h5><a id=\"322___UpdateNotificationConfiguration__KVS__SNS__207\"></a><strong>3.2.2 执行 UpdateNotificationConfiguration 配置 KVS 基于 SNS 通知下发</strong></h5>\n<p>UpdateNotificationConfiguration 是配置基于 SNS 自动化通知下发的 API,通过该 API 配置 KVS Stream 之后,当 KVS 接受到 producer 发送到带有 AWS_KINESISVIDEO_NOTIFICATION 标签的帧后,会触发 SNS 通知。</p>\n<ul>\n<li>准备 update-notification-configuration.json 文件</li>\n</ul>\n<pre><code class=\"lang-\">{\n "NotificationConfiguration": { \n "DestinationConfig": { \n "Uri": "string" # SNS ARN\n },\n "Status": "string" # ENABLED或DISABLE 控制该项功能的启用或禁止\n },\n "StreamARN": "string", # StreamARN 与 StreamName二者选填一个,用于标识KVS\n "StreamName": "string"\n}\n</code></pre>\n<p>该命令执行如果报权限错误,您需要在该命令中指定 profile, 在上面的命令后加上–profile your profile name</p>\n<ul>\n<li><strong>执行UpdateNotificationConfiguration API</strong></li>\n</ul>\n<pre><code class=\"lang-\">aws kinesisvideo update-notification-configuration —cli-input-json file://./updateNotificationConfiguration.json\n</code></pre>\n<p>注意:</p>\n<p>1、执行 UpdateImageGenerationConfiguration 或 UpdateNotificationConfiguration 后,KVS Stream 的自动图片抽取和基于 SNS 需要1分钟之后才能生效。</p>\n<p>2、UpdateImageGenerationConfiguration 采样的时间间隔最小是3秒钟,如果您想要提高采样频率可以联系 Amazon support 来提升。</p>\n<h5><a id=\"323__Cloud9__KVS_Producer__236\"></a><strong>3.2.3 Cloud9 模拟 KVS Producer 推送视频流</strong></h5>\n<ul>\n<li>获取临时token</li>\n</ul>\n<p>执行如下命令:aws sts get-session-token —profile your profile name 获取临时 token</p>\n<pre><code class=\"lang-\">"Credentials": {\n"AccessKeyId": "your AccessKeyId",\n"SecretAccessKey": "your SecretAccessKey",\n"SessionToken": "your SessionToken",\n"Expiration": "2022-05-30T21:03:10Z"\n}\n</code></pre>\n<ul>\n<li>配置环境变量</li>\n</ul>\n<pre><code class=\"lang-\">export AWS_SESSION_TOKEN=your SessionToken\nexport AWS_DEFAULT_REGION=eu-west-1\nexport AWS_ACCESS_KEY_ID=your AccessKeyId\nexport AWS_SECRET_ACCESS_KEY=your SecretAccessKey\n</code></pre>\n<ul>\n<li>执行 Producer Sample 推送视频流</li>\n</ul>\n<pre><code class=\"lang-\">status = putKinesisVideoFrame(data->streamHandle, &frame);\n if (data->firstFrame) {\n startUpLatency = (DOUBLE)(GETTIME() - data->startTime) / (DOUBLE) HUNDREDS_OF_NANOS_IN_A_MILLISECOND;\n DLOGD("Start up latency: %lf ms", startUpLatency);\n data->firstFrame = FALSE;\n }\n else if (frame.flags == FRAME_FLAG_KEY_FRAME) {\n if(gKeyFrameCount%KEYFRAME_EVENT_INTERVAL == 0)\n {\n //reset to 0 to avoid overflow in long running applications\n gKeyFrameCount = 0;\n switch (gEventsEnabled) {\n // NOTIFICATION标签\n case 1:\n putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_NOTIFICATION, NULL);\n break;\n // IMAGE_GENERATION标签\n case 2:\n putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_IMAGE_GENERATION, NULL);\n break;\n // NOTIFICATION和IMAGE_GENERATION标签\n case 3:\n putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_NOTIFICATION | STREAM_EVENT_TYPE_IMAGE_GENERATION, NULL);\n break;\n default:\n break;\n }\n }\n gKeyFrameCount++;\n }\n</code></pre>\n<p>Producer 端视频帧无标签,这时不会触发自动抽图和 Notification</p>\n<pre><code class=\"lang-\">./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac\n</code></pre>\n<p>Producer 端给视频帧打上 STREAM_EVENT_TYPE_IMAGE_GENERATION,仅自动抽图</p>\n<pre><code class=\"lang-\">./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac image\n</code></pre>\n<p>Producer 端给视频帧打上 STREAM_EVENT_TYPE_NOTIFICATION,仅 notification</p>\n<pre><code class=\"lang-\">./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac notification\n</code></pre>\n<p>Producer端给视频帧打上STREAM_EVENT_TYPE_IMAGE_GENERATION 和STREAM_EVENT_TYPE_IMAGE_GENERATION两种标签,自动抽图并发送notification</p>\n<pre><code class=\"lang-\">./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac both\n</code></pre>\n<h5><a id=\"324_KVS_Stream__304\"></a><strong>3.2.4 KVS Stream 自动抽图结果</strong></h5>\n<ul>\n<li><strong>s3 object key 说明如下图所示:由如下字段组成:file-extension</strong></li>\n</ul>\n<pre><code class=\"lang-\">1.ImagePrefix - Value of AWS_KINESISVIDEO_IMAGE_PREFIX.\n2.AccountID - Account ID under which the stream is created.\n3.StreamName - Name of the stream for which the image is generated.\n4.ImageTimecode - Epoch timecode in the fragment at which the image is generated.\n5.RandomID - Random GUID.\n6.file-extension - JPG or PNG based on the Image format requested.\n</code></pre>\n<p><img src=\"https://dev-media.amazoncloud.cn/c9f174f9c73c4066ae19a4e1b030e6b3_image.png\" alt=\"image.png\" /></p>\n<ul>\n<li><strong>s3 object Metadata</strong></li>\n</ul>\n<pre><code class=\"lang-\">{ \n // KVS S3 object metadata \n x-amz-meta-aws_kinesisvideo_fragment_number : 'string', \n x-amz-meta-aws_kinesisvideo_producer_timestamp: 'number', \n x-amz-meta-aws_kinesisvideo_server_timestamp: 'number', \n // Optional key value pair sent as part of the MKV tags \n custom_key_1: custom_value_1, \n custom_key_2: custom_value_2, \n }\n</code></pre>\n<p><img src=\"https://dev-media.amazoncloud.cn/f8033a1de6164d1c9d85daede9ae1ad5_image.png\" alt=\"image.png\" /></p>\n<p>您可以基于其中的aws_kinesisvideo_fragment_number、timestamp和Producer自定义tag来满足具体的业务场景,比如使用aws_kinesisvideo_fragment_number对kvs视频流进行定位回放等。</p>\n<h5><a id=\"325_KVS_Stream__SNS__332\"></a>3.2.5 KVS Stream 基于 SNS 的通知结果</h5>\n<pre><code class=\"lang-\">{\n "StreamArn": "your kvs stream arn",\n "FragmentNumber": "91343852333182293998949405270547347888495435985",\n "FragmentStartProducerTimestamp": 1653905243571,\n "FragmentStartServerTimestamp": 1653905243687,\n "NotificationType": "PERSISTED"\n}\n</code></pre>\n<h4><a id=\"33__KVS_GetImage__342\"></a><strong>3.3 基于 KVS GetImage 抽图流程</strong></h4>\n<p>GetImages 是 KVS 最新推出的一个 API ,使用该 API 您可以采用完成托管的方式从存储在 KVS Stream 视频流中按照您期望的方式抽取图片。您可以将该图片用于机器学习推理,如对视频流进行人形、宠物、车辆等物体检测或者推送给最终用户进行预览。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/993391a80a4047798412e7a265476db8_image.png\" alt=\"image.png\" /></p>\n<h5><a id=\"331_KVS_GetImages_API_346\"></a><strong>3.3.1 KVS GetImages API说明</strong></h5>\n<ul>\n<li>KVS GetImages Request参数</li>\n</ul>\n<pre><code class=\"lang-\">{\n "StreamARN": "string", # KVS stream标识\n "StreamName": "string",\n "Format": "string", # 返回图片的格式 JPEG|PNG\n "FormatConfig": {\n "string": "string"\n },\n "HeightPixels": number, # 图片像素\n "WidthPixels": number # 图片像素\n "ImageSelectorType": "string", # PRODUCER_TIMESTAMP | SERVER_TIMESTAMP\n "MaxResults": number, # 返回图片最大数量\n "NextToken": "string",\n "SamplingInterval": number, # 采样的时间间隔\n "StartTimestamp": number, # 抽图的开始时间\n "EndTimestamp": number, # 抽图的结束时间\n}\n</code></pre>\n<ul>\n<li>KVS GetImages Response参数</li>\n</ul>\n<pre><code class=\"lang-\">{\n "Images": [ # GetImages API 返回的图片集合\n {\n "Error": "string",\n "ImageContent": "string", # 图片数据采用BASE64编码后的内容\n "TimeStamp": number\n }\n ],\n "NextToken": "string"\n}\n</code></pre>\n<h5><a id=\"331_KVS_GetImages__379\"></a>3.3.1 KVS GetImages 实验步骤</h5>\n<ul>\n<li><strong>按照2.3 Cloud9 模拟 KVS Producer 推送视频流到对应的 KVS Stream</strong></li>\n<li><strong>记录下上一步骤中 KVS Producer 推流中 terminal 中打印的时间</strong></li>\n</ul>\n<pre><code class=\"lang-\">2022-05-31 14:00:33 DEBUG logStreamMetric(): Total elementary frame rate (fps): 25.000000 \n2022-05-31 14:00:33 DEBUG logStreamMetric(): Average API call retry count for client: 0.000000\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 65524 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 39363 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 25886 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {"EventType":"RECEIVED","FragmentTimecode":0,"FragmentNumber":"91343852333182358371831448110348590349566628324"}\n\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 20922 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {"EventType":"BUFFERING","FragmentTimecode":1800,"FragmentNumber":"91343852333182358376783208267490111901301663845"}\n\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 17251 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 20494 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 709 bytes to Kinesis Video. Upload stream handle: 0\n2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {"EventType":"PERSISTED","FragmentTimecode":0,"FragmentNumber":"91343852333182358371831448110348590349566628324"}\n</code></pre>\n<ul>\n<li><strong>如下图所示执行1.2 模拟 KVS Consumer 端环境准备的样例代码</strong><br />\n核心代码说明:如下图是基于 Python 代码</li>\n</ul>\n<pre><code class=\"lang-\">def get_and_write_frame(args, kvs_am_client, timestamp, writer):\n """ Fetch a frame at the timestamp and write it to the video writer """\n try:\n res = kvs_am_client.get_images(\n StreamName=args.stream_name,\n ImageSelectorType='SERVER_TIMESTAMP',\n StartTimestamp=timestamp,\n EndTimestamp=timestamp + datetime.timedelta(seconds=3),\n SamplingInterval=3000,\n Format='JPEG',\n WidthPixels=args.width,\n HeightPixels=args.height,\n MaxResults=3,\n )\n except kvs_am_client.exceptions.ResourceNotFoundException as e:\n print(f"{e} at {timestamp}")\n return\n for image in res["Images"]:\n if "Error" not in image:\n content = image["ImageContent"]\n path = "/tmp/image.jpg"\n print(f"Write a frame at {timestamp}")\n with open(path, "wb") as fw:\n fw.write(base64.b64decode(content))\n\n cv2_image = cv2.imread(path)\n writer.write(cv2_image)\n return\n print(f"Couldn't find a valid image frame at {timestamp}") \n</code></pre>\n<p>运行 main.py,并传入封装好的参数</p>\n<pre><code class=\"lang-\">python3 main.py —stream-name your stream name\n—start-time 2022-05-31T09:40:33 # 开始时间\n—end-time 2022-05-31T09:42:19 # 结束时间\n—duration 3 # 采用周期\n—width 1920 —height 1080 # 图片分辨率\n—output-path result1.mp4\n</code></pre>\n<ul>\n<li><strong>观测 KVS Images GetImages 抽取图片,如下图所示 Consumer端抽取图片成功</strong></li>\n</ul>\n<pre><code class=\"lang-\">Couldn't find a valid image frame at 2022-05-31 09:40:33\nWrite a frame at 2022-05-31 09:40:35\nWrite a frame at 2022-05-31 09:40:37\nWrite a frame at 2022-05-31 09:40:39\nWrite a frame at 2022-05-31 09:40:41\nWrite a frame at 2022-05-31 09:40:43\nWrite a frame at 2022-05-31 09:40:45\nWrite a frame at 2022-05-31 09:40:47\nWrite a frame at 2022-05-31 09:40:49\n</code></pre>\n<h3><a id=\"4_452\"></a>4.结束语</h3>\n<p>在端到端的处理流程中,按照检测数据输入来源、输入数据格式、数据处理方案、智能检测方式这几个维度的可选的组合有如下几种技术方案可供选择。Amazon 提供的云服务能力可以很好的支持这些方案的实现。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/df3a929a22c24ee780c07f6681411c41_image.png\" alt=\"image.png\" /></p>\n<ul>\n<li>智能检测部署位置对比分析</li>\n</ul>\n<p><img src=\"https://dev-media.amazoncloud.cn/4914b084d8674ce699ee0b3244a2579d_image.png\" alt=\"image.png\" /></p>\n<ul>\n<li>智能检测输入数据格式对比分析</li>\n</ul>\n<p><img src=\"https://dev-media.amazoncloud.cn/d8ec4a73447245a38dfcd9b3899eee30_image.png\" alt=\"image.png\" /></p>\n<ul>\n<li>智能检测输入数据处理对比分析</li>\n</ul>\n<p><img src=\"https://dev-media.amazoncloud.cn/be93cd6002104a53a8b4b5b08f5c1096_image.png\" alt=\"image.png\" /></p>\n<ul>\n<li>智能检测方案对比分析</li>\n</ul>\n<p><img src=\"https://dev-media.amazoncloud.cn/1a39dfefb33b4d79912f2317060e2986_image.png\" alt=\"image.png\" /></p>\n<p>实际应用中您可以根据AI场景的复杂度、团队的技术储备、成本、项目交付周期这几个维度选择适合当前状况的方案。</p>\n<h3><a id=\"5__470\"></a><strong>5. 参考资料</strong></h3>\n<p>Kinesis Video Streams Images 官方文档</p>\n<p><a href=\"https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/images.html\" target=\"_blank\">https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/images.html</a></p>\n<p>C语言版本的 KVS Producer 包含了 KVS Images 功能的样例代码</p>\n<p><a href=\"https://github.com/awslabs/amazon-kinesis-video-streams-producer-c\" target=\"_blank\">https://github.com/awslabs/amazon-kinesis-video-streams-producer-c</a></p>\n<p>CPP 语言版本的 KVS Producer 包含了 KVS Images 功能的样例代码</p>\n<p><a href=\"https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp\" target=\"_blank\">https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp</a></p>\n<p>Python 语言版本的 KVS 包含了 KVS Images 功能的样例代码</p>\n<p><a href=\"https://github.com/arch-team/amazon-kinesis-video-streams-time-lapse-video-main\" target=\"_blank\">https://github.com/arch-team/amazon-kinesis-video-streams-time-lapse-video-main</a></p>\n<p>Python 升级到 Python3.7 版本说明</p>\n<p><a href=\"https://www.itbulu.com/up-ubuntu-python37.html\" target=\"_blank\">https://www.itbulu.com/up-ubuntu-python37.html</a></p>\n<h3><a id=\"_491\"></a>本篇作者</h3>\n<p><img src=\"https://dev-media.amazoncloud.cn/ae2397ea6b774957b8eae38320efc091_image.png\" alt=\"image.png\" /><br />\n<strong>孙进华</strong><br />\n亚马逊云科技资深解决方案架构师,负责帮助客户进行上云架构的设计和咨询。加入 Amazon 前自主创业负责电商平台搭建和车企电商平台整体架构设计。曾就职于全球领先的通讯设备公司,担任高级工程师,负责 LTE 设备系统的多个子系统的开发与架构设计。在高并发、高可用系统架构设计、微服务架构设计、数据库、中间件、IOT 等方面有着丰富的经验。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/80fee0f8653844f993c08bf0bf5a93a1_image.png\" alt=\"image.png\" /><br />\n<strong>徐开</strong><br />\nAmazon 物联网实验室 解决方案架构师,主要负责物联网解决方案,致力于 Amazon IoT 相关技术的推广与应用</p>\n"}