IMA HTML5 SDK 支持完全自动化的广告播放列表。此功能可在投放广告时,按照 Google Ad Manager 中的指定将广告插播时间点插入到内容中。它还大大简化了支持广告插播(包括前贴片广告、中贴片广告和后贴片广告)所需的视频播放器代码。
- 创建
AdsManager
时,使用 getAdsManager 调用传入contentPlayback
对象。此对象必须具有一个currentTime
属性,用于返回视频的当前播放头位置。如果您使用 HTML5video
元素来显示内容,只需将该元素传递给 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,而不是在广告播放完毕时通知 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
属性。