オーバーレイの作成

このページでは、コード変換された動画にオーバーレイを挿入する方法について説明します。オーバーレイは出力動画の上に重ねて挿入される画像で構成され、必要に応じて指定した期間内でフェードインまたはフェードアウトできます。オーバーレイを挿入するには、JobConfig テンプレート内の overlays 配列を使用します。

サポートされている画像ファイル形式のリストをご覧ください。

Cloud Storage に画像をアップロードする

まず、次の手順で、オーバーレイ イメージを Cloud Storage バケットにアップロードします。

  1. Google Cloud コンソールで、Cloud Storage ブラウザページに移動します。
    [Cloud Storage ブラウザ] ページに移動
  2. バケットの名前をクリックしてバケットを開きます。
  3. [ファイルをアップロード] をクリックします。
  4. ローカルマシンからアップロードする画像ファイルを選択します。

オーバーレイを作成する

静的アニメーションの 2 種類のオーバーレイを作成できます。どちらのオーバーレイも静止画像を使用します。静的オーバーレイの表示と非表示を切り替えることができます。アニメーション オーバーレイは、画像のフェードインとフェードアウトをサポートしています。

1 つの出力動画に複数のオーバーレイを挿入できます。

静的オーバーレイを作成する

image オブジェクトの uri フィールドを使用して、Cloud Storage 内のオーバーレイ イメージを指定します。resolution オブジェクトで、x と y の値を 0~1.0 に設定します。値が 0 の場合は、そのサイズに対するソース画像の解像度が維持されます。値が 1.0 の場合は、出力動画のサイズに合わせて画像が伸縮されます。たとえば、x: 1y: 0.5 の値を使用すると、出力動画と同じ幅で、高さは出力動画の半分に伸縮されます。

animations 配列で、x と y 座標が 0 から 1.0 の animationStatic オブジェクトを作成します。これらの座標は、出力動画の解像度に基づきます。値 x: 0y: 0 を使用して、出力動画の左上隅にオーバーレイの左上隅を配置します。オーバーレイを出力動画のタイムラインに表示するタイミングは、startTimeOffset フィールドを使用して指定します。

静的アニメーションを削除するには、animationEnd オブジェクトを作成します。startTimeOffset フィールドを使用して、出力動画タイムラインでアニメーションを終了する(つまり、オーバーレイを非表示にする)タイミングを指定します。

この構成をジョブ テンプレートに追加するか、アドホック ジョブ構成に含めることができます。

REST

リクエストのデータを使用する前に、次のように置き換えます。

  • PROJECT_ID: IAM 設定に載っている Google Cloud プロジェクト ID。
  • LOCATION: ジョブを実行するロケーション。サポートされているリージョンのいずれかを使用します。
    3~7 つの店舗を表示
    • 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: 作成した Cloud Storage バケットの名前。
  • STORAGE_INPUT_VIDEO: コード変換する Cloud Storage バケット内の動画の名前(my-vid.mp4 など)。このフィールドでは、バケットで作成したフォルダ(input/my-vid.mp4 など)を考慮する必要があります。
  • STORAGE_INPUT_OVERLAY: Cloud Storage バケットにありオーバーレイに使用する画像の名前(my-overlay.png など)。このフィールドでは、バケットで作成したフォルダ(input/my-overlay.png など)を考慮する必要があります。
  • STORAGE_OUTPUT_FOLDER: エンコードされた動画出力を保存する Cloud Storage フォルダ名。

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

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

gcloud

  1. ジョブ フィールドを定義する request.json ファイルを作成します。gcloud コマンドを次のように置き換えます。
    • STORAGE_BUCKET_NAME: 作成した Cloud Storage バケットの名前。
    • STORAGE_INPUT_VIDEO: コード変換する Cloud Storage バケット内の動画の名前(my-vid.mp4 など)。このフィールドでは、バケットで作成したフォルダ(input/my-vid.mp4 など)を考慮する必要があります。
    • STORAGE_INPUT_OVERLAY: Cloud Storage バケットにありオーバーレイに使用する画像ファイルの名前(my-overlay.png など)。このフィールドでは、バケットに作成したフォルダ(input/my-overlay.png など)を含める必要があります。
    • LOCATION: ジョブを実行するロケーション。次に挙げるロケーションの 1 つを使用します。
      3~7 つの店舗を表示
      • 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: エンコードされた動画出力を保存する Cloud Storage フォルダ名。
    {
      "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. 次のコマンドを実行します。
    gcloud transcoder jobs create --location=LOCATION --file="request.json"
    
    次のようなレスポンスが表示されます。
    {
      "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
      "config": {
       ...
      },
      "state": "PENDING",
      "createTime": CREATE_TIME,
      "ttlAfterCompletionDays": 30
    }
    

C#

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある C# の設定手順を行ってください。 詳細については、Transcoder API C# の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Go の設定手順を行ってください。 詳細については、Transcoder API Go の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Java の設定手順を行ってください。 詳細については、Transcoder API Java の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Node.js の設定手順を行ってください。 詳細については、Transcoder API Node.js の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある PHP の設定手順を行ってください。 詳細については、Transcoder API PHP の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Python の設定手順を行ってください。 詳細については、Transcoder API Python の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Ruby の設定手順を行ってください。 詳細については、Transcoder API Ruby の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

# 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}"

出力動画に表示される静的オーバーレイは、次の特性を有しています。

  • タイムラインの始めに 10 秒間表示されます。
  • 出力動画の全幅と半分の高さの両方を継承します。
  • 出力動画の左上隅に配置されます。

この構成については、サンプル出力動画をご覧ください。この動画では、サンプル オーバーレイ画像を使用しています。

アニメーション オーバーレイの作成

image オブジェクトの uri フィールドを使用して、Cloud Storage 内のオーバーレイ イメージを指定します。resolution オブジェクトで、x と y の値を 0~1.0 に設定します。値が 0 の場合は、そのサイズに対するソース画像の解像度が維持されます。値が 1.0 の場合は、出力動画のサイズに合わせて画像が伸縮されます。たとえば、値 x: 0y: 0 を使用して、オーバーレイ画像の元の解像度を維持します。

animations 配列で、fadeTypeFADE_IN として animationFade オブジェクトを作成します。x 座標と y 座標は、0~1.0 に設定します。これらの座標は、出力動画の解像度に基づきます。値 x: 0.5y: 0.5 を使用して、出力動画の中心にオーバーレイの左上隅を配置します。startTimeOffset フィールドを使用して、出力動画タイムラインでオーバーレイを表示し始めるタイミングを指定します。オーバーレイは、endTimeOffset フィールドで設定された時間に完全に表示されます。

オーバーレイをフェードアウトするには、別の animationFade オブジェクトを作成します。今回は、fadeTypeFADE_OUT に設定します。前と同じように、位置座標、開始時刻、終了時刻を入力します。

この構成をジョブ テンプレートに追加するか、アドホック ジョブ構成に含めることができます。

REST

リクエストのデータを使用する前に、次のように置き換えます。

  • PROJECT_ID: IAM 設定に載っている Google Cloud プロジェクト ID。
  • LOCATION: ジョブを実行するロケーション。サポートされているリージョンのいずれかを使用します。
    3~7 つの店舗を表示
    • 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: 作成した Cloud Storage バケットの名前。
  • STORAGE_INPUT_VIDEO: コード変換する Cloud Storage バケット内の動画の名前(my-vid.mp4 など)。このフィールドでは、バケットで作成したフォルダ(input/my-vid.mp4 など)を考慮する必要があります。
  • STORAGE_INPUT_OVERLAY: Cloud Storage バケットにありオーバーレイに使用する画像の名前(my-overlay.png など)。このフィールドでは、バケットで作成したフォルダ(input/my-overlay.png など)を考慮する必要があります。
  • STORAGE_OUTPUT_FOLDER: エンコードされた動画出力を保存する Cloud Storage フォルダ名。

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

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

gcloud

  1. ジョブ フィールドを定義する request.json ファイルを作成します。gcloud コマンドを次のように置き換えます。
    • STORAGE_BUCKET_NAME: 作成した Cloud Storage バケットの名前。
    • STORAGE_INPUT_VIDEO: コード変換する Cloud Storage バケット内の動画の名前(my-vid.mp4 など)。このフィールドでは、バケットで作成したフォルダ(input/my-vid.mp4 など)を考慮する必要があります。
    • STORAGE_INPUT_OVERLAY: Cloud Storage バケットにありオーバーレイに使用する画像ファイルの名前(my-overlay.png など)。このフィールドでは、バケットに作成したフォルダ(input/my-overlay.png など)を含める必要があります。
    • LOCATION: ジョブを実行するロケーション。次に挙げるロケーションの 1 つを使用します。
      3~7 つの店舗を表示
      • 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: エンコードされた動画出力を保存する Cloud Storage フォルダ名。
    {
      "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. 次のコマンドを実行します。
    gcloud transcoder jobs create --location=LOCATION --file="request.json"
    
    次のようなレスポンスが表示されます。
    {
      "name": "projects/PROJECT_NUMBER/locations/LOCATION/jobs/JOB_ID",
      "config": {
       ...
      },
      "state": "PENDING",
      "createTime": CREATE_TIME,
      "ttlAfterCompletionDays": 30
    }
    

C#

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある C# の設定手順を行ってください。 詳細については、Transcoder API C# の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Go の設定手順を行ってください。 詳細については、Transcoder API Go の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Java の設定手順を行ってください。 詳細については、Transcoder API Java の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Node.js の設定手順を行ってください。 詳細については、Transcoder API Node.js の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある PHP の設定手順を行ってください。 詳細については、Transcoder API PHP の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Python の設定手順を行ってください。 詳細については、Transcoder API Python の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


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

このサンプルを試す前に、クライアント ライブラリを使用した Transcoder API クイックスタートにある Ruby の設定手順を行ってください。 詳細については、Transcoder API Ruby の API のリファレンス ドキュメントをご覧ください。

Transcoder API への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

# 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}"

結果として生成される動画では、アニメーション オーバーレイに次のような特徴があります。

  1. 出力動画の 5 秒のマークでフェードインを開始します。オーバーレイのアルファ値は 0 から始まり、1.0 で終了します。オーバーレイの左上隅が出力動画の中央に表示されます。オーバーレイは、オーバーレイ画像の元の解像度で表示されます。
  2. フェードイン後、オーバーレイは 2 秒間表示されます。
  3. 出力動画の 12 秒のマークでフェードアウトを開始します。オーバーレイのアルファ値は 1.0 で始まり、0 で終了します。
  4. 15 秒のマークでアニメーションが非表示になります。

この構成については、サンプル出力動画をご覧ください。この動画では、サンプル オーバーレイ画像を使用しています。