Skip to content

Commit

Permalink
Switch to faster videos + update print statements (#395)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ace Nassri authored and ahrarmonsur committed Nov 17, 2022
1 parent 6b428b9 commit e12d354
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 85 deletions.
109 changes: 63 additions & 46 deletions video-intelligence/analyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
function analyzeFaces (gcsUri) {
// [START analyze_faces]
// Imports the Google Cloud Video Intelligence library
const Video = require('@google-cloud/videointelligence');
const Video = require('@google-cloud/video-intelligence');

// Instantiates a client
const video = Video().videoIntelligenceServiceClient();
const video = Video();

// The GCS filepath of the video to analyze
// const gcsUri = 'gs://my-bucket/my-video.mp4';
Expand All @@ -43,15 +43,23 @@ function analyzeFaces (gcsUri) {
const faces = results[0].annotationResults[0].faceAnnotations;
console.log('Faces:');
faces.forEach((face, faceIdx) => {
console.log('\tThumbnail size:', face.thumbnail.length);
face.segments.forEach((segment, segmentIdx) => {
if (segment.startTimeOffset === -1 && segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log('Thumbnail size:', face.thumbnail.length);

const isEntireVideo = face.segments.some((segment) =>
segment.startTimeOffset.toNumber() === -1 &&
segment.endTimeOffset.toNumber() === -1
);

if (isEntireVideo) {
console.log(`Face #${faceIdx}`);
console.log(`\tEntire video`);
} else {
face.segments.forEach((segment, segmentIdx) => {
console.log(`Face #${faceIdx}, appearance #${segmentIdx}:`);
console.log(`\tStart: ${segment.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${segment.endTimeOffset / 1e6}s`);
}
});
});
}
});
})
.catch((err) => {
Expand All @@ -63,10 +71,10 @@ function analyzeFaces (gcsUri) {
function analyzeLabelsGCS (gcsUri) {
// [START analyze_labels_gcs]
// Imports the Google Cloud Video Intelligence library
const Video = require('@google-cloud/videointelligence');
const Video = require('@google-cloud/video-intelligence');

// Instantiates a client
const video = Video().videoIntelligenceServiceClient();
const video = Video();

// The GCS filepath of the video to analyze
// const gcsUri = 'gs://my-bucket/my-video.mp4';
Expand All @@ -88,16 +96,20 @@ function analyzeLabelsGCS (gcsUri) {
const labels = results[0].annotationResults[0].labelAnnotations;
console.log('Labels:');
labels.forEach((label) => {
console.log('Label description:', label.description);
console.log('Locations:');
label.locations.forEach((location) => {
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log(`Label ${label.description} occurs at:`);
const isEntireVideo = label.locations.some((location) =>
location.segment.startTimeOffset.toNumber() === -1 &&
location.segment.endTimeOffset.toNumber() === -1
);

if (isEntireVideo) {
console.log(`\tEntire video`);
} else {
label.locations.forEach((location) => {
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`);
}
});
});
}
});
})
.catch((err) => {
Expand All @@ -109,11 +121,11 @@ function analyzeLabelsGCS (gcsUri) {
function analyzeLabelsLocal (path) {
// [START analyze_labels_local]
// Imports the Google Cloud Video Intelligence library + Node's fs library
const Video = require('@google-cloud/videointelligence');
const Video = require('@google-cloud/video-intelligence');
const fs = require('fs');

// Instantiates a client
const video = Video().videoIntelligenceServiceClient();
const video = Video();

// The local filepath of the video to analyze
// const path = 'my-file.mp4';
Expand All @@ -140,16 +152,20 @@ function analyzeLabelsLocal (path) {
const labels = results[0].annotationResults[0].labelAnnotations;
console.log('Labels:');
labels.forEach((label) => {
console.log('Label description:', label.description);
console.log('Locations:');
label.locations.forEach((location) => {
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log(`Label ${label.description} occurs at:`);
const isEntireVideo = label.locations.some((location) =>
location.segment.startTimeOffset.toNumber() === -1 &&
location.segment.endTimeOffset.toNumber() === -1
);

if (isEntireVideo) {
console.log(`\tEntire video`);
} else {
label.locations.forEach((location) => {
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`);
}
});
});
}
});
})
.catch((err) => {
Expand All @@ -161,10 +177,10 @@ function analyzeLabelsLocal (path) {
function analyzeShots (gcsUri) {
// [START analyze_shots]
// Imports the Google Cloud Video Intelligence library
const Video = require('@google-cloud/videointelligence');
const Video = require('@google-cloud/video-intelligence');

// Instantiates a client
const video = Video().videoIntelligenceServiceClient();
const video = Video();

// The GCS filepath of the video to analyze
// const gcsUri = 'gs://my-bucket/my-video.mp4';
Expand All @@ -185,15 +201,16 @@ function analyzeShots (gcsUri) {
// Gets shot changes
const shotChanges = results[0].annotationResults[0].shotAnnotations;
console.log('Shot changes:');
shotChanges.forEach((shot, shotIdx) => {
console.log(`Scene ${shotIdx}:`);
if (shot.startTimeOffset === -1 && shot.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log(`\tStart: ${shot.startTimeOffset}`);
console.log(`\tEnd: ${shot.endTimeOffset}`);
}
});

if (shotChanges.length === 1) {
console.log(`The entire video is one shot.`);
} else {
shotChanges.forEach((shot, shotIdx) => {
console.log(`Shot ${shotIdx} occurs from:`);
console.log(`\tStart: ${shot.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${shot.endTimeOffset / 1e6}s`);
});
}
})
.catch((err) => {
console.error('ERROR:', err);
Expand All @@ -204,10 +221,10 @@ function analyzeShots (gcsUri) {
function analyzeSafeSearch (gcsUri) {
// [START analyze_safe_search]
// Imports the Google Cloud Video Intelligence library
const Video = require('@google-cloud/videointelligence');
const Video = require('@google-cloud/video-intelligence');

// Instantiates a client
const video = Video().videoIntelligenceServiceClient();
const video = Video();

// The GCS filepath of the video to analyze
// const gcsUri = 'gs://my-bucket/my-video.mp4';
Expand Down Expand Up @@ -278,11 +295,11 @@ require(`yargs`) // eslint-disable-line
{},
(opts) => analyzeSafeSearch(opts.gcsUri)
)
.example(`node $0 faces gs://demomaker/volleyball_court.mp4`)
.example(`node $0 shots gs://demomaker/volleyball_court.mp4`)
.example(`node $0 labels-gcs gs://demomaker/volleyball_court.mp4`)
.example(`node $0 faces gs://demomaker/larry_sergey_ice_bucket_short.mp4`)
.example(`node $0 shots gs://demomaker/sushi.mp4`)
.example(`node $0 labels-gcs gs://demomaker/tomatoes.mp4`)
.example(`node $0 labels-file cat.mp4`)
.example(`node $0 safe-search gs://demomaker/volleyball_court.mp4`)
.example(`node $0 safe-search gs://demomaker/tomatoes.mp4`)
.wrap(120)
.recommendCommands()
.epilogue(`For more information, see https://cloud.google.com/video-intelligence/docs`)
Expand Down
5 changes: 3 additions & 2 deletions video-intelligence/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
"scripts": {
"lint": "samples lint",
"pretest": "npm run lint",
"system-test": "ava -T 10m --verbose system-test/*.test.js",
"system-test": "ava -T 5m --verbose system-test/*.test.js",
"test": "npm run system-test"
},
"dependencies": {
"@google-cloud/videointelligence": "https://storage.googleapis.com/videointelligence-alpha/videointelligence-nodejs.tar.gz",
"@google-cloud/video-intelligence": "0.1.0",
"googleapis": "19.0.0",
"long": "^3.2.0",
"safe-buffer": "5.0.1",
"yargs": "7.1.0"
},
Expand Down
58 changes: 35 additions & 23 deletions video-intelligence/quickstart.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@

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

// Instantiates a client
const video = Video.videoIntelligenceServiceClient({
const video = Video({
projectId: process.env.GCLOUD_PROJECT // Replace with your Google Cloud project ID
});

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

// Construct request
const request = {
Expand All @@ -48,42 +48,54 @@ video.annotateVideo(request)
const faces = annotations.faceAnnotations;
faces.forEach((face, faceIdx) => {
console.log('Thumbnail size:', face.thumbnail.length);
face.segments.forEach((segment, segmentIdx) => {
console.log(`Face #${faceIdx}, appearance #${segmentIdx}:`);
if (segment.startTimeOffset === -1 && segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {

const isEntireVideo = face.segments.some((segment) =>
segment.startTimeOffset.toNumber() === -1 &&
segment.endTimeOffset.toNumber() === -1
);

if (isEntireVideo) {
console.log(`Face #${faceIdx}`);
console.log(`\tEntire video`);
} else {
face.segments.forEach((segment, segmentIdx) => {
console.log(`Face #${faceIdx}, appearance #${segmentIdx}:`);
console.log(`\tStart: ${segment.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${segment.endTimeOffset / 1e6}s`);
}
});
});
}
});

// Gets labels for video from its annotations
const labels = annotations.labelAnnotations;
labels.forEach((label) => {
console.log(`Label ${label.description} occurs at:`);
label.locations.forEach((location) => {
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
const isEntireVideo = label.locations.some((location) =>
location.segment.startTimeOffset.toNumber() === -1 &&
location.segment.endTimeOffset.toNumber() === -1
);

if (isEntireVideo) {
console.log(`\tEntire video`);
} else {
label.locations.forEach((location) => {
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`);
}
});
});
}
});

// Gets shot changes for video from its annotations
const shotChanges = annotations.shotAnnotations;
shotChanges.forEach((shot, shotIdx) => {
console.log(`Scene ${shotIdx} occurs from:`);
if (shot.startTimeOffset === -1 && shot.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
if (shotChanges.length === 1) {
console.log(`The entire video is one scene.`);
} else {
shotChanges.forEach((shot, shotIdx) => {
console.log(`Scene ${shotIdx} occurs from:`);
console.log(`\tStart: ${shot.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${shot.endTimeOffset / 1e6}s`);
}
});
});
}
})
.catch((err) => {
console.error('ERROR:', err);
Expand Down
41 changes: 29 additions & 12 deletions video-intelligence/system-test/analyze.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,48 @@ const cwd = path.join(__dirname, `..`);

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

// analyze_labels_gcs
test(`should analyze labels in a GCS file`, async (t) => {
const output = await tools.runAsync(`${cmd} labels-gcs gs://nodejs-docs-samples/video/cat.mp4`, cwd);
t.regex(output, /Label description: Whiskers/);
// analyze_labels_gcs (one scene)
test(`should analyze labels in a GCS file with one scene`, async (t) => {
const output = await tools.runAsync(`${cmd} labels-gcs gs://demomaker/tomatoes.mp4`, cwd);
t.regex(output, /Label Tomato occurs at:/);
t.regex(output, /Entire video/);
});

// analyze_labels_gcs (multiple scenes)
test(`should analyze labels in a GCS file with multiple scenes`, async (t) => {
const output = await tools.runAsync(`${cmd} labels-gcs gs://demomaker/sushi.mp4`, cwd);
t.regex(output, /Label Food occurs at:/);
t.regex(output, /Start: \d+\.\d+s/);
t.regex(output, /End: \d+\.\d+s/);
});

// analyze_labels_local
test(`should analyze labels in a local file`, async (t) => {
const output = await tools.runAsync(`${cmd} labels-file resources/cat.mp4`, cwd);
t.regex(output, /Label description: Whiskers/);
t.regex(output, /Label Whiskers occurs at:/);
t.regex(output, /Entire video/);
});

// analyze_shots (multiple shots)
test(`should analyze shots in a GCS file with multiple shots`, async (t) => {
const output = await tools.runAsync(`${cmd} shots gs://demomaker/sushi.mp4`, cwd);
t.regex(output, /Shot 0 occurs from:/);
});

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

// analyze_safe_search
test(`should analyze safe search results in a GCS file`, async (t) => {
const output = await tools.runAsync(`${cmd} safe-search gs://nodejs-docs-samples/video/google_gmail.mp4`, cwd);
t.regex(output, /Time: \d\.\d+s/);
const output = await tools.runAsync(`${cmd} safe-search gs://demomaker/tomatoes.mp4`, cwd);
t.regex(output, /Spoof:/);
});
5 changes: 3 additions & 2 deletions video-intelligence/system-test/quickstart.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const cwd = path.join(__dirname, `..`);

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

0 comments on commit e12d354

Please sign in to comment.