1

I have been trying to send a request to the Google Video Intelligence API for SAFE_SEARCH_DETECTION (in node.js), but I keep running into the same error:

ERROR: { Error: Request contains an invalid argument. at /Users/paulsteenkiste/node_modules/grpc/src/node/src/client.js:569:15 code: 3, metadata: Metadata { _internal_repr: {} }, note: 'Exception occurred in retry method that was not classified as transient' }

I tried to dive into that client.js file listed in the error, but it was not very illuminating. Here is the code that yields this error:

const firebase = require('firebase');

firebase.initializeApp({
    serviceAccount: "./service-account.json",
    apiKey: "<API key>",
    databaseURL: "<My Database>"
});

// Imports the Google Cloud Video Intelligence library
const Video = require('@google-cloud/video-intelligence');

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

firebase.auth().signInWithEmailAndPassword("<My email>", "<My password>")
    .then(function(user) {

    // The GCS filepath of the video to analyze
    const gcsUri = '<File location>';

    const request = {
      inputUri: 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) => {
        const operation = results[0];
        console.log('Waiting for operation to complete...');
        return operation.promise();
      })
      .then((results) => {
        // Gets unsafe content
        const safeSearchResults = results[0].annotationResults[0].safeSearchAnnotations;
        console.log('Safe search results:');
        safeSearchResults.forEach((result) => {
          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) => {
        console.error('ERROR:', err);
      });
    })
    .catch(function(error) {
        var errorCode = error.code;
        var errorMessage = error.message;
        console.log(errorMessage);
    });

(Note that this is essentially copied and pasted from Google's docs at https://cloud.google.com/video-intelligence/docs/analyze-safesearch). The service-account.json is the file I downloaded when I created the service account, and it is in the same folder as the above file. I do not think it is necessary to do that firebase authentication, but I wanted to make sure that wasn't the issue. I have enabled the API and have full access to the project, so neither of those are the issue.

I believe the problem is coming from the service account somehow, but whatever I try the same error shows up. Some of the things that I have tried:

  1. Setting GOOGLE_APPLICATION_CREDENTIALS from the terminal
  2. Giving that service account "Suite Domain-wide Delegation"
  3. Making the file public
  4. Doing the "gsutil" command recommended by the answer here: Permission Denied When Making Request to GCP Video Intelligence API

Any ideas as to what the problem is?

1 Answers1

0

I had this exact same issue in a recent project, and found out that it was due to submitting an https:// URI when Google Cloud Services expected a gs:// URI. The Error: Request contains an invalid argument. makes me pretty sure that this is the issue.

The simplist fix would be to directly modify the url you are passing on to the API call.

const gcsUri = '<File location>'.replace('https://storage.googleapis.com/', 'gs://')

And yes, most of their APIs require the files to be in their own cloud storage. If you are trying to process a video located elsewhere, you will likely first need to copy it into their cloud storage.