VAST4.2でつくる動画広告の世界 その1

[Supershipグループ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/supership) の12月2日担当の三宅です。
普段はアドテクノロジーセンターで副センター長をしています。

前回、第0回目でタイトルの前提となる動画広告の種類について話をしたので、今回はタイトルどおり実際に動画広告の仕組みとフォーマットについて話していきます。

https://qiita.com/miyay/items/c8e3a58b4e2c526b4986

# TL;DR

* VASTは広告配信サーバーと動画プレイヤーを繋ぐ、XMLベースの規格
* VASTは動画プレイヤーのクライアントで処理されるパターンと、動画配信サーバー上で処理されるパターンがある
* VAST3.0と4.2を比較すると結構破壊的に変更されているので一度目を通した方がよさそう

# 動画広告と音声広告の仕組み

ここでは便宜上、以下のように呼びます。

* 動画が再生されるサイトやアプリ: メディア
* 動画を再生する機能を持つJSやネイティブのSDK: プレイヤー
* RTBや純広でVASTを吐き出すサーバー: (広告)配信サーバー、VASTサーバー

広告入札の仕組みはここでは触れませんが、動画広告は静止画広告と同じようにRTBや純広の広告配信サーバーから返却されます。
静止画の場合はscriptタグが返されメディア側でそのまま描画されることが多いと思いますが、動画広告/音声広告は **VAST** というフォーマットで配信サーバーからプレイヤーを制御し、広告素材(動画等)を読み込み再生します。

![vast30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6892/ac4b7beb-28a1-965e-9e8a-fd727627bbfb.png)
(VAST3.0 Referenceより)

# What's VAST

**VAST** とは Video Ad Serving Template の略で、名前の通り動画広告のフォーマットを表す規格です。が、実際には動画以外にも音声広告でも利用されています。

:::note warn
音声広告についてはVAST3.0から派生した **DAAST**(Digital Audio Ad Serving Template) という仕様が策定されましたが、VAST4.1で再度統合されました。
https://iabtechlab.com/blog/vast-4-1-now-with-audio-power/

VAST が VAAST(Video and Audio Ad Serving Template) に改名されず本当によかったと思います。
:::

VASTおよび関連仕様・ガイドラインは様々なインターネット広告の仕様策定を行っている IAB TechLab のワーキンググループで策定されています。

VASTはXMLで記載されており、最新版は2019年6月にリリースされた Version4.2 となっています。

https://iabtechlab.com/wp-content/uploads/2019/06/VAST_4.2_final_june26.pdf

# フォーマット

主には以下のような情報をプレイヤーに指示します。

* Impressionビーコン
    * VASTが実際に表示(Impression)されたかどうか、その際の落札金額を配信サーバー側に通知するURL
* 動画秒数
    * CM素材の再生時間
* メディアファイル
    * 動画/音声ファイルのURLや縦横サイズ、bitrateなど
    * スマホ用、PC用など通常は1つのCMに対し広告配信サーバー側で予めマルチトランスコードを行い、複数サイズのメディアファイルを指定する
* クリックURL
    * CMがクリックできる場合の遷移先のURL
    * ただしインストリームではクリックできない(non clickable)場合も多い
* スキップ秒数
    * CMの再生時間が長い場合、指定秒数以上経過したらスキップ可能(skipable)にする
* 計測タグ
    * 指定した計測ポイントでビーコンが発火するようになっており、例えばこのimpは最後までCMを視聴したかなどを計測できます
* インタラクティブ広告
    * VASTの仕様では実現できないインタラクティブな操作と連動する広告を定義するのに使います
    * 別途後日記載しますが、今までは **VPAID** という規格が使われていましたが、VAST4.2以降は **SIMID** という規格に置き換わります
* 広告計測
    * 前述のImpビーコンや計測タグにより広告が表示されたか≒課金対象(支払い対象)になるかを判断することになりますが、このImpビーコンを発火するかどうかはプレイヤーに委ねられるため、不具合もしくは故意等によりビーコンが発火しなかった場合は広告配信サーバー側は計測が不可能になります
    * 広告配信サーバー側、もしくは第三者機関が広告計測に介入することで不正を防止した計測が可能になります
    * こちらも別途記載しますが、インタラクティブと同じく今までは **VPAID** という規格が使われていました。しかしVPAIDは元々インタラクティブ制御用の規格であること、広告配信サーバー側がJSで直接プレイヤーに介入する方法に問題があったため、 **OMID** という規格を通してIAB TechLabが提供するSDK(OMSDK)を叩いて計測を行う方法に変わりました
* Wrapper情報
    * VASTはWrapの機能があり、例えば配信サーバーAのVASTを配信サーバーBがWrapして配信することが可能です
        * 例えばDSPが出力したVASTをSSPが計測タグだけ追加しWrapして、プレイヤーに渡すといったことが可能です
    * Wrapは最大5回まで可能で、それ以上Wrapされている場合はプレイヤーでエラーを出すこととされています

```xml:sample_vast.xml
<?xml version="1.0" encoding="UTF-8"?>
<VAST version='4.2' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns='http://www.iab.com/VAST'>
  <Ad id='1'>
    <InLine>
      <AdSystem version='1'>SerialVastGenerator</AdSystem>
      <Impression id='Impression-ID'>
        <!-- Impressionビーコン -->
        <![CDATA[https://example.com]]>
      </Impression>
      <AdTitle>商品A</AdTitle>
      <Creatives>
        <Creative id='1' sequence='1' adId='1'>
          <Linear>
            <!-- 動画秒数 -->
            <Duration>00:00:15</Duration>
            
            <!-- メディアファイル -->
            <MediaFiles>
              <MediaFile delivery='progressive' type='video/mp4' bitrate='500' width='640' height='360' scalable='0' codec='h264'>
                <![CDATA[https://example.com]]>
              </MediaFile>
              <MediaFile delivery='progressive' type='video/mp4' bitrate='1000' width='1024' height='576' scalable='0' codec='h264'>
                <![CDATA[https://example.com]]>
              </MediaFile>
              <MediaFile delivery='progressive' type='video/mp4' bitrate='3000' width='1920' height='1080' scalable='0' codec='h264'>
                <![CDATA[https://example.com]]>
              </MediaFile>
            </MediaFiles>
            
            <!-- クリックURL。この場合はクリックできない -->
            <VideoClicks>
              <ClickThrough/>
            </VideoClicks>
            
            <!-- 計測タグ -->
            <TrackingEvents>
              <Tracking event="start"><![CDATA[https://example.com]]></Tracking>
              <Tracking event="complete"><![CDATA[https://example.com]]></Tracking>
            </TrackingEvents>
          </Linear>
        </Creative>
      </Creatives>
    </InLine>
  </Ad>
</VAST>
```
(要素は一部省略)

公式のXML Schemaはこちらです。

https://github.com/InteractiveAdvertisingBureau/vast/blob/master/vast_4.2.xsd

各要素は次回以降で細かく見ていきます。

# プレイヤーでの再生方法

プレイヤーがVASTを読み込み本編映像と共に再生する方法は何種類かに分かれます

## クライアントサイド再生(CSAI)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6892/ada4754b-39b1-791c-2bb2-ad891bed4cdf.png)

動画プレイヤーのクライアント側でVAST取得を行い再生します。

1. プレイヤーが配信サーバー(AdServer、DSP、3Pasなど)へ広告を要求
1. 配信サーバーからVASTを出力
1. (必要であれば)Wrap元の配信サーバーへVASTを要求
1. (必要であれば)Wrap元の配信サーバーがVASTを出力
1. プレイヤーがVASTを解釈し、動画/音声を再生
1. 計測ビーコンの発火

メディアはVASTに対応したプレイヤーを用意するだけで済むため、アウトストリームや標準的なインストリームでも採用されます。

## サーバーサイド再生(SSAI)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6892/838a4059-a5bb-40ea-57f7-e56f489fa092.png)

動画サイトのサーバー側でVAST取得と解釈を行い、本編映像と同じストリームに乗せ広告を再生します。

1. プレイヤーから動画配信サーバーへ広告を要求
1. 動画配信サーバーから広告配信サーバー(AdServer、DSP、3Pasなど)へ広告を要求
1. 広告配信サーバーからVASTを出力
1. (後述)メザニンファイルがあれば処理
1. VAST内の適切なメディアファイルを取得する
1. 本編映像のCM枠に上記メディアファイルを入れ込み、一緒にプレイヤーへ配信(これをユーザー単位で行う)

図には記載されていませんが、計測ビーコンの発火もサーバーサイドで行われます。
その際、UAやIPやCookieがクライアントのものではなく動画配信サーバーのものになるため、別途渡すなり対応が必要です。またCSAIに比べ遅延も起こります。

地上波と同じような感覚でCMを配信できますが相応の設備が必要になるため、プレミアムなインストリーム等で採用されます。

:::note warn
メザニンファイル

前述の通りメディアファイルは広告サーバー側で予めエンコードを行い複数画質のものを作っておきますが、それでも本編動画の画質や音質と異なる場合があります。
本編動画と比べ著しく画質が劣っていたり、特に音量が異なるというのはメディア側のユーザーに対して大変ストレスになります。だからと言って動画サービスの数だけ広告配信サーバー側でエンコードを行うのはCPU負荷的にもストレージ負荷的にも看過できないものです。

そこでVAST4.0ではメザニンファイルという概念が追加されました。
1. 広告配信サーバー側でエンコード前の生の動画ファイルをファイルに対して一意の識別子と共にVASTに載せ渡す
1. 動画配信サーバーが識別子に対して初回アクセスした時に非同期的に生の動画ファイルを適切なフォーマットでエンコードを行う
1. 以後同じ識別子が来た場合は動画配信サーバー側でエンコードを行った動画ファイルを使って再生する

独自エンコード仕様が増えていくのに比べるとかなり良い仕様だと思いますが、放送局基準の未エンコード動画ファイルは20mbpsとかあるので誤ってユーザーに配信されるとCDN代とか通信量とかいろいろやばそうです
:::

# おまけ: VAST4.0から4.2までの主な変更点
## VAST4.0

* SSAIのサポート
* メザニンファイルの対応
* ユニバーサル広告ID `<UniversalAdId>` のサポート
    * `adID`は各事業者が好き勝手決めていたため、それとは異なるシステム間で一意のクリエイティブID。
* 広告検証のための `<AdVerifications>` `<ViewableImpression>` のサポート
    * VPAIDは本来インタラクションに使用されるためのものなので、それの代替
    * このためのOpen Measurement(OM, OMID)の規格が策定されている
* 広告カテゴリのサポート
    * 競合分離用

## VAST4.1

* DAASTの統合
* VPAIDの非推奨化
* トラッキングイベントの追加と廃止
    * 追加: "loaded", "closeLinear"
    * 削除: "acceptInvitationLinear", "timeSpentViewing"
* AdServingIdの追加
    * クリエイティブではなく、インプレッションやトラッキングで一意のID
* Flashの削除
* Surveyの非推奨化
* ノンリニア広告の非推奨化？

## VAST4.2

* SIMIDのサポート
* ClickThroughのWrapper指定
* アイコン要素の更新

# 次回、リニア広告

`<Linear>` タグ内のメディアファイルや計測タグについて詳しく見ていきます。

# 最後に

Supershipではプロダクト開発やサービス開発に関わる人を絶賛募集しております。
ご興味がある方は以下リンクよりご確認ください。

[Supership 採用サイト](https://supership.jp/recruit/)

是非ともよろしくお願いします。