広告再生リストを自動化する
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
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 プロパティを使用してミッドロール挿入点の再生タイミングを判断するようになりました。
特に記載のない限り、このページのコンテンツはクリエイティブ・コモンズの表示 4.0 ライセンスにより使用許諾されます。コードサンプルは Apache 2.0 ライセンスにより使用許諾されます。詳しくは、Google Developers サイトのポリシーをご覧ください。Java は Oracle および関連会社の登録商標です。
最終更新日 2025-08-31 UTC。
[null,null,["最終更新日 2025-08-31 UTC。"],[[["\u003cp\u003eThe IMA HTML5 SDK enables automated ad playlists, simplifying ad integration and supporting pre-rolls, mid-rolls, and post-rolls by leveraging Google Ad Manager.\u003c/p\u003e\n"],["\u003cp\u003eTo ensure proper ad playback, developers must signal content completion using \u003ccode\u003eAdsLoader.contentComplete()\u003c/code\u003e and manage content state synchronization with the SDK.\u003c/p\u003e\n"],["\u003cp\u003eCustom content playback objects can be used to address seeking issues and provide finer control over ad break timing and behavior.\u003c/p\u003e\n"],["\u003cp\u003eThe SDK provides events like \u003ccode\u003eCONTENT_PAUSE_REQUESTED\u003c/code\u003e, \u003ccode\u003eCONTENT_RESUME_REQUESTED\u003c/code\u003e, and \u003ccode\u003eAD_BREAK_READY\u003c/code\u003e for developers to manage content playback and ad interactions.\u003c/p\u003e\n"],["\u003cp\u003eSpecific code adjustments are necessary to handle seeking accurately on mobile Safari due to platform limitations.\u003c/p\u003e\n"]]],[],null,["# Automate ad playlists\n\nIMA HTML5 SDK supports fully automated ad playlists. This feature\ninserts ad breaks into the content as specified in\n[Google Ad Manager](//www.google.com/dfp)\nwhen trafficking your ads. It also greatly simplifies the video player code\nnecessary to support ad breaks, including pre-rolls, mid-rolls and post-rolls.\n\n- When creating the `AdsManager`, a `contentPlayback` object is passed in using the [getAdsManager](/interactive-media-ads/docs/sdks/html5/client-side/reference/interface/google.ima.AdsManagerLoadedEvent#google.ima.AdsManagerLoadedEvent.getAdsManager) call. This object must have a `currentTime` property that returns the current playhead position of the video. If you're using an HTML5 `video` element to display your content, you can just pass that element to the SDK. This object is used to track the progress of the content playback so ad breaks are automatically inserted at the times specified in Ad Manager. You also need to let the SDK know that you want it to handle content state on your behalf. \n\n ```javascript\n var adsRenderingSettings = new google.ima.AdsRenderingSettings();\n adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true;\n adsManager = adsManagerLoadedEvent.getAdsManager(\n videoContent, adsRenderingSettings); // See API reference for /interactive-media-ads/docs/sdks/html5/client-side/reference/interface/google.ima.AdsManagerLoadedEvent#google.ima.AdsManagerLoadedEvent.getAdsManager.\n ```\n- To ensure post-rolls are played, you need to let the SDK know when your content is finished. This is a bit tricky, because in some cases the SDK uses your video player to play ads, so you need to make sure you're only letting the SDK know when your content is finished, and not when an ad is finished. You can do that using the following code: \n\n ```javascript\n var videoContent = document.getElementById('contentElement');\n var contentEndedListener = function() {adsLoader.contentComplete();};\n\n videoContent.addEventListener('ended', contentEndedListener);\n\n function onContentPauseRequested() {\n contentElement.removeEventListener('ended', contentEndedListener);\n ...\n }\n\n function onContentResumeRequested() {\n contentElement.addEventListener('ended', contentEndedListener);\n ...\n }\n ```\n- The [CONTENT_PAUSE_REQUESTED](/interactive-media-ads/docs/sdks/html5/client-side/reference/namespace/google.ima.AdEvent#google.ima.AdEvent.Type) and [CONTENT_RESUME_REQUESTED](/interactive-media-ads/docs/sdks/html5/client-side/reference/namespace/google.ima.AdEvent#google.ima.AdEvent.Type) events are used to pause and resume the content when ad breaks are played.\n- If your video player supports drag-to-seek, and the current time property of the video player updates while the user is dragging, the SDK can't differentiate between content progressing normally and a user seeking through the content. You must use a custom contentPlayback object as your parameter to `getAdsManager`. For an example of this use case, see [The Trouble with Seeking](#trouble-with-seeking).\n\n**Note:** When the content has finished playing or\nthe user has stopped playback, be sure to call AdsLoader.contentComplete\nin order to signal to the SDK that the content is done. The SDK then plays\nthe post-roll ad break, if one has been scheduled. The `ALL_ADS_COMPLETED`\nevent is raised when ALL ad breaks have been played. In addition, note\nthat content tracking begins when `init()` is called and you should\nalways call `init()` before playing content.\n\nDisable automatic playback of ad breaks\n---------------------------------------\n\nIn some circumstances you may want to prevent the SDK from playing ad breaks until\nyou're ready for them. In this scenario, you can disable automatic playback of ad breaks\nin favor of letting the SDK know when you're ready for an ad break to play. With this\nconfiguration, once the SDK has loaded an ad break, it fires an\n`AD_BREAK_READY` event. When your player is ready for the ad break to start,\nyou can call adsManager.start(): \n\n```javascript\nfunction requestAds() {}\n ...\n adsLoader.getSettings().setAutoPlayAdBreaks(false);\n ...\n}\n\nfunction onAdsManagerLoaded() {\n ...\n // For non-auto ad breaks, listen for ad break ready\n adsManager.addEventListener(\n google.ima.AdEvent.Type.AD_BREAK_READY,\n adBreakReadyHandler);\n ...\n}\n\nfunction adBreakReadyHandler() {\n // Once we're ready to play ads. To skip this ad break, simply return\n // from this handler without calling adsManager.start().\n adsManager.start();\n}\n```\n\nTry it out\n----------\n\nSee the following code for a working implementation.\nSee the Pen \\\u003ca href='http://codepen.io/imasdk/pen/QyBNrq/'\\\u003eManual Ad Breaks\\\u003c/a\\\u003e by IMA SDK (\\\u003ca href='http://codepen.io/imasdk'\\\u003e@imasdk\\\u003c/a\\\u003e) on \\\u003ca href='http://codepen.io'\\\u003eCodePen\\\u003c/a\\\u003e.\n\nThe trouble with seeking\n------------------------\n\nIf you use ad rules, you may run into a problem with click-and-drag seeking.\nSpecifically, after a user clicks and drags to seek through video past multiple\nmidroll pods, they may see 2 or more of those pods play back to back before\ncontent resumes. This is caused by the video playhead time updating while the\nuser is seeking; if the SDK happens to poll for the current time while the user\nseeks past an ad, it may think that ad should be played. When the content\nresumes, it plays that ad, and then the most recent ad since the seek. For a\nvisual representation of this problem, see the following diagram:\n\nSave the current time when the user starts seeking, and report that time when the SDK\nasks for it until the user resumes normal playback. For a visual representation of this\nsolution, see the following diagram:\n\nWith this solution, you properly skip the 0:10 mid-roll and only play the 0:20 mid-roll.\nThis is done using a custom playhead tracker in the following code snippet. This code\ncontains modifications (shown in bold) of `ads.js` in the advanced HTML5\nsample available on our\n[download page](/interactive-media-ads/docs/sdks/html5/download). \n\n```javascript\nvar Ads = function(application, videoPlayer) {\n ...\n this.currentTime = 0;\n setInterval(this.updateCurrentTime, 1000);\n};\n\nAds.prototype.updateCurrentTime = function() {\n if (!this.videoPlayer_.contentPlayer.seeking) {\n this.currentTime = this.videoPlayer_.contentPlayer.currentTime;\n }\n};\n\nAds.prototype.onAdsManagerLoaded_ = function(adsManagerLoadedEvent) {\n this.application_.log('Ads loaded.');\n this.adsManager_ = adsManagerLoadedEvent.getAdsManager(this);\n this.processAdsManager_(this.adsManager_);\n};\n```\n\n### Known issues with mobile Safari\n\nThis method should work on every plaform except mobile Safari. On mobile\nSafari, the seeking property of the video tag is not properly implemented (it\nalways returns false). To get around that, you need to do your own check to\nsee if the user is seeking through the video. The sample code for this method\nfollows. Again, the bolded lines are modifications to existing code. \n\n```javascript\nvar Ads = function(application, videoPlayer) {\n ...\n this.currentTime = 0;\n setInterval(this.updateCurrentTime, 1000);\n this.seeking = false;\n this.seekCheckInterval = 1000;\n // You may need to adjust this value, depending on your platform\n this.seekThreshold = 100;\n this.previousTime = 0;\n setInterval(\n Application.bind(this, this.checkForSeeking),\n this.seekCheckInterval);\n};\n\nAds.prototype.updateCurrentTime = function() {\n if (!this.seeking) {\n this.currentTime = this.videoPlayer_.contentPlayer.currentTime;\n }\n};\n\nAds.prototype.checkForSeeking = function() {\n var currentTime = this.videoPlayer_.contentPlayer.currentTime;\n // How much time has passed since you last ran this method, in milliseconds\n var diff = (currentTime - this.previousTime) * 1000;\n // If that difference is greater than the time since you last ran this method,\n // plus the threshold, the user was seeking\n if (Math.abs(diff) \u003e this.interval + this.threshold) {\n this.seeking = true;\n } else {\n this.seeking = false;\n }\n // Grab the current video time again to make up for time spent in this method\n previousTime = this.videoPlayer_.contentPlayer.currentTime;\n};\n\nAds.prototype.onAdsManagerLoaded_ = function(adsManagerLoadedEvent) {\n this.application_.log('Ads loaded.');\n this.adsManager_ = adsManagerLoadedEvent.getAdsManager(this);\n this.processAdsManager_(this.adsManager_);\n};\n```\n\nWith these changes, the SDK is now using the currentTime property of your `Ads`\nobject to determine when to play ad breaks, not the `currentTime` property of the\ncontent video player."]]