From 96cba212fb5c5c01a548a18efdac9d49ae66a5c0 Mon Sep 17 00:00:00 2001 From: Nirupa Anantha Kumar Date: Tue, 26 Mar 2019 09:06:04 -0700 Subject: [PATCH] docs(samples): streaming beta samples (#210) --- ...analyze-streaming-annotation-to-storage.js | 74 +++++++++++++++++ .../analyze-streaming-labels.js | 73 ++++++++++++++++ .../analyze-streaming-object.js | 83 +++++++++++++++++++ .../analyze-streaming-safe-search.js | 74 +++++++++++++++++ .../analyze-streaming-shot-change.js | 78 +++++++++++++++++ ...ze-streaming-annotation-to-storage.test.js | 35 ++++++++ .../analyze-streaming-labels.test.js | 34 ++++++++ .../analyze-streaming-object.test.js | 34 ++++++++ .../analyze-streaming-safe-search.test.js | 33 ++++++++ .../analyze-streaming-shot-change.test.js | 33 ++++++++ 10 files changed, 551 insertions(+) create mode 100644 video-intelligence/analyze-streaming-annotation-to-storage.js create mode 100644 video-intelligence/analyze-streaming-labels.js create mode 100644 video-intelligence/analyze-streaming-object.js create mode 100644 video-intelligence/analyze-streaming-safe-search.js create mode 100644 video-intelligence/analyze-streaming-shot-change.js create mode 100644 video-intelligence/system-test/analyze-streaming-annotation-to-storage.test.js create mode 100644 video-intelligence/system-test/analyze-streaming-labels.test.js create mode 100644 video-intelligence/system-test/analyze-streaming-object.test.js create mode 100644 video-intelligence/system-test/analyze-streaming-safe-search.test.js create mode 100644 video-intelligence/system-test/analyze-streaming-shot-change.test.js diff --git a/video-intelligence/analyze-streaming-annotation-to-storage.js b/video-intelligence/analyze-streaming-annotation-to-storage.js new file mode 100644 index 0000000000..69de4d0b55 --- /dev/null +++ b/video-intelligence/analyze-streaming-annotation-to-storage.js @@ -0,0 +1,74 @@ +/** + * 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. + */ + +'use strict'; + +async function main(path = 'YOUR_LOCAL_FILE', outputUri = 'PATH_TO_OUTPUT') { + // [START video_streaming_annotation_to_storage_beta] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // const path = 'Local file to analyze, e.g. ./my-file.mp4'; + // const outputUri = 'Path to output, e.g. gs://path_to_output'; + + const { + StreamingVideoIntelligenceServiceClient, + } = require('@google-cloud/video-intelligence').v1p3beta1; + const fs = require('fs'); + + // Instantiates a client + const client = new StreamingVideoIntelligenceServiceClient(); + // Streaming configuration + const configRequest = { + videoConfig: { + feature: 'STREAMING_LABEL_DETECTION', + storageConfig: { + enableStorageAnnotationResult: true, + annotationResultStorageDirectory: outputUri, + }, + }, + }; + const readStream = fs.createReadStream(path, { + highWaterMark: 5 * 1024 * 1024, //chunk size set to 5MB (recommended less than 10MB) + encoding: 'base64', + }); + //Load file content + const chunks = []; + readStream + .on('data', chunk => { + const request = { + inputContent: chunk.toString(), + }; + chunks.push(request); + }) + .on('close', function() { + // configRequest should be the first in the stream of requests + stream.write(configRequest); + for (let i = 0; i < chunks.length; i++) { + stream.write(chunks[i]); + } + stream.end(); + }); + + const stream = client.streamingAnnotateVideo().on('data', response => { + //Gets annotations for video + console.log( + `The annotation is stored at: ${response.annotationResultsUri} ` + ); + }); + // [END video_streaming_annotation_to_storage_beta] +} + +main(...process.argv.slice(2)).catch(console.error()); diff --git a/video-intelligence/analyze-streaming-labels.js b/video-intelligence/analyze-streaming-labels.js new file mode 100644 index 0000000000..b1a0861206 --- /dev/null +++ b/video-intelligence/analyze-streaming-labels.js @@ -0,0 +1,73 @@ +/** + * 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. + */ + +'use strict'; + +async function main(path = 'YOUR_LOCAL_FILE') { + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // const path = 'Local file to analyze, e.g. ./my-file.mp4'; + const { + StreamingVideoIntelligenceServiceClient, + } = require('@google-cloud/video-intelligence').v1p3beta1; + const fs = require('fs'); + + // Instantiates a client + const client = new StreamingVideoIntelligenceServiceClient(); + // Streaming configuration + const configRequest = { + videoConfig: { + feature: 'STREAMING_LABEL_DETECTION', + }, + }; + const readStream = fs.createReadStream(path, { + highWaterMark: 5 * 1024 * 1024, //chunk size set to 5MB (recommended less than 10MB) + encoding: 'base64', + }); + //Load file content + const chunks = []; + readStream + .on('data', chunk => { + const request = { + inputContent: chunk.toString(), + }; + chunks.push(request); + }) + .on('close', function() { + // configRequest should be the first in the stream of requests + stream.write(configRequest); + for (let i = 0; i < chunks.length; i++) { + stream.write(chunks[i]); + } + stream.end(); + }); + + const stream = client.streamingAnnotateVideo().on('data', response => { + //Gets annotations for video + const annotations = response.annotationResults; + const labels = annotations.labelAnnotations; + labels.forEach(label => { + console.log( + `Label ${label.entity.description} occurs at: ${label.frames[0] + .timeOffset.seconds || 0}` + + `.${(label.frames[0].timeOffset.nanos / 1e6).toFixed(0)}s` + ); + console.log(` Confidence: ${label.frames[0].confidence}`); + }); + }); + // [END video_streaming_label_detection_beta] +} +main(...process.argv.slice(2)).catch(console.error()); diff --git a/video-intelligence/analyze-streaming-object.js b/video-intelligence/analyze-streaming-object.js new file mode 100644 index 0000000000..35869b5388 --- /dev/null +++ b/video-intelligence/analyze-streaming-object.js @@ -0,0 +1,83 @@ +/** + * 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. + */ + +'use strict'; + +async function main(path = 'YOUR_LOCAL_FILE') { + // [START video_streaming_object_tracking_beta] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // const path = 'Local file to analyze, e.g. ./my-file.mp4'; + const { + StreamingVideoIntelligenceServiceClient, + } = require('@google-cloud/video-intelligence').v1p3beta1; + const fs = require('fs'); + + // Instantiates a client + const client = new StreamingVideoIntelligenceServiceClient(); + // Streaming configuration + const configRequest = { + videoConfig: { + feature: 'STREAMING_OBJECT_TRACKING', + }, + }; + const readStream = fs.createReadStream(path, { + highWaterMark: 5 * 1024 * 1024, //chunk size set to 5MB (recommended less than 10MB) + encoding: 'base64', + }); + //Load file content + const chunks = []; + readStream + .on('data', chunk => { + const request = { + inputContent: chunk.toString(), + }; + chunks.push(request); + }) + .on('close', function() { + // configRequest should be the first in the stream of requests + stream.write(configRequest); + for (let i = 0; i < chunks.length; i++) { + stream.write(chunks[i]); + } + stream.end(); + }); + + const stream = client.streamingAnnotateVideo().on('data', response => { + //Gets annotations for video + const annotations = response.annotationResults; + const objects = annotations.objectAnnotations; + objects.forEach(object => { + console.log(`Entity description: ${object.entity.description}`); + console.log(`Entity id: ${object.entity.entityId}`); + console.log(`Track id: ${object.trackId}`); + console.log(`Confidence: ${object.confidence}`); + console.log( + `Time offset for the frame: ${object.frames[0].timeOffset.seconds || + 0}` + `.${(object.frames[0].timeOffset.nanos / 1e6).toFixed(0)}s` + ); + //Every annotation has only one frame. + const box = object.frames[0].normalizedBoundingBox; + console.log(`Bounding box position:`); + console.log(` left :${box.left}`); + console.log(` top :${box.top}`); + console.log(` right :${box.right}`); + console.log(` bottom:${box.bottom}`); + }); + }); + // [END video_streaming_object_tracking_beta] +} +main(...process.argv.slice(2)).catch(console.error()); diff --git a/video-intelligence/analyze-streaming-safe-search.js b/video-intelligence/analyze-streaming-safe-search.js new file mode 100644 index 0000000000..dc89083512 --- /dev/null +++ b/video-intelligence/analyze-streaming-safe-search.js @@ -0,0 +1,74 @@ +/** + * 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. + */ + +'use strict'; + +async function main(path = 'YOUR_LOCAL_FILE') { + // [START video_streaming_explicit_content_detection_beta] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // const path = 'Local file to analyze, e.g. ./my-file.mp4'; + const { + StreamingVideoIntelligenceServiceClient, + } = require('@google-cloud/video-intelligence').v1p3beta1; + const fs = require('fs'); + + // Instantiates a client + const client = new StreamingVideoIntelligenceServiceClient(); + // Streaming configuration + const configRequest = { + videoConfig: { + feature: 'STREAMING_EXPLICIT_CONTENT_DETECTION', + }, + }; + + const readStream = fs.createReadStream(path, { + highWaterMark: 5 * 1024 * 1024, //chunk size set to 5MB (recommended less than 10MB) + encoding: 'base64', + }); + //Load file content + const chunks = []; + readStream + .on('data', chunk => { + const request = { + inputContent: chunk.toString(), + }; + chunks.push(request); + }) + .on('close', function() { + // configRequest should be the first in the stream of requests + stream.write(configRequest); + for (let i = 0; i < chunks.length; i++) { + stream.write(chunks[i]); + } + stream.end(); + }); + + const stream = client.streamingAnnotateVideo().on('data', response => { + //Gets annotations for video + const annotations = response.annotationResults; + const explicitContentResults = annotations.explicitAnnotation.frames; + explicitContentResults.forEach(result => { + console.log( + `Time: ${result.timeOffset.seconds || 0}` + + `.${(result.timeOffset.nanos / 1e6).toFixed(0)}s` + ); + console.log(` Pornography likelihood: ${result.pornographyLikelihood}`); + }); + }); + // [END video_streaming_explicit_content_detection_beta] +} +main(...process.argv.slice(2)).catch(console.error()); diff --git a/video-intelligence/analyze-streaming-shot-change.js b/video-intelligence/analyze-streaming-shot-change.js new file mode 100644 index 0000000000..1d1c3ef6c5 --- /dev/null +++ b/video-intelligence/analyze-streaming-shot-change.js @@ -0,0 +1,78 @@ +/** + * 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. + */ + +'use strict'; + +async function main(path = 'YOUR_LOCAL_FILE') { + // [START video_streaming_shot_change_detection_beta] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // const path = 'Local file to analyze, e.g. ./my-file.mp4'; + const { + StreamingVideoIntelligenceServiceClient, + } = require('@google-cloud/video-intelligence').v1p3beta1; + const fs = require('fs'); + + // Instantiates a client + const client = new StreamingVideoIntelligenceServiceClient(); + // Streaming configuration + const configRequest = { + videoConfig: { + feature: 'STREAMING_SHOT_CHANGE_DETECTION', + }, + }; + const readStream = fs.createReadStream(path, { + highWaterMark: 5 * 1024 * 1024, //chunk size set to 5MB (recommended less than 10MB) + encoding: 'base64', + }); + //Load file content + const chunks = []; + readStream + .on('data', chunk => { + const request = { + inputContent: chunk.toString(), + }; + chunks.push(request); + }) + .on('close', function() { + // configRequest should be the first in the stream of requests + stream.write(configRequest); + for (let i = 0; i < chunks.length; i++) { + stream.write(chunks[i]); + } + stream.end(); + }); + + const stream = client.streamingAnnotateVideo().on('data', response => { + //Gets annotations for video + const annotations = response.annotationResults; + const shotChanges = annotations.shotAnnotations; + console.log(JSON.stringify(shotChanges)); + if (shotChanges.length === 1) { + console.log(`The entire video is one shot.`); + } + shotChanges.forEach(shot => { + console.log( + ` Shot: ${shot.startTimeOffset.seconds || 0}` + + `.${(shot.startTimeOffset.nanos / 1e6).toFixed(0)}s to ${shot + .endTimeOffset.seconds || 0}` + + `.${(shot.endTimeOffset.nanos / 1e6).toFixed(0)}s` + ); + }); + }); + // [END video_streaming_shot_change_detection_beta] +} +main(...process.argv.slice(2)).catch(console.error()); diff --git a/video-intelligence/system-test/analyze-streaming-annotation-to-storage.test.js b/video-intelligence/system-test/analyze-streaming-annotation-to-storage.test.js new file mode 100644 index 0000000000..116150bf0f --- /dev/null +++ b/video-intelligence/system-test/analyze-streaming-annotation-to-storage.test.js @@ -0,0 +1,35 @@ +/** + * 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. + */ + +'use strict'; + +const path = require('path'); +const execa = require('execa'); +const {assert} = require('chai'); + +const cmd = `node analyze-streaming-annotation-to-storage.js`; +const cwd = path.join(__dirname, '..'); +const project = process.env.GLCOUD_PROJECT; +const exec = async cmd => (await execa.shell(cmd, {cwd})).stdout; + +const file = 'resources/cat.mp4'; +const outputUri = 'gs://' + project + '/VIDEO_STREAMING_OUTPUT'; + +describe('streaming annotation to storage', () => { + it('should store the annotation results in GCS', async () => { + const output = await exec(`${cmd} ${file} ${outputUri}`); + assert.match(output, /The annotation is stored at:/); + }); +}); diff --git a/video-intelligence/system-test/analyze-streaming-labels.test.js b/video-intelligence/system-test/analyze-streaming-labels.test.js new file mode 100644 index 0000000000..405860d351 --- /dev/null +++ b/video-intelligence/system-test/analyze-streaming-labels.test.js @@ -0,0 +1,34 @@ +/** + * 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. + */ + +'use strict'; + +const path = require('path'); +const execa = require('execa'); +const {assert} = require('chai'); + +const cmd = `node analyze-streaming-labels.js`; +const cwd = path.join(__dirname, '..'); +const exec = async cmd => (await execa.shell(cmd, {cwd})).stdout; + +const file = 'resources/cat.mp4'; + +describe('streaming label', () => { + it('should analyze labels in a streaming video', async () => { + const output = await exec(`${cmd} ${file}`); + assert.match(output, /cat/); + assert.match(output, /Confidence: \d+\.\d+/); + }); +}); diff --git a/video-intelligence/system-test/analyze-streaming-object.test.js b/video-intelligence/system-test/analyze-streaming-object.test.js new file mode 100644 index 0000000000..c26538b700 --- /dev/null +++ b/video-intelligence/system-test/analyze-streaming-object.test.js @@ -0,0 +1,34 @@ +/** + * 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. + */ + +'use strict'; + +const path = require('path'); +const execa = require('execa'); +const {assert} = require('chai'); + +const cmd = `node analyze-streaming-object.js`; +const cwd = path.join(__dirname, '..'); +const exec = async cmd => (await execa.shell(cmd, {cwd})).stdout; + +const file = 'resources/cat.mp4'; + +describe('streaming object', () => { + it('should track an object in a streaming video', async () => { + const output = await exec(`${cmd} ${file}`); + assert.match(output, /cat/); + assert.match(output, /Confidence: \d+\.\d+/); + }); +}); diff --git a/video-intelligence/system-test/analyze-streaming-safe-search.test.js b/video-intelligence/system-test/analyze-streaming-safe-search.test.js new file mode 100644 index 0000000000..d211e69a83 --- /dev/null +++ b/video-intelligence/system-test/analyze-streaming-safe-search.test.js @@ -0,0 +1,33 @@ +/** + * 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. + */ + +'use strict'; + +const path = require('path'); +const execa = require('execa'); +const {assert} = require('chai'); + +const cmd = `node analyze-streaming-safe-search.js`; +const cwd = path.join(__dirname, '..'); +const exec = async cmd => (await execa.shell(cmd, {cwd})).stdout; + +const file = 'resources/cat.mp4'; + +describe('streaming safe search', () => { + it('should analyze explicit content in a streaming video', async () => { + const output = await exec(`${cmd} ${file}`); + assert.match(output, /UNLIKELY/); + }); +}); diff --git a/video-intelligence/system-test/analyze-streaming-shot-change.test.js b/video-intelligence/system-test/analyze-streaming-shot-change.test.js new file mode 100644 index 0000000000..22774307ff --- /dev/null +++ b/video-intelligence/system-test/analyze-streaming-shot-change.test.js @@ -0,0 +1,33 @@ +/** + * 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. + */ + +'use strict'; + +const path = require('path'); +const execa = require('execa'); +const {assert} = require('chai'); + +const cmd = `node analyze-streaming-shot-change.js`; +const cwd = path.join(__dirname, '..'); +const exec = async cmd => (await execa.shell(cmd, {cwd})).stdout; + +const file = 'resources/cat.mp4'; + +describe('streaming shot change', () => { + it('should analyze shot changes in a streaming video', async () => { + const output = await exec(`${cmd} ${file}`); + assert.match(output, /The entire video is one shot./); + }); +});