Amazon Rekognition
Developer Guide

Analyzing a Video Stored in an Amazon S3 Bucket with Java or Python (SDK)

This procedure shows you how to detect labels in a video by using Amazon Rekognition Video label detection operations, a video stored in an Amazon S3 bucket, and an Amazon SNS topic. The procedure also shows how to use an Amazon SQS queue to get the completion status from the Amazon SNS topic. For more information, see Calling Amazon Rekognition Video Operations. You aren't restricted to using an Amazon SQS queue. For example, you can use an AWS Lambda function to get the completion status. For more information, see Invoking Lambda functions using Amazon SNS notifications.

The procedure shows you how to use the Amazon SNS console to do the following:

  • Create the Amazon SNS topic.

  • Create the Amazon SQS queue.

  • Give Amazon Rekognition Video permission to publish the completion status of a video analysis operation to the Amazon SNS topic.

  • Subscribe the Amazon SQS queue to the Amazon SNS topic.


This procedure uses a single Amazon SQS queue and a single Amazon SNS topic for all video analysis requests.

The example code in the procedure shows you how to do the following:

  1. Start the video analysis request by calling StartLabelDetection.

  2. Get the completion status from the Amazon SQS queue. The example tracks the job identifier (JobId) that's returned in StartLabelDetection and only gets the results for matching job identifiers that are read from the completion status. This is an important consideration if other applications are using the same queue and topic. For simplicity, the example deletes jobs that don't match. Consider adding them to an Amazon SQS dead-letter queue for further investigation.

  3. Get and display the video analysis results by calling GetLabelDetection.


To run this procedure, you need to have the AWS SDK for Java installed. For more information, see Getting Started with Amazon Rekognition. The AWS account that you use must have access permissions to the Amazon Rekognition API. For more information, see Amazon Rekognition API Permissions: Actions, Permissions, and Resources Reference.

To Detect Labels in a Video

  1. Configure user access to Amazon Rekognition Video and configure Amazon Rekognition Video access to Amazon SNS. For more information, see Configuring Amazon Rekognition Video.

  2. Create an Amazon SNS topic by using the Amazon SNS console. Prepend the topic name with AmazonRekognition. Note the topic Amazon Resource Name (ARN). Ensure the topic is in the same region as the AWS endpoint that you are using.

  3. Create an Amazon SQS standard queue by using the Amazon SQS console. Note the queue ARN.

  4. Subscribe the queue to the topic you created in step 2.

  5. Give permission to the Amazon SNS topic to send messages to the Amazon SQS queue.

  6. Upload an .mp4, .mov or .avi format video file to your S3 Bucket. For test purposes, upload a video that's no longer than 30 seconds in length.

    For instructions, see Uploading Objects into Amazon S3 in the Amazon Simple Storage Service Console User Guide.

  7. Use the following AWS SDK for Java code to detect labels in a video.

    • Replace topicArn, roleArn, and queueUrl with the Amazon SNS topic ARN, IAM role ARN, and Amazon SQS queue URL that you previously noted.

    • Replace the values of bucket and video with the bucket and video file name that you specified in step 6.

    //Copyright 2018, Inc. or its affiliates. All Rights Reserved. //PDX-License-Identifier: MIT-0 (For details, see package com.amazonaws.samples; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.*; public class VideoDetect { private static String bucket = ""; private static String video = ""; private static String queueUrl = ""; private static String topicArn=""; private static String roleArn=""; private static AmazonSQS sqs = null; private static AmazonRekognition rek = null; private static NotificationChannel channel= new NotificationChannel() .withSNSTopicArn(topicArn) .withRoleArn(roleArn); private static String startJobId = null; public static void main(String[] args) throws Exception{ sqs = AmazonSQSClientBuilder.defaultClient(); rek = AmazonRekognitionClientBuilder.defaultClient(); //================================================= StartLabels(bucket, video); //================================================= 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(queueUrl).getMessages(); if (dotLine++<20){ 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")){ //============================================ GetResultsLabels(); //============================================ } else{ System.out.println("Video analysis failed"); } sqs.deleteMessage(queueUrl,message.getReceiptHandle()); } else{ System.out.println("Job received was not job " + startJobId); //Delete unknown message. Consider moving message to dead letter queue sqs.deleteMessage(queueUrl,message.getReceiptHandle()); } } } } while (!jobFound); System.out.println("Done!"); } private static void StartLabels(String bucket, String video) throws Exception{ 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 GetResultsLabels() 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(); System.out.print("Millisecond: " + Long.toString(seconds) + " "); System.out.println("\t" + detectedLabel.getLabel().getName() + " \t" + detectedLabel.getLabel().getConfidence().toString()); System.out.println(); } } while (labelDetectionResult !=null && labelDetectionResult.getNextToken() != null); } }
    #Copyright 2018, Inc. or its affiliates. All Rights Reserved. #PDX-License-Identifier: MIT-0 (For details, see import boto3 import json import sys class VideoDetect: jobId = '' rek = boto3.client('rekognition') queueUrl = '' roleArn = '' topicArn = '' bucket = '' video = '' def main(self): jobFound = False sqs = boto3.client('sqs') #===================================== response = self.rek.start_label_detection(Video={'S3Object': {'Bucket': self.bucket, 'Name':}}, NotificationChannel={'RoleArn': self.roleArn, 'SNSTopicArn': self.topicArn}) #===================================== print('Start Job Id: ' + response['JobId']) dotLine=0 while jobFound == False: sqsResponse = sqs.receive_message(QueueUrl=self.queueUrl, MessageAttributeNames=['ALL'], MaxNumberOfMessages=10) if sqsResponse: if 'Messages' not in sqsResponse: if dotLine<20: print('.', end='') dotLine=dotLine+1 else: print() dotLine=0 sys.stdout.flush() continue for message in sqsResponse['Messages']: notification = json.loads(message['Body']) rekMessage = json.loads(notification['Message']) print(rekMessage['JobId']) print(rekMessage['Status']) if str(rekMessage['JobId']) == response['JobId']: print('Matching Job Found:' + rekMessage['JobId']) jobFound = True #============================================= self.GetResultsLabels(rekMessage['JobId']) #============================================= sqs.delete_message(QueueUrl=self.queueUrl, ReceiptHandle=message['ReceiptHandle']) else: print("Job didn't match:" + str(rekMessage['JobId']) + ' : ' + str(response['JobId'])) # Delete the unknown message. Consider sending to dead letter queue sqs.delete_message(QueueUrl=self.queueUrl, ReceiptHandle=message['ReceiptHandle']) print('done') def GetResultsLabels(self, jobId): maxResults = 10 paginationToken = '' finished = False while finished == False: response = self.rek.get_label_detection(JobId=jobId, MaxResults=maxResults, NextToken=paginationToken, SortBy='TIMESTAMP') print(response['VideoMetadata']['Codec']) print(str(response['VideoMetadata']['DurationMillis'])) print(response['VideoMetadata']['Format']) print(response['VideoMetadata']['FrameRate']) for labelDetection in response['Labels']: print(labelDetection['Label']['Name']) print(labelDetection['Label']['Confidence']) print(str(labelDetection['Timestamp'])) if 'NextToken' in response: paginationToken = response['NextToken'] else: finished = True if __name__ == "__main__": analyzer=VideoDetect() analyzer.main()
  8. Build and run the code. The operation might take a while to finish. After it's finished, a list of the labels detected in the video is displayed. For more information, see Detecting Labels in a Video.

On this page: