androidx / androidx/media

Recommended approach for true zero inter-presentation delay in short-form video feeds with DefaultPreloadManager

Open
#3,244 0 comments 2 reactions 1 assignee View on GitHub

@tianyif is already working on this.

Since May 29, 2026.

needs triage question
Dominant language
Java
Stars
3k
Forks
955
Avg merge
12d 14h
Merged PRs (30d)
2

Description

I'm building a short-form vertical video feed (similar to Reels/Shorts) using DefaultPreloadManager with a single ExoPlayer instance (Media3 1.8.0). My TargetPreloadStatusControl preloads 3 seconds of data for adjacent items. The preloaded data is confirmed ready before the user swipes (verified via PreloadManagerListener.onCompleted).

Even with fully preloaded data, every item switch via seekToDefaultPosition(newIndex) triggers a STATE_BUFFERINGSTATE_READY transition lasting ~200-500ms. This appears to be codec initialization + first-frame decode time, not a network issue — the same latency occurs on wifi and throttled networks as long as preload has completed.

I believe this is related to #1973 (setting video surface causes rebuffer). The fundamental issue seems to be that ExoPlayer must reconfigure the codec pipeline on each item switch, even when the SampleQueue already has data ready.

Measured behavior (Pixel 9 Pro Fold, Android 16)
Condition Transition time (seekToDefaultPosition → STATE_READY)
Preloaded, 15 Mbps ~200-500ms
Preloaded, 1 Mbps (preload completed before switch) ~200-400ms
Not preloaded, 15 Mbps ~400-2500ms

The preload eliminates network latency but not the codec setup cost.

Questions

I'm aware that ByteDance's VOD SDK uses a two-player pre-rendering approach — a separate ExoPlayer instance decodes the next item's first frame in advance, then the pre-rendered player is swapped into the foreground on swipe. This achieves true zero visual delay but at higher memory cost (multiple codec instances).

Meanwhile, the Instagram/Facebook case study shows Meta migrated to DefaultPreloadManager with a single player and achieved "instant playback."

  1. Is the ~200-500ms codec initialization on item switch an expected/unavoidable cost with the single-player DefaultPreloadManager architecture?
  2. Is there a planned API or recommended pattern for pre-decoding the next item's first frame within the DefaultPreloadManager framework (without creating a separate ExoPlayer instance)?
  3. If true zero-IPD requires a two-player approach, is there guidance on how to safely share a DefaultPreloadManager's preloaded MediaSource with a secondary "pre-render" ExoPlayer?
Related issues
  • #1973 — Setting video surface after player is ready causes rebuffer
  • #2165 — How to actually use PreloadManager (single vs. multiple players)
Environment
  • Media3 version: 1.8.0
  • Devices: Pixel 9 Pro Fold (Android 16), Fire Max 11 (Fire OS 8)
  • Content: DASH (CMAF fMP4, HEVC video, XHE-AAC audio, 4 ABR variants 360p-1080p, ~42s each)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.