Détecter du contenu explicite dans des vidéos

La détection de contenu explicite permet de détecter le contenu réservé aux adultes dans les vidéos. Le contenu réservé aux adultes est généralement inapproprié aux moins de 18 ans et inclut, sans s'y limiter, la nudité, les activités sexuelles et la pornographie. Ce type de contenu est également détecté dans des dessins animés ou dans des animations.

La réponse comprend une valeur de probabilité compartimentée, allant de VERY_UNLIKELY à VERY_LIKELY.

Lorsque la fonctionnalité de détection de contenu explicite évalue une vidéo, elle le fait sur la base des images, et ne prend en compte que le contenu visuel. La partie audio de la vidéo n'est pas utilisée.

Voici un exemple d'utilisation des fonctionnalités de détection de contenu explicite sur un fichier situé dans Cloud Storage.

API REST et ligne de commande

Envoyer une requête d'annotation vidéo

Vous trouverez ci-dessous la procédure à suivre pour envoyer une requête à la méthode videos:annotate. Cet exemple fait intervenir le jeton d'accès associé à un compte de service configuré pour le projet à l'aide du SDK Cloud. Pour obtenir des instructions sur l'installation du SDK Cloud, la configuration d'un projet avec un compte de service et l'obtention d'un jeton d'accès, consultez la page Guide de démarrage rapide de l'API Video Intelligence.

Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

  • INPUT_URI : bucket Cloud Storage contenant le fichier que vous souhaitez annoter, y compris son nom. Doit commencer par gs://.
    Par exemple, "inputUri": "gs://cloud-videointelligence-demo/assistant.mp4",

Méthode HTTP et URL :

POST https://videointelligence.googleapis.com/v1/videos:annotate

Corps JSON de la requête :

{
  "inputUri": "INPUT_URI",
  "features": ["EXPLICIT_CONTENT_DETECTION"]
}

Pour envoyer votre requête, développez l'une des options suivantes :

Vous devriez recevoir une réponse JSON de ce type :

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID"
}

Si la réponse aboutit, l'API Video Intelligence renvoie le name de votre opération. Vous trouverez ci-dessous un exemple de réponse de ce type, où :

  • PROJECT_NUMBER : numéro de votre projet.
  • LOCATION_ID : région cloud dans laquelle l'annotation doit avoir lieu. Les régions cloud compatibles sont les suivantes : us-east1, us-west1, europe-west1 et asia-east1. Si aucune région n'est spécifiée, une région sera déterminée en fonction de l'emplacement du fichier vidéo.
  • OPERATION_ID : ID de l'opération de longue durée créée pour la requête, qui est fourni dans la réponse renvoyée au démarrage de l'opération, par exemple 12345...

Obtenir des résultats d'annotation

Pour récupérer le résultat de l'opération, envoyez une requête GET en utilisant le nom de l'opération renvoyé par l'appel à videos:annotate, comme indiqué dans l'exemple suivant.

Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

  • OPERATION_NAME: nom de l'opération tel qu'il a été renvoyé par l'API Video Intelligence. Il est au format suivant : projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID.

Méthode HTTP et URL :

GET https://videointelligence.googleapis.com/v1/OPERATION_NAME

Pour envoyer votre requête, développez l'une des options suivantes :

Vous devriez recevoir une réponse JSON de ce type :

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress",
    "annotationProgress": [
     {
      "inputUri": "/demomaker/gbikes_dinosaur.mp4",
      "progressPercent": 100,
      "startTime": "2020-03-26T00:16:35.112404Z",
      "updateTime": "2020-03-26T00:16:55.937889Z"
     }
    ]
   },
   "done": true,
   "response": {
    "@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse",
    "annotationResults": [
     {
      "inputUri": "/demomaker/gbikes_dinosaur.mp4",
      "explicitAnnotation": {
       "frames": [
        {
         "timeOffset": "0.056149s",
         "pornographyLikelihood": "VERY_UNLIKELY"
        },
        {
         "timeOffset": "1.166841s",
         "pornographyLikelihood": "VERY_UNLIKELY"
        },
            ...
        {
         "timeOffset": "41.678209s",
         "pornographyLikelihood": "VERY_UNLIKELY"
        },
        {
         "timeOffset": "42.596413s",
         "pornographyLikelihood": "VERY_UNLIKELY"
        }
       ]
      }
     }
    ]
   }
  }
Les annotations de détection de plans sont renvoyées sous la forme d'une liste shotAnnotations. Remarque : Le champ done n'est renvoyé que lorsque sa valeur est True. Il n'est pas inclus dans les réponses pour lesquelles l'opération n'est pas terminée.

Télécharger les résultats d'annotation

Copiez l'annotation de la source dans le bucket de destination: (voir Copier les fichiers et les objets).

gsutil cp gcs_uri gs://my-bucket

Remarque: Si l'URI gcs de sortie est fourni par l'utilisateur, l'annotation est stockée dans cet URI gcs.

Go


func explicitContentURI(w io.Writer, file string) error {
	ctx := context.Background()
	client, err := video.NewClient(ctx)
	if err != nil {
		return err
	}
	defer client.Close()

	op, err := client.AnnotateVideo(ctx, &videopb.AnnotateVideoRequest{
		Features: []videopb.Feature{
			videopb.Feature_EXPLICIT_CONTENT_DETECTION,
		},
		InputUri: file,
	})
	if err != nil {
		return err
	}
	resp, err := op.Wait(ctx)
	if err != nil {
		return err
	}

	// A single video was processed. Get the first result.
	result := resp.AnnotationResults[0].ExplicitAnnotation

	for _, frame := range result.Frames {
		offset, _ := ptypes.Duration(frame.TimeOffset)
		fmt.Fprintf(w, "%s - %s\n", offset, frame.PornographyLikelihood.String())
	}

	return nil
}

Java

// Instantiate a com.google.cloud.videointelligence.v1.VideoIntelligenceServiceClient
try (VideoIntelligenceServiceClient client = VideoIntelligenceServiceClient.create()) {
  // Create an operation that will contain the response when the operation completes.
  AnnotateVideoRequest request =
      AnnotateVideoRequest.newBuilder()
          .setInputUri(gcsUri)
          .addFeatures(Feature.EXPLICIT_CONTENT_DETECTION)
          .build();

  OperationFuture<AnnotateVideoResponse, AnnotateVideoProgress> response =
      client.annotateVideoAsync(request);

  System.out.println("Waiting for operation to complete...");
  // Print detected annotations and their positions in the analyzed video.
  for (VideoAnnotationResults result : response.get().getAnnotationResultsList()) {
    for (ExplicitContentFrame frame : result.getExplicitAnnotation().getFramesList()) {
      double frameTime =
          frame.getTimeOffset().getSeconds() + frame.getTimeOffset().getNanos() / 1e9;
      System.out.printf("Location: %.3fs\n", frameTime);
      System.out.println("Adult: " + frame.getPornographyLikelihood());
    }
  }

Node.js

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

// Creates a client
const client = new video.VideoIntelligenceServiceClient();

/**
 * TODO(developer): Uncomment the following line before running the sample.
 */
// const gcsUri = 'GCS URI of video to analyze, e.g. gs://my-bucket/my-video.mp4';

const request = {
  inputUri: gcsUri,
  features: ['EXPLICIT_CONTENT_DETECTION'],
};

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

// Detects unsafe content
const [operation] = await client.annotateVideo(request);
console.log('Waiting for operation to complete...');
const [operationResult] = await operation.promise();
// Gets unsafe content
const explicitContentResults =
  operationResult.annotationResults[0].explicitAnnotation;
console.log('Explicit annotation results:');
explicitContentResults.frames.forEach(result => {
  if (result.timeOffset === undefined) {
    result.timeOffset = {};
  }
  if (result.timeOffset.seconds === undefined) {
    result.timeOffset.seconds = 0;
  }
  if (result.timeOffset.nanos === undefined) {
    result.timeOffset.nanos = 0;
  }
  console.log(
    `\tTime: ${result.timeOffset.seconds}` +
      `.${(result.timeOffset.nanos / 1e6).toFixed(0)}s`
  );
  console.log(
    `\t\tPornography likelihood: ${likelihoods[result.pornographyLikelihood]}`
  );
});

Python

Pour en savoir plus sur l'installation et l'utilisation de la bibliothèque cliente de l'API Cloud Video Intelligence pour Python, reportez-vous aux bibliothèques clientes de l'API Cloud Video Intelligence.
""" Detects explicit content from the GCS path to a video. """
video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.EXPLICIT_CONTENT_DETECTION]

operation = video_client.annotate_video(
    request={"features": features, "input_uri": path}
)
print("\nProcessing video for explicit content annotations:")

result = operation.result(timeout=90)
print("\nFinished processing.")

# Retrieve first result because a single video was processed
for frame in result.annotation_results[0].explicit_annotation.frames:
    likelihood = videointelligence.Likelihood(frame.pornography_likelihood)
    frame_time = frame.time_offset.seconds + frame.time_offset.microseconds / 1e6
    print("Time: {}s".format(frame_time))
    print("\tpornography: {}".format(likelihood.name))

Langues supplémentaires

C# : suivez les instructions de configuration C# sur la page des bibliothèques clientes, puis consultez le{ 10.1 Documentation de référence Video Intelligence pour .NET.

PHP : suivez les instructions de configuration PHP sur la page des bibliothèques clientes, puis consultez le{ 10.1 Documentation de référence Video Intelligence pour PHP.

Ruby : suivez les instructions de configuration de Ruby sur la page des bibliothèques clientes, puis accédez à la page { 10.1 Documentation de référence Video Intelligence pour Ruby.