Skip to content

Commit 2ac3dd6

Browse files
author
Ace Nassri
authored
Switch to faster videos + update print statements (#395)
1 parent 8b6b0a2 commit 2ac3dd6

File tree

5 files changed

+133
-85
lines changed

5 files changed

+133
-85
lines changed

video/analyze.js

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

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

2626
// The GCS filepath of the video to analyze
2727
// const gcsUri = 'gs://my-bucket/my-video.mp4';
@@ -43,15 +43,23 @@ function analyzeFaces (gcsUri) {
4343
const faces = results[0].annotationResults[0].faceAnnotations;
4444
console.log('Faces:');
4545
faces.forEach((face, faceIdx) => {
46-
console.log('\tThumbnail size:', face.thumbnail.length);
47-
face.segments.forEach((segment, segmentIdx) => {
48-
if (segment.startTimeOffset === -1 && segment.endTimeOffset === -1) {
49-
console.log(`\tEntire video`);
50-
} else {
46+
console.log('Thumbnail size:', face.thumbnail.length);
47+
48+
const isEntireVideo = face.segments.some((segment) =>
49+
segment.startTimeOffset.toNumber() === -1 &&
50+
segment.endTimeOffset.toNumber() === -1
51+
);
52+
53+
if (isEntireVideo) {
54+
console.log(`Face #${faceIdx}`);
55+
console.log(`\tEntire video`);
56+
} else {
57+
face.segments.forEach((segment, segmentIdx) => {
58+
console.log(`Face #${faceIdx}, appearance #${segmentIdx}:`);
5159
console.log(`\tStart: ${segment.startTimeOffset / 1e6}s`);
5260
console.log(`\tEnd: ${segment.endTimeOffset / 1e6}s`);
53-
}
54-
});
61+
});
62+
}
5563
});
5664
})
5765
.catch((err) => {
@@ -63,10 +71,10 @@ function analyzeFaces (gcsUri) {
6371
function analyzeLabelsGCS (gcsUri) {
6472
// [START analyze_labels_gcs]
6573
// Imports the Google Cloud Video Intelligence library
66-
const Video = require('@google-cloud/videointelligence');
74+
const Video = require('@google-cloud/video-intelligence');
6775

6876
// Instantiates a client
69-
const video = Video().videoIntelligenceServiceClient();
77+
const video = Video();
7078

7179
// The GCS filepath of the video to analyze
7280
// const gcsUri = 'gs://my-bucket/my-video.mp4';
@@ -88,16 +96,20 @@ function analyzeLabelsGCS (gcsUri) {
8896
const labels = results[0].annotationResults[0].labelAnnotations;
8997
console.log('Labels:');
9098
labels.forEach((label) => {
91-
console.log('Label description:', label.description);
92-
console.log('Locations:');
93-
label.locations.forEach((location) => {
94-
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
95-
console.log(`\tEntire video`);
96-
} else {
99+
console.log(`Label ${label.description} occurs at:`);
100+
const isEntireVideo = label.locations.some((location) =>
101+
location.segment.startTimeOffset.toNumber() === -1 &&
102+
location.segment.endTimeOffset.toNumber() === -1
103+
);
104+
105+
if (isEntireVideo) {
106+
console.log(`\tEntire video`);
107+
} else {
108+
label.locations.forEach((location) => {
97109
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`);
98110
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`);
99-
}
100-
});
111+
});
112+
}
101113
});
102114
})
103115
.catch((err) => {
@@ -109,11 +121,11 @@ function analyzeLabelsGCS (gcsUri) {
109121
function analyzeLabelsLocal (path) {
110122
// [START analyze_labels_local]
111123
// Imports the Google Cloud Video Intelligence library + Node's fs library
112-
const Video = require('@google-cloud/videointelligence');
124+
const Video = require('@google-cloud/video-intelligence');
113125
const fs = require('fs');
114126

115127
// Instantiates a client
116-
const video = Video().videoIntelligenceServiceClient();
128+
const video = Video();
117129

118130
// The local filepath of the video to analyze
119131
// const path = 'my-file.mp4';
@@ -140,16 +152,20 @@ function analyzeLabelsLocal (path) {
140152
const labels = results[0].annotationResults[0].labelAnnotations;
141153
console.log('Labels:');
142154
labels.forEach((label) => {
143-
console.log('Label description:', label.description);
144-
console.log('Locations:');
145-
label.locations.forEach((location) => {
146-
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
147-
console.log(`\tEntire video`);
148-
} else {
155+
console.log(`Label ${label.description} occurs at:`);
156+
const isEntireVideo = label.locations.some((location) =>
157+
location.segment.startTimeOffset.toNumber() === -1 &&
158+
location.segment.endTimeOffset.toNumber() === -1
159+
);
160+
161+
if (isEntireVideo) {
162+
console.log(`\tEntire video`);
163+
} else {
164+
label.locations.forEach((location) => {
149165
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`);
150166
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`);
151-
}
152-
});
167+
});
168+
}
153169
});
154170
})
155171
.catch((err) => {
@@ -161,10 +177,10 @@ function analyzeLabelsLocal (path) {
161177
function analyzeShots (gcsUri) {
162178
// [START analyze_shots]
163179
// Imports the Google Cloud Video Intelligence library
164-
const Video = require('@google-cloud/videointelligence');
180+
const Video = require('@google-cloud/video-intelligence');
165181

166182
// Instantiates a client
167-
const video = Video().videoIntelligenceServiceClient();
183+
const video = Video();
168184

169185
// The GCS filepath of the video to analyze
170186
// const gcsUri = 'gs://my-bucket/my-video.mp4';
@@ -185,15 +201,16 @@ function analyzeShots (gcsUri) {
185201
// Gets shot changes
186202
const shotChanges = results[0].annotationResults[0].shotAnnotations;
187203
console.log('Shot changes:');
188-
shotChanges.forEach((shot, shotIdx) => {
189-
console.log(`Scene ${shotIdx}:`);
190-
if (shot.startTimeOffset === -1 && shot.endTimeOffset === -1) {
191-
console.log(`\tEntire video`);
192-
} else {
193-
console.log(`\tStart: ${shot.startTimeOffset}`);
194-
console.log(`\tEnd: ${shot.endTimeOffset}`);
195-
}
196-
});
204+
205+
if (shotChanges.length === 1) {
206+
console.log(`The entire video is one shot.`);
207+
} else {
208+
shotChanges.forEach((shot, shotIdx) => {
209+
console.log(`Shot ${shotIdx} occurs from:`);
210+
console.log(`\tStart: ${shot.startTimeOffset / 1e6}s`);
211+
console.log(`\tEnd: ${shot.endTimeOffset / 1e6}s`);
212+
});
213+
}
197214
})
198215
.catch((err) => {
199216
console.error('ERROR:', err);
@@ -204,10 +221,10 @@ function analyzeShots (gcsUri) {
204221
function analyzeSafeSearch (gcsUri) {
205222
// [START analyze_safe_search]
206223
// Imports the Google Cloud Video Intelligence library
207-
const Video = require('@google-cloud/videointelligence');
224+
const Video = require('@google-cloud/video-intelligence');
208225

209226
// Instantiates a client
210-
const video = Video().videoIntelligenceServiceClient();
227+
const video = Video();
211228

212229
// The GCS filepath of the video to analyze
213230
// const gcsUri = 'gs://my-bucket/my-video.mp4';
@@ -278,11 +295,11 @@ require(`yargs`) // eslint-disable-line
278295
{},
279296
(opts) => analyzeSafeSearch(opts.gcsUri)
280297
)
281-
.example(`node $0 faces gs://demomaker/volleyball_court.mp4`)
282-
.example(`node $0 shots gs://demomaker/volleyball_court.mp4`)
283-
.example(`node $0 labels-gcs gs://demomaker/volleyball_court.mp4`)
298+
.example(`node $0 faces gs://demomaker/larry_sergey_ice_bucket_short.mp4`)
299+
.example(`node $0 shots gs://demomaker/sushi.mp4`)
300+
.example(`node $0 labels-gcs gs://demomaker/tomatoes.mp4`)
284301
.example(`node $0 labels-file cat.mp4`)
285-
.example(`node $0 safe-search gs://demomaker/volleyball_court.mp4`)
302+
.example(`node $0 safe-search gs://demomaker/tomatoes.mp4`)
286303
.wrap(120)
287304
.recommendCommands()
288305
.epilogue(`For more information, see https://cloud.google.com/video-intelligence/docs`)

video/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
"scripts": {
1515
"lint": "samples lint",
1616
"pretest": "npm run lint",
17-
"system-test": "ava -T 10m --verbose system-test/*.test.js",
17+
"system-test": "ava -T 5m --verbose system-test/*.test.js",
1818
"test": "npm run system-test"
1919
},
2020
"dependencies": {
21-
"@google-cloud/videointelligence": "https://storage.googleapis.com/videointelligence-alpha/videointelligence-nodejs.tar.gz",
21+
"@google-cloud/video-intelligence": "0.1.0",
2222
"googleapis": "19.0.0",
23+
"long": "^3.2.0",
2324
"safe-buffer": "5.0.1",
2425
"yargs": "7.1.0"
2526
},

video/quickstart.js

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717

1818
// [START videointelligence_quickstart]
1919
// Imports the Google Cloud Video Intelligence library
20-
const Video = require('@google-cloud/videointelligence').v1beta1();
20+
const Video = require('@google-cloud/video-intelligence');
2121

2222
// Instantiates a client
23-
const video = Video.videoIntelligenceServiceClient({
23+
const video = Video({
2424
projectId: process.env.GCLOUD_PROJECT // Replace with your Google Cloud project ID
2525
});
2626

2727
// The GCS filepath of the video to analyze
28-
const gcsUri = 'gs://demomaker/volleyball_court.mp4';
28+
const gcsUri = 'gs://demomaker/tomatoes.mp4';
2929

3030
// Construct request
3131
const request = {
@@ -48,42 +48,54 @@ video.annotateVideo(request)
4848
const faces = annotations.faceAnnotations;
4949
faces.forEach((face, faceIdx) => {
5050
console.log('Thumbnail size:', face.thumbnail.length);
51-
face.segments.forEach((segment, segmentIdx) => {
52-
console.log(`Face #${faceIdx}, appearance #${segmentIdx}:`);
53-
if (segment.startTimeOffset === -1 && segment.endTimeOffset === -1) {
54-
console.log(`\tEntire video`);
55-
} else {
51+
52+
const isEntireVideo = face.segments.some((segment) =>
53+
segment.startTimeOffset.toNumber() === -1 &&
54+
segment.endTimeOffset.toNumber() === -1
55+
);
56+
57+
if (isEntireVideo) {
58+
console.log(`Face #${faceIdx}`);
59+
console.log(`\tEntire video`);
60+
} else {
61+
face.segments.forEach((segment, segmentIdx) => {
62+
console.log(`Face #${faceIdx}, appearance #${segmentIdx}:`);
5663
console.log(`\tStart: ${segment.startTimeOffset / 1e6}s`);
5764
console.log(`\tEnd: ${segment.endTimeOffset / 1e6}s`);
58-
}
59-
});
65+
});
66+
}
6067
});
6168

6269
// Gets labels for video from its annotations
6370
const labels = annotations.labelAnnotations;
6471
labels.forEach((label) => {
6572
console.log(`Label ${label.description} occurs at:`);
66-
label.locations.forEach((location) => {
67-
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
68-
console.log(`\tEntire video`);
69-
} else {
73+
const isEntireVideo = label.locations.some((location) =>
74+
location.segment.startTimeOffset.toNumber() === -1 &&
75+
location.segment.endTimeOffset.toNumber() === -1
76+
);
77+
78+
if (isEntireVideo) {
79+
console.log(`\tEntire video`);
80+
} else {
81+
label.locations.forEach((location) => {
7082
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`);
7183
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`);
72-
}
73-
});
84+
});
85+
}
7486
});
7587

7688
// Gets shot changes for video from its annotations
7789
const shotChanges = annotations.shotAnnotations;
78-
shotChanges.forEach((shot, shotIdx) => {
79-
console.log(`Scene ${shotIdx} occurs from:`);
80-
if (shot.startTimeOffset === -1 && shot.endTimeOffset === -1) {
81-
console.log(`\tEntire video`);
82-
} else {
90+
if (shotChanges.length === 1) {
91+
console.log(`The entire video is one scene.`);
92+
} else {
93+
shotChanges.forEach((shot, shotIdx) => {
94+
console.log(`Scene ${shotIdx} occurs from:`);
8395
console.log(`\tStart: ${shot.startTimeOffset / 1e6}s`);
8496
console.log(`\tEnd: ${shot.endTimeOffset / 1e6}s`);
85-
}
86-
});
97+
});
98+
}
8799
})
88100
.catch((err) => {
89101
console.error('ERROR:', err);

video/system-test/analyze.test.js

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,48 @@ const cwd = path.join(__dirname, `..`);
2626

2727
// analyze_faces
2828
test(`should analyze faces in a GCS file`, async (t) => {
29-
const output = await tools.runAsync(`${cmd} faces gs://nodejs-docs-samples/video/google_gmail.mp4`, cwd);
29+
const output = await tools.runAsync(`${cmd} faces gs://demomaker/larry_sergey_ice_bucket_short.mp4`, cwd);
3030
t.regex(output, /Thumbnail size: \d+/);
31+
t.regex(output, /Start: \d+\.\d+s/);
32+
t.regex(output, /End: \d+\.\d+s/);
3133
});
3234

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/);
35+
// analyze_labels_gcs (one scene)
36+
test(`should analyze labels in a GCS file with one scene`, async (t) => {
37+
const output = await tools.runAsync(`${cmd} labels-gcs gs://demomaker/tomatoes.mp4`, cwd);
38+
t.regex(output, /Label Tomato occurs at:/);
39+
t.regex(output, /Entire video/);
40+
});
41+
42+
// analyze_labels_gcs (multiple scenes)
43+
test(`should analyze labels in a GCS file with multiple scenes`, async (t) => {
44+
const output = await tools.runAsync(`${cmd} labels-gcs gs://demomaker/sushi.mp4`, cwd);
45+
t.regex(output, /Label Food occurs at:/);
46+
t.regex(output, /Start: \d+\.\d+s/);
47+
t.regex(output, /End: \d+\.\d+s/);
3748
});
3849

3950
// analyze_labels_local
4051
test(`should analyze labels in a local file`, async (t) => {
4152
const output = await tools.runAsync(`${cmd} labels-file resources/cat.mp4`, cwd);
42-
t.regex(output, /Label description: Whiskers/);
53+
t.regex(output, /Label Whiskers occurs at:/);
54+
t.regex(output, /Entire video/);
55+
});
56+
57+
// analyze_shots (multiple shots)
58+
test(`should analyze shots in a GCS file with multiple shots`, async (t) => {
59+
const output = await tools.runAsync(`${cmd} shots gs://demomaker/sushi.mp4`, cwd);
60+
t.regex(output, /Shot 0 occurs from:/);
4361
});
4462

45-
// analyze_shots
46-
test(`should analyze shots in a GCS file`, async (t) => {
47-
const output = await tools.runAsync(`${cmd} shots gs://nodejs-docs-samples/video/google_gmail.mp4`, cwd);
48-
t.regex(output, /Scene 0:/);
63+
// analyze_shots (one shot)
64+
test(`should analyze shots in a GCS file with one shot`, async (t) => {
65+
const output = await tools.runAsync(`${cmd} shots gs://demomaker/tomatoes.mp4`, cwd);
66+
t.regex(output, /The entire video is one shot./);
4967
});
5068

5169
// analyze_safe_search
5270
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, /Time: \d\.\d+s/);
71+
const output = await tools.runAsync(`${cmd} safe-search gs://demomaker/tomatoes.mp4`, cwd);
5572
t.regex(output, /Spoof:/);
5673
});

video/system-test/quickstart.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const cwd = path.join(__dirname, `..`);
2424

2525
test(`should analyze a hardcoded video`, async (t) => {
2626
const output = await tools.runAsync(cmd, cwd);
27-
t.regex(output, /Label Property occurs at:/);
28-
t.regex(output, /Scene \d+ occurs from:/);
27+
t.regex(output, /Label Tomato occurs at:/);
28+
t.regex(output, /Entire video/);
29+
t.regex(output, /The entire video is one scene./);
2930
});

0 commit comments

Comments
 (0)