如何防止由于缓冲和系统速度变慢而导致 HLS 视频流播放延迟增加?

问题描述 投票:0回答:1

我正在使用视频元素和 Hls.js 播放 HLS 流。然而,我遇到了一个问题,视频播放逐渐落后于直播。这种延迟是由偶尔的卡顿、缓冲和系统速度减慢引起的。当这些事件发生时,视频会从中断处继续播放,从而导致流随着时间的推移进一步向前推进。

为了补偿这种不断增加的延迟,我尝试使用

video.currentTime
将视频查找到当前流位置,每当下载新片段时(1-5 秒)
hls.on(Hls.Events.BUFFER_APPENDED, ...)
,但不幸的是,这会造成大规模冻结(~1.2 秒),这不是最佳的。

这是我的代码的简化版本:

const video = document.getElementById('video')
const hls = new Hls()

hls.loadSource('http://example.com/playlist.m3u8')
hls.attachMedia(video)

hls.on(Hls.Events.BUFFER_APPENDED, (name, data) => {
  const bufferLength = getBufferLength(video, data)
  // seek to play the latest segment
  video.currentTime = Math.max(video.duration - bufferLength, 0)
})

function getBufferLength(video, data) {
  // returns the last segment length + some additional buffer to avoid stuttering
}

我还尝试使用

video.playbackRate = 1.1
提高播放速率,看起来不错且无缝。仅当缓冲区耗尽时,它才会暂停一小段时间(比查找时间短),直到加载新段。不幸的是,增加的播放速率可能会带来不舒服的体验,尤其是在实时摄像机镜头场景中。设置更保守且不太明显的播放速率,但由于其他事件导致的时间累积量,事实证明是不够的。

那么问题来了,如何以最人性化、最便捷的方式解决这个问题?被广泛接受的行业标准是什么?

html5-video http-live-streaming
1个回答
0
投票

首先,您应该知道,如果您真的关心接近实时,那么您使用的是根本错误的技术。 没有任何分块方法能让你实时,因为这不是它设计的目的。 重点是记录可以通过 CDN 和其他普通 HTTP 服务器分发和缓存的块。

这种延迟是由偶尔的卡顿、缓冲和系统速度减慢引起的。当这些事件发生时,视频会从中断处继续播放,从而导致流随着时间的推移进一步向前推进。

嗯,是的,这就是它应该做的。 它为播放器提供了更多的缓冲区,以防止流故障。 玩家估计需要缓冲多少,并且由于这些缓冲区不足,因此决定需要更大的缓冲区。

为了补偿这种不断增加的延迟,我尝试将视频查找到当前流位置...

没有足够的数据被缓冲,所以如果你尝试向前猛拉它并且没有足够的数据,它就必须缓冲更多。 你无法寻求你还没有的东西。 请记住,块不一定是可独立解码的。 如果编码器是这样配置的,某些块可能依赖于其他块。

我还尝试使用 video.playbackRate = 1.1 来提高播放速率,这看起来不错且无缝。仅当缓冲区耗尽时,它才会暂停一小段时间(比查找时间短),直到加载新段。不幸的是,增加的播放速率可能会带来不舒服的体验......

我真的不确定你的期望是什么。 您想要更接近实时头部,但您发现您无法可靠地跳到它。 您还认为以更高的播放速率转向它是不可接受的。 这只是一个物理问题......你必须以某种方式赶上。 简单地不落后并不是一种选择,因为客户总会有一些落后的原因。

那么问题来了,如何以最人性化、最便捷的方式解决这个问题?被广泛接受的行业标准是什么?

首先,确保您遇到的任何问题都不是在源/编码器/上传方面。 假设您的流一切正常且编码正确,并且假设客户端实际上有足够的 CPU 和带宽来播放该流...

配置 HLS.js 以实现低延迟实时流:

lowLatencyMode: true

这基本上完成了您已经尝试过的操作。 它会提高播放速率,以便尽可能靠近现场头部。 如果它落后于某个特定阈值,那么它会重新开始播放并尝试通过搜索来尽可能接近。

© www.soinside.com 2019 - 2024. All rights reserved.