Membuat overlay

Halaman ini menjelaskan cara menyisipkan overlay ke video yang di-transcoding. Overlay terdiri dari gambar yang dimasukkan di atas video output, dan dapat menjadi jelas atau memudar secara opsional selama jangka waktu tertentu. Untuk menyisipkan overlay, gunakan array overlays di template JobConfig.

Lihat daftar format file gambar yang didukung.

Mengupload gambar ke Cloud Storage

Untuk memulai, lakukan langkah berikut guna mengupload gambar overlay ke bucket Cloud Storage:

  1. Di konsol Google Cloud, buka halaman Browser Cloud Storage.
    Buka halaman Browser Cloud Storage
  2. Klik nama bucket untuk membukanya.
  3. Klik Upload files.
  4. Pilih file image yang akan diupload dari komputer Anda.

Membuat overlay

Anda dapat membuat dua jenis overlay: statis atau animasi. Kedua jenis overlay menggunakan gambar statis. Anda dapat menampilkan atau menyembunyikan overlay statis. Overlay animasi mendukung animasi fade-in dan fade out pada gambar.

Anda dapat menyisipkan beberapa overlay ke dalam satu video output.

Membuat overlay statis

Pada objek image, gunakan kolom uri untuk menentukan gambar overlay di Cloud Storage. Pada objek resolution, tetapkan nilai x dan y dari 0 hingga 1,0. Nilai 0 mempertahankan resolusi gambar sumber untuk dimensi tersebut; nilai 1,0 akan merentangkan gambar agar sesuai dengan dimensi video output. Misalnya, gunakan nilai x: 1 dan y: 0.5 untuk melebarkan gambar overlay dengan lebar penuh dan setengah dari tinggi video output.

Dalam array animations, buat objek animationStatic dengan koordinat x dan y dari 0 hingga 1,0. Koordinat ini didasarkan pada resolusi video output. Gunakan nilai x: 0 dan y: 0 untuk memosisikan sudut kiri atas overlay di pojok kiri atas video output. Tentukan kapan overlay akan muncul di linimasa video output menggunakan kolom startTimeOffset.

Untuk menghapus animasi statis, buat objek animationEnd. Tentukan kapan animasi akan berakhir (yaitu, overlay akan menghilang) di linimasa video output menggunakan kolom startTimeOffset.

Anda dapat menambahkan konfigurasi ini ke template tugas atau menyertakannya dalam konfigurasi tugas ad-hoc:

REST

Sebelum menggunakan salah satu data permintaan, lakukan penggantian berikut:

  • PROJECT_ID: Project ID Google Cloud Anda yang tercantum di Setelan IAM.
  • LOCATION: Lokasi tempat tugas akan dijalankan. Gunakan salah satu wilayah yang didukung.
    Tampilkan lokasi
    • 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: Nama bucket Cloud Storage yang Anda buat.
  • STORAGE_INPUT_VIDEO: Nama video di bucket Cloud Storage yang di-transcoding, seperti my-vid.mp4. Kolom ini harus mempertimbangkan setiap folder yang Anda buat di bucket (misalnya, input/my-vid.mp4).
  • STORAGE_INPUT_OVERLAY: Nama gambar di bucket Cloud Storage yang Anda gunakan untuk overlay, seperti my-overlay.png. Kolom ini harus mempertimbangkan setiap folder yang Anda buat di bucket (misalnya, input/my-overlay.png).
  • STORAGE_OUTPUT_FOLDER: Nama folder Cloud Storage tempat Anda ingin menyimpan output video yang dienkode.

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Anda akan melihat respons JSON seperti berikut:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
  "config": {
   ...
  },
  "state": "PENDING",
  "createTime": CREATE_TIME,
  "ttlAfterCompletionDays": 30
}

gcloud

  1. Buat file request.json yang menentukan kolom lowongan. Lakukan pengganti berikut untuk perintah gcloud :
    • STORAGE_BUCKET_NAME: Nama bucket Cloud Storage yang Anda buat.
    • STORAGE_INPUT_VIDEO: Nama video di bucket Cloud Storage yang di-transcoding, seperti my-vid.mp4. Kolom ini harus mempertimbangkan setiap folder yang Anda buat di bucket (misalnya, input/my-vid.mp4).
    • STORAGE_INPUT_OVERLAY: Nama file gambar di bucket Cloud Storage yang Anda gunakan untuk overlay, seperti my-overlay.png. Kolom ini harus mempertimbangkan setiap folder yang Anda buat di bucket (misalnya, input/my-overlay.png).
    • LOCATION: Lokasi tempat tugas akan dijalankan. Gunakan lokasi dari daftar berikut.
      Tampilkan lokasi
      • 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: Nama folder Cloud Storage tempat Anda ingin menyimpan output video yang dienkode.
    {
      "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/"
        },
        "overlays": [
          {
            "image": {
              "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_INPUT_OVERLAY",
              "resolution": {
                "x": 1,
                "y": 0.5
              },
              "alpha": 1
            },
            "animations": [
              {
                "animationStatic": {
                  "xy": {
                    "x": 0,
                    "y": 0
                  },
                  "startTimeOffset": "0s"
                }
              },
              {
                "animationEnd": {
                  "startTimeOffset": "10s"
                }
              }
            ]
          }
        ]
      }
    }
    
  2. Jalankan perintah berikut:
    gcloud transcoder jobs create --location=LOCATION --file="request.json"
    
    Anda akan melihat respons seperti berikut:
    {
      "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
      "config": {
       ...
      },
      "state": "PENDING",
      "createTime": CREATE_TIME,
      "ttlAfterCompletionDays": 30
    }
    

C#

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan C# di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API C# Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


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

public class CreateJobWithStaticOverlaySample
{
    public Job CreateJobWithStaticOverlay(
        string projectId, string location, string inputUri, string overlayImageUri, 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
        };

        // Create the overlay image. Image resolution is based on output video
        // resolution. To respect the original image aspect ratio, set either x
        // or y to 0.0. This example stretches the overlay image the full width
        // and half of the height of the output video.
        Overlay.Types.Image overlayImage = new Overlay.Types.Image
        {
            Uri = overlayImageUri,
            Alpha = 1,
            Resolution = new Overlay.Types.NormalizedCoordinate
            {
                X = 1,
                Y = 0.5
            }
        };

        // Create the starting animation (when the overlay appears). Use the values x: 0 and y: 0 to
        // position the top-left corner of the overlay in the top-left corner of the output video.
        Overlay.Types.Animation animationStart = new Overlay.Types.Animation
        {
            AnimationStatic = new Overlay.Types.AnimationStatic
            {
                Xy = new Overlay.Types.NormalizedCoordinate
                {
                    X = 0,
                    Y = 0
                },
                StartTimeOffset = Duration.FromTimeSpan(TimeSpan.FromSeconds(0))
            }
        };

        // Create the ending animation (when the overlay disappears). In this example, the overlay
        // disappears at the 10-second mark in the output video.
        Overlay.Types.Animation animationEnd = new Overlay.Types.Animation
        {
            AnimationEnd = new Overlay.Types.AnimationEnd
            {
                StartTimeOffset = Duration.FromTimeSpan(TimeSpan.FromSeconds(10))
            }
        };

        // Create the overlay and add the image and animations to it.
        Overlay overlay = new Overlay
        {
            Image = overlayImage,
            Animations = { animationStart, animationEnd }
        };

        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 },
            Overlays = { overlay }
        };

        // 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

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Go Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

import (
	"context"
	"fmt"
	"io"

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

	transcoder "cloud.google.com/go/video/transcoder/apiv1"
	"cloud.google.com/go/video/transcoder/apiv1/transcoderpb"
)

// createJobWithStaticOverlay creates a job based on a given configuration that
// includes a static overlay. See
// https://cloud.google.com/transcoder/docs/how-to/create-overlays#create-static-overlay
// for more information.
func createJobWithStaticOverlay(w io.Writer, projectID string, location string, inputURI string, overlayImageURI string, outputURI string) error {
	// projectID := "my-project-id"
	// location := "us-central1"
	// inputURI := "gs://my-bucket/my-video-file"
	// overlayImageURI := "gs://my-bucket/my-overlay-image-file"
	// outputURI := "gs://my-bucket/my-output-folder/"
	ctx := context.Background()
	client, err := transcoder.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient: %w", 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"},
						},
					},
					Overlays: []*transcoderpb.Overlay{
						{
							Image: &transcoderpb.Overlay_Image{
								Uri: overlayImageURI,
								Resolution: &transcoderpb.Overlay_NormalizedCoordinate{
									X: 1,
									Y: 0.5,
								},
								Alpha: 1,
							},
							Animations: []*transcoderpb.Overlay_Animation{
								{
									AnimationType: &transcoderpb.Overlay_Animation_AnimationStatic{
										AnimationStatic: &transcoderpb.Overlay_AnimationStatic{
											Xy: &transcoderpb.Overlay_NormalizedCoordinate{
												X: 0,
												Y: 0,
											},
											StartTimeOffset: &duration.Duration{
												Seconds: 0,
											},
										},
									},
								},

								{
									AnimationType: &transcoderpb.Overlay_Animation_AnimationEnd{
										AnimationEnd: &transcoderpb.Overlay_AnimationEnd{
											StartTimeOffset: &duration.Duration{
												Seconds: 10,
											},
										},
									},
								},
							},
						},
					},
				},
			},
		},
	}
	// Creates the job. Jobs take a variable amount of time to run.
	// You can query for the job state; see getJob() in get_job.go.
	response, err := client.CreateJob(ctx, req)
	if err != nil {
		return fmt.Errorf("createJobWithStaticOverlay: %w", err)
	}

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

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Java Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


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.Overlay;
import com.google.cloud.video.transcoder.v1.Overlay.AnimationEnd;
import com.google.cloud.video.transcoder.v1.Overlay.AnimationStatic;
import com.google.cloud.video.transcoder.v1.Overlay.NormalizedCoordinate;
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 CreateJobWithStaticOverlay {

  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 overlayImageUri = "gs://my-bucket/my-overlay-image.jpg";
    String outputUri = "gs://my-bucket/my-output-folder/";

    createJobWithStaticOverlay(projectId, location, inputUri, overlayImageUri, outputUri);
  }

  // Creates a job from an ad-hoc configuration and adds a static overlay to it.
  public static void createJobWithStaticOverlay(
      String projectId, String location, String inputUri, String overlayImageUri, 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();

      // Create the overlay image. Image resolution is based on output video resolution.
      // To respect the original image aspect ratio, set either x or y to 0.0. This example
      // stretches the overlay image the full width and half of the height of the
      // output video.
      Overlay.Image overlayImage =
          Overlay.Image.newBuilder()
              .setUri(overlayImageUri)
              .setResolution(NormalizedCoordinate.newBuilder().setX(1).setY(0.5).build())
              .setAlpha(1)
              .build();

      // Create the starting animation (when the overlay appears). Use the values x: 0 and y: 0 to
      // position the top-left corner of the overlay in the top-left corner of the output video.
      Overlay.Animation animationStart =
          Overlay.Animation.newBuilder()
              .setAnimationStatic(
                  AnimationStatic.newBuilder()
                      .setXy(NormalizedCoordinate.newBuilder().setX(0).setY(0).build())
                      .setStartTimeOffset(Duration.newBuilder().setSeconds(0).build())
                      .build())
              .build();

      // Create the ending animation (when the overlay disappears). In this example, the overlay
      // disappears at the 10-second mark in the output video.
      Overlay.Animation animationEnd =
          Overlay.Animation.newBuilder()
              .setAnimationEnd(
                  AnimationEnd.newBuilder()
                      .setStartTimeOffset(Duration.newBuilder().setSeconds(10).build())
                      .build())
              .build();

      // Create the overlay and add the image and animations to it.
      Overlay overlay =
          Overlay.newBuilder()
              .setImage(overlayImage)
              .addAnimations(animationStart)
              .addAnimations(animationEnd)
              .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())
              .addOverlays(overlay) // Add the overlay to the job config
              .build();

      CreateJobRequest 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

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Node.js di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Node.js Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// projectId = 'my-project-id';
// location = 'us-central1';
// inputUri = 'gs://my-bucket/my-video-file';
// overlayImageUri = 'gs://my-bucket/my-overlay-image-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 createJobFromStaticOverlay() {
  // 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'],
          },
        ],
        overlays: [
          {
            image: {
              uri: overlayImageUri,
              resolution: {
                x: 1,
                y: 0.5,
              },
              alpha: 1.0,
            },
            animations: [
              {
                animationStatic: {
                  xy: {
                    x: 0,
                    y: 0,
                  },
                  startTimeOffset: {
                    seconds: 0,
                  },
                },
              },
              {
                animationEnd: {
                  startTimeOffset: {
                    seconds: 10,
                  },
                },
              },
            ],
          },
        ],
      },
    },
  };

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

createJobFromStaticOverlay();

PHP

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan PHP di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API PHP Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

use Google\Cloud\Video\Transcoder\V1\AudioStream;
use Google\Cloud\Video\Transcoder\V1\Client\TranscoderServiceClient;
use Google\Cloud\Video\Transcoder\V1\CreateJobRequest;
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\Overlay;
use Google\Cloud\Video\Transcoder\V1\VideoStream;
use Google\Protobuf\Duration;

/**
 * Creates a job based on a supplied job config that includes a static image overlay.
 *
 * @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 $overlayImageUri Uri of the image for the overlay in the Cloud Storage bucket.
 * @param string $outputUri Uri of the video output folder in the Cloud Storage bucket.
 */
function create_job_with_static_overlay($projectId, $location, $inputUri, $overlayImageUri, $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'])
        ])->setOverlays([
            (new Overlay())
                ->setImage(
                    (new Overlay\Image())
                        ->setUri($overlayImageUri)
                        ->setResolution(
                            (new Overlay\NormalizedCoordinate())
                                ->setX(1)
                                ->setY(0.5)
                        )
                        ->setAlpha(1)
                )
                ->setAnimations([
                    (new Overlay\Animation())
                        ->setAnimationStatic(
                            (new Overlay\AnimationStatic())
                                ->setXy(
                                    (new Overlay\NormalizedCoordinate())
                                        ->setY(0)
                                        ->setX(0)
                                )
                                ->setStartTimeOffset(
                                    (new Duration())
                                        ->setSeconds(0)
                                )
                        ),
                    (new Overlay\Animation())
                        ->setAnimationEnd(
                            (new Overlay\AnimationEnd())
                                ->setStartTimeOffset(
                                    (new Duration())
                                        ->setSeconds(10)
                                )
                        )
                ])
        ]);

    $job = (new Job())
        ->setInputUri($inputUri)
        ->setOutputUri($outputUri)
        ->setConfig($jobConfig);
    $request = (new CreateJobRequest())
        ->setParent($formattedParent)
        ->setJob($job);

    $response = $transcoderServiceClient->createJob($request);

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

Python

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Python Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


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_static_overlay(
    project_id: str,
    location: str,
    input_uri: str,
    overlay_image_uri: str,
    output_uri: str,
) -> transcoder_v1.types.resources.Job:
    """Creates a job based on an ad-hoc job configuration that includes a static image overlay.

    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.
        overlay_image_uri: Uri of the image for the overlay in the Cloud Storage bucket.
        output_uri: Uri of the video output folder in the Cloud Storage bucket.

    Returns:
        The job resource.
    """

    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(
        elementary_streams=[
            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,
                    ),
                ),
            ),
            transcoder_v1.types.ElementaryStream(
                key="audio-stream0",
                audio_stream=transcoder_v1.types.AudioStream(
                    codec="aac", bitrate_bps=64000
                ),
            ),
        ],
        mux_streams=[
            transcoder_v1.types.MuxStream(
                key="sd",
                container="mp4",
                elementary_streams=["video-stream0", "audio-stream0"],
            ),
        ],
        overlays=[
            transcoder_v1.types.Overlay(
                image=transcoder_v1.types.Overlay.Image(
                    uri=overlay_image_uri,
                    resolution=transcoder_v1.types.Overlay.NormalizedCoordinate(
                        x=1,
                        y=0.5,
                    ),
                    alpha=1,
                ),
                animations=[
                    transcoder_v1.types.Overlay.Animation(
                        animation_static=transcoder_v1.types.Overlay.AnimationStatic(
                            xy=transcoder_v1.types.Overlay.NormalizedCoordinate(
                                x=0,
                                y=0,
                            ),
                            start_time_offset=duration.Duration(
                                seconds=0,
                            ),
                        ),
                    ),
                    transcoder_v1.types.Overlay.Animation(
                        animation_end=transcoder_v1.types.Overlay.AnimationEnd(
                            start_time_offset=duration.Duration(
                                seconds=10,
                            ),
                        ),
                    ),
                ],
            ),
        ],
    )
    response = client.create_job(parent=parent, job=job)
    print(f"Job: {response.name}")
    return response

Ruby

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Ruby di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Ruby Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

# 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")
# overlay_image_uri   = "YOUR-GCS-OVERLAY-IMAGE"  # (e.g. "gs://my-bucket/overlay.jpg")
# 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"
        ]
      }
    ],
    overlays: [
      {
        image: {
          uri: overlay_image_uri,
          resolution: {
            x: 1,
            y: 0.5
          },
          alpha: 1
        },
        animations: [
          {
            animation_static: {
              xy: {
                x: 0,
                y: 0
              },
              start_time_offset: {
                seconds: 0
              }
            }
          },
          {
            animation_end: {
              start_time_offset: {
                seconds: 10
              }
            }
          }
        ]
      }
    ]
  }
}

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

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

Dalam video output, overlay statis memiliki karakteristik berikut:

  • Tombol ini muncul di awal linimasa dan terlihat selama 10 detik.
  • Gambar ini merentangkan lebar penuh dan setengah dari tinggi video output.
  • Ikon ini diposisikan di pojok kiri atas video output.

Lihat video output contoh untuk konfigurasi ini. Video ini menggunakan gambar overlay contoh.

Membuat overlay animasi

Pada objek image, gunakan kolom uri untuk menentukan gambar overlay di Cloud Storage. Pada objek resolution, tetapkan nilai x dan y dari 0 hingga 1,0. Nilai 0 mempertahankan resolusi gambar sumber untuk dimensi tersebut; nilai 1,0 akan merentangkan gambar agar sesuai dengan dimensi video output. Misalnya, gunakan nilai x: 0 dan y: 0 untuk mempertahankan resolusi asli gambar overlay.

Dalam array animations, buat objek animationFade dengan fadeType dari FADE_IN. Menetapkan koordinat x dan y dari 0 hingga 1,0. Koordinat ini didasarkan pada resolusi video output. Gunakan nilai x: 0.5 dan y: 0.5 untuk memosisikan sudut kiri atas overlay di tengah video output. Tentukan kapan overlay akan mulai muncul di linimasa video output menggunakan kolom startTimeOffset. Overlay harus terlihat sepenuhnya pada waktu yang disetel di kolom endTimeOffset.

Untuk memudarkan overlay, buat objek animationFade lain. Kali ini, tetapkan fadeType ke FADE_OUT. Masukkan koordinat posisi serta waktu mulai dan berakhir seperti sebelumnya.

Anda dapat menambahkan konfigurasi ini ke template tugas atau menyertakannya dalam konfigurasi tugas ad-hoc:

REST

Sebelum menggunakan salah satu data permintaan, lakukan penggantian berikut:

  • PROJECT_ID: Project ID Google Cloud Anda yang tercantum di Setelan IAM.
  • LOCATION: Lokasi tempat tugas akan dijalankan. Gunakan salah satu wilayah yang didukung.
    Tampilkan lokasi
    • 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: Nama bucket Cloud Storage yang Anda buat.
  • STORAGE_INPUT_VIDEO: Nama video di bucket Cloud Storage yang di-transcoding, seperti my-vid.mp4. Kolom ini harus mempertimbangkan setiap folder yang Anda buat di bucket (misalnya, input/my-vid.mp4).
  • STORAGE_INPUT_OVERLAY: Nama gambar di bucket Cloud Storage yang Anda gunakan untuk overlay, seperti my-overlay.png. Kolom ini harus mempertimbangkan setiap folder yang Anda buat di bucket (misalnya, input/my-overlay.png).
  • STORAGE_OUTPUT_FOLDER: Nama folder Cloud Storage tempat Anda ingin menyimpan output video yang dienkode.

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Anda akan melihat respons JSON seperti berikut:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
  "config": {
   ...
  },
  "state": "PENDING",
  "createTime": CREATE_TIME,
  "ttlAfterCompletionDays": 30
}

gcloud

  1. Buat file request.json yang menentukan kolom lowongan. Lakukan pengganti berikut untuk perintah gcloud :
    • STORAGE_BUCKET_NAME: Nama bucket Cloud Storage yang Anda buat.
    • STORAGE_INPUT_VIDEO: Nama video di bucket Cloud Storage yang di-transcoding, seperti my-vid.mp4. Kolom ini harus mempertimbangkan setiap folder yang Anda buat di bucket (misalnya, input/my-vid.mp4).
    • STORAGE_INPUT_OVERLAY: Nama file gambar di bucket Cloud Storage yang Anda gunakan untuk overlay, seperti my-overlay.png. Kolom ini harus mempertimbangkan setiap folder yang Anda buat di bucket (misalnya, input/my-overlay.png).
    • LOCATION: Lokasi tempat tugas akan dijalankan. Gunakan lokasi dari daftar berikut.
      Tampilkan lokasi
      • 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: Nama folder Cloud Storage tempat Anda ingin menyimpan output video yang dienkode.
    {
      "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/"
        },
        "overlays": [
          {
            "image": {
              "uri": "gs://STORAGE_BUCKET_NAME/STORAGE_INPUT_OVERLAY",
              "resolution": {
                "x": 0,
                "y": 0
              },
              "alpha": 1
            },
            "animations": [
              {
                "animationFade": {
                  "fadeType": "FADE_IN",
                  "xy": {
                    "x": 0.5,
                    "y": 0.5
                  },
                  "startTimeOffset": "5s",
                  "endTimeOffset": "10s"
                }
              },
              {
                "animationFade": {
                  "fadeType": "FADE_OUT",
                  "xy": {
                    "x": 0.5,
                    "y": 0.5
                  },
                  "startTimeOffset": "12s",
                  "endTimeOffset": "15s"
                }
              }
            ]
          }
        ]
      }
    }
    
  2. Jalankan perintah berikut:
    gcloud transcoder jobs create --location=LOCATION --file="request.json"
    
    Anda akan melihat respons seperti berikut:
    {
      "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
      "config": {
       ...
      },
      "state": "PENDING",
      "createTime": CREATE_TIME,
      "ttlAfterCompletionDays": 30
    }
    

C#

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan C# di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API C# Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


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

public class CreateJobWithAnimatedOverlaySample
{
    public Job CreateJobWithAnimatedOverlay(
        string projectId, string location, string inputUri, string overlayImageUri, 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
        };

        // Create the overlay image. Image resolution is based on output video resolution.
        // This example uses the values x: 0 and y: 0 to maintain the original resolution
        // of the overlay image.
        Overlay.Types.Image overlayImage = new Overlay.Types.Image
        {
            Uri = overlayImageUri,
            Alpha = 1,
            Resolution = new Overlay.Types.NormalizedCoordinate
            {
                X = 0,
                Y = 0
            }
        };

        // Create the starting animation (when the overlay starts to fade in). Use the values x: 0.5
        // and y: 0.5 to position the top-left corner of the overlay in the center of the output
        // video.
        Overlay.Types.Animation animationFadeIn = new Overlay.Types.Animation
        {
            AnimationFade = new Overlay.Types.AnimationFade
            {
                FadeType = Overlay.Types.FadeType.FadeIn,
                Xy = new Overlay.Types.NormalizedCoordinate
                {
                    X = 0.5,
                    Y = 0.5
                },
                StartTimeOffset = Duration.FromTimeSpan(TimeSpan.FromSeconds(5)),
                EndTimeOffset = Duration.FromTimeSpan(TimeSpan.FromSeconds(10))
            }
        };

        // Create the ending animation (when the overlay starts to fade out). The overlay will start
        // to fade out at the 12-second mark in the output video.
        Overlay.Types.Animation animationFadeOut = new Overlay.Types.Animation
        {
            AnimationFade = new Overlay.Types.AnimationFade
            {
                FadeType = Overlay.Types.FadeType.FadeOut,
                Xy = new Overlay.Types.NormalizedCoordinate
                {
                    X = 0.5,
                    Y = 0.5
                },
                StartTimeOffset = Duration.FromTimeSpan(TimeSpan.FromSeconds(12)),
                EndTimeOffset = Duration.FromTimeSpan(TimeSpan.FromSeconds(15))
            }
        };

        // Create the overlay and add the image and animations to it.
        Overlay overlay = new Overlay
        {
            Image = overlayImage,
            Animations = { animationFadeIn, animationFadeOut }
        };

        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 },
            Overlays = { overlay }
        };

        // 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

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Go Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

import (
	"context"
	"fmt"
	"io"

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

	transcoder "cloud.google.com/go/video/transcoder/apiv1"
	"cloud.google.com/go/video/transcoder/apiv1/transcoderpb"
)

// createJobWithAnimatedOverlay creates a job based on a given configuration that
// includes an animated overlay. See
// https://cloud.google.com/transcoder/docs/how-to/create-overlays#create-animated-overlay
// for more information.
func createJobWithAnimatedOverlay(w io.Writer, projectID string, location string, inputURI string, overlayImageURI string, outputURI string) error {
	// projectID := "my-project-id"
	// location := "us-central1"
	// inputURI := "gs://my-bucket/my-video-file"
	// overlayImageURI := "gs://my-bucket/my-overlay-image-file"
	// outputURI := "gs://my-bucket/my-output-folder/"
	ctx := context.Background()
	client, err := transcoder.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient: %w", 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"},
						},
					},
					Overlays: []*transcoderpb.Overlay{
						{
							Image: &transcoderpb.Overlay_Image{
								Uri: overlayImageURI,
								Resolution: &transcoderpb.Overlay_NormalizedCoordinate{
									X: 0,
									Y: 0,
								},
								Alpha: 1,
							},
							Animations: []*transcoderpb.Overlay_Animation{
								{
									AnimationType: &transcoderpb.Overlay_Animation_AnimationFade{
										AnimationFade: &transcoderpb.Overlay_AnimationFade{
											FadeType: transcoderpb.Overlay_FADE_IN,
											Xy: &transcoderpb.Overlay_NormalizedCoordinate{
												X: 0.5,
												Y: 0.5,
											},
											StartTimeOffset: &duration.Duration{
												Seconds: 5,
											},
											EndTimeOffset: &duration.Duration{
												Seconds: 10,
											},
										},
									},
								},

								{
									AnimationType: &transcoderpb.Overlay_Animation_AnimationFade{
										AnimationFade: &transcoderpb.Overlay_AnimationFade{
											FadeType: transcoderpb.Overlay_FADE_OUT,
											Xy: &transcoderpb.Overlay_NormalizedCoordinate{
												X: 0.5,
												Y: 0.5,
											},
											StartTimeOffset: &duration.Duration{
												Seconds: 12,
											},
											EndTimeOffset: &duration.Duration{
												Seconds: 15,
											},
										},
									},
								},
							},
						},
					},
				},
			},
		},
	}
	// Creates the job. Jobs take a variable amount of time to run.
	// You can query for the job state; see getJob() in get_job.go.
	response, err := client.CreateJob(ctx, req)
	if err != nil {
		return fmt.Errorf("createJobWithAnimatedOverlay: %w", err)
	}

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

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Java Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


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.Overlay;
import com.google.cloud.video.transcoder.v1.Overlay.Animation;
import com.google.cloud.video.transcoder.v1.Overlay.AnimationFade;
import com.google.cloud.video.transcoder.v1.Overlay.FadeType;
import com.google.cloud.video.transcoder.v1.Overlay.NormalizedCoordinate;
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 CreateJobWithAnimatedOverlay {

  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 overlayImageUri = "gs://my-bucket/my-overlay-image.jpg";
    String outputUri = "gs://my-bucket/my-output-folder/";

    createJobWithAnimatedOverlay(projectId, location, inputUri, overlayImageUri, outputUri);
  }

  // Creates a job from an ad-hoc configuration and adds an animated overlay to it.
  public static void createJobWithAnimatedOverlay(
      String projectId, String location, String inputUri, String overlayImageUri, 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();

      // Create the overlay image. Image resolution is based on output video resolution.
      // This example uses the values x: 0 and y: 0 to maintain the original resolution
      // of the overlay image.
      Overlay.Image overlayImage =
          Overlay.Image.newBuilder()
              .setUri(overlayImageUri)
              .setResolution(NormalizedCoordinate.newBuilder().setX(0).setY(0).build())
              .setAlpha(1)
              .build();

      // Create the starting animation (when the overlay starts to fade in). Use the values x: 0.5
      // and y: 0.5 to position the top-left corner of the overlay in the top-left corner of the
      // output video.
      Overlay.Animation animationFadeIn =
          Animation.newBuilder()
              .setAnimationFade(
                  AnimationFade.newBuilder()
                      .setFadeType(FadeType.FADE_IN)
                      .setXy(NormalizedCoordinate.newBuilder().setX(0.5).setY(0.5).build())
                      .setStartTimeOffset(Duration.newBuilder().setSeconds(5).build())
                      .setEndTimeOffset(Duration.newBuilder().setSeconds(10).build())
                      .build())
              .build();

      // Create the ending animation (when the overlay starts to fade out). The overlay will start
      // to fade out at the 12-second mark in the output video.
      Overlay.Animation animationFadeOut =
          Animation.newBuilder()
              .setAnimationFade(
                  AnimationFade.newBuilder()
                      .setFadeType(FadeType.FADE_OUT)
                      .setXy(NormalizedCoordinate.newBuilder().setX(0.5).setY(0.5).build())
                      .setStartTimeOffset(Duration.newBuilder().setSeconds(12).build())
                      .setEndTimeOffset(Duration.newBuilder().setSeconds(15).build())
                      .build())
              .build();

      // Create the overlay and add the image and animations to it.
      Overlay overlay =
          Overlay.newBuilder()
              .setImage(overlayImage)
              .addAnimations(animationFadeIn)
              .addAnimations(animationFadeOut)
              .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())
              .addOverlays(overlay) // Add the overlay to the job config
              .build();

      CreateJobRequest 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

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Node.js di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Node.js Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// projectId = 'my-project-id';
// location = 'us-central1';
// inputUri = 'gs://my-bucket/my-video-file';
// overlayImageUri = 'gs://my-bucket/my-overlay-image-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 createJobFromAnimatedOverlay() {
  // 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'],
          },
        ],
        overlays: [
          {
            image: {
              uri: overlayImageUri,
              resolution: {
                x: 0,
                y: 0,
              },
              alpha: 1.0,
            },
            animations: [
              {
                animationFade: {
                  fadeType: 'FADE_IN',
                  xy: {
                    x: 0.5,
                    y: 0.5,
                  },
                  startTimeOffset: {
                    seconds: 5,
                  },
                  endTimeOffset: {
                    seconds: 10,
                  },
                },
              },
              {
                animationFade: {
                  fadeType: 'FADE_OUT',
                  xy: {
                    x: 0.5,
                    y: 0.5,
                  },
                  startTimeOffset: {
                    seconds: 12,
                  },
                  endTimeOffset: {
                    seconds: 15,
                  },
                },
              },
            ],
          },
        ],
      },
    },
  };

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

createJobFromAnimatedOverlay();

PHP

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan PHP di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API PHP Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

use Google\Cloud\Video\Transcoder\V1\AudioStream;
use Google\Cloud\Video\Transcoder\V1\Client\TranscoderServiceClient;
use Google\Cloud\Video\Transcoder\V1\CreateJobRequest;
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\Overlay;
use Google\Cloud\Video\Transcoder\V1\VideoStream;
use Google\Protobuf\Duration;

/**
 * Creates a job based on a supplied job config that includes an animated overlay.
 *
 * @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 $overlayImageUri Uri of the image for the overlay in the Cloud Storage bucket.
 * @param string $outputUri Uri of the video output folder in the Cloud Storage bucket.
 */
function create_job_with_animated_overlay($projectId, $location, $inputUri, $overlayImageUri, $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'])
        ])->setOverlays([
            (new Overlay())->setImage(
                (new Overlay\Image())
                    ->setUri($overlayImageUri)
                    ->setResolution(
                        (new Overlay\NormalizedCoordinate())
                            ->setX(0)
                            ->setY(0)
                    )
                    ->setAlpha(1)
            )->setAnimations([
                (new Overlay\Animation())->setAnimationFade(
                    (new Overlay\AnimationFade())
                        ->setFadeType(Overlay\FadeType::FADE_IN)
                        ->setXy(
                            (new Overlay\NormalizedCoordinate())
                                ->setY(0.5)
                                ->setX(0.5)
                        )
                        ->setStartTimeOffset(new Duration(['seconds' => 5]))
                        ->setEndTimeOffset(new Duration(['seconds' => 10]))
                ),
                (new Overlay\Animation())->setAnimationFade(
                    (new Overlay\AnimationFade())
                        ->setFadeType(Overlay\FadeType::FADE_OUT)
                        ->setXy(
                            (new Overlay\NormalizedCoordinate())
                                ->setY(0.5)
                                ->setX(0.5)
                        )
                        ->setStartTimeOffset(new Duration(['seconds' => 12]))
                        ->setEndTimeOffset(new Duration(['seconds' => 15]))
                )
            ])
        ]);

    $job = (new Job())
        ->setInputUri($inputUri)
        ->setOutputUri($outputUri)
        ->setConfig($jobConfig);
    $request = (new CreateJobRequest())
        ->setParent($formattedParent)
        ->setJob($job);

    $response = $transcoderServiceClient->createJob($request);

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

Python

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Python Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


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_animated_overlay(
    project_id: str,
    location: str,
    input_uri: str,
    overlay_image_uri: str,
    output_uri: str,
) -> transcoder_v1.types.resources.Job:
    """Creates a job based on an ad-hoc job configuration that includes an animated image overlay.

    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.
        overlay_image_uri: Uri of the image for the overlay in the Cloud Storage bucket.
        output_uri: Uri of the video output folder in the Cloud Storage bucket.

    Returns:
        The job resource.
    """

    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(
        elementary_streams=[
            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,
                    ),
                ),
            ),
            transcoder_v1.types.ElementaryStream(
                key="audio-stream0",
                audio_stream=transcoder_v1.types.AudioStream(
                    codec="aac", bitrate_bps=64000
                ),
            ),
        ],
        mux_streams=[
            transcoder_v1.types.MuxStream(
                key="sd",
                container="mp4",
                elementary_streams=["video-stream0", "audio-stream0"],
            ),
        ],
        overlays=[
            transcoder_v1.types.Overlay(
                image=transcoder_v1.types.Overlay.Image(
                    uri=overlay_image_uri,
                    resolution=transcoder_v1.types.Overlay.NormalizedCoordinate(
                        x=0,
                        y=0,
                    ),
                    alpha=1,
                ),
                animations=[
                    transcoder_v1.types.Overlay.Animation(
                        animation_fade=transcoder_v1.types.Overlay.AnimationFade(
                            fade_type=transcoder_v1.types.Overlay.FadeType.FADE_IN,
                            xy=transcoder_v1.types.Overlay.NormalizedCoordinate(
                                x=0.5,
                                y=0.5,
                            ),
                            start_time_offset=duration.Duration(
                                seconds=5,
                            ),
                            end_time_offset=duration.Duration(
                                seconds=10,
                            ),
                        ),
                    ),
                    transcoder_v1.types.Overlay.Animation(
                        animation_fade=transcoder_v1.types.Overlay.AnimationFade(
                            fade_type=transcoder_v1.types.Overlay.FadeType.FADE_OUT,
                            xy=transcoder_v1.types.Overlay.NormalizedCoordinate(
                                x=0.5,
                                y=0.5,
                            ),
                            start_time_offset=duration.Duration(
                                seconds=12,
                            ),
                            end_time_offset=duration.Duration(
                                seconds=15,
                            ),
                        ),
                    ),
                ],
            ),
        ],
    )
    response = client.create_job(parent=parent, job=job)
    print(f"Job: {response.name}")
    return response

Ruby

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Ruby di Panduan memulai Transcoder API menggunakan library klien. Untuk informasi selengkapnya, lihat Dokumentasi referensi API Ruby Transcoder API.

Untuk melakukan autentikasi ke Transcoder API, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

# 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")
# overlay_image_uri   = "YOUR-GCS-OVERLAY-IMAGE"  # (e.g. "gs://my-bucket/overlay.jpg")
# 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"
        ]
      }
    ],
    overlays: [
      {
        image: {
          uri: overlay_image_uri,
          resolution: {
            x: 0,
            y: 0
          },
          alpha: 1
        },
        animations: [
          {
            animation_fade: {
              fade_type: Google::Cloud::Video::Transcoder::V1::Overlay::FadeType::FADE_IN,
              xy: {
                x: 0.5,
                y: 0.5
              },
              start_time_offset: {
                seconds: 5
              },
              end_time_offset: {
                seconds: 10
              }
            }
          },
          {
            animation_fade: {
              fade_type: Google::Cloud::Video::Transcoder::V1::Overlay::FadeType::FADE_OUT,
              xy: {
                x: 0.5,
                y: 0.5
              },
              start_time_offset: {
                seconds: 12
              },
              end_time_offset: {
                seconds: 15
              }
            }
          }
        ]
      }
    ]
  }
}

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

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

Pada video yang dihasilkan, overlay animasi memiliki karakteristik berikut:

  1. Ikon mulai memudar pada tanda 5 detik dalam video output. Nilai alfa untuk overlay dimulai dari 0 dan berakhir di 1,0. Sudut kiri atas overlay muncul di tengah video output. Overlay akan muncul dengan resolusi asli gambar overlay.
  2. Setelah menghilang, overlay akan ditampilkan selama 2 detik.
  3. Tombol mulai memudar pada tanda 12 detik dalam video output. Nilai alfa untuk overlay dimulai dari 1,0 dan berakhir di 0.
  4. Animasi akan menghilang selama tanda 15 detik.

Lihat video output contoh untuk konfigurasi ini. Video ini menggunakan gambar overlay contoh.