IMA SDK 支持预加载视频广告素材资源。 您可以在 SDK 集成中启用此功能,以便在广告和内容之间实现更顺畅的过渡。 本指南介绍了使用 IMA SDK 实现媒体预加载的技术细节。
前提条件
预加载功能需要 IMA Android SDK 3.17.0 或更高版本。
启用预加载
如需启用预加载,请使用AdsRenderingSettings.setEnablePreloading()
将预加载设置为 true。此操作必须在 onAdsManagerLoaded()
回调中完成:
@Override
public void onAdsManagerLoaded(AdsManagerLoadedEvent adsManagerLoadedEvent) {
...
AdsRenderingSettings adsRenderingSettings =
ImaSdkFactory.getInstance().createAdsRenderingSettings();
adsRenderingSettings.setEnablePreloading(true);
mAdsManager.init(adsRenderingSettings);
}
支持使用自定义 VideoAdPlayer 进行预加载
我们建议使用 Android ExoPlayer 示例应用中使用的 ExoPlayer-IMA 扩展程序。集成后,ExoPlayer-IMA 扩展程序默认启用预加载,并包含内置的预加载支持。
如果您在不使用 ExoPlayer-IMA 扩展程序的情况下实现预加载,则在调用 setEnablePreloading()
后需要进行其他更改。为了让视频播放器支持预加载广告,它必须跟踪通过 loadAd()
和 playAd()
的调用传入的 AdMediaInfo
对象,并在 AdPlayerCallback
调用中包含正确的 AdMediaInfo
。这可能需要一个数据结构来管理 AdMediaInfo
对象,因为在播放之前的 AdMediaInfo
时,可能会出现后续 AdMediaInfo
的 loadAd()
。以下示例演示了您可能需要进行的一些更改,以便应用支持预加载:
// enum for cases of PlayerState.
static enum PlayerState {
IDLE,
LOADED,
PLAYING,
PAUSED,
}
...
private final List<VideoAdPlayer.VideoAdPlayerCallback> callbacks;
private final ArrayList<AdMediaInfo> mediaInfos = new ArrayList<>();
private PlayerState playerState;
private boolean adCurrentlyLoaded;
...
@Override
public void playAd(AdMediaInfo adMediaInfo) {
switch (playerState) {
case LOADED:
for (VideoAdPlayerCallback callback : callbacks) {
callback.onPlay(adMediaInfo);
}
break;
case PAUSED:
for (VideoAdPlayerCallback callback : callbacks) {
callback.onResume(adMediaInfo);
}
break;
case PLAYING:
// Intentionally and silently ignore since it is already playing from a prior media item,
// note that onPlay is triggered by positionDiscontinuity.
return;
case IDLE:
throw new IllegalStateException("Call to playAd when player state is not LOADED.");
}
playerState = PlayerState.PLAYING;
player.setPlayWhenReady(true);
}
@Override
public void loadAd(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) {
if (adCurrentlyLoaded == true) {
mediaInfos.add(adMediaInfo);
return;
}
player.stop();
player.seekTo(0);
mediaInfos.clear();
mediaInfos.add(adMediaInfo);
player.setPlayWhenReady(false);
player.loadMedia(adMediaInfo.getUrl());
playerState = PlayerState.LOADED;
adCurrentlyLoaded = true;
}
@Override
public void stopAd(AdMediaInfo adMediaInfo) {
if (allAdsInBreakHavePlayed()) {
if (isFinalAd(adMediaInfo)) {
// handle clean up after all ads have played.
} else {
seekToNextItem(player);
}
} else {
mediaInfos.remove(adMediaInfo);
}
}
private boolean allAdsInBreakHavePlayed() {
// Code to determine if all the ads in the current ad break have completed.
}
private boolean isFinalAd(AdMediaInfo adMediaInfo) {
// Code to determine if this adMediaInfo is the final ad.
}
private void seekToNextItem(YourPlayerClass player) {
// Code to seek your player to the next media item.
}
测试自定义预加载实现
对于自定义预加载实现,建议测试以下边缘情况,以验证预加载设置是否正确:
- 单个广告前贴片
- 3 个广告连播前贴片广告
- 3 个广告连播中贴片广告
- 在第一个中贴片广告开始预加载但尚未播放时,搜索到第二个中贴片广告
- 后贴片广告播放
计时
下表总结了启用预加载功能后广告加载时序的变化:
事件 | 带预加载 | 无预加载 |
---|---|---|
已请求 VAST 广告 | AdsLoader.requestAds() |
AdsLoader.requestAds() |
前贴片广告已加载(单个广告) | AdsManager.init() |
AdsManager.start() |
前贴片广告已加载(VMAP/广告规则) | AdsManager.init() |
AdsManager.init() |
中贴片广告或后贴片广告已加载 | 对于广告插播时间点中的第 1 个广告,为广告开始时间前 8 秒。 对于连续广告,在前一个广告开始播放时。 | 在广告开始时间。 |
常见问题解答
- 媒体预加载是否会加载整个广告素材?
- 否,广告播放开始时,广告素材通常尚未完全加载。 预加载旨在通过最大限度地缩短广告加载时间来改善用户体验。它并非旨在支持离线广告投放。
- 是否需要为广告的 VAST 和媒体启用媒体预加载?
- 否,无论此预加载设置如何,SDK 始终会预加载广告的 VAST。