-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Video update #476
Video update #476
Changes from 4 commits
0df0619
7287b87
2fadc9e
0ffcffc
7bfa28b
bc851fe
97f6476
b49a84d
fff7af9
3a06862
7cd9b48
8f5dd56
a50f868
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,9 @@ function analyzeFaces (gcsUri) { | |
const Video = require('@google-cloud/video-intelligence'); | ||
|
||
// Instantiates a client | ||
const video = Video(); | ||
const video = Video({ | ||
servicePath: `alpha-videointelligence.googleapis.com` | ||
}); | ||
|
||
// The GCS filepath of the video to analyze | ||
// const gcsUri = 'gs://my-bucket/my-video.mp4'; | ||
|
@@ -41,13 +43,18 @@ function analyzeFaces (gcsUri) { | |
.then((results) => { | ||
// Gets faces | ||
const faces = results[0].annotationResults[0].faceAnnotations; | ||
console.log('Faces:'); | ||
faces.forEach((face, faceIdx) => { | ||
console.log('Thumbnail size:', face.thumbnail.length); | ||
console.log(`Face #${faceIdx}`); | ||
console.log(`\tThumbnail size: ${face.thumbnail.length}`); | ||
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`); | ||
console.log(`\tAppearance #${segmentIdx}:`); | ||
console.log(`\t\tStart: ${segment.startTimeOffset / 1e6}s`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the time offset fields have been changed to return seconds and nanoseconds, perhaps (also for other instances of {start,end}TimeOffsets) |
||
console.log(`\t\tEnd: ${segment.endTimeOffset / 1e6}s`); | ||
}); | ||
console.log(`\tLocations:`); | ||
face.locations.forEach((location, locationIdx) => { | ||
const box = location.boundingBox; | ||
console.log(`\t\tTime ${location.timeOffset / 1e6}s: (${box.top}, ${box.left}) - (${box.bottom}, ${box.right})`); | ||
}); | ||
}); | ||
}) | ||
|
@@ -63,7 +70,9 @@ function analyzeLabelsGCS (gcsUri) { | |
const Video = require('@google-cloud/video-intelligence'); | ||
|
||
// Instantiates a client | ||
const video = Video(); | ||
const video = Video({ | ||
servicePath: `alpha-videointelligence.googleapis.com` | ||
}); | ||
|
||
// The GCS filepath of the video to analyze | ||
// const gcsUri = 'gs://my-bucket/my-video.mp4'; | ||
|
@@ -83,22 +92,27 @@ function analyzeLabelsGCS (gcsUri) { | |
.then((results) => { | ||
// Gets labels | ||
const labels = results[0].annotationResults[0].labelAnnotations; | ||
// TODO What does "level" mean? | ||
// TODO Why are there no segment-level annotations? | ||
|
||
console.log('Labels:'); | ||
labels.forEach((label) => { | ||
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) => { | ||
label.locations.forEach((location) => { | ||
const isEntireVideo = label.locations.some((location) => | ||
location.segment.startTimeOffset.toNumber() === -1 && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe we no longer return |
||
location.segment.endTimeOffset.toNumber() === -1 | ||
); | ||
|
||
if (isEntireVideo) { | ||
console.log(`\tEntire video`); | ||
} else { | ||
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`); | ||
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`); | ||
}); | ||
} | ||
} | ||
|
||
console.log(`\tConfidence: ${location.confidence}`); | ||
}); | ||
}); | ||
}) | ||
.catch((err) => { | ||
|
@@ -114,7 +128,9 @@ function analyzeLabelsLocal (path) { | |
const fs = require('fs'); | ||
|
||
// Instantiates a client | ||
const video = Video(); | ||
const video = Video({ | ||
servicePath: `alpha-videointelligence.googleapis.com` | ||
}); | ||
|
||
// The local filepath of the video to analyze | ||
// const path = 'my-file.mp4'; | ||
|
@@ -139,22 +155,26 @@ function analyzeLabelsLocal (path) { | |
.then((results) => { | ||
// Gets labels for first video | ||
const labels = results[0].annotationResults[0].labelAnnotations; | ||
// TODO What does "level" mean? | ||
// TODO Why are there no segment-level annotations? | ||
|
||
console.log('Labels:'); | ||
labels.forEach((label) => { | ||
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) => { | ||
|
||
label.locations.forEach((location) => { | ||
const isEntireVideo = | ||
location.segment.startTimeOffset.toNumber() === -1 && | ||
location.segment.endTimeOffset.toNumber() === -1; | ||
|
||
if (isEntireVideo) { | ||
console.log(`\tEntire video`); | ||
} else { | ||
console.log(`\tStart: ${location.segment.startTimeOffset / 1e6}s`); | ||
console.log(`\tEnd: ${location.segment.endTimeOffset / 1e6}s`); | ||
}); | ||
} | ||
} | ||
console.log(`\tConfidence: ${location.confidence}`); | ||
}); | ||
}); | ||
}) | ||
.catch((err) => { | ||
|
@@ -169,7 +189,9 @@ function analyzeShots (gcsUri) { | |
const Video = require('@google-cloud/video-intelligence'); | ||
|
||
// Instantiates a client | ||
const video = Video(); | ||
const video = Video({ | ||
servicePath: `alpha-videointelligence.googleapis.com` | ||
}); | ||
|
||
// The GCS filepath of the video to analyze | ||
// const gcsUri = 'gs://my-bucket/my-video.mp4'; | ||
|
@@ -213,7 +235,9 @@ function analyzeSafeSearch (gcsUri) { | |
const Video = require('@google-cloud/video-intelligence'); | ||
|
||
// Instantiates a client | ||
const video = Video(); | ||
const video = Video({ | ||
servicePath: `alpha-videointelligence.googleapis.com` | ||
}); | ||
|
||
// The GCS filepath of the video to analyze | ||
// const gcsUri = 'gs://my-bucket/my-video.mp4'; | ||
|
@@ -235,9 +259,9 @@ function analyzeSafeSearch (gcsUri) { | |
}) | ||
.then((results) => { | ||
// Gets unsafe content | ||
const safeSearchResults = results[0].annotationResults[0].safeSearchAnnotations; | ||
console.log('Safe search results:'); | ||
safeSearchResults.forEach((result) => { | ||
const explicitContentResults = results[0].annotationResults[0].safeSearchAnnotations; | ||
console.log('Explicit content results:'); | ||
explicitContentResults.forEach((result) => { | ||
console.log(`Time: ${result.timeOffset / 1e6}s`); | ||
console.log(`\tAdult: ${likelihoods[result.adult]}`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spoof, medical etc are removed (the API has not been returning non-empty values for those), and only adult (renamed pornography_likelihood) remains. |
||
console.log(`\tSpoof: ${likelihoods[result.spoof]}`); | ||
|
@@ -280,7 +304,7 @@ require(`yargs`) // eslint-disable-line | |
) | ||
.command( | ||
`safe-search <gcsUri>`, | ||
`Detects adult content in a video stored in Google Cloud Storage.`, | ||
`Detects explicit content in a video stored in Google Cloud Storage.`, | ||
{}, | ||
(opts) => analyzeSafeSearch(opts.gcsUri) | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,50 +24,58 @@ const tools = require(`@google-cloud/nodejs-repo-tools`); | |
const cmd = `node analyze.js`; | ||
const cwd = path.join(__dirname, `..`); | ||
|
||
const url = `gs://nodejs-docs-samples-video/quickstart.mp4`; | ||
const shortUrl = `gs://nodejs-docs-samples-video/quickstart_short.mp4`; | ||
const file = `resources/cat.mp4`; | ||
|
||
// analyze_faces | ||
test(`should analyze faces in a GCS file`, async (t) => { | ||
const output = await tools.runAsync(`${cmd} faces gs://demomaker/larry_sergey_ice_bucket_short.mp4`, cwd); | ||
test.serial(`should analyze faces in a GCS file`, async (t) => { | ||
const output = await tools.runAsync(`${cmd} faces ${url}`, cwd); | ||
t.regex(output, /Thumbnail size: \d+/); | ||
t.regex(output, /Start: \d+\.\d+s/); | ||
t.regex(output, /End: \d+\.\d+s/); | ||
t.regex(output, /Time \d+\.\d+s: \(\d+, \d+\) - \(\d+, \d+\)/); | ||
}); | ||
|
||
// 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:/); | ||
test.serial(`should analyze labels in a GCS file with one scene`, async (t) => { | ||
const output = await tools.runAsync(`${cmd} labels-gcs ${shortUrl}`, cwd); | ||
t.regex(output, /Label shirt occurs at:/); | ||
t.regex(output, /Entire video/); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might no longer show "Entire video" in the output. (see comments above about time offsets) |
||
t.regex(output, /Confidence: \d+\.\d+/); | ||
}); | ||
|
||
// 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/); | ||
test.serial(`should analyze labels in a GCS file with multiple scenes`, async (t) => { | ||
const output = await tools.runAsync(`${cmd} labels-gcs ${url}`, cwd); | ||
t.regex(output, /Label shirt occurs at:/); | ||
t.regex(output, /Entire video/); | ||
t.regex(output, /Confidence: \d+\.\d+/); | ||
}); | ||
|
||
// 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 Whiskers occurs at:/); | ||
test.serial(`should analyze labels in a local file`, async (t) => { | ||
const output = await tools.runAsync(`${cmd} labels-file ${file}`, cwd); | ||
t.regex(output, /Label whiskers occurs at:/); | ||
t.regex(output, /Entire video/); | ||
t.regex(output, /Confidence: \d+\.\d+/); | ||
}); | ||
|
||
// 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); | ||
test.serial(`should analyze shots in a GCS file with multiple shots`, async (t) => { | ||
const output = await tools.runAsync(`${cmd} shots ${url}`, cwd); | ||
t.regex(output, /Shot 0 occurs from:/); | ||
}); | ||
|
||
// 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); | ||
test.serial(`should analyze shots in a GCS file with one shot`, async (t) => { | ||
const output = await tools.runAsync(`${cmd} shots ${shortUrl}`, 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://demomaker/tomatoes.mp4`, cwd); | ||
test.serial(`should analyze safe search results in a GCS file`, async (t) => { | ||
const output = await tools.runAsync(`${cmd} safe-search ${url}`, cwd); | ||
t.regex(output, /Time: \d+\.\d+s/); | ||
t.regex(output, /Spoof:/); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reminder: remove this (and other instances of "alpha-") before merging.