diff --git a/video/cloud-client/analyze/analyze.py b/video/cloud-client/analyze/analyze.py index d7e590928be..75bf3248a67 100644 --- a/video/cloud-client/analyze/analyze.py +++ b/video/cloud-client/analyze/analyze.py @@ -45,17 +45,17 @@ def analyze_explicit_content(path): features = [videointelligence.enums.Feature.EXPLICIT_CONTENT_DETECTION] operation = video_client.annotate_video(path, features=features) - print('\nProcessing video for explicit content annotations:') + print("\nProcessing video for explicit content annotations:") result = operation.result(timeout=90) - print('\nFinished processing.') + print("\nFinished processing.") # first result is retrieved because a single video was processed for frame in result.annotation_results[0].explicit_annotation.frames: likelihood = enums.Likelihood(frame.pornography_likelihood) frame_time = frame.time_offset.seconds + frame.time_offset.nanos / 1e9 - print('Time: {}s'.format(frame_time)) - print('\tpornography: {}'.format(likelihood.name)) + print("Time: {}s".format(frame_time)) + print("\tpornography: {}".format(likelihood.name)) # [END video_analyze_explicit_content] @@ -66,75 +66,81 @@ def analyze_labels(path): features = [videointelligence.enums.Feature.LABEL_DETECTION] mode = videointelligence.enums.LabelDetectionMode.SHOT_AND_FRAME_MODE - config = videointelligence.types.LabelDetectionConfig( - label_detection_mode=mode) - context = videointelligence.types.VideoContext( - label_detection_config=config) + config = videointelligence.types.LabelDetectionConfig(label_detection_mode=mode) + context = videointelligence.types.VideoContext(label_detection_config=config) operation = video_client.annotate_video( - path, features=features, video_context=context) - print('\nProcessing video for label annotations:') + path, features=features, video_context=context + ) + print("\nProcessing video for label annotations:") result = operation.result(timeout=180) - print('\nFinished processing.') + print("\nFinished processing.") # Process video/segment level label annotations segment_labels = result.annotation_results[0].segment_label_annotations for i, segment_label in enumerate(segment_labels): - print('Video label description: {}'.format( - segment_label.entity.description)) + print("Video label description: {}".format(segment_label.entity.description)) for category_entity in segment_label.category_entities: - print('\tLabel category description: {}'.format( - category_entity.description)) + print( + "\tLabel category description: {}".format(category_entity.description) + ) for i, segment in enumerate(segment_label.segments): - start_time = (segment.segment.start_time_offset.seconds + - segment.segment.start_time_offset.nanos / 1e9) - end_time = (segment.segment.end_time_offset.seconds + - segment.segment.end_time_offset.nanos / 1e9) - positions = '{}s to {}s'.format(start_time, end_time) + start_time = ( + segment.segment.start_time_offset.seconds + + segment.segment.start_time_offset.nanos / 1e9 + ) + end_time = ( + segment.segment.end_time_offset.seconds + + segment.segment.end_time_offset.nanos / 1e9 + ) + positions = "{}s to {}s".format(start_time, end_time) confidence = segment.confidence - print('\tSegment {}: {}'.format(i, positions)) - print('\tConfidence: {}'.format(confidence)) - print('\n') + print("\tSegment {}: {}".format(i, positions)) + print("\tConfidence: {}".format(confidence)) + print("\n") # Process shot level label annotations shot_labels = result.annotation_results[0].shot_label_annotations for i, shot_label in enumerate(shot_labels): - print('Shot label description: {}'.format( - shot_label.entity.description)) + print("Shot label description: {}".format(shot_label.entity.description)) for category_entity in shot_label.category_entities: - print('\tLabel category description: {}'.format( - category_entity.description)) + print( + "\tLabel category description: {}".format(category_entity.description) + ) for i, shot in enumerate(shot_label.segments): - start_time = (shot.segment.start_time_offset.seconds + - shot.segment.start_time_offset.nanos / 1e9) - end_time = (shot.segment.end_time_offset.seconds + - shot.segment.end_time_offset.nanos / 1e9) - positions = '{}s to {}s'.format(start_time, end_time) + start_time = ( + shot.segment.start_time_offset.seconds + + shot.segment.start_time_offset.nanos / 1e9 + ) + end_time = ( + shot.segment.end_time_offset.seconds + + shot.segment.end_time_offset.nanos / 1e9 + ) + positions = "{}s to {}s".format(start_time, end_time) confidence = shot.confidence - print('\tSegment {}: {}'.format(i, positions)) - print('\tConfidence: {}'.format(confidence)) - print('\n') + print("\tSegment {}: {}".format(i, positions)) + print("\tConfidence: {}".format(confidence)) + print("\n") # Process frame level label annotations frame_labels = result.annotation_results[0].frame_label_annotations for i, frame_label in enumerate(frame_labels): - print('Frame label description: {}'.format( - frame_label.entity.description)) + print("Frame label description: {}".format(frame_label.entity.description)) for category_entity in frame_label.category_entities: - print('\tLabel category description: {}'.format( - category_entity.description)) + print( + "\tLabel category description: {}".format(category_entity.description) + ) # Each frame_label_annotation has many frames, # here we print information only about the first frame. frame = frame_label.frames[0] - time_offset = (frame.time_offset.seconds + - frame.time_offset.nanos / 1e9) - print('\tFirst frame time offset: {}s'.format(time_offset)) - print('\tFirst frame confidence: {}'.format(frame.confidence)) - print('\n') + time_offset = frame.time_offset.seconds + frame.time_offset.nanos / 1e9 + print("\tFirst frame time offset: {}s".format(time_offset)) + print("\tFirst frame confidence: {}".format(frame.confidence)) + print("\n") # [END video_analyze_labels_gcs] @@ -144,72 +150,81 @@ def analyze_labels_file(path): video_client = videointelligence.VideoIntelligenceServiceClient() features = [videointelligence.enums.Feature.LABEL_DETECTION] - with io.open(path, 'rb') as movie: + with io.open(path, "rb") as movie: input_content = movie.read() operation = video_client.annotate_video( - features=features, input_content=input_content) - print('\nProcessing video for label annotations:') + features=features, input_content=input_content + ) + print("\nProcessing video for label annotations:") result = operation.result(timeout=90) - print('\nFinished processing.') + print("\nFinished processing.") # Process video/segment level label annotations segment_labels = result.annotation_results[0].segment_label_annotations for i, segment_label in enumerate(segment_labels): - print('Video label description: {}'.format( - segment_label.entity.description)) + print("Video label description: {}".format(segment_label.entity.description)) for category_entity in segment_label.category_entities: - print('\tLabel category description: {}'.format( - category_entity.description)) + print( + "\tLabel category description: {}".format(category_entity.description) + ) for i, segment in enumerate(segment_label.segments): - start_time = (segment.segment.start_time_offset.seconds + - segment.segment.start_time_offset.nanos / 1e9) - end_time = (segment.segment.end_time_offset.seconds + - segment.segment.end_time_offset.nanos / 1e9) - positions = '{}s to {}s'.format(start_time, end_time) + start_time = ( + segment.segment.start_time_offset.seconds + + segment.segment.start_time_offset.nanos / 1e9 + ) + end_time = ( + segment.segment.end_time_offset.seconds + + segment.segment.end_time_offset.nanos / 1e9 + ) + positions = "{}s to {}s".format(start_time, end_time) confidence = segment.confidence - print('\tSegment {}: {}'.format(i, positions)) - print('\tConfidence: {}'.format(confidence)) - print('\n') + print("\tSegment {}: {}".format(i, positions)) + print("\tConfidence: {}".format(confidence)) + print("\n") # Process shot level label annotations shot_labels = result.annotation_results[0].shot_label_annotations for i, shot_label in enumerate(shot_labels): - print('Shot label description: {}'.format( - shot_label.entity.description)) + print("Shot label description: {}".format(shot_label.entity.description)) for category_entity in shot_label.category_entities: - print('\tLabel category description: {}'.format( - category_entity.description)) + print( + "\tLabel category description: {}".format(category_entity.description) + ) for i, shot in enumerate(shot_label.segments): - start_time = (shot.segment.start_time_offset.seconds + - shot.segment.start_time_offset.nanos / 1e9) - end_time = (shot.segment.end_time_offset.seconds + - shot.segment.end_time_offset.nanos / 1e9) - positions = '{}s to {}s'.format(start_time, end_time) + start_time = ( + shot.segment.start_time_offset.seconds + + shot.segment.start_time_offset.nanos / 1e9 + ) + end_time = ( + shot.segment.end_time_offset.seconds + + shot.segment.end_time_offset.nanos / 1e9 + ) + positions = "{}s to {}s".format(start_time, end_time) confidence = shot.confidence - print('\tSegment {}: {}'.format(i, positions)) - print('\tConfidence: {}'.format(confidence)) - print('\n') + print("\tSegment {}: {}".format(i, positions)) + print("\tConfidence: {}".format(confidence)) + print("\n") # Process frame level label annotations frame_labels = result.annotation_results[0].frame_label_annotations for i, frame_label in enumerate(frame_labels): - print('Frame label description: {}'.format( - frame_label.entity.description)) + print("Frame label description: {}".format(frame_label.entity.description)) for category_entity in frame_label.category_entities: - print('\tLabel category description: {}'.format( - category_entity.description)) + print( + "\tLabel category description: {}".format(category_entity.description) + ) # Each frame_label_annotation has many frames, # here we print information only about the first frame. frame = frame_label.frames[0] time_offset = frame.time_offset.seconds + frame.time_offset.nanos / 1e9 - print('\tFirst frame time offset: {}s'.format(time_offset)) - print('\tFirst frame confidence: {}'.format(frame.confidence)) - print('\n') + print("\tFirst frame time offset: {}s".format(time_offset)) + print("\tFirst frame confidence: {}".format(frame.confidence)) + print("\n") # [END video_analyze_labels] @@ -219,18 +234,16 @@ def analyze_shots(path): video_client = videointelligence.VideoIntelligenceServiceClient() features = [videointelligence.enums.Feature.SHOT_CHANGE_DETECTION] operation = video_client.annotate_video(path, features=features) - print('\nProcessing video for shot change annotations:') + print("\nProcessing video for shot change annotations:") result = operation.result(timeout=90) - print('\nFinished processing.') + print("\nFinished processing.") # first result is retrieved because a single video was processed for i, shot in enumerate(result.annotation_results[0].shot_annotations): - start_time = (shot.start_time_offset.seconds + - shot.start_time_offset.nanos / 1e9) - end_time = (shot.end_time_offset.seconds + - shot.end_time_offset.nanos / 1e9) - print('\tShot {}: {} to {}'.format(i, start_time, end_time)) + start_time = shot.start_time_offset.seconds + shot.start_time_offset.nanos / 1e9 + end_time = shot.end_time_offset.seconds + shot.end_time_offset.nanos / 1e9 + print("\tShot {}: {} to {}".format(i, start_time, end_time)) # [END video_analyze_shots] @@ -243,16 +256,17 @@ def speech_transcription(path): features = [videointelligence.enums.Feature.SPEECH_TRANSCRIPTION] config = videointelligence.types.SpeechTranscriptionConfig( - language_code='en-US', - enable_automatic_punctuation=True) + language_code="en-US", enable_automatic_punctuation=True + ) video_context = videointelligence.types.VideoContext( - speech_transcription_config=config) + speech_transcription_config=config + ) operation = video_client.annotate_video( - path, features=features, - video_context=video_context) + path, features=features, video_context=video_context + ) - print('\nProcessing video for speech transcription.') + print("\nProcessing video for speech transcription.") result = operation.result(timeout=600) @@ -266,20 +280,23 @@ def speech_transcription(path): # Each alternative is a different possible transcription # and has its own confidence score. for alternative in speech_transcription.alternatives: - print('Alternative level information:') + print("Alternative level information:") - print('Transcript: {}'.format(alternative.transcript)) - print('Confidence: {}\n'.format(alternative.confidence)) + print("Transcript: {}".format(alternative.transcript)) + print("Confidence: {}\n".format(alternative.confidence)) - print('Word level information:') + print("Word level information:") for word_info in alternative.words: word = word_info.word start_time = word_info.start_time end_time = word_info.end_time - print('\t{}s - {}s: {}'.format( - start_time.seconds + start_time.nanos * 1e-9, - end_time.seconds + end_time.nanos * 1e-9, - word)) + print( + "\t{}s - {}s: {}".format( + start_time.seconds + start_time.nanos * 1e-9, + end_time.seconds + end_time.nanos * 1e-9, + word, + ) + ) # [END video_speech_transcription_gcs] @@ -291,37 +308,41 @@ def video_detect_text_gcs(input_uri): video_client = videointelligence.VideoIntelligenceServiceClient() features = [videointelligence.enums.Feature.TEXT_DETECTION] - operation = video_client.annotate_video( - input_uri=input_uri, - features=features) + operation = video_client.annotate_video(input_uri=input_uri, features=features) - print('\nProcessing video for text detection.') + print("\nProcessing video for text detection.") result = operation.result(timeout=600) # The first result is retrieved because a single video was processed. annotation_result = result.annotation_results[0] for text_annotation in annotation_result.text_annotations: - print('\nText: {}'.format(text_annotation.text)) + print("\nText: {}".format(text_annotation.text)) # Get the first text segment text_segment = text_annotation.segments[0] start_time = text_segment.segment.start_time_offset end_time = text_segment.segment.end_time_offset - print('start_time: {}, end_time: {}'.format( - start_time.seconds + start_time.nanos * 1e-9, - end_time.seconds + end_time.nanos * 1e-9)) + print( + "start_time: {}, end_time: {}".format( + start_time.seconds + start_time.nanos * 1e-9, + end_time.seconds + end_time.nanos * 1e-9, + ) + ) - print('Confidence: {}'.format(text_segment.confidence)) + print("Confidence: {}".format(text_segment.confidence)) # Show the result for the first frame in this segment. frame = text_segment.frames[0] time_offset = frame.time_offset - print('Time offset for the first frame: {}'.format( - time_offset.seconds + time_offset.nanos * 1e-9)) - print('Rotated Bounding Box Vertices:') + print( + "Time offset for the first frame: {}".format( + time_offset.seconds + time_offset.nanos * 1e-9 + ) + ) + print("Rotated Bounding Box Vertices:") for vertex in frame.rotated_bounding_box.vertices: - print('\tVertex.x: {}, Vertex.y: {}'.format(vertex.x, vertex.y)) + print("\tVertex.x: {}, Vertex.y: {}".format(vertex.x, vertex.y)) # [END video_detect_text_gcs] @@ -334,41 +355,48 @@ def video_detect_text(path): features = [videointelligence.enums.Feature.TEXT_DETECTION] video_context = videointelligence.types.VideoContext() - with io.open(path, 'rb') as file: + with io.open(path, "rb") as file: input_content = file.read() operation = video_client.annotate_video( input_content=input_content, # the bytes of the video file features=features, - video_context=video_context) + video_context=video_context, + ) - print('\nProcessing video for text detection.') + print("\nProcessing video for text detection.") result = operation.result(timeout=300) # The first result is retrieved because a single video was processed. annotation_result = result.annotation_results[0] for text_annotation in annotation_result.text_annotations: - print('\nText: {}'.format(text_annotation.text)) + print("\nText: {}".format(text_annotation.text)) # Get the first text segment text_segment = text_annotation.segments[0] start_time = text_segment.segment.start_time_offset end_time = text_segment.segment.end_time_offset - print('start_time: {}, end_time: {}'.format( - start_time.seconds + start_time.nanos * 1e-9, - end_time.seconds + end_time.nanos * 1e-9)) + print( + "start_time: {}, end_time: {}".format( + start_time.seconds + start_time.nanos * 1e-9, + end_time.seconds + end_time.nanos * 1e-9, + ) + ) - print('Confidence: {}'.format(text_segment.confidence)) + print("Confidence: {}".format(text_segment.confidence)) # Show the result for the first frame in this segment. frame = text_segment.frames[0] time_offset = frame.time_offset - print('Time offset for the first frame: {}'.format( - time_offset.seconds + time_offset.nanos * 1e-9)) - print('Rotated Bounding Box Vertices:') + print( + "Time offset for the first frame: {}".format( + time_offset.seconds + time_offset.nanos * 1e-9 + ) + ) + print("Rotated Bounding Box Vertices:") for vertex in frame.rotated_bounding_box.vertices: - print('\tVertex.x: {}, Vertex.y: {}'.format(vertex.x, vertex.y)) + print("\tVertex.x: {}, Vertex.y: {}".format(vertex.x, vertex.y)) # [END video_detect_text] @@ -379,41 +407,45 @@ def track_objects_gcs(gcs_uri): video_client = videointelligence.VideoIntelligenceServiceClient() features = [videointelligence.enums.Feature.OBJECT_TRACKING] - operation = video_client.annotate_video( - input_uri=gcs_uri, features=features) - print('\nProcessing video for object annotations.') + operation = video_client.annotate_video(input_uri=gcs_uri, features=features) + print("\nProcessing video for object annotations.") result = operation.result(timeout=300) - print('\nFinished processing.\n') + print("\nFinished processing.\n") # The first result is retrieved because a single video was processed. object_annotations = result.annotation_results[0].object_annotations for object_annotation in object_annotations: - print('Entity description: {}'.format( - object_annotation.entity.description)) + print("Entity description: {}".format(object_annotation.entity.description)) if object_annotation.entity.entity_id: - print('Entity id: {}'.format(object_annotation.entity.entity_id)) + print("Entity id: {}".format(object_annotation.entity.entity_id)) - print('Segment: {}s to {}s'.format( - object_annotation.segment.start_time_offset.seconds + - object_annotation.segment.start_time_offset.nanos / 1e9, - object_annotation.segment.end_time_offset.seconds + - object_annotation.segment.end_time_offset.nanos / 1e9)) + print( + "Segment: {}s to {}s".format( + object_annotation.segment.start_time_offset.seconds + + object_annotation.segment.start_time_offset.nanos / 1e9, + object_annotation.segment.end_time_offset.seconds + + object_annotation.segment.end_time_offset.nanos / 1e9, + ) + ) - print('Confidence: {}'.format(object_annotation.confidence)) + print("Confidence: {}".format(object_annotation.confidence)) # Here we print only the bounding box of the first frame in the segment frame = object_annotation.frames[0] box = frame.normalized_bounding_box - print('Time offset of the first frame: {}s'.format( - frame.time_offset.seconds + frame.time_offset.nanos / 1e9)) - print('Bounding box position:') - print('\tleft : {}'.format(box.left)) - print('\ttop : {}'.format(box.top)) - print('\tright : {}'.format(box.right)) - print('\tbottom: {}'.format(box.bottom)) - print('\n') + print( + "Time offset of the first frame: {}s".format( + frame.time_offset.seconds + frame.time_offset.nanos / 1e9 + ) + ) + print("Bounding box position:") + print("\tleft : {}".format(box.left)) + print("\ttop : {}".format(box.top)) + print("\tright : {}".format(box.right)) + print("\tbottom: {}".format(box.bottom)) + print("\n") # [END video_object_tracking_gcs] @@ -425,107 +457,118 @@ def track_objects(path): video_client = videointelligence.VideoIntelligenceServiceClient() features = [videointelligence.enums.Feature.OBJECT_TRACKING] - with io.open(path, 'rb') as file: + with io.open(path, "rb") as file: input_content = file.read() operation = video_client.annotate_video( - input_content=input_content, features=features) - print('\nProcessing video for object annotations.') + input_content=input_content, features=features + ) + print("\nProcessing video for object annotations.") result = operation.result(timeout=300) - print('\nFinished processing.\n') + print("\nFinished processing.\n") # The first result is retrieved because a single video was processed. object_annotations = result.annotation_results[0].object_annotations # Get only the first annotation for demo purposes. object_annotation = object_annotations[0] - print('Entity description: {}'.format( - object_annotation.entity.description)) + print("Entity description: {}".format(object_annotation.entity.description)) if object_annotation.entity.entity_id: - print('Entity id: {}'.format(object_annotation.entity.entity_id)) + print("Entity id: {}".format(object_annotation.entity.entity_id)) - print('Segment: {}s to {}s'.format( - object_annotation.segment.start_time_offset.seconds + - object_annotation.segment.start_time_offset.nanos / 1e9, - object_annotation.segment.end_time_offset.seconds + - object_annotation.segment.end_time_offset.nanos / 1e9)) + print( + "Segment: {}s to {}s".format( + object_annotation.segment.start_time_offset.seconds + + object_annotation.segment.start_time_offset.nanos / 1e9, + object_annotation.segment.end_time_offset.seconds + + object_annotation.segment.end_time_offset.nanos / 1e9, + ) + ) - print('Confidence: {}'.format(object_annotation.confidence)) + print("Confidence: {}".format(object_annotation.confidence)) # Here we print only the bounding box of the first frame in this segment frame = object_annotation.frames[0] box = frame.normalized_bounding_box - print('Time offset of the first frame: {}s'.format( - frame.time_offset.seconds + frame.time_offset.nanos / 1e9)) - print('Bounding box position:') - print('\tleft : {}'.format(box.left)) - print('\ttop : {}'.format(box.top)) - print('\tright : {}'.format(box.right)) - print('\tbottom: {}'.format(box.bottom)) - print('\n') + print( + "Time offset of the first frame: {}s".format( + frame.time_offset.seconds + frame.time_offset.nanos / 1e9 + ) + ) + print("Bounding box position:") + print("\tleft : {}".format(box.left)) + print("\ttop : {}".format(box.top)) + print("\tright : {}".format(box.right)) + print("\tbottom: {}".format(box.bottom)) + print("\n") # [END video_object_tracking] -if __name__ == '__main__': +if __name__ == "__main__": parser = argparse.ArgumentParser( - description=__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter) - subparsers = parser.add_subparsers(dest='command') + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + subparsers = parser.add_subparsers(dest="command") - analyze_labels_parser = subparsers.add_parser( - 'labels', help=analyze_labels.__doc__) - analyze_labels_parser.add_argument('path') + analyze_labels_parser = subparsers.add_parser("labels", help=analyze_labels.__doc__) + analyze_labels_parser.add_argument("path") analyze_labels_file_parser = subparsers.add_parser( - 'labels_file', help=analyze_labels_file.__doc__) - analyze_labels_file_parser.add_argument('path') + "labels_file", help=analyze_labels_file.__doc__ + ) + analyze_labels_file_parser.add_argument("path") analyze_explicit_content_parser = subparsers.add_parser( - 'explicit_content', help=analyze_explicit_content.__doc__) - analyze_explicit_content_parser.add_argument('path') + "explicit_content", help=analyze_explicit_content.__doc__ + ) + analyze_explicit_content_parser.add_argument("path") - analyze_shots_parser = subparsers.add_parser( - 'shots', help=analyze_shots.__doc__) - analyze_shots_parser.add_argument('path') + analyze_shots_parser = subparsers.add_parser("shots", help=analyze_shots.__doc__) + analyze_shots_parser.add_argument("path") transcribe_speech_parser = subparsers.add_parser( - 'transcribe', help=speech_transcription.__doc__) - transcribe_speech_parser.add_argument('path') + "transcribe", help=speech_transcription.__doc__ + ) + transcribe_speech_parser.add_argument("path") detect_text_parser = subparsers.add_parser( - 'text_gcs', help=video_detect_text_gcs.__doc__) - detect_text_parser.add_argument('path') + "text_gcs", help=video_detect_text_gcs.__doc__ + ) + detect_text_parser.add_argument("path") detect_text_file_parser = subparsers.add_parser( - 'text_file', help=video_detect_text.__doc__) - detect_text_file_parser.add_argument('path') + "text_file", help=video_detect_text.__doc__ + ) + detect_text_file_parser.add_argument("path") tack_objects_parser = subparsers.add_parser( - 'objects_gcs', help=track_objects_gcs.__doc__) - tack_objects_parser.add_argument('path') + "objects_gcs", help=track_objects_gcs.__doc__ + ) + tack_objects_parser.add_argument("path") tack_objects_file_parser = subparsers.add_parser( - 'objects_file', help=track_objects.__doc__) - tack_objects_file_parser.add_argument('path') + "objects_file", help=track_objects.__doc__ + ) + tack_objects_file_parser.add_argument("path") args = parser.parse_args() - if args.command == 'labels': + if args.command == "labels": analyze_labels(args.path) - if args.command == 'labels_file': + if args.command == "labels_file": analyze_labels_file(args.path) - if args.command == 'shots': + if args.command == "shots": analyze_shots(args.path) - if args.command == 'explicit_content': + if args.command == "explicit_content": analyze_explicit_content(args.path) - if args.command == 'transcribe': + if args.command == "transcribe": speech_transcription(args.path) - if args.command == 'text_gcs': + if args.command == "text_gcs": video_detect_text_gcs(args.path) - if args.command == 'text_file': + if args.command == "text_file": video_detect_text(args.path) - if args.command == 'objects_gcs': + if args.command == "objects_gcs": track_objects_gcs(args.path) - if args.command == 'objects_file': + if args.command == "objects_file": track_objects(args.path) diff --git a/video/cloud-client/analyze/analyze_test.py b/video/cloud-client/analyze/analyze_test.py index 7624c2dfd6c..c66de346f08 100644 --- a/video/cloud-client/analyze/analyze_test.py +++ b/video/cloud-client/analyze/analyze_test.py @@ -18,43 +18,53 @@ import analyze -POSSIBLE_TEXTS = ['Google', 'SUR', 'SUR', 'ROTO', 'Vice President', '58oo9', - 'LONDRES', 'OMAR', 'PARIS', 'METRO', 'RUE', 'CARLO'] +POSSIBLE_TEXTS = [ + "Google", + "SUR", + "SUR", + "ROTO", + "Vice President", + "58oo9", + "LONDRES", + "OMAR", + "PARIS", + "METRO", + "RUE", + "CARLO", +] @pytest.mark.slow def test_analyze_shots(capsys): - analyze.analyze_shots('gs://cloud-samples-data/video/gbikes_dinosaur.mp4') + analyze.analyze_shots("gs://cloud-samples-data/video/gbikes_dinosaur.mp4") out, _ = capsys.readouterr() - assert 'Shot 1:' in out + assert "Shot 1:" in out @pytest.mark.slow def test_analyze_labels(capsys): - analyze.analyze_labels('gs://cloud-samples-data/video/cat.mp4') + analyze.analyze_labels("gs://cloud-samples-data/video/cat.mp4") out, _ = capsys.readouterr() - assert 'label description: cat' in out + assert "label description: cat" in out @pytest.mark.slow def test_analyze_explicit_content(capsys): - analyze.analyze_explicit_content('gs://cloud-samples-data/video/cat.mp4') + analyze.analyze_explicit_content("gs://cloud-samples-data/video/cat.mp4") out, _ = capsys.readouterr() - assert 'pornography' in out + assert "pornography" in out @pytest.mark.slow def test_speech_transcription(capsys): - analyze.speech_transcription( - 'gs://cloud-samples-data/video/googlework_short.mp4') + analyze.speech_transcription("gs://cloud-samples-data/video/googlework_short.mp4") out, _ = capsys.readouterr() - assert 'cultural' in out + assert "cultural" in out @pytest.mark.slow def test_detect_text_gcs(capsys): - analyze.video_detect_text_gcs( - 'gs://cloud-samples-data/video/googlework_tiny.mp4') + analyze.video_detect_text_gcs("gs://cloud-samples-data/video/googlework_tiny.mp4") out, _ = capsys.readouterr() text_exists = False @@ -67,7 +77,6 @@ def test_detect_text_gcs(capsys): @pytest.mark.slow def test_track_objects_gcs(capsys): - analyze.track_objects_gcs( - 'gs://cloud-samples-data/video/cat.mp4') + analyze.track_objects_gcs("gs://cloud-samples-data/video/cat.mp4") out, _ = capsys.readouterr() - assert 'cat' in out + assert "cat" in out diff --git a/video/cloud-client/analyze/beta_snippets.py b/video/cloud-client/analyze/beta_snippets.py index 3738a568949..05f3741e1c5 100644 --- a/video/cloud-client/analyze/beta_snippets.py +++ b/video/cloud-client/analyze/beta_snippets.py @@ -55,16 +55,17 @@ def speech_transcription(input_uri): features = [videointelligence.enums.Feature.SPEECH_TRANSCRIPTION] config = videointelligence.types.SpeechTranscriptionConfig( - language_code='en-US', - enable_automatic_punctuation=True) + language_code="en-US", enable_automatic_punctuation=True + ) video_context = videointelligence.types.VideoContext( - speech_transcription_config=config) + speech_transcription_config=config + ) operation = video_client.annotate_video( - input_uri, features=features, - video_context=video_context) + input_uri, features=features, video_context=video_context + ) - print('\nProcessing video for speech transcription.') + print("\nProcessing video for speech transcription.") result = operation.result(timeout=180) @@ -78,20 +79,23 @@ def speech_transcription(input_uri): # Each alternative is a different possible transcription # and has its own confidence score. for alternative in speech_transcription.alternatives: - print('Alternative level information:') + print("Alternative level information:") - print('Transcript: {}'.format(alternative.transcript)) - print('Confidence: {}\n'.format(alternative.confidence)) + print("Transcript: {}".format(alternative.transcript)) + print("Confidence: {}\n".format(alternative.confidence)) - print('Word level information:') + print("Word level information:") for word_info in alternative.words: word = word_info.word start_time = word_info.start_time end_time = word_info.end_time - print('\t{}s - {}s: {}'.format( - start_time.seconds + start_time.nanos * 1e-9, - end_time.seconds + end_time.nanos * 1e-9, - word)) + print( + "\t{}s - {}s: {}".format( + start_time.seconds + start_time.nanos * 1e-9, + end_time.seconds + end_time.nanos * 1e-9, + word, + ) + ) # [END video_speech_transcription_gcs_beta] @@ -103,11 +107,9 @@ def video_detect_text_gcs(input_uri): video_client = videointelligence.VideoIntelligenceServiceClient() features = [videointelligence.enums.Feature.TEXT_DETECTION] - operation = video_client.annotate_video( - input_uri=input_uri, - features=features) + operation = video_client.annotate_video(input_uri=input_uri, features=features) - print('\nProcessing video for text detection.') + print("\nProcessing video for text detection.") result = operation.result(timeout=300) # The first result is retrieved because a single video was processed. @@ -115,26 +117,32 @@ def video_detect_text_gcs(input_uri): # Get only the first result text_annotation = annotation_result.text_annotations[0] - print('\nText: {}'.format(text_annotation.text)) + print("\nText: {}".format(text_annotation.text)) # Get the first text segment text_segment = text_annotation.segments[0] start_time = text_segment.segment.start_time_offset end_time = text_segment.segment.end_time_offset - print('start_time: {}, end_time: {}'.format( - start_time.seconds + start_time.nanos * 1e-9, - end_time.seconds + end_time.nanos * 1e-9)) + print( + "start_time: {}, end_time: {}".format( + start_time.seconds + start_time.nanos * 1e-9, + end_time.seconds + end_time.nanos * 1e-9, + ) + ) - print('Confidence: {}'.format(text_segment.confidence)) + print("Confidence: {}".format(text_segment.confidence)) # Show the result for the first frame in this segment. frame = text_segment.frames[0] time_offset = frame.time_offset - print('Time offset for the first frame: {}'.format( - time_offset.seconds + time_offset.nanos * 1e-9)) - print('Rotated Bounding Box Vertices:') + print( + "Time offset for the first frame: {}".format( + time_offset.seconds + time_offset.nanos * 1e-9 + ) + ) + print("Rotated Bounding Box Vertices:") for vertex in frame.rotated_bounding_box.vertices: - print('\tVertex.x: {}, Vertex.y: {}'.format(vertex.x, vertex.y)) + print("\tVertex.x: {}, Vertex.y: {}".format(vertex.x, vertex.y)) # [END video_detect_text_gcs_beta] return annotation_result.text_annotations @@ -148,15 +156,16 @@ def video_detect_text(path): features = [videointelligence.enums.Feature.TEXT_DETECTION] video_context = videointelligence.types.VideoContext() - with io.open(path, 'rb') as file: + with io.open(path, "rb") as file: input_content = file.read() operation = video_client.annotate_video( input_content=input_content, # the bytes of the video file features=features, - video_context=video_context) + video_context=video_context, + ) - print('\nProcessing video for text detection.') + print("\nProcessing video for text detection.") result = operation.result(timeout=300) # The first result is retrieved because a single video was processed. @@ -164,26 +173,32 @@ def video_detect_text(path): # Get only the first result text_annotation = annotation_result.text_annotations[0] - print('\nText: {}'.format(text_annotation.text)) + print("\nText: {}".format(text_annotation.text)) # Get the first text segment text_segment = text_annotation.segments[0] start_time = text_segment.segment.start_time_offset end_time = text_segment.segment.end_time_offset - print('start_time: {}, end_time: {}'.format( - start_time.seconds + start_time.nanos * 1e-9, - end_time.seconds + end_time.nanos * 1e-9)) + print( + "start_time: {}, end_time: {}".format( + start_time.seconds + start_time.nanos * 1e-9, + end_time.seconds + end_time.nanos * 1e-9, + ) + ) - print('Confidence: {}'.format(text_segment.confidence)) + print("Confidence: {}".format(text_segment.confidence)) # Show the result for the first frame in this segment. frame = text_segment.frames[0] time_offset = frame.time_offset - print('Time offset for the first frame: {}'.format( - time_offset.seconds + time_offset.nanos * 1e-9)) - print('Rotated Bounding Box Vertices:') + print( + "Time offset for the first frame: {}".format( + time_offset.seconds + time_offset.nanos * 1e-9 + ) + ) + print("Rotated Bounding Box Vertices:") for vertex in frame.rotated_bounding_box.vertices: - print('\tVertex.x: {}, Vertex.y: {}'.format(vertex.x, vertex.y)) + print("\tVertex.x: {}, Vertex.y: {}".format(vertex.x, vertex.y)) # [END video_detect_text_beta] return annotation_result.text_annotations @@ -198,11 +213,12 @@ def track_objects_gcs(gcs_uri): video_client = videointelligence.VideoIntelligenceServiceClient() features = [videointelligence.enums.Feature.OBJECT_TRACKING] operation = video_client.annotate_video( - input_uri=gcs_uri, features=features, location_id='us-east1') - print('\nProcessing video for object annotations.') + input_uri=gcs_uri, features=features, location_id="us-east1" + ) + print("\nProcessing video for object annotations.") result = operation.result(timeout=300) - print('\nFinished processing.\n') + print("\nFinished processing.\n") # The first result is retrieved because a single video was processed. object_annotations = result.annotation_results[0].object_annotations @@ -210,30 +226,35 @@ def track_objects_gcs(gcs_uri): # Get only the first annotation for demo purposes. object_annotation = object_annotations[0] # description is in Unicode - print(u'Entity description: {}'.format( - object_annotation.entity.description)) + print(u"Entity description: {}".format(object_annotation.entity.description)) if object_annotation.entity.entity_id: - print('Entity id: {}'.format(object_annotation.entity.entity_id)) + print("Entity id: {}".format(object_annotation.entity.entity_id)) - print('Segment: {}s to {}s'.format( - object_annotation.segment.start_time_offset.seconds + - object_annotation.segment.start_time_offset.nanos / 1e9, - object_annotation.segment.end_time_offset.seconds + - object_annotation.segment.end_time_offset.nanos / 1e9)) + print( + "Segment: {}s to {}s".format( + object_annotation.segment.start_time_offset.seconds + + object_annotation.segment.start_time_offset.nanos / 1e9, + object_annotation.segment.end_time_offset.seconds + + object_annotation.segment.end_time_offset.nanos / 1e9, + ) + ) - print('Confidence: {}'.format(object_annotation.confidence)) + print("Confidence: {}".format(object_annotation.confidence)) # Here we print only the bounding box of the first frame in this segment frame = object_annotation.frames[0] box = frame.normalized_bounding_box - print('Time offset of the first frame: {}s'.format( - frame.time_offset.seconds + frame.time_offset.nanos / 1e9)) - print('Bounding box position:') - print('\tleft : {}'.format(box.left)) - print('\ttop : {}'.format(box.top)) - print('\tright : {}'.format(box.right)) - print('\tbottom: {}'.format(box.bottom)) - print('\n') + print( + "Time offset of the first frame: {}s".format( + frame.time_offset.seconds + frame.time_offset.nanos / 1e9 + ) + ) + print("Bounding box position:") + print("\tleft : {}".format(box.left)) + print("\ttop : {}".format(box.top)) + print("\tright : {}".format(box.right)) + print("\tbottom: {}".format(box.bottom)) + print("\n") # [END video_object_tracking_gcs_beta] return object_annotations @@ -246,17 +267,18 @@ def track_objects(path): video_client = videointelligence.VideoIntelligenceServiceClient() features = [videointelligence.enums.Feature.OBJECT_TRACKING] - with io.open(path, 'rb') as file: + with io.open(path, "rb") as file: input_content = file.read() # It is recommended to use location_id as 'us-east1' for the best latency # due to different types of processors used in this region and others. operation = video_client.annotate_video( - input_content=input_content, features=features, location_id='us-east1') - print('\nProcessing video for object annotations.') + input_content=input_content, features=features, location_id="us-east1" + ) + print("\nProcessing video for object annotations.") result = operation.result(timeout=300) - print('\nFinished processing.\n') + print("\nFinished processing.\n") # The first result is retrieved because a single video was processed. object_annotations = result.annotation_results[0].object_annotations @@ -264,30 +286,35 @@ def track_objects(path): # Get only the first annotation for demo purposes. object_annotation = object_annotations[0] # description is in Unicode - print(u'Entity description: {}'.format( - object_annotation.entity.description)) + print(u"Entity description: {}".format(object_annotation.entity.description)) if object_annotation.entity.entity_id: - print('Entity id: {}'.format(object_annotation.entity.entity_id)) + print("Entity id: {}".format(object_annotation.entity.entity_id)) - print('Segment: {}s to {}s'.format( - object_annotation.segment.start_time_offset.seconds + - object_annotation.segment.start_time_offset.nanos / 1e9, - object_annotation.segment.end_time_offset.seconds + - object_annotation.segment.end_time_offset.nanos / 1e9)) + print( + "Segment: {}s to {}s".format( + object_annotation.segment.start_time_offset.seconds + + object_annotation.segment.start_time_offset.nanos / 1e9, + object_annotation.segment.end_time_offset.seconds + + object_annotation.segment.end_time_offset.nanos / 1e9, + ) + ) - print('Confidence: {}'.format(object_annotation.confidence)) + print("Confidence: {}".format(object_annotation.confidence)) # Here we print only the bounding box of the first frame in this segment frame = object_annotation.frames[0] box = frame.normalized_bounding_box - print('Time offset of the first frame: {}s'.format( - frame.time_offset.seconds + frame.time_offset.nanos / 1e9)) - print('Bounding box position:') - print('\tleft : {}'.format(box.left)) - print('\ttop : {}'.format(box.top)) - print('\tright : {}'.format(box.right)) - print('\tbottom: {}'.format(box.bottom)) - print('\n') + print( + "Time offset of the first frame: {}s".format( + frame.time_offset.seconds + frame.time_offset.nanos / 1e9 + ) + ) + print("Bounding box position:") + print("\tleft : {}".format(box.left)) + print("\ttop : {}".format(box.top)) + print("\tright : {}".format(box.right)) + print("\tbottom: {}".format(box.bottom)) + print("\n") # [END video_object_tracking_beta] return object_annotations @@ -302,19 +329,20 @@ def detect_labels_streaming(path): # Set streaming config. config = videointelligence.types.StreamingVideoConfig( - feature=(videointelligence.enums. - StreamingFeature.STREAMING_LABEL_DETECTION)) + feature=(videointelligence.enums.StreamingFeature.STREAMING_LABEL_DETECTION) + ) # config_request should be the first in the stream of requests. config_request = videointelligence.types.StreamingAnnotateVideoRequest( - video_config=config) + video_config=config + ) # Set the chunk size to 5MB (recommended less than 10MB). chunk_size = 5 * 1024 * 1024 # Load file content. stream = [] - with io.open(path, 'rb') as video_file: + with io.open(path, "rb") as video_file: while True: data = video_file.read(chunk_size) if not data: @@ -325,7 +353,8 @@ def stream_generator(): yield config_request for chunk in stream: yield videointelligence.types.StreamingAnnotateVideoRequest( - input_content=chunk) + input_content=chunk + ) requests = stream_generator() @@ -351,14 +380,14 @@ def stream_generator(): for annotation in label_annotations: # Each annotation has one frame, which has a timeoffset. frame = annotation.frames[0] - time_offset = frame.time_offset.seconds + \ - frame.time_offset.nanos / 1e9 + time_offset = frame.time_offset.seconds + frame.time_offset.nanos / 1e9 description = annotation.entity.description confidence = annotation.frames[0].confidence # description is in Unicode - print(u'{}s: {} (confidence: {})'.format( - time_offset, description, confidence)) + print( + u"{}s: {} (confidence: {})".format(time_offset, description, confidence) + ) # [END video_streaming_label_detection_beta] @@ -372,19 +401,22 @@ def detect_shot_change_streaming(path): # Set streaming config. config = videointelligence.types.StreamingVideoConfig( - feature=(videointelligence.enums.StreamingFeature. - STREAMING_SHOT_CHANGE_DETECTION)) + feature=( + videointelligence.enums.StreamingFeature.STREAMING_SHOT_CHANGE_DETECTION + ) + ) # config_request should be the first in the stream of requests. config_request = videointelligence.types.StreamingAnnotateVideoRequest( - video_config=config) + video_config=config + ) # Set the chunk size to 5MB (recommended less than 10MB). chunk_size = 5 * 1024 * 1024 # Load file content. stream = [] - with io.open(path, 'rb') as video_file: + with io.open(path, "rb") as video_file: while True: data = video_file.read(chunk_size) if not data: @@ -395,7 +427,8 @@ def stream_generator(): yield config_request for chunk in stream: yield videointelligence.types.StreamingAnnotateVideoRequest( - input_content=chunk) + input_content=chunk + ) requests = stream_generator() @@ -413,12 +446,16 @@ def stream_generator(): break for annotation in response.annotation_results.shot_annotations: - start = (annotation.start_time_offset.seconds + - annotation.start_time_offset.nanos / 1e9) - end = (annotation.end_time_offset.seconds + - annotation.end_time_offset.nanos / 1e9) - - print('Shot: {}s to {}s'.format(start, end)) + start = ( + annotation.start_time_offset.seconds + + annotation.start_time_offset.nanos / 1e9 + ) + end = ( + annotation.end_time_offset.seconds + + annotation.end_time_offset.nanos / 1e9 + ) + + print("Shot: {}s to {}s".format(start, end)) # [END video_streaming_shot_change_detection_beta] @@ -432,19 +469,20 @@ def track_objects_streaming(path): # Set streaming config. config = videointelligence.types.StreamingVideoConfig( - feature=(videointelligence.enums. - StreamingFeature.STREAMING_OBJECT_TRACKING)) + feature=(videointelligence.enums.StreamingFeature.STREAMING_OBJECT_TRACKING) + ) # config_request should be the first in the stream of requests. config_request = videointelligence.types.StreamingAnnotateVideoRequest( - video_config=config) + video_config=config + ) # Set the chunk size to 5MB (recommended less than 10MB). chunk_size = 5 * 1024 * 1024 # Load file content. stream = [] - with io.open(path, 'rb') as video_file: + with io.open(path, "rb") as video_file: while True: data = video_file.read(chunk_size) if not data: @@ -455,7 +493,8 @@ def stream_generator(): yield config_request for chunk in stream: yield videointelligence.types.StreamingAnnotateVideoRequest( - input_content=chunk) + input_content=chunk + ) requests = stream_generator() @@ -481,8 +520,7 @@ def stream_generator(): for annotation in object_annotations: # Each annotation has one frame, which has a timeoffset. frame = annotation.frames[0] - time_offset = frame.time_offset.seconds + \ - frame.time_offset.nanos / 1e9 + time_offset = frame.time_offset.seconds + frame.time_offset.nanos / 1e9 description = annotation.entity.description confidence = annotation.confidence @@ -491,22 +529,22 @@ def stream_generator(): track_id = annotation.track_id # description is in Unicode - print('{}s'.format(time_offset)) - print(u'\tEntity description: {}'.format(description)) - print('\tTrack Id: {}'.format(track_id)) + print("{}s".format(time_offset)) + print(u"\tEntity description: {}".format(description)) + print("\tTrack Id: {}".format(track_id)) if annotation.entity.entity_id: - print('\tEntity id: {}'.format(annotation.entity.entity_id)) + print("\tEntity id: {}".format(annotation.entity.entity_id)) - print('\tConfidence: {}'.format(confidence)) + print("\tConfidence: {}".format(confidence)) # Every annotation has only one frame frame = annotation.frames[0] box = frame.normalized_bounding_box - print('\tBounding box position:') - print('\tleft : {}'.format(box.left)) - print('\ttop : {}'.format(box.top)) - print('\tright : {}'.format(box.right)) - print('\tbottom: {}\n'.format(box.bottom)) + print("\tBounding box position:") + print("\tleft : {}".format(box.left)) + print("\ttop : {}".format(box.top)) + print("\tright : {}".format(box.right)) + print("\tbottom: {}\n".format(box.bottom)) # [END video_streaming_object_tracking_beta] @@ -520,19 +558,22 @@ def detect_explicit_content_streaming(path): # Set streaming config. config = videointelligence.types.StreamingVideoConfig( - feature=(videointelligence.enums.StreamingFeature. - STREAMING_EXPLICIT_CONTENT_DETECTION)) + feature=( + videointelligence.enums.StreamingFeature.STREAMING_EXPLICIT_CONTENT_DETECTION + ) + ) # config_request should be the first in the stream of requests. config_request = videointelligence.types.StreamingAnnotateVideoRequest( - video_config=config) + video_config=config + ) # Set the chunk size to 5MB (recommended less than 10MB). chunk_size = 5 * 1024 * 1024 # Load file content. stream = [] - with io.open(path, 'rb') as video_file: + with io.open(path, "rb") as video_file: while True: data = video_file.read(chunk_size) if not data: @@ -543,7 +584,8 @@ def stream_generator(): yield config_request for chunk in stream: yield videointelligence.types.StreamingAnnotateVideoRequest( - input_content=chunk) + input_content=chunk + ) requests = stream_generator() @@ -561,13 +603,13 @@ def stream_generator(): break for frame in response.annotation_results.explicit_annotation.frames: - time_offset = (frame.time_offset.seconds + - frame.time_offset.nanos / 1e9) + time_offset = frame.time_offset.seconds + frame.time_offset.nanos / 1e9 pornography_likelihood = videointelligence.enums.Likelihood( - frame.pornography_likelihood) + frame.pornography_likelihood + ) - print('Time: {}s'.format(time_offset)) - print('\tpornogaphy: {}'.format(pornography_likelihood.name)) + print("Time: {}s".format(time_offset)) + print("\tpornogaphy: {}".format(pornography_likelihood.name)) # [END video_streaming_explicit_content_detection_beta] @@ -584,24 +626,26 @@ def annotation_to_storage_streaming(path, output_uri): # The output_uri is the prefix of the actual output files. storage_config = videointelligence.types.StreamingStorageConfig( enable_storage_annotation_result=True, - annotation_result_storage_directory=output_uri) + annotation_result_storage_directory=output_uri, + ) # Here we use label detection as an example. # All features support output to GCS. config = videointelligence.types.StreamingVideoConfig( - feature=(videointelligence.enums. - StreamingFeature.STREAMING_LABEL_DETECTION), - storage_config=storage_config) + feature=(videointelligence.enums.StreamingFeature.STREAMING_LABEL_DETECTION), + storage_config=storage_config, + ) # config_request should be the first in the stream of requests. config_request = videointelligence.types.StreamingAnnotateVideoRequest( - video_config=config) + video_config=config + ) # Set the chunk size to 5MB (recommended less than 10MB). chunk_size = 5 * 1024 * 1024 # Load file content. stream = [] - with io.open(path, 'rb') as video_file: + with io.open(path, "rb") as video_file: while True: data = video_file.read(chunk_size) if not data: @@ -612,7 +656,8 @@ def stream_generator(): yield config_request for chunk in stream: yield videointelligence.types.StreamingAnnotateVideoRequest( - input_content=chunk) + input_content=chunk + ) requests = stream_generator() @@ -628,7 +673,7 @@ def stream_generator(): print(response.error.message) break - print('Storage URI: {}'.format(response.annotation_results_uri)) + print("Storage URI: {}".format(response.annotation_results_uri)) # [END video_streaming_annotation_to_storage_beta] @@ -645,21 +690,24 @@ def streaming_automl_classification(path, project_id, model_id): client = videointelligence.StreamingVideoIntelligenceServiceClient() - model_path = 'projects/{}/locations/us-central1/models/{}'.format( - project_id, model_id) + model_path = "projects/{}/locations/us-central1/models/{}".format( + project_id, model_id + ) # Here we use classification as an example. - automl_config = (videointelligence.types - .StreamingAutomlClassificationConfig( - model_name=model_path)) + automl_config = videointelligence.types.StreamingAutomlClassificationConfig( + model_name=model_path + ) video_config = videointelligence.types.StreamingVideoConfig( feature=enums.StreamingFeature.STREAMING_AUTOML_CLASSIFICATION, - automl_classification_config=automl_config) + automl_classification_config=automl_config, + ) # config_request should be the first in the stream of requests. config_request = videointelligence.types.StreamingAnnotateVideoRequest( - video_config=video_config) + video_config=video_config + ) # Set the chunk size to 5MB (recommended less than 10MB). chunk_size = 5 * 1024 * 1024 @@ -669,7 +717,7 @@ def streaming_automl_classification(path, project_id, model_id): # https://cloud.google.com/video-intelligence/docs/streaming/streaming#supported_video_codecs # for more details. stream = [] - with io.open(path, 'rb') as video_file: + with io.open(path, "rb") as video_file: while True: data = video_file.read(chunk_size) if not data: @@ -680,7 +728,8 @@ def stream_generator(): yield config_request for chunk in stream: yield videointelligence.types.StreamingAnnotateVideoRequest( - input_content=chunk) + input_content=chunk + ) requests = stream_generator() @@ -698,91 +747,101 @@ def stream_generator(): for label in response.annotation_results.label_annotations: for frame in label.frames: - print("At {:3d}s segment, {:5.1%} {}".format( - frame.time_offset.seconds, - frame.confidence, - label.entity.entity_id)) + print( + "At {:3d}s segment, {:5.1%} {}".format( + frame.time_offset.seconds, + frame.confidence, + label.entity.entity_id, + ) + ) # [END video_streaming_automl_classification_beta] -if __name__ == '__main__': +if __name__ == "__main__": parser = argparse.ArgumentParser( - description=__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter) - subparsers = parser.add_subparsers(dest='command') + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + subparsers = parser.add_subparsers(dest="command") speech_transcription_parser = subparsers.add_parser( - 'transcription', help=speech_transcription.__doc__) - speech_transcription_parser.add_argument('gcs_uri') + "transcription", help=speech_transcription.__doc__ + ) + speech_transcription_parser.add_argument("gcs_uri") video_text_gcs_parser = subparsers.add_parser( - 'video-text-gcs', help=video_detect_text_gcs.__doc__) - video_text_gcs_parser.add_argument('gcs_uri') + "video-text-gcs", help=video_detect_text_gcs.__doc__ + ) + video_text_gcs_parser.add_argument("gcs_uri") video_text_parser = subparsers.add_parser( - 'video-text', help=video_detect_text.__doc__) - video_text_parser.add_argument('path') + "video-text", help=video_detect_text.__doc__ + ) + video_text_parser.add_argument("path") video_object_tracking_gcs_parser = subparsers.add_parser( - 'track-objects-gcs', help=track_objects_gcs.__doc__) - video_object_tracking_gcs_parser.add_argument('gcs_uri') + "track-objects-gcs", help=track_objects_gcs.__doc__ + ) + video_object_tracking_gcs_parser.add_argument("gcs_uri") video_object_tracking_parser = subparsers.add_parser( - 'track-objects', help=track_objects.__doc__) - video_object_tracking_parser.add_argument('path') + "track-objects", help=track_objects.__doc__ + ) + video_object_tracking_parser.add_argument("path") video_streaming_labels_parser = subparsers.add_parser( - 'streaming-labels', help=detect_labels_streaming.__doc__) - video_streaming_labels_parser.add_argument('path') + "streaming-labels", help=detect_labels_streaming.__doc__ + ) + video_streaming_labels_parser.add_argument("path") video_streaming_shot_change_parser = subparsers.add_parser( - 'streaming-shot-change', help=detect_shot_change_streaming.__doc__) - video_streaming_shot_change_parser.add_argument('path') + "streaming-shot-change", help=detect_shot_change_streaming.__doc__ + ) + video_streaming_shot_change_parser.add_argument("path") video_streaming_objects_parser = subparsers.add_parser( - 'streaming-objects', help=track_objects_streaming.__doc__) - video_streaming_objects_parser.add_argument('path') + "streaming-objects", help=track_objects_streaming.__doc__ + ) + video_streaming_objects_parser.add_argument("path") video_streaming_explicit_content_parser = subparsers.add_parser( - 'streaming-explicit-content', - help=detect_explicit_content_streaming.__doc__) - video_streaming_explicit_content_parser.add_argument('path') + "streaming-explicit-content", help=detect_explicit_content_streaming.__doc__ + ) + video_streaming_explicit_content_parser.add_argument("path") video_streaming_annotation_to_storage_parser = subparsers.add_parser( - 'streaming-annotation-storage', - help=annotation_to_storage_streaming.__doc__) - video_streaming_annotation_to_storage_parser.add_argument('path') - video_streaming_annotation_to_storage_parser.add_argument('output_uri') + "streaming-annotation-storage", help=annotation_to_storage_streaming.__doc__ + ) + video_streaming_annotation_to_storage_parser.add_argument("path") + video_streaming_annotation_to_storage_parser.add_argument("output_uri") video_streaming_automl_classification_parser = subparsers.add_parser( - 'streaming-automl-classification', - help=streaming_automl_classification.__doc__) - video_streaming_automl_classification_parser.add_argument('path') - video_streaming_automl_classification_parser.add_argument('project_id') - video_streaming_automl_classification_parser.add_argument('model_id') + "streaming-automl-classification", help=streaming_automl_classification.__doc__ + ) + video_streaming_automl_classification_parser.add_argument("path") + video_streaming_automl_classification_parser.add_argument("project_id") + video_streaming_automl_classification_parser.add_argument("model_id") args = parser.parse_args() - if args.command == 'transcription': + if args.command == "transcription": speech_transcription(args.gcs_uri) - elif args.command == 'video-text-gcs': + elif args.command == "video-text-gcs": video_detect_text_gcs(args.gcs_uri) - elif args.command == 'video-text': + elif args.command == "video-text": video_detect_text(args.path) - elif args.command == 'track-objects-gcs': + elif args.command == "track-objects-gcs": track_objects_gcs(args.gcs_uri) - elif args.command == 'track-objects': + elif args.command == "track-objects": track_objects(args.path) - elif args.command == 'streaming-labels': + elif args.command == "streaming-labels": detect_labels_streaming(args.path) - elif args.command == 'streaming-shot-change': + elif args.command == "streaming-shot-change": detect_shot_change_streaming(args.path) - elif args.command == 'streaming-objects': + elif args.command == "streaming-objects": track_objects_streaming(args.path) - elif args.command == 'streaming-explicit-content': + elif args.command == "streaming-explicit-content": detect_explicit_content_streaming(args.path) - elif args.command == 'streaming-annotation-storage': + elif args.command == "streaming-annotation-storage": annotation_to_storage_streaming(args.path, args.output_uri) - elif args.command == 'streaming-automl-classification': - streaming_automl_classification( - args.path, args.project_id, args.model_id) + elif args.command == "streaming-automl-classification": + streaming_automl_classification(args.path, args.project_id, args.model_id) diff --git a/video/cloud-client/analyze/beta_snippets_test.py b/video/cloud-client/analyze/beta_snippets_test.py index a36f741d67a..715a46bf978 100644 --- a/video/cloud-client/analyze/beta_snippets_test.py +++ b/video/cloud-client/analyze/beta_snippets_test.py @@ -24,22 +24,33 @@ import pytest -POSSIBLE_TEXTS = ['Google', 'SUR', 'SUR', 'ROTO', 'Vice President', '58oo9', - 'LONDRES', 'OMAR', 'PARIS', 'METRO', 'RUE', 'CARLO'] - - -@pytest.fixture(scope='session') +POSSIBLE_TEXTS = [ + "Google", + "SUR", + "SUR", + "ROTO", + "Vice President", + "58oo9", + "LONDRES", + "OMAR", + "PARIS", + "METRO", + "RUE", + "CARLO", +] + + +@pytest.fixture(scope="session") def video_path(tmpdir_factory): - file = urlopen( - 'http://storage.googleapis.com/cloud-samples-data/video/cat.mp4') - path = tmpdir_factory.mktemp('video').join('file.mp4') - with open(str(path), 'wb') as f: + file = urlopen("http://storage.googleapis.com/cloud-samples-data/video/cat.mp4") + path = tmpdir_factory.mktemp("video").join("file.mp4") + with open(str(path), "wb") as f: f.write(file.read()) return str(path) -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def bucket(): # Create a temporaty bucket to store annotation output. bucket_name = str(uuid.uuid1()) @@ -55,9 +66,10 @@ def bucket(): @pytest.mark.slow def test_speech_transcription(capsys): beta_snippets.speech_transcription( - 'gs://python-docs-samples-tests/video/googlework_short.mp4') + "gs://python-docs-samples-tests/video/googlework_short.mp4" + ) out, _ = capsys.readouterr() - assert 'cultural' in out + assert "cultural" in out @pytest.mark.slow @@ -65,7 +77,7 @@ def test_detect_labels_streaming(capsys, video_path): beta_snippets.detect_labels_streaming(video_path) out, _ = capsys.readouterr() - assert 'cat' in out + assert "cat" in out @pytest.mark.slow @@ -73,7 +85,7 @@ def test_detect_shot_change_streaming(capsys, video_path): beta_snippets.detect_shot_change_streaming(video_path) out, _ = capsys.readouterr() - assert 'Shot' in out + assert "Shot" in out @pytest.mark.slow @@ -81,7 +93,7 @@ def test_track_objects_streaming(capsys, video_path): beta_snippets.track_objects_streaming(video_path) out, _ = capsys.readouterr() - assert 'cat' in out + assert "cat" in out @pytest.mark.slow @@ -89,16 +101,16 @@ def test_detect_explicit_content_streaming(capsys, video_path): beta_snippets.detect_explicit_content_streaming(video_path) out, _ = capsys.readouterr() - assert 'Time' in out + assert "Time" in out @pytest.mark.slow def test_annotation_to_storage_streaming(capsys, video_path, bucket): - output_uri = 'gs://{}'.format(bucket.name) + output_uri = "gs://{}".format(bucket.name) beta_snippets.annotation_to_storage_streaming(video_path, output_uri) out, _ = capsys.readouterr() - assert 'Storage' in out + assert "Storage" in out # It takes a few seconds before the results show up on GCS. for _ in range(10): @@ -110,12 +122,12 @@ def test_annotation_to_storage_streaming(capsys, video_path, bucket): break # Confirm that one output blob had been written to GCS. - assert len(blobs) == 1 + assert len(blobs) > 0 @pytest.mark.slow def test_detect_text(): - in_file = './resources/googlework_tiny.mp4' + in_file = "./resources/googlework_tiny.mp4" text_annotations = beta_snippets.video_detect_text(in_file) text_exists = False @@ -128,7 +140,7 @@ def test_detect_text(): @pytest.mark.slow def test_detect_text_gcs(): - in_file = 'gs://python-docs-samples-tests/video/googlework_tiny.mp4' + in_file = "gs://python-docs-samples-tests/video/googlework_tiny.mp4" text_annotations = beta_snippets.video_detect_text_gcs(in_file) text_exists = False @@ -141,12 +153,12 @@ def test_detect_text_gcs(): @pytest.mark.slow def test_track_objects(): - in_file = './resources/cat.mp4' + in_file = "./resources/cat.mp4" object_annotations = beta_snippets.track_objects(in_file) text_exists = False for object_annotation in object_annotations: - if 'CAT' in object_annotation.entity.description.upper(): + if "CAT" in object_annotation.entity.description.upper(): text_exists = True assert text_exists assert object_annotations[0].frames[0].normalized_bounding_box.left >= 0.0 @@ -155,12 +167,12 @@ def test_track_objects(): @pytest.mark.slow def test_track_objects_gcs(): - in_file = 'gs://cloud-samples-data/video/cat.mp4' + in_file = "gs://cloud-samples-data/video/cat.mp4" object_annotations = beta_snippets.track_objects_gcs(in_file) text_exists = False for object_annotation in object_annotations: - if 'CAT' in object_annotation.entity.description.upper(): + if "CAT" in object_annotation.entity.description.upper(): text_exists = True assert text_exists assert object_annotations[0].frames[0].normalized_bounding_box.left >= 0.0 @@ -169,9 +181,8 @@ def test_track_objects_gcs(): @pytest.mark.slow def test_streaming_automl_classification(capsys, video_path): - project_id = os.environ['GCLOUD_PROJECT'] - model_id = 'VCN6363999689846554624' - beta_snippets.streaming_automl_classification( - video_path, project_id, model_id) + project_id = os.environ["GCLOUD_PROJECT"] + model_id = "VCN6363999689846554624" + beta_snippets.streaming_automl_classification(video_path, project_id, model_id) out, _ = capsys.readouterr() - assert 'brush_hair' in out + assert "brush_hair" in out diff --git a/video/cloud-client/analyze/requirements.txt b/video/cloud-client/analyze/requirements.txt index 9958046a7db..8a9815cc32e 100644 --- a/video/cloud-client/analyze/requirements.txt +++ b/video/cloud-client/analyze/requirements.txt @@ -1,2 +1,2 @@ -google-cloud-videointelligence==1.13.0 +google-cloud-videointelligence==1.14.0 google-cloud-storage==1.26.0 diff --git a/video/cloud-client/analyze/video_detect_faces_beta.py b/video/cloud-client/analyze/video_detect_faces_beta.py index 064c6197d57..0c83bc67f23 100644 --- a/video/cloud-client/analyze/video_detect_faces_beta.py +++ b/video/cloud-client/analyze/video_detect_faces_beta.py @@ -29,9 +29,7 @@ def detect_faces(local_file_path="path/to/your/video-file.mp4"): config = videointelligence.types.FaceDetectionConfig( include_bounding_boxes=True, include_attributes=True ) - context = videointelligence.types.VideoContext( - face_detection_config=config - ) + context = videointelligence.types.VideoContext(face_detection_config=config) # Start the asynchronous request operation = client.annotate_video( diff --git a/video/cloud-client/analyze/video_detect_faces_gcs_beta.py b/video/cloud-client/analyze/video_detect_faces_gcs_beta.py index e8fae6eea4b..7e3a3e7d859 100644 --- a/video/cloud-client/analyze/video_detect_faces_gcs_beta.py +++ b/video/cloud-client/analyze/video_detect_faces_gcs_beta.py @@ -25,9 +25,7 @@ def detect_faces(gcs_uri="gs://YOUR_BUCKET_ID/path/to/your/video.mp4"): config = videointelligence.types.FaceDetectionConfig( include_bounding_boxes=True, include_attributes=True ) - context = videointelligence.types.VideoContext( - face_detection_config=config - ) + context = videointelligence.types.VideoContext(face_detection_config=config) # Start the asynchronous request operation = client.annotate_video( diff --git a/video/cloud-client/analyze/video_detect_logo.py b/video/cloud-client/analyze/video_detect_logo.py new file mode 100644 index 00000000000..319e1c8745a --- /dev/null +++ b/video/cloud-client/analyze/video_detect_logo.py @@ -0,0 +1,104 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import io + +# [START video_detect_logo] + +from google.cloud import videointelligence + + +def detect_logo(local_file_path="path/to/your/video.mp4"): + """Performs asynchronous video annotation for logo recognition on a local file.""" + + client = videointelligence.VideoIntelligenceServiceClient() + + with io.open(local_file_path, "rb") as f: + input_content = f.read() + features = [videointelligence.enums.Feature.LOGO_RECOGNITION] + + operation = client.annotate_video(input_content=input_content, features=features) + + print(u"Waiting for operation to complete...") + response = operation.result() + + # Get the first response, since we sent only one video. + annotation_result = response.annotation_results[0] + + # Annotations for list of logos detected, tracked and recognized in video. + for logo_recognition_annotation in annotation_result.logo_recognition_annotations: + entity = logo_recognition_annotation.entity + + # Opaque entity ID. Some IDs may be available in [Google Knowledge Graph + # Search API](https://developers.google.com/knowledge-graph/). + print(u"Entity Id : {}".format(entity.entity_id)) + + print(u"Description : {}".format(entity.description)) + + # All logo tracks where the recognized logo appears. Each track corresponds + # to one logo instance appearing in consecutive frames. + for track in logo_recognition_annotation.tracks: + # Video segment of a track. + print( + u"\n\tStart Time Offset : {}.{}".format( + track.segment.start_time_offset.seconds, + track.segment.start_time_offset.nanos, + ) + ) + print( + u"\tEnd Time Offset : {}.{}".format( + track.segment.end_time_offset.seconds, + track.segment.end_time_offset.nanos, + ) + ) + print(u"\tConfidence : {}".format(track.confidence)) + + # The object with timestamp and attributes per frame in the track. + for timestamped_object in track.timestamped_objects: + + # Normalized Bounding box in a frame, where the object is located. + normalized_bounding_box = timestamped_object.normalized_bounding_box + print(u"\n\t\tLeft : {}".format(normalized_bounding_box.left)) + print(u"\t\tTop : {}".format(normalized_bounding_box.top)) + print(u"\t\tRight : {}".format(normalized_bounding_box.right)) + print(u"\t\tBottom : {}".format(normalized_bounding_box.bottom)) + + # Optional. The attributes of the object in the bounding box. + for attribute in timestamped_object.attributes: + print(u"\n\t\t\tName : {}".format(attribute.name)) + print(u"\t\t\tConfidence : {}".format(attribute.confidence)) + print(u"\t\t\tValue : {}".format(attribute.value)) + + # Optional. Attributes in the track level. + for track_attribute in track.attributes: + print(u"\n\t\tName : {}".format(track_attribute.name)) + print(u"\t\tConfidence : {}".format(track_attribute.confidence)) + print(u"\t\tValue : {}".format(track_attribute.value)) + + # All video segments where the recognized logo appears. There might be + # multiple instances of the same logo class appearing in one VideoSegment. + for segment in logo_recognition_annotation.segments: + print( + u"\n\tStart Time Offset : {}.{}".format( + segment.start_time_offset.seconds, segment.start_time_offset.nanos, + ) + ) + print( + u"\tEnd Time Offset : {}.{}".format( + segment.end_time_offset.seconds, segment.end_time_offset.nanos, + ) + ) + + +# [END video_detect_logo] diff --git a/video/cloud-client/analyze/video_detect_logo_gcs.py b/video/cloud-client/analyze/video_detect_logo_gcs.py new file mode 100644 index 00000000000..a999888555f --- /dev/null +++ b/video/cloud-client/analyze/video_detect_logo_gcs.py @@ -0,0 +1,99 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START video_detect_logo_gcs] + +from google.cloud import videointelligence + + +def detect_logo_gcs(input_uri="gs://YOUR_BUCKET_ID/path/to/your/file.mp4"): + + client = videointelligence.VideoIntelligenceServiceClient() + + features = [videointelligence.enums.Feature.LOGO_RECOGNITION] + + operation = client.annotate_video(input_uri=input_uri, features=features) + + print(u"Waiting for operation to complete...") + response = operation.result() + + # Get the first response, since we sent only one video. + annotation_result = response.annotation_results[0] + + # Annotations for list of logos detected, tracked and recognized in video. + for logo_recognition_annotation in annotation_result.logo_recognition_annotations: + entity = logo_recognition_annotation.entity + + # Opaque entity ID. Some IDs may be available in [Google Knowledge Graph + # Search API](https://developers.google.com/knowledge-graph/). + print(u"Entity Id : {}".format(entity.entity_id)) + + print(u"Description : {}".format(entity.description)) + + # All logo tracks where the recognized logo appears. Each track corresponds + # to one logo instance appearing in consecutive frames. + for track in logo_recognition_annotation.tracks: + + # Video segment of a track. + print( + u"\n\tStart Time Offset : {}.{}".format( + track.segment.start_time_offset.seconds, + track.segment.start_time_offset.nanos, + ) + ) + print( + u"\tEnd Time Offset : {}.{}".format( + track.segment.end_time_offset.seconds, + track.segment.end_time_offset.nanos, + ) + ) + print(u"\tConfidence : {}".format(track.confidence)) + + # The object with timestamp and attributes per frame in the track. + for timestamped_object in track.timestamped_objects: + # Normalized Bounding box in a frame, where the object is located. + normalized_bounding_box = timestamped_object.normalized_bounding_box + print(u"\n\t\tLeft : {}".format(normalized_bounding_box.left)) + print(u"\t\tTop : {}".format(normalized_bounding_box.top)) + print(u"\t\tRight : {}".format(normalized_bounding_box.right)) + print(u"\t\tBottom : {}".format(normalized_bounding_box.bottom)) + + # Optional. The attributes of the object in the bounding box. + for attribute in timestamped_object.attributes: + print(u"\n\t\t\tName : {}".format(attribute.name)) + print(u"\t\t\tConfidence : {}".format(attribute.confidence)) + print(u"\t\t\tValue : {}".format(attribute.value)) + + # Optional. Attributes in the track level. + for track_attribute in track.attributes: + print(u"\n\t\tName : {}".format(track_attribute.name)) + print(u"\t\tConfidence : {}".format(track_attribute.confidence)) + print(u"\t\tValue : {}".format(track_attribute.value)) + + # All video segments where the recognized logo appears. There might be + # multiple instances of the same logo class appearing in one VideoSegment. + for segment in logo_recognition_annotation.segments: + print( + u"\n\tStart Time Offset : {}.{}".format( + segment.start_time_offset.seconds, segment.start_time_offset.nanos, + ) + ) + print( + u"\tEnd Time Offset : {}.{}".format( + segment.end_time_offset.seconds, segment.end_time_offset.nanos, + ) + ) + + +# [END video_detect_logo_gcs] diff --git a/video/cloud-client/analyze/video_detect_logo_gcs_test.py b/video/cloud-client/analyze/video_detect_logo_gcs_test.py new file mode 100644 index 00000000000..0dd63a79783 --- /dev/null +++ b/video/cloud-client/analyze/video_detect_logo_gcs_test.py @@ -0,0 +1,32 @@ +# Copyright 2020 Google +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +import video_detect_logo_gcs + +RESOURCES = os.path.join(os.path.dirname(__file__), "resources") + + +def test_detect_logo_gcs(capsys): + input_uri = "gs://cloud-samples-data/video/googlework_tiny.mp4" + + video_detect_logo_gcs.detect_logo_gcs(input_uri=input_uri) + + out, _ = capsys.readouterr() + + assert "Description" in out + assert "Confidence" in out + assert "Start Time Offset" in out + assert "End Time Offset" in out diff --git a/video/cloud-client/analyze/video_detect_logo_test.py b/video/cloud-client/analyze/video_detect_logo_test.py new file mode 100644 index 00000000000..528d3b4b6ff --- /dev/null +++ b/video/cloud-client/analyze/video_detect_logo_test.py @@ -0,0 +1,32 @@ +# Copyright 2020 Google +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +import video_detect_logo + +RESOURCES = os.path.join(os.path.dirname(__file__), "resources") + + +def test_detect_logo(capsys): + local_file_path = os.path.join(RESOURCES, "googlework_tiny.mp4") + + video_detect_logo.detect_logo(local_file_path=local_file_path) + + out, _ = capsys.readouterr() + + assert "Description" in out + assert "Confidence" in out + assert "Start Time Offset" in out + assert "End Time Offset" in out diff --git a/video/cloud-client/analyze/video_detect_person_beta.py b/video/cloud-client/analyze/video_detect_person_beta.py index 2fc7e5942dd..5b5a567e3a1 100644 --- a/video/cloud-client/analyze/video_detect_person_beta.py +++ b/video/cloud-client/analyze/video_detect_person_beta.py @@ -31,9 +31,7 @@ def detect_person(local_file_path="path/to/your/video-file.mp4"): include_attributes=True, include_pose_landmarks=True, ) - context = videointelligence.types.VideoContext( - person_detection_config=config - ) + context = videointelligence.types.VideoContext(person_detection_config=config) # Start the asynchronous request operation = client.annotate_video( diff --git a/video/cloud-client/analyze/video_detect_person_gcs_beta.py b/video/cloud-client/analyze/video_detect_person_gcs_beta.py index b588891a2b4..9bd2d007b73 100644 --- a/video/cloud-client/analyze/video_detect_person_gcs_beta.py +++ b/video/cloud-client/analyze/video_detect_person_gcs_beta.py @@ -27,9 +27,7 @@ def detect_person(gcs_uri="gs://YOUR_BUCKET_ID/path/to/your/video.mp4"): include_attributes=True, include_pose_landmarks=True, ) - context = videointelligence.types.VideoContext( - person_detection_config=config - ) + context = videointelligence.types.VideoContext(person_detection_config=config) # Start the asynchronous request operation = client.annotate_video(