Java 또는 Python (SDK) 을 사용하여 Amazon S3 버킷에 저장된 비디오 분석 - Amazon Rekognition

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Java 또는 Python (SDK) 을 사용하여 Amazon S3 버킷에 저장된 비디오 분석

이 절차는 Amazon Rekognition Video 레이블 탐지 작업, Amazon S3 버킷에 저장된 비디오 및 Amazon 주제를 사용하여 비디오에서 레이블을 감지하는 방법을 보여줍니다. SNS 이 절차에서는 Amazon SQS 대기열을 사용하여 Amazon SNS 주제에서 완료 상태를 가져오는 방법도 보여줍니다. 자세한 내용은 Amazon Rekognition Video 작업 직접 호출 단원을 참조하십시오. Amazon SQS 대기열 사용에는 제한이 없습니다. 예를 들어 AWS Lambda 함수를 사용하여 완료 상태를 가져올 수 있습니다. 자세한 내용은 Amazon 알림을 사용한 Lambda 함수 호출을 참조하십시오. SNS

이 절차의 예제 코드는 다음을 실행하는 방법을 보여줍니다.

  1. Amazon SNS 주제를 생성하십시오.

  2. 아마존 SQS 대기열을 생성하십시오.

  3. Amazon Rekognition Video에 비디오 분석 작업의 완료 상태를 Amazon 주제에 게시할 권한을 부여하십시오. SNS

  4. Amazon SQS 대기열에서 Amazon SNS 주제를 구독하십시오.

  5. 전화를 걸어 동영상 분석 요청을 StartLabelDetection시작하세요.

  6. Amazon SQS 대기열에서 완료 상태를 가져옵니다. 이 예제는 StartLabelDetection에서 반환되는 작업 식별자(JobId)를 추적하여 완료 상태에서 판독되는 작업 식별자와 일치하는 결과만 가져옵니다. 이점은 다른 애플리케이션에서 동일한 대기열과 주제를 사용할 경우에 중요하게 고려해야 합니다. 간소화를 위해 이 예제에서는 일치하지 않는 작업을 삭제합니다. 추가 조사를 위해 Amazon SQS 데드레터 대기열에 추가하는 것을 고려해 보십시오.

  7. 전화를 걸어 비디오 분석 결과를 받아 표시하십시오. GetLabelDetection

사전 조건

이 절차에 대한 예제 코드는 Java 및 Python에 제공됩니다. 적절한 AWS SDK 설치가 필요합니다. 자세한 내용은 Amazon Rekognition 시작 단원을 참조하십시오. 사용하는 AWS 계정에는 Amazon API Rekognition에 대한 액세스 권한이 있어야 합니다. 자세한 내용은 Amazon Rekognition에서 정의한 작업을 참조하세요.

비디오에서 레이블을 감지하려면
  1. Amazon Rekognition Video에 대한 사용자 액세스를 구성하고 Amazon에 대한 Amazon Rekognition Video 액세스를 구성합니다. SNS 자세한 내용은 Amazon Rekognition Video 구성 단원을 참조하십시오. 예제 코드가 Amazon SNS 주제 및 Amazon 대기열을 생성하고 구성하므로 3, 4, 5, 6단계를 수행할 필요가 없습니다. SQS

  2. MOV또는 MPEG -4 형식의 비디오 파일을 Amazon S3 버킷에 업로드합니다. 테스트할 때는 30초 이하의 비디오를 업로드합니다.

    이에 관한 지침은 Amazon Simple Storage Service 사용 설명서에서 Amazon S3에 객체 업로드를 참조하세요.

  3. 다음 코드 예제를 사용하여 비디오에서 레이블을 감지합니다.

    Java

    main 함수에서 수행:

    • ARN의 Amazon Rekognition Video를 구성하려면 7단계에서 생성한 IAM 서비스 roleArn 역할로 대체하십시오.

    • bucketvideo 값을 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 함수에서 수행:

    • ARN의 7단계에서 만든 IAM 서비스 roleArn 역할로 Amazon Rekognition Video를 구성하려면 바꾸십시오.

    • bucketvideo 값을 2단계에서 지정한 버킷과 비디오 파일 이름으로 바꿉니다.

    • Rekognition 세션을 생성하는 라인에서 profile_name의 값을 개발자 프로필의 이름으로 대체합니다.

    • 설정 파라미터에 필터링 기준을 포함할 수도 있습니다. 예를 들어, LabelsInclusionFilter 또는 LabelsExclusionFilter를 원하는 값의 목록과 함께 사용할 수 있습니다. 아래 코드에서 Features and Settings 섹션의 주석을 제거하고 사용자가 원하는 값을 제공하여 반환되는 결과를 관심 있는 레이블로만 제한할 수 있습니다.

    • GetLabelDetection을 직접 호출할 때 SortByAggregateBy 인수의 값을 제공할 수 있습니다. 시간별로 정렬하려면 SortBy 입력 파라미터 값을 TIMESTAMP로 설정합니다. 엔터티별로 정렬하려면 SortBy 입력 파라미터를 수행할 작업에 해당하는 값과 함께 사용합니다. 타임스탬프 기준으로 결과를 집계하려면 AggregateBy 파라미터 값을 TIMESTAMPS로 설정합니다. 비디오 세그먼트 기준으로 집계하려면 SEGMENTS를 사용합니다.

    ## 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 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의 값을 계정의 운영 리전 이름으로 바꿉니다.

    • bucket의 값을 비디오 파일이 들어 있는 Amazon S3 버킷의 이름으로 바꿉니다.

    • videoName의 값을 Amazon S3 버킷에 들어 있는 비디오 파일 이름으로 바꿉니다.

    • Rekognition 세션을 생성하는 라인에서 profile_name의 값을 개발자 프로필의 이름으로 대체합니다.

    • ARN의 7단계에서 만든 IAM 서비스 roleArn 역할로 Amazon Rekognition Video를 구성하려면 바꾸십시오.

    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", 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 리포지토리에서 가져온 것입니다. 전체 예제는 여기에서 확인하세요.

    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, myBucket). \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] }
  4. 코드를 작성하고 실행합니다. 이 작업은 마치는 데 시간이 걸릴 수 있습니다. 작업이 끝나면 비디오에서 감지된 레이블 목록이 표시됩니다. 자세한 내용은 비디오에서 레이블 감지 단원을 참조하십시오.