Skip to content

Commit 750e13c

Browse files
nirupa-kumarAhrar Monsur
authored and
Ahrar Monsur
committed
docs(samples): Object tracking and Text detection GA samples (#202)
1 parent 3747929 commit 750e13c

File tree

3 files changed

+295
-1
lines changed

3 files changed

+295
-1
lines changed

video-intelligence/analyze.js

+265
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,241 @@ async function analyzeVideoTranscription(gcsUri) {
301301
// [END video_speech_transcription_gcs]
302302
}
303303

304+
async function analyzeTextGCS(gcsUri) {
305+
//gcsUri - GCS URI of the video to analyze, e.g. gs://my-bucket/my-video.mp4
306+
//[START video_detect_text_gcs]
307+
// Imports the Google Cloud Video Intelligence library
308+
const Video = require('@google-cloud/video-intelligence');
309+
// Creates a client
310+
const video = new Video.VideoIntelligenceServiceClient();
311+
312+
/**
313+
* TODO(developer): Uncomment the following line before running the sample.
314+
*/
315+
// const gcsUri = 'GCS URI of the video to analyze, e.g. gs://my-bucket/my-video.mp4';
316+
317+
const request = {
318+
inputUri: gcsUri,
319+
features: ['TEXT_DETECTION'],
320+
};
321+
// Detects text in a video
322+
const [operation] = await video.annotateVideo(request);
323+
const results = await operation.promise();
324+
console.log('Waiting for operation to complete...');
325+
// Gets annotations for video
326+
const textAnnotations = results[0].annotationResults[0].textAnnotations;
327+
textAnnotations.forEach(textAnnotation => {
328+
console.log(`Text ${textAnnotation.text} occurs at:`);
329+
textAnnotation.segments.forEach(segment => {
330+
const time = segment.segment;
331+
console.log(
332+
` Start: ${time.startTimeOffset.seconds || 0}.${(
333+
time.startTimeOffset.nanos / 1e6
334+
).toFixed(0)}s`
335+
);
336+
console.log(
337+
` End: ${time.endTimeOffset.seconds || 0}.${(
338+
time.endTimeOffset.nanos / 1e6
339+
).toFixed(0)}s`
340+
);
341+
console.log(` Confidence: ${segment.confidence}`);
342+
segment.frames.forEach(frame => {
343+
const timeOffset = frame.timeOffset;
344+
console.log(
345+
`Time offset for the frame: ${timeOffset.seconds || 0}` +
346+
`.${(timeOffset.nanos / 1e6).toFixed(0)}s`
347+
);
348+
console.log(`Rotated Bounding Box Vertices:`);
349+
frame.rotatedBoundingBox.vertices.forEach(vertex => {
350+
console.log(`Vertex.x:${vertex.x}, Vertex.y:${vertex.y}`);
351+
});
352+
});
353+
});
354+
});
355+
// [END video_detect_text_gcs]
356+
}
357+
358+
async function analyzeObjectTrackingGCS(gcsUri) {
359+
//gcsUri - GCS URI of the video to analyze, e.g. gs://my-bucket/my-video.mp4
360+
//[START video_object_tracking_gcs]
361+
// Imports the Google Cloud Video Intelligence library
362+
const Video = require('@google-cloud/video-intelligence');
363+
364+
// Creates a client
365+
const video = new Video.VideoIntelligenceServiceClient();
366+
367+
/**
368+
* TODO(developer): Uncomment the following line before running the sample.
369+
*/
370+
// const gcsUri = 'GCS URI of the video to analyze, e.g. gs://my-bucket/my-video.mp4';
371+
372+
const request = {
373+
inputUri: gcsUri,
374+
features: ['OBJECT_TRACKING'],
375+
//recommended to use us-east1 for the best latency due to different types of processors used in this region and others
376+
locationId: 'us-east1',
377+
};
378+
// Detects objects in a video
379+
const [operation] = await video.annotateVideo(request);
380+
const results = await operation.promise();
381+
console.log('Waiting for operation to complete...');
382+
//Gets annotations for video
383+
const annotations = results[0].annotationResults[0];
384+
const objects = annotations.objectAnnotations;
385+
objects.forEach(object => {
386+
console.log(`Entity description: ${object.entity.description}`);
387+
console.log(`Entity id: ${object.entity.entityId}`);
388+
const time = object.segment;
389+
console.log(
390+
`Segment: ${time.startTimeOffset.seconds || 0}` +
391+
`.${(time.startTimeOffset.nanos / 1e6).toFixed(0)}s to ${time
392+
.endTimeOffset.seconds || 0}.` +
393+
`${(time.endTimeOffset.nanos / 1e6).toFixed(0)}s`
394+
);
395+
console.log(`Confidence: ${object.confidence}`);
396+
const frame = object.frames[0];
397+
const box = frame.normalizedBoundingBox;
398+
const timeOffset = frame.timeOffset;
399+
console.log(
400+
`Time offset for the first frame: ${timeOffset.seconds || 0}` +
401+
`.${(timeOffset.nanos / 1e6).toFixed(0)}s`
402+
);
403+
console.log(`Bounding box position:`);
404+
console.log(` left :${box.left}`);
405+
console.log(` top :${box.top}`);
406+
console.log(` right :${box.right}`);
407+
console.log(` bottom :${box.bottom}`);
408+
});
409+
// [END video_object_tracking_gcs]
410+
}
411+
412+
async function analyzeText(path) {
413+
//[START video_detect_text]
414+
// Imports the Google Cloud Video Intelligence library + Node's fs library
415+
const Video = require('@google-cloud/video-intelligence');
416+
const fs = require('fs');
417+
const util = require('util');
418+
// Creates a client
419+
const video = new Video.VideoIntelligenceServiceClient();
420+
421+
/**
422+
* TODO(developer): Uncomment the following line before running the sample.
423+
*/
424+
// const path = 'Local file to analyze, e.g. ./my-file.mp4';
425+
426+
// Reads a local video file and converts it to base64
427+
const file = await util.promisify(fs.readFile)(path);
428+
const inputContent = file.toString('base64');
429+
430+
const request = {
431+
inputContent: inputContent,
432+
features: ['TEXT_DETECTION'],
433+
};
434+
// Detects text in a video
435+
const [operation] = await video.annotateVideo(request);
436+
const results = await operation.promise();
437+
console.log('Waiting for operation to complete...');
438+
439+
// Gets annotations for video
440+
const textAnnotations = results[0].annotationResults[0].textAnnotations;
441+
textAnnotations.forEach(textAnnotation => {
442+
console.log(`Text ${textAnnotation.text} occurs at:`);
443+
textAnnotation.segments.forEach(segment => {
444+
const time = segment.segment;
445+
if (time.startTimeOffset.seconds === undefined) {
446+
time.startTimeOffset.seconds = 0;
447+
}
448+
if (time.startTimeOffset.nanos === undefined) {
449+
time.startTimeOffset.nanos = 0;
450+
}
451+
if (time.endTimeOffset.seconds === undefined) {
452+
time.endTimeOffset.seconds = 0;
453+
}
454+
if (time.endTimeOffset.nanos === undefined) {
455+
time.endTimeOffset.nanos = 0;
456+
}
457+
console.log(
458+
`\tStart: ${time.startTimeOffset.seconds || 0}` +
459+
`.${(time.startTimeOffset.nanos / 1e6).toFixed(0)}s`
460+
);
461+
console.log(
462+
`\tEnd: ${time.endTimeOffset.seconds || 0}.` +
463+
`${(time.endTimeOffset.nanos / 1e6).toFixed(0)}s`
464+
);
465+
console.log(`\tConfidence: ${segment.confidence}`);
466+
segment.frames.forEach(frame => {
467+
const timeOffset = frame.timeOffset;
468+
console.log(
469+
`Time offset for the frame: ${timeOffset.seconds || 0}` +
470+
`.${(timeOffset.nanos / 1e6).toFixed(0)}s`
471+
);
472+
console.log(`Rotated Bounding Box Vertices:`);
473+
frame.rotatedBoundingBox.vertices.forEach(vertex => {
474+
console.log(`Vertex.x:${vertex.x}, Vertex.y:${vertex.y}`);
475+
});
476+
});
477+
});
478+
});
479+
// [END video_detect_text]
480+
}
481+
482+
async function analyzeObjectTracking(path) {
483+
//[START video_object_tracking]
484+
// Imports the Google Cloud Video Intelligence library
485+
const Video = require('@google-cloud/video-intelligence');
486+
const fs = require('fs');
487+
const util = require('util');
488+
// Creates a client
489+
const video = new Video.VideoIntelligenceServiceClient();
490+
/**
491+
* TODO(developer): Uncomment the following line before running the sample.
492+
*/
493+
// const path = 'Local file to analyze, e.g. ./my-file.mp4';
494+
495+
// Reads a local video file and converts it to base64
496+
const file = await util.promisify(fs.readFile)(path);
497+
const inputContent = file.toString('base64');
498+
499+
const request = {
500+
inputContent: inputContent,
501+
features: ['OBJECT_TRACKING'],
502+
//recommended to use us-east1 for the best latency due to different types of processors used in this region and others
503+
locationId: 'us-east1',
504+
};
505+
// Detects objects in a video
506+
const [operation] = await video.annotateVideo(request);
507+
const results = await operation.promise();
508+
console.log('Waiting for operation to complete...');
509+
//Gets annotations for video
510+
const annotations = results[0].annotationResults[0];
511+
const objects = annotations.objectAnnotations;
512+
objects.forEach(object => {
513+
console.log(`Entity description: ${object.entity.description}`);
514+
console.log(`Entity id: ${object.entity.entityId}`);
515+
const time = object.segment;
516+
console.log(
517+
`Segment: ${time.startTimeOffset.seconds || 0}` +
518+
`.${(time.startTimeOffset.nanos / 1e6).toFixed(0)}s to ${time
519+
.endTimeOffset.seconds || 0}.` +
520+
`${(time.endTimeOffset.nanos / 1e6).toFixed(0)}s`
521+
);
522+
console.log(`Confidence: ${object.confidence}`);
523+
const frame = object.frames[0];
524+
const box = frame.normalizedBoundingBox;
525+
const timeOffset = frame.timeOffset;
526+
console.log(
527+
`Time offset for the first frame: ${timeOffset.seconds || 0}` +
528+
`.${(timeOffset.nanos / 1e6).toFixed(0)}s`
529+
);
530+
console.log(`Bounding box position:`);
531+
console.log(` left :${box.left}`);
532+
console.log(` top :${box.top}`);
533+
console.log(` right :${box.right}`);
534+
console.log(` bottom :${box.bottom}`);
535+
});
536+
// [END video_object_tracking]
537+
}
538+
304539
async function main() {
305540
require(`yargs`)
306541
.demand(1)
@@ -334,11 +569,41 @@ async function main() {
334569
{},
335570
opts => analyzeVideoTranscription(opts.gcsUri)
336571
)
572+
.command(
573+
`video-text-gcs <gcsUri>`,
574+
`Analyzes text in a video stored in Google Cloud Storage using the Cloud Video Intelligence API.`,
575+
{},
576+
opts => analyzeTextGCS(opts.gcsUri)
577+
)
578+
.command(
579+
`track-objects-gcs <gcsUri>`,
580+
`Analyzes objects in a video stored in Google Cloud Storage using the Cloud Video Intelligence API.`,
581+
{},
582+
opts => analyzeObjectTrackingGCS(opts.gcsUri)
583+
)
584+
.command(
585+
`video-text <path>`,
586+
`Analyzes text in a video stored in a local file using the Cloud Video Intelligence API.`,
587+
{},
588+
opts => analyzeText(opts.path)
589+
)
590+
.command(
591+
`track-objects <path>`,
592+
`Analyzes objects in a video stored in a local file using the Cloud Video Intelligence API.`,
593+
{},
594+
opts => analyzeObjectTracking(opts.path)
595+
)
337596
.example(`node $0 shots gs://demomaker/sushi.mp4`)
338597
.example(`node $0 labels-gcs gs://demomaker/tomatoes.mp4`)
339598
.example(`node $0 labels-file cat.mp4`)
340599
.example(`node $0 safe-search gs://demomaker/tomatoes.mp4`)
341600
.example(`node $0 transcription gs://demomaker/tomatoes.mp4`)
601+
.example(`node $0 video-text ./resources/googlework_short.mp4`)
602+
.example(
603+
`node $0 video-text-gcs gs://nodejs-docs-samples/videos/googlework_short.mp4`
604+
)
605+
.example(`node $0 track-objects ./resources/cat.mp4`)
606+
.example(`node $0 track-objects-gcs gs://nodejs-docs-samples/video/cat.mp4`)
342607
.wrap(120)
343608
.recommendCommands()
344609
.epilogue(

video-intelligence/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"node": ">=8"
1313
},
1414
"scripts": {
15-
"test": "mocha system-test --timeout=600000"
15+
"test": "mocha system-test --timeout=800000"
1616
},
1717
"dependencies": {
1818
"@google-cloud/video-intelligence": "^1.6.0",

video-intelligence/system-test/analyze.test.js

+29
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ const cmd = 'node analyze.js';
2525
const cwd = path.join(__dirname, '..');
2626
const url = 'gs://nodejs-docs-samples-video/quickstart.mp4';
2727
const shortUrl = 'gs://nodejs-docs-samples-video/quickstart_short.mp4';
28+
const catUrl = 'gs://nodejs-docs-samples/video/cat.mp4';
2829
const file = 'resources/cat.mp4';
30+
const file2 = 'resources/googlework_short.mp4';
31+
const possibleTexts = /Google|GOOGLE|SUR|OMAR|ROTO|Vice President|58oo9|LONDRES|PARIS|METRO|RUE|CARLO/;
2932

3033
const exec = async cmd => (await execa.shell(cmd, {cwd})).stdout;
3134

@@ -75,4 +78,30 @@ describe('analyze samples', () => {
7578
const output = await exec(`${cmd} transcription ${shortUrl}`);
7679
assert.match(output, /over the pass/);
7780
});
81+
82+
//detect_text_gcs
83+
it('should detect text in a GCS file', async () => {
84+
const output = await exec(`${cmd} video-text-gcs ${shortUrl}`);
85+
assert.match(output, possibleTexts);
86+
});
87+
88+
//detect_text
89+
it('should detect text in a local file', async () => {
90+
const output = await exec(`${cmd} video-text ${file2}`);
91+
assert.match(output, possibleTexts);
92+
});
93+
94+
//object_tracking_gcs
95+
it('should track objects in a GCS file', async () => {
96+
const output = await exec(`${cmd} track-objects-gcs ${catUrl}`);
97+
assert.match(output, /cat/);
98+
assert.match(output, /Confidence: \d+\.\d+/);
99+
});
100+
101+
//object_tracking
102+
it('should track objects in a local file', async () => {
103+
const output = await exec(`${cmd} track-objects ${file}`);
104+
assert.match(output, /cat/);
105+
assert.match(output, /Confidence: \d+\.\d+/);
106+
});
78107
});

0 commit comments

Comments
 (0)