동영상 광고 소재 수집 API

Video Creative Ingest API를 사용하면 서드 파티 광고 시스템에서 YouTube 및 DAI 제품에 광고 소재를 사전에 처리할 수 있습니다. 이 프로세스를 통해 Google 이외의 광고 서버에서 광고가 결정되면 반환된 광고 소재가 YouTube 또는 DAI 동영상 스트림에 게재될 준비가 됩니다.

서드 파티 광고 시스템에서 광고 소재를 사전에 처리하는 프로세스에는 두 가지 주요 부분이 포함됩니다. 첫 번째 부분을 사용하면 서드 파티 광고 시스템이 Google에 광고 소재를 제공하고 Google 동영상 인프라에 광고 소재가 처리되는 동안 광고 소재의 진행 상황을 모니터링할 수 있습니다. 광고 소재가 처리되면 식별자가 광고 시스템으로 다시 전달됩니다.

두 번째 단계에서는 광고 시스템이 이러한 식별자를 가져와서 Universal Ad ID (VAST 4.0 이상) 또는 'UniversalAdId' 유형의 광고 확장 프로그램을 사용하여 제출된 광고 소재를 참조하는 VAST 문서에 포함합니다. DAI 또는 YouTube의 결정 시점에 광고 시스템의 VAST 문서가 발견되면 광고 소재 시스템은 VAST에서 이러한 식별자를 추출하고 재생을 위해 삽입할 적절한 광고 소재를 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. 서드 파티 광고 시스템이 광고 소재와 연결된 미디어 파일 목록이 포함된 HTTP 요청을 Video Creative Ingest API로 전송합니다.
  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 PubSub 주제에 대한 액세스 권한이 부여됩니다.

인증 프로세스를 시작하려면 다음 단계를 따르세요.

  1. Google Cloud 계정을 만듭니다.
  2. DAI API에 요청을 전송할 계정으로 프로젝트를 설정합니다.
  3. 프로젝트 내에서 왼쪽의 IAM 및 관리자 탭으로 이동하여 새 서비스 계정을 만듭니다. 요청은 서비스 계정을 사용하여 전송됩니다.
  4. PubSub API를 사용 설정하고 API가 모든 처리 성공 및 실패 알림을 게시하는 고유한 파트너 알림 주제를 하나 만듭니다.

    도메인 제한 조직 정책이 적용된 경우 허용된 고객 목록에 Google 고객 ID를 추가해야 합니다. creativeingestion@google.com에 문의하여 ID를 받으세요. 완료되면 허용된 고객 목록 (API의 고객 ID)에서 IAM 정책 (PubSub 게시자)에 주 구성원 (Google 로봇 계정)을 추가할 수 있습니다.

    video-creative-library-discovery@system.gserviceaccount.com를 주제에 PubSub 게시자로 추가합니다.

  5. 서비스 계정 이메일 주소와 PubSub 주제를 creativeingestion@google.com에 제공하여 이 정보를 API에 등록합니다.

  6. 계정이 서비스 소비자로 추가된 후 DAI API를 사용 설정합니다.

  7. API에 액세스하기 위한 사용자 인증 정보를 설정하려면 다음 단계를 따르세요.

    • 서비스 계정에서 사용자 인증 정보 다운로드: IAM 및 관리자 탭의 서비스 계정 섹션에서 서비스 계정을 클릭하고 키 만들기를 클릭한 후 사용자 인증 정보를 저장합니다.

    • API 호출자 인증 GOOGLE_APPLICATION_CREDENTIALS를 JSON 파일의 경로로 설정합니다. 일반적인 언어로 gRPC 클라이언트를 인증하는 방법은 코드 예를 참고하세요.

광고 소재 처리

파트너의 광고 시스템에서 새 광고 소재를 사용할 때마다 파트너의 시스템에서 광고 소재를 Creative Ingest API에 제출해야 합니다.

동영상 인프라에 로드하기 위해 새 광고 소재를 Google에 제출할 때는 광고 시스템에서 생성된 VAST 문서에 포함된 것과 동일한 광고 소재 데이터를 제공해야 합니다. 이렇게 하면 광고 소재를 Google에 사전 처리하여 처리하는 동작이 광고 응답에서 광고 소재가 처음 발견될 때 광고 소재를 로드하는 동작과 동일한 동작을 갖습니다.

제출된 각 광고 소재는 서버에서 상태를 쿼리할 수 있는 장기 실행 처리 작업을 만듭니다. 작업이 완료되면 시스템 내에 광고 소재 리소스가 생성됩니다. 광고 소재 제출에 대한 응답에는 요청으로 인해 발생한 작업의 ID가 포함됩니다. 결과 작업 ID는 작업이 완료될 때 전송되는 Cloud PubSub 알림에 포함되어 제출된 원본 광고 소재에 다시 매핑됩니다. 작업 ID는 특정 시점에 작업 진행 상황을 확인하는 데도 사용할 수 있습니다.

광고 소재 요청

데이터는 프로토콜 버퍼 또는 JSON 객체로 API에 전송됩니다. gRPC를 사용하여 전송되는 프로토콜 버퍼는 PubSub 알림을 소비하는 데 필요하므로 권장되며 JSON을 Unmarshalling하면 응답의 google.protobuf.Any 필드로 인해 추가적인 복잡성이 발생합니다.

창의적인 대답

성공하면 서버는 요청 유형에 따라 Protocol Buffer 응답 또는 JSON 응답을 반환합니다. 응답에는 새로 생성된 처리 작업 이름과 작업 세부정보가 포함됩니다.

처음 제출할 때 작업과 연결된 일부 메타데이터가 비어 있고 결과가 없을 수 있습니다. 작업이 완료되면 결과에 광고 리소스 (또는 오류)가 채워지고 메타데이터에 처리 상태에 관한 정보가 포함됩니다.

메타데이터는 Any 프로토에서 CreateCreativeOperationMetadata 프로토로, 응답 (있는 경우)은 Creative 프로토로 unmarshal해야 합니다.

API에 액세스하는 클라이언트 라이브러리

API와 통합하려면 다음 단계를 따르세요.

  1. 프로토콜 버퍼 종속 항목을 다운로드하고 전체 google 폴더를 src 디렉터리로 이동합니다. Google Cloud App Engine을 사용하는 경우 이 단계를 건너뛸 수 있습니다.
  2. protoc 플러그인을 사용하여 proto 파일에서 gRPC 코드를 생성하고 생성된 코드를 관련 디렉터리에 배치합니다.
  3. PubSub 알림에서 반환된 proto의 새 proto 파일을 만듭니다. 이전 단계를 반복하여 proto에서 코드를 생성합니다.
  4. gRPC를 사용하여 API에 요청합니다.

    1. 다음 범위로 기본 사용자 인증 정보를 가져옵니다.

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

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

    1. 요청을 Creative Ingest로 전송합니다.
    • 기본 사용자 인증 정보를 사용하여 dai.googleapis.com:443에 연결합니다.
    • gRPC 프로토 생성 코드를 사용하여 광고 처리 서비스의 클라이언트 스텁을 만듭니다.
    • 클라이언트 스텁을 사용하여 CreateCreative를 호출합니다.

    원하는 경우 2단계에서 다운로드한 googleapis 디렉터리에 포함된 장기 실행 작업 gRPC 코드를 사용하여 Operations 서비스의 스텁을 만듭니다. 이 스텁은 지정된 작업 (GetOperation)의 상태를 가져오는 데 사용할 수 있습니다.

  5. PubSub에서 알림을 확인합니다.

    1. PubSub 클라이언트 라이브러리 또는 gRPC를 사용하여 PubSub 서비스에 연결하고 제공된 주제에 게시된 PubSub 알림을 폴링합니다.

    2. 4단계의 PubSub 메시지를 proto로 마샬링합니다.

    3. 장기 실행 작업이 CreateCreative, GetOperation 호출에서 반환되거나 PubSub 알림에서 반환될 때마다 메타데이터를 google.protobuf.Any 프로토에서 discovery.protoCreateCreativeOperationMetadata로, 모든 응답을 discovery.protoCreative로 Unmarshal합니다.

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 동영상 인프라에서 가져와 사용자에게 재생됩니다.

파트너가 수정한 VAST 문서

광고 소재가 Google 동영상 인프라에 성공적으로 로드된 후 광고 시스템에서 VAST 응답이 반환되면 문서에 처리된 광고 소재에 대한 참조가 포함되어야 합니다. VAST 문서에는 특정 광고 소재의 미디어 파일이 계속 포함되어야 하지만 이러한 미디어 파일이 시스템에서 사용된다고 보장할 수는 없습니다.

VAST 문서에서 처리된 광고 소재를 참조하는 방법에는 두 가지가 있습니다. VAST 4 이상 문서에 새 UniversalAdId 요소를 추가하거나 맞춤 확장 프로그램을 추가하는 것입니다.

범용 광고 ID

Video Creative Ingest API에서 반환하는 gvRegistryID는 여러 광고 시스템에서 동영상 광고 소재를 고유하게 식별하는 데 사용되는 범용 공개 ID입니다. 이 ID는 광고 시스템의 VAST 4 이상 문서에 추가되어야 합니다. 그러면 VAST 문서가 YouTube 또는 DAI에서 수신될 때 이 ID를 사용하여 원래 제출된 광고 소재로 다시 매핑할 수 있습니다.

광고 시스템은 광고 소재 노드 아래의 VAST 4 이상 문서에 새 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>

UniversalAdId가 이미 다른 UniversalAdId 레지스트리의 ID로 채워진 경우 VAST 4 이상에서도 CreativeExtension 접근 방식을 사용할 수 있습니다.

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