Générer une feuille de sprites pour les images vidéo

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Cette page explique comment générer une feuille de sprites contenant des images à partir d'une vidéo transcodée. Ces images à taille réduite, également appelées vignettes, sont utiles pour organiser et prévisualiser du contenu. Pour générer la feuille de sprites, utilisez le tableau spriteSheets dans le modèle JobConfig.

Deux options s'offrent à vous pour générer la feuille de sprites :

Générer un nombre défini d'images miniatures

La configuration ci-dessous génère une feuille de sprites de 10 x 10 contenant de grandes images et une feuille de sprites de 10 x 10 contenant de petites images, chacune renfermant 100 miniatures. Notez que les feuilles de sprites nécessitent au moins un élément VideoStream dans la configuration de la tâche.

Vous pouvez ajouter cette configuration à un modèle de tâche ou l'inclure dans une configuration de tâche ad hoc :

API REST et ligne de commande

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

  • PROJECT_ID : ID de votre projet Google Cloud répertorié dans les paramètres IAM.
  • LOCATION : emplacement dans lequel votre tâche sera exécutée. Utilisez l'une des régions disponibles :
    • us-central1
    • us-west1
    • us-west2
    • us-east1
    • us-east4
    • southamerica-east1
    • asia-east1
    • asia-south1
    • asia-southeast1
    • europe-west1
    • europe-west2
    • europe-west4
  • STORAGE_BUCKET_NAME : nom du bucket Cloud Storage que vous avez créé.
  • STORAGE_INPUT_VIDEO : nom de la vidéo dans votre bucket Cloud Storage que vous transcodez, par exemple my-vid.mp4. Ce champ doit tenir compte des dossiers créés dans le bucket (par exemple, input/my-vid.mp4).
  • STORAGE_OUTPUT_FOLDER : nom du dossier Cloud Storage dans lequel vous souhaitez enregistrer les sorties vidéo encodées.

Corps JSON de la requête :

{
  "config": {
    "inputs": [
          {
            "key": "input0",
            "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_INPUT_VIDEO"
          }
    ],
    "elementaryStreams": [
      {
        "key": "video-stream0",
        "videoStream": {
          "h264": {
            "heightPixels": 360,
            "widthPixels": 640,
            "bitrateBps": 550000,
            "frameRate": 60
          }
        }
      },
      {
        "key": "audio-stream0",
        "audioStream": {
          "codec": "aac",
          "bitrateBps": 64000
        }
      }
    ],
    "muxStreams": [
      {
        "key": "sd",
        "container": "mp4",
        "elementaryStreams": [
          "video-stream0",
          "audio-stream0"
        ]
      }
    ],
    "output": {
      "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_OUTPUT_FOLDER/"
    },
    "spriteSheets": [
      {
        "filePrefix": "small-sprite-sheet",
        "spriteHeightPixels": 32,
        "spriteWidthPixels": 64,
        "columnCount": 10,
        "rowCount": 10,
        "totalCount": 100
      },
      {
        "filePrefix": "large-sprite-sheet",
        "spriteHeightPixels": 72,
        "spriteWidthPixels": 128,
        "columnCount": 10,
        "rowCount": 10,
        "totalCount": 100
      }
    ]
  }
}

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/jobs/JOB_ID",
  "config": {
   ...
  },
  "state": "PENDING",
  "createTime": CREATE_TIME,
  "ttlAfterCompletionDays": 30
}

gcloud

  1. Créez un fichier request.json qui définit les champs de la tâche. Effectuez les remplacements suivants pour la commande gcloud :
    • STORAGE_BUCKET_NAME : nom du bucket Cloud Storage que vous avez créé.
    • STORAGE_INPUT_VIDEO : nom de la vidéo de votre bucket Cloud Storage que vous transcodez, par exemple my-vid.mp4. Ce champ doit prendre en compte tous les dossiers que vous avez créés dans le bucket (par exemple, input/my-vid.mp4).
    • LOCATION : emplacement où la tâche sera exécutée. Utilisez un emplacement issu de la liste suivante :
      • us-central1
      • us-west1
      • us-west2
      • us-east1
      • us-east4
      • southamerica-east1
      • asia-east1
      • asia-south1
      • asia-southeast1
      • europe-west1
      • europe-west2
      • europe-west4
    • STORAGE_OUTPUT_FOLDER : nom du dossier Cloud Storage dans lequel vous souhaitez enregistrer les sorties vidéo encodées.
    {
      "config": {
        "inputs": [
              {
                "key": "input0",
                "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_INPUT_VIDEO"
              }
        ],
        "elementaryStreams": [
          {
            "key": "video-stream0",
            "videoStream": {
              "h264": {
                "heightPixels": 360,
                "widthPixels": 640,
                "bitrateBps": 550000,
                "frameRate": 60
              }
            }
          },
          {
            "key": "audio-stream0",
            "audioStream": {
              "codec": "aac",
              "bitrateBps": 64000
            }
          }
        ],
        "muxStreams": [
          {
            "key": "sd",
            "container": "mp4",
            "elementaryStreams": [
              "video-stream0",
              "audio-stream0"
            ]
          }
        ],
        "output": {
          "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_OUTPUT_FOLDER/"
        },
        "spriteSheets": [
          {
            "filePrefix": "small-sprite-sheet",
            "spriteHeightPixels": 32,
            "spriteWidthPixels": 64,
            "columnCount": 10,
            "rowCount": 10,
            "totalCount": 100
          },
          {
            "filePrefix": "large-sprite-sheet",
            "spriteHeightPixels": 72,
            "spriteWidthPixels": 128,
            "columnCount": 10,
            "rowCount": 10,
            "totalCount": 100
          }
        ]
      }
    }
    
  2. Exécutez la commande suivante :
    gcloud transcoder jobs create --location=LOCATION --file="request.json"
    
    Un résultat semblable à ceci doit s'afficher :
    {
      "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
      "config": {
       ...
      },
      "state": "PENDING",
      "createTime": CREATE_TIME,
      "ttlAfterCompletionDays": 30
    }
    

C#

Avant d'essayer cet exemple, suivez les instructions de configuration de C# dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder C#.


using Google.Api.Gax.ResourceNames;
using Google.Cloud.Video.Transcoder.V1;

public class CreateJobWithSetNumberImagesSpritesheetSample
{
    public const string SmallSpritesheetFilePrefix = "small-sprite-sheet";
    public const string LargeSpritesheetFilePrefix = "large-sprite-sheet";
    public Job CreateJobWithSetNumberImagesSpritesheet(
        string projectId, string location, string inputUri, string outputUri)
    {
        // Create the client.
        TranscoderServiceClient client = TranscoderServiceClient.Create();

        // Build the parent location name.
        LocationName parent = new LocationName(projectId, location);

        // Build the job config.
        VideoStream videoStream0 = new VideoStream
        {
            H264 = new VideoStream.Types.H264CodecSettings
            {
                BitrateBps = 550000,
                FrameRate = 60,
                HeightPixels = 360,
                WidthPixels = 640
            }
        };

        AudioStream audioStream0 = new AudioStream
        {
            Codec = "aac",
            BitrateBps = 64000
        };

        // Generates a 10x10 spritesheet of small images from the input video.
        // To preserve the source aspect ratio, you should set the
        // SpriteWidthPixels field or the SpriteHeightPixels field, but not
        // both (the API will automatically calculate the missing field). For
        // this sample, we don't care about the aspect ratio so we set both
        // fields.
        SpriteSheet smallSpriteSheet = new SpriteSheet
        {
            FilePrefix = SmallSpritesheetFilePrefix,
            SpriteHeightPixels = 32,
            SpriteWidthPixels = 64,
            ColumnCount = 10,
            RowCount = 10,
            TotalCount = 100
        };

        // Generates a 10x10 spritesheet of larger images from the input video.
        // input video. To preserve the source aspect ratio, you should set the
        // SpriteWidthPixels field or the SpriteHeightPixels field, but not
        // both (the API will automatically calculate the missing field). For
        // this sample, we don't care about the aspect ratio so we set both
        // fields.
        SpriteSheet largeSpriteSheet = new SpriteSheet
        {
            FilePrefix = LargeSpritesheetFilePrefix,
            SpriteHeightPixels = 72,
            SpriteWidthPixels = 128,
            ColumnCount = 10,
            RowCount = 10,
            TotalCount = 100
        };

        ElementaryStream elementaryStream0 = new ElementaryStream
        {
            Key = "video_stream0",
            VideoStream = videoStream0
        };

        ElementaryStream elementaryStream1 = new ElementaryStream
        {
            Key = "audio_stream0",
            AudioStream = audioStream0
        };

        MuxStream muxStream0 = new MuxStream
        {
            Key = "sd",
            Container = "mp4",
            ElementaryStreams = { "video_stream0", "audio_stream0" }
        };

        Input input = new Input
        {
            Key = "input0",
            Uri = inputUri
        };

        Output output = new Output
        {
            Uri = outputUri
        };

        JobConfig jobConfig = new JobConfig
        {
            Inputs = { input },
            Output = output,
            ElementaryStreams = { elementaryStream0, elementaryStream1 },
            MuxStreams = { muxStream0 },
            SpriteSheets = { smallSpriteSheet, largeSpriteSheet }
        };

        // Build the job.
        Job newJob = new Job();
        newJob.InputUri = inputUri;
        newJob.OutputUri = outputUri;
        newJob.Config = jobConfig;

        // Call the API.
        Job job = client.CreateJob(parent, newJob);

        // Return the result.
        return job;
    }
}

Go

Avant d'essayer cet exemple, suivez les instructions de configuration de Go dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Go.

import (
	"context"
	"fmt"
	"io"

	transcoder "cloud.google.com/go/video/transcoder/apiv1"
	transcoderpb "google.golang.org/genproto/googleapis/cloud/video/transcoder/v1"
)

// createJobWithSetNumberImagesSpritesheet creates a job from an ad-hoc configuration and generates
// two spritesheets from the input video. Each spritesheet contains a set number of images.
func createJobWithSetNumberImagesSpritesheet(w io.Writer, projectID string, location string, inputURI string, outputURI string) error {
	// projectID := "my-project-id"
	// location := "us-central1"
	// inputURI := "gs://my-bucket/my-video-file"
	// outputURI := "gs://my-bucket/my-output-folder/"
	ctx := context.Background()
	client, err := transcoder.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient: %v", err)
	}
	defer client.Close()

	req := &transcoderpb.CreateJobRequest{
		Parent: fmt.Sprintf("projects/%s/locations/%s", projectID, location),
		Job: &transcoderpb.Job{
			InputUri:  inputURI,
			OutputUri: outputURI,
			JobConfig: &transcoderpb.Job_Config{
				Config: &transcoderpb.JobConfig{
					ElementaryStreams: []*transcoderpb.ElementaryStream{
						{
							Key: "video_stream0",
							ElementaryStream: &transcoderpb.ElementaryStream_VideoStream{
								VideoStream: &transcoderpb.VideoStream{
									CodecSettings: &transcoderpb.VideoStream_H264{
										H264: &transcoderpb.VideoStream_H264CodecSettings{
											BitrateBps:   550000,
											FrameRate:    60,
											HeightPixels: 360,
											WidthPixels:  640,
										},
									},
								},
							},
						},
						{
							Key: "audio_stream0",
							ElementaryStream: &transcoderpb.ElementaryStream_AudioStream{
								AudioStream: &transcoderpb.AudioStream{
									Codec:      "aac",
									BitrateBps: 64000,
								},
							},
						},
					},
					MuxStreams: []*transcoderpb.MuxStream{
						{
							Key:               "sd",
							Container:         "mp4",
							ElementaryStreams: []string{"video_stream0", "audio_stream0"},
						},
					},
					SpriteSheets: []*transcoderpb.SpriteSheet{
						{
							FilePrefix:         "small-sprite-sheet",
							SpriteWidthPixels:  64,
							SpriteHeightPixels: 32,
							ColumnCount:        10,
							RowCount:           10,
							ExtractionStrategy: &transcoderpb.SpriteSheet_TotalCount{
								TotalCount: 100,
							},
						},
						{
							FilePrefix:         "large-sprite-sheet",
							SpriteWidthPixels:  128,
							SpriteHeightPixels: 72,
							ColumnCount:        10,
							RowCount:           10,
							ExtractionStrategy: &transcoderpb.SpriteSheet_TotalCount{
								TotalCount: 100,
							},
						},
					},
				},
			},
		},
	}
	// Creates the job. Jobs take a variable amount of time to run. You can query for the job state.
	// See https://cloud.google.com/transcoder/docs/how-to/jobs#check_job_status for more info.
	response, err := client.CreateJob(ctx, req)
	if err != nil {
		return fmt.Errorf("createJobWithSetNumberImagesSpritesheet: %v", err)
	}

	fmt.Fprintf(w, "Job: %v", response.GetName())
	return nil
}

Java

Avant d'essayer cet exemple, suivez les instructions de configuration de Java dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Java.


import com.google.cloud.video.transcoder.v1.AudioStream;
import com.google.cloud.video.transcoder.v1.CreateJobRequest;
import com.google.cloud.video.transcoder.v1.ElementaryStream;
import com.google.cloud.video.transcoder.v1.Input;
import com.google.cloud.video.transcoder.v1.Job;
import com.google.cloud.video.transcoder.v1.JobConfig;
import com.google.cloud.video.transcoder.v1.LocationName;
import com.google.cloud.video.transcoder.v1.MuxStream;
import com.google.cloud.video.transcoder.v1.Output;
import com.google.cloud.video.transcoder.v1.SpriteSheet;
import com.google.cloud.video.transcoder.v1.TranscoderServiceClient;
import com.google.cloud.video.transcoder.v1.VideoStream;
import java.io.IOException;

public class CreateJobWithSetNumberImagesSpritesheet {

  public static final String smallSpritesheetFilePrefix = "small-sprite-sheet";
  public static final String largeSpritesheetFilePrefix = "large-sprite-sheet";
  public static final String spritesheetFileSuffix = "0000000000.jpeg";

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String location = "us-central1";
    String inputUri = "gs://my-bucket/my-video-file";
    String outputUri = "gs://my-bucket/my-output-folder/";

    createJobWithSetNumberImagesSpritesheet(projectId, location, inputUri, outputUri);
  }

  // Creates a job from an ad-hoc configuration and generates two spritesheets from the input video.
  // Each spritesheet contains a set number of images.
  public static void createJobWithSetNumberImagesSpritesheet(
      String projectId, String location, String inputUri, String outputUri) throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (TranscoderServiceClient transcoderServiceClient = TranscoderServiceClient.create()) {

      VideoStream videoStream0 =
          VideoStream.newBuilder()
              .setH264(
                  VideoStream.H264CodecSettings.newBuilder()
                      .setBitrateBps(550000)
                      .setFrameRate(60)
                      .setHeightPixels(360)
                      .setWidthPixels(640))
              .build();

      AudioStream audioStream0 =
          AudioStream.newBuilder().setCodec("aac").setBitrateBps(64000).build();

      // Generates a 10x10 spritesheet of small images from the input video. To preserve the source
      // aspect ratio, you should set the spriteWidthPixels field or the spriteHeightPixels
      // field, but not both.
      SpriteSheet smallSpriteSheet =
          SpriteSheet.newBuilder()
              .setFilePrefix(smallSpritesheetFilePrefix)
              .setSpriteHeightPixels(32)
              .setSpriteWidthPixels(64)
              .setColumnCount(10)
              .setRowCount(10)
              .setTotalCount(100)
              .build();

      // Generates a 10x10 spritesheet of larger images from the input video.
      SpriteSheet largeSpriteSheet =
          SpriteSheet.newBuilder()
              .setFilePrefix(largeSpritesheetFilePrefix)
              .setSpriteHeightPixels(72)
              .setSpriteWidthPixels(128)
              .setColumnCount(10)
              .setRowCount(10)
              .setTotalCount(100)
              .build();

      JobConfig config =
          JobConfig.newBuilder()
              .addInputs(Input.newBuilder().setKey("input0").setUri(inputUri))
              .setOutput(Output.newBuilder().setUri(outputUri))
              .addElementaryStreams(
                  ElementaryStream.newBuilder()
                      .setKey("video_stream0")
                      .setVideoStream(videoStream0))
              .addElementaryStreams(
                  ElementaryStream.newBuilder()
                      .setKey("audio_stream0")
                      .setAudioStream(audioStream0))
              .addMuxStreams(
                  MuxStream.newBuilder()
                      .setKey("sd")
                      .setContainer("mp4")
                      .addElementaryStreams("video_stream0")
                      .addElementaryStreams("audio_stream0")
                      .build())
              .addSpriteSheets(smallSpriteSheet) // Add the spritesheet config to the job config
              .addSpriteSheets(largeSpriteSheet) // Add the spritesheet config to the job config
              .build();

      var createJobRequest =
          CreateJobRequest.newBuilder()
              .setJob(
                  Job.newBuilder()
                      .setInputUri(inputUri)
                      .setOutputUri(outputUri)
                      .setConfig(config)
                      .build())
              .setParent(LocationName.of(projectId, location).toString())
              .build();

      // Send the job creation request and process the response.
      Job job = transcoderServiceClient.createJob(createJobRequest);
      System.out.println("Job: " + job.getName());
    }
  }
}

Node.js

Avant d'essayer cet exemple, suivez les instructions de configuration de Node.js dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Node.js.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// projectId = 'my-project-id';
// location = 'us-central1';
// inputUri = 'gs://my-bucket/my-video-file';
// outputUri = 'gs://my-bucket/my-output-folder/';

// Imports the Transcoder library
const {TranscoderServiceClient} =
  require('@google-cloud/video-transcoder').v1;

// Instantiates a client
const transcoderServiceClient = new TranscoderServiceClient();

async function createJobWithSetNumberImagesSpritesheet() {
  // Construct request
  const request = {
    parent: transcoderServiceClient.locationPath(projectId, location),
    job: {
      inputUri: inputUri,
      outputUri: outputUri,
      config: {
        elementaryStreams: [
          {
            key: 'video-stream0',
            videoStream: {
              h264: {
                heightPixels: 360,
                widthPixels: 640,
                bitrateBps: 550000,
                frameRate: 60,
              },
            },
          },
          {
            key: 'audio-stream0',
            audioStream: {
              codec: 'aac',
              bitrateBps: 64000,
            },
          },
        ],
        muxStreams: [
          {
            key: 'sd',
            container: 'mp4',
            elementaryStreams: ['video-stream0', 'audio-stream0'],
          },
        ],
        spriteSheets: [
          {
            filePrefix: 'small-sprite-sheet',
            spriteHeightPixels: 32,
            spriteWidthPixels: 64,
            columnCount: 10,
            rowCount: 10,
            totalCount: 100,
          },
          {
            filePrefix: 'large-sprite-sheet',
            spriteHeightPixels: 72,
            spriteWidthPixels: 128,
            columnCount: 10,
            rowCount: 10,
            totalCount: 100,
          },
        ],
      },
    },
  };

  // Run request
  const [response] = await transcoderServiceClient.createJob(request);
  console.log(`Job: ${response.name}`);
}

createJobWithSetNumberImagesSpritesheet();

PHP

Avant d'essayer cet exemple, suivez les instructions de configuration de PHP dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder PHP.

use Google\Cloud\Video\Transcoder\V1\AudioStream;
use Google\Cloud\Video\Transcoder\V1\ElementaryStream;
use Google\Cloud\Video\Transcoder\V1\Job;
use Google\Cloud\Video\Transcoder\V1\JobConfig;
use Google\Cloud\Video\Transcoder\V1\MuxStream;
use Google\Cloud\Video\Transcoder\V1\SpriteSheet;
use Google\Cloud\Video\Transcoder\V1\TranscoderServiceClient;
use Google\Cloud\Video\Transcoder\V1\VideoStream;

/**
 * Creates a job that generates two spritesheets from the input video. Each
 * spritesheet contains a set number of images.
 *
 * @param string $projectId The ID of your Google Cloud Platform project.
 * @param string $location The location of the job.
 * @param string $inputUri Uri of the video in the Cloud Storage bucket.
 * @param string $outputUri Uri of the video output folder in the Cloud Storage bucket.
 */
function create_job_with_set_number_images_spritesheet($projectId, $location, $inputUri, $outputUri)
{
    // Instantiate a client.
    $transcoderServiceClient = new TranscoderServiceClient();

    $formattedParent = $transcoderServiceClient->locationName($projectId, $location);
    $jobConfig =
        (new JobConfig())->setElementaryStreams([
            (new ElementaryStream())
                ->setKey('video-stream0')
                ->setVideoStream(
                    (new VideoStream())
                        ->setH264(
                            (new VideoStream\H264CodecSettings())
                                ->setBitrateBps(550000)
                                ->setFrameRate(60)
                                ->setHeightPixels(360)
                                ->setWidthPixels(640)
                        )
                ),
            (new ElementaryStream())
                ->setKey('audio-stream0')
                ->setAudioStream(
                    (new AudioStream())
                        ->setCodec('aac')
                        ->setBitrateBps(64000)
                )
        ])->setMuxStreams([
            (new MuxStream())
                ->setKey('sd')
                ->setContainer('mp4')
                ->setElementaryStreams(['video-stream0', 'audio-stream0'])
        ])->setSpriteSheets([
            (new SpriteSheet())
                ->setFilePrefix('small-sprite-sheet')
                ->setSpriteWidthPixels(64)
                ->setSpriteHeightPixels(32)
                ->setColumnCount(10)
                ->setRowCount(10)
                ->setTotalCount(100),
            (new SpriteSheet())
                ->setFilePrefix('large-sprite-sheet')
                ->setSpriteWidthPixels(128)
                ->setSpriteHeightPixels(72)
                ->setColumnCount(10)
                ->setRowCount(10)
                ->setTotalCount(100)
        ]);

    $job = (new Job())
        ->setInputUri($inputUri)
        ->setOutputUri($outputUri)
        ->setConfig($jobConfig);

    $response = $transcoderServiceClient->createJob($formattedParent, $job);

    // Print job name.
    printf('Job: %s' . PHP_EOL, $response->getName());
}

Python

Avant d'essayer cet exemple, suivez les instructions de configuration de Python dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Python.


import argparse

from google.cloud.video import transcoder_v1
from google.cloud.video.transcoder_v1.services.transcoder_service import (
    TranscoderServiceClient,
)

def create_job_with_set_number_images_spritesheet(
    project_id, location, input_uri, output_uri
):
    """Creates a job based on an ad-hoc job configuration that generates two spritesheets.

    Args:
        project_id: The GCP project ID.
        location: The location to start the job in.
        input_uri: Uri of the video in the Cloud Storage bucket.
        output_uri: Uri of the video output folder in the Cloud Storage bucket."""

    client = TranscoderServiceClient()

    parent = f"projects/{project_id}/locations/{location}"
    job = transcoder_v1.types.Job()
    job.input_uri = input_uri
    job.output_uri = output_uri
    job.config = transcoder_v1.types.JobConfig(
        # Create an ad-hoc job. For more information, see https://cloud.google.com/transcoder/docs/how-to/jobs#create_jobs_ad_hoc.
        # See all options for the job config at https://cloud.google.com/transcoder/docs/reference/rest/v1/JobConfig.
        elementary_streams=[
            # This section defines the output video stream.
            transcoder_v1.types.ElementaryStream(
                key="video-stream0",
                video_stream=transcoder_v1.types.VideoStream(
                    h264=transcoder_v1.types.VideoStream.H264CodecSettings(
                        height_pixels=360,
                        width_pixels=640,
                        bitrate_bps=550000,
                        frame_rate=60,
                    ),
                ),
            ),
            # This section defines the output audio stream.
            transcoder_v1.types.ElementaryStream(
                key="audio-stream0",
                audio_stream=transcoder_v1.types.AudioStream(
                    codec="aac", bitrate_bps=64000
                ),
            ),
        ],
        # This section multiplexes the output audio and video together into a container.
        mux_streams=[
            transcoder_v1.types.MuxStream(
                key="sd",
                container="mp4",
                elementary_streams=["video-stream0", "audio-stream0"],
            ),
        ],
        # Generate two sprite sheets from the input video into the GCS bucket. For more information, see
        # https://cloud.google.com/transcoder/docs/how-to/generate-spritesheet#generate_set_number_of_images.
        sprite_sheets=[
            # Generate a 10x10 sprite sheet with 64x32px images.
            transcoder_v1.types.SpriteSheet(
                file_prefix="small-sprite-sheet",
                sprite_width_pixels=64,
                sprite_height_pixels=32,
                column_count=10,
                row_count=10,
                total_count=100,
            ),
            # Generate a 10x10 sprite sheet with 128x72px images.
            transcoder_v1.types.SpriteSheet(
                file_prefix="large-sprite-sheet",
                sprite_width_pixels=128,
                sprite_height_pixels=72,
                column_count=10,
                row_count=10,
                total_count=100,
            ),
        ],
    )
    response = client.create_job(parent=parent, job=job)
    print(f"Job: {response.name}")
    return response

Ruby

Avant d'essayer cet exemple, suivez les instructions de configuration de Ruby dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Ruby.

# project_id  = "YOUR-GOOGLE-CLOUD-PROJECT"  # (e.g. "my-project")
# location    = "YOUR-JOB-LOCATION"  # (e.g. "us-central1")
# input_uri   = "YOUR-GCS-INPUT-VIDEO"  # (e.g. "gs://my-bucket/my-video-file")
# output_uri  = "YOUR-GCS-OUTPUT-FOLDER/"  # (e.g. "gs://my-bucket/my-output-folder/")

# Require the Transcoder client library.
require "google/cloud/video/transcoder"

# Create a Transcoder client.
client = Google::Cloud::Video::Transcoder.transcoder_service

# Build the resource name of the parent.
parent = client.location_path project: project_id, location: location

# Build the job config.
new_job = {
  input_uri: input_uri,
  output_uri: output_uri,
  config: {
    elementary_streams: [
      {
        key: "video-stream0",
        video_stream: {
          h264: {
            height_pixels: 360,
            width_pixels: 640,
            bitrate_bps: 550_000,
            frame_rate: 60
          }
        }
      },
      {
        key: "audio-stream0",
        audio_stream: {
          codec: "aac",
          bitrate_bps: 64_000
        }
      }
    ],
    mux_streams: [
      {
        key: "sd",
        container: "mp4",
        elementary_streams: [
          "video-stream0",
          "audio-stream0"
        ]
      }
    ],
    sprite_sheets: [
      {
        file_prefix: "small-sprite-sheet",
        sprite_width_pixels: 64,
        sprite_height_pixels: 32,
        column_count: 10,
        row_count: 10,
        total_count: 100
      },
      {
        file_prefix: "large-sprite-sheet",
        sprite_width_pixels: 128,
        sprite_height_pixels: 72,
        column_count: 10,
        row_count: 10,
        total_count: 100
      }
    ]
  }
}

job = client.create_job parent: parent, job: new_job

# Print the job name.
puts "Job: #{job.name}"

Utilisez cette configuration sur l'exemple de vidéo pour générer les feuilles de sprites suivantes :

Feuille de sprites de petites images
Figure 1. Feuille de sprites de petites images (100 vignettes)

Feuille de sprites de grandes images
Figure 2. Feuille de sprites de grandes images (100 vignettes)

Générer une image miniature régulièrement

La configuration ci-dessous génère une feuille de sprites de petites images et une feuille de sprites de grandes images. Chaque feuille de sprites contient des vignettes générées toutes les 7 secondes à partir de la vidéo d'entrée. Notez que les feuilles de sprites nécessitent au moins un élément VideoStream dans la configuration de la tâche.

Vous pouvez ajouter cette configuration à un modèle de tâche ou l'inclure dans une configuration de tâche ad hoc :

API REST et ligne de commande

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

  • PROJECT_ID : ID de votre projet Google Cloud répertorié dans les paramètres IAM.
  • LOCATION : emplacement dans lequel votre tâche sera exécutée. Utilisez l'une des régions disponibles :
    • us-central1
    • us-west1
    • us-west2
    • us-east1
    • us-east4
    • southamerica-east1
    • asia-east1
    • asia-south1
    • asia-southeast1
    • europe-west1
    • europe-west2
    • europe-west4
  • STORAGE_BUCKET_NAME : nom du bucket Cloud Storage que vous avez créé.
  • STORAGE_INPUT_VIDEO : nom de la vidéo dans votre bucket Cloud Storage que vous transcodez, par exemple my-vid.mp4. Ce champ doit tenir compte des dossiers créés dans le bucket (par exemple, input/my-vid.mp4).
  • STORAGE_OUTPUT_FOLDER : nom du dossier Cloud Storage dans lequel vous souhaitez enregistrer les sorties vidéo encodées.

Corps JSON de la requête :

{
  "config": {
    "inputs": [
          {
            "key": "input0",
            "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_INPUT_VIDEO"
          }
    ],
    "elementaryStreams": [
      {
        "key": "video-stream0",
        "videoStream": {
          "h264": {
            "heightPixels": 360,
            "widthPixels": 640,
            "bitrateBps": 550000,
            "frameRate": 60
          }
        }
      },
      {
        "key": "audio-stream0",
        "audioStream": {
          "codec": "aac",
          "bitrateBps": 64000
        }
      }
    ],
    "muxStreams": [
      {
        "key": "sd",
        "container": "mp4",
        "elementaryStreams": [
          "video-stream0",
          "audio-stream0"
        ]
      }
    ],
    "output": {
      "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_OUTPUT_FOLDER/"
    },
    "spriteSheets": [
      {
        "filePrefix": "small-sprite-sheet",
        "spriteHeightPixels": 32,
        "spriteWidthPixels": 64,
        "interval": "7s"
      },
      {
        "filePrefix": "large-sprite-sheet",
        "spriteHeightPixels": 72,
        "spriteWidthPixels": 128,
        "interval": "7s"
      }
    ]
  }
}

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/jobs/JOB_ID",
  "config": {
   ...
  },
  "state": "PENDING",
  "createTime": CREATE_TIME,
  "ttlAfterCompletionDays": 30
}

gcloud

  1. Créez un fichier request.json qui définit les champs de la tâche. Effectuez les remplacements suivants pour la commande gcloud :
    • STORAGE_BUCKET_NAME : nom du bucket Cloud Storage que vous avez créé.
    • STORAGE_INPUT_VIDEO : nom de la vidéo de votre bucket Cloud Storage que vous transcodez, par exemple my-vid.mp4. Ce champ doit prendre en compte tous les dossiers que vous avez créés dans le bucket (par exemple, input/my-vid.mp4).
    • LOCATION: emplacement où la tâche sera exécutée. Utilisez un emplacement issu de la liste suivante :
      • us-central1
      • us-west1
      • us-west2
      • us-east1
      • us-east4
      • southamerica-east1
      • asia-east1
      • asia-south1
      • asia-southeast1
      • europe-west1
      • europe-west2
      • europe-west4
    • STORAGE_OUTPUT_FOLDER: nom du dossier Cloud Storage dans lequel vous souhaitez enregistrer les sorties vidéo encodées.
    {
      "config": {
        "inputs": [
              {
                "key": "input0",
                "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_INPUT_VIDEO"
              }
        ],
        "elementaryStreams": [
          {
            "key": "video-stream0",
            "videoStream": {
              "h264": {
                "heightPixels": 360,
                "widthPixels": 640,
                "bitrateBps": 550000,
                "frameRate": 60
              }
            }
          },
          {
            "key": "audio-stream0",
            "audioStream": {
              "codec": "aac",
              "bitrateBps": 64000
            }
          }
        ],
        "muxStreams": [
          {
            "key": "sd",
            "container": "mp4",
            "elementaryStreams": [
              "video-stream0",
              "audio-stream0"
            ]
          }
        ],
        "output": {
          "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_OUTPUT_FOLDER/"
        },
        "spriteSheets": [
          {
            "filePrefix": "small-sprite-sheet",
            "spriteHeightPixels": 32,
            "spriteWidthPixels": 64,
            "interval": "7s"
          },
          {
            "filePrefix": "large-sprite-sheet",
            "spriteHeightPixels": 72,
            "spriteWidthPixels": 128,
            "interval": "7s"
          }
        ]
      }
    }
    
  2. Exécutez la commande suivante :
    gcloud transcoder jobs create --location=LOCATION --file="request.json"
    
    Un résultat semblable à ceci doit s'afficher :
    {
      "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
      "config": {
       ...
      },
      "state": "PENDING",
      "createTime": CREATE_TIME,
      "ttlAfterCompletionDays": 30
    }
    

C#

Avant d'essayer cet exemple, suivez les instructions de configuration de C# dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder C#.


using Google.Api.Gax.ResourceNames;
using Google.Cloud.Video.Transcoder.V1;
using Google.Protobuf.WellKnownTypes;
using System;

public class CreateJobWithPeriodicImagesSpritesheetSample
{
    public const string SmallSpritesheetFilePrefix = "small-sprite-sheet";
    public const string LargeSpritesheetFilePrefix = "large-sprite-sheet";
    public Job CreateJobWithPeriodicImagesSpritesheet(
        string projectId, string location, string inputUri, string outputUri)
    {
        // Create the client.
        TranscoderServiceClient client = TranscoderServiceClient.Create();

        // Build the parent location name.
        LocationName parent = new LocationName(projectId, location);

        // Build the job config.
        VideoStream videoStream0 = new VideoStream
        {
            H264 = new VideoStream.Types.H264CodecSettings
            {
                BitrateBps = 550000,
                FrameRate = 60,
                HeightPixels = 360,
                WidthPixels = 640
            }
        };

        AudioStream audioStream0 = new AudioStream
        {
            Codec = "aac",
            BitrateBps = 64000
        };

        // Generates a spritesheet of small images taken periodically from the
        // input video. To preserve the source aspect ratio, you should set the
        // SpriteWidthPixels field or the SpriteHeightPixels field, but not
        // both (the API will automatically calculate the missing field). For
        // this sample, we don't care about the aspect ratio so we set both
        // fields.
        SpriteSheet smallSpriteSheet = new SpriteSheet
        {
            FilePrefix = SmallSpritesheetFilePrefix,
            SpriteHeightPixels = 32,
            SpriteWidthPixels = 64,
            Interval = Duration.FromTimeSpan(TimeSpan.FromSeconds(7))
        };

        // Generates a spritesheet of larger images taken periodically from the
        // input video. To preserve the source aspect ratio, you should set the
        // SpriteWidthPixels field or the SpriteHeightPixels field, but not
        // both (the API will automatically calculate the missing field). For
        // this sample, we don't care about the aspect ratio so we set both
        // fields.
        SpriteSheet largeSpriteSheet = new SpriteSheet
        {
            FilePrefix = LargeSpritesheetFilePrefix,
            SpriteHeightPixels = 72,
            SpriteWidthPixels = 128,
            Interval = Duration.FromTimeSpan(TimeSpan.FromSeconds(7))
        };

        ElementaryStream elementaryStream0 = new ElementaryStream
        {
            Key = "video_stream0",
            VideoStream = videoStream0
        };

        ElementaryStream elementaryStream1 = new ElementaryStream
        {
            Key = "audio_stream0",
            AudioStream = audioStream0
        };

        MuxStream muxStream0 = new MuxStream
        {
            Key = "sd",
            Container = "mp4",
            ElementaryStreams = { "video_stream0", "audio_stream0" }
        };

        Input input = new Input
        {
            Key = "input0",
            Uri = inputUri
        };

        Output output = new Output
        {
            Uri = outputUri
        };

        JobConfig jobConfig = new JobConfig
        {
            Inputs = { input },
            Output = output,
            ElementaryStreams = { elementaryStream0, elementaryStream1 },
            MuxStreams = { muxStream0 },
            SpriteSheets = { smallSpriteSheet, largeSpriteSheet }
        };

        // Build the job.
        Job newJob = new Job
        {
            InputUri = inputUri,
            OutputUri = outputUri,
            Config = jobConfig
        };

        // Call the API.
        Job job = client.CreateJob(parent, newJob);

        // Return the result.
        return job;
    }
}

Go

Avant d'essayer cet exemple, suivez les instructions de configuration de Go dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Go.

import (
	"context"
	"fmt"
	"io"

	"github.com/golang/protobuf/ptypes/duration"

	transcoder "cloud.google.com/go/video/transcoder/apiv1"
	transcoderpb "google.golang.org/genproto/googleapis/cloud/video/transcoder/v1"
)

// createJobWithPeriodicImagesSpritesheet creates a job from an ad-hoc configuration and generates
// two spritesheets from the input video. Each spritesheet contains images that are captured
// periodically based on a user-defined time interval.
func createJobWithPeriodicImagesSpritesheet(w io.Writer, projectID string, location string, inputURI string, outputURI string) error {
	// projectID := "my-project-id"
	// location := "us-central1"
	// inputURI := "gs://my-bucket/my-video-file"
	// outputURI := "gs://my-bucket/my-output-folder/"
	ctx := context.Background()
	client, err := transcoder.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient: %v", err)
	}
	defer client.Close()

	req := &transcoderpb.CreateJobRequest{
		Parent: fmt.Sprintf("projects/%s/locations/%s", projectID, location),
		Job: &transcoderpb.Job{
			InputUri:  inputURI,
			OutputUri: outputURI,
			JobConfig: &transcoderpb.Job_Config{
				Config: &transcoderpb.JobConfig{
					ElementaryStreams: []*transcoderpb.ElementaryStream{
						{
							Key: "video_stream0",
							ElementaryStream: &transcoderpb.ElementaryStream_VideoStream{
								VideoStream: &transcoderpb.VideoStream{
									CodecSettings: &transcoderpb.VideoStream_H264{
										H264: &transcoderpb.VideoStream_H264CodecSettings{
											BitrateBps:   550000,
											FrameRate:    60,
											HeightPixels: 360,
											WidthPixels:  640,
										},
									},
								},
							},
						},
						{
							Key: "audio_stream0",
							ElementaryStream: &transcoderpb.ElementaryStream_AudioStream{
								AudioStream: &transcoderpb.AudioStream{
									Codec:      "aac",
									BitrateBps: 64000,
								},
							},
						},
					},
					MuxStreams: []*transcoderpb.MuxStream{
						{
							Key:               "sd",
							Container:         "mp4",
							ElementaryStreams: []string{"video_stream0", "audio_stream0"},
						},
					},
					SpriteSheets: []*transcoderpb.SpriteSheet{
						{
							FilePrefix:         "small-sprite-sheet",
							SpriteWidthPixels:  64,
							SpriteHeightPixels: 32,
							ExtractionStrategy: &transcoderpb.SpriteSheet_Interval{
								Interval: &duration.Duration{
									Seconds: 7,
								},
							},
						},
						{
							FilePrefix:         "large-sprite-sheet",
							SpriteWidthPixels:  128,
							SpriteHeightPixels: 72,
							ExtractionStrategy: &transcoderpb.SpriteSheet_Interval{
								Interval: &duration.Duration{
									Seconds: 7,
								},
							},
						},
					},
				},
			},
		},
	}
	// Creates the job. Jobs take a variable amount of time to run. You can query for the job state.
	// See https://cloud.google.com/transcoder/docs/how-to/jobs#check_job_status for more info.
	response, err := client.CreateJob(ctx, req)
	if err != nil {
		return fmt.Errorf("createJobWithPeriodicImagesSpritesheet: %v", err)
	}

	fmt.Fprintf(w, "Job: %v", response.GetName())
	return nil
}

Java

Avant d'essayer cet exemple, suivez les instructions de configuration de Java dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Java.


import com.google.cloud.video.transcoder.v1.AudioStream;
import com.google.cloud.video.transcoder.v1.CreateJobRequest;
import com.google.cloud.video.transcoder.v1.ElementaryStream;
import com.google.cloud.video.transcoder.v1.Input;
import com.google.cloud.video.transcoder.v1.Job;
import com.google.cloud.video.transcoder.v1.JobConfig;
import com.google.cloud.video.transcoder.v1.LocationName;
import com.google.cloud.video.transcoder.v1.MuxStream;
import com.google.cloud.video.transcoder.v1.Output;
import com.google.cloud.video.transcoder.v1.SpriteSheet;
import com.google.cloud.video.transcoder.v1.TranscoderServiceClient;
import com.google.cloud.video.transcoder.v1.VideoStream;
import com.google.protobuf.Duration;
import java.io.IOException;

public class CreateJobWithPeriodicImagesSpritesheet {

  public static final String smallSpritesheetFilePrefix = "small-sprite-sheet";
  public static final String largeSpritesheetFilePrefix = "large-sprite-sheet";
  public static final String spritesheetFileSuffix = "0000000000.jpeg";

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String location = "us-central1";
    String inputUri = "gs://my-bucket/my-video-file";
    String outputUri = "gs://my-bucket/my-output-folder/";

    createJobWithPeriodicImagesSpritesheet(projectId, location, inputUri, outputUri);
  }

  // Creates a job from an ad-hoc configuration and generates two spritesheets from the input video.
  // Each spritesheet contains images that are captured periodically based on a user-defined time
  // interval.
  public static void createJobWithPeriodicImagesSpritesheet(
      String projectId, String location, String inputUri, String outputUri) throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (TranscoderServiceClient transcoderServiceClient = TranscoderServiceClient.create()) {

      VideoStream videoStream0 =
          VideoStream.newBuilder()
              .setH264(
                  VideoStream.H264CodecSettings.newBuilder()
                      .setBitrateBps(550000)
                      .setFrameRate(60)
                      .setHeightPixels(360)
                      .setWidthPixels(640))
              .build();

      AudioStream audioStream0 =
          AudioStream.newBuilder().setCodec("aac").setBitrateBps(64000).build();

      // Generates a spritesheet of small images taken periodically from the input video. To
      // preserve the source aspect ratio, you should set the spriteWidthPixels field or the
      // spriteHeightPixels field, but not both.
      SpriteSheet smallSpriteSheet =
          SpriteSheet.newBuilder()
              .setFilePrefix(smallSpritesheetFilePrefix)
              .setSpriteHeightPixels(32)
              .setSpriteWidthPixels(64)
              .setInterval(Duration.newBuilder().setSeconds(7).build())
              .build();

      // Generates a spritesheet of larger images taken periodically from the input video. To
      SpriteSheet largeSpriteSheet =
          SpriteSheet.newBuilder()
              .setFilePrefix(largeSpritesheetFilePrefix)
              .setSpriteHeightPixels(72)
              .setSpriteWidthPixels(128)
              .setInterval(Duration.newBuilder().setSeconds(7).build())
              .build();

      JobConfig config =
          JobConfig.newBuilder()
              .addInputs(Input.newBuilder().setKey("input0").setUri(inputUri))
              .setOutput(Output.newBuilder().setUri(outputUri))
              .addElementaryStreams(
                  ElementaryStream.newBuilder()
                      .setKey("video_stream0")
                      .setVideoStream(videoStream0))
              .addElementaryStreams(
                  ElementaryStream.newBuilder()
                      .setKey("audio_stream0")
                      .setAudioStream(audioStream0))
              .addMuxStreams(
                  MuxStream.newBuilder()
                      .setKey("sd")
                      .setContainer("mp4")
                      .addElementaryStreams("video_stream0")
                      .addElementaryStreams("audio_stream0")
                      .build())
              .addSpriteSheets(smallSpriteSheet) // Add the spritesheet config to the job config
              .addSpriteSheets(largeSpriteSheet) // Add the spritesheet config to the job config
              .build();

      var createJobRequest =
          CreateJobRequest.newBuilder()
              .setJob(
                  Job.newBuilder()
                      .setInputUri(inputUri)
                      .setOutputUri(outputUri)
                      .setConfig(config)
                      .build())
              .setParent(LocationName.of(projectId, location).toString())
              .build();

      // Send the job creation request and process the response.
      Job job = transcoderServiceClient.createJob(createJobRequest);
      System.out.println("Job: " + job.getName());
    }
  }
}

Node.js

Avant d'essayer cet exemple, suivez les instructions de configuration de Node.js dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Node.js.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// projectId = 'my-project-id';
// location = 'us-central1';
// inputUri = 'gs://my-bucket/my-video-file';
// outputUri = 'gs://my-bucket/my-output-folder/';

// Imports the Transcoder library
const {TranscoderServiceClient} =
  require('@google-cloud/video-transcoder').v1;

// Instantiates a client
const transcoderServiceClient = new TranscoderServiceClient();

async function createJobWithPeriodicImagesSpritesheet() {
  // Construct request
  const request = {
    parent: transcoderServiceClient.locationPath(projectId, location),
    job: {
      inputUri: inputUri,
      outputUri: outputUri,
      config: {
        elementaryStreams: [
          {
            key: 'video-stream0',
            videoStream: {
              h264: {
                heightPixels: 360,
                widthPixels: 640,
                bitrateBps: 550000,
                frameRate: 60,
              },
            },
          },
          {
            key: 'audio-stream0',
            audioStream: {
              codec: 'aac',
              bitrateBps: 64000,
            },
          },
        ],
        muxStreams: [
          {
            key: 'sd',
            container: 'mp4',
            elementaryStreams: ['video-stream0', 'audio-stream0'],
          },
        ],
        spriteSheets: [
          {
            filePrefix: 'small-sprite-sheet',
            spriteHeightPixels: 32,
            spriteWidthPixels: 64,
            interval: {
              seconds: 7,
            },
          },
          {
            filePrefix: 'large-sprite-sheet',
            spriteHeightPixels: 72,
            spriteWidthPixels: 128,
            interval: {
              seconds: 7,
            },
          },
        ],
      },
    },
  };

  // Run request
  const [response] = await transcoderServiceClient.createJob(request);
  console.log(`Job: ${response.name}`);
}

createJobWithPeriodicImagesSpritesheet();

PHP

Avant d'essayer cet exemple, suivez les instructions de configuration de PHP dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder PHP.

use Google\Cloud\Video\Transcoder\V1\AudioStream;
use Google\Cloud\Video\Transcoder\V1\ElementaryStream;
use Google\Cloud\Video\Transcoder\V1\Job;
use Google\Cloud\Video\Transcoder\V1\JobConfig;
use Google\Cloud\Video\Transcoder\V1\MuxStream;
use Google\Cloud\Video\Transcoder\V1\SpriteSheet;
use Google\Cloud\Video\Transcoder\V1\TranscoderServiceClient;
use Google\Cloud\Video\Transcoder\V1\VideoStream;
use Google\Protobuf\Duration;

/**
 * Creates a job that generates two spritesheets from the input video. Each
 * spritesheet contains images that are captured periodically.
 *
 * @param string $projectId The ID of your Google Cloud Platform project.
 * @param string $location The location of the job.
 * @param string $inputUri Uri of the video in the Cloud Storage bucket.
 * @param string $outputUri Uri of the video output folder in the Cloud Storage bucket.
 */
function create_job_with_periodic_images_spritesheet($projectId, $location, $inputUri, $outputUri)
{
    // Instantiate a client.
    $transcoderServiceClient = new TranscoderServiceClient();

    $formattedParent = $transcoderServiceClient->locationName($projectId, $location);
    $jobConfig =
        (new JobConfig())->setElementaryStreams([
            (new ElementaryStream())
                ->setKey('video-stream0')
                ->setVideoStream(
                    (new VideoStream())
                        ->setH264(
                            (new VideoStream\H264CodecSettings())
                                ->setBitrateBps(550000)
                                ->setFrameRate(60)
                                ->setHeightPixels(360)
                                ->setWidthPixels(640)
                        )
                ),
            (new ElementaryStream())
                ->setKey('audio-stream0')
                ->setAudioStream(
                    (new AudioStream())
                        ->setCodec('aac')
                        ->setBitrateBps(64000)
                )
        ])->setMuxStreams([
            (new MuxStream())
                ->setKey('sd')
                ->setContainer('mp4')
                ->setElementaryStreams(['video-stream0', 'audio-stream0'])
        ])->setSpriteSheets([
            (new SpriteSheet())
                ->setFilePrefix('small-sprite-sheet')
                ->setSpriteWidthPixels(64)
                ->setSpriteHeightPixels(32)
                ->setInterval(
                    (new Duration())
                        ->setSeconds(7)
                ),
            (new SpriteSheet())
                ->setFilePrefix('large-sprite-sheet')
                ->setSpriteWidthPixels(128)
                ->setSpriteHeightPixels(72)
                ->setInterval(new Duration(['seconds' => 7]))
        ]);

    $job = (new Job())
        ->setInputUri($inputUri)
        ->setOutputUri($outputUri)
        ->setConfig($jobConfig);

    $response = $transcoderServiceClient->createJob($formattedParent, $job);

    // Print job name.
    printf('Job: %s' . PHP_EOL, $response->getName());
}

Python

Avant d'essayer cet exemple, suivez les instructions de configuration de Python dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Python.


import argparse

from google.cloud.video import transcoder_v1
from google.cloud.video.transcoder_v1.services.transcoder_service import (
    TranscoderServiceClient,
)
from google.protobuf import duration_pb2 as duration

def create_job_with_periodic_images_spritesheet(
    project_id, location, input_uri, output_uri
):
    """Creates a job based on an ad-hoc job configuration that generates two spritesheets.

    Args:
        project_id: The GCP project ID.
        location: The location to start the job in.
        input_uri: Uri of the video in the Cloud Storage bucket.
        output_uri: Uri of the video output folder in the Cloud Storage bucket."""

    client = TranscoderServiceClient()

    parent = f"projects/{project_id}/locations/{location}"
    job = transcoder_v1.types.Job()
    job.input_uri = input_uri
    job.output_uri = output_uri
    job.config = transcoder_v1.types.JobConfig(
        # Create an ad-hoc job. For more information, see https://cloud.google.com/transcoder/docs/how-to/jobs#create_jobs_ad_hoc.
        # See all options for the job config at https://cloud.google.com/transcoder/docs/reference/rest/v1/JobConfig.
        elementary_streams=[
            # This section defines the output video stream.
            transcoder_v1.types.ElementaryStream(
                key="video-stream0",
                video_stream=transcoder_v1.types.VideoStream(
                    h264=transcoder_v1.types.VideoStream.H264CodecSettings(
                        height_pixels=360,
                        width_pixels=640,
                        bitrate_bps=550000,
                        frame_rate=60,
                    ),
                ),
            ),
            # This section defines the output audio stream.
            transcoder_v1.types.ElementaryStream(
                key="audio-stream0",
                audio_stream=transcoder_v1.types.AudioStream(
                    codec="aac", bitrate_bps=64000
                ),
            ),
        ],
        # This section multiplexes the output audio and video together into a container.
        mux_streams=[
            transcoder_v1.types.MuxStream(
                key="sd",
                container="mp4",
                elementary_streams=["video-stream0", "audio-stream0"],
            ),
        ],
        # Generate two sprite sheets from the input video into the GCS bucket. For more information, see
        # https://cloud.google.com/transcoder/docs/how-to/generate-spritesheet#generate_image_periodically.
        sprite_sheets=[
            # Generate a sprite sheet with 64x32px images. An image is taken every 7 seconds from the video.
            transcoder_v1.types.SpriteSheet(
                file_prefix="small-sprite-sheet",
                sprite_width_pixels=64,
                sprite_height_pixels=32,
                interval=duration.Duration(
                    seconds=7,
                ),
            ),
            # Generate a sprite sheet with 128x72px images. An image is taken every 7 seconds from the video.
            transcoder_v1.types.SpriteSheet(
                file_prefix="large-sprite-sheet",
                sprite_width_pixels=128,
                sprite_height_pixels=72,
                interval=duration.Duration(
                    seconds=7,
                ),
            ),
        ],
    )
    response = client.create_job(parent=parent, job=job)
    print(f"Job: {response.name}")
    return response

Ruby

Avant d'essayer cet exemple, suivez les instructions de configuration de Ruby dans le guide de démarrage rapide de l'API Transcoder à l'aide de bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Transcoder Ruby.

# project_id  = "YOUR-GOOGLE-CLOUD-PROJECT"  # (e.g. "my-project")
# location    = "YOUR-JOB-LOCATION"  # (e.g. "us-central1")
# input_uri   = "YOUR-GCS-INPUT-VIDEO"  # (e.g. "gs://my-bucket/my-video-file")
# output_uri  = "YOUR-GCS-OUTPUT-FOLDER/"  # (e.g. "gs://my-bucket/my-output-folder/")

# Require the Transcoder client library.
require "google/cloud/video/transcoder"

# Create a Transcoder client.
client = Google::Cloud::Video::Transcoder.transcoder_service

# Build the resource name of the parent.
parent = client.location_path project: project_id, location: location

# Build the job config.
new_job = {
  input_uri: input_uri,
  output_uri: output_uri,
  config: {
    elementary_streams: [
      {
        key: "video-stream0",
        video_stream: {
          h264: {
            height_pixels: 360,
            width_pixels: 640,
            bitrate_bps: 550_000,
            frame_rate: 60
          }
        }
      },
      {
        key: "audio-stream0",
        audio_stream: {
          codec: "aac",
          bitrate_bps: 64_000
        }
      }
    ],
    mux_streams: [
      {
        key: "sd",
        container: "mp4",
        elementary_streams: [
          "video-stream0",
          "audio-stream0"
        ]
      }
    ],
    sprite_sheets: [
      {
        file_prefix: "small-sprite-sheet",
        sprite_width_pixels: 64,
        sprite_height_pixels: 32,
        interval: {
          seconds: 7
        }
      },
      {
        file_prefix: "large-sprite-sheet",
        sprite_width_pixels: 128,
        sprite_height_pixels: 72,
        interval: {
          seconds: 7
        }
      }
    ]
  }
}

job = client.create_job parent: parent, job: new_job

# Print the job name.
puts "Job: #{job.name}"

Utilisez cette configuration sur l'exemple de vidéo pour générer les feuilles de sprites suivantes :

Feuille de sprites de petites images
Figure 3. Feuille de sprites de petites images (une miniature toutes les 7 secondes)

Feuille de sprites de grandes images
Figure 4. Feuille de sprites de grandes images (une miniature toutes les 7 secondes)

Huit miniatures sont générées à partir de l'exemple de vidéo, qui dure 60 secondes.