Skip to content

Commit

Permalink
Address comments (#388)
Browse files Browse the repository at this point in the history
* Address sgreenberg's comments

* Massage package.json + generate README
  • Loading branch information
Ace Nassri committed Nov 17, 2022
1 parent be5d236 commit e3efddc
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 34 deletions.
54 changes: 38 additions & 16 deletions video-intelligence/analyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ function analyzeFaces (gcsUri) {
faces.forEach((face, faceIdx) => {
console.log('\tThumbnail size:', face.thumbnail.length);
face.segments.forEach((segment, segmentIdx) => {
console.log(`\tTrack ${segmentIdx} of face ${faceIdx}: frames ${segment.startTimeOffset} to ${segment.endTimeOffset}`);
if (segment.startTimeOffset === -1 && segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log(`\tStart: ${segment.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${segment.endTimeOffset / 1e6}s`);
}
});
});
})
Expand Down Expand Up @@ -86,7 +91,12 @@ function analyzeLabelsGCS (gcsUri) {
console.log('Label description:', label.description);
console.log('Locations:');
label.locations.forEach((location) => {
console.log(`\tFrames ${location.segment.startTimeOffset} to ${location.segment.endTimeOffset}`);
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`);
}
});
});
})
Expand Down Expand Up @@ -133,7 +143,12 @@ function analyzeLabelsLocal (path) {
console.log('Label description:', label.description);
console.log('Locations:');
label.locations.forEach((location) => {
console.log(`\tFrames ${location.segment.startTimeOffset} to ${location.segment.endTimeOffset}`);
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`);
}
});
});
})
Expand Down Expand Up @@ -172,8 +187,12 @@ function analyzeShots (gcsUri) {
console.log('Shot changes:');
shotChanges.forEach((shot, shotIdx) => {
console.log(`Scene ${shotIdx}:`);
console.log(`\tStart: ${shot.startTimeOffset}`);
console.log(`\tEnd: ${shot.endTimeOffset}`);
if (shot.startTimeOffset === -1 && shot.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log(`\tStart: ${shot.startTimeOffset}`);
console.log(`\tEnd: ${shot.endTimeOffset}`);
}
});
})
.catch((err) => {
Expand All @@ -198,6 +217,9 @@ function analyzeSafeSearch (gcsUri) {
features: ['SAFE_SEARCH_DETECTION']
};

// Human-readable likelihoods
const likelihoods = ['UNKNOWN', 'VERY_UNLIKELY', 'UNLIKELY', 'POSSIBLE', 'LIKELY', 'VERY_LIKELY'];

// Detects unsafe content
video.annotateVideo(request)
.then((results) => {
Expand All @@ -210,12 +232,12 @@ function analyzeSafeSearch (gcsUri) {
const safeSearchResults = results[0].annotationResults[0].safeSearchAnnotations;
console.log('Safe search results:');
safeSearchResults.forEach((result) => {
console.log(`Frame ${result.timeOffset}:`);
console.log(`\tAdult: ${result.adult}`);
console.log(`\tSpoof: ${result.spoof}`);
console.log(`\tMedical: ${result.medical}`);
console.log(`\tViolent: ${result.violent}`);
console.log(`\tRacy: ${result.racy}`);
console.log(`Time: ${result.timeOffset / 1e6}s`);
console.log(`\tAdult: ${likelihoods[result.adult]}`);
console.log(`\tSpoof: ${likelihoods[result.spoof]}`);
console.log(`\tMedical: ${likelihoods[result.medical]}`);
console.log(`\tViolent: ${likelihoods[result.violent]}`);
console.log(`\tRacy: ${likelihoods[result.racy]}`);
});
})
.catch((err) => {
Expand Down Expand Up @@ -256,11 +278,11 @@ require(`yargs`) // eslint-disable-line
{},
(opts) => analyzeSafeSearch(opts.gcsUri)
)
.example(`node $0 faces gs://my-bucket/my-video.mp4`)
.example(`node $0 shots gs://my-bucket/my-video.mp4`)
.example(`node $0 labels-gcs gs://my-bucket/my-video.mp4`)
.example(`node $0 labels-file my-video.mp4`)
.example(`node $0 safe-search gs://my-bucket/my-video.mp4`)
.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 labels-file cat.mp4`)
.example(`node $0 safe-search gs://demomaker/volleyball_court.mp4`)
.wrap(120)
.recommendCommands()
.epilogue(`For more information, see https://cloud.google.com/video-intelligence/docs`)
Expand Down
19 changes: 16 additions & 3 deletions video-intelligence/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,27 @@
},
"dependencies": {
"@google-cloud/videointelligence": "https://storage.googleapis.com/videointelligence-alpha/videointelligence-nodejs.tar.gz",
"googleapis": "19.0.0",
"safe-buffer": "5.0.1",
"yargs": "7.1.0"
},
"devDependencies": {
"@google-cloud/nodejs-repo-tools": "1.4.7",
"ava": "0.19.1"
"@google-cloud/nodejs-repo-tools": "1.4.13",
"ava": "0.19.1",
"proxyquire": "1.7.11"
},
"cloud-repo-tools": {
"requiresKeyFile": true,
"requiresProjectId": true
"requiresProjectId": true,
"product": "video",
"samples": [
{
"id": "video",
"name": "Video Intelligence",
"file": "analyze.js",
"docs_link": "https://cloud.google.com/video-intelligence/docs",
"usage": "node analyze.js --help"
}
]
}
}
30 changes: 22 additions & 8 deletions video-intelligence/quickstart.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const video = Video.videoIntelligenceServiceClient({
});

// The GCS filepath of the video to analyze
const gcsUri = 'gs://nodejs-docs-samples/videointelligence_quickstart.mp4';
const gcsUri = 'gs://demomaker/volleyball_court.mp4';

// Construct request
const request = {
Expand All @@ -49,26 +49,40 @@ video.annotateVideo(request)
faces.forEach((face, faceIdx) => {
console.log('Thumbnail size:', face.thumbnail.length);
face.segments.forEach((segment, segmentIdx) => {
console.log(`Track ${segmentIdx} of face ${faceIdx}: frames ${segment.startTimeOffset} to ${segment.endTimeOffset}`);
console.log(`Face #${faceIdx}, appearance #${segmentIdx}:`);
if (segment.startTimeOffset === -1 && segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
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 description:', label.description);
console.log('Locations:');
console.log(`Label ${label.description} occurs at:`);
label.locations.forEach((location) => {
console.log(`\tFrames ${location.segment.startTimeOffset} to ${location.segment.endTimeOffset}`);
if (location.segment.startTimeOffset === -1 && location.segment.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
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}:`);
console.log(`\tStart: ${shot.startTimeOffset}`);
console.log(`\tEnd: ${shot.endTimeOffset}`);
console.log(`Scene ${shotIdx} occurs from:`);
if (shot.startTimeOffset === -1 && shot.endTimeOffset === -1) {
console.log(`\tEntire video`);
} else {
console.log(`\tStart: ${shot.startTimeOffset / 1e6}s`);
console.log(`\tEnd: ${shot.endTimeOffset / 1e6}s`);
}
});
})
.catch((err) => {
Expand Down
6 changes: 3 additions & 3 deletions video-intelligence/system-test/analyze.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ test(`should analyze labels in a local file`, async (t) => {

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

// 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, /Frame \d+/);
t.regex(output, /Spoof: \d+/);
t.regex(output, /Time: \d\.\d+s/);
t.regex(output, /Spoof:/);
});
6 changes: 2 additions & 4 deletions video-intelligence/system-test/quickstart.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ const cwd = path.join(__dirname, `..`);

test(`should analyze a hardcoded video`, async (t) => {
const output = await tools.runAsync(cmd, cwd);
t.regex(output, /Label description:/);
t.regex(output, /Frames \d+ to \d+/);
t.regex(output, /Track \d+ of face \d+: frames \d+ to \d+/);
t.regex(output, /Scene \d+/);
t.regex(output, /Label Property occurs at:/);
t.regex(output, /Scene \d+ occurs from:/);
});

0 comments on commit e3efddc

Please sign in to comment.