From 3a5e006e69e9ee73812591449ecc5563fab2b30c Mon Sep 17 00:00:00 2001 From: Ace Nassri Date: Wed, 8 Mar 2017 12:59:04 -0600 Subject: [PATCH] Video samples (#319) * First + second drafts of the Video API Change-Id: I9bac19d0bf64065c93c6d84ec1edd0cece78af41 * Fix test failures * Change video lib to Cloud Storage link * Use videos that pass licensing requirements --- video-intelligence/analyze.js | 157 ++++++++++++++++++ video-intelligence/package.json | 17 ++ .../system-test/analyze.test.js | 40 +++++ 3 files changed, 214 insertions(+) create mode 100644 video-intelligence/analyze.js create mode 100644 video-intelligence/package.json create mode 100644 video-intelligence/system-test/analyze.test.js diff --git a/video-intelligence/analyze.js b/video-intelligence/analyze.js new file mode 100644 index 0000000000..37bd8f802f --- /dev/null +++ b/video-intelligence/analyze.js @@ -0,0 +1,157 @@ +/** + * Copyright 2017, Google, Inc. + * 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. + */ + +// https://cloud.google.com/video-intelligence/docs/ + +'use strict'; + +function analyzeFaces (gcsPath) { + // [START analyze_faces] + // Imports the Google Cloud Video Intelligence library + const Video = require('@google-cloud/videointelligence').v1beta1(); + + // Instantiates a client + const video = Video.videoIntelligenceServiceClient(); + + // The GCS filepath of the video to analyze + // const gcsPath = 'gs://my-bucket/my-video.mp4' + + const request = { + inputUri: gcsPath, + features: ['FACE_DETECTION'] + }; + + // Detect faces in a video + video.annotateVideo(request) + .then((startResponse) => { + const operation = startResponse[0]; + console.log('Waiting for operation to complete...'); + return operation.promise(); + }) + .then((doneResponse) => { + // Get faces for first video + const faces = doneResponse[0].annotationResults[0].faceAnnotations; + faces.forEach((face, faceIdx) => { + console.log('Thumbnail size:', face.thumbnail.buffer.length); + face.segments.forEach((segment, segmentIdx) => { + console.log(`Track ${segmentIdx} of face ${faceIdx}: frames ${segment.startTimeOffset} to ${segment.endTimeOffset}`); + }); + }); + }); + // [END analyze_faces] +} + +function analyzeLabels (gcsPath) { + // [START analyze_labels] + // Imports the Google Cloud Video Intelligence library + const Video = require('@google-cloud/videointelligence').v1beta1(); + + // Instantiates a client + const video = Video.videoIntelligenceServiceClient(); + + // The GCS filepath of the video to analyze + // const gcsPath = 'gs://my-bucket/my-video.mp4' + + const request = { + inputUri: gcsPath, + features: ['LABEL_DETECTION'] + }; + + // Detect labels in a video + video.annotateVideo(request) + .then((startResponse) => { + const operation = startResponse[0]; + console.log('Waiting for operation to complete...'); + return operation.promise(); + }) + .then((doneResponse) => { + // Get labels for first video + const labels = doneResponse[0].annotationResults[0].labelAnnotations; + labels.forEach((label) => { + console.log('Label description:', label.description); + console.log('Locations:'); + label.locations.forEach((location) => { + console.log(`\tFrames ${location.segment.startTimeOffset} to ${location.segment.endTimeOffset}`); + }); + }); + }); + // [END analyze_labels] +} + +function analyzeShots (gcsPath) { + // [START analyze_shots] + // Imports the Google Cloud Video Intelligence library + const Video = require('@google-cloud/videointelligence').v1beta1(); + + // Instantiates a client + const video = Video.videoIntelligenceServiceClient(); + + // The GCS filepath of the video to analyze + // const gcsPath = 'gs://my-bucket/my-video.mp4' + + const request = { + inputUri: gcsPath, + features: ['SHOT_CHANGE_DETECTION'] + }; + + // Detect camera shot changes + video.annotateVideo(request) + .then((startResponse) => { + const operation = startResponse[0]; + console.log('Waiting for operation to complete...'); + return operation.promise(); + }) + .then((doneResponse) => { + // Get shot changes for first video + const shotChanges = doneResponse[0].annotationResults[0].shotAnnotations; + shotChanges.forEach((shot, shotIdx) => { + console.log(`Scene ${shotIdx}:`); + console.log(`\tStart: ${shot.startTimeOffset}`); + console.log(`\tEnd: ${shot.endTimeOffset}`); + }); + }); + // [END analyze_shots] +} + +const cli = require(`yargs`) + .demand(1) + .command( + `faces `, + `Analyzes faces in a video using the Cloud Video Intelligence API.`, + {}, + (opts) => analyzeFaces(opts.gcsPath) + ) + .command( + `shots `, + `Analyzes shot angles in a video using the Cloud Video Intelligence API.`, + {}, + (opts) => analyzeShots(opts.gcsPath) + ) + .command( + `labels `, + `Labels objects in a video using the Cloud Video Intelligence API.`, + {}, + (opts) => analyzeLabels(opts.gcsPath) + ) + .example(`node $0 faces gs://my-bucket/my-video.mp4`) + .example(`node $0 shots gs://my-bucket/my-video.mp4`) + .example(`node $0 labels gs://my-bucket/my-video.mp4`) + .wrap(120) + .recommendCommands() + .epilogue(`For more information, see https://cloud.google.com/video-intelligence/docs`); + +if (module === require.main) { + cli.help().strict().argv; +} diff --git a/video-intelligence/package.json b/video-intelligence/package.json new file mode 100644 index 0000000000..675f002291 --- /dev/null +++ b/video-intelligence/package.json @@ -0,0 +1,17 @@ +{ + "name": "nodejs-docs-samples-videointelligence", + "version": "0.0.1", + "private": true, + "license": "Apache Version 2.0", + "author": "Google Inc.", + "scripts": { + "test": "cd ..; npm run st -- --verbose video/system-test/*.test.js" + }, + "dependencies": { + "@google-cloud/videointelligence": "https://storage.googleapis.com/videointelligence-alpha/videointelligence-nodejs.tar.gz", + "yargs": "6.6.0" + }, + "engines": { + "node": ">=4.3.2" + } +} diff --git a/video-intelligence/system-test/analyze.test.js b/video-intelligence/system-test/analyze.test.js new file mode 100644 index 0000000000..9e51554014 --- /dev/null +++ b/video-intelligence/system-test/analyze.test.js @@ -0,0 +1,40 @@ +/** + * Copyright 2017, Google, Inc. + * 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. + */ + +// https://cloud.google.com/video-intelligence/docs/ + +'use strict'; + +require(`../../system-test/_setup`); + +const cmd = `node analyze.js`; + +// analyze_faces +test(`should analyze faces`, async (t) => { + const output = console.log(`${cmd} faces gs://nodejs-docs-samples/video/google_gmail.mp4`); + t.regex(output, 'Thumbnail size: \d+'); +}); + +// analyze_labels +test(`should analyze labels`, async (t) => { + const output = await runAsync(`${cmd} labels gs://nodejs-docs-samples/video/cat.mp4`); + t.regex(output, /Label description: Whiskers/); +}); + +// analyze_shots +test(`should analyze shots`, async (t) => { + const output = await runAsync(`${cmd} shots gs://nodejs-docs-samples/video/gbike_dinosaur.mp4`); + t.regex(output, /Scene 0:/); +});