Skip to navigation

Pre-cache videos before a player exists

Preloading and pre-rendering warm the entries around a player that already exists. Sometimes you want to warm videos earlier than that: the rows of a list screen before one is opened, or a feed’s first items at app start, when no player has been built yet. FastPixPreCacher warms items into the same disk cache with no player involved. It stores the playlists, the first segments of the rendition a new player will start on, and the matching audio. The player you build later, with the same CacheConfig, then starts from disk.


Before you begin

Make sure you have the following:


Warm items into the cache

Create one FastPixPreCacher for the screen, for example in a list screen or a ViewModel, and hand it the items the user is likely to open next. Warm by playback ID (private videos pass their token), or by stream URL for URLs you already have.

// e.g. in the list screen or a ViewModel; one instance is enough
val preCacher = FastPixPreCacher.create(context, CacheConfig.enabled())
preCacher?.setListener(object : PreCacheListener {
override fun onPreCached(url: String, bytesWritten: Long) { /* optional */ }
override fun onPreCacheFailed(url: String, error: Throwable) { /* optional */ }
})
// By playback ID; private videos pass their token. Cancels warms for items no longer in the list.
preCacher?.preCacheItems(
visibleItems.map { PlaylistItem.fastPix(it.playbackId, it.playbackToken) }
)
// Or by stream URL, for URLs you already have
preCacher?.preCache(visibleItems.map { it.streamUrl })

Each call to preCacheItems replaces the previous set, so warms for items no longer visible are cancelled. Hand it the items the user is likely to open next, not the whole catalogue.


Check whether an item is warm

Use isWarm to tell whether an item has been warmed in this process, for example to show a “ready” badge:

val ready = preCacher?.isWarm(PlaylistItem.fastPix(id, token)) == true

Build the player with the same cache

On the player screen, build the player with the same CacheConfig. There is nothing else to wire up: the player finds the warmed bytes on disk and starts from them.

FastPixPlayer.Builder(context)
.setCacheConfig(CacheConfig.enabled())
.build()

Control how much is warmed

PreCacheConfig sets how much is warmed per item. The default warms two segments up to 2 MB per item; PreCacheConfig.LIGHT warms one segment.

FastPixPreCacher.create(
context,
CacheConfig.enabled(),
preCacheConfig = PreCacheConfig(segmentCount = 2, maxBytesPerItem = 2 * 1024 * 1024)
)
OptionDefaultDescription
segmentCount2Number of leading segments warmed per item
maxBytesPerItem2 MBCeiling on bytes written per item
targetBitrateBpsFollows the playerPin the warmed rendition to a known bitrate cap. Set this only if the player is pinned too

Match the rendition the player will pick

The rendition warmed follows the player: its starting bandwidth estimate, the network-type caps from AbrConfig, and the display size. If your players use a custom AbrConfig, pass the same one to the pre-cacher so it warms the rendition playback will actually use:

FastPixPreCacher.create(context, CacheConfig.enabled(), abrConfig = myAbrConfig)

Set PreCacheConfig(targetBitrateBps = ...) only when the player is pinned to a known bitrate cap.


Release the pre-cacher

Release the pre-cacher when its screen goes away. This cancels in-flight warms; the bytes already written stay in the shared cache for the player to read.

// when the screen goes away
preCacher?.release()

Note:

  • Tokens are not part of the cache key. A private video warmed with one token still starts from disk when the player is given a refreshed token for the same playback ID.
  • Pass the same CacheConfig to the pre-cacher and the player. The cache is process-wide, so the first config to open it fixes its location and size.
  • For one player moving through a feed, prefer a playlist with PreloadConfig. It warms the same way and also buffers the next entry in memory.
  • DRM videos warm their playlists and segments, but the Widevine licence is still requested on every play, so a warmed DRM video starts a few hundred milliseconds later than a clear one.

Frequently asked questions

How do I pre-cache videos before building a player on Android?

Create a FastPixPreCacher with FastPixPreCacher.create(context, CacheConfig.enabled()), then call preCacheItems(...) with the playback IDs (and tokens for private videos) the user is likely to open next, or preCache(urls) for stream URLs. Build the player later with the same CacheConfig and it starts from disk. Release the pre-cacher when its screen goes away.

What is the difference between pre-caching and preloading on Android?

Pre-caching with FastPixPreCacher warms items into the disk cache before any player exists, which suits a list screen or app start. Preloading with PreloadConfig warms the entries around a player that already exists and also buffers the next entry in memory. For one player moving through a feed, preloading is the better fit; for a list of items none of which is playing yet, pre-caching is.

Does a refreshed playback token break the pre-cache on Android?

No. The token is not part of the cache key, so a private video warmed with one token still starts from disk when the player is later given a refreshed token for the same playback ID. The warmed bytes stay readable from disk until they are evicted.

Does pre-caching speed up DRM videos?

Partly. Pre-caching warms a DRM video’s playlists and segments, but the Widevine licence is still requested on every play, so a warmed DRM video starts a few hundred milliseconds later than a clear one.


What’s next