You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Custom AdsLoader: no supported way to play a skipped-over midroll without breaking AdPlaybackState invariants #3424
Desired behaviour (force-play the last missed ad break after a seek)
Cues at 10 / 20 / 30 / 40 min. User starts at 5 min, seeks to 35 min. We want to play the last skipped break (30 min), resume at 35 min, keep 10/20 rewindable, and play 40 min once on the normal AdsLoader path.
Wanted:
[10] [20] still playable if user seeks back
[30] played after the seek
[40] untouched, AdsMediaSource when playhead reaches it
How we build AdPlaybackState today
Media3 1.6+ (checkValidAdPlaybackStateUpdate): timeUs immutable, groups append-only, times must stay sorted (getAdGroupIndexForPositionUs walks from the last index). count = UNSET at the playhead stalls forever; count = 0 is a skipped placeholder that may grow (0 → N + URIs).
At start we publish one group per cue, sorted, at the real times :
Cold start (playhead = 0)
t=0 preroll count = UNSET → AdsMediaSource waits, we resolve VAST then fill or skip
t=10m midroll count = 0 → content plays through
t=20m midroll count = 0
t=30m midroll count = 0
t=40m midroll count = 0
Continue watching (bookmark = 12 min)
t=0 skipped / unused preroll at 0
t=10m midroll count = 0
t=12m resume preroll slot count = UNSET ← bookmark is in the initial sorted list
t=20m midroll count = 0
t=30m midroll count = 0
t=40m midroll count = 0
• Midrolls: count = 0 from launch so content is not blocked; AdsMediaSource can createPeriod at the real cue.
• 3–10 s before a cue we resolve VAST and grow that placeholder (count + media). We never move timeUs.
• Resume: a preroll at t=0 is ignored behind the playhead. We put the bookmark in the first sorted AdPlaybackState(...) (not appended later — that would sit after 40 min and hide midrolls). That slot stays UNSET until VAST, then we fill or skip.
Natural playback works. Force-play the last missed ad break after a seek does not.
What we cannot do
Move the 30 min group to playhead + 1 after 5→35 ->crash.
Rewrite all midroll timeUs after the seek — forbidden.
-> 40 min already exists → append at ~35 min inserts a time before 40 min → unsorted / wrong index
Insert a group at the playhead — same case, forbidden (shifts later indexes).
Question
Do you see a way to implement this on top of the model above (real cue times, midrolls count = 0, UNSET preroll at 0 or bookmark, fill in the preload window) without breaking checkValidAdPlaybackStateUpdate?
In particular:
• After a user seek, can we play the last skipped-over midroll and then resume at the seek position, while later cues (e.g. 40 min) stay on the normal AdsMediaSource path?
• Is anything planned in this area (seek vs behind-playhead groups)?
Thank you in advance for your help and for taking the time to respond.
Reacted by Grégory LORY, david-bedrock, Oreste Mosciatti and Franck Dev
Activity