> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://fastpix.com/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://fastpix.com/docs/_mcp/server.

# Pre-cache videos before a player exists

> Warm FastPix videos into the disk cache before any player is built, so the player you create later starts from disk, using FastPixPreCacher in the Android Player SDK.

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:

* The FastPix Android Player SDK version 2.2.2 or later, installed and set up. See [Install FastPix Android player](/docs/android-player/install-fastpix-android-player) and [Set up the player](/docs/android-player/set-up-the-player).
* Disk caching enabled with `CacheConfig`. See [Preload and cache for faster startup](/docs/android-player/preload-and-cache-for-faster-startup). The pre-cacher and the player must use the same `CacheConfig`, because the cache is process-wide and the first config to open it wins.

\


## 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.

```kotlin
// 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:

```kotlin
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.

```kotlin
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.

```kotlin
FastPixPreCacher.create(
    context,
    CacheConfig.enabled(),
    preCacheConfig = PreCacheConfig(segmentCount = 2, maxBytesPerItem = 2 * 1024 * 1024)
)
```

| Option             | Default            | Description                                                                                |
| ------------------ | ------------------ | ------------------------------------------------------------------------------------------ |
| `segmentCount`     | `2`                | Number of leading segments warmed per item                                                 |
| `maxBytesPerItem`  | 2 MB               | Ceiling on bytes written per item                                                          |
| `targetBitrateBps` | Follows the player | Pin 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:

```kotlin
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.

```kotlin
// 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](/docs/android-player/manage-playlists) 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

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.

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.

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.

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

* [Preload and cache for faster startup](/docs/android-player/preload-and-cache-for-faster-startup) for the buffering, preloading, caching, and pre-rendering levers.
* [Build video feeds](/docs/android-player/build-video-feeds) with `FastPixPlayerPool` for reels and carousels.
* [Enable secure video playback](/docs/android-player/enable-secure-video-playback) for warming private videos with a playback token.