The IMA SDK supports preloading video ad assets. You can enable this feature in your SDK integration to provide a more seamless transition between ads and content. This guide goes over the technical details of implementing media preload with the IMA SDK.
Prerequisite
Preloading requires version 3.17.0 or higher of the IMA Android SDK.
Enable preloading
To enable preloading, useAdsRenderingSettings.setEnablePreloading()
to set preloading to true. This must be done within the onAdsManagerLoaded()
callback: @
Override
public
void
onAdsManagerLoaded
(
AdsManagerLoadedEvent
adsManagerLoadedEvent
)
{
...
AdsRenderingSettings
adsRenderingSettings
=
ImaSdkFactory
.
getInstance
()
.
createAdsRenderingSettings
();
adsRenderingSettings
.
setEnablePreloading
(
true
);
mAdsManager
.
init
(
adsRenderingSettings
);
}
Supporting preloading with a custom VideoAdPlayer
We recommend the ExoPlayer-IMA extension that is used in the Android ExoPlayer example app . When integrated, the ExoPlayer-IMA extension has preloading enabled by default and includes built-in preloading support.
If you are implementing preloading without the ExoPlayer-IMA extension,
additional changes are required once setEnablePreloading()
is called. In order
for a video player to support preloading ads, it must keep track of the AdMediaInfo
objects which are passed in calls from loadAd()
and playAd()
,
and include the correct AdMediaInfo
on the AdPlayerCallback
calls. This may
require a data-structure to manage AdMediaInfo
objects, given that loadAd()
for a subsequent AdMediaInfo
may occur while a prior AdMediaInfo
is
currently playing back. The following example demonstrates some of the changes
you may need to make for your app to support preloading:
//
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
.
}
Testing custom preloading implementations
For custom preloading implementations, testing the following edge-cases is recommended to verify a correct preloading setup:
- Single ad preroll
- 3 ad pod preroll
- 3 ad pod midroll
- Seeking to a second midroll after the first midroll has begun preloading but before it has played
- Postroll playback
Timing
The following table summarizes the changes in ad-load timing when preloading is enabled:
Event | With Preload | Without Preload |
---|---|---|
Ad VAST requested
|
AdsLoader.requestAds()
|
AdsLoader.requestAds()
|
Pre-roll loaded (single ad)
|
AdsManager.init()
|
AdsManager.start()
|
Pre-roll loaded (VMAP/Ad rules)
|
AdsManager.init()
|
AdsManager.init()
|
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. |
FAQ
- Does media preloading load the full creative?
- No, the creative is usually not fully loaded when ad playback begins. Preloading is intended for improving the user experience by minimizing the time it takes for the ad to load. It is not intended to support offline ad serving.
- Does media preloading need to be enabled for the ad's VAST as well as media?
- No, the SDK always preloads the ad's VAST, regardless of this preload setting.