Fixing buffering and stuttering: a checklist that starts with the right question

The app already classifies nine distinct playback faults. Knowing which one you have turns a vague problem into a short list.

Most buffering advice starts with "check your internet". You already did. The better first move is to work out which of several failures you have, because each has a different fix and the app has already classified it for you.

Nine failures, not one

The player has no single notion of "not working". It classifies faults into 9 kinds, and the class decides which recovery runs:

F1  NetStall      no bytes arriving at all
F2  SilentEof     the stream ended without you asking
F3  HardError     the stream would not open
F4  DemuxStarve   bytes arriving, no frames coming out
F5  VideoFreeze   picture stopped, audio still playing
F6  TotalFreeze   both stopped, data still flowing
F7  BlackFrames   everything healthy, picture is black
F8  ClockStall    the input clock stopped advancing
F9  RebufferLoop  repeated rebuffering in a rolling window

These are different problems. F1 is your network or the provider's. F4 is a stream sending padding instead of video, which is a provider problem your connection cannot fix. F7 is usually the source feeding black, which no amount of restarting will help.

Nothing is declared instantly. A fault has to persist through a window first: 4 seconds of zero bytes, 6 seconds of a starved demuxer, 4 seconds of stalled video, 4 seconds of total freeze. Those windows exist because a 2 second hiccup is not a fault. A player that reacted to every one would spend the evening restarting a stream that was about to recover.

What the player already does before you do anything

Three things, so you do not duplicate them.

It adapts its own buffers. When rebuffering repeats, the player raises its caching floor by 1000 milliseconds per verdict, up to 5000. On a marginal connection the app has probably already given itself more buffer than the 1200 milliseconds of network cache and 800 of live cache it starts with. Turning a buffer setting up by hand often redoes work that already happened.

It is also careful about what counts as rebuffering. An episode is counted only when the cache drops below 62 percent, and it ends at 88. That hysteresis exists because live HLS cache readings wobble across segment boundaries, and counting every dip below full would flag healthy streams as broken.

And it catches the failure that produces no error, which is why "it just sits there" is a real category. A stream can stop sending while leaving its socket open. We tested this against a fault-injection harness and the result was unambiguous: the byte counter delta goes to 0 and there is no player event at all. Nothing errors. Nothing throws. The picture holds on the last frame it had.

That is why detection is a timer watching counters rather than an error handler, and why there is a 4 second wait before anything happens. If your stream freezes and recovers a few seconds later, you have watched that mechanism work.

I did not expect the retry side to be the biggest lever. With both connect graces at 8 seconds, a total byte stall spent 8 of its 15.7 seconds restarting a URL that was still dead. Shortening the retry grace to 4 seconds, the same 4 seconds of zero bytes already trusted to condemn an established stream, was the single largest improvement in measured fault-to-alternate time. The ladder also allows exactly 1 restart before switching sources, because field data showed a second restart of a dead source never helps.

The checklist, in the order that finds things fastest

1. Is it one channel or all of them? One channel is a source problem and no setting on your machine will fix it. If your provider offers the same channel in another quality or from another server, try that. All channels is your side.

2. Is it wired or wireless? This is the single most productive question. A live stream is a continuous real-time read, and marginal wireless produces exactly the symptom people blame on the player. Try a cable once, purely as a diagnostic.

3. Does the same channel play on another device on the same network? If it plays on a phone and not on the PC, you have narrowed it to the machine. If it fails on both, you have narrowed it to the network or the provider.

4. Are you at your connection limit? Two connections and three devices is a stutter that looks like bandwidth and is not. Max connections covers why a connection can stay spent after you stopped watching.

5. Is the picture actually stopping, or is it judder? Regular, rhythmic stutter on panning shots is usually a refresh-rate mismatch: 50 Hz content on a 60 Hz display. That is a display setting, not a buffer problem, and no amount of caching will change it. Connecting a laptop over HDMI covers it.

If you use a proxy or VPN inside the app

One behaviour to expect. When a connection profile is configured, media the transport cannot carry fails closed rather than quietly falling back to a direct connection. That is deliberate. A privacy setting that silently stops applying is worse than one that stops working visibly.

So a channel that worked before you configured a profile and fails after it is not necessarily a broken profile. It may be a stream whose scheme the relay cannot carry, refusing to leak. That is the profile working. VPNs and stream performance covers what actually matters there.

If the picture is frozen but the sound continues, that is F5 specifically and it has its own article: video freezes, audio continues for the mechanism, and sound but no picture for what to do about it.

What this article measured22 claims, each with the evidence behind it
ClaimEvidenceCounted
Playback faults are classified into nine kinds rather than reported as one generic error, and the class selects which recovery rung runs.n = 9Aug 31, 2026
Each fault has to persist for a fixed window before it is declared: 4 seconds of zero bytes, 6 seconds of a starved demuxer, 4 seconds of stalled video, and 4 seconds of total freeze.n = 4Aug 31, 2026
A rebuffer episode is counted only when the cache falls below 62 percent and ends at 88 percent, because live HLS cache readings wobble across segment boundaries and counting every dip below full would flag healthy streams.n = 1Aug 23, 2026
When a rebuffer loop is declared the player raises its own caching floor by 1000 milliseconds per verdict, up to a ceiling of 5000 milliseconds, rather than asking the viewer to change a setting.n = 1Aug 23, 2026
Default buffering is 1200 milliseconds of network cache and 800 of live cache on the full-screen live path, against 350 and 200 on a muted multiview tile.n = 1Aug 23, 2026
A stream that stops sending while leaving its socket open produces no player event at all. The byte counter delta goes to zero and nothing else changes, which is why detection has to be a timer rather than an error handler.n = 1Aug 16, 2026
The whole detector has three rollout modes: Active, Shadow (detect and log only) and Off. The default is Active, and the mode is settable from configuration without a rebuild.n = 3Sep 1, 2026
Counters are sampled once a second while a stream looks healthy and twice a second once it looks suspect.n = 2Sep 1, 2026
Opening a stream is judged separately from playing one: 15 seconds to reach first presentation on a cold open, 8 on a recovery attempt, with total network silence condemned at 8 seconds cold and 4 on a retry.n = 4Sep 1, 2026
Shortening the retry grace was the single largest improvement in measured fault-to-alternate time: with both graces at 8 seconds, a total byte stall spent 8 of its 15.7 seconds restarting a URL that was still dead.n = 1Sep 1, 2026
A suspect stream returns to healthy after 3 seconds of normal deltas, and 60 continuous seconds of health resets the recovery ladder and its backoff.n = 2Sep 1, 2026
Counters are allowed to stall for 5 seconds after a user seek without that counting as a fault.n = 1Sep 1, 2026
Channels that are not ordinary video get their own windows: 15 seconds for a low-frame-rate channel and 12 for one classified audio-only, against 4 for normal video.n = 3Sep 1, 2026
A session is classified audio-only after 4 seconds, chosen to sit inside the start grace but above observed late-PMT delays, because misclassifying a video channel would silently disable its freeze rules for the rest of the session.n = 1Sep 1, 2026
Stream corruption arms shorter freeze windows: 3 discontinuities or 25 corrupted units in one sample keep the shortened windows armed for 10 seconds.n = 3Sep 1, 2026
For 10 seconds after a recovery, verdict windows are halved, because the evidence that condemned the source moments ago still stands. A genuinely fixed stream advances its counters immediately and never enters those windows.n = 1Sep 1, 2026
Retries back off as base times two to the attempt minus one, capped at 30 seconds and jittered by plus or minus 20 percent, so the first attempt fires immediately and later ones grow 1, 3 and 7 seconds.n = 3Sep 1, 2026
The ladder allows exactly 1 restart of a failing URL before switching sources, because field data showed a second restart of a dead source never helps and only delays the switch.n = 1Sep 1, 2026
A fault inside the first 15 seconds of a session enters the ladder at failover rather than restart, on the reasoning that the source never proved itself. Mature sessions keep restart first so a mid-viewing hiccup never causes a source switch.n = 1Sep 1, 2026
After the ladder gives up, background retries continue every 60 seconds and stop entirely after 30 minutes, leaving manual retry as the only route.n = 2Sep 1, 2026
Seamless failover brings the replacement up on a second decoder and swaps at its first frame, but it costs one extra provider connection during the overlap, so the planner refuses whenever that connection is not provably spare and degrades to an ordinary restart.n = 1Sep 1, 2026
When a connection profile is in use, media that cannot be carried by the configured transport fails closed rather than falling back to a direct connection.n = 1Aug 25, 2026