Skip to content

Low Latency playback - recovering after stalls #6350

Open
@vk342

Description

@vk342

What do you want to do with Hls.js?

I am trying to support ultra low-latency HLS stream using 6 second segments and 0.5 second parts with liveSyncDuration of 1.4 seconds.

Hls.js version is 1.5.7.

My config looks as following:

{
    "debug": false,
    "enableWorker": true,
    "lowLatencyMode": true,
    "backBufferLength": 90,
    "liveSyncDuration": 1.4,
    "liveMaxLatencyDuration": 5,
    "maxLiveSyncPlaybackRate": 1.2,
    "liveDurationInfinity": true,
    "startFragPrefetch": true
}

Periodically the player encounters a stall, and after each stall LatencyController target latency is increased by 1 second:
this.stallCount * liveSyncOnStallIncrease, see targetLatency below:

get targetLatency(): number | null {
const { levelDetails } = this;
if (levelDetails === null) {
return null;
}
const { holdBack, partHoldBack, targetduration } = levelDetails;
const { liveSyncDuration, liveSyncDurationCount, lowLatencyMode } =
this.config;
const userConfig = this.hls.userConfig;
let targetLatency = lowLatencyMode ? partHoldBack || holdBack : holdBack;
if (
userConfig.liveSyncDuration ||
userConfig.liveSyncDurationCount ||
targetLatency === 0
) {
targetLatency =
liveSyncDuration !== undefined
? liveSyncDuration
: liveSyncDurationCount * targetduration;
}
const maxLiveSyncOnStallIncrease = targetduration;
const liveSyncOnStallIncrease = 1.0;
return (
targetLatency +
Math.min(
this.stallCount * liveSyncOnStallIncrease,
maxLiveSyncOnStallIncrease,
)
);
}

So if the stream is played for an hour and encountered 3 stalls our target latency drifts from 1.4 to 4.4.

I might be missing something, but I don't seem to see a mechanism to recover from this condition.

I do not see the API to programmatically change targetLatency after player has been created, so the only way to return to lower latency is to reset the player.

I am looking for a more graceful way to return to lower targetLatency after a period of successful playback.

What have you tried so far?

I have tried to programmatically set LatencyController.stallCount to a lower value after X seconds of playback without a stall.

private stallCount: number = 0;

This did reduce player.targetLatency, but did not affect the actual playback latency, despite the fact that maxLiveSyncPlaybackRate is set to 1.2 and I was hoping that the player would try to catch up to targetLatency.

I have also tried to change liveSyncOnStallIncrease from 1.0 to 0.1 second.

const liveSyncOnStallIncrease = 1.0;

This did cause targetLatency to drift slower, however I still observed that the actual playback latency remained higher then the target latency and the player did not attempt to catch up.

Note: whenever the drift happened, I was able to start another playback in the same stream in a different window using the same version of hls.js and the second player would start and play the stream at my initial target latency of 1.4. For example, my first player would have targetLatency = 1.4, but actual latency of 3.4 sec, while my second player would have both target and actual latency of 1.4 sec.

This indicates that the content has been available on the server.

I would be very grateful for the guidance on how to improve the playback latency in this scenario.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    • Status

      To do

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions