動画クリエイティブの取り込み API

Video Creative Ingest API を使用すると、サードパーティの広告システムは YouTube と DAI プロダクトにクリエイティブを事前に取り込むことができます。このプロセスにより、Google 以外の広告サーバーから広告が決定されたときに、返されたクリエイティブが YouTube または DAI 動画ストリームに配信される準備が整います。

サードパーティ広告システムからクリエイティブを事前に取り込むプロセスは、主に 2 つの部分で構成されています。最初の部分では、サードパーティの広告システムが Google にクリエイティブを提供し、Google の動画インフラストラクチャにクリエイティブが取り込まれる際の進捗状況をモニタリングできます。クリエイティブが正常に取り込まれると、識別子は広告システムに返されます。

2 つ目のステップでは、広告システムがこれらの ID を取得し、ユニバーサル広告 ID(VAST 4.0 以降)または「UniversalAdId」タイプのクリエイティブ拡張機能を使用して、送信されたクリエイティブを参照する VAST ドキュメントに含めます。DAI または YouTube の決定時に広告システムの VAST ドキュメントが検出されると、クリエイティブ システムは VAST からこれらの ID を抽出し、再生のために挿入する適切なクリエイティブを Google 動画インフラストラクチャから取得します。

メディアの要件

API に送信されるクリエイティブ メディアは、システムで正常に処理されるように、次の条件を満たしている必要があります。

メディアの種類

Google で使用できるメディアの種類は次のとおりです。その他のメディア タイプは、送信時に拒否される可能性があります。

  • video/mp4
  • video/webm
  • video/quicktime
  • video/avi
  • video/mpeg
  • video/x-flv
  • flv-application/octet-stream
  • application/octet-stream
  • video/3gpp
  • video/ogg
  • audio/mp4
  • audio/mpeg

メディアのプロパティ

送信するメディアは、次の条件を満たしている必要があります。

  • メディアには、少なくとも 1 つの音声トラックまたは動画トラックが必要です。
  • メディアの長さは適度である必要があります。数分を超えるものはありません。
  • メディアの音声または動画の長さは 1 秒以上である必要があります。
  • メディアに音声が含まれている場合は、モノラル、ステレオ、サラウンド音声などの標準の音声チャンネル構成が必要です。

クリエイティブを送信して取り込む

取り込みプロセスのフロー図

  1. サードパーティの広告システムが、クリエイティブに関連付けられたメディア ファイルのリストを添えて、Video Creative Ingest API に HTTP リクエストを送信します。
  2. Video Creative Ingest API は、指定されたリストから品質が最も高いクリエイティブを選択し、CDN からダウンロードします。
  3. Video Creative Ingest API は、ダウンロードしたクリエイティブを Google 動画インフラストラクチャに取り込み、YouTube と DAI の両方のプロダクトで使用できるようにします。
  4. Pub/Sub 通知が、クリエイティブのステータスとともにサードパーティの広告システムに送り返されます。通知には、YouTube と DAI の両方で正常に読み込まれたかどうかが表示されます。クリエイティブの読み込みが失敗した場合は、通知に失敗の原因が表示されます。

クリエイティブを送信する際は、次のガイドラインに従ってください。

認証

Google Cloud サービス アカウントを使用して API にアクセスする必要があります。統合時に、適切な認可を得るためにアカウント情報を Google に提供する必要があります。

アカウント情報が creativeingestion@google.com から Google に提供されると、通知の公開に使用される API エンドポイントと Cloud Pub/Sub トピックへのアクセス権が付与されます。

認証プロセスを開始する手順は次のとおりです。

  1. Google Cloud アカウントを作成します。
  2. DAI API にリクエストを送信するアカウントを使用してプロジェクトを設定します。
  3. プロジェクト内で、左側の [IAM と管理] タブに移動し、新しいサービス アカウントを作成します。リクエストはサービス アカウントを使用して送信されます。
  4. PubSub API を有効にして、API がすべての取り込み成功と失敗の通知をパブリッシュする一意のパートナー通知トピックを 1 つ作成します。

    ドメイン制限の組織のポリシーが設定されている場合は、Google のお客様 ID を許可されたお客様リストに追加する必要があります。ID については creativeingestion@google.com にお問い合わせください。これで、許可されたお客様リスト(API のお客様 ID)のプリンシパル(Google のロボット アカウント)を IAM ポリシー(PubSub パブリッシャー)に追加できます。

    video-creative-library-discovery@system.gserviceaccount.com を Pub/Sub パブリッシャーとしてトピックに追加します。

  5. サービス アカウントのメールアドレスと Pub/Sub トピックを creativeingestion@google.com に指定して、この情報を API に登録します。

  6. アカウントがサービス コンシューマとして追加されたら、DAI API を有効にします。

  7. API にアクセスするための認証情報を設定するには:

    • サービス アカウントから認証情報をダウンロードします。[IAM と管理] タブの [サービス アカウント] セクションでサービス アカウントをクリックし、[キーを作成] をクリックして認証情報を保存します。

    • API 呼び出し元を認証するGOOGLE_APPLICATION_CREDENTIALS を JSON ファイルのパスに設定します。一般的な言語で gRPC クライアントを認証する方法については、コード例をご覧ください。

クリエイティブの取り込み

パートナーの広告システムで新しいクリエイティブが利用可能になるたびに、パートナーのシステムからクリエイティブ取り込み API にクリエイティブを送信する必要があります。

新しいクリエイティブを Google に送信して動画インフラストラクチャに読み込む場合は、広告システムによって生成された VAST ドキュメントに含まれるクリエイティブ データと同じものを指定する必要があります。これにより、クリエイティブを Google に事前に取り込む動作が、広告レスポンスでクリエイティブが最初に検出されたときにクリエイティブを読み込む動作と同じ動作になります。

送信されたクリエイティブごとに、サーバーで長時間実行の取り込みオペレーションが作成されます。このオペレーションのステータスはクエリできます。オペレーションが正常に完了すると、システム内にクリエイティブ リソースが作成されます。クリエイティブの送信に対するレスポンスには、リクエストの結果として生成されたオペレーションの ID が含まれます。生成されたオペレーション ID は、オペレーションの完了時に送信される Cloud Pub/Sub 通知に含まれ、送信された元のクリエイティブにマッピングされます。オペレーション ID を使用して、オペレーションの進行状況をいつでも確認することもできます。

クリエイティブ リクエスト

データは、プロトコル バッファまたは JSON オブジェクトとして API に送信されます。gRPC を使用して送信されるプロトコル バッファは、Pub/Sub 通知の使用に必要であり、JSON の unmarshaling はレスポンスの google.protobuf.Any フィールドにより複雑になるため、推奨されます。

創造的な回答

成功すると、サーバーはリクエストの種類に応じて、Protocol Buffer レスポンスまたは JSON レスポンスを返します。レスポンスには、新しく作成された取り込みオペレーション名とオペレーションの詳細が含まれます。

最初の送信時に、オペレーションに関連付けられているメタデータの一部が空で、結果が存在しない場合があります。オペレーションが完了すると、結果にクリエイティブ リソース(またはエラー)が入力され、メタデータに取り込みステータスに関する情報が含まれます。

メタデータは Any proto から CreateCreativeOperationMetadata proto にアンマーシャルされ、レスポンス(存在する場合)は Creative proto にアンマーシャルする必要があります。

API にアクセスするクライアント ライブラリ

API を統合する手順は次のとおりです。

  1. プロトコル バッファの依存関係をダウンロードし、google フォルダ全体を src ディレクトリに移動します。Google Cloud App Engine を使用している場合は、この手順をスキップできます。
  2. protoc プラグインを使用して proto ファイルから gRPC コードを生成し、生成されたコードを関連するディレクトリに配置します。
  3. Pub/Sub 通知で返された proto の新しい proto ファイルを作成します。前の手順を繰り返して、proto からコードを生成します。
  4. gRPC を使用して API にリクエストを送信します。

    1. 次のスコープを使用してデフォルト認証情報を取得します。

    https://www.googleapis.com/auth/video-ads

    https://www.googleapis.com/auth/pubsub

    1. リクエストをクリエイティブ インジェストに送信します。
    • デフォルトの認証情報を使用して dai.googleapis.com:443 に接続します。
    • gRPC proto 生成コードを使用して、クリエイティブ インジェスト サービスのクライアント スタブを作成します。
    • クライアント スタブを使用して CreateCreative を呼び出します。

    必要に応じて、長時間実行オペレーションの gRPC コード(ステップ 2 でダウンロードした googleapis ディレクトリに含まれています)を使用して、Operations サービスのスタブを作成します。このスタブを使用して、特定のオペレーション(GetOperation)のステータスを取得できます。

  5. PubSub で通知を確認します。

    1. PubSub クライアント ライブラリまたは gRPC を使用して PubSub サービスに接続し、指定されたトピックにパブリッシュされた PubSub 通知をポーリングします。

    2. Pub/Sub メッセージを手順 4 の proto に Unmarshal します。

    3. CreateCreative または GetOperation の呼び出しから、または PubSub 通知で長時間実行オペレーションが返された場合は、メタデータを google.protobuf.Any proto から discovery.protoCreateCreativeOperationMetadata に、レスポンスは discovery.protoCreative にアンマッシュルします。

Go クライアント コードの例

// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
  dai "google.golang.org/genproto/googleapis/ads/dai/v1"
  psnotif "protos/dai"
  "google.golang.org/genproto/googleapis/longrunning"
  "cloud.google.com/go/pubsub"
  "golang.org/x/net/context"
  "google.golang.org/grpc"
  "google.golang.org/grpc/credentials"
  "google.golang.org/grpc/credentials/oauth"
  "github.com/golang/protobuf/proto"
  anypb "github.com/golang/protobuf/ptypes/any"
)

var scopes = []string{"https://www.googleapis.com/auth/video-ads", "https://www.googleapis.com/auth/pubsub"}

const (
  subID = "sub-id" // The ID for the subscription to the topic you provided us (projects/<project ID>/subscriptions/<subscription ID>)
  project = "your-project-id" // Your Google Cloud Project ID
)

func main() {
  ctx := context.Background()
  crpc, err := oauth.NewApplicationDefault(ctx, scopes...)
  if err != nil {
    // TODO: Handle error
  }

  conn, err := grpc.Dial("dai.googleapis.com:443",
    grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
    grpc.WithPerRPCCredentials(crpc))
  if err != nil {
    // TODO: Handle error 
  }

  apiclient := dai.NewPartnerDiscoveryServiceClient(conn)
  opclient := longrunning.NewOperationsClient(conn)

  op, err := apiclient.CreateCreative(ctx, &dai.CreateCreativeRequest{
    // TODO: Add Creative with metadata and media files.
  })
  if err != nil {
    // TODO: Handle error
  }

  pubsubClient, err := pubsub.NewClient(ctx, project)
  if err != nil {
    // TODO: Handle error
  }
  sub := pubsubClient.Subscription(subID)

  // TODO: Pull from Pub/Sub subscription to receive messages, and acknowledge them
  var msg *pubsub.Message // Assume msg = a received Pub/Sub message

  // Unmarshal the Pub/Sub message into the proto created in step 9a of guide
  var n psnotif.CreateCreativeStatus
  if err := proto.Unmarshal(msg.Data, &n); err != nil {
    // TODO: Handle error
  }
  op = n.GetDetails()
  md, err = anyToMetadata(op.GetMetadata())
  if err != nil {
    // TODO: Handle error
  }
  // TODO: Check if ingest was successful and get Google Video ID from md.GetGvRegistryId()
  // TODO: Enable serving of creative using Google Video ID in VAST document

  // Optionally check the status of an ingest request using the status endpoint
  op, err = opclient.GetOperation(ctx, &longrunning.GetOperationRequest{Name:   op.Name})
  if err != nil {
    // TODO: Handle error
  }
}

// anyToMetadata converts the metadata Any field in an Operation message to
// CreateCreativeOperationMetadata.
func anyToMetadata(msg *anypb.Any) (*dai.CreateCreativeOperationMetadata, error) {
  var md dai.CreateCreativeOperationMetadata
  return &md, proto.Unmarshal(msg.Value, &md)
}

// anyToCreative converts the response Any field in an Operation message to
// Creative.
func anyToCreative(msg *anypb.Any) (*dai.Creative, error) {
  var cr dai.Creative
  return &cr, proto.Unmarshal(msg.Value, &cr)
}

再生中のクリエイティブの検索

クリエイティブ検索プロセスのフロー図

  1. ユーザーが YouTube または DAI でコンテンツを表示するようリクエストしている。
  2. YouTube / DAI は、コンテンツに挿入する広告について、第三者広告システムから VAST レスポンスを取得します。
  3. 返された広告は、以前に取り込まれたクリエイティブにマッピングされます。これらのクリエイティブは再生の準備ができており、Google Video Infrastructure から取得されてユーザーに再生されます。

パートナーが変更した VAST ドキュメント

クリエイティブが Google 動画インフラストラクチャに正常に読み込まれた後に広告システムから VAST レスポンスが返された場合、ドキュメントには処理済みのクリエイティブへの参照が含まれている必要があります。VAST ドキュメントには、特定のクリエイティブのメディア ファイルを引き続き含める必要がありますが、これらのメディア ファイルがシステムで使用される保証はありません。

VAST ドキュメントで処理済みのクリエイティブを参照するには、VAST 4 以降のドキュメントに新しい UniversalAdId 要素を追加するか、カスタム拡張機能を追加します。

ユニバーサル広告 ID

Video Creative Ingest API から返される gvRegistryID は、複数の広告システムで動画クリエイティブを一意に識別するために使用される、公開されているユニバーサル ID です。この ID は、広告システムの VAST 4 以降のドキュメントに追加する必要があります。これにより、YouTube または DAI が VAST ドキュメントを受信したときに、ID を使用して元に送信されたクリエイティブにマッピングできます。

広告システムは、VAST 4 以降のドキュメントの Creative ノードに新しい UniversalAdId 要素を追加する必要があります。idRegistry 属性は「googlevideo」に設定し、値は正常に処理されたクリエイティブ通知のステータスで指定された値にする必要があります。

新しいユニバーサル広告 ID が追加された VAST 4 ドキュメントの例を次に示します。

<VAST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vast.xsd" version="4.0">
  <Ad id="318230556">
    <InLine>
      <AdSystem>DCM</AdSystem>
      <AdTitle>In-Stream Video</AdTitle>
      <Creatives>
        <Creative id="79534759" AdID="" sequence="1">
          <UniversalAdId idRegistry="googlevideo">dQw4w9WgXcQ</UniversalAdId>
          <Linear>
            <Duration>00:00:15</Duration>
            <MediaFiles>
              <Mezzanine>
                <![CDATA[https://cdn.com/media.mp4]]>
              </Mezzanine>
              <MediaFile delivery="progressive" width="640" height="360" type="video/mp4" bitrate="313">
                <![CDATA[https://cdn.com/low-res-media.mp4]]>
              </MediaFile>
            </MediaFiles>
          </Linear>
        </Creative>
      </Creatives>
    </InLine>
  </Ad>
</VAST>

CreativeExtension

ユニバーサル広告 ID 要素は VAST 4.0 でのみ導入されたため、同じデータをバージョン 4.0 より前の VAST ドキュメントで公開するには、カスタム拡張機能が必要です。これは、VAST 仕様の Creative 要素の下に CreativeExtension 要素を使用して行います。

新しく導入された拡張機能は、任意の Universal AD ID 値を入力できるように有効にされた汎用拡張機能です。この場合、ユニバーサル広告 ID は googlevideo レジストリに属し、ID は google video ID になります。

<VAST version="3.0">
  <Ad id="318230556">
    <InLine>
      <AdSystem>My Ad Server</AdSystem>
      <AdTitle>Car Company</AdTitle>
      <Creatives>
        <Creative id="79534759" AdID="" sequence="1">
          <Linear>...</Linear>
          <CreativeExtensions>
            <CreativeExtension type="UniversalAdId">
              <UniversalAdId idRegistry="googlevideo">dQw4w9WgXcQ</UniversalAdId>
            </CreativeExtension>
          </CreativeExtensions>
        </Creative>
      </Creative>
    </InLine>
  </Ad>
</VAST>

CreativeExtension アプローチは、UniversalAdId に別の UniversalAdId レジストリの ID がすでに入力されている場合、VAST 4 以降でも使用できます。

<VAST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vast.xsd" version="4.0">
  <Ad id="318230556">
    <InLine>
      <AdSystem>DCM</AdSystem>
      <AdTitle>In-Stream Video</AdTitle>
      <Creatives>
        <Creative id="79534759" AdID="" sequence="1">
          <UniversalAdId idRegistry="other-registry">other-id</UniversalAdId>
          <Linear>
            <Duration>00:00:15</Duration>
            <MediaFiles>
              <Mezzanine>
                <![CDATA[https://cdn.com/media.mp4]]>
              </Mezzanine>
              <MediaFile delivery="progressive" width="640" height="360" type="video/mp4" bitrate="313">
                <![CDATA[https://cdn.com/low-res-media.mp4]]>
              </MediaFile>
            </MediaFiles>
          </Linear>
          <CreativeExtensions>
            <CreativeExtension type="UniversalAdId">
              <UniversalAdId idRegistry="googlevideo">dQw4w9WgXcQ</UniversalAdId>
            </CreativeExtension>
          </CreativeExtensions>
        </Creative>
      </Creatives>
    </InLine>
  </Ad>
</VAST>