IMA HTML5 SDK は、完全に自動化された広告再生リストをサポートしています。この機能は、広告の入稿時に Google アド マネージャーで指定したように、コンテンツにミッドロール挿入点が挿入されます。また、プレロール、ミッドロール、ポストロールなどのミッドロール広告ブレークをサポートするために必要な動画プレーヤー コードも大幅に簡素化されます。
AdsManager
を作成するときに、getAdsManager 呼び出しを使用してcontentPlayback
オブジェクトが渡されます。このオブジェクトには、動画の現在の再生ヘッド位置を返すcurrentTime
プロパティが必要です。HTML5 のvideo
要素を使用してコンテンツを表示する場合は、その要素を SDK に渡すだけです。このオブジェクトは、コンテンツの再生の進行状況を追跡して、アド マネージャーで指定されたタイミングでミッドロール挿入点が自動的に挿入されるようにするために使用されます。また、コンテンツの状態を 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 では、動画タグのシーク プロパティが正しく実装されていません(常に 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 プロパティを使用してミッドロール挿入点の再生タイミングを判断するようになりました。