IMA SDK を設定する

IMA SDK を使用すると、マルチメディア広告をウェブサイトやアプリに簡単に統合できます。IMA SDK は、 VAST 準拠の任意の広告サーバーから広告をリクエストし、アプリ内の広告再生を管理できます。IMA クライアントサイド SDK を使用すると、コンテンツ動画の再生は引き続き管理できますが、広告の再生は SDK が処理します。広告は、アプリのコンテンツ動画プレーヤーの上に配置された別の動画プレーヤーで再生されます。

このガイドでは、IMA SDK をシンプルな動画プレーヤー アプリに統合する方法について説明します。統合が完了したサンプルを確認したり、その手順を学びたい場合は、GitHub からシンプルな例をダウンロードしてください。SDK があらかじめ統合された HTML5 プレーヤーをご希望の場合は、Video.js 用の IMA SDK プラグインをご覧ください。

IMA クライアントサイドの概要

IMA をクライアントサイドで実装するには、次の 4 つの主要な SDK コンポーネントを使用します。このガイドでは、これらのコンポーネントについて説明します。

  • AdDisplayContainer: IMA が広告 UI 要素をレンダリングする場所を指定し、アクティブ ビューオープン測定などの視認性を測定するコンテナ オブジェクト。
  • AdsLoader: 広告をリクエストし、広告リクエスト レスポンスからのイベントを処理するオブジェクト。インスタンス化すべき広告ローダは 1 つだけです。この広告ローダは、アプリのライフサイクル全体で再利用できます。
  • AdsRequest: 広告リクエストを定義するオブジェクト。Google 広告リクエストでは、VAST 広告タグの URL と、広告のサイズなどの追加パラメータを指定します。
  • AdsManager: 広告リクエストへのレスポンスを含むオブジェクト。広告の再生を制御し、SDK によって発生した広告イベントをリッスンします。

前提条件

始める前に、次のものが必要になります。

  • 3 つの空のファイル:
    • index.html
    • style.css
    • ads.js
  • Python がパソコン、またはテストに使用するウェブサーバーにインストールされている

1. 開発用サーバーを起動する

IMA SDK は、読み込まれたページと同じプロトコルを使用して依存関係を読み込むため、ウェブサーバーを使用してアプリをテストする必要があります。ローカルの開発用サーバーを起動する最も簡単な方法は、Python が組み込みまれているサーバーを使用することです。

  1. index.html ファイルを含むディレクトリから次のコマンドを実行します。
      python -m http.server 8000
  2. ウェブブラウザで http://localhost:8000/ にアクセスします。

Apache HTTP Server などの他のウェブサーバーも使用できます。

2. シンプルな動画プレーヤーを作成する

まず、index.html を変更して、ラップ要素に含まれるシンプルな HTML5 動画要素と、再生をトリガーするボタンを作成します。次の例では、IMA SDK をインポートし、AdDisplayContainer コンテナ要素を設定します。詳しくは、 IMA SDK をインポートする 広告コンテナを作成する の手順をご覧ください。

<html>
  <head>
    <title>IMA HTML5 Simple Demo</title>
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <div id="mainContainer">
      <div id="content">
        <video id="contentElement">
          <source src="https://storage.googleapis.com/gvabox/media/samples/stock.mp4"></source>
        </video>
      </div>
      <div id="adContainer"></div>
    </div>
    <button id="playButton">Play</button>
    <script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
    <script src="ads.js"></script>
  </body>
</html>
#mainContainer {
  position: relative;
  width: 640px;
  height: 360px;
}

#content {
  position: absolute;
  top: 0;
  left: 0;
  width: 640px;
  height: 360px;
}

#contentElement {
  width: 640px;
  height: 360px;
  overflow: hidden;
}

#playButton {
  margin-top:10px;
  vertical-align: top;
  width: 350px;
  height: 60px;
  padding: 0;
  font-size: 22px;
  color: white;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  background: #2c3e50;
  border: 0;
  border-bottom: 2px solid #22303f;
  cursor: pointer;
  -webkit-box-shadow: inset 0 -2px #22303f;
  box-shadow: inset 0 -2px #22303f;
}
let adsManager;
let adsLoader;
let adDisplayContainer;
let isAdPlaying;
let isContentFinished;
let playButton;
let videoContent;
let adContainer;

// On window load, attach an event to the play button click
// that triggers playback of the video element.
window.addEventListener('load', function(event) {
  videoContent = document.getElementById('contentElement');
  adContainer = document.getElementById('adContainer');
  adContainer.addEventListener('click', adContainerClick);
  playButton = document.getElementById('playButton');
  playButton.addEventListener('click', playAds);
  setUpIMA();
});

style.css ファイルと ads.js ファイルを読み込むために必要なタグを追加します。次に、styles.css を変更して、モバイル デバイス向けに動画プレーヤーをレスポンシブにします。最後に、ads.js で変数を宣言し、再生ボタンをクリックしたときに動画の再生をトリガーします。

ads.js コード スニペットには、 AdsLoader を初期化して広告リクエストを行う セクションで定義されている setUpIMA() への呼び出しが含まれています。

3. IMA SDK をインポートする

次に、index.html で、ads.js のタグの前にスクリプトタグを使用して IMA フレームワークを追加します。

<script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script>

4. 広告コンテナを作成する

ほとんどのブラウザでは、IMA SDK は専用の広告コンテナ要素を使用して、広告と広告関連の UI 要素の両方を表示します。このコンテナは、左上の隅から動画要素をオーバーレイするようにサイズを設定する必要があります。このコンテナに配置される広告の高さと幅は adsManager オブジェクトによって設定されるため、これらの値を手動で設定する必要はありません。

この広告コンテナ要素を実装するには、まず video-container 要素内に新しい div を作成します。次に、CSS を更新して、要素を video-element の左上に配置します。最後に、createAdDisplayContainer() 関数を追加して、新しい広告コンテナ div を使用して AdDisplayContainer オブジェクトを作成します。

<div id="adContainer"></div>
#adContainer {
  position: absolute;
  top: 0;
  left: 0;
  width: 640px;
  height: 360px;
}
/**
 * Sets the 'adContainer' div as the IMA ad display container.
 */
function createAdDisplayContainer() {
  adDisplayContainer = new google.ima.AdDisplayContainer(
      document.getElementById('adContainer'), videoContent);
}

5. AdsLoader を初期化して広告リクエストを行う

広告をリクエストするには、AdsLoader インスタンスを作成します。AdsLoader コンストラクタは AdDisplayContainer オブジェクトを入力として受け取り、指定された広告タグ URL に関連付けられた AdsRequest オブジェクトを処理するために使用できます。この例で使用されている広告タグには、10 秒間のプレロール広告が含まれています。この広告タグ URL や他の広告タグ URL は、IMA Video Suite Inspector を使用してテストできます。

ベスト プラクティスとして、ページのライフサイクル全体で AdsLoader のインスタンスを 1 つだけ維持します。追加の広告リクエストを行うには、新しい AdsRequest オブジェクトを作成しますが、同じ AdsLoader を再利用します。詳しくは、IMA SDK に関するよくある質問をご覧ください。

AdsLoader.addEventListener を使用して、広告の読み込みイベントとエラー イベントをリッスンし、応答します。次のイベントをリッスンします。

  • ADS_MANAGER_LOADED
  • AD_ERROR

onAdsManagerLoaded() リスナーと onAdError() リスナーを作成するには、次の例をご覧ください。

/**
 * Sets up IMA ad display container, ads loader, and makes an ad request.
 */
function setUpIMA() {
  // Create the ad display container.
  createAdDisplayContainer();
  // Create ads loader.
  adsLoader = new google.ima.AdsLoader(adDisplayContainer);
  // Listen and respond to ads loaded and error events.
  adsLoader.addEventListener(
      google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
      onAdsManagerLoaded, false);
  adsLoader.addEventListener(
      google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false);

  // An event listener to tell the SDK that our content video
  // is completed so the SDK can play any post-roll ads.
  const contentEndedListener = function() {
    // An ad might have been playing in the content element, in which case the
    // content has not actually ended.
    if (isAdPlaying) return;
    isContentFinished = true;
    adsLoader.contentComplete();
  };
  videoContent.onended = contentEndedListener;

  // Request video ads.
  const adsRequest = new google.ima.AdsRequest();
  adsRequest.adTagUrl = 'https://pubads.g.doubleclick.net/gampad/ads?' +
      'iu=/21775744923/external/single_ad_samples&sz=640x480&' +
      'cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&gdfp_req=1&' +
      'output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=';

  // Specify the linear and nonlinear slot sizes. This helps the SDK to
  // select the correct creative if multiple are returned.
  adsRequest.linearAdSlotWidth = 640;
  adsRequest.linearAdSlotHeight = 400;

  adsRequest.nonLinearAdSlotWidth = 640;
  adsRequest.nonLinearAdSlotHeight = 150;

  adsLoader.requestAds(adsRequest);
}

6. AdsLoader イベントに応答する

AdsLoader が広告を正常に読み込むと、ADS_MANAGER_LOADED イベントを送信します。コールバックに渡されたイベントを解析して、AdsManager オブジェクトを初期化します。AdsManager は、広告タグ URL へのレスポンスで定義されているように、個々の広告を読み込みます。

読み込みプロセス中に発生したエラーを処理するようにしてください。広告が読み込まれない場合は、ユーザーがコンテンツを視聴する際に妨げにならないように、広告なしでメディアの再生が続行されるようにしてください。

/**
 * Handles the ad manager loading and sets ad event listeners.
 * @param {!google.ima.AdsManagerLoadedEvent} adsManagerLoadedEvent
 */
function onAdsManagerLoaded(adsManagerLoadedEvent) {
  // Get the ads manager.
  const adsRenderingSettings = new google.ima.AdsRenderingSettings();
  adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true;
  // videoContent should be set to the content video element.
  adsManager =
      adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings);

  // Add listeners to the required events.
  adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError);
  adsManager.addEventListener(
      google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested);
  adsManager.addEventListener(
      google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
      onContentResumeRequested);
  adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdLoaded);
}

/**
 * Handles ad errors.
 * @param {!google.ima.AdErrorEvent} adErrorEvent
 */
function onAdError(adErrorEvent) {
  // Handle the error logging.
  console.log(adErrorEvent.getError());
  adsManager.destroy();
}

onAdsManagerLoaded() 関数で設定されるリスナーの詳細については、次のサブセクションをご覧ください。

AdsManager エラーを処理する

AdsLoader 用に作成されたエラーハンドラは、AdsManager のエラーハンドラとしても機能します。onAdError() 関数を再利用するイベント ハンドラをご覧ください。

adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError);

再生と一時停止のイベントを処理する

AdsManager が広告を挿入して表示する準備ができたら、CONTENT_PAUSE_REQUESTED イベントを発生させます。このイベントを処理するには、基盤となる動画プレーヤーで一時停止をトリガーします。同様に、広告が完了すると、AdsManagerCONTENT_RESUME_REQUESTED イベントを発生させます。このイベントを処理するには、基盤となるコンテンツ動画の再生を再開します。

adsManager.addEventListener(
    google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested);
adsManager.addEventListener(
    google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
    onContentResumeRequested);

onContentPauseRequested() 関数と onContentResumeRequested() 関数の定義については、次の例をご覧ください。

/**
 * Pauses video content and sets up ad UI.
 */
function onContentPauseRequested() {
  isAdPlaying = true;
  videoContent.pause();
  // This function is where you should setup UI for showing ads (for example,
  // display ad timer countdown, disable seeking and more.)
  // setupUIForAds();
}

/**
 * Resumes video content and removes ad UI.
 */
function onContentResumeRequested() {
  isAdPlaying = false;
  if (!isContentFinished) {
    videoContent.play();
  }
  // This function is where you should ensure that your UI is ready
  // to play content. It is the responsibility of the Publisher to
  // implement this function when necessary.
  // setupUIForContent();
}

ノンリニア広告中のコンテンツの再生を処理する

AdsManager は、広告を再生する準備ができたときにコンテンツ動画を一時停止しますが、この動作は、広告が表示されている間もコンテンツの再生が続くノンリニア広告には対応していません。

adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdLoaded);

非リニア広告をサポートするには、AdsManager をリッスンして LOADED イベントを出力します。広告がリニアかどうかを確認します。リニアでない場合、動画要素の再生を再開します。

onAdLoaded() 関数の定義については、次の例をご覧ください。

/**
 * Handles ad loaded event to support non-linear ads. Continues content playback
 * if the ad is not linear.
 * @param {!google.ima.AdEvent} adEvent
 */
function onAdLoaded(adEvent) {
  let ad = adEvent.getAd();
  if (!ad.isLinear()) {
    videoContent.play();
  }
}

7. モバイル デバイスでクリックして一時停止をトリガーする

AdContainer は動画要素をオーバーレイするため、ユーザーは基盤となるプレーヤーを直接操作できません。モバイル デバイスのユーザーは、動画プレーヤーをタップして再生を一時停止できると想定しているため、混乱を招く可能性があります。この問題に対処するため、IMA SDK は IMA で処理されないクリックを広告オーバーレイから AdContainer 要素に渡します。この要素でクリックを処理できます。モバイル以外のブラウザのリニア広告には適用されません。広告をクリックするとクリックスルー リンクが開きます。

クリックして一時停止を実装するには、on window load リスナーに adContainerClick() クリック ハンドラ関数を追加します。

/**
 * Handles clicks on the ad container to support expected play and pause
 * behavior on mobile devices.
 * @param {!Event} event
 */
function adContainerClick(event) {
  console.log("ad container clicked");
  if(videoContent.paused) {
    videoContent.play();
  } else {
    videoContent.pause();
  }
}

8. AdsManager を起動する

広告の再生を開始するには、AdsManager を開始します。広告を自動再生できないモバイル ブラウザを完全にサポートするには、再生ボタンのクリックなど、ページに対するユーザー操作から広告の再生をトリガーします。

/**
 * Loads the video content and initializes IMA ad playback.
 */
function playAds() {
  // Initialize the container. Must be done through a user action on mobile
  // devices.
  videoContent.load();
  adDisplayContainer.initialize();

  try {
    // Initialize the ads manager. This call starts ad playback for VMAP ads.
    adsManager.init(640, 360);
    // Call play to start showing the ad. Single video and overlay ads will
    // start at this time; the call will be ignored for VMAP ads.
    adsManager.start();
  } catch (adError) {
    // An error may be thrown if there was a problem with the VAST response.
    videoContent.play();
  }
}

9. プレーヤーのサイズ変更をサポートする

広告のサイズを動的に変更して動画プレーヤーのサイズに合わせたり、画面の向きの変更に合わせたりするには、ウィンドウのサイズ変更イベントに応じて adsManager.resize() を呼び出します。

window.addEventListener('resize', function(event) {
  console.log("window resized");
  if(adsManager) {
    let width = videoContent.clientWidth;
    let height = videoContent.clientHeight;
    adsManager.resize(width, height, google.ima.ViewMode.NORMAL);
  }
});

これで、これで、IMA SDK を使用して広告をリクエストして表示できるようになりました。SDK の高度な機能について詳しくは、他のガイドまたは GitHub のサンプルをご覧ください。