広告再生リストを自動化する

プラットフォームを選択: HTML5 Android iOS tvOS

IMA HTML5 SDK は、完全に自動化された広告プレイリストをサポートしています。この機能では、広告を入稿する際に、Google アド マネージャーで指定したとおりに広告ブレークがコンテンツに挿入されます。また、プレロール、ミッドロール、ポストロールなどの広告ブレークをサポートするために必要な動画プレーヤーのコードも大幅に簡素化されます。

  • AdsManager を作成するときに、getAdsManager 呼び出しを使用して contentPlayback オブジェクトが渡されます。このオブジェクトには、動画の現在の再生ヘッド位置を返す currentTime プロパティが必要です。HTML5 の video 要素を使用してコンテンツを表示している場合は、その要素を SDK に渡すだけで済みます。このオブジェクトは、コンテンツの再生の進行状況を追跡するために使用されます。これにより、アド マネージャーで指定された時間にミッドロール挿入点が自動的に挿入されます。また、コンテンツの状態を代行して処理することを SDK に伝える必要もあります。
    var adsRenderingSettings = new google.ima.AdsRenderingSettings();
    adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true;
    adsManager = adsManagerLoadedEvent.getAdsManager(
        videoContent, adsRenderingSettings); // See API reference for contentPlayback.
  • ポストロールを確実に再生するには、コンテンツの終了時に SDK に通知する必要があります。SDK が動画プレーヤーを使用して広告を再生する場合があるため、これは少し複雑です。コンテンツが終了したときにのみ SDK に通知し、広告が終了したときには通知しないようにする必要があります。次のコードを使用して、これを行うことができます。
    var videoContent = document.getElementById('contentElement');
    var contentEndedListener = function() {adsLoader.contentComplete();};
    
    videoContent.addEventListener('ended', contentEndedListener);
    
    function onContentPauseRequested() {
      contentElement.removeEventListener('ended', contentEndedListener);
      ...
    }
    
    function onContentResumeRequested() {
      contentElement.addEventListener('ended', contentEndedListener);
      ...
    }
  • CONTENT_PAUSE_REQUESTED イベントと CONTENT_RESUME_REQUESTED イベントは、広告ブレークの再生時にコンテンツを一時停止および再開するために使用されます。
  • 動画プレーヤーがドラッグしてシークすることをサポートしており、ユーザーがドラッグしている間に動画プレーヤーの現在時刻プロパティが更新される場合、SDK はコンテンツが正常に進行しているのか、ユーザーがコンテンツをシークしているのかを区別できません。getAdsManager のパラメータとしてカスタム contentPlayback オブジェクトを使用する必要があります。このユースケースの例については、シークのトラブルをご覧ください。

注: コンテンツの再生が終了したときや、ユーザーが再生を停止したときは、必ず AdsLoader.contentComplete を呼び出して、コンテンツが終了したことを SDK に通知してください。その後、ポストロール広告ブレークがスケジュールされている場合は、SDK がポストロール広告ブレークを再生します。ALL_ADS_COMPLETED イベントは、すべての広告ブレークが再生されたときに発生します。また、コンテンツのトラッキングは init() が呼び出されたときに開始されるため、コンテンツを再生する前に必ず init() を呼び出す必要があります。

広告ブレークの自動再生を無効にする

状況によっては、広告ブレークの準備が整うまで SDK で広告ブレークが再生されないようにしたい場合があります。このシナリオでは、広告ブレークの自動再生を無効にして、広告ブレークの再生準備が整ったときに SDK に通知できます。この構成では、SDK が広告ブレークを読み込むと、AD_BREAK_READY イベントが発生します。プレーヤーで広告ブレークを開始する準備ができたら、adsManager.start() を呼び出すことができます。

function requestAds() {}
  ...
  adsLoader.getSettings().setAutoPlayAdBreaks(false);
  ...
}

function onAdsManagerLoaded() {
  ...
  // For non-auto ad breaks, listen for ad break ready
  adsManager.addEventListener(
      google.ima.AdEvent.Type.AD_BREAK_READY,
      adBreakReadyHandler);
  ...
}

function adBreakReadyHandler() {
  // Once we're ready to play ads. To skip this ad break, simply return
  // from this handler without calling adsManager.start().
  adsManager.start();
}

試してみる

動作する実装については、次のコードをご覧ください。

シークに関する問題

広告ルールを使用している場合は、クリック&ドラッグ シークで問題が発生する可能性があります。具体的には、ユーザーがクリックしてドラッグし、複数のミッドロール ポッドを通過して動画をシークすると、コンテンツが再開される前に、それらのポッドが 2 つ以上連続して再生されることがあります。これは、ユーザーがシークしている間に動画の再生ヘッドの時間が更新されることが原因です。ユーザーが広告をシークしている間に SDK が現在の時間をポーリングすると、広告を再生する必要があると判断されることがあります。コンテンツが再開されると、その広告が再生され、次にシーク以降の最新の広告が再生されます。この問題の視覚的な表現については、次の図をご覧ください。

ユーザーがシークを開始したときの現在時刻を保存し、ユーザーが通常の再生を再開するまで、SDK から要求されるたびにその時刻をレポートします。このソリューションの視覚的な表現については、次の図をご覧ください。

このソリューションでは、0:10 のミッドロールを適切にスキップし、0:20 のミッドロールのみを再生します。これは、次のコード スニペットのカスタム再生ヘッド トラッカーを使用して行われます。このコードには、ダウンロード ページで入手できる高度な HTML5 サンプル内の ads.js の変更(太字で表示)が含まれています。

var Ads = function(application, videoPlayer) {
  ...
  this.currentTime = 0;
  setInterval(this.updateCurrentTime, 1000);
};

Ads.prototype.updateCurrentTime = function() {
  if (!this.videoPlayer_.contentPlayer.seeking) {
    this.currentTime = this.videoPlayer_.contentPlayer.currentTime;
  }
};

Ads.prototype.onAdsManagerLoaded_ = function(adsManagerLoadedEvent) {
  this.application_.log('Ads loaded.');
  this.adsManager_ = adsManagerLoadedEvent.getAdsManager(this);
  this.processAdsManager_(this.adsManager_);
};

モバイル Safari に関する既知の問題

この方法は、モバイル Safari を除くすべてのプラットフォームで機能します。モバイル Safari では、動画タグの seeking プロパティが正しく実装されていません(常に false を返します)。これを回避するには、ユーザーが動画をシークしているかどうかを独自に確認する必要があります。このメソッドのサンプルコードは次のとおりです。太字の行は、既存のコードに対する変更です。

var Ads = function(application, videoPlayer) {
  ...
  this.currentTime = 0;
  setInterval(this.updateCurrentTime, 1000);
  this.seeking = false;
  this.seekCheckInterval = 1000;
  // You may need to adjust this value, depending on your platform
  this.seekThreshold = 100;
  this.previousTime = 0;
  setInterval(
      Application.bind(this, this.checkForSeeking),
      this.seekCheckInterval);
};

Ads.prototype.updateCurrentTime = function() {
  if (!this.seeking) {
    this.currentTime = this.videoPlayer_.contentPlayer.currentTime;
  }
};

Ads.prototype.checkForSeeking = function() {
  var currentTime = this.videoPlayer_.contentPlayer.currentTime;
  // How much time has passed since you last ran this method, in milliseconds
  var diff = (currentTime - this.previousTime) * 1000;
  // If that difference is greater than the time since you last ran this method,
  // plus the threshold, the user was seeking
  if (Math.abs(diff)  > this.interval + this.threshold) {
    this.seeking = true;
  } else {
    this.seeking = false;
  }
  // Grab the current video time again to make up for time spent in this method
  previousTime = this.videoPlayer_.contentPlayer.currentTime;
};

Ads.prototype.onAdsManagerLoaded_ = function(adsManagerLoadedEvent) {
  this.application_.log('Ads loaded.');
  this.adsManager_ = adsManagerLoadedEvent.getAdsManager(this);
  this.processAdsManager_(this.adsManager_);
};

これらの変更により、SDK はコンテンツ動画プレーヤーの currentTime プロパティではなく、Ads オブジェクトの currentTime プロパティを使用して、広告ブレークを再生するタイミングを判断するようになりました。