Detección de cambios de plano

La función Análisis de cambio de plano detecta los cambios de plano de un vídeo.

En esta sección se muestran algunas formas de analizar un vídeo para detectar cambios de plano.

A continuación, se muestra un ejemplo de cómo realizar un análisis de vídeo para detectar cambios de plano en un archivo ubicado en Cloud Storage.

¿Buscas información más detallada? Consulta nuestro tutorial detallado sobre Python.

REST

Enviar solicitud de anotación de vídeo

A continuación, se muestra cómo enviar una solicitud POST al método videos:annotate. En el ejemplo se usa Google Cloud CLI para crear un token de acceso. Para obtener instrucciones sobre cómo instalar gcloud CLI, consulta la guía de inicio rápido de la API Video Intelligence.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • INPUT_URI: un segmento de Cloud Storage que contiene el archivo que quieres anotar, incluido el nombre del archivo. Debe empezar por gs://.
  • PROJECT_NUMBER: identificador numérico de tu Google Cloud proyecto

Método HTTP y URL:

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

Cuerpo JSON de la solicitud:

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

Para enviar tu solicitud, despliega una de estas opciones:

Deberías recibir una respuesta JSON similar a la siguiente:

Si la respuesta es correcta, la API Video Intelligence devuelve el name de tu operación. En el ejemplo anterior se muestra una respuesta de este tipo, donde project-name es el nombre de tu proyecto y operation-id es el ID de la operación de larga duración creada para la solicitud.

  • PROJECT_NUMBER: el número de tu proyecto
  • LOCATION_ID: la región de Cloud en la que se debe realizar la anotación. Las regiones de nube admitidas son us-east1, us-west1, europe-west1 y asia-east1. Si no se especifica ninguna región, se determinará una en función de la ubicación del archivo de vídeo.
  • OPERATION_ID: el ID de la operación de larga duración creada para la solicitud y proporcionada en la respuesta cuando iniciaste la operación. Por ejemplo, 12345.....

Obtener resultados de anotación

Para obtener el resultado de la operación, haz una solicitud GET con el nombre de la operación devuelto por la llamada a videos:annotate, como se muestra en el siguiente ejemplo.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • OPERATION_NAME: el nombre de la operación tal como lo devuelve la API Video Intelligence. El nombre de la operación tiene el formato projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID
  • PROJECT_NUMBER: identificador numérico de tu Google Cloud proyecto

Método HTTP y URL:

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

Para enviar tu solicitud, despliega una de estas opciones:

Deberías recibir una respuesta JSON similar a la siguiente:

Las anotaciones de detección de planos se devuelven como una lista shotAnnotations. Nota: El campo done solo se devuelve cuando su valor es True. No se incluye en las respuestas de las operaciones que no se han completado.

Descargar resultados de anotación

Copia la anotación del segmento de origen al de destino (consulta Copiar archivos y objetos).

gcloud storage cp gcs_uri gs://my-bucket

Nota: Si el usuario proporciona el URI de GCS de salida, la anotación se almacenará en ese URI.

Go


func shotChangeURI(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_SHOT_CHANGE_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].ShotAnnotations

	for _, shot := range result {
		start, _ := ptypes.Duration(shot.StartTimeOffset)
		end, _ := ptypes.Duration(shot.EndTimeOffset)

		fmt.Fprintf(w, "Shot: %s to %s\n", start, end)
	}

	return nil
}

Java

Para autenticarte en Video Intelligence, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación en un entorno de desarrollo local.

// Instantiate a com.google.cloud.videointelligence.v1.VideoIntelligenceServiceClient
try (VideoIntelligenceServiceClient client = VideoIntelligenceServiceClient.create()) {
  // Provide path to file hosted on GCS as "gs://bucket-name/..."
  AnnotateVideoRequest request =
      AnnotateVideoRequest.newBuilder()
          .setInputUri(gcsUri)
          .addFeatures(Feature.SHOT_CHANGE_DETECTION)
          .build();

  // Create an operation that will contain the response when the operation completes.
  OperationFuture<AnnotateVideoResponse, AnnotateVideoProgress> response =
      client.annotateVideoAsync(request);

  System.out.println("Waiting for operation to complete...");
  // Print detected shot changes and their location ranges in the analyzed video.
  for (VideoAnnotationResults result : response.get().getAnnotationResultsList()) {
    if (result.getShotAnnotationsCount() > 0) {
      System.out.println("Shots: ");
      for (VideoSegment segment : result.getShotAnnotationsList()) {
        double startTime =
            segment.getStartTimeOffset().getSeconds()
                + segment.getStartTimeOffset().getNanos() / 1e9;
        double endTime =
            segment.getEndTimeOffset().getSeconds()
                + segment.getEndTimeOffset().getNanos() / 1e9;
        System.out.printf("Location: %.3f:%.3f\n", startTime, endTime);
      }
    } else {
      System.out.println("No shot changes detected in " + gcsUri);
    }
  }
}

Node.js

Para autenticarte en Video Intelligence, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación en un entorno de desarrollo local.

// 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 file to analyze, e.g. gs://my-bucket/my-video.mp4';

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

// Detects camera shot changes
const [operation] = await client.annotateVideo(request);
console.log('Waiting for operation to complete...');
const [operationResult] = await operation.promise();
// Gets shot changes
const shotChanges = operationResult.annotationResults[0].shotAnnotations;
console.log('Shot changes:');

if (shotChanges.length === 1) {
  console.log('The entire video is one shot.');
} else {
  shotChanges.forEach((shot, shotIdx) => {
    console.log(`Scene ${shotIdx} occurs from:`);
    if (shot.startTimeOffset === undefined) {
      shot.startTimeOffset = {};
    }
    if (shot.endTimeOffset === undefined) {
      shot.endTimeOffset = {};
    }
    if (shot.startTimeOffset.seconds === undefined) {
      shot.startTimeOffset.seconds = 0;
    }
    if (shot.startTimeOffset.nanos === undefined) {
      shot.startTimeOffset.nanos = 0;
    }
    if (shot.endTimeOffset.seconds === undefined) {
      shot.endTimeOffset.seconds = 0;
    }
    if (shot.endTimeOffset.nanos === undefined) {
      shot.endTimeOffset.nanos = 0;
    }
    console.log(
      `\tStart: ${shot.startTimeOffset.seconds}` +
        `.${(shot.startTimeOffset.nanos / 1e6).toFixed(0)}s`
    );
    console.log(
      `\tEnd: ${shot.endTimeOffset.seconds}.` +
        `${(shot.endTimeOffset.nanos / 1e6).toFixed(0)}s`
    );
  });
}

Python

Para obtener más información sobre cómo instalar y usar la biblioteca de cliente de la API Video Intelligence para Python, consulta Bibliotecas de cliente de la API Video Intelligence.
"""Detects camera shot changes."""
video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.SHOT_CHANGE_DETECTION]
operation = video_client.annotate_video(
    request={"features": features, "input_uri": path}
)
print("\nProcessing video for shot change annotations:")

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

# first result is retrieved because a single video was processed
for i, shot in enumerate(result.annotation_results[0].shot_annotations):
    start_time = (
        shot.start_time_offset.seconds + shot.start_time_offset.microseconds / 1e6
    )
    end_time = (
        shot.end_time_offset.seconds + shot.end_time_offset.microseconds / 1e6
    )
    print("\tShot {}: {} to {}".format(i, start_time, end_time))

Idiomas adicionales

C#: Sigue las instrucciones de configuración de C# en la página de bibliotecas de cliente y, a continuación, consulta la documentación de referencia de Video Intelligence para .NET.

PHP Sigue las instrucciones de configuración de PHP en la página de bibliotecas de cliente y, a continuación, consulta la documentación de referencia de Video Intelligence para PHP.

Ruby: Sigue las instrucciones de configuración de Ruby en la página de bibliotecas de cliente y, a continuación, consulta la documentación de referencia de Video Intelligence para Ruby.