| 30 | |
| 31 | // Performs asynchronous video annotation for logo recognition on a file. |
| 32 | async function detectLogo() { |
| 33 | const inputContent = fs.readFileSync(localFilePath).toString('base64'); |
| 34 | |
| 35 | // Build the request with the input content and logo recognition feature. |
| 36 | const request = { |
| 37 | inputContent: inputContent, |
| 38 | features: ['LOGO_RECOGNITION'], |
| 39 | }; |
| 40 | |
| 41 | // Make the asynchronous request |
| 42 | const [operation] = await client.annotateVideo(request); |
| 43 | |
| 44 | // Wait for the results |
| 45 | const [response] = await operation.promise(); |
| 46 | |
| 47 | // Get the first response, since we sent only one video. |
| 48 | const annotationResult = response.annotationResults[0]; |
| 49 | for (const logoRecognitionAnnotation of annotationResult.logoRecognitionAnnotations) { |
| 50 | const entity = logoRecognitionAnnotation.entity; |
| 51 | // Opaque entity ID. Some IDs may be available in |
| 52 | // [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/). |
| 53 | console.log(`Entity Id: ${entity.entityId}`); |
| 54 | console.log(`Description: ${entity.description}`); |
| 55 | |
| 56 | // All logo tracks where the recognized logo appears. |
| 57 | // Each track corresponds to one logo instance appearing in consecutive frames. |
| 58 | for (const track of logoRecognitionAnnotation.tracks) { |
| 59 | console.log( |
| 60 | `\n\tStart Time Offset: ${track.segment.startTimeOffset.seconds}.${track.segment.startTimeOffset.nanos}` |
| 61 | ); |
| 62 | console.log( |
| 63 | `\tEnd Time Offset: ${track.segment.endTimeOffset.seconds}.${track.segment.endTimeOffset.nanos}` |
| 64 | ); |
| 65 | console.log(`\tConfidence: ${track.confidence}`); |
| 66 | |
| 67 | // The object with timestamp and attributes per frame in the track. |
| 68 | for (const timestampedObject of track.timestampedObjects) { |
| 69 | // Normalized Bounding box in a frame, where the object is located. |
| 70 | const normalizedBoundingBox = timestampedObject.normalizedBoundingBox; |
| 71 | console.log(`\n\t\tLeft: ${normalizedBoundingBox.left}`); |
| 72 | console.log(`\t\tTop: ${normalizedBoundingBox.top}`); |
| 73 | console.log(`\t\tRight: ${normalizedBoundingBox.right}`); |
| 74 | console.log(`\t\tBottom: ${normalizedBoundingBox.bottom}`); |
| 75 | // Optional. The attributes of the object in the bounding box. |
| 76 | for (const attribute of timestampedObject.attributes) { |
| 77 | console.log(`\n\t\t\tName: ${attribute.name}`); |
| 78 | console.log(`\t\t\tConfidence: ${attribute.confidence}`); |
| 79 | console.log(`\t\t\tValue: ${attribute.value}`); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | // Optional. Attributes in the track level. |
| 84 | for (const trackAttribute of track.attributes) { |
| 85 | console.log(`\n\t\tName: ${trackAttribute.name}`); |
| 86 | console.log(`\t\tConfidence: ${trackAttribute.confidence}`); |
| 87 | console.log(`\t\tValue: ${trackAttribute.value}`); |
| 88 | } |
| 89 | } |