Progress is observed both from timeUpdate events and by reading currentTime on each poll. A
late timeUpdate alone is not a stall: when the main thread is busy (a long task, a GC pause) or
event delivery is delayed, the play head keeps advancing while no timeUpdate reaches script,
and the poll sees that advance rather than reporting a freeze.
Detection only runs once playback has actually been observed (a playing event) and is
suspended on pause/seeking/emptied until playback is observed again — so a stall is never
reported during initial loading or while awaiting a seek. A detected stall ends when the play
head advances again (playing) or playback stops for another reason (pause/seeking/
emptied); StallEndedInfo.duration is measured from the last observed progress before
the freeze, so it reflects the full frozen time rather than only the time past the threshold.
Watches a ReadonlyPlaybackController for stalls while playing: the play head freezing (
currentTimenot advancing) for longer than StallMonitorOptions.stallThreshold seconds.Progress is observed both from
timeUpdateevents and by readingcurrentTimeon each poll. A latetimeUpdatealone is not a stall: when the main thread is busy (a long task, a GC pause) or event delivery is delayed, the play head keeps advancing while notimeUpdatereaches script, and the poll sees that advance rather than reporting a freeze.Detection only runs once playback has actually been observed (a
playingevent) and is suspended onpause/seeking/emptieduntil playback is observed again — so a stall is never reported during initial loading or while awaiting a seek. A detected stall ends when the play head advances again (playing) or playback stops for another reason (pause/seeking/emptied); StallEndedInfo.duration is measured from the last observed progress before the freeze, so it reflects the full frozen time rather than only the time past the threshold.Returns a function that stops the monitor.