自动制作广告播放列表
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
IMA HTML5 SDK 支持完全自动化的广告播放列表。此功能会在投放广告时,按照 Google Ad Manager 中指定的方式将广告插播点插入内容中。此外,它还大大简化了支持广告插播(包括前贴片广告、中贴片广告和后贴片广告)所需的视频播放器代码。
- 创建
AdsManager
时,系统会使用 getAdsManager 调用传入 contentPlayback
对象。此对象必须具有一个 currentTime
属性,用于返回视频的当前播放头位置。如果您使用 HTML5 video
元素来展示内容,只需将该元素传递给 SDK 即可。此对象用于跟踪内容播放进度,以便在 Ad Manager 中指定的时间自动插入广告插播时间点。您还需要告知 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 无法区分内容正常播放和用户跳转内容。
您必须使用自定义 contentPlayback 对象作为
getAdsManager
的参数。
如需查看此用例的示例,请参阅跳转问题。
注意:当内容播放完毕或用户停止播放时,请务必调用 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 现在使用 Ads
对象的 currentTime 属性来确定何时播放广告插播时间点,而不是内容视频播放器的 currentTime
属性。
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-31。
[null,null,["最后更新时间 (UTC):2025-08-31。"],[[["\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."]]