Skip to content

Commit be5d236

Browse files
author
Ace Nassri
committed
Add new video samples (#382)
1 parent 0b28815 commit be5d236

File tree

4 files changed

+151
-32
lines changed

4 files changed

+151
-32
lines changed

video-intelligence/analyze.js

Lines changed: 132 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,34 @@
1818
function analyzeFaces (gcsUri) {
1919
// [START analyze_faces]
2020
// Imports the Google Cloud Video Intelligence library
21-
const Video = require('@google-cloud/videointelligence').v1beta1();
21+
const Video = require('@google-cloud/videointelligence');
2222

2323
// Instantiates a client
24-
const video = Video.videoIntelligenceServiceClient();
24+
const video = Video().videoIntelligenceServiceClient();
2525

2626
// The GCS filepath of the video to analyze
27-
// const gcsUri = 'gs://my-bucket/my-video.mp4'
27+
// const gcsUri = 'gs://my-bucket/my-video.mp4';
2828

2929
const request = {
3030
inputUri: gcsUri,
3131
features: ['FACE_DETECTION']
3232
};
3333

34-
// Detect faces in a video
34+
// Detects faces in a video
3535
video.annotateVideo(request)
3636
.then((results) => {
3737
const operation = results[0];
3838
console.log('Waiting for operation to complete...');
3939
return operation.promise();
4040
})
4141
.then((results) => {
42-
// Get faces for first video
42+
// Gets faces
4343
const faces = results[0].annotationResults[0].faceAnnotations;
44+
console.log('Faces:');
4445
faces.forEach((face, faceIdx) => {
45-
console.log('Thumbnail size:', face.thumbnail.buffer.length);
46+
console.log('\tThumbnail size:', face.thumbnail.length);
4647
face.segments.forEach((segment, segmentIdx) => {
47-
console.log(`Track ${segmentIdx} of face ${faceIdx}: frames ${segment.startTimeOffset} to ${segment.endTimeOffset}`);
48+
console.log(`\tTrack ${segmentIdx} of face ${faceIdx}: frames ${segment.startTimeOffset} to ${segment.endTimeOffset}`);
4849
});
4950
});
5051
})
@@ -54,32 +55,33 @@ function analyzeFaces (gcsUri) {
5455
// [END analyze_faces]
5556
}
5657

57-
function analyzeLabels (gcsUri) {
58-
// [START analyze_labels]
58+
function analyzeLabelsGCS (gcsUri) {
59+
// [START analyze_labels_gcs]
5960
// Imports the Google Cloud Video Intelligence library
60-
const Video = require('@google-cloud/videointelligence').v1beta1();
61+
const Video = require('@google-cloud/videointelligence');
6162

6263
// Instantiates a client
63-
const video = Video.videoIntelligenceServiceClient();
64+
const video = Video().videoIntelligenceServiceClient();
6465

6566
// The GCS filepath of the video to analyze
66-
// const gcsUri = 'gs://my-bucket/my-video.mp4'
67+
// const gcsUri = 'gs://my-bucket/my-video.mp4';
6768

6869
const request = {
6970
inputUri: gcsUri,
7071
features: ['LABEL_DETECTION']
7172
};
7273

73-
// Detect labels in a video
74+
// Detects labels in a video
7475
video.annotateVideo(request)
7576
.then((results) => {
7677
const operation = results[0];
7778
console.log('Waiting for operation to complete...');
7879
return operation.promise();
7980
})
8081
.then((results) => {
81-
// Get labels for first video
82+
// Gets labels
8283
const labels = results[0].annotationResults[0].labelAnnotations;
84+
console.log('Labels:');
8385
labels.forEach((label) => {
8486
console.log('Label description:', label.description);
8587
console.log('Locations:');
@@ -91,35 +93,83 @@ function analyzeLabels (gcsUri) {
9193
.catch((err) => {
9294
console.error('ERROR:', err);
9395
});
94-
// [END analyze_labels]
96+
// [END analyze_labels_gcs]
97+
}
98+
99+
function analyzeLabelsLocal (path) {
100+
// [START analyze_labels_local]
101+
// Imports the Google Cloud Video Intelligence library + Node's fs library
102+
const Video = require('@google-cloud/videointelligence');
103+
const fs = require('fs');
104+
105+
// Instantiates a client
106+
const video = Video().videoIntelligenceServiceClient();
107+
108+
// The local filepath of the video to analyze
109+
// const path = 'my-file.mp4';
110+
111+
// Reads a local video file and converts it to base64
112+
const file = fs.readFileSync(path);
113+
const inputContent = file.toString('base64');
114+
115+
// Constructs request
116+
const request = {
117+
inputContent: inputContent,
118+
features: ['LABEL_DETECTION']
119+
};
120+
121+
// Detects labels in a video
122+
video.annotateVideo(request)
123+
.then((results) => {
124+
const operation = results[0];
125+
console.log('Waiting for operation to complete...');
126+
return operation.promise();
127+
})
128+
.then((results) => {
129+
// Gets labels for first video
130+
const labels = results[0].annotationResults[0].labelAnnotations;
131+
console.log('Labels:');
132+
labels.forEach((label) => {
133+
console.log('Label description:', label.description);
134+
console.log('Locations:');
135+
label.locations.forEach((location) => {
136+
console.log(`\tFrames ${location.segment.startTimeOffset} to ${location.segment.endTimeOffset}`);
137+
});
138+
});
139+
})
140+
.catch((err) => {
141+
console.error('ERROR:', err);
142+
});
143+
// [END analyze_labels_local]
95144
}
96145

97146
function analyzeShots (gcsUri) {
98147
// [START analyze_shots]
99148
// Imports the Google Cloud Video Intelligence library
100-
const Video = require('@google-cloud/videointelligence').v1beta1();
149+
const Video = require('@google-cloud/videointelligence');
101150

102151
// Instantiates a client
103-
const video = Video.videoIntelligenceServiceClient();
152+
const video = Video().videoIntelligenceServiceClient();
104153

105154
// The GCS filepath of the video to analyze
106-
// const gcsUri = 'gs://my-bucket/my-video.mp4'
155+
// const gcsUri = 'gs://my-bucket/my-video.mp4';
107156

108157
const request = {
109158
inputUri: gcsUri,
110159
features: ['SHOT_CHANGE_DETECTION']
111160
};
112161

113-
// Detect camera shot changes
162+
// Detects camera shot changes
114163
video.annotateVideo(request)
115164
.then((results) => {
116165
const operation = results[0];
117166
console.log('Waiting for operation to complete...');
118167
return operation.promise();
119168
})
120169
.then((results) => {
121-
// Get shot changes for first video
170+
// Gets shot changes
122171
const shotChanges = results[0].annotationResults[0].shotAnnotations;
172+
console.log('Shot changes:');
123173
shotChanges.forEach((shot, shotIdx) => {
124174
console.log(`Scene ${shotIdx}:`);
125175
console.log(`\tStart: ${shot.startTimeOffset}`);
@@ -132,29 +182,85 @@ function analyzeShots (gcsUri) {
132182
// [END analyze_shots]
133183
}
134184

185+
function analyzeSafeSearch (gcsUri) {
186+
// [START analyze_safe_search]
187+
// Imports the Google Cloud Video Intelligence library
188+
const Video = require('@google-cloud/videointelligence');
189+
190+
// Instantiates a client
191+
const video = Video().videoIntelligenceServiceClient();
192+
193+
// The GCS filepath of the video to analyze
194+
// const gcsUri = 'gs://my-bucket/my-video.mp4';
195+
196+
const request = {
197+
inputUri: gcsUri,
198+
features: ['SAFE_SEARCH_DETECTION']
199+
};
200+
201+
// Detects unsafe content
202+
video.annotateVideo(request)
203+
.then((results) => {
204+
const operation = results[0];
205+
console.log('Waiting for operation to complete...');
206+
return operation.promise();
207+
})
208+
.then((results) => {
209+
// Gets unsafe content
210+
const safeSearchResults = results[0].annotationResults[0].safeSearchAnnotations;
211+
console.log('Safe search results:');
212+
safeSearchResults.forEach((result) => {
213+
console.log(`Frame ${result.timeOffset}:`);
214+
console.log(`\tAdult: ${result.adult}`);
215+
console.log(`\tSpoof: ${result.spoof}`);
216+
console.log(`\tMedical: ${result.medical}`);
217+
console.log(`\tViolent: ${result.violent}`);
218+
console.log(`\tRacy: ${result.racy}`);
219+
});
220+
})
221+
.catch((err) => {
222+
console.error('ERROR:', err);
223+
});
224+
// [END analyze_safe_search]
225+
}
226+
135227
require(`yargs`) // eslint-disable-line
136228
.demand(1)
137229
.command(
138230
`faces <gcsUri>`,
139-
`Analyzes faces in a video using the Cloud Video Intelligence API.`,
231+
`Analyzes faces in a video stored in Google Cloud Storage using the Cloud Video Intelligence API.`,
140232
{},
141233
(opts) => analyzeFaces(opts.gcsUri)
142234
)
143235
.command(
144236
`shots <gcsUri>`,
145-
`Analyzes shot angles in a video using the Cloud Video Intelligence API.`,
237+
`Analyzes shot angles in a video stored in Google Cloud Storage using the Cloud Video Intelligence API.`,
146238
{},
147239
(opts) => analyzeShots(opts.gcsUri)
148240
)
149241
.command(
150-
`labels <gcsUri>`,
151-
`Labels objects in a video using the Cloud Video Intelligence API.`,
242+
`labels-gcs <gcsUri>`,
243+
`Labels objects in a video stored in Google Cloud Storage using the Cloud Video Intelligence API.`,
244+
{},
245+
(opts) => analyzeLabelsGCS(opts.gcsUri)
246+
)
247+
.command(
248+
`labels-file <gcsUri>`,
249+
`Labels objects in a video stored locally using the Cloud Video Intelligence API.`,
250+
{},
251+
(opts) => analyzeLabelsLocal(opts.gcsUri)
252+
)
253+
.command(
254+
`safe-search <gcsUri>`,
255+
`Detects adult content in a video stored in Google Cloud Storage.`,
152256
{},
153-
(opts) => analyzeLabels(opts.gcsUri)
257+
(opts) => analyzeSafeSearch(opts.gcsUri)
154258
)
155259
.example(`node $0 faces gs://my-bucket/my-video.mp4`)
156260
.example(`node $0 shots gs://my-bucket/my-video.mp4`)
157-
.example(`node $0 labels gs://my-bucket/my-video.mp4`)
261+
.example(`node $0 labels-gcs gs://my-bucket/my-video.mp4`)
262+
.example(`node $0 labels-file my-video.mp4`)
263+
.example(`node $0 safe-search gs://my-bucket/my-video.mp4`)
158264
.wrap(120)
159265
.recommendCommands()
160266
.epilogue(`For more information, see https://cloud.google.com/video-intelligence/docs`)

video-intelligence/quickstart.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ video.annotateVideo(request)
4747
// Gets faces for video from its annotations
4848
const faces = annotations.faceAnnotations;
4949
faces.forEach((face, faceIdx) => {
50-
console.log('Thumbnail size:', face.thumbnail.buffer.length);
50+
console.log('Thumbnail size:', face.thumbnail.length);
5151
face.segments.forEach((segment, segmentIdx) => {
5252
console.log(`Track ${segmentIdx} of face ${faceIdx}: frames ${segment.startTimeOffset} to ${segment.endTimeOffset}`);
5353
});
6.1 MB
Binary file not shown.

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,32 @@ const cmd = `node analyze.js`;
2525
const cwd = path.join(__dirname, `..`);
2626

2727
// analyze_faces
28-
test(`should analyze faces`, async (t) => {
28+
test(`should analyze faces in a GCS file`, async (t) => {
2929
const output = await tools.runAsync(`${cmd} faces gs://nodejs-docs-samples/video/google_gmail.mp4`, cwd);
3030
t.regex(output, /Thumbnail size: \d+/);
3131
});
3232

33-
// analyze_labels
34-
test(`should analyze labels`, async (t) => {
35-
const output = await tools.runAsync(`${cmd} labels gs://nodejs-docs-samples/video/cat.mp4`, cwd);
33+
// analyze_labels_gcs
34+
test(`should analyze labels in a GCS file`, async (t) => {
35+
const output = await tools.runAsync(`${cmd} labels-gcs gs://nodejs-docs-samples/video/cat.mp4`, cwd);
36+
t.regex(output, /Label description: Whiskers/);
37+
});
38+
39+
// analyze_labels_local
40+
test(`should analyze labels in a local file`, async (t) => {
41+
const output = await tools.runAsync(`${cmd} labels-file resources/cat.mp4`, cwd);
3642
t.regex(output, /Label description: Whiskers/);
3743
});
3844

3945
// analyze_shots
40-
test(`should analyze shots`, async (t) => {
46+
test(`should analyze shots in a GCS file`, async (t) => {
4147
const output = await tools.runAsync(`${cmd} shots gs://nodejs-docs-samples/video/gbike_dinosaur.mp4`, cwd);
4248
t.regex(output, /Scene 0:/);
4349
});
50+
51+
// analyze_safe_search
52+
test(`should analyze safe search results in a GCS file`, async (t) => {
53+
const output = await tools.runAsync(`${cmd} safe-search gs://nodejs-docs-samples/video/google_gmail.mp4`, cwd);
54+
t.regex(output, /Frame \d+/);
55+
t.regex(output, /Spoof: \d+/);
56+
});

0 commit comments

Comments
 (0)