预加载媒体
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
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
的 loadAd()
,因此这可能需要使用数据结构来管理 AdMediaInfo
对象。以下示例展示了您可能需要进行的一些更改,以便应用支持预加载:
// 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() |
加载了中贴片广告或后贴片广告 |
对于广告插播时间点中的第一个广告,应在广告开始时间前 8 秒。
对于连续广告,是在前一广告开始播放时。 |
在广告开始时间。 |
常见问题解答
- 媒体预加载是否会加载完整广告素材?
- 否,广告开始播放时,广告素材通常尚未完全加载。预加载旨在通过最大限度缩短广告加载时间来改善用户体验。它不支持离线广告投放。
- 是否需要为广告的 VAST 和媒体启用媒体预加载?
- 否,无论此预加载设置如何,SDK 始终会预加载广告的 VAST。
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-31。
[null,null,["最后更新时间 (UTC):2025-08-31。"],[[["\u003cp\u003eThe IMA SDK supports preloading video ad assets to create smoother transitions between ads and content, requiring version 3.17.0 or higher of the IMA Android SDK.\u003c/p\u003e\n"],["\u003cp\u003ePreloading is enabled using \u003ccode\u003eAdsRenderingSettings.setEnablePreloading(true)\u003c/code\u003e within the \u003ccode\u003eonAdsManagerLoaded()\u003c/code\u003e callback.\u003c/p\u003e\n"],["\u003cp\u003eWhile the ExoPlayer-IMA extension has built-in preloading, custom implementations require managing \u003ccode\u003eAdMediaInfo\u003c/code\u003e objects to ensure proper ad playback.\u003c/p\u003e\n"],["\u003cp\u003ePreloading primarily focuses on minimizing initial ad load times and does not guarantee full creative download or offline ad serving.\u003c/p\u003e\n"]]],[],null,["# Preload media\n\nThe IMA SDK supports preloading video ad assets.\nYou can enable this feature in your SDK integration\nto provide a more seamless transition between ads and content.\nThis guide goes over the technical details of implementing\nmedia preload with the IMA SDK.\n\nPrerequisite\n------------\n\nPreloading requires version 3.17.0 or higher of the IMA Android SDK.\n\nEnable preloading\n-----------------\n\nTo enable preloading, use [`AdsRenderingSettings.setEnablePreloading()`](/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsRenderingSettings#setEnablePreloading(boolean)) to set preloading to true. This must be done within the `onAdsManagerLoaded()` callback:\n\n\u003cbr /\u003e\n\n @Override\n public void onAdsManagerLoaded(AdsManagerLoadedEvent adsManagerLoadedEvent) {\n ...\n AdsRenderingSettings adsRenderingSettings =\n ImaSdkFactory.getInstance().createAdsRenderingSettings();\n adsRenderingSettings.setEnablePreloading(true);\n mAdsManager.init(adsRenderingSettings);\n }\n\nSupporting preloading with a custom VideoAdPlayer\n-------------------------------------------------\n\nWe recommend the\n[ExoPlayer-IMA extension](//github.com/androidx/media/tree/release/libraries/exoplayer_ima)\nthat is used in the\n[Android ExoPlayer example app](//github.com/googleads/googleads-ima-android/tree/main/ExoPlayerExample).\nWhen integrated, the ExoPlayer-IMA extension has preloading enabled by default\nand includes built-in preloading support.\n\nIf you are implementing preloading without the ExoPlayer-IMA extension,\nadditional changes are required once `setEnablePreloading()` is called. In order\nfor a video player to support preloading ads, it must keep track of the\n`AdMediaInfo` objects which are passed in calls from `loadAd()` and `playAd()`,\nand include the correct `AdMediaInfo` on the `AdPlayerCallback` calls. This may\nrequire a data-structure to manage `AdMediaInfo` objects, given that `loadAd()`\nfor a subsequent `AdMediaInfo` may occur while a prior `AdMediaInfo` is\ncurrently playing back. The following example demonstrates some of the changes\nyou may need to make for your app to support preloading: \n\n // enum for cases of PlayerState.\n static enum PlayerState {\n IDLE,\n LOADED,\n PLAYING,\n PAUSED,\n }\n\n ...\n\n private final List\u003cVideoAdPlayer.VideoAdPlayerCallback\u003e callbacks;\n private final ArrayList\u003cAdMediaInfo\u003e mediaInfos = new ArrayList\u003c\u003e();\n private PlayerState playerState;\n private boolean adCurrentlyLoaded;\n\n ...\n\n @Override\n public void playAd(AdMediaInfo adMediaInfo) {\n switch (playerState) {\n case LOADED:\n for (VideoAdPlayerCallback callback : callbacks) {\n callback.onPlay(adMediaInfo);\n }\n break;\n case PAUSED:\n for (VideoAdPlayerCallback callback : callbacks) {\n callback.onResume(adMediaInfo);\n }\n break;\n case PLAYING:\n // Intentionally and silently ignore since it is already playing from a prior media item,\n // note that onPlay is triggered by positionDiscontinuity.\n return;\n case IDLE:\n throw new IllegalStateException(\"Call to playAd when player state is not LOADED.\");\n }\n playerState = PlayerState.PLAYING;\n player.setPlayWhenReady(true);\n }\n\n @Override\n public void loadAd(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) {\n if (adCurrentlyLoaded == true) {\n mediaInfos.add(adMediaInfo);\n return;\n }\n player.stop();\n player.seekTo(0);\n mediaInfos.clear();\n mediaInfos.add(adMediaInfo);\n player.setPlayWhenReady(false);\n player.loadMedia(adMediaInfo.getUrl());\n playerState = PlayerState.LOADED;\n adCurrentlyLoaded = true;\n }\n\n @Override\n public void stopAd(AdMediaInfo adMediaInfo) {\n if (allAdsInBreakHavePlayed()) {\n if (isFinalAd(adMediaInfo)) {\n // handle clean up after all ads have played.\n } else {\n seekToNextItem(player);\n }\n } else {\n mediaInfos.remove(adMediaInfo);\n }\n }\n\n private boolean allAdsInBreakHavePlayed() {\n // Code to determine if all the ads in the current ad break have completed.\n }\n\n private boolean isFinalAd(AdMediaInfo adMediaInfo) {\n // Code to determine if this adMediaInfo is the final ad.\n }\n\n private void seekToNextItem(YourPlayerClass player) {\n // Code to seek your player to the next media item.\n }\n\n### Testing custom preloading implementations\n\nFor custom preloading implementations, testing the following edge-cases is\nrecommended to verify a correct preloading setup:\n\n- Single ad preroll\n- 3 ad pod preroll\n- 3 ad pod midroll\n- Seeking to a second midroll after the first midroll has begun preloading but before it has played\n- Postroll playback\n\nTiming\n------\n\nThe following table summarizes the changes in ad-load timing when preloading\nis enabled:\n\n| Event | With Preload | Without Preload |\n|---------------------------------|--------------------------------------------------------------------------------------------------------------------------|--------------------------|\n| Ad VAST requested | `AdsLoader.requestAds()` | `AdsLoader.requestAds()` |\n| Pre-roll loaded (single ad) | `AdsManager.init()` | `AdsManager.start()` |\n| Pre-roll loaded (VMAP/Ad rules) | `AdsManager.init()` | `AdsManager.init()` |\n| Mid-roll or post-roll loaded | For the 1st ad in an ad break, 8 seconds before ad start time. For consecutive ads, when the previous ad starts playing. | At ad start time. |\n\nFAQ\n---\n\nDoes media preloading load the full creative?\n: No, the creative is usually not fully loaded when ad playback begins.\n Preloading is intended for improving the user experience by minimizing the time\n it takes for the ad to load. It is not intended to support offline ad serving.\n\nDoes media preloading need to be enabled for the ad's VAST as well as media?\n: No, the SDK always preloads the ad's VAST, regardless of this preload\n setting."]]