diff --git a/video/beta/pom.xml b/video/beta/pom.xml index eb6902ec7d8..c03bd59c14e 100644 --- a/video/beta/pom.xml +++ b/video/beta/pom.xml @@ -40,7 +40,7 @@ com.google.cloud google-cloud-video-intelligence - 0.101.0-beta + 0.106.0-beta com.google.cloud diff --git a/video/beta/src/main/java/com/example/video/StreamingAutoMlClassification.java b/video/beta/src/main/java/com/example/video/StreamingAutoMlClassification.java new file mode 100644 index 00000000000..b84672b77a3 --- /dev/null +++ b/video/beta/src/main/java/com/example/video/StreamingAutoMlClassification.java @@ -0,0 +1,117 @@ +/* + * Copyright 2019 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 + * + * 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. + */ + +package com.example.video; + +// [START video_streaming_automl_classification_beta] +import com.google.api.gax.rpc.BidiStream; +import com.google.cloud.videointelligence.v1p3beta1.LabelAnnotation; +import com.google.cloud.videointelligence.v1p3beta1.LabelFrame; +import com.google.cloud.videointelligence.v1p3beta1.StreamingAnnotateVideoRequest; +import com.google.cloud.videointelligence.v1p3beta1.StreamingAnnotateVideoResponse; +import com.google.cloud.videointelligence.v1p3beta1.StreamingAutomlClassificationConfig; +import com.google.cloud.videointelligence.v1p3beta1.StreamingFeature; +import com.google.cloud.videointelligence.v1p3beta1.StreamingVideoAnnotationResults; +import com.google.cloud.videointelligence.v1p3beta1.StreamingVideoConfig; +import com.google.cloud.videointelligence.v1p3beta1.StreamingVideoIntelligenceServiceClient; +import com.google.protobuf.ByteString; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; + +class StreamingAutoMlClassification { + + // Perform streaming video classification with an AutoML Model + static void streamingAutoMlClassification(String filePath, String projectId, String modelId) { + // String filePath = "path_to_your_video_file"; + // String projectId = "YOUR_GCP_PROJECT_ID"; + // String modelId = "YOUR_AUTO_ML_CLASSIFICATION_MODEL_ID"; + + try (StreamingVideoIntelligenceServiceClient client = + StreamingVideoIntelligenceServiceClient.create()) { + + Path path = Paths.get(filePath); + byte[] data = Files.readAllBytes(path); + // Set the chunk size to 5MB (recommended less than 10MB). + int chunkSize = 5 * 1024 * 1024; + int numChunks = (int) Math.ceil((double) data.length / chunkSize); + + String modelPath = String.format("projects/%s/locations/us-central1/models/%s", + projectId, + modelId); + + System.out.println(modelPath); + + StreamingAutomlClassificationConfig streamingAutomlClassificationConfig = + StreamingAutomlClassificationConfig.newBuilder() + .setModelName(modelPath) + .build(); + + StreamingVideoConfig streamingVideoConfig = StreamingVideoConfig.newBuilder() + .setFeature(StreamingFeature.STREAMING_AUTOML_CLASSIFICATION) + .setAutomlClassificationConfig(streamingAutomlClassificationConfig) + .build(); + + BidiStream call = + client.streamingAnnotateVideoCallable().call(); + + // The first request must **only** contain the audio configuration: + call.send( + StreamingAnnotateVideoRequest.newBuilder() + .setVideoConfig(streamingVideoConfig) + .build()); + + // Subsequent requests must **only** contain the audio data. + // Send the requests in chunks + for (int i = 0; i < numChunks; i++) { + call.send( + StreamingAnnotateVideoRequest.newBuilder() + .setInputContent(ByteString.copyFrom( + Arrays.copyOfRange(data, i * chunkSize, i * chunkSize + chunkSize))) + .build()); + } + + // Tell the service you are done sending data + call.closeSend(); + + for (StreamingAnnotateVideoResponse response : call) { + if (response.hasError()) { + System.out.println(response.getError().getMessage()); + break; + } + + StreamingVideoAnnotationResults annotationResults = response.getAnnotationResults(); + + for (LabelAnnotation annotation : annotationResults.getLabelAnnotationsList()) { + String entity = annotation.getEntity().getDescription(); + + // There is only one frame per annotation + LabelFrame labelFrame = annotation.getFrames(0); + double offset = labelFrame.getTimeOffset().getSeconds() + + labelFrame.getTimeOffset().getNanos() / 1e9; + float confidence = labelFrame.getConfidence(); + + System.out.format("%fs: %s (%f)\n", offset, entity, confidence); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} +// [END video_streaming_automl_classification_beta] diff --git a/video/beta/src/main/java/com/example/video/TextDetection.java b/video/beta/src/main/java/com/example/video/TextDetection.java index 51e9ccd6184..c095be6b7b5 100644 --- a/video/beta/src/main/java/com/example/video/TextDetection.java +++ b/video/beta/src/main/java/com/example/video/TextDetection.java @@ -63,7 +63,7 @@ public static VideoAnnotationResults detectText(String filePath) throws Exceptio System.out.println("Waiting for operation to complete..."); // The first result is retrieved because a single video was processed. - AnnotateVideoResponse response = future.get(300, TimeUnit.SECONDS); + AnnotateVideoResponse response = future.get(600, TimeUnit.SECONDS); VideoAnnotationResults results = response.getAnnotationResults(0); // Get only the first annotation for demo purposes. @@ -123,7 +123,7 @@ public static VideoAnnotationResults detectTextGcs(String gcsUri) throws Excepti System.out.println("Waiting for operation to complete..."); // The first result is retrieved because a single video was processed. - AnnotateVideoResponse response = future.get(300, TimeUnit.SECONDS); + AnnotateVideoResponse response = future.get(600, TimeUnit.SECONDS); VideoAnnotationResults results = response.getAnnotationResults(0); // Get only the first annotation for demo purposes. diff --git a/video/beta/src/main/java/com/example/video/TrackObjects.java b/video/beta/src/main/java/com/example/video/TrackObjects.java index 3a10fb89e1a..7a5a52f0f27 100644 --- a/video/beta/src/main/java/com/example/video/TrackObjects.java +++ b/video/beta/src/main/java/com/example/video/TrackObjects.java @@ -63,7 +63,7 @@ public static VideoAnnotationResults trackObjects(String filePath) throws Except System.out.println("Waiting for operation to complete..."); // The first result is retrieved because a single video was processed. - AnnotateVideoResponse response = future.get(300, TimeUnit.SECONDS); + AnnotateVideoResponse response = future.get(600, TimeUnit.SECONDS); VideoAnnotationResults results = response.getAnnotationResults(0); // Get only the first annotation for demo purposes. diff --git a/video/beta/src/test/java/com/example/video/StreamingAutoMlClassificationIT.java b/video/beta/src/test/java/com/example/video/StreamingAutoMlClassificationIT.java new file mode 100644 index 00000000000..1a37bbd539c --- /dev/null +++ b/video/beta/src/test/java/com/example/video/StreamingAutoMlClassificationIT.java @@ -0,0 +1,67 @@ +/* + * Copyright 2019 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 + * + * 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. + */ + + +package com.example.video; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + + +/** + * Integration (system) tests for {@link StreamingAutoMlClassification}. + */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class StreamingAutoMlClassificationIT { + + private static String PROJECT_ID = "779844219229"; // System.getenv().get("GOOGLE_CLOUD_PROJECT"); + private static String MODEL_ID = "VCN6455760532254228480"; + + private ByteArrayOutputStream bout; + private PrintStream out; + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testStreamingAutoMlClassification() { + StreamingAutoMlClassification.streamingAutoMlClassification( + "resources/cat.mp4", + PROJECT_ID, + MODEL_ID); + String got = bout.toString(); + + assertThat(got).contains("brush_hair"); + } +}